]> git.donarmstrong.com Git - perltidy.git/commitdiff
* upgrade to the 20060614 release
authordon <don@8f7917da-ec0b-0410-a553-b9b0e350d17e>
Fri, 23 Jun 2006 20:31:41 +0000 (20:31 +0000)
committerdon <don@8f7917da-ec0b-0410-a553-b9b0e350d17e>
Fri, 23 Jun 2006 20:31:41 +0000 (20:31 +0000)
21 files changed:
BUGS
CHANGES
INSTALL
MANIFEST
META.yml [new file with mode: 0644]
README
TODO
bin/perltidy
debian/changelog
debian/compat [new file with mode: 0644]
debian/control
debian/rules
docs/README
docs/perltidy.1
docs/stylekey.pod
examples/README
examples/perlcomment.pl
examples/perltidy.bat [deleted file]
examples/perltidyrc_dump.pl [new file with mode: 0644]
examples/pt.bat [new file with mode: 0644]
lib/Perl/Tidy.pm

diff --git a/BUGS b/BUGS
index 79b8b44110c69444fab8fab2fa36ec6344a42a22..edca9bc7fdb9770c1d2a2f2121276a5c5172081b 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -16,3 +16,24 @@ Perltidy open BUGS
             END
             print "$text\n";
 
             END
             print "$text\n";
 
+    A workaround is to put the here-doc in a temporary string and then do
+    the substitution:
+
+            my $text="Hello World!\n";
+            my $str=<<'END';
+            Goodbye 
+            Cruel
+            END
+            $text =~ s@Hello@$str@e;
+            print "$text\n";
+
+  The --extrude option can occasionally produce code with syntax errors
+    The --extrude tries to put as many newlines in the formatted code as
+    possible. This option is of limited use for formatting, but it has been
+    helpful for debugging purposes. Occasionally it will produce code which
+    Perl considers to have a syntax error. These problems usually involve
+    code where Perl is having to guess the tokenization. For example,
+    --extrude will currently cause a syntax error in the following line:
+
+     utime $inc+0 ? ($mtime, $ntime) : ($atime, $atime), $file;
+
diff --git a/CHANGES b/CHANGES
index 5c3748c8ae5031000ca02b2c845ba85063d1c263..b59e99b2cba1ca44ad152d288178d4414a7d2053 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,113 @@ Perltidy Change Log
      please send a note to perltidy at users.sourceforge.net.  All
      suggestions are welcome.
 
      please send a note to perltidy at users.sourceforge.net.  All
      suggestions are welcome.
 
+  2006 06 14
+     -Attribute argument lists are now correctly treated as quoted strings
+     and not formatted.  This is the most important update in this version.
+     Thanks to Borris Zentner, Greg Ferguson, Steve Kirkup.
+
+     -Updated to recognize the defined or operator, //, to be released in Perl 10.
+     Thanks to Sebastien Aperghis-Tramoni.
+
+     -A useful utility perltidyrc_dump.pl is included in the examples section.  It
+     will read any perltidyrc file and write it back out in a standard format
+     (though comments are lost).
+
+     -Added option to have perltidy read and return a hash with the contents of a
+     perltidyrc file.  This may be used by Leif Eriksen's tidyview code.  This
+     feature is used by the demonstration program 'perltidyrc_dump.pl' in the
+     examples directory.
+
+     -Improved error checking in perltidyrc files.  Unknown bare words were not
+     being caught.
+
+     -The --dump-options parameter now dumps parameters in the format required by a
+     perltidyrc file.
+
+     -V-Strings with underscores are now recognized.
+     For example: $v = v1.2_3; 
+
+     -cti=3 option added which gives one extra indentation level to closing 
+     tokens always.  This provides more predictable closing token placement
+     than cti=2.  If you are using cti=2 you might want to try cti=3.
+
+     -To identify all left-adjusted comments as static block comments, use C<-sbcp='^#'>.
+
+     -New parameters -fs, -fsb, -fse added to allow sections of code between #<<<
+     and #>>> to be passed through verbatim. This is enabled by default and turned
+     off by -nfs.  Flags -fsb and -fse allow other beginning and ending markers.
+     Thanks to Wolfgang Werner and Marion Berryman for suggesting this.  
+
+     -added flag -skp to put a space between all Perl keywords and following paren.
+     The default is to only do this for certain keywords.  Suggested by
+     H.Merijn Brand.
+
+     -added flag -sfp to put a space between a function name and following paren.
+     The default is not to do this.  Suggested by H.Merijn Brand.
+
+     -Added patch to avoid breaking GetOpt::Long::Configure set by calling program. 
+     Thanks to BOOK at CPAN. 
+
+     -An error was fixed in which certain parameters in a .perltidyrc file given
+     without the equals sign were not recognized.  That is,
+     '--brace-tightness 0' gave an error but '--brace-tightness=0' worked
+     ok.  Thanks to Zac Hansen.
+
+     -An error preventing the -nwrs flag from working was corrected. Thanks to
+      Greg Ferguson.
+
+     -Corrected some alignment problems with entab option.
+
+     -A bug with the combination of -lp and -extrude was fixed (though this
+     combination doesn't really make sense).  The bug was that a line with
+     a single zero would be dropped.  Thanks to Cameron Hayne.
+
+     -Updated Windows detection code to avoid an undefined variable.
+     Thanks to Joe Yates and Russ Jones.
+
+     -Improved formatting for short trailing statements following a closing paren.
+     Thanks to Joe Matarazzo.
+
+     -The handling of the -icb (indent closing block braces) flag has been changed
+     slightly to provide more consistent and predictable formatting of complex
+     structures.  Instead of giving a closing block brace the indentation of the
+     previous line, it is now given one extra indentation level.  The two methods
+     give the same result if the previous line was a complete statement, as in this
+     example:
+
+            if ($task) {
+                yyy();
+                }    # -icb
+            else {
+                zzz();
+                }
+     The change also fixes a problem with empty blocks such as:
+
+        OLD, -icb:
+        elsif ($debug) {
+        }
+
+        NEW, -icb:
+        elsif ($debug) {
+            }
+
+     -A problem with -icb was fixed in which a closing brace was misplaced when
+     it followed a quote which spanned multiple lines.
+
+     -Some improved breakpoints for -wba='&& || and or'
+
+     -Fixed problem with misaligned cuddled else in complex statements
+     when the -bar flag was also used.  Thanks to Alex and Royce Reese.
+
+     -Corrected documentation to show that --outdent-long-comments is the default.
+     Thanks to Mario Lia.
+
+     -New flag -otr (opening-token-right) is similar to -bar (braces-always-right)
+     but applies to non-structural opening tokens.
+
+     -new flags -sot (stack-opening-token), -sct (stack-closing-token).
+     Suggested by Tony.
+
   2003 10 21
      -The default has been changed to not do syntax checking with perl.  
        Use -syn if you want it.  Perltidy is very robust now, and the -syn
   2003 10 21
      -The default has been changed to not do syntax checking with perl.  
        Use -syn if you want it.  Perltidy is very robust now, and the -syn
@@ -26,12 +133,12 @@ Perltidy Change Log
       In most cases it looks better.  To recover the previous format, use
       '-gnu -cti=2'
 
       In most cases it looks better.  To recover the previous format, use
       '-gnu -cti=2'
 
-     -Added flags B<-cti=n> for finer control of closing token indentation.
+     -Added flags -cti=n for finer control of closing token indentation.
        -cti = 0 no extra indentation (default; same as -nicp)
        -cti = 1 enough indentation so that the closing token
             aligns with its opening token.
        -cti = 2 one extra indentation level if the line has the form 
        -cti = 0 no extra indentation (default; same as -nicp)
        -cti = 1 enough indentation so that the closing token
             aligns with its opening token.
        -cti = 2 one extra indentation level if the line has the form 
-              C<);>, C<];>, or <};> (same as -icp).
+              );   ];   or   };     (same as -icp).
 
        The new option -cti=1 works well with -lp:
 
 
        The new option -cti=1 works well with -lp:
 
@@ -100,7 +207,7 @@ Perltidy Change Log
      prevent the use of Html::Entities to encode special symbols.  The
      default is -hent.  Html::Entities when formatting perl text to escape
      special symbols.  This may or may not be the right thing to do,
      prevent the use of Html::Entities to encode special symbols.  The
      default is -hent.  Html::Entities when formatting perl text to escape
      special symbols.  This may or may not be the right thing to do,
-     depending on browser/language combinations.  Thanks to Gurak Bursoy for
+     depending on browser/language combinations.  Thanks to Burak Gursoy for
      this suggestion.
 
      -Bareword strings with leading '-', like, '-foo' now count as 1 token
      this suggestion.
 
      -Bareword strings with leading '-', like, '-foo' now count as 1 token
diff --git a/INSTALL b/INSTALL
index 1c810509add23fbf92c2df1c5980097a75359d38..f5fa7f4652cc82cb7b01d65462b5ba22d42ec5ab 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -11,6 +11,11 @@ Get a distribution file
         The web site also has links to RPM and Debian .deb Linux packages,
         which may be convenient for some users.
 
         The web site also has links to RPM and Debian .deb Linux packages,
         which may be convenient for some users.
 
+Quick Test Drive
+    If you want to do a quick test of perltidy without doing any
+    installation, get a .tar.gz or a .zip source file and see the section
+    below "Method 2: Installation as a single binary script".
+
 Uninstall older versions
     In certain circumstances, it is best to remove an older version of
     perltidy before installing the latest version. These are:
 Uninstall older versions
     In certain circumstances, it is best to remove an older version of
     perltidy before installing the latest version. These are:
@@ -60,18 +65,26 @@ Two Installation Methods - Overview
         install" step.
 
     Method 2: Installation as a single binary script
         install" step.
 
     Method 2: Installation as a single binary script
-        An alternative method is possible which avoids installing modules.
-        This method can be used to quickly test perltidy to see if it will
-        be useful, without doing a full installation. Also, this might be
-        helpful on a system for which the Makefile.PL method does not work,
-        or if you are temporarily a guest on some system.
+        If you just want to take perltidy for a quick test drive without
+        installing it, or are having trouble installing modules, you can
+        bundle it all in one independent executable script. This might also
+        be helpful on a system for which the Makefile.PL method does not
+        work, or if you are temporarily a guest on some system, or if you
+        want to try hacking a special version of perltidy without messing up
+        your regular version.
 
 
-        The command to do this is
+        You just need to uncompress the source distribution, cd down into
+        it, and enter the command:
 
                 perl pm2pl
 
         which will combine the pieces of perltidy into a single script named
 
                 perl pm2pl
 
         which will combine the pieces of perltidy into a single script named
-        perltidy in the current directory. This script should be functional.
+        perltidy in the current directory. This script should be fully
+        functional. Try it out on a handy perl script, for example
+
+          perl perltidy Makefile.PL
+
+        This should create Makefile.PL.tdy.
 
     After Installation
         After installation by either method, verify that the installation
 
     After Installation
         After installation by either method, verify that the installation
index a7d7a54824f1f13bffbcbe0befb3aa90aa4c7cf2..a1e0a49b149a6ba61d5ae052cd4473589a3ee902 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -22,11 +22,12 @@ examples/bbtidy.pl
 examples/ex_mp.pl
 examples/lextest
 examples/find_naughty.pl
 examples/ex_mp.pl
 examples/lextest
 examples/find_naughty.pl
+examples/perltidyrc_dump.pl
 examples/perlcomment.pl
 examples/perllinetype.pl
 examples/perlmask.pl
 examples/perlxmltok.pl
 examples/perlcomment.pl
 examples/perllinetype.pl
 examples/perlmask.pl
 examples/perlxmltok.pl
-examples/perltidy.bat
+examples/pt.bat
 examples/testfa.t
 examples/testff.t
 lib/Perl/Tidy.pm
 examples/testfa.t
 examples/testff.t
 lib/Perl/Tidy.pm
@@ -34,3 +35,4 @@ pm2pl
 t/test.t
 t/testsa.t
 t/testss.t
 t/test.t
 t/testsa.t
 t/testss.t
+META.yml                                 Module meta-data (added by MakeMaker)
diff --git a/META.yml b/META.yml
new file mode 100644 (file)
index 0000000..7718427
--- /dev/null
+++ b/META.yml
@@ -0,0 +1,10 @@
+# http://module-build.sourceforge.net/META-spec.html
+#XXXXXXX This is a prototype!!!  It will change in the future!!! XXXXX#
+name:         Perl-Tidy
+version:      20060614
+version_from: lib/Perl/Tidy.pm
+installdirs:  site
+requires:
+
+distribution_type: module
+generated_by: ExtUtils::MakeMaker version 6.17
diff --git a/README b/README
index 81e376c9d21c752dac150f02c856f0167e56c135..60d1143bbf7113a9267b665f4537f958cf6383a6 100644 (file)
--- a/README
+++ b/README
@@ -10,19 +10,14 @@ PREREQUISITES
     (You can find your version with "perl -v"). However, some systems this
     old may have problems, particularly Windows versions.
 
     (You can find your version with "perl -v"). However, some systems this
     old may have problems, particularly Windows versions.
 
-    This this release was successfully tested on a 5.004_04 linux
-    distribution (1997) and a 5.005_03 Windows version (ActiveState build
-    522, 1999).
-
     The following modules are not required, but perltidy may use them if
     detected:
 
     The following modules are not required, but perltidy may use them if
     detected:
 
-      Win32    will be used to help identify a Windows system if detected
       HTML::Entities  will be used to encode HTML entities if detected
       Pod::Html will be used to format pod text
 
     The total disk space needed after removing the installation directory
       HTML::Entities  will be used to encode HTML entities if detected
       Pod::Html will be used to format pod text
 
     The total disk space needed after removing the installation directory
-    will about 1 Mb.
+    will about 2 Mb.
 
 DOWNLOAD
     There are two source distribution files:
 
 DOWNLOAD
     There are two source distribution files:
@@ -42,7 +37,8 @@ INSTALLATION
      make test
      make install
 
      make test
      make install
 
-    The INSTALL file has additional installation notes.
+    The INSTALL file has additional installation notes, and tells how to use
+    perltidy without doing an installation.
 
 WHAT NEXT
     Please see the CHANGES file for notices of any recent updates.
 
 WHAT NEXT
     Please see the CHANGES file for notices of any recent updates.
diff --git a/TODO b/TODO
index 9c3ef3052cb0701db7d2f409c411ab8650177c28..463f148d392d54e51a073fba698b5a7de6992f84 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,17 +1,34 @@
 Perltidy TODO List
 Perltidy TODO List
-    This is a "wish-list" of features to add and things to do. All of these
-    are of interest, but there is no particular schedule for implementing
-    them.
+    This is a partial "wish-list" of features to add and things to do. All
+    of these are of interest, but there is no particular schedule for
+    implementing them.
 
   Improved Vertical Alignment
     There are many opportunities for improving vertical alignment.
 
 
   Improved Vertical Alignment
     There are many opportunities for improving vertical alignment.
 
+  More options for controling placement of opening/closing tokens
+    Many have requested even more options to control opening and closing
+    token placement.
+
   improved ?: formatting
     An indentation level should be associated with ?: statements. This will
     make nested ?: statements more readable.
 
   improved ?: formatting
     An indentation level should be associated with ?: statements. This will
     make nested ?: statements more readable.
 
-  Recursive file processing
-    A -r flag might be nice.
+  improved internal if/unless formatting
+    Consider giving internal if/unless statements an additional level of
+    indentation. This would avoid running out of indentation levels.
+    Suggested by Jeff Armstorng. For example, we would like the 'ands' in
+    the following statement to be indented more than the if:
+
+        return $ship->chargeWeapons("phaser-canon")
+          if $encounter->description eq 'klingon'
+          and $ship->firepower >= $encounter->firepower
+          and $location->status ne 'neutral';
+
+  enable -ole under Windows
+    This only works under unix (or cygwin) at present. It doesn't work for
+    Windows versions, such as Active State, because they change line endings
+    that they don't like.
 
   Documentation
     A FAQ is needed to explain some of the more subtle formatting issues,
 
   Documentation
     A FAQ is needed to explain some of the more subtle formatting issues,
@@ -26,3 +43,12 @@ Perltidy TODO List
     multi-line quotes. Then code needs to be written to scan for and markup
     identifiers.
 
     multi-line quotes. Then code needs to be written to scan for and markup
     identifiers.
 
+  Automatic style detection
+    It would be nice to write a program to read a sample of perl code and
+    write an approximate .perltidyrc file for that style.
+
+Things which have been suggested but will not be done
+  Recursive file processing
+    A -r flag might be nice, but this is probably best handled by an
+    exterior shell script.
+
index 66c16b843d773a1082ee371b796ab48b804c499f..24870fdc9d5d81f9a8195f1f7249a9aceb5764b8 100755 (executable)
@@ -153,8 +153,8 @@ Options may not be bundled together.  In other words, options B<-q> and
 B<-g> may NOT be entered as B<-qg>.
 
 Option names may be terminated early as long as they are uniquely identified.
 B<-g> may NOT be entered as B<-qg>.
 
 Option names may be terminated early as long as they are uniquely identified.
-For example, instead of B<-dump-token-types>, it would be sufficient to enter
-B<-dump-tok>, or even B<-dump-t>, to uniquely identify this command.
+For example, instead of B<--dump-token-types>, it would be sufficient to enter
+B<--dump-tok>, or even B<--dump-t>, to uniquely identify this command.
 
 =head2 I/O control
 
 
 =head2 I/O control
 
@@ -185,7 +185,7 @@ request outputting to the standard output.  For example,
   perltidy somefile.pl -st >somefile.new.pl
 
 This option may only be used if there is just a single input file.  
   perltidy somefile.pl -st >somefile.new.pl
 
 This option may only be used if there is just a single input file.  
-The default is B<-nst> or B<-nostandard-output>.
+The default is B<-nst> or B<--nostandard-output>.
 
 =item  B<-se>,    B<--standard-error-output>
 
 
 =item  B<-se>,    B<--standard-error-output>
 
@@ -378,7 +378,7 @@ does its own checking, but this option employs perl to get a "second
 opinion".
 
 If perl reports errors in the input file, they will not be reported in
 opinion".
 
 If perl reports errors in the input file, they will not be reported in
-the error output unless the B<-warning-output> flag is given. 
+the error output unless the B<--warning-output> flag is given. 
 
 The default is B<not> to do this type of syntax checking (although
 perltidy will still do as much self-checking as possible).  The reason
 
 The default is B<not> to do this type of syntax checking (although
 perltidy will still do as much self-checking as possible).  The reason
@@ -520,6 +520,7 @@ a C<)>, C<]>, or a non-block C<}>.  Such a line receives:
         aligns with its opening token.
  -cti = 2 one extra indentation level if the line looks like:
         );  or  ];  or  };
         aligns with its opening token.
  -cti = 2 one extra indentation level if the line looks like:
         );  or  ];  or  };
+ -cti = 3 one extra indentation level always
 
 The flags B<-cti=1> and B<-cti=2> work well with the B<-lp> flag (previous
 section).
 
 The flags B<-cti=1> and B<-cti=2> work well with the B<-lp> flag (previous
 section).
@@ -543,9 +544,9 @@ B<cti=1> is constrained to be no more than one indentation level.
 If desired, this control can be applied independently to each of the
 closing container token types.  In fact, B<-cti=n> is merely an
 abbreviation for B<-cpi=n -csbi=n -cbi=n>, where:  
 If desired, this control can be applied independently to each of the
 closing container token types.  In fact, B<-cti=n> is merely an
 abbreviation for B<-cpi=n -csbi=n -cbi=n>, where:  
-B<-cpi> or B<-closing-paren-indentation> controls B<)>'s,
-B<-csbi> or B<-closing-square-bracket-indentation> controls B<]>'s, 
-B<-cbi> or B<-closing-brace-indentation> controls non-block B<}>'s. 
+B<-cpi> or B<--closing-paren-indentation> controls B<)>'s,
+B<-csbi> or B<--closing-square-bracket-indentation> controls B<]>'s, 
+B<-cbi> or B<--closing-brace-indentation> controls non-block B<}>'s. 
 
 =item B<-icp>, B<--indent-closing-paren>
 
 
 =item B<-icp>, B<--indent-closing-paren>
 
@@ -555,8 +556,8 @@ equivalent B<-cti=0>.  They are included for backwards compatability.
 
 =item B<-icb>, B<--indent-closing-brace>
 
 
 =item B<-icb>, B<--indent-closing-brace>
 
-The B<-icb> option leaves a brace which terminates a code block 
-indented with the same indentation as the previous line.  For example,
+The B<-icb> option gives one extra level of indentation to a brace which
+terminates a code block .  For example,
 
         if ($task) {
             yyy();
 
         if ($task) {
             yyy();
@@ -783,11 +784,15 @@ a space takes priority.
 
 It is necessary to have a list of all token types in order to create
 this type of input.  Such a list can be obtained by the command
 
 It is necessary to have a list of all token types in order to create
 this type of input.  Such a list can be obtained by the command
-B<-dump-token-types>.
+B<--dump-token-types>.  Also try the -D flag on a short snippet of code
+and look at the .DEBUG file to see the tokenization. 
 
 
-=item Space between keyword and opening paren
+B<WARNING> Be sure to put these tokens in quotes to avoid having them
+misinterpreted by your command shell.
 
 
-When an opening paren follows a keyword, no space is introduced after the
+=item Space between specific keywords and opening paren
+
+When an opening paren follows a Perl keyword, no space is introduced after the
 keyword, unless it is (by default) one of these:
 
    my local our and or eq ne if else elsif until unless 
 keyword, unless it is (by default) one of these:
 
    my local our and or eq ne if else elsif until unless 
@@ -804,6 +809,31 @@ where B<s> is a list of keywords (in quotes if necessary).  For example,
   my ( $a, $b, $c ) = @_;    # default
   my( $a, $b, $c ) = @_;     # -nsak="my local our"
 
   my ( $a, $b, $c ) = @_;    # default
   my( $a, $b, $c ) = @_;     # -nsak="my local our"
 
+To put a space after all keywords, see the next item.
+
+=item Space between all keywords and opening parens
+
+When an opening paren follows a function or keyword, no space is introduced
+after the keyword except for the keywords noted in the previous item.  To
+always put a space between a function or keyword and its opening paren,
+use the command:
+
+B<-skp>  or B<--space-keyword-paren>
+
+You will probably also want to use the flag B<-sfp> (next item) too.
+
+=item Space between all function names and opening parens
+
+When an opening paren follows a function the default is not to introduce
+a space.  To cause a space to be introduced use:
+
+B<-sfp>  or B<--space-function-paren>
+
+  myfunc( $a, $b, $c );    # default 
+  myfunc ( $a, $b, $c );   # -sfp
+
+You will probably also want to use the flag B<-skp> (previous item) too.
+
 =item Trimming whitespace around C<qw> quotes
 
 B<-tqw> or B<--trim-qw> provide the default behavior of trimming
 =item Trimming whitespace around C<qw> quotes
 
 B<-tqw> or B<--trim-qw> provide the default behavior of trimming
@@ -854,7 +884,7 @@ If both B<-ibc> and B<-isbc> are set, then B<-isbc> takes priority.
 
 When B<-olc> is set, lines which are full-line (block) comments longer
 than the value B<maximum-line-length> will have their indentation
 
 When B<-olc> is set, lines which are full-line (block) comments longer
 than the value B<maximum-line-length> will have their indentation
-removed.  The default is not to do this.  
+removed.  This is the default; use B<-nolc> to prevent outdenting.
 
 =item B<-msc=n>,  B<--minimum-space-to-comment=n>
 
 
 =item B<-msc=n>,  B<--minimum-space-to-comment=n>
 
@@ -883,7 +913,7 @@ whitespace, they will not be mistaken as hanging side comments.
 A closing side comment is a special comment which perltidy can
 automatically create and place after the closing brace of a code block.
 They can be useful for code maintenance and debugging.  The command
 A closing side comment is a special comment which perltidy can
 automatically create and place after the closing brace of a code block.
 They can be useful for code maintenance and debugging.  The command
-B<-csc> (or B<-closing-side-comments>) adds or updates closing side
+B<-csc> (or B<--closing-side-comments>) adds or updates closing side
 comments.  For example, here is a small code snippet
 
         sub message {
 comments.  For example, here is a small code snippet
 
         sub message {
@@ -919,7 +949,7 @@ commands, B<-csc> and B<-dcsc>:
 
 =over 4
 
 
 =over 4
 
-=item B<-csci=n>, or B<-closing-side-comment-interval=n> 
+=item B<-csci=n>, or B<--closing-side-comment-interval=n> 
 
 where C<n> is the minimum number of lines that a block must have in
 order for a closing side comment to be added.  The default value is
 
 where C<n> is the minimum number of lines that a block must have in
 order for a closing side comment to be added.  The default value is
@@ -938,7 +968,7 @@ C<n=6>.  To illustrate:
 Now the C<if> and C<else> blocks are commented.  However, now this has
 become very cluttered.
 
 Now the C<if> and C<else> blocks are commented.  However, now this has
 become very cluttered.
 
-=item B<-cscp=string>, or B<-closing-side-comment-prefix=string> 
+=item B<-cscp=string>, or B<--closing-side-comment-prefix=string> 
 
 where string is the prefix used before the name of the block type.  The
 default prefix, shown above, is C<## end>.  This string will be added to
 
 where string is the prefix used before the name of the block type.  The
 default prefix, shown above, is C<## end>.  This string will be added to
@@ -947,7 +977,7 @@ order to update, delete, and format them.  Any comment identified as a
 closing side comment will be placed just a single space to the right of
 its closing brace.
 
 closing side comment will be placed just a single space to the right of
 its closing brace.
 
-=item B<-cscl=string>, or B<-closing-side-comment-list-string> 
+=item B<-cscl=string>, or B<--closing-side-comment-list-string> 
 
 where C<string> is a list of block types to be tagged with closing side
 comments.  By default, all code block types preceded by a keyword or
 
 where C<string> is a list of block types to be tagged with closing side
 comments.  By default, all code block types preceded by a keyword or
@@ -960,7 +990,7 @@ affected by any B<-csc> or B<-dcsc> operation:
 
    -cscl="sub : BEGIN END"
 
 
    -cscl="sub : BEGIN END"
 
-=item B<-csct=n>, or B<-closing-side-comment-maximum-text=n> 
+=item B<-csct=n>, or B<--closing-side-comment-maximum-text=n> 
 
 The text appended to certain block types, such as an C<if> block, is
 whatever lies between the keyword introducing the block, such as C<if>,
 
 The text appended to certain block types, such as an C<if> block, is
 whatever lies between the keyword introducing the block, such as C<if>,
@@ -974,7 +1004,7 @@ this).  To illustrate, in the above example, the appended text of the
 first block is C< ( !defined( $_[0] )...>.  The existing limit of
 C<n=20> caused this text to be truncated, as indicated by the C<...>.
 
 first block is C< ( !defined( $_[0] )...>.  The existing limit of
 C<n=20> caused this text to be truncated, as indicated by the C<...>.
 
-=item B<-csce=n>, or B<-closing-side-comment-else-flag=n> 
+=item B<-csce=n>, or B<--closing-side-comment-else-flag=n> 
 
 The default, B<n=0>, places the text of the opening C<if> statement after any
 terminal C<else>.
 
 The default, B<n=0>, places the text of the opening C<if> statement after any
 terminal C<else>.
@@ -987,7 +1017,7 @@ side comments.
 If B<n=1> is used, the results will be the same as B<n=2> whenever the
 resulting line length is less than the maximum allowed.
 
 If B<n=1> is used, the results will be the same as B<n=2> whenever the
 resulting line length is less than the maximum allowed.
 
-=item B<-cscw>, or B<-closing-side-comment-warnings> 
+=item B<-cscw>, or B<--closing-side-comment-warnings> 
 
 This parameter is intended to help make the initial transition to the use of
 closing side comments.  
 
 This parameter is intended to help make the initial transition to the use of
 closing side comments.  
@@ -1109,15 +1139,19 @@ The default is to use B<-sbc>.  This may be deactivated with B<-nsbc>.
 
 This parameter defines the prefix used to identify static block comments
 when the B<-sbc> parameter is set.  The default prefix is C<##>,
 
 This parameter defines the prefix used to identify static block comments
 when the B<-sbc> parameter is set.  The default prefix is C<##>,
-corresponding to C<-sbcp=##>.  The first character must be a C<#>
-symbol, since this must only match comments.  As a simple example, to
+corresponding to C<-sbcp=##>.  The prefix is actually part of a perl 
+pattern used to match lines and it must either begin with C<#> or C<^#>.  
+In the first case a prefix ^\s* will be added to match any leading
+whitespace, while in the second case the pattern will match only
+comments with no leading whitespace.  For example, to
 identify all comments as static block comments, one would use C<-sbcp=#>.
 identify all comments as static block comments, one would use C<-sbcp=#>.
+To identify all left-adjusted comments as static block comments, use C<-sbcp='^#'>.
 
 Please note that B<-sbcp> merely defines the pattern used to identify static
 block comments; it will not be used unless the switch B<-sbc> is set.  Also,
 
 Please note that B<-sbcp> merely defines the pattern used to identify static
 block comments; it will not be used unless the switch B<-sbc> is set.  Also,
-please be aware that this string is used in a perl regular expression which
-identifies these comments, so it must enable a valid regular expression to be
-formed.
+please be aware that since this string is used in a perl regular expression
+which identifies these comments, it must enable a valid regular expression to
+be formed.
 
 =item B<-osbc>, B<--outdent-static-block-comments>
 
 
 =item B<-osbc>, B<--outdent-static-block-comments>
 
@@ -1157,6 +1191,64 @@ expression to be formed.
 =back
 
 
 =back
 
 
+=back
+
+=head2 Skipping Selected Sections of Code
+
+Selected lines of code may be passed verbatim to the output without any
+formatting.  This feature is enabled by default but can be disabled with
+the B<--noformat-skipping> or B<-nfs> flag.  It should be used sparingly to
+avoid littering code with markers, but it might be helpful for working
+around occasional problems.  For example it might be useful for keeping
+the indentation of old commented code unchanged, keeping indentation of
+long blocks of aligned comments unchanged, keeping certain list
+formatting unchanged, or working around a glitch in perltidy.
+
+=over 4
+
+=item B<-fs>,  B<--format-skipping>
+
+This flag, which is enabled by default, causes any code between
+special beginning and ending comment markers to be passed to the
+output without formatting.  The default beginning marker is #<<<
+and the default ending marker is #>>> but they
+may be changed (see next items below).  Additional text may appear on
+these special comment lines provided that it is separated from the
+marker by at least one space.  For example
+
+ #<<<  do not let perltidy touch this
+    my @list = (1,
+                1, 1,
+                1, 2, 1,
+                1, 3, 3, 1,
+                1, 4, 6, 4, 1,);
+ #>>>
+
+The comment markers may be placed at any location that a block comment may
+appear.  If they do not appear to be working, use the -log flag and examine the
+F<.LOG> file.  Use B<-nfs> to disable this feature.
+
+=item B<-fsb=string>,  B<--format-skipping-begin=string>
+
+The B<-fsb=string> parameter may be used to change the beginning marker for
+format skipping.  The default is equivalent to -fsb='#<<<'.  The string that
+you enter must begin with a # and should be in quotes as necessary to get past
+the command shell of your system.  It is actually the leading text of a pattern
+that is constructed by appending a '\s', so you must also include backslashes
+for characters to be taken literally rather than as patterns.  
+
+Some examples show how example strings become patterns:
+
+ -fsb='#\{\{\{' becomes /^#\{\{\{\s/  which matches  #{{{ but not #{{{{
+ -fsb='#\*\*'   becomes /^#\*\*\s/    which matches  #** but not #***
+ -fsb='#\*{2,}' becomes /^#\*{2,}\s/  which matches  #** and #***** 
+
+=item B<-fse=string>,  B<--format-skipping-end=string>
+
+The B<-fsb=string> is the corresponding parameter used to change the
+ending marker for format skipping.  The default is equivalent to
+-fse='#<<<'.  
+
 =back
 
 =head2 Line Break Control
 =back
 
 =head2 Line Break Control
@@ -1259,7 +1351,7 @@ B<-blil='if elsif else'> would apply it to only C<if/elsif/else> blocks.
 
 =item B<-bar>,    B<--opening-brace-always-on-right>     
 
 
 =item B<-bar>,    B<--opening-brace-always-on-right>     
 
-The default style, B<-nbl> places the opening brace on a new
+The default style, B<-nbl> places the opening code block brace on a new
 line if it does not fit on the same line as the opening keyword, like
 this:
 
 line if it does not fit on the same line as the opening keyword, like
 this:
 
@@ -1279,6 +1371,32 @@ flag.  In this case, the above example becomes
 
 A conflict occurs if both B<-bl> and B<-bar> are specified.
 
 
 A conflict occurs if both B<-bl> and B<-bar> are specified.
 
+=item B<-otr>,  B<--opening-token-right> and related flags
+
+The B<-otr> flag is a hint that perltidy should not place a break between a
+comma and an opening token.  For example:
+
+    # default formatting
+    push @{ $self->{$module}{$key} },
+      {
+        accno       => $ref->{accno},
+        description => $ref->{description}
+      };
+
+    # perltidy -otr
+    push @{ $self->{$module}{$key} }, {
+        accno       => $ref->{accno},
+        description => $ref->{description}
+      };
+
+The flag B<-otr> is actually a synonym for three other flags
+which can be used to control parens, hash braces, and square brackets
+separately if desired:
+
+  -opr  or --opening-paren-right
+  -ohbr or --opening-hash-brace-right
+  -osbr or --opening-square-bracket-right
+
 =item Vertical tightness of non-block curly braces, parentheses, and square brackets.
 
 These parameters control what shall be called vertical tightness.  Here are the
 =item Vertical tightness of non-block curly braces, parentheses, and square brackets.
 
 These parameters control what shall be called vertical tightness.  Here are the
@@ -1453,12 +1571,92 @@ possible values of this string, see L<Specifying Block Types>
 
 For example, if we want to just apply this style to C<if>,
 C<elsif>, and C<else> blocks, we could use 
 
 For example, if we want to just apply this style to C<if>,
 C<elsif>, and C<else> blocks, we could use 
-C<perltidy -bli -bbvt -bbvtl='if elsif else'>.
+C<perltidy -bli -bbvt=1 -bbvtl='if elsif else'>.
 
 There is no vertical tightness control for closing block braces; with
 the exception of one-line blocks, they will normally remain on a 
 separate line.
 
 
 There is no vertical tightness control for closing block braces; with
 the exception of one-line blocks, they will normally remain on a 
 separate line.
 
+=item B<-sot>,  B<--stack-opening-token> and related flags
+
+The B<-sot> flag tells perltidy to "stack" opening tokens
+when possible to avoid lines with isolated opening tokens.
+
+For example:
+
+    # default
+    $opt_c = Text::CSV_XS->new(
+        {
+            binary       => 1,
+            sep_char     => $opt_c,
+            always_quote => 1,
+        }
+    );
+
+    # -sot
+    $opt_c = Text::CSV_XS->new( {
+            binary       => 1,
+            sep_char     => $opt_c,
+            always_quote => 1,
+        }
+    );
+
+For detailed control of individual closing tokens the following
+controls can be used:
+
+  -sop  or --stack-opening-paren
+  -sohb or --stack-opening-hash-brace
+  -sosb or --stack-opening-square-bracket
+
+The flag B<-sot> is a synonym for B<-sop -sohb -sosb>.
+
+=item B<-sct>,  B<--stack-closing-token> and related flags
+
+The B<-sct> flag tells perltidy to "stack" closing tokens
+when possible to avoid lines with isolated closing tokens.
+
+For example:
+
+    # default
+    $opt_c = Text::CSV_XS->new(
+        {
+            binary       => 1,
+            sep_char     => $opt_c,
+            always_quote => 1,
+        }
+    );
+
+    # -sct
+    $opt_c = Text::CSV_XS->new(
+        {
+            binary       => 1,
+            sep_char     => $opt_c,
+            always_quote => 1,
+        } );
+
+The B<-sct> flag is somewhat similar to the B<-vtc> flags, and in some
+cases it can give a similar result.  The difference is that the B<-vtc>
+flags try to avoid lines with leading opening tokens by "hiding" them at
+the end of a previous line, whereas the B<-sct> flag merely tries to
+reduce the number of lines with isolated closing tokens by stacking them
+but does not try to hide them.  For example:
+
+    # -vtc=2
+    $opt_c = Text::CSV_XS->new(
+        {
+            binary       => 1,
+            sep_char     => $opt_c,
+            always_quote => 1, } );
+
+For detailed control of the stacking of individual closing tokens the
+following controls can be used:
+
+  -scp  or --stack-closing-paren
+  -schb or --stack-closing-hash-brace
+  -scsb or --stack-closing-square-bracket
+
+The flag B<-sct> is a synonym for B<-scp -schb -scsb>.
+
 =item B<-dnl>,  B<--delete-old-newlines>
 
 By default, perltidy first deletes all old line break locations, and then it
 =item B<-dnl>,  B<--delete-old-newlines>
 
 By default, perltidy first deletes all old line break locations, and then it
@@ -1470,10 +1668,10 @@ points.
 
 By default, perltidy will add line breaks when necessary to create
 continuations of long lines and to improve the script appearance.  Use
 
 By default, perltidy will add line breaks when necessary to create
 continuations of long lines and to improve the script appearance.  Use
-B<-nanl> or B<-noadd-newlines> to prevent any new line breaks.  
+B<-nanl> or B<--noadd-newlines> to prevent any new line breaks.  
 
 This flag does not prevent perltidy from eliminating existing line
 
 This flag does not prevent perltidy from eliminating existing line
-breaks; see B<-freeze-newlines> to completely prevent changes to line
+breaks; see B<--freeze-newlines> to completely prevent changes to line
 break points.
 
 =item Controlling whether perltidy breaks before or after operators
 break points.
 
 =item Controlling whether perltidy breaks before or after operators
@@ -1508,11 +1706,15 @@ math operators C<'+'>, C<'-'>, C<'/'>, and C<'*'>:
 
   -wbb="+ - / *"
 
 
   -wbb="+ - / *"
 
-These commands should work well for most of the token types that
-perltidy uses (use B<--dump-token-types> for a list).  However, for a
-few token types there may be conflicts with hardwired logic which cause
-unexpected results.  One example is curly braces, which should be
-controlled with the parameter B<bl> provided for that purpose.
+These commands should work well for most of the token types that perltidy uses
+(use B<--dump-token-types> for a list).  Also try the -D flag on a short
+snippet of code and look at the .DEBUG file to see the tokenization.  However,
+for a few token types there may be conflicts with hardwired logic which cause
+unexpected results.  One example is curly braces, which should be controlled
+with the parameter B<bl> provided for that purpose.
+
+B<WARNING> Be sure to put these tokens in quotes to avoid having them
+misinterpreted by your command shell.
 
 =back
 
 
 =back
 
@@ -1554,7 +1756,8 @@ to retain the original style, yields
                 1, 4, 6, 4, 1,);
 
 A disadvantage of this flag is that all tables in the file
                 1, 4, 6, 4, 1,);
 
 A disadvantage of this flag is that all tables in the file
-must already be nicely formatted.
+must already be nicely formatted.  For another possibility see
+the -fs flag in L<Skipping Selected Sections of Code>.
 
 =item B<-mft=n>,  B<--maximum-fields-per-table=n>
 
 
 =item B<-mft=n>,  B<--maximum-fields-per-table=n>
 
@@ -1876,8 +2079,8 @@ the B<-npro> option.
 
 =item *
 
 
 =item *
 
-The commands B<-dump-options>, B<-dump-defaults>, B<-dump-long-names>,
-and B<-dump-short-names>, all described below, may all be helpful.
+The commands B<--dump-options>, B<--dump-defaults>, B<--dump-long-names>,
+and B<--dump-short-names>, all described below, may all be helpful.
 
 =back
 
 
 =back
 
@@ -2251,21 +2454,21 @@ located with an internet search for "HTML color tables".
 
 Besides color, two other character attributes may be set: bold, and italics.
 To set a token type to use bold, use the flag
 
 Besides color, two other character attributes may be set: bold, and italics.
 To set a token type to use bold, use the flag
-B<-html-bold-xxxxxx> or B<-hbx>, where B<xxxxxx> or B<x> are the long
+B<--html-bold-xxxxxx> or B<-hbx>, where B<xxxxxx> or B<x> are the long
 or short names from the above table.  Conversely, to set a token type to 
 or short names from the above table.  Conversely, to set a token type to 
-NOT use bold, use B<-nohtml-bold-xxxxxx> or B<-nhbx>.
+NOT use bold, use B<--nohtml-bold-xxxxxx> or B<-nhbx>.
 
 Likewise, to set a token type to use an italic font, use the flag
 
 Likewise, to set a token type to use an italic font, use the flag
-B<-html-italic-xxxxxx> or B<-hix>, where again B<xxxxxx> or B<x> are the
+B<--html-italic-xxxxxx> or B<-hix>, where again B<xxxxxx> or B<x> are the
 long or short names from the above table.  And to set a token type to
 long or short names from the above table.  And to set a token type to
-NOT use italics, use B<-nohtml-italic-xxxxxx> or B<-nhix>.
+NOT use italics, use B<--nohtml-italic-xxxxxx> or B<-nhix>.
 
 For example, to use bold braces and lime color, non-bold, italics keywords the
 following command would be used:
 
        perltidy -html -hbs -hck=00FF00 -nhbk -hik somefile.pl
 
 
 For example, to use bold braces and lime color, non-bold, italics keywords the
 following command would be used:
 
        perltidy -html -hbs -hck=00FF00 -nhbk -hik somefile.pl
 
-The background color can be specified with B<-html-color-background=n>,
+The background color can be specified with B<--html-color-background=n>,
 or B<-hcbg=n> for short, where n is a 6 character hex RGB value.  The
 default color of text is the value given to B<punctuation>, which is
 black as a default.
 or B<-hcbg=n> for short, where n is a 6 character hex RGB value.  The
 default color of text is the value given to B<punctuation>, which is
 black as a default.
@@ -2325,11 +2528,12 @@ dot is added, and the backup file will be F<somefile.pl~>  .
 The following list shows all short parameter names which allow a prefix
 'n' to produce the negated form:
 
 The following list shows all short parameter names which allow a prefix
 'n' to produce the negated form:
 
-    D anl asc aws b bbb bbc bbs bli boc bok bol bot syn ce csc 
-    dac dbc dcsc dnl dws dp dpro dsm dsc ddf dln dop dsn dtt dwls dwrs 
-    f fll frm hsc html ibc icb icp iob isbc lp log lal x lsl ple pod bl 
-    sbl okw ola oll ple pvl q opt sbc sfs ssc sts se st sob 
-    t tac tbc toc tp tsc tqw w
+ D    anl asc  aws  b    bbb bbc bbs  bl   bli  boc bok  bol  bot  ce
+ csc  dac dbc  dcsc ddf  dln dnl dop  dp   dpro dsc dsm  dsn  dtt  dwls
+ dwrs dws f    fll  frm  fs  hsc html ibc  icb  icp iob  isbc lal  log
+ lp   lsl ohbr okw  ola  oll opr opt  osbr otr  ple ple  pod  pvl  q
+ sbc  sbl schb scp  scsb sct se  sfp  sfs  skp  sob sohb sop  sosb sot
+ ssc  st  sts  syn  t    tac tbc toc  tp   tqw  tsc w    x
 
 Equivalently, the prefix 'no' or 'no-' on the corresponding long names may be
 used.
 
 Equivalently, the prefix 'no' or 'no-' on the corresponding long names may be
 used.
@@ -2403,7 +2607,7 @@ perlstyle(1), Perl::Tidy(3)
 
 =head1 VERSION
 
 
 =head1 VERSION
 
-This man page documents perltidy version 20031021.
+This man page documents perltidy version 20060614.
 
 =head1 CREDITS
 
 
 =head1 CREDITS
 
@@ -2428,7 +2632,7 @@ see the CHANGES file.
 
 =head1 COPYRIGHT
 
 
 =head1 COPYRIGHT
 
-Copyright (c) 2000-2003 by Steve Hancock
+Copyright (c) 2000-2006 by Steve Hancock
 
 =head1 LICENSE
 
 
 =head1 LICENSE
 
index 4e5e0608798b66de2ab4232aba23daea358d1aa9..9143d674984820f43fc18fc3b9fce7fb1a303667 100644 (file)
@@ -1,3 +1,9 @@
+perltidy (20060616-1) unstable; urgency=low
+
+  * New upstream release
+
+ -- Don Armstrong <don@debian.org>  Fri, 23 Jun 2006 13:23:08 -0700
+
 perltidy (20031021-2) unstable; urgency=low
 
   * New maintainer adopting this package (closes: #206884)
 perltidy (20031021-2) unstable; urgency=low
 
   * New maintainer adopting this package (closes: #206884)
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..bf0d87a
--- /dev/null
@@ -0,0 +1 @@
+4
\ No newline at end of file
index 9bd42ccad0a0095af816eac152d51eba24adf27e..2c8db7c25a57f02d32bb0b9a4fce7403ff152bae 100644 (file)
@@ -1,9 +1,9 @@
 Source: perltidy
 Source: perltidy
-Section: interpreters
+Section: devel
 Priority: optional
 Priority: optional
-Maintainer: Don Armstrong <don@donarmstrong.com>
-Build-Depends: debhelper (>= 3.0.5), perl (>= 5.6.0-16)
-Standards-Version: 3.6.1
+Maintainer: Don Armstrong <don@debian.org>
+Build-Depends: debhelper (>= 4), perl (>= 5.6.0-16)
+Standards-Version: 3.7.2
 
 Package: perltidy
 Architecture: all
 
 Package: perltidy
 Architecture: all
index 5241f1b7d24800cefdd1f4e90ef6821063016099..37629636840a0910fc12e0eb6e38594023f77d81 100755 (executable)
@@ -6,7 +6,6 @@
 
 # Uncomment this to turn on verbose mode.
 #export DH_VERBOSE=1
 
 # Uncomment this to turn on verbose mode.
 #export DH_VERBOSE=1
-export DH_COMPAT=3
 
 PACKAGE=$(shell dh_listpackages)
 
 
 PACKAGE=$(shell dh_listpackages)
 
index 6e19a1aa9b5d38d62d3c9ef615744a783f61e091..9a5bcffe30fb56018515f31e319dc12154b53793 100644 (file)
@@ -1,7 +1,7 @@
 All of the documentation for perltidy can be found at 
 http://perltidy.sourceforge.net
 
 All of the documentation for perltidy can be found at 
 http://perltidy.sourceforge.net
 
-The man page is in pod formatt appended to the script bin/perltidy.
+The man page is in pod format appended to the script bin/perltidy.
 
 The man page for use of the module Perl::Tidy.pm is appended to that file.
 
 
 The man page for use of the module Perl::Tidy.pm is appended to that file.
 
index 285b39da9009f086bde43d3bc7be0805728d5a02..fa71edd6c1470578c10daeb4bea681e222c40a41 100644 (file)
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man v1.3, Pod::Parser v1.13
+.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.3
 .\"
 .\" Standard preamble:
 .\" ========================================================================
 .\"
 .\" Standard preamble:
 .\" ========================================================================
@@ -21,7 +21,6 @@
 ..
 .de Ve \" End verbatim text
 .ft R
 ..
 .de Ve \" End verbatim text
 .ft R
-
 .fi
 ..
 .\" Set up some character translations and predefined strings.  \*(-- will
 .fi
 ..
 .\" Set up some character translations and predefined strings.  \*(-- will
 .\" ========================================================================
 .\"
 .IX Title "PERLTIDY 1"
 .\" ========================================================================
 .\"
 .IX Title "PERLTIDY 1"
-.TH PERLTIDY 1 "2003-10-22" "perl v5.6.1" "User Contributed Perl Documentation"
-.UC
+.TH PERLTIDY 1 "2006-06-13" "perl v5.8.7" "User Contributed Perl Documentation"
 .SH "NAME"
 perltidy \- a perl script indenter and reformatter
 .SH "SYNOPSIS"
 .SH "NAME"
 perltidy \- a perl script indenter and reformatter
 .SH "SYNOPSIS"
@@ -139,8 +137,8 @@ perltidy \- a perl script indenter and reformatter
 .Vb 5
 \&    perltidy [ options ] file1 file2 file3 ...
 \&            (output goes to file1.tdy, file2.tdy, file3.tdy, ...)
 .Vb 5
 \&    perltidy [ options ] file1 file2 file3 ...
 \&            (output goes to file1.tdy, file2.tdy, file3.tdy, ...)
-\&    perltidy [ options ] file1 -o outfile
-\&    perltidy [ options ] file1 -st >outfile
+\&    perltidy [ options ] file1 \-o outfile
+\&    perltidy [ options ] file1 \-st >outfile
 \&    perltidy [ options ] <infile >outfile
 .Ve
 .SH "DESCRIPTION"
 \&    perltidy [ options ] <infile >outfile
 .Ve
 .SH "DESCRIPTION"
@@ -169,6 +167,7 @@ formatter which is described in \*(L"\s-1HTML\s0 \s-1OPTIONS\s0\*(R".
 .Vb 1
 \&  perltidy somefile.pl
 .Ve
 .Vb 1
 \&  perltidy somefile.pl
 .Ve
+.PP
 This will produce a file \fIsomefile.pl.tdy\fR containing the script reformatted
 using the default options, which approximate the style suggested in 
 \&\fIperlstyle\fR\|(1).  Perltidy never changes the input file.
 This will produce a file \fIsomefile.pl.tdy\fR containing the script reformatted
 using the default options, which approximate the style suggested in 
 \&\fIperlstyle\fR\|(1).  Perltidy never changes the input file.
@@ -176,82 +175,94 @@ using the default options, which approximate the style suggested in
 .Vb 1
 \&  perltidy *.pl
 .Ve
 .Vb 1
 \&  perltidy *.pl
 .Ve
+.PP
 Execute perltidy on all \fI.pl\fR files in the current directory with the
 default options.  The output will be in files with an appended \fI.tdy\fR
 extension.  For any file with an error, there will be a file with extension
 \&\fI.ERR\fR.
 .PP
 .Vb 1
 Execute perltidy on all \fI.pl\fR files in the current directory with the
 default options.  The output will be in files with an appended \fI.tdy\fR
 extension.  For any file with an error, there will be a file with extension
 \&\fI.ERR\fR.
 .PP
 .Vb 1
-\&  perltidy -b file1.pl file2.pl
+\&  perltidy \-b file1.pl file2.pl
 .Ve
 .Ve
+.PP
 Modify \fIfile1.pl\fR and \fIfile1.pl\fR in place, and backup the originals to
 \&\fIfile1.pl.bak\fR and \fIfile2.pl.bak\fR.  If \fIfile1.pl.bak\fR and/or \fIfile2.pl.bak\fR
 already exist, they will be overwritten.
 .PP
 .Vb 1
 Modify \fIfile1.pl\fR and \fIfile1.pl\fR in place, and backup the originals to
 \&\fIfile1.pl.bak\fR and \fIfile2.pl.bak\fR.  If \fIfile1.pl.bak\fR and/or \fIfile2.pl.bak\fR
 already exist, they will be overwritten.
 .PP
 .Vb 1
-\&  perltidy -gnu somefile.pl
+\&  perltidy \-gnu somefile.pl
 .Ve
 .Ve
+.PP
 Execute perltidy on file \fIsomefile.pl\fR with a style which approximates the
 \&\s-1GNU\s0 Coding Standards for C programs.  The output will be \fIsomefile.pl.tdy\fR.
 .PP
 .Vb 1
 Execute perltidy on file \fIsomefile.pl\fR with a style which approximates the
 \&\s-1GNU\s0 Coding Standards for C programs.  The output will be \fIsomefile.pl.tdy\fR.
 .PP
 .Vb 1
-\&  perltidy -i=3 somefile.pl
+\&  perltidy \-i=3 somefile.pl
 .Ve
 .Ve
+.PP
 Execute perltidy on file \fIsomefile.pl\fR, with 3 columns for each level of
 indentation (\fB\-i=3\fR) instead of the default 4 columns.  There will not be any
 tabs in the reformatted script, except for any which already exist in comments,
 pod documents, quotes, and here documents.  Output will be \fIsomefile.pl.tdy\fR. 
 .PP
 .Vb 1
 Execute perltidy on file \fIsomefile.pl\fR, with 3 columns for each level of
 indentation (\fB\-i=3\fR) instead of the default 4 columns.  There will not be any
 tabs in the reformatted script, except for any which already exist in comments,
 pod documents, quotes, and here documents.  Output will be \fIsomefile.pl.tdy\fR. 
 .PP
 .Vb 1
-\&  perltidy -i=3 -et=8 somefile.pl
+\&  perltidy \-i=3 \-et=8 somefile.pl
 .Ve
 .Ve
+.PP
 Same as the previous example, except that leading whitespace will
 be entabbed with one tab character per 8 spaces.
 .PP
 .Vb 1
 Same as the previous example, except that leading whitespace will
 be entabbed with one tab character per 8 spaces.
 .PP
 .Vb 1
-\&  perltidy -ce -l=72 somefile.pl
+\&  perltidy \-ce \-l=72 somefile.pl
 .Ve
 .Ve
+.PP
 Execute perltidy on file \fIsomefile.pl\fR with all defaults except use \*(L"cuddled
 elses\*(R" (\fB\-ce\fR) and a maximum line length of 72 columns (\fB\-l=72\fR) instead of
 the default 80 columns.  
 .PP
 .Vb 1
 Execute perltidy on file \fIsomefile.pl\fR with all defaults except use \*(L"cuddled
 elses\*(R" (\fB\-ce\fR) and a maximum line length of 72 columns (\fB\-l=72\fR) instead of
 the default 80 columns.  
 .PP
 .Vb 1
-\&  perltidy -g somefile.pl
+\&  perltidy \-g somefile.pl
 .Ve
 .Ve
+.PP
 Execute perltidy on file \fIsomefile.pl\fR and save a log file \fIsomefile.pl.LOG\fR
 which shows the nesting of braces, parentheses, and square brackets at
 the start of every line.
 .PP
 .Vb 1
 Execute perltidy on file \fIsomefile.pl\fR and save a log file \fIsomefile.pl.LOG\fR
 which shows the nesting of braces, parentheses, and square brackets at
 the start of every line.
 .PP
 .Vb 1
-\&  perltidy -html somefile.pl
+\&  perltidy \-html somefile.pl
 .Ve
 .Ve
+.PP
 This will produce a file \fIsomefile.pl.html\fR containing the script with
 html markup.  The output file will contain an embedded style sheet in
 the <\s-1HEAD\s0> section which may be edited to change the appearance.
 .PP
 .Vb 1
 This will produce a file \fIsomefile.pl.html\fR containing the script with
 html markup.  The output file will contain an embedded style sheet in
 the <\s-1HEAD\s0> section which may be edited to change the appearance.
 .PP
 .Vb 1
-\&  perltidy -html -css=mystyle.css somefile.pl
+\&  perltidy \-html \-css=mystyle.css somefile.pl
 .Ve
 .Ve
+.PP
 This will produce a file \fIsomefile.pl.html\fR containing the script with
 html markup.  This output file will contain a link to a separate style
 sheet file \fImystyle.css\fR.  If the file \fImystyle.css\fR does not exist,
 it will be created.  If it exists, it will not be overwritten.
 .PP
 .Vb 1
 This will produce a file \fIsomefile.pl.html\fR containing the script with
 html markup.  This output file will contain a link to a separate style
 sheet file \fImystyle.css\fR.  If the file \fImystyle.css\fR does not exist,
 it will be created.  If it exists, it will not be overwritten.
 .PP
 .Vb 1
-\&  perltidy -html -pre somefile.pl
+\&  perltidy \-html \-pre somefile.pl
 .Ve
 .Ve
+.PP
 Write an html snippet with only the \s-1PRE\s0 section to \fIsomefile.pl.html\fR.
 This is useful when code snippets are being formatted for inclusion in a
 larger web page.  No style sheet will be written in this case.  
 .PP
 .Vb 1
 Write an html snippet with only the \s-1PRE\s0 section to \fIsomefile.pl.html\fR.
 This is useful when code snippets are being formatted for inclusion in a
 larger web page.  No style sheet will be written in this case.  
 .PP
 .Vb 1
-\&  perltidy -html -ss >mystyle.css
+\&  perltidy \-html \-ss >mystyle.css
 .Ve
 .Ve
+.PP
 Write a style sheet to \fImystyle.css\fR and exit.
 .PP
 .Vb 1
 Write a style sheet to \fImystyle.css\fR and exit.
 .PP
 .Vb 1
-\&  perltidy -html -frm mymodule.pm
+\&  perltidy \-html \-frm mymodule.pm
 .Ve
 .Ve
+.PP
 Write html with a frame holding a table of contents and the source code.  The
 output files will be \fImymodule.pm.html\fR (the frame), \fImymodule.pm.toc.html\fR
 (the table of contents), and \fImymodule.pm.src.html\fR (the source code).
 Write html with a frame holding a table of contents and the source code.  The
 output files will be \fImymodule.pm.html\fR (the frame), \fImymodule.pm.toc.html\fR
 (the table of contents), and \fImymodule.pm.src.html\fR (the source code).
@@ -278,8 +289,8 @@ Options may not be bundled together.  In other words, options \fB\-q\fR and
 \&\fB\-g\fR may \s-1NOT\s0 be entered as \fB\-qg\fR.
 .PP
 Option names may be terminated early as long as they are uniquely identified.
 \&\fB\-g\fR may \s-1NOT\s0 be entered as \fB\-qg\fR.
 .PP
 Option names may be terminated early as long as they are uniquely identified.
-For example, instead of \fB\-dump\-token\-types\fR, it would be sufficient to enter
-\&\fB\-dump\-tok\fR, or even \fB\-dump\-t\fR, to uniquely identify this command.
+For example, instead of \fB\-\-dump\-token\-types\fR, it would be sufficient to enter
+\&\fB\-\-dump\-tok\fR, or even \fB\-\-dump\-t\fR, to uniquely identify this command.
 .Sh "I/O control"
 .IX Subsection "I/O control"
 The following parameters concern the files which are read and written.
 .Sh "I/O control"
 .IX Subsection "I/O control"
 The following parameters concern the files which are read and written.
@@ -300,10 +311,11 @@ standard output device, so a special flag, \fB\-st\fR, is required to
 request outputting to the standard output.  For example,
 .Sp
 .Vb 1
 request outputting to the standard output.  For example,
 .Sp
 .Vb 1
-\&  perltidy somefile.pl -st >somefile.new.pl
+\&  perltidy somefile.pl \-st >somefile.new.pl
 .Ve
 .Ve
+.Sp
 This option may only be used if there is just a single input file.  
 This option may only be used if there is just a single input file.  
-The default is \fB\-nst\fR or \fB\-nostandard\-output\fR.
+The default is \fB\-nst\fR or \fB\-\-nostandard\-output\fR.
 .IP "\fB\-se\fR,    \fB\-\-standard\-error\-output\fR" 4
 .IX Item "-se,    --standard-error-output"
 If perltidy detects an error when processing file \fIsomefile.pl\fR, its
 .IP "\fB\-se\fR,    \fB\-\-standard\-error\-output\fR" 4
 .IX Item "-se,    --standard-error-output"
 If perltidy detects an error when processing file \fIsomefile.pl\fR, its
@@ -329,8 +341,9 @@ to add one if it is missing.
 For example
 .Sp
 .Vb 1
 For example
 .Sp
 .Vb 1
-\& perltidy somefile.pl -opath=/tmp/
+\& perltidy somefile.pl \-opath=/tmp/
 .Ve
 .Ve
+.Sp
 will produce \fI/tmp/somefile.pl.tdy\fR.  Otherwise, \fIsomefile.pl.tdy\fR will
 appear in whatever directory contains \fIsomefile.pl\fR.
 .Sp
 will produce \fI/tmp/somefile.pl.tdy\fR.  Otherwise, \fIsomefile.pl.tdy\fR will
 appear in whatever directory contains \fIsomefile.pl\fR.
 .Sp
@@ -366,8 +379,9 @@ For example, if you use a vi-style editor, such as vim, you may execute
 perltidy as a filter from within the editor using something like
 .Sp
 .Vb 1
 perltidy as a filter from within the editor using something like
 .Sp
 .Vb 1
-\& :n1,n2!perltidy -q
+\& :n1,n2!perltidy \-q
 .Ve
 .Ve
+.Sp
 where \f(CW\*(C`n1,n2\*(C'\fR represents the selected text.  Without the \fB\-q\fR flag,
 any error message may mess up your screen, so be prepared to use your
 \&\*(L"undo\*(R" key.
 where \f(CW\*(C`n1,n2\*(C'\fR represents the selected text.  Without the \fB\-q\fR flag,
 any error message may mess up your screen, so be prepared to use your
 \&\*(L"undo\*(R" key.
@@ -410,8 +424,9 @@ name of .perltidyrc.  There must not be a space on either side of the
 \&'=' sign.  For example, the line
 .Sp
 .Vb 1
 \&'=' sign.  For example, the line
 .Sp
 .Vb 1
-\&   perltidy -pro=testcfg
+\&   perltidy \-pro=testcfg
 .Ve
 .Ve
+.Sp
 would cause file \fItestcfg\fR to be used instead of the 
 default \fI.perltidyrc\fR.
 .IP "\fB\-opt\fR,   \fB\-\-show\-options\fR" 4
 would cause file \fItestcfg\fR to be used instead of the 
 default \fI.perltidyrc\fR.
 .IP "\fB\-opt\fR,   \fB\-\-show\-options\fR" 4
@@ -476,7 +491,7 @@ does its own checking, but this option employs perl to get a \*(L"second
 opinion\*(R".
 .Sp
 If perl reports errors in the input file, they will not be reported in
 opinion\*(R".
 .Sp
 If perl reports errors in the input file, they will not be reported in
-the error output unless the \fB\-warning\-output\fR flag is given. 
+the error output unless the \fB\-\-warning\-output\fR flag is given. 
 .Sp
 The default is \fBnot\fR to do this type of syntax checking (although
 perltidy will still do as much self-checking as possible).  The reason
 .Sp
 The default is \fBnot\fR to do this type of syntax checking (although
 perltidy will still do as much self-checking as possible).  The reason
@@ -534,15 +549,17 @@ Continuation indentation is extra indentation spaces applied when
 a long line is broken.  The default is n=2, illustrated here:
 .Sp
 .Vb 2
 a long line is broken.  The default is n=2, illustrated here:
 .Sp
 .Vb 2
-\& my $level =   # -ci=2      
+\& my $level =   # \-ci=2      
 \&   ( $max_index_to_go >= 0 ) ? $levels_to_go[0] : $last_output_level;
 .Ve
 \&   ( $max_index_to_go >= 0 ) ? $levels_to_go[0] : $last_output_level;
 .Ve
+.Sp
 The same example, with n=0, is a little harder to read:
 .Sp
 .Vb 2
 The same example, with n=0, is a little harder to read:
 .Sp
 .Vb 2
-\& my $level =   # -ci=0    
+\& my $level =   # \-ci=0    
 \& ( $max_index_to_go >= 0 ) ? $levels_to_go[0] : $last_output_level;
 .Ve
 \& ( $max_index_to_go >= 0 ) ? $levels_to_go[0] : $last_output_level;
 .Ve
+.Sp
 The value given to \fB\-ci\fR is also used by some commands when a small
 space is required.  Examples are commands for outdenting labels,
 \&\fB\-ola\fR, and control keywords, \fB\-okw\fR.  
 The value given to \fB\-ci\fR is also used by some commands when a small
 space is required.  Examples are commands for outdenting labels,
 \&\fB\-ola\fR, and control keywords, \fB\-okw\fR.  
@@ -569,18 +586,20 @@ is specified with \fB\-i=n\fR.  Here is a small list formatted in this way:
 \&        'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
 \&    );
 .Ve
 \&        'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
 \&    );
 .Ve
+.Sp
 Use the \fB\-lp\fR flag to add extra indentation to cause the data to begin
 past the opening parentheses of a sub call or list, or opening square
 bracket of an anonymous array, or opening curly brace of an anonymous
 hash.  With this option, the above list would become:
 .Sp
 .Vb 5
 Use the \fB\-lp\fR flag to add extra indentation to cause the data to begin
 past the opening parentheses of a sub call or list, or opening square
 bracket of an anonymous array, or opening curly brace of an anonymous
 hash.  With this option, the above list would become:
 .Sp
 .Vb 5
-\&    # perltidy -lp
+\&    # perltidy \-lp
 \&    @month_of_year = (
 \&                       'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
 \&                       'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
 \&    );
 .Ve
 \&    @month_of_year = (
 \&                       'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
 \&                       'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
 \&    );
 .Ve
+.Sp
 If the available line length (see \fB\-l=n\fR ) does not permit this much 
 space, perltidy will use less.   For alternate placement of the
 closing paren, see the next section.
 If the available line length (see \fB\-l=n\fR ) does not permit this much 
 space, perltidy will use less.   For alternate placement of the
 closing paren, see the next section.
@@ -605,30 +624,34 @@ hierarchical lists, and these flags may prevent that.
 The \fB\-cti=n\fR flag controls the indentation of a line beginning with 
 a \f(CW\*(C`)\*(C'\fR, \f(CW\*(C`]\*(C'\fR, or a non-block \f(CW\*(C`}\*(C'\fR.  Such a line receives:
 .Sp
 The \fB\-cti=n\fR flag controls the indentation of a line beginning with 
 a \f(CW\*(C`)\*(C'\fR, \f(CW\*(C`]\*(C'\fR, or a non-block \f(CW\*(C`}\*(C'\fR.  Such a line receives:
 .Sp
-.Vb 5
-\& -cti = 0 no extra indentation (default)
-\& -cti = 1 extra indentation such that the closing token
+.Vb 6
+\& \-cti = 0 no extra indentation (default)
+\& \-cti = 1 extra indentation such that the closing token
 \&        aligns with its opening token.
 \&        aligns with its opening token.
-\& -cti = 2 one extra indentation level if the line looks like:
+\& \-cti = 2 one extra indentation level if the line looks like:
 \&        );  or  ];  or  };
 \&        );  or  ];  or  };
+\& \-cti = 3 one extra indentation level always
 .Ve
 .Ve
+.Sp
 The flags \fB\-cti=1\fR and \fB\-cti=2\fR work well with the \fB\-lp\fR flag (previous
 section).
 .Sp
 .Vb 5
 The flags \fB\-cti=1\fR and \fB\-cti=2\fR work well with the \fB\-lp\fR flag (previous
 section).
 .Sp
 .Vb 5
-\&    # perltidy -lp -cti=1
+\&    # perltidy \-lp \-cti=1
 \&    @month_of_year = (
 \&                       'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
 \&                       'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
 \&                     );
 .Ve
 \&    @month_of_year = (
 \&                       'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
 \&                       'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
 \&                     );
 .Ve
+.Sp
 .Vb 5
 .Vb 5
-\&    # perltidy -lp -cti=2
+\&    # perltidy \-lp \-cti=2
 \&    @month_of_year = (
 \&                       'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
 \&                       'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
 \&                       );
 .Ve
 \&    @month_of_year = (
 \&                       'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
 \&                       'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
 \&                       );
 .Ve
+.Sp
 These flags are merely hints to the formatter and they may not always be
 followed.  In particular, if \-lp is not being used, the indentation for
 \&\fBcti=1\fR is constrained to be no more than one indentation level.
 These flags are merely hints to the formatter and they may not always be
 followed.  In particular, if \-lp is not being used, the indentation for
 \&\fBcti=1\fR is constrained to be no more than one indentation level.
@@ -636,9 +659,9 @@ followed.  In particular, if \-lp is not being used, the indentation for
 If desired, this control can be applied independently to each of the
 closing container token types.  In fact, \fB\-cti=n\fR is merely an
 abbreviation for \fB\-cpi=n \-csbi=n \-cbi=n\fR, where:  
 If desired, this control can be applied independently to each of the
 closing container token types.  In fact, \fB\-cti=n\fR is merely an
 abbreviation for \fB\-cpi=n \-csbi=n \-cbi=n\fR, where:  
-\&\fB\-cpi\fR or \fB\-closing\-paren\-indentation\fR controls \fB)\fR's,
-\&\fB\-csbi\fR or \fB\-closing\-square\-bracket\-indentation\fR controls \fB]\fR's, 
-\&\fB\-cbi\fR or \fB\-closing\-brace\-indentation\fR controls non-block \fB}\fR's. 
+\&\fB\-cpi\fR or \fB\-\-closing\-paren\-indentation\fR controls \fB)\fR's,
+\&\fB\-csbi\fR or \fB\-\-closing\-square\-bracket\-indentation\fR controls \fB]\fR's, 
+\&\fB\-cbi\fR or \fB\-\-closing\-brace\-indentation\fR controls non-block \fB}\fR's. 
 .IP "\fB\-icp\fR, \fB\-\-indent\-closing\-paren\fR" 4
 .IX Item "-icp, --indent-closing-paren"
 The \fB\-icp\fR flag is equivalent to
 .IP "\fB\-icp\fR, \fB\-\-indent\-closing\-paren\fR" 4
 .IX Item "-icp, --indent-closing-paren"
 The \fB\-icp\fR flag is equivalent to
@@ -646,17 +669,18 @@ The \fB\-icp\fR flag is equivalent to
 equivalent \fB\-cti=0\fR.  They are included for backwards compatability.
 .IP "\fB\-icb\fR, \fB\-\-indent\-closing\-brace\fR" 4
 .IX Item "-icb, --indent-closing-brace"
 equivalent \fB\-cti=0\fR.  They are included for backwards compatability.
 .IP "\fB\-icb\fR, \fB\-\-indent\-closing\-brace\fR" 4
 .IX Item "-icb, --indent-closing-brace"
-The \fB\-icb\fR option leaves a brace which terminates a code block 
-indented with the same indentation as the previous line.  For example,
+The \fB\-icb\fR option gives one extra level of indentation to a brace which
+terminates a code block .  For example,
 .Sp
 .Vb 6
 \&        if ($task) {
 \&            yyy();
 .Sp
 .Vb 6
 \&        if ($task) {
 \&            yyy();
-\&            }    # -icb
+\&            }    # \-icb
 \&        else {
 \&            zzz();
 \&            }
 .Ve
 \&        else {
 \&            zzz();
 \&            }
 .Ve
+.Sp
 The default is not to do this, indicated by \fB\-nicb\fR.
 .IP "\fB\-olq\fR, \fB\-\-outdent\-long\-quotes\fR" 4
 .IX Item "-olq, --outdent-long-quotes"
 The default is not to do this, indicated by \fB\-nicb\fR.
 .IP "\fB\-olq\fR, \fB\-\-outdent\-long\-quotes\fR" 4
 .IX Item "-olq, --outdent-long-quotes"
@@ -683,6 +707,7 @@ has been set to), if possible.  This is the default.  For example:
 \&            fixit($i);
 \&        }
 .Ve
 \&            fixit($i);
 \&        }
 .Ve
+.Sp
 Use \fB\-nola\fR to not outdent labels. 
 .IP "Outdenting Keywords" 4
 .IX Item "Outdenting Keywords"
 Use \fB\-nola\fR to not outdent labels. 
 .IP "Outdenting Keywords" 4
 .IX Item "Outdenting Keywords"
@@ -708,6 +733,7 @@ For example, using \f(CW\*(C`perltidy \-okw\*(C'\fR on the previous example give
 \&            fixit($i);
 \&        }
 .Ve
 \&            fixit($i);
 \&        }
 .Ve
+.Sp
 The default is not to do this.  
 .IP "Specifying Outdented Keywords: \fB\-okwl=string\fR,  \fB\-\-outdent\-keyword\-list=string\fR" 4
 .IX Item "Specifying Outdented Keywords: -okwl=string,  --outdent-keyword-list=string"
 The default is not to do this.  
 .IP "Specifying Outdented Keywords: \fB\-okwl=string\fR,  \fB\-\-outdent\-keyword\-list=string\fR" 4
 .IX Item "Specifying Outdented Keywords: -okwl=string,  --outdent-keyword-list=string"
@@ -747,10 +773,11 @@ parens.  The example below shows the effect of the three possible
 values, 0, 1, and 2:
 .Sp
 .Vb 3
 values, 0, 1, and 2:
 .Sp
 .Vb 3
-\& if ( ( my $len_tab = length( $tabstr ) ) > 0 ) {  # -pt=0
-\& if ( ( my $len_tab = length($tabstr) ) > 0 ) {    # -pt=1 (default)
-\& if ((my $len_tab = length($tabstr)) > 0) {        # -pt=2
+\& if ( ( my $len_tab = length( $tabstr ) ) > 0 ) {  # \-pt=0
+\& if ( ( my $len_tab = length($tabstr) ) > 0 ) {    # \-pt=1 (default)
+\& if ((my $len_tab = length($tabstr)) > 0) {        # \-pt=2
 .Ve
 .Ve
+.Sp
 When n is 0, there is always a space to the right of a '(' and to the left
 of a ')'.  For n=2 there is never a space.  For n=1, the default, there
 is a space unless the quantity within the parens is a single token, such
 When n is 0, there is always a space to the right of a '(' and to the left
 of a ')'.  For n=2 there is never a space.  For n=1, the default, there
 is a space unless the quantity within the parens is a single token, such
@@ -760,26 +787,28 @@ Likewise, the parameter \fB\-sbt=n\fR or \fB\-\-square\-bracket\-tightness=n\fR
 controls the space within square brackets, as illustrated below.
 .Sp
 .Vb 3
 controls the space within square brackets, as illustrated below.
 .Sp
 .Vb 3
-\& $width = $col[ $j + $k ] - $col[ $j ];  # -sbt=0
-\& $width = $col[ $j + $k ] - $col[$j];    # -sbt=1 (default)
-\& $width = $col[$j + $k] - $col[$j];      # -sbt=2
+\& $width = $col[ $j + $k ] \- $col[ $j ];  # \-sbt=0
+\& $width = $col[ $j + $k ] \- $col[$j];    # \-sbt=1 (default)
+\& $width = $col[$j + $k] \- $col[$j];      # \-sbt=2
 .Ve
 .Ve
+.Sp
 Curly braces which do not contain code blocks are controlled by
 the parameter \fB\-bt=n\fR or \fB\-\-brace\-tightness=n\fR. 
 .Sp
 .Vb 3
 Curly braces which do not contain code blocks are controlled by
 the parameter \fB\-bt=n\fR or \fB\-\-brace\-tightness=n\fR. 
 .Sp
 .Vb 3
-\& $obj->{ $parsed_sql->{ 'table' }[0] };    # -bt=0
-\& $obj->{ $parsed_sql->{'table'}[0] };      # -bt=1 (default)
-\& $obj->{$parsed_sql->{'table'}[0]};        # -bt=2
+\& $obj\->{ $parsed_sql\->{ 'table' }[0] };    # \-bt=0
+\& $obj\->{ $parsed_sql\->{'table'}[0] };      # \-bt=1 (default)
+\& $obj\->{$parsed_sql\->{'table'}[0]};        # \-bt=2
 .Ve
 .Ve
+.Sp
 And finally, curly braces which contain blocks of code are controlled by the
 parameter \fB\-bbt=n\fR or \fB\-\-block\-brace\-tightness=n\fR as illustrated in the
 example below.   
 .Sp
 .Vb 3
 And finally, curly braces which contain blocks of code are controlled by the
 parameter \fB\-bbt=n\fR or \fB\-\-block\-brace\-tightness=n\fR as illustrated in the
 example below.   
 .Sp
 .Vb 3
-\& %bf = map { $_ => -M $_ } grep { /\e.deb$/ } dirents '.'; # -bbt=0 (default)
-\& %bf = map { $_ => -M $_ } grep {/\e.deb$/} dirents '.';   # -bbt=1
-\& %bf = map {$_ => -M $_} grep {/\e.deb$/} dirents '.';     # -bbt=2
+\& %bf = map { $_ => \-M $_ } grep { /\e.deb$/ } dirents '.'; # \-bbt=0 (default)
+\& %bf = map { $_ => \-M $_ } grep {/\e.deb$/} dirents '.';   # \-bbt=1
+\& %bf = map {$_ => \-M $_} grep {/\e.deb$/} dirents '.';     # \-bbt=2
 .Ve
 .IP "\fB\-sts\fR,   \fB\-\-space\-terminal\-semicolon\fR" 4
 .IX Item "-sts,   --space-terminal-semicolon"
 .Ve
 .IP "\fB\-sts\fR,   \fB\-\-space\-terminal\-semicolon\fR" 4
 .IX Item "-sts,   --space-terminal-semicolon"
@@ -788,8 +817,8 @@ default is for no such space, and is indicated with \fB\-nsts\fR or
 \&\fB\-\-nospace\-terminal\-semicolon\fR.
 .Sp
 .Vb 2
 \&\fB\-\-nospace\-terminal\-semicolon\fR.
 .Sp
 .Vb 2
-\&        $i = 1 ;     #  -sts
-\&        $i = 1;      #  -nsts   (default)
+\&        $i = 1 ;     #  \-sts
+\&        $i = 1;      #  \-nsts   (default)
 .Ve
 .IP "\fB\-sfs\fR,   \fB\-\-space\-for\-semicolon\fR" 4
 .IX Item "-sfs,   --space-for-semicolon"
 .Ve
 .IP "\fB\-sfs\fR,   \fB\-\-space\-for\-semicolon\fR" 4
 .IX Item "-sfs,   --space-for-semicolon"
@@ -799,8 +828,8 @@ both sides of these special semicolons, and is the default.  Use
 \&\fB\-nsfs\fR or \fB\-\-nospace\-for\-semicolon\fR to deactivate it.
 .Sp
 .Vb 2
 \&\fB\-nsfs\fR or \fB\-\-nospace\-for\-semicolon\fR to deactivate it.
 .Sp
 .Vb 2
-\& for ( @a = @$ap, $u = shift @a ; @a ; $u = $v ) {  # -sfs (default)
-\& for ( @a = @$ap, $u = shift @a; @a; $u = $v ) {    # -nsfs
+\& for ( @a = @$ap, $u = shift @a ; @a ; $u = $v ) {  # \-sfs (default)
+\& for ( @a = @$ap, $u = shift @a; @a; $u = $v ) {    # \-nsfs
 .Ve
 .IP "\fB\-asc\fR,  \fB\-\-add\-semicolons\fR" 4
 .IX Item "-asc,  --add-semicolons"
 .Ve
 .IP "\fB\-asc\fR,  \fB\-\-add\-semicolons\fR" 4
 .IX Item "-asc,  --add-semicolons"
@@ -850,19 +879,22 @@ space on either side of the token types \fB= + \- / *\fR.  The following two
 parameters would specify this desire:
 .Sp
 .Vb 1
 parameters would specify this desire:
 .Sp
 .Vb 1
-\&  -nwls="= + - / *"    -nwrs="= + - / *"
+\&  \-nwls="= + \- / *"    \-nwrs="= + \- / *"
 .Ve
 .Ve
+.Sp
 (Note that the token types are in quotes, and that they are separated by
 spaces).  With these modified whitespace rules, the following line of math:
 .Sp
 .Vb 1
 (Note that the token types are in quotes, and that they are separated by
 spaces).  With these modified whitespace rules, the following line of math:
 .Sp
 .Vb 1
-\&  $root = -$b + sqrt( $b * $b - 4. * $a * $c ) / ( 2. * $a );
+\&  $root = \-$b + sqrt( $b * $b \- 4. * $a * $c ) / ( 2. * $a );
 .Ve
 .Ve
+.Sp
 becomes this:
 .Sp
 .Vb 1
 becomes this:
 .Sp
 .Vb 1
-\&  $root=-$b+sqrt( $b*$b-4.*$a*$c )/( 2.*$a );
+\&  $root=\-$b+sqrt( $b*$b\-4.*$a*$c )/( 2.*$a );
 .Ve
 .Ve
+.Sp
 These parameters should be considered to be hints to perltidy rather
 than fixed rules, because perltidy must try to resolve conflicts that
 arise between them and all of the other rules that it uses.  One
 These parameters should be considered to be hints to perltidy rather
 than fixed rules, because perltidy must try to resolve conflicts that
 arise between them and all of the other rules that it uses.  One
@@ -872,16 +904,21 @@ a space takes priority.
 .Sp
 It is necessary to have a list of all token types in order to create
 this type of input.  Such a list can be obtained by the command
 .Sp
 It is necessary to have a list of all token types in order to create
 this type of input.  Such a list can be obtained by the command
-\&\fB\-dump\-token\-types\fR.
-.IP "Space between keyword and opening paren" 4
-.IX Item "Space between keyword and opening paren"
-When an opening paren follows a keyword, no space is introduced after the
+\&\fB\-\-dump\-token\-types\fR.  Also try the \-D flag on a short snippet of code
+and look at the .DEBUG file to see the tokenization. 
+.Sp
+\&\fB\s-1WARNING\s0\fR Be sure to put these tokens in quotes to avoid having them
+misinterpreted by your command shell.
+.IP "Space between specific keywords and opening paren" 4
+.IX Item "Space between specific keywords and opening paren"
+When an opening paren follows a Perl keyword, no space is introduced after the
 keyword, unless it is (by default) one of these:
 .Sp
 .Vb 2
 \&   my local our and or eq ne if else elsif until unless 
 \&   while for foreach return switch case given when
 .Ve
 keyword, unless it is (by default) one of these:
 .Sp
 .Vb 2
 \&   my local our and or eq ne if else elsif until unless 
 \&   while for foreach return switch case given when
 .Ve
+.Sp
 These defaults can be modified with two commands:
 .Sp
 \&\fB\-sak=s\fR  or \fB\-\-space\-after\-keyword=s\fR  adds keywords.
 These defaults can be modified with two commands:
 .Sp
 \&\fB\-sak=s\fR  or \fB\-\-space\-after\-keyword=s\fR  adds keywords.
@@ -892,8 +929,33 @@ where \fBs\fR is a list of keywords (in quotes if necessary).  For example,
 .Sp
 .Vb 2
 \&  my ( $a, $b, $c ) = @_;    # default
 .Sp
 .Vb 2
 \&  my ( $a, $b, $c ) = @_;    # default
-\&  my( $a, $b, $c ) = @_;     # -nsak="my local our"
+\&  my( $a, $b, $c ) = @_;     # \-nsak="my local our"
 .Ve
 .Ve
+.Sp
+To put a space after all keywords, see the next item.
+.IP "Space between all keywords and opening parens" 4
+.IX Item "Space between all keywords and opening parens"
+When an opening paren follows a function or keyword, no space is introduced
+after the keyword except for the keywords noted in the previous item.  To
+always put a space between a function or keyword and its opening paren,
+use the command:
+.Sp
+\&\fB\-skp\fR  or \fB\-\-space\-keyword\-paren\fR
+.Sp
+You will probably also want to use the flag \fB\-sfp\fR (next item) too.
+.IP "Space between all function names and opening parens" 4
+.IX Item "Space between all function names and opening parens"
+When an opening paren follows a function the default is not to introduce
+a space.  To cause a space to be introduced use:
+.Sp
+\&\fB\-sfp\fR  or \fB\-\-space\-function\-paren\fR
+.Sp
+.Vb 2
+\&  myfunc( $a, $b, $c );    # default 
+\&  myfunc ( $a, $b, $c );   # \-sfp
+.Ve
+.Sp
+You will probably also want to use the flag \fB\-skp\fR (previous item) too.
 .ie n .IP "Trimming whitespace around ""qw"" quotes" 4
 .el .IP "Trimming whitespace around \f(CWqw\fR quotes" 4
 .IX Item "Trimming whitespace around qw quotes"
 .ie n .IP "Trimming whitespace around ""qw"" quotes" 4
 .el .IP "Trimming whitespace around \f(CWqw\fR quotes" 4
 .IX Item "Trimming whitespace around qw quotes"
@@ -918,15 +980,17 @@ you may use \fB\-nibc\fR to keep block comments left\-justified.  Here is an
 example:
 .Sp
 .Vb 2
 example:
 .Sp
 .Vb 2
-\&             # this comment is indented      (-ibc, default)
+\&             # this comment is indented      (\-ibc, default)
 \&             if ($task) { yyy(); }
 .Ve
 \&             if ($task) { yyy(); }
 .Ve
+.Sp
 The alternative is \fB\-nibc\fR:
 .Sp
 .Vb 2
 The alternative is \fB\-nibc\fR:
 .Sp
 .Vb 2
-\& # this comment is not indented              (-nibc)
+\& # this comment is not indented              (\-nibc)
 \&             if ($task) { yyy(); }
 .Ve
 \&             if ($task) { yyy(); }
 .Ve
+.Sp
 See also the next item, \fB\-isbc\fR, as well as \fB\-sbc\fR, for other ways to
 have some indented and some outdented block comments.
 .IP "\fB\-isbc\fR,  \fB\-\-indent\-spaced\-block\-comments\fR" 4
 See also the next item, \fB\-isbc\fR, as well as \fB\-sbc\fR, for other ways to
 have some indented and some outdented block comments.
 .IP "\fB\-isbc\fR,  \fB\-\-indent\-spaced\-block\-comments\fR" 4
@@ -939,7 +1003,7 @@ If both \fB\-ibc\fR and \fB\-isbc\fR are set, then \fB\-isbc\fR takes priority.
 .IX Item "-olc, --outdent-long-comments"
 When \fB\-olc\fR is set, lines which are full-line (block) comments longer
 than the value \fBmaximum-line-length\fR will have their indentation
 .IX Item "-olc, --outdent-long-comments"
 When \fB\-olc\fR is set, lines which are full-line (block) comments longer
 than the value \fBmaximum-line-length\fR will have their indentation
-removed.  The default is not to do this.  
+removed.  This is the default; use \fB\-nolc\fR to prevent outdenting.
 .IP "\fB\-msc=n\fR,  \fB\-\-minimum\-space\-to\-comment=n\fR" 4
 .IX Item "-msc=n,  --minimum-space-to-comment=n"
 Side comments look best when lined up several spaces to the right of
 .IP "\fB\-msc=n\fR,  \fB\-\-minimum\-space\-to\-comment=n\fR" 4
 .IX Item "-msc=n,  --minimum-space-to-comment=n"
 Side comments look best when lined up several spaces to the right of
@@ -955,6 +1019,7 @@ comments\*(R", which are something like this:
 \&                           # This is a hanging side comment
 \&                           # And so is this
 .Ve
 \&                           # This is a hanging side comment
 \&                           # And so is this
 .Ve
+.Sp
 A comment is considered to be a hanging side comment if (1) it immediately
 follows a line with a side comment, or another hanging side comment, and
 (2) there is some leading whitespace on the line.
 A comment is considered to be a hanging side comment if (1) it immediately
 follows a line with a side comment, or another hanging side comment, and
 (2) there is some leading whitespace on the line.
@@ -966,7 +1031,7 @@ whitespace, they will not be mistaken as hanging side comments.
 A closing side comment is a special comment which perltidy can
 automatically create and place after the closing brace of a code block.
 They can be useful for code maintenance and debugging.  The command
 A closing side comment is a special comment which perltidy can
 automatically create and place after the closing brace of a code block.
 They can be useful for code maintenance and debugging.  The command
-\&\fB\-csc\fR (or \fB\-closing\-side\-comments\fR) adds or updates closing side
+\&\fB\-csc\fR (or \fB\-\-closing\-side\-comments\fR) adds or updates closing side
 comments.  For example, here is a small code snippet
 .Sp
 .Vb 8
 comments.  For example, here is a small code snippet
 .Sp
 .Vb 8
@@ -979,6 +1044,7 @@ comments.  For example, here is a small code snippet
 \&            }
 \&        }
 .Ve
 \&            }
 \&        }
 .Ve
+.Sp
 And here is the result of processing with \f(CW\*(C`perltidy \-csc\*(C'\fR:
 .Sp
 .Vb 8
 And here is the result of processing with \f(CW\*(C`perltidy \-csc\*(C'\fR:
 .Sp
 .Vb 8
@@ -991,6 +1057,7 @@ And here is the result of processing with \f(CW\*(C`perltidy \-csc\*(C'\fR:
 \&            }
 \&        } ## end sub message
 .Ve
 \&            }
 \&        } ## end sub message
 .Ve
+.Sp
 A closing side comment was added for \f(CW\*(C`sub message\*(C'\fR in this case, but not
 for the \f(CW\*(C`if\*(C'\fR and \f(CW\*(C`else\*(C'\fR blocks, because they were below the 6 line
 cutoff limit for adding closing side comments.  This limit may be
 A closing side comment was added for \f(CW\*(C`sub message\*(C'\fR in this case, but not
 for the \f(CW\*(C`if\*(C'\fR and \f(CW\*(C`else\*(C'\fR blocks, because they were below the 6 line
 cutoff limit for adding closing side comments.  This limit may be
@@ -1002,14 +1069,14 @@ process and removes these comments.
 Several commands are available to modify the behavior of these two basic
 commands, \fB\-csc\fR and \fB\-dcsc\fR:
 .RS 4
 Several commands are available to modify the behavior of these two basic
 commands, \fB\-csc\fR and \fB\-dcsc\fR:
 .RS 4
-.IP "\fB\-csci=n\fR, or \fB\-closing\-side\-comment\-interval=n\fR" 4
-.IX Item "-csci=n, or -closing-side-comment-interval=n"
+.IP "\fB\-csci=n\fR, or \fB\-\-closing\-side\-comment\-interval=n\fR" 4
+.IX Item "-csci=n, or --closing-side-comment-interval=n"
 where \f(CW\*(C`n\*(C'\fR is the minimum number of lines that a block must have in
 order for a closing side comment to be added.  The default value is
 \&\f(CW\*(C`n=6\*(C'\fR.  To illustrate:
 .Sp
 .Vb 9
 where \f(CW\*(C`n\*(C'\fR is the minimum number of lines that a block must have in
 order for a closing side comment to be added.  The default value is
 \&\f(CW\*(C`n=6\*(C'\fR.  To illustrate:
 .Sp
 .Vb 9
-\&        # perltidy -csci=2 -csc
+\&        # perltidy \-csci=2 \-csc
 \&        sub message {
 \&            if ( !defined( $_[0] ) ) {
 \&                print("Hello, World\en");
 \&        sub message {
 \&            if ( !defined( $_[0] ) ) {
 \&                print("Hello, World\en");
@@ -1019,18 +1086,19 @@ order for a closing side comment to be added.  The default value is
 \&            } ## end else [ if ( !defined( $_[0] ))
 \&        } ## end sub message
 .Ve
 \&            } ## end else [ if ( !defined( $_[0] ))
 \&        } ## end sub message
 .Ve
+.Sp
 Now the \f(CW\*(C`if\*(C'\fR and \f(CW\*(C`else\*(C'\fR blocks are commented.  However, now this has
 become very cluttered.
 Now the \f(CW\*(C`if\*(C'\fR and \f(CW\*(C`else\*(C'\fR blocks are commented.  However, now this has
 become very cluttered.
-.IP "\fB\-cscp=string\fR, or \fB\-closing\-side\-comment\-prefix=string\fR" 4
-.IX Item "-cscp=string, or -closing-side-comment-prefix=string"
+.IP "\fB\-cscp=string\fR, or \fB\-\-closing\-side\-comment\-prefix=string\fR" 4
+.IX Item "-cscp=string, or --closing-side-comment-prefix=string"
 where string is the prefix used before the name of the block type.  The
 default prefix, shown above, is \f(CW\*(C`## end\*(C'\fR.  This string will be added to
 closing side comments, and it will also be used to recognize them in
 order to update, delete, and format them.  Any comment identified as a
 closing side comment will be placed just a single space to the right of
 its closing brace.
 where string is the prefix used before the name of the block type.  The
 default prefix, shown above, is \f(CW\*(C`## end\*(C'\fR.  This string will be added to
 closing side comments, and it will also be used to recognize them in
 order to update, delete, and format them.  Any comment identified as a
 closing side comment will be placed just a single space to the right of
 its closing brace.
-.IP "\fB\-cscl=string\fR, or \fB\-closing\-side\-comment\-list\-string\fR" 4
-.IX Item "-cscl=string, or -closing-side-comment-list-string"
+.IP "\fB\-cscl=string\fR, or \fB\-\-closing\-side\-comment\-list\-string\fR" 4
+.IX Item "-cscl=string, or --closing-side-comment-list-string"
 where \f(CW\*(C`string\*(C'\fR is a list of block types to be tagged with closing side
 comments.  By default, all code block types preceded by a keyword or
 label (such as \f(CW\*(C`if\*(C'\fR, \f(CW\*(C`sub\*(C'\fR, and so on) will be tagged.  The \fB\-cscl\fR
 where \f(CW\*(C`string\*(C'\fR is a list of block types to be tagged with closing side
 comments.  By default, all code block types preceded by a keyword or
 label (such as \f(CW\*(C`if\*(C'\fR, \f(CW\*(C`sub\*(C'\fR, and so on) will be tagged.  The \fB\-cscl\fR
@@ -1041,23 +1109,23 @@ requests that only \f(CW\*(C`sub\*(C'\fR's, labels, \f(CW\*(C`BEGIN\*(C'\fR, and
 affected by any \fB\-csc\fR or \fB\-dcsc\fR operation:
 .Sp
 .Vb 1
 affected by any \fB\-csc\fR or \fB\-dcsc\fR operation:
 .Sp
 .Vb 1
-\&   -cscl="sub : BEGIN END"
+\&   \-cscl="sub : BEGIN END"
 .Ve
 .Ve
-.IP "\fB\-csct=n\fR, or \fB\-closing\-side\-comment\-maximum\-text=n\fR" 4
-.IX Item "-csct=n, or -closing-side-comment-maximum-text=n"
+.IP "\fB\-csct=n\fR, or \fB\-\-closing\-side\-comment\-maximum\-text=n\fR" 4
+.IX Item "-csct=n, or --closing-side-comment-maximum-text=n"
 The text appended to certain block types, such as an \f(CW\*(C`if\*(C'\fR block, is
 whatever lies between the keyword introducing the block, such as \f(CW\*(C`if\*(C'\fR,
 and the opening brace.  Since this might be too much text for a side
 comment, there needs to be a limit, and that is the purpose of this
 parameter.  The default value is \f(CW\*(C`n=20\*(C'\fR, meaning that no additional
 tokens will be appended to this text after its length reaches 20
 The text appended to certain block types, such as an \f(CW\*(C`if\*(C'\fR block, is
 whatever lies between the keyword introducing the block, such as \f(CW\*(C`if\*(C'\fR,
 and the opening brace.  Since this might be too much text for a side
 comment, there needs to be a limit, and that is the purpose of this
 parameter.  The default value is \f(CW\*(C`n=20\*(C'\fR, meaning that no additional
 tokens will be appended to this text after its length reaches 20
-characters.  Omitted text is indicated with \f(CW...\fR.  (Tokens, including
+characters.  Omitted text is indicated with \f(CW\*(C`...\*(C'\fR.  (Tokens, including
 sub names, are never truncated, however, so actual lengths may exceed
 this).  To illustrate, in the above example, the appended text of the
 first block is \f(CW\*(C` ( !defined( $_[0] )...\*(C'\fR.  The existing limit of
 sub names, are never truncated, however, so actual lengths may exceed
 this).  To illustrate, in the above example, the appended text of the
 first block is \f(CW\*(C` ( !defined( $_[0] )...\*(C'\fR.  The existing limit of
-\&\f(CW\*(C`n=20\*(C'\fR caused this text to be truncated, as indicated by the \f(CW...\fR.
-.IP "\fB\-csce=n\fR, or \fB\-closing\-side\-comment\-else\-flag=n\fR" 4
-.IX Item "-csce=n, or -closing-side-comment-else-flag=n"
+\&\f(CW\*(C`n=20\*(C'\fR caused this text to be truncated, as indicated by the \f(CW\*(C`...\*(C'\fR.
+.IP "\fB\-csce=n\fR, or \fB\-\-closing\-side\-comment\-else\-flag=n\fR" 4
+.IX Item "-csce=n, or --closing-side-comment-else-flag=n"
 The default, \fBn=0\fR, places the text of the opening \f(CW\*(C`if\*(C'\fR statement after any
 terminal \f(CW\*(C`else\*(C'\fR.
 .Sp
 The default, \fBn=0\fR, places the text of the opening \f(CW\*(C`if\*(C'\fR statement after any
 terminal \f(CW\*(C`else\*(C'\fR.
 .Sp
@@ -1068,8 +1136,8 @@ side comments.
 .Sp
 If \fBn=1\fR is used, the results will be the same as \fBn=2\fR whenever the
 resulting line length is less than the maximum allowed.
 .Sp
 If \fBn=1\fR is used, the results will be the same as \fBn=2\fR whenever the
 resulting line length is less than the maximum allowed.
-.IP "\fB\-cscw\fR, or \fB\-closing\-side\-comment\-warnings\fR" 4
-.IX Item "-cscw, or -closing-side-comment-warnings"
+.IP "\fB\-cscw\fR, or \fB\-\-closing\-side\-comment\-warnings\fR" 4
+.IX Item "-cscw, or --closing-side-comment-warnings"
 This parameter is intended to help make the initial transition to the use of
 closing side comments.  
 It causes two
 This parameter is intended to help make the initial transition to the use of
 closing side comments.  
 It causes two
@@ -1085,30 +1153,30 @@ should only be needed on the first run with \fB\-csc\fR.
 .RS 4
 .Sp
 \&\fBImportant Notes on Closing Side Comments:\fR 
 .RS 4
 .Sp
 \&\fBImportant Notes on Closing Side Comments:\fR 
-.IP "\(bu" 4
+.IP "*" 4
 Closing side comments are only placed on lines terminated with a closing
 brace.  Certain closing styles, such as the use of cuddled elses
 (\fB\-ce\fR), preclude the generation of some closing side comments.
 Closing side comments are only placed on lines terminated with a closing
 brace.  Certain closing styles, such as the use of cuddled elses
 (\fB\-ce\fR), preclude the generation of some closing side comments.
-.IP "\(bu" 4
+.IP "*" 4
 Please note that adding or deleting of closing side comments takes
 place only through the commands \fB\-csc\fR or \fB\-dcsc\fR.  The other commands,
 if used, merely modify the behavior of these two commands.  
 Please note that adding or deleting of closing side comments takes
 place only through the commands \fB\-csc\fR or \fB\-dcsc\fR.  The other commands,
 if used, merely modify the behavior of these two commands.  
-.IP "\(bu" 4
+.IP "*" 4
 It is recommended that the \fB\-cscw\fR flag be used along with \fB\-csc\fR on
 the first use of perltidy on a given file.  This will prevent loss of
 any existing side comment data which happens to have the csc prefix.
 It is recommended that the \fB\-cscw\fR flag be used along with \fB\-csc\fR on
 the first use of perltidy on a given file.  This will prevent loss of
 any existing side comment data which happens to have the csc prefix.
-.IP "\(bu" 4
+.IP "*" 4
 Once you use \fB\-csc\fR, you should continue to use it so that any
 closing side comments remain correct as code changes.  Otherwise, these
 comments will become incorrect as the code is updated.
 Once you use \fB\-csc\fR, you should continue to use it so that any
 closing side comments remain correct as code changes.  Otherwise, these
 comments will become incorrect as the code is updated.
-.IP "\(bu" 4
+.IP "*" 4
 If you edit the closing side comments generated by perltidy, you must also
 change the prefix to be different from the closing side comment prefix.
 Otherwise, your edits will be lost when you rerun perltidy with \fB\-csc\fR.   For
 example, you could simply change \f(CW\*(C`## end\*(C'\fR to be \f(CW\*(C`## End\*(C'\fR, since the test is
 case sensitive.  You may also want to use the \fB\-ssc\fR flag to keep these
 modified closing side comments spaced the same as actual closing side comments.
 If you edit the closing side comments generated by perltidy, you must also
 change the prefix to be different from the closing side comment prefix.
 Otherwise, your edits will be lost when you rerun perltidy with \fB\-csc\fR.   For
 example, you could simply change \f(CW\*(C`## end\*(C'\fR to be \f(CW\*(C`## End\*(C'\fR, since the test is
 case sensitive.  You may also want to use the \fB\-ssc\fR flag to keep these
 modified closing side comments spaced the same as actual closing side comments.
-.IP "\(bu" 4
+.IP "*" 4
 Temporarily generating closing side comments is a useful technique for
 exploring and/or debugging a perl script, especially one written by someone
 else.  You can always remove them with \fB\-dcsc\fR.
 Temporarily generating closing side comments is a useful technique for
 exploring and/or debugging a perl script, especially one written by someone
 else.  You can always remove them with \fB\-dcsc\fR.
@@ -1131,13 +1199,13 @@ default, will be treated specially.
 .Sp
 Comments so identified  are treated as follows: 
 .RS 4
 .Sp
 Comments so identified  are treated as follows: 
 .RS 4
-.IP "\(bu" 4
+.IP "*" 4
 If there is no leading space on the line, then the comment will not
 be indented, and otherwise it may be,
 If there is no leading space on the line, then the comment will not
 be indented, and otherwise it may be,
-.IP "\(bu" 4
+.IP "*" 4
 no new blank line will be
 inserted before such a comment, and 
 no new blank line will be
 inserted before such a comment, and 
-.IP "\(bu" 4
+.IP "*" 4
 such a comment will never become
 a hanging side comment.  
 .RE
 such a comment will never become
 a hanging side comment.  
 .RE
@@ -1147,22 +1215,25 @@ For example, assuming \f(CW@month_of_year\fR is
 left\-adjusted:
 .Sp
 .Vb 4
 left\-adjusted:
 .Sp
 .Vb 4
-\&    @month_of_year = (    # -sbc (default)
+\&    @month_of_year = (    # \-sbc (default)
 \&        'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct',
 \&    ##  'Dec', 'Nov'
 \&        'Nov', 'Dec');
 .Ve
 \&        'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct',
 \&    ##  'Dec', 'Nov'
 \&        'Nov', 'Dec');
 .Ve
+.Sp
 Without this convention, the above code would become
 .Sp
 .Vb 2
 Without this convention, the above code would become
 .Sp
 .Vb 2
-\&    @month_of_year = (   # -nsbc
+\&    @month_of_year = (   # \-nsbc
 \&        'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct',
 .Ve
 \&        'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct',
 .Ve
+.Sp
 .Vb 3
 \&        ##  'Dec', 'Nov'
 \&        'Nov', 'Dec'
 \&    );
 .Ve
 .Vb 3
 \&        ##  'Dec', 'Nov'
 \&        'Nov', 'Dec'
 \&    );
 .Ve
+.Sp
 which is not as clear.
 The default is to use \fB\-sbc\fR.  This may be deactivated with \fB\-nsbc\fR.
 .RE
 which is not as clear.
 The default is to use \fB\-sbc\fR.  This may be deactivated with \fB\-nsbc\fR.
 .RE
@@ -1170,15 +1241,19 @@ The default is to use \fB\-sbc\fR.  This may be deactivated with \fB\-nsbc\fR.
 .IX Item "-sbcp=string, --static-block-comment-prefix=string"
 This parameter defines the prefix used to identify static block comments
 when the \fB\-sbc\fR parameter is set.  The default prefix is \f(CW\*(C`##\*(C'\fR,
 .IX Item "-sbcp=string, --static-block-comment-prefix=string"
 This parameter defines the prefix used to identify static block comments
 when the \fB\-sbc\fR parameter is set.  The default prefix is \f(CW\*(C`##\*(C'\fR,
-corresponding to \f(CW\*(C`\-sbcp=##\*(C'\fR.  The first character must be a \f(CW\*(C`#\*(C'\fR
-symbol, since this must only match comments.  As a simple example, to
+corresponding to \f(CW\*(C`\-sbcp=##\*(C'\fR.  The prefix is actually part of a perl 
+pattern used to match lines and it must either begin with \f(CW\*(C`#\*(C'\fR or \f(CW\*(C`^#\*(C'\fR.  
+In the first case a prefix ^\es* will be added to match any leading
+whitespace, while in the second case the pattern will match only
+comments with no leading whitespace.  For example, to
 identify all comments as static block comments, one would use \f(CW\*(C`\-sbcp=#\*(C'\fR.
 identify all comments as static block comments, one would use \f(CW\*(C`\-sbcp=#\*(C'\fR.
+To identify all left-adjusted comments as static block comments, use \f(CW\*(C`\-sbcp='^#'\*(C'\fR.
 .Sp
 Please note that \fB\-sbcp\fR merely defines the pattern used to identify static
 block comments; it will not be used unless the switch \fB\-sbc\fR is set.  Also,
 .Sp
 Please note that \fB\-sbcp\fR merely defines the pattern used to identify static
 block comments; it will not be used unless the switch \fB\-sbc\fR is set.  Also,
-please be aware that this string is used in a perl regular expression which
-identifies these comments, so it must enable a valid regular expression to be
-formed.
+please be aware that since this string is used in a perl regular expression
+which identifies these comments, it must enable a valid regular expression to
+be formed.
 .IP "\fB\-osbc\fR, \fB\-\-outdent\-static\-block\-comments\fR" 4
 .IX Item "-osbc, --outdent-static-block-comments"
 The command \fB\-osbc\fR will will cause static block comments to be outdented by 2
 .IP "\fB\-osbc\fR, \fB\-\-outdent\-static\-block\-comments\fR" 4
 .IX Item "-osbc, --outdent-static-block-comments"
 The command \fB\-osbc\fR will will cause static block comments to be outdented by 2
@@ -1213,6 +1288,60 @@ expression to be formed.
 .RE
 .RS 4
 .RE
 .RE
 .RS 4
 .RE
+.Sh "Skipping Selected Sections of Code"
+.IX Subsection "Skipping Selected Sections of Code"
+Selected lines of code may be passed verbatim to the output without any
+formatting.  This feature is enabled by default but can be disabled with
+the \fB\-\-noformat\-skipping\fR or \fB\-nfs\fR flag.  It should be used sparingly to
+avoid littering code with markers, but it might be helpful for working
+around occasional problems.  For example it might be useful for keeping
+the indentation of old commented code unchanged, keeping indentation of
+long blocks of aligned comments unchanged, keeping certain list
+formatting unchanged, or working around a glitch in perltidy.
+.IP "\fB\-fs\fR,  \fB\-\-format\-skipping\fR" 4
+.IX Item "-fs,  --format-skipping"
+This flag, which is enabled by default, causes any code between
+special beginning and ending comment markers to be passed to the
+output without formatting.  The default beginning marker is #<<<
+and the default ending marker is #>>> but they
+may be changed (see next items below).  Additional text may appear on
+these special comment lines provided that it is separated from the
+marker by at least one space.  For example
+.Sp
+.Vb 7
+\& #<<<  do not let perltidy touch this
+\&    my @list = (1,
+\&                1, 1,
+\&                1, 2, 1,
+\&                1, 3, 3, 1,
+\&                1, 4, 6, 4, 1,);
+\& #>>>
+.Ve
+.Sp
+The comment markers may be placed at any location that a block comment may
+appear.  If they do not appear to be working, use the \-log flag and examine the
+\&\fI.LOG\fR file.  Use \fB\-nfs\fR to disable this feature.
+.IP "\fB\-fsb=string\fR,  \fB\-\-format\-skipping\-begin=string\fR" 4
+.IX Item "-fsb=string,  --format-skipping-begin=string"
+The \fB\-fsb=string\fR parameter may be used to change the beginning marker for
+format skipping.  The default is equivalent to \-fsb='#<<<'.  The string that
+you enter must begin with a # and should be in quotes as necessary to get past
+the command shell of your system.  It is actually the leading text of a pattern
+that is constructed by appending a '\es', so you must also include backslashes
+for characters to be taken literally rather than as patterns.  
+.Sp
+Some examples show how example strings become patterns:
+.Sp
+.Vb 3
+\& \-fsb='#\e{\e{\e{' becomes /^#\e{\e{\e{\es/  which matches  #{{{ but not #{{{{
+\& \-fsb='#\e*\e*'   becomes /^#\e*\e*\es/    which matches  #** but not #***
+\& \-fsb='#\e*{2,}' becomes /^#\e*{2,}\es/  which matches  #** and #*****
+.Ve
+.IP "\fB\-fse=string\fR,  \fB\-\-format\-skipping\-end=string\fR" 4
+.IX Item "-fse=string,  --format-skipping-end=string"
+The \fB\-fsb=string\fR is the corresponding parameter used to change the
+ending marker for format skipping.  The default is equivalent to
+\&\-fse='#<<<'.  
 .Sh "Line Break Control"
 .IX Subsection "Line Break Control"
 .IP "\fB\-fnl\fR,  \fB\-\-freeze\-newlines\fR" 4
 .Sh "Line Break Control"
 .IX Subsection "Line Break Control"
 .IP "\fB\-fnl\fR,  \fB\-\-freeze\-newlines\fR" 4
@@ -1235,15 +1364,16 @@ alternatives:
 .Vb 5
 \&  if ($task) {
 \&      yyy();
 .Vb 5
 \&  if ($task) {
 \&      yyy();
-\&  } else {    # -ce
+\&  } else {    # \-ce
 \&      zzz();
 \&  }
 .Ve
 \&      zzz();
 \&  }
 .Ve
+.Sp
 .Vb 6
 \&  if ($task) {
 \&        yyy();
 \&  }
 .Vb 6
 \&  if ($task) {
 \&        yyy();
 \&  }
-\&  else {    # -nce  (default)
+\&  else {    # \-nce  (default)
 \&        zzz();
 \&  }
 .Ve
 \&        zzz();
 \&  }
 .Ve
@@ -1252,11 +1382,12 @@ alternatives:
 Use the flag \fB\-bl\fR to place the opening brace on a new line:
 .Sp
 .Vb 4
 Use the flag \fB\-bl\fR to place the opening brace on a new line:
 .Sp
 .Vb 4
-\&  if ( $input_file eq '-' )    # -bl 
+\&  if ( $input_file eq '\-' )    # \-bl 
 \&  {                          
 \&      important_function();
 \&  }
 .Ve
 \&  {                          
 \&      important_function();
 \&  }
 .Ve
+.Sp
 This flag applies to all structural blocks, including sub's (unless
 the \fB\-sbl\fR flag is set \*(-- see next item).
 .Sp
 This flag applies to all structural blocks, including sub's (unless
 the \fB\-sbl\fR flag is set \*(-- see next item).
 .Sp
@@ -1264,7 +1395,7 @@ The default style, \fB\-nbl\fR, places an opening brace on the same line as
 the keyword introducing it.  For example,
 .Sp
 .Vb 1
 the keyword introducing it.  For example,
 .Sp
 .Vb 1
-\&  if ( $input_file eq '-' ) {   # -nbl (default)
+\&  if ( $input_file eq '\-' ) {   # \-nbl (default)
 .Ve
 .IP "\fB\-sbl\fR,    \fB\-\-opening\-sub\-brace\-on\-new\-line\fR" 4
 .IX Item "-sbl,    --opening-sub-brace-on-new-line"
 .Ve
 .IP "\fB\-sbl\fR,    \fB\-\-opening\-sub\-brace\-on\-new\-line\fR" 4
 .IX Item "-sbl,    --opening-sub-brace-on-new-line"
@@ -1272,8 +1403,9 @@ The flag \fB\-sbl\fR can be used to override the value of \fB\-bl\fR for
 opening sub braces.  For example, 
 .Sp
 .Vb 1
 opening sub braces.  For example, 
 .Sp
 .Vb 1
-\& perltidy -sbl
+\& perltidy \-sbl
 .Ve
 .Ve
+.Sp
 produces this result:
 .Sp
 .Vb 9
 produces this result:
 .Sp
 .Vb 9
@@ -1287,6 +1419,7 @@ produces this result:
 \&    }
 \& }
 .Ve
 \&    }
 \& }
 .Ve
+.Sp
 This flag is negated with \fB\-nsbl\fR.  If \fB\-sbl\fR is not specified,
 the value of \fB\-bl\fR is used.
 .IP "\fB\-bli\fR,    \fB\-\-brace\-left\-and\-indent\fR" 4
 This flag is negated with \fB\-nsbl\fR.  If \fB\-sbl\fR is not specified,
 the value of \fB\-bl\fR is used.
 .IP "\fB\-bli\fR,    \fB\-\-brace\-left\-and\-indent\fR" 4
@@ -1298,11 +1431,12 @@ an opening and closing block braces.
 For example,
 .Sp
 .Vb 4
 For example,
 .Sp
 .Vb 4
-\&        if ( $input_file eq '-' )    # -bli
+\&        if ( $input_file eq '\-' )    # \-bli
 \&          {
 \&            important_function();
 \&          }
 .Ve
 \&          {
 \&            important_function();
 \&          }
 .Ve
+.Sp
 By default, this extra indentation occurs for blocks of type:
 \&\fBif\fR, \fBelsif\fR, \fBelse\fR, \fBunless\fR, \fBfor\fR, \fBforeach\fR, \fBsub\fR, 
 \&\fBwhile\fR, \fBuntil\fR, and also with a preceding label.  The next item
 By default, this extra indentation occurs for blocks of type:
 \&\fBif\fR, \fBelsif\fR, \fBelse\fR, \fBunless\fR, \fBfor\fR, \fBforeach\fR, \fBsub\fR, 
 \&\fBwhile\fR, \fBuntil\fR, and also with a preceding label.  The next item
@@ -1314,7 +1448,7 @@ Use this parameter to change the types of block braces for which the
 \&\fB\-blil='if elsif else'\fR would apply it to only \f(CW\*(C`if/elsif/else\*(C'\fR blocks.
 .IP "\fB\-bar\fR,    \fB\-\-opening\-brace\-always\-on\-right\fR" 4
 .IX Item "-bar,    --opening-brace-always-on-right"
 \&\fB\-blil='if elsif else'\fR would apply it to only \f(CW\*(C`if/elsif/else\*(C'\fR blocks.
 .IP "\fB\-bar\fR,    \fB\-\-opening\-brace\-always\-on\-right\fR" 4
 .IX Item "-bar,    --opening-brace-always-on-right"
-The default style, \fB\-nbl\fR places the opening brace on a new
+The default style, \fB\-nbl\fR places the opening code block brace on a new
 line if it does not fit on the same line as the opening keyword, like
 this:
 .Sp
 line if it does not fit on the same line as the opening keyword, like
 this:
 .Sp
@@ -1325,6 +1459,7 @@ this:
 \&            big_waste_of_time();
 \&        }
 .Ve
 \&            big_waste_of_time();
 \&        }
 .Ve
+.Sp
 To force the opening brace to always be on the right, use the \fB\-bar\fR
 flag.  In this case, the above example becomes
 .Sp
 To force the opening brace to always be on the right, use the \fB\-bar\fR
 flag.  In this case, the above example becomes
 .Sp
@@ -1334,42 +1469,75 @@ flag.  In this case, the above example becomes
 \&            big_waste_of_time();
 \&        }
 .Ve
 \&            big_waste_of_time();
 \&        }
 .Ve
+.Sp
 A conflict occurs if both \fB\-bl\fR and \fB\-bar\fR are specified.
 A conflict occurs if both \fB\-bl\fR and \fB\-bar\fR are specified.
+.IP "\fB\-otr\fR,  \fB\-\-opening\-token\-right\fR and related flags" 4
+.IX Item "-otr,  --opening-token-right and related flags"
+The \fB\-otr\fR flag is a hint that perltidy should not place a break between a
+comma and an opening token.  For example:
+.Sp
+.Vb 6
+\&    # default formatting
+\&    push @{ $self\->{$module}{$key} },
+\&      {
+\&        accno       => $ref\->{accno},
+\&        description => $ref\->{description}
+\&      };
+.Ve
+.Sp
+.Vb 5
+\&    # perltidy \-otr
+\&    push @{ $self\->{$module}{$key} }, {
+\&        accno       => $ref\->{accno},
+\&        description => $ref\->{description}
+\&      };
+.Ve
+.Sp
+The flag \fB\-otr\fR is actually a synonym for three other flags
+which can be used to control parens, hash braces, and square brackets
+separately if desired:
+.Sp
+.Vb 3
+\&  \-opr  or \-\-opening\-paren\-right
+\&  \-ohbr or \-\-opening\-hash\-brace\-right
+\&  \-osbr or \-\-opening\-square\-bracket\-right
+.Ve
 .IP "Vertical tightness of non-block curly braces, parentheses, and square brackets." 4
 .IX Item "Vertical tightness of non-block curly braces, parentheses, and square brackets."
 These parameters control what shall be called vertical tightness.  Here are the
 main points:
 .RS 4
 .IP "Vertical tightness of non-block curly braces, parentheses, and square brackets." 4
 .IX Item "Vertical tightness of non-block curly braces, parentheses, and square brackets."
 These parameters control what shall be called vertical tightness.  Here are the
 main points:
 .RS 4
-.IP "\(bu" 4
+.IP "*" 4
 Opening tokens (except for block braces) are controlled by \fB\-vt=n\fR, or
 \&\fB\-\-vertical\-tightness=n\fR, where
 .Sp
 .Vb 4
 Opening tokens (except for block braces) are controlled by \fB\-vt=n\fR, or
 \&\fB\-\-vertical\-tightness=n\fR, where
 .Sp
 .Vb 4
-\& -vt=0 always break a line after opening token (default). 
-\& -vt=1 do not break unless this would produce more than one 
+\& \-vt=0 always break a line after opening token (default). 
+\& \-vt=1 do not break unless this would produce more than one 
 \&         step in indentation in a line.
 \&         step in indentation in a line.
-\& -vt=2 never break a line after opening token
+\& \-vt=2 never break a line after opening token
 .Ve
 .Ve
-.IP "\(bu" 4
+.IP "*" 4
 You must also use the \fB\-lp\fR flag when you use the \fB\-vt\fR flag; the
 reason is explained below.
 You must also use the \fB\-lp\fR flag when you use the \fB\-vt\fR flag; the
 reason is explained below.
-.IP "\(bu" 4
+.IP "*" 4
 Closing tokens (except for block braces) are controlled by \fB\-vtc=n\fR, or
 \&\fB\-\-vertical\-tightness\-closing=n\fR, where
 .Sp
 .Vb 5
 Closing tokens (except for block braces) are controlled by \fB\-vtc=n\fR, or
 \&\fB\-\-vertical\-tightness\-closing=n\fR, where
 .Sp
 .Vb 5
-\& -vtc=0 always break a line before a closing token (default), 
-\& -vtc=1 do not break before a closing token which is followed 
+\& \-vtc=0 always break a line before a closing token (default), 
+\& \-vtc=1 do not break before a closing token which is followed 
 \&        by a semicolon or another closing token, and is not in 
 \&        a list environment.
 \&        by a semicolon or another closing token, and is not in 
 \&        a list environment.
-\& -vtc=2 never break before a closing token.
+\& \-vtc=2 never break before a closing token.
 .Ve
 .Ve
+.Sp
 The rules for \fB\-vtc=1\fR are designed to maintain a reasonable balance
 between tightness and readability in complex lists.
 The rules for \fB\-vtc=1\fR are designed to maintain a reasonable balance
 between tightness and readability in complex lists.
-.IP "\(bu" 4
+.IP "*" 4
 Different controls may be applied to to different token types,
 and it is also possible to control block braces; see below.
 Different controls may be applied to to different token types,
 and it is also possible to control block braces; see below.
-.IP "\(bu" 4
+.IP "*" 4
 Finally, please note that these vertical tightness flags are merely
 hints to the formatter, and it cannot always follow them.  Things which
 make it difficult or impossible include comments, blank lines, blocks of
 Finally, please note that these vertical tightness flags are merely
 hints to the formatter, and it cannot always follow them.  Things which
 make it difficult or impossible include comments, blank lines, blocks of
@@ -1382,7 +1550,7 @@ length).
 Here are some examples: 
 .Sp
 .Vb 7
 Here are some examples: 
 .Sp
 .Vb 7
-\&    # perltidy -lp -vt=0 -vtc=0
+\&    # perltidy \-lp \-vt=0 \-vtc=0
 \&    %romanNumerals = (
 \&                       one   => 'I',
 \&                       two   => 'II',
 \&    %romanNumerals = (
 \&                       one   => 'I',
 \&                       two   => 'II',
@@ -1390,38 +1558,43 @@ Here are some examples:
 \&                       four  => 'IV',
 \&    );
 .Ve
 \&                       four  => 'IV',
 \&    );
 .Ve
+.Sp
 .Vb 6
 .Vb 6
-\&    # perltidy -lp -vt=1 -vtc=0
+\&    # perltidy \-lp \-vt=1 \-vtc=0
 \&    %romanNumerals = ( one   => 'I',
 \&                       two   => 'II',
 \&                       three => 'III',
 \&                       four  => 'IV',
 \&    );
 .Ve
 \&    %romanNumerals = ( one   => 'I',
 \&                       two   => 'II',
 \&                       three => 'III',
 \&                       four  => 'IV',
 \&    );
 .Ve
+.Sp
 .Vb 5
 .Vb 5
-\&    # perltidy -lp -vt=1 -vtc=1
+\&    # perltidy \-lp \-vt=1 \-vtc=1
 \&    %romanNumerals = ( one   => 'I',
 \&                       two   => 'II',
 \&                       three => 'III',
 \&                       four  => 'IV', );
 .Ve
 \&    %romanNumerals = ( one   => 'I',
 \&                       two   => 'II',
 \&                       three => 'III',
 \&                       four  => 'IV', );
 .Ve
+.Sp
 The difference between \fB\-vt=1\fR and \fB\-vt=2\fR is shown here:
 .Sp
 .Vb 6
 The difference between \fB\-vt=1\fR and \fB\-vt=2\fR is shown here:
 .Sp
 .Vb 6
-\&    # perltidy -lp -vt=1 
-\&    $init->add(
+\&    # perltidy \-lp \-vt=1 
+\&    $init\->add(
 \&                mysprintf( "(void)find_threadsv(%s);",
 \&                mysprintf( "(void)find_threadsv(%s);",
-\&                           cstring( $threadsv_names[ $op->targ ] )
+\&                           cstring( $threadsv_names[ $op\->targ ] )
 \&                )
 \&    );
 .Ve
 \&                )
 \&    );
 .Ve
+.Sp
 .Vb 5
 .Vb 5
-\&    # perltidy -lp -vt=2 
-\&    $init->add( mysprintf( "(void)find_threadsv(%s);",
-\&                           cstring( $threadsv_names[ $op->targ ] )
+\&    # perltidy \-lp \-vt=2 
+\&    $init\->add( mysprintf( "(void)find_threadsv(%s);",
+\&                           cstring( $threadsv_names[ $op\->targ ] )
 \&                )
 \&    );
 .Ve
 \&                )
 \&    );
 .Ve
+.Sp
 With \fB\-vt=1\fR, the line ending in \f(CW\*(C`add(\*(C'\fR does not combine with the next
 line because the next line is not balanced.  This can help with
 readability, but \fB\-vt=2\fR can be used to ignore this rule.
 With \fB\-vt=1\fR, the line ending in \f(CW\*(C`add(\*(C'\fR does not combine with the next
 line because the next line is not balanced.  This can help with
 readability, but \fB\-vt=2\fR can be used to ignore this rule.
@@ -1430,10 +1603,11 @@ The tightest, and least readable, code is produced with both \f(CW\*(C`\-vt=2\*(
 \&\f(CW\*(C`\-vtc=2\*(C'\fR:
 .Sp
 .Vb 3
 \&\f(CW\*(C`\-vtc=2\*(C'\fR:
 .Sp
 .Vb 3
-\&    # perltidy -lp -vt=2 -vtc=2
-\&    $init->add( mysprintf( "(void)find_threadsv(%s);",
-\&                           cstring( $threadsv_names[ $op->targ ] ) ) );
+\&    # perltidy \-lp \-vt=2 \-vtc=2
+\&    $init\->add( mysprintf( "(void)find_threadsv(%s);",
+\&                           cstring( $threadsv_names[ $op\->targ ] ) ) );
 .Ve
 .Ve
+.Sp
 Notice how the code in all of these examples collapses vertically as
 \&\fB\-vt\fR increases, but the indentation remains unchanged.  This is
 because perltidy implements the \fB\-vt\fR parameter by first formatting as
 Notice how the code in all of these examples collapses vertically as
 \&\fB\-vt\fR increases, but the indentation remains unchanged.  This is
 because perltidy implements the \fB\-vt\fR parameter by first formatting as
@@ -1468,18 +1642,19 @@ The \fB\-bbvt=n\fR flag is just like the \fB\-vt=n\fR flag but applies
 to opening code block braces.
 .Sp
 .Vb 4
 to opening code block braces.
 .Sp
 .Vb 4
-\& -bbvt=0 break after opening block brace (default). 
-\& -bbvt=1 do not break unless this would produce more than one 
+\& \-bbvt=0 break after opening block brace (default). 
+\& \-bbvt=1 do not break unless this would produce more than one 
 \&         step in indentation in a line.
 \&         step in indentation in a line.
-\& -bbvt=2 do not break after opening block brace.
+\& \-bbvt=2 do not break after opening block brace.
 .Ve
 .Ve
+.Sp
 It is necessary to also use either \fB\-bl\fR or \fB\-bli\fR for this to work,
 because, as with other vertical tightness controls, it is implemented by
 simply overwriting a line ending with an opening block brace with the
 subsequent line.  For example:
 .Sp
 .Vb 10
 It is necessary to also use either \fB\-bl\fR or \fB\-bli\fR for this to work,
 because, as with other vertical tightness controls, it is implemented by
 simply overwriting a line ending with an opening block brace with the
 subsequent line.  For example:
 .Sp
 .Vb 10
-\&    # perltidy -bli -bbvt=0
+\&    # perltidy \-bli \-bbvt=0
 \&    if ( open( FILE, "< $File" ) )
 \&      {
 \&        while ( $File = <FILE> )
 \&    if ( open( FILE, "< $File" ) )
 \&      {
 \&        while ( $File = <FILE> )
@@ -1490,8 +1665,9 @@ subsequent line.  For example:
 \&        close(FILE);
 \&      }
 .Ve
 \&        close(FILE);
 \&      }
 .Ve
+.Sp
 .Vb 8
 .Vb 8
-\&    # perltidy -bli -bbvt=1
+\&    # perltidy \-bli \-bbvt=1
 \&    if ( open( FILE, "< $File" ) )
 \&      { while ( $File = <FILE> )
 \&          { $In .= $File;
 \&    if ( open( FILE, "< $File" ) )
 \&      { while ( $File = <FILE> )
 \&          { $In .= $File;
@@ -1500,6 +1676,7 @@ subsequent line.  For example:
 \&        close(FILE);
 \&      }
 .Ve
 \&        close(FILE);
 \&      }
 .Ve
+.Sp
 By default this applies to blocks associated with keywords \fBif\fR,
 \&\fBelsif\fR, \fBelse\fR, \fBunless\fR, \fBfor\fR, \fBforeach\fR, \fBsub\fR, \fBwhile\fR,
 \&\fBuntil\fR, and also with a preceding label.  This can be changed with
 By default this applies to blocks associated with keywords \fBif\fR,
 \&\fBelsif\fR, \fBelse\fR, \fBunless\fR, \fBfor\fR, \fBforeach\fR, \fBsub\fR, \fBwhile\fR,
 \&\fBuntil\fR, and also with a preceding label.  This can be changed with
@@ -1510,11 +1687,103 @@ possible values of this string, see \*(L"Specifying Block Types\*(R"
 .Sp
 For example, if we want to just apply this style to \f(CW\*(C`if\*(C'\fR,
 \&\f(CW\*(C`elsif\*(C'\fR, and \f(CW\*(C`else\*(C'\fR blocks, we could use 
 .Sp
 For example, if we want to just apply this style to \f(CW\*(C`if\*(C'\fR,
 \&\f(CW\*(C`elsif\*(C'\fR, and \f(CW\*(C`else\*(C'\fR blocks, we could use 
-\&\f(CW\*(C`perltidy \-bli \-bbvt \-bbvtl='if elsif else'\*(C'\fR.
+\&\f(CW\*(C`perltidy \-bli \-bbvt=1 \-bbvtl='if elsif else'\*(C'\fR.
 .Sp
 There is no vertical tightness control for closing block braces; with
 the exception of one-line blocks, they will normally remain on a 
 separate line.
 .Sp
 There is no vertical tightness control for closing block braces; with
 the exception of one-line blocks, they will normally remain on a 
 separate line.
+.IP "\fB\-sot\fR,  \fB\-\-stack\-opening\-token\fR and related flags" 4
+.IX Item "-sot,  --stack-opening-token and related flags"
+The \fB\-sot\fR flag tells perltidy to \*(L"stack\*(R" opening tokens
+when possible to avoid lines with isolated opening tokens.
+.Sp
+For example:
+.Sp
+.Vb 8
+\&    # default
+\&    $opt_c = Text::CSV_XS\->new(
+\&        {
+\&            binary       => 1,
+\&            sep_char     => $opt_c,
+\&            always_quote => 1,
+\&        }
+\&    );
+.Ve
+.Sp
+.Vb 7
+\&    # \-sot
+\&    $opt_c = Text::CSV_XS\->new( {
+\&            binary       => 1,
+\&            sep_char     => $opt_c,
+\&            always_quote => 1,
+\&        }
+\&    );
+.Ve
+.Sp
+For detailed control of individual closing tokens the following
+controls can be used:
+.Sp
+.Vb 3
+\&  \-sop  or \-\-stack\-opening\-paren
+\&  \-sohb or \-\-stack\-opening\-hash\-brace
+\&  \-sosb or \-\-stack\-opening\-square\-bracket
+.Ve
+.Sp
+The flag \fB\-sot\fR is a synonym for \fB\-sop \-sohb \-sosb\fR.
+.IP "\fB\-sct\fR,  \fB\-\-stack\-closing\-token\fR and related flags" 4
+.IX Item "-sct,  --stack-closing-token and related flags"
+The \fB\-sct\fR flag tells perltidy to \*(L"stack\*(R" closing tokens
+when possible to avoid lines with isolated closing tokens.
+.Sp
+For example:
+.Sp
+.Vb 8
+\&    # default
+\&    $opt_c = Text::CSV_XS\->new(
+\&        {
+\&            binary       => 1,
+\&            sep_char     => $opt_c,
+\&            always_quote => 1,
+\&        }
+\&    );
+.Ve
+.Sp
+.Vb 7
+\&    # \-sct
+\&    $opt_c = Text::CSV_XS\->new(
+\&        {
+\&            binary       => 1,
+\&            sep_char     => $opt_c,
+\&            always_quote => 1,
+\&        } );
+.Ve
+.Sp
+The \fB\-sct\fR flag is somewhat similar to the \fB\-vtc\fR flags, and in some
+cases it can give a similar result.  The difference is that the \fB\-vtc\fR
+flags try to avoid lines with leading opening tokens by \*(L"hiding\*(R" them at
+the end of a previous line, whereas the \fB\-sct\fR flag merely tries to
+reduce the number of lines with isolated closing tokens by stacking them
+but does not try to hide them.  For example:
+.Sp
+.Vb 6
+\&    # \-vtc=2
+\&    $opt_c = Text::CSV_XS\->new(
+\&        {
+\&            binary       => 1,
+\&            sep_char     => $opt_c,
+\&            always_quote => 1, } );
+.Ve
+.Sp
+For detailed control of the stacking of individual closing tokens the
+following controls can be used:
+.Sp
+.Vb 3
+\&  \-scp  or \-\-stack\-closing\-paren
+\&  \-schb or \-\-stack\-closing\-hash\-brace
+\&  \-scsb or \-\-stack\-closing\-square\-bracket
+.Ve
+.Sp
+The flag \fB\-sct\fR is a synonym for \fB\-scp \-schb \-scsb\fR.
 .IP "\fB\-dnl\fR,  \fB\-\-delete\-old\-newlines\fR" 4
 .IX Item "-dnl,  --delete-old-newlines"
 By default, perltidy first deletes all old line break locations, and then it
 .IP "\fB\-dnl\fR,  \fB\-\-delete\-old\-newlines\fR" 4
 .IX Item "-dnl,  --delete-old-newlines"
 By default, perltidy first deletes all old line break locations, and then it
@@ -1525,10 +1794,10 @@ points.
 .IX Item "-anl,  --add-newlines"
 By default, perltidy will add line breaks when necessary to create
 continuations of long lines and to improve the script appearance.  Use
 .IX Item "-anl,  --add-newlines"
 By default, perltidy will add line breaks when necessary to create
 continuations of long lines and to improve the script appearance.  Use
-\&\fB\-nanl\fR or \fB\-noadd\-newlines\fR to prevent any new line breaks.  
+\&\fB\-nanl\fR or \fB\-\-noadd\-newlines\fR to prevent any new line breaks.  
 .Sp
 This flag does not prevent perltidy from eliminating existing line
 .Sp
 This flag does not prevent perltidy from eliminating existing line
-breaks; see \fB\-freeze\-newlines\fR to completely prevent changes to line
+breaks; see \fB\-\-freeze\-newlines\fR to completely prevent changes to line
 break points.
 .IP "Controlling whether perltidy breaks before or after operators" 4
 .IX Item "Controlling whether perltidy breaks before or after operators"
 break points.
 .IP "Controlling whether perltidy breaks before or after operators" 4
 .IX Item "Controlling whether perltidy breaks before or after operators"
@@ -1556,19 +1825,25 @@ To illustrate, to cause a break after a concatenation operator, \f(CW'.'\fR,
 rather than before it, the command line would be
 .Sp
 .Vb 1
 rather than before it, the command line would be
 .Sp
 .Vb 1
-\&  -wba="."
+\&  \-wba="."
 .Ve
 .Ve
+.Sp
 As another example, the following command would cause a break before 
 math operators \f(CW'+'\fR, \f(CW'\-'\fR, \f(CW'/'\fR, and \f(CW'*'\fR:
 .Sp
 .Vb 1
 As another example, the following command would cause a break before 
 math operators \f(CW'+'\fR, \f(CW'\-'\fR, \f(CW'/'\fR, and \f(CW'*'\fR:
 .Sp
 .Vb 1
-\&  -wbb="+ - / *"
+\&  \-wbb="+ \- / *"
 .Ve
 .Ve
-These commands should work well for most of the token types that
-perltidy uses (use \fB\-\-dump\-token\-types\fR for a list).  However, for a
-few token types there may be conflicts with hardwired logic which cause
-unexpected results.  One example is curly braces, which should be
-controlled with the parameter \fBbl\fR provided for that purpose.
+.Sp
+These commands should work well for most of the token types that perltidy uses
+(use \fB\-\-dump\-token\-types\fR for a list).  Also try the \-D flag on a short
+snippet of code and look at the .DEBUG file to see the tokenization.  However,
+for a few token types there may be conflicts with hardwired logic which cause
+unexpected results.  One example is curly braces, which should be controlled
+with the parameter \fBbl\fR provided for that purpose.
+.Sp
+\&\fB\s-1WARNING\s0\fR Be sure to put these tokens in quotes to avoid having them
+misinterpreted by your command shell.
 .Sh "Controlling List Formatting"
 .IX Subsection "Controlling List Formatting"
 Perltidy attempts to place comma-separated arrays of values in tables
 .Sh "Controlling List Formatting"
 .IX Subsection "Controlling List Formatting"
 Perltidy attempts to place comma-separated arrays of values in tables
@@ -1589,25 +1864,29 @@ but consider:
 \&                1, 3, 3, 1,
 \&                1, 4, 6, 4, 1,);
 .Ve
 \&                1, 3, 3, 1,
 \&                1, 4, 6, 4, 1,);
 .Ve
+.Sp
 The default formatting will flatten this down to one line:
 .Sp
 .Vb 2
 \&    # perltidy (default)
 \&    my @list = ( 1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1, );
 .Ve
 The default formatting will flatten this down to one line:
 .Sp
 .Vb 2
 \&    # perltidy (default)
 \&    my @list = ( 1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1, );
 .Ve
+.Sp
 which hides the structure. Using \fB\-boc\fR, plus additional flags
 to retain the original style, yields
 .Sp
 .Vb 6
 which hides the structure. Using \fB\-boc\fR, plus additional flags
 to retain the original style, yields
 .Sp
 .Vb 6
-\&    # perltidy -boc -lp -pt=2 -vt=1 -vtc=1
+\&    # perltidy \-boc \-lp \-pt=2 \-vt=1 \-vtc=1
 \&    my @list = (1,
 \&                1, 1,
 \&                1, 2, 1,
 \&                1, 3, 3, 1,
 \&                1, 4, 6, 4, 1,);
 .Ve
 \&    my @list = (1,
 \&                1, 1,
 \&                1, 2, 1,
 \&                1, 3, 3, 1,
 \&                1, 4, 6, 4, 1,);
 .Ve
+.Sp
 A disadvantage of this flag is that all tables in the file
 A disadvantage of this flag is that all tables in the file
-must already be nicely formatted.
+must already be nicely formatted.  For another possibility see
+the \-fs flag in \*(L"Skipping Selected Sections of Code\*(R".
 .IP "\fB\-mft=n\fR,  \fB\-\-maximum\-fields\-per\-table=n\fR" 4
 .IX Item "-mft=n,  --maximum-fields-per-table=n"
 If the computed number of fields for any table exceeds \fBn\fR, then it
 .IP "\fB\-mft=n\fR,  \fB\-\-maximum\-fields\-per\-table=n\fR" 4
 .IX Item "-mft=n,  --maximum-fields-per-table=n"
 If the computed number of fields for any table exceeds \fBn\fR, then it
@@ -1620,7 +1899,7 @@ be introduced somewhere to freeze the formatting in future applications
 of perltidy.
 .Sp
 .Vb 9
 of perltidy.
 .Sp
 .Vb 9
-\&    # perltidy -mft=2
+\&    # perltidy \-mft=2
 \&    @month_of_year = (    
 \&        'Jan', 'Feb',
 \&        'Mar', 'Apr',
 \&    @month_of_year = (    
 \&        'Jan', 'Feb',
 \&        'Mar', 'Apr',
@@ -1641,11 +1920,12 @@ being forced because \fB\-boc\fR is used).  The possible values of \fBn\fR are:
 .Vb 6
 \& n=0 break at all commas after =>  
 \& n=1 stable: break at all commas after => unless this would break
 .Vb 6
 \& n=0 break at all commas after =>  
 \& n=1 stable: break at all commas after => unless this would break
-\&     an existing one-line container (default)
+\&     an existing one\-line container (default)
 \& n=2 break at all commas after =>, but try to form the maximum
 \& n=2 break at all commas after =>, but try to form the maximum
-\&     maximum one-line container lengths
+\&     maximum one\-line container lengths
 \& n=3 do not treat commas after => specially at all
 .Ve
 \& n=3 do not treat commas after => specially at all
 .Ve
+.Sp
 For example, given the following single line, perltidy by default will
 not add any line breaks because it would break the existing one-line
 container:
 For example, given the following single line, perltidy by default will
 not add any line breaks because it would break the existing one-line
 container:
@@ -1653,15 +1933,17 @@ container:
 .Vb 1
 \&    bless { B => $B, Root => $Root } => $package;
 .Ve
 .Vb 1
 \&    bless { B => $B, Root => $Root } => $package;
 .Ve
+.Sp
 Using \fB\-cab=0\fR will force a break after each comma-arrow item:
 .Sp
 .Vb 5
 Using \fB\-cab=0\fR will force a break after each comma-arrow item:
 .Sp
 .Vb 5
-\&    # perltidy -cab=0:
+\&    # perltidy \-cab=0:
 \&    bless {
 \&        B    => $B,
 \&        Root => $Root
 \&    } => $package;
 .Ve
 \&    bless {
 \&        B    => $B,
 \&        Root => $Root
 \&    } => $package;
 .Ve
+.Sp
 If perltidy is subsequently run with this container broken, then by
 default it will break after each '=>' because the container is now
 broken.  To reform a one-line container, the parameter \fB\-cab=2\fR would
 If perltidy is subsequently run with this container broken, then by
 default it will break after each '=>' because the container is now
 broken.  To reform a one-line container, the parameter \fB\-cab=2\fR would
@@ -1674,7 +1956,7 @@ will be determined by the same rules that are used for any other table.
 Here is an example.
 .Sp
 .Vb 6
 Here is an example.
 .Sp
 .Vb 6
-\&    # perltidy -cab=3
+\&    # perltidy \-cab=3
 \&    my %last_day = (
 \&        "01" => 31, "02" => 29, "03" => 31, "04" => 30,
 \&        "05" => 31, "06" => 30, "07" => 31, "08" => 31,
 \&    my %last_day = (
 \&        "01" => 31, "02" => 29, "03" => 31, "04" => 30,
 \&        "05" => 31, "06" => 30, "07" => 31, "08" => 31,
@@ -1742,11 +2024,11 @@ A blank line will be introduced before blocks of coding delimited by
 \&\fBfor\fR, \fBforeach\fR, \fBwhile\fR, \fBuntil\fR, and \fBif\fR, \fBunless\fR, in the following
 circumstances:
 .RS 4
 \&\fBfor\fR, \fBforeach\fR, \fBwhile\fR, \fBuntil\fR, and \fBif\fR, \fBunless\fR, in the following
 circumstances:
 .RS 4
-.IP "\(bu" 4
+.IP "*" 4
 The block is not preceded by a comment.
 The block is not preceded by a comment.
-.IP "\(bu" 4
+.IP "*" 4
 The block is not a one-line block.
 The block is not a one-line block.
-.IP "\(bu" 4
+.IP "*" 4
 The number of consecutive non-blank lines at the current indentation depth is at least \fB\-lbl\fR
 (see next section).
 .RE
 The number of consecutive non-blank lines at the current indentation depth is at least \fB\-lbl\fR
 (see next section).
 .RE
@@ -1788,7 +2070,7 @@ not apply to perl) as they are sometimes implemented.  At present, this
 style overrides the default style with the following parameters:
 .Sp
 .Vb 1
 style overrides the default style with the following parameters:
 .Sp
 .Vb 1
-\&    -lp -bl -noll -pt=2 -bt=2 -sbt=2 -icp
+\&    \-lp \-bl \-noll \-pt=2 \-bt=2 \-sbt=2 \-icp
 .Ve
 .Sh "Other Controls"
 .IX Subsection "Other Controls"
 .Ve
 .Sh "Other Controls"
 .IX Subsection "Other Controls"
@@ -1854,13 +2136,14 @@ Here is an example of a \fI.perltidyrc\fR file:
 .Vb 8
 \&  # This is a simple of a .perltidyrc configuration file
 \&  # This implements a highly spaced style
 .Vb 8
 \&  # This is a simple of a .perltidyrc configuration file
 \&  # This implements a highly spaced style
-\&  -se    # errors to standard error output
-\&  -w     # show all warnings
-\&  -bl    # braces on new lines
-\&  -pt=0  # parens not tight at all
-\&  -bt=0  # braces not tight
-\&  -sbt=0 # square brackets not tight
+\&  \-se    # errors to standard error output
+\&  \-w     # show all warnings
+\&  \-bl    # braces on new lines
+\&  \-pt=0  # parens not tight at all
+\&  \-bt=0  # braces not tight
+\&  \-sbt=0 # square brackets not tight
 .Ve
 .Ve
+.Sp
 The parameters in the \fI.perltidyrc\fR file are installed first, so any
 parameters given on the command line will have priority over them.  
 .Sp
 The parameters in the \fI.perltidyrc\fR file are installed first, so any
 parameters given on the command line will have priority over them.  
 .Sp
@@ -1868,12 +2151,13 @@ To avoid confusion, perltidy ignores any command in the .perltidyrc
 file which would cause some kind of dump and an exit.  These are:
 .Sp
 .Vb 1
 file which would cause some kind of dump and an exit.  These are:
 .Sp
 .Vb 1
-\& -h -v -ddf -dln -dop -dsn -dtt -dwls -dwrs -ss
+\& \-h \-v \-ddf \-dln \-dop \-dsn \-dtt \-dwls \-dwrs \-ss
 .Ve
 .Ve
+.Sp
 There are several options may be helpful in debugging a \fI.perltidyrc\fR
 file:  
 .RS 4
 There are several options may be helpful in debugging a \fI.perltidyrc\fR
 file:  
 .RS 4
-.IP "\(bu" 4
+.IP "*" 4
 A very helpful command is \fB\-\-dump\-profile\fR or \fB\-dpro\fR.  It writes a
 list of all configuration filenames tested to standard output, and 
 if a file is found, it dumps the content to standard output before
 A very helpful command is \fB\-\-dump\-profile\fR or \fB\-dpro\fR.  It writes a
 list of all configuration filenames tested to standard output, and 
 if a file is found, it dumps the content to standard output before
@@ -1881,18 +2165,18 @@ exiting.  So, to find out where perltidy looks for its configuration
 files, and which one if any it selects, just enter 
 .Sp
 .Vb 1
 files, and which one if any it selects, just enter 
 .Sp
 .Vb 1
-\&  perltidy -dpro
+\&  perltidy \-dpro
 .Ve
 .Ve
-.IP "\(bu" 4
+.IP "*" 4
 It may be simplest to develop and test configuration files with
 alternative names, and invoke them with \fB\-pro=filename\fR on the command
 line.  Then rename the desired file to \fI.perltidyrc\fR when finished.
 It may be simplest to develop and test configuration files with
 alternative names, and invoke them with \fB\-pro=filename\fR on the command
 line.  Then rename the desired file to \fI.perltidyrc\fR when finished.
-.IP "\(bu" 4
+.IP "*" 4
 The parameters in the \fI.perltidyrc\fR file can be switched off with 
 the \fB\-npro\fR option.
 The parameters in the \fI.perltidyrc\fR file can be switched off with 
 the \fB\-npro\fR option.
-.IP "\(bu" 4
-The commands \fB\-dump\-options\fR, \fB\-dump\-defaults\fR, \fB\-dump\-long\-names\fR,
-and \fB\-dump\-short\-names\fR, all described below, may all be helpful.
+.IP "*" 4
+The commands \fB\-\-dump\-options\fR, \fB\-\-dump\-defaults\fR, \fB\-\-dump\-long\-names\fR,
+and \fB\-\-dump\-short\-names\fR, all described below, may all be helpful.
 .RE
 .RS 4
 .RE
 .RE
 .RS 4
 .RE
@@ -1907,10 +2191,11 @@ are preceded by the name of the alias (without leading dashes), like this:
 .Sp
 .Vb 4
 \&        newword {
 .Sp
 .Vb 4
 \&        newword {
-\&        -opt1
-\&        -opt2
+\&        \-opt1
+\&        \-opt2
 \&        }
 .Ve
 \&        }
 .Ve
+.Sp
 where \fBnewword\fR is the abbreviation, and \fBopt1\fR, etc, are existing parameters
 \&\fIor other abbreviations\fR.  The main syntax requirement is that
 the new abbreviation must begin on a new line.
 where \fBnewword\fR is the abbreviation, and \fBopt1\fR, etc, are existing parameters
 \&\fIor other abbreviations\fR.  The main syntax requirement is that
 the new abbreviation must begin on a new line.
@@ -1919,13 +2204,15 @@ For a
 specific example, the following line
 .Sp
 .Vb 1
 specific example, the following line
 .Sp
 .Vb 1
-\&        airy {-bl -pt=0 -bt=0 -sbt=0}
+\&        airy {\-bl \-pt=0 \-bt=0 \-sbt=0}
 .Ve
 .Ve
+.Sp
 could be placed in a \fI.perltidyrc\fR file, and then invoked at will with
 .Sp
 .Vb 1
 could be placed in a \fI.perltidyrc\fR file, and then invoked at will with
 .Sp
 .Vb 1
-\&        perltidy -airy somefile.pl
+\&        perltidy \-airy somefile.pl
 .Ve
 .Ve
+.Sp
 (Either \f(CW\*(C`\-airy\*(C'\fR or \f(CW\*(C`\-\-airy\*(C'\fR may be used).
 .IP "Skipping leading non-perl commands with \fB\-x\fR or \fB\-\-look\-for\-hash\-bang\fR" 4
 .IX Item "Skipping leading non-perl commands with -x or --look-for-hash-bang"
 (Either \f(CW\*(C`\-airy\*(C'\fR or \f(CW\*(C`\-\-airy\*(C'\fR may be used).
 .IP "Skipping leading non-perl commands with \fB\-x\fR or \fB\-\-look\-for\-hash\-bang\fR" 4
 .IX Item "Skipping leading non-perl commands with -x or --look-for-hash-bang"
@@ -1954,8 +2241,9 @@ have other uses.
 One use for \fB\-\-mangle\fR is the following:
 .Sp
 .Vb 1
 One use for \fB\-\-mangle\fR is the following:
 .Sp
 .Vb 1
-\&  perltidy --mangle myfile.pl -st | perltidy -o myfile.pl.new
+\&  perltidy \-\-mangle myfile.pl \-st | perltidy \-o myfile.pl.new
 .Ve
 .Ve
+.Sp
 This will form the maximum possible number of one-line blocks (see next
 section), and can sometimes help clean up a badly formatted script.
 .Sp
 This will form the maximum possible number of one-line blocks (see next
 section), and can sometimes help clean up a badly formatted script.
 .Sp
@@ -1972,6 +2260,7 @@ block is something like this,
 .Vb 1
 \&        if ($x > 0) { $y = 1 / $x }
 .Ve
 .Vb 1
 \&        if ($x > 0) { $y = 1 / $x }
 .Ve
+.Sp
 where the contents within the curly braces is short enough to fit
 on a single line.
 .Sp
 where the contents within the curly braces is short enough to fit
 on a single line.
 .Sp
@@ -2059,8 +2348,9 @@ The flag \fB\-html\fR causes perltidy to write an html file with extension
 \&\fI.html\fR.  So, for example, the following command
 .Sp
 .Vb 1
 \&\fI.html\fR.  So, for example, the following command
 .Sp
 .Vb 1
-\&        perltidy -html somefile.pl
+\&        perltidy \-html somefile.pl
 .Ve
 .Ve
+.Sp
 will produce a syntax-colored html file named \fIsomefile.pl.html\fR
 which may be viewed with a browser.
 .Sp
 will produce a syntax-colored html file named \fIsomefile.pl.html\fR
 which may be viewed with a browser.
 .Sp
@@ -2105,15 +2395,17 @@ pod2html, and this prefix will be removed before they are passed to
 pod2html.  The flags which have the additional \f(CW\*(C`pod\*(C'\fR prefix are:
 .Sp
 .Vb 2
 pod2html.  The flags which have the additional \f(CW\*(C`pod\*(C'\fR prefix are:
 .Sp
 .Vb 2
-\&   --[no]podheader --[no]podindex --[no]podrecurse --[no]podquiet 
-\&   --[no]podverbose --podflush
+\&   \-\-[no]podheader \-\-[no]podindex \-\-[no]podrecurse \-\-[no]podquiet 
+\&   \-\-[no]podverbose \-\-podflush
 .Ve
 .Ve
+.Sp
 The flags which are unchanged from their use in pod2html are:
 .Sp
 .Vb 2
 The flags which are unchanged from their use in pod2html are:
 .Sp
 .Vb 2
-\&   --backlink=s --cachedir=s --htmlroot=s --libpods=s --title=s
-\&   --podpath=s --podroot=s
+\&   \-\-backlink=s \-\-cachedir=s \-\-htmlroot=s \-\-libpods=s \-\-title=s
+\&   \-\-podpath=s \-\-podroot=s
 .Ve
 .Ve
+.Sp
 where 's' is an appropriate character string.  Not all of these flags are
 available in older versions of Pod::Html.  See your Pod::Html documentation for
 more information.
 where 's' is an appropriate character string.  Not all of these flags are
 available in older versions of Pod::Html.  See your Pod::Html documentation for
 more information.
@@ -2132,10 +2424,11 @@ simplifies code browsing.  Assume, for example, that the input file is
 files will be created:
 .Sp
 .Vb 3
 files will be created:
 .Sp
 .Vb 3
-\& MyModule.pm.html      - the frame
-\& MyModule.pm.toc.html  - the table of contents
-\& MyModule.pm.src.html  - the formatted source code
+\& MyModule.pm.html      \- the frame
+\& MyModule.pm.toc.html  \- the table of contents
+\& MyModule.pm.src.html  \- the formatted source code
 .Ve
 .Ve
+.Sp
 Obviously this file naming scheme requires that output be directed to a real
 file (as opposed to, say, standard output).  If this is not the
 case, or if the file extension is unknown, the \fB\-frm\fR option will be
 Obviously this file naming scheme requires that output be directed to a real
 file (as opposed to, say, standard output).  If this is not the
 case, or if the file extension is unknown, the \fB\-frm\fR option will be
@@ -2175,8 +2468,9 @@ sheet could not be written for some reason, such as if the \fB\-pre\fR flag
 was used.  Thus, for example,
 .Sp
 .Vb 1
 was used.  Thus, for example,
 .Sp
 .Vb 1
-\&  perltidy -html -ss >mystyle.css
+\&  perltidy \-html \-ss >mystyle.css
 .Ve
 .Ve
+.Sp
 will write a style sheet with the default properties to file
 \&\fImystyle.css\fR.
 .Sp
 will write a style sheet with the default properties to file
 \&\fImystyle.css\fR.
 .Sp
@@ -2198,15 +2492,15 @@ corresponding abbreviation:
 .Sp
 .Vb 19
 \&      Token Type             xxxxxx           x 
 .Sp
 .Vb 19
 \&      Token Type             xxxxxx           x 
-\&      ----------             --------         --
+\&      \-\-\-\-\-\-\-\-\-\-             \-\-\-\-\-\-\-\-         \-\-
 \&      comment                comment          c
 \&      number                 numeric          n
 \&      identifier             identifier       i
 \&      bareword, function     bareword         w
 \&      keyword                keyword          k
 \&      quite, pattern         quote            q
 \&      comment                comment          c
 \&      number                 numeric          n
 \&      identifier             identifier       i
 \&      bareword, function     bareword         w
 \&      keyword                keyword          k
 \&      quite, pattern         quote            q
-\&      here doc text          here-doc-text    h
-\&      here doc target        here-doc-target  hh
+\&      here doc text          here\-doc\-text    h
+\&      here doc target        here\-doc\-target  hh
 \&      punctuation            punctuation      pu
 \&      parentheses            paren            p
 \&      structural braces      structure        s
 \&      punctuation            punctuation      pu
 \&      parentheses            paren            p
 \&      structural braces      structure        s
@@ -2215,8 +2509,9 @@ corresponding abbreviation:
 \&      comma                  comma            cm
 \&      label                  label            j
 \&      sub definition name    subroutine       m
 \&      comma                  comma            cm
 \&      label                  label            j
 \&      sub definition name    subroutine       m
-\&      pod text               pod-text         pd
+\&      pod text               pod\-text         pd
 .Ve
 .Ve
+.Sp
 A default set of colors has been defined, but they may be changed by providing
 values to any of the following parameters, where \fBn\fR is either a 6 digit 
 hex \s-1RGB\s0 color value or an ascii name for a color, such as 'red'.
 A default set of colors has been defined, but they may be changed by providing
 values to any of the following parameters, where \fBn\fR is either a 6 digit 
 hex \s-1RGB\s0 color value or an ascii name for a color, such as 'red'.
@@ -2225,13 +2520,15 @@ To illustrate, the following command will produce an html
 file \fIsomefile.pl.html\fR with \*(L"aqua\*(R" keywords:
 .Sp
 .Vb 1
 file \fIsomefile.pl.html\fR with \*(L"aqua\*(R" keywords:
 .Sp
 .Vb 1
-\&        perltidy -html -hck=00ffff somefile.pl
+\&        perltidy \-html \-hck=00ffff somefile.pl
 .Ve
 .Ve
+.Sp
 and this should be equivalent for most browsers:
 .Sp
 .Vb 1
 and this should be equivalent for most browsers:
 .Sp
 .Vb 1
-\&        perltidy -html -hck=aqua somefile.pl
+\&        perltidy \-html \-hck=aqua somefile.pl
 .Ve
 .Ve
+.Sp
 Perltidy merely writes any non-hex names that it sees in the html file.
 The following 16 color names are defined in the \s-1HTML\s0 3.2 standard:
 .Sp
 Perltidy merely writes any non-hex names that it sees in the html file.
 The following 16 color names are defined in the \s-1HTML\s0 3.2 standard:
 .Sp
@@ -2253,28 +2550,30 @@ The following 16 color names are defined in the \s-1HTML\s0 3.2 standard:
 \&        teal    => 008080,
 \&        aqua    => 00ffff,
 .Ve
 \&        teal    => 008080,
 \&        aqua    => 00ffff,
 .Ve
+.Sp
 Many more names are supported in specific browsers, but it is safest
 to use the hex codes for other colors.  Helpful color tables can be
 located with an internet search for \*(L"\s-1HTML\s0 color tables\*(R". 
 .Sp
 Besides color, two other character attributes may be set: bold, and italics.
 To set a token type to use bold, use the flag
 Many more names are supported in specific browsers, but it is safest
 to use the hex codes for other colors.  Helpful color tables can be
 located with an internet search for \*(L"\s-1HTML\s0 color tables\*(R". 
 .Sp
 Besides color, two other character attributes may be set: bold, and italics.
 To set a token type to use bold, use the flag
-\&\fB\-html\-bold\-xxxxxx\fR or \fB\-hbx\fR, where \fBxxxxxx\fR or \fBx\fR are the long
+\&\fB\-\-html\-bold\-xxxxxx\fR or \fB\-hbx\fR, where \fBxxxxxx\fR or \fBx\fR are the long
 or short names from the above table.  Conversely, to set a token type to 
 or short names from the above table.  Conversely, to set a token type to 
-\&\s-1NOT\s0 use bold, use \fB\-nohtml\-bold\-xxxxxx\fR or \fB\-nhbx\fR.
+\&\s-1NOT\s0 use bold, use \fB\-\-nohtml\-bold\-xxxxxx\fR or \fB\-nhbx\fR.
 .Sp
 Likewise, to set a token type to use an italic font, use the flag
 .Sp
 Likewise, to set a token type to use an italic font, use the flag
-\&\fB\-html\-italic\-xxxxxx\fR or \fB\-hix\fR, where again \fBxxxxxx\fR or \fBx\fR are the
+\&\fB\-\-html\-italic\-xxxxxx\fR or \fB\-hix\fR, where again \fBxxxxxx\fR or \fBx\fR are the
 long or short names from the above table.  And to set a token type to
 long or short names from the above table.  And to set a token type to
-\&\s-1NOT\s0 use italics, use \fB\-nohtml\-italic\-xxxxxx\fR or \fB\-nhix\fR.
+\&\s-1NOT\s0 use italics, use \fB\-\-nohtml\-italic\-xxxxxx\fR or \fB\-nhix\fR.
 .Sp
 For example, to use bold braces and lime color, non\-bold, italics keywords the
 following command would be used:
 .Sp
 .Vb 1
 .Sp
 For example, to use bold braces and lime color, non\-bold, italics keywords the
 following command would be used:
 .Sp
 .Vb 1
-\&        perltidy -html -hbs -hck=00FF00 -nhbk -hik somefile.pl
+\&        perltidy \-html \-hbs \-hck=00FF00 \-nhbk \-hik somefile.pl
 .Ve
 .Ve
-The background color can be specified with \fB\-html\-color\-background=n\fR,
+.Sp
+The background color can be specified with \fB\-\-html\-color\-background=n\fR,
 or \fB\-hcbg=n\fR for short, where n is a 6 character hex \s-1RGB\s0 value.  The
 default color of text is the value given to \fBpunctuation\fR, which is
 black as a default.
 or \fB\-hcbg=n\fR for short, where n is a 6 character hex \s-1RGB\s0 value.  The
 default color of text is the value given to \fBpunctuation\fR, which is
 black as a default.
@@ -2305,8 +2604,9 @@ For example, the following parameter specifies \f(CW\*(C`sub\*(C'\fR, labels, \f
 \&\f(CW\*(C`END\*(C'\fR blocks:
 .PP
 .Vb 1
 \&\f(CW\*(C`END\*(C'\fR blocks:
 .PP
 .Vb 1
-\&   -cscl="sub : BEGIN END"
+\&   \-cscl="sub : BEGIN END"
 .Ve
 .Ve
+.PP
 (the meaning of the \-cscl parameter is described above.)  Note that
 quotes are required around the list of block types because of the
 spaces.
 (the meaning of the \-cscl parameter is described above.)  Note that
 quotes are required around the list of block types because of the
 spaces.
@@ -2330,13 +2630,15 @@ dot is added, and the backup file will be \fIsomefile.pl~\fR  .
 The following list shows all short parameter names which allow a prefix
 \&'n' to produce the negated form:
 .PP
 The following list shows all short parameter names which allow a prefix
 \&'n' to produce the negated form:
 .PP
-.Vb 5
-\&    D anl asc aws b bbb bbc bbs bli boc bok bol bot syn ce csc 
-\&    dac dbc dcsc dnl dws dp dpro dsm dsc ddf dln dop dsn dtt dwls dwrs 
-\&    f fll frm hsc html ibc icb icp iob isbc lp log lal x lsl ple pod bl 
-\&    sbl okw ola oll ple pvl q opt sbc sfs ssc sts se st sob 
-\&    t tac tbc toc tp tsc tqw w
+.Vb 6
+\& D    anl asc  aws  b    bbb bbc bbs  bl   bli  boc bok  bol  bot  ce
+\& csc  dac dbc  dcsc ddf  dln dnl dop  dp   dpro dsc dsm  dsn  dtt  dwls
+\& dwrs dws f    fll  frm  fs  hsc html ibc  icb  icp iob  isbc lal  log
+\& lp   lsl ohbr okw  ola  oll opr opt  osbr otr  ple ple  pod  pvl  q
+\& sbc  sbl schb scp  scsb sct se  sfp  sfs  skp  sob sohb sop  sosb sot
+\& ssc  st  sts  syn  t    tac tbc toc  tp   tqw  tsc w    x
 .Ve
 .Ve
+.PP
 Equivalently, the prefix 'no' or 'no\-' on the corresponding long names may be
 used.
 .SH "LIMITATIONS"
 Equivalently, the prefix 'no' or 'no\-' on the corresponding long names may be
 used.
 .SH "LIMITATIONS"
@@ -2393,7 +2695,7 @@ purpose of this rule is to prevent generating confusing filenames such as
 \&\fIperlstyle\fR\|(1), \fIPerl::Tidy\fR\|(3)
 .SH "VERSION"
 .IX Header "VERSION"
 \&\fIperlstyle\fR\|(1), \fIPerl::Tidy\fR\|(3)
 .SH "VERSION"
 .IX Header "VERSION"
-This man page documents perltidy version 20031021.
+This man page documents perltidy version 20060614.
 .SH "CREDITS"
 .IX Header "CREDITS"
 Michael Cartmell supplied code for adaptation to \s-1VMS\s0 and helped with
 .SH "CREDITS"
 .IX Header "CREDITS"
 Michael Cartmell supplied code for adaptation to \s-1VMS\s0 and helped with
@@ -2417,7 +2719,7 @@ see the \s-1CHANGES\s0 file.
 .Ve
 .SH "COPYRIGHT"
 .IX Header "COPYRIGHT"
 .Ve
 .SH "COPYRIGHT"
 .IX Header "COPYRIGHT"
-Copyright (c) 2000\-2003 by Steve Hancock
+Copyright (c) 2000\-2006 by Steve Hancock
 .SH "LICENSE"
 .IX Header "LICENSE"
 This package is free software; you can redistribute it and/or modify it
 .SH "LICENSE"
 .IX Header "LICENSE"
 This package is free software; you can redistribute it and/or modify it
index ee49994ae659c0c4d5469538af5d062bf86f5b12..07edac48b00a73c97c33f219c39d41aa16b74cd2 100644 (file)
@@ -1,11 +1,19 @@
 =head1 Perltidy Style Key
 
 =head1 Perltidy Style Key
 
-Use this document to quickly and methodically find a set of perltidy
-parameters to approximate your style.  Just read each question and
-select the best answer.  Enter your parameters in a file named
-F<.perltidyrc> (examples are listed at the end).  Then move it to one of
-the places where perltidy will find it.  You can run perltidy with the
-parameter B<-dpro> to see where these places are for your system.
+When perltidy was first developed, the main parameter choices were the number
+of indentation spaces and if the user liked cuddled else's.  As the number of
+users has grown so has the number of parameters.  Now there are so many that it
+can be difficult for a new user to find a good initial set.  This document is
+one attempt to help with this problem, and some other suggestions are given at
+the end.
+
+Use this document to methodically find a starting set of perltidy parameters to
+approximate your style.  We will be working on just one aspect of formatting at
+a time.  Just read each question and select the best answer.  Enter your
+parameters in a file named F<.perltidyrc> (examples are listed at the end).
+Then move it to one of the places where perltidy will find it.  You can run
+perltidy with the parameter B<-dpro> to see where these places are for your
+system.
 
 Before you begin, experiment using just C<perltidy filename.pl> on some
 of your files.  From the results (which you will find in files with a
 
 Before you begin, experiment using just C<perltidy filename.pl> on some
 of your files.  From the results (which you will find in files with a
@@ -49,13 +57,12 @@ Look at the statement beginning with C<$anchor>:
           . substr( $char_list, $place_2, 1 );
     }
 
           . substr( $char_list, $place_2, 1 );
     }
 
-The statement is too long for the line length (80 characters by
-default), so it has been broken into 4 lines.  The second and later
-lines have some extra "continuation indentation" to help make the start
-of the statement easy to find.  The default number of extra spaces is 2.
-If you prefer a number n different from 2, you may specify this with
-B<-ci=n>.  It is best to keep this less than the value of the primary
-indentation.
+The statement is too long for the line length (80 characters by default), so it
+has been broken into 4 lines.  The second and later lines have some extra
+"continuation indentation" to help make the start of the statement easy to
+find.  The default number of extra spaces is 2.  If you prefer a number n
+different from 2, you may specify this with B<-ci=n>.  It is probably best if
+it does not exceed the value of the primary indentation.
 
 =head2 Tabs
 
 
 =head2 Tabs
 
@@ -66,24 +73,33 @@ use B<-et=n>.  Typically, B<n> would be 8.
 
 =head2 Opening Block Brace Right or Left?
 
 
 =head2 Opening Block Brace Right or Left?
 
-Decide which of the following opening brace styles you prefer:
+Opening and closing curly braces, parentheses, and square brackets are divided
+into two separate categories and controlled separately in most cases.  The two
+categories are (1) code block curly braces, which contain perl code, and (2)
+everything else.  Basically, a code block brace is one which could contain
+semicolon-terminated lines of perl code.  We will first work on the scheme for
+code block curly braces.  
+
+Decide which of the following opening brace styles you prefer for most blocks
+of code (with the possible exception of a B<sub block brace> which will
+be covered later):
 
 If you like opening braces on the right, like this, go to 
 
 If you like opening braces on the right, like this, go to 
-L<Braces Right>.
+L<Opening Braces Right>.
 
     if ( $flag eq "h" ) {
         $headers = 0;
     }  
 
 If you like opening braces on the left, like this, go to 
 
     if ( $flag eq "h" ) {
         $headers = 0;
     }  
 
 If you like opening braces on the left, like this, go to 
-L<Braces Left>.
+L<Opening Braces Left>.
 
     if ( $flag eq "h" )
     {
         $headers = 0;
     }
 
 
     if ( $flag eq "h" )
     {
         $headers = 0;
     }
 
-=head2 Braces Right
+=head2 Opening Braces Right
 
 In a multi-line B<if> test expression, the default is to place
 the opening brace on the left, like this:
 
 In a multi-line B<if> test expression, the default is to place
 the opening brace on the left, like this:
@@ -134,10 +150,9 @@ instead of this default style?
     }
 
 If yes, you should use B<-ce>.
     }
 
 If yes, you should use B<-ce>.
+Now skip ahead to L<Opening Sub Braces>.
 
 
-Now skip ahead to L<Indentation Style for Other Containers>.
-
-=head2 Braces Left
+=head2 Opening Braces Left
 
 Use B<-bl> if you prefer this style:
 
 
 Use B<-bl> if you prefer this style:
 
@@ -156,10 +171,41 @@ Use B<-bli> if you prefer this indented-brace style:
 The number of spaces of extra indentation will be the value specified
 for continuation indentation with the B<-ci=n> parameter (2 by default).
 
 The number of spaces of extra indentation will be the value specified
 for continuation indentation with the B<-ci=n> parameter (2 by default).
 
+=head2 Opening Sub Braces
+
+By default, the opening brace of a sub block will be treated
+the same as other code blocks.  If this is okay, skip ahead
+to L<Block Brace Vertical Tightness>.
+
+If you prefer an opening sub brace to be on a new line,
+like this: 
+
+    sub message
+    {
+        # -sbl
+    }
+
+use B<-sbl>.  If you prefer the sub brace on the right like this
+
+    sub message {
+
+        # -nsbl
+    }
+
+use B<-nsbl>.
+
+If you wish to give this opening sub brace some indentation you can do
+that with the parameters B<-bli> and B<-blil> which are described in the
+manual.
+
 =head2 Block Brace Vertical Tightness
 
 =head2 Block Brace Vertical Tightness
 
-The default is to leave the opening brace on a line by itself, like this (shown
-for B<-bli>, but also true to B<-bl>):
+If you chose to put opening block braces of all types to the right, skip
+ahead to L<Closing Block Brace Indentation>.
+
+If you chose to put braces of any type on the left, the default is to leave the
+opening brace on a line by itself, like this (shown for B<-bli>, but also true
+for B<-bl>):
 
     if ( $flag eq "h" )
       {
 
     if ( $flag eq "h" )
       {
@@ -173,7 +219,7 @@ But you may also use this more compressed style if you wish:
       }
 
 If you do not prefer this more compressed form, go to 
       }
 
 If you do not prefer this more compressed form, go to 
-L<Indentation Style for Other Containers>.
+L<Opening Sub Braces>.
 
 Otherwise use parameter B<-bbvt=n>, where n=1 or n=2.  To decide,
 look at this snippet:
 
 Otherwise use parameter B<-bbvt=n>, where n=1 or n=2.  To decide,
 look at this snippet:
@@ -189,21 +235,54 @@ look at this snippet:
 
     # -bli -bbvt=2
     sub _directives
 
     # -bli -bbvt=2
     sub _directives
-      { {
+    {   {
             'ENDIF' => \&_endif,
             'ENDIF' => \&_endif,
-               'IF' => \&_if,
+            'IF'    => \&_if,
         };
         };
-      }
+    }
 
 The difference is that B<-bbvt=1> breaks after an opening brace if
 
 The difference is that B<-bbvt=1> breaks after an opening brace if
-the next line is unbalanced, whereas B<-bbvt=2> never breaks.
+the next line is unbalanced, whereas B<-bbvt=2> never breaks.  
+
+If you were expecting the 'ENDIF' word to move up vertically here, note that
+the second opening brace in the above example is not a code block brace (it is
+a hash brace), so the B<-bbvt> does not apply to it (another parameter will).
+
+=head2 Closing Block Brace Indentation
+
+The default is to place closing braces at the same indentation as the
+opening keyword or brace of that code block, as shown here:
+
+        if ($task) {
+            yyy();
+        }            # default
+
+If you chose the B<-bli> style, however, the default closing braces will be
+indented one continuation indentation like the opening brace:
+
+        if ($task)
+          {
+            yyy();
+          }    # -bli
+
+If you prefer to give closing block braces one full level of
+indentation, independently of how the opening brace is treated,
+for example like this:
+
+        if ($task) {
+            yyy();
+            }          # -icb
+
+use B<-icb>.
+
+This completes the definition of the placement of code block braces.
 
 =head2 Indentation Style for Other Containers
 
 
 =head2 Indentation Style for Other Containers
 
-You have a choice of two indentation schemes for non-block containers.
-The default is to use a fixed number of spaces per indentation level (the
-same number of spaces used for code blocks).  Here is an example of the
-default:
+You have a choice of two basic indentation schemes for non-block containers.
+The default is to use a fixed number of spaces per indentation level (the same
+number of spaces used for code blocks, which is 4 by default).  Here is an
+example of the default:
 
     $dbh = DBI->connect(
         undef, undef, undef,
 
     $dbh = DBI->connect(
         undef, undef, undef,
@@ -213,6 +292,11 @@ default:
         }
     );
 
         }
     );
 
+In this default indentation scheme, a simple formula is used to find the
+indentation of every line.  Notice how the first 'undef' is indented 4
+spaces (one level) to the right, and how 'PrintError' is indented 4 more
+speces (one more level) to the right.  
+
 The alternate is to let the location of the opening paren (or square
 bracket, or curly brace) define the indentation, like this:
 
 The alternate is to let the location of the opening paren (or square
 bracket, or curly brace) define the indentation, like this:
 
@@ -224,14 +308,23 @@ bracket, or curly brace) define the indentation, like this:
                          }
     );
 
                          }
     );
 
-If you prefer the first (default) scheme, skip ahead to 
-L<Closing Token Placement>.
+The first scheme is completely robust.  The second scheme often looks a little
+nicer, but be aware that deeply nested structures it can be spoiled if the line
+length limit is exceeded.  Also, if there are comments or blank lines within a
+complex structure perltidy will temporarily fall back on the default
+indentation scheme.  You may want to try both on large sections of code to see
+which works best.
+
+If you prefer the first (default) scheme, no parameter is needed.
 
 
-If you prefer the latter scheme, use B<-lp> and continue to the next
-section.  
+If you prefer the latter scheme, use B<-lp>. 
 
 =head2 Opening Vertical Tightness
 
 
 =head2 Opening Vertical Tightness
 
+The information in this section applies mainly to the B<-lp>
+style but it also applies in some cases to the default style.
+It will be illustrated for the B<-lp> indentation style.
+
 The default B<-lp> indentation style ends a line at the
 opening tokens, like this:
 
 The default B<-lp> indentation style ends a line at the
 opening tokens, like this:
 
@@ -252,6 +345,11 @@ with the opening tokens:
                          }
     );
 
                          }
     );
 
+The difference is that the lines have been compressed vertically without
+any changes to the indentation.  This can almost always be done with the
+B<-lp> indentation style, but only in limited cases for the default
+indentation style. 
+
 If you prefer the default, skip ahead to L<Closing Token Placement>.
 
 Otherwise, use B<-vt=n>, where B<n> should be either 1 or 2.  To help
 If you prefer the default, skip ahead to L<Closing Token Placement>.
 
 Otherwise, use B<-vt=n>, where B<n> should be either 1 or 2.  To help
@@ -290,6 +388,11 @@ after them.
 The B<-vt=2> style does not limit itself to a single indentation step
 per line.
 
 The B<-vt=2> style does not limit itself to a single indentation step
 per line.
 
+Note that in the above example the function 'do_sumething_about_it'
+started on a new line. This is because it follows an opening code
+block brace and is governed by the flag previously set in 
+L<Block Brace Vertical Tightness>.
+
 =head2 Closing Token Placement
 
 You have several options for dealing with the terminal closing tokens of
 =head2 Closing Token Placement
 
 You have several options for dealing with the terminal closing tokens of
@@ -329,10 +432,10 @@ opening paren, if possible:
                        'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
                      );
 
                        'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
                      );
 
-A third alternative, B<-cti=2>, indents a line with leading closing
+Another alternative, B<-cti=3>, indents a line with leading closing
 paren one full indentation level:
 
 paren one full indentation level:
 
-    # perltidy -lp -cti=2
+    # perltidy -lp -cti=3
     @month_of_year = (
                        'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                        'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
     @month_of_year = (
                        'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                        'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
@@ -349,8 +452,11 @@ at the end of the previous line, like this:
         'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
         'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' );
 
         'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
         'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' );
 
-Use B<-vtc=n> if you prefer to do this, where n is either 1 or 2. To
-determine n, we have to look at something more complex.  Observe the
+Perltidy will automatically do this to save space for very short lists but not
+for longer lists.
+
+Use B<-vtc=n> if you prefer to usually do this, where B<n> is either 1 or 2. To
+determine B<n>, we have to look at something more complex.  Observe the
 behavior of the closing tokens in the following snippet:
 
 Here is B<-lp -vtc=1>:
 behavior of the closing tokens in the following snippet:
 
 Here is B<-lp -vtc=1>:
@@ -374,7 +480,6 @@ Here is B<-lp -vtc=2>:
                           $self->read_value(
                                              $lookup->{'VFMT2'},
                                              $loc, $lookup, $fh ) ];
                           $self->read_value(
                                              $lookup->{'VFMT2'},
                                              $loc, $lookup, $fh ) ];
 
 Choose the one that you prefer.  The difference is that B<-vtc=1> leaves
 closing tokens at the start of a line within a list, which can assist in
 
 Choose the one that you prefer.  The difference is that B<-vtc=1> leaves
 closing tokens at the start of a line within a list, which can assist in
@@ -385,6 +490,66 @@ If you choose B<-vtc=1>,
 you may also want to specify a value of B<-cti=n> (previous section) to
 handle cases where a line begins with a closing paren.
 
 you may also want to specify a value of B<-cti=n> (previous section) to
 handle cases where a line begins with a closing paren.
 
+=head2 Stack Opening Tokens
+
+In the following snippet the opening hash brace has been placed
+alone on a new line.  
+
+    $opt_c = Text::CSV_XS->new(
+        {
+            binary       => 1,
+            sep_char     => $opt_c,
+            always_quote => 1,
+        }
+    );
+
+If you prefer to avoid isolated opening opening tokens by
+"stacking" them together with other opening tokens like this:
+
+    $opt_c = Text::CSV_XS->new( {
+            binary       => 1,
+            sep_char     => $opt_c,
+            always_quote => 1,
+        }
+    );
+
+use B<-sot>.
+
+=head2 Stack Closing Tokens
+
+Likewise, in the same snippet the default formatting leaves
+the closing paren on a line by itself here:
+
+    $opt_c = Text::CSV_XS->new(
+        {
+            binary       => 1,
+            sep_char     => $opt_c,
+            always_quote => 1,
+        }
+    );
+
+If you would like to avoid leaving isolated closing tokens by
+stacking them with other closing tokens, like this:
+
+    $opt_c = Text::CSV_XS->new(
+        {
+            binary       => 1,
+            sep_char     => $opt_c,
+            always_quote => 1,
+        } );
+
+use B<-sct>.
+
+The B<-sct> flag is somewhat similar to the B<-vtc> flags, and in some cases it
+can give a similar result.  The difference is that the B<-vtc> flags try to
+avoid lines with leading opening tokens by "hiding" them at the end of a
+previous line, whereas the B<-sct> flag merely tries to reduce the number of
+lines with isolated closing tokens by stacking multiple closing tokens
+together, but it does not try to hide them.  
+
+The manual shows how all of these vertical tightness controls may be applied
+independently to each type of non-block opening and opening token.
+
 =head2 Define Horizontal Tightness
 
 Horizontal tightness parameters define how much space is included
 =head2 Define Horizontal Tightness
 
 Horizontal tightness parameters define how much space is included
@@ -422,6 +587,36 @@ B<-bbt=n> you prefer:
  %bf = map { $_ => -M $_ } grep {/\.deb$/} dirents '.';   # -bbt=1
  %bf = map {$_ => -M $_} grep {/\.deb$/} dirents '.';     # -bbt=2
 
  %bf = map { $_ => -M $_ } grep {/\.deb$/} dirents '.';   # -bbt=1
  %bf = map {$_ => -M $_} grep {/\.deb$/} dirents '.';     # -bbt=2
 
+=head2 Spaces between function names and opening parens
+
+The default is not to place a space after a function call:
+
+  myfunc( $a, $b, $c );    # default 
+
+If you prefer a space:
+
+  myfunc ( $a, $b, $c );   # -sfp
+
+use B<-sfp>.
+
+=head2 Spaces between Perl keywords and parens
+
+The default is to place a space between only these keywords
+and an opening paren:
+
+   my local our and or eq ne if else elsif until unless 
+   while for foreach return switch case given when
+
+but no others. For example, the default is:
+
+    $aa = pop(@bb);
+
+If you want a space between all Perl keywords and an opening paren,
+
+    $aa = pop (@bb);
+
+use B<-skp>.  For detailed control of individual keywords, see the manual.
+
 =head2 Statement Termination Semicolon Spaces
 
 The default is not to put a space before a statement termination
 =head2 Statement Termination Semicolon Spaces
 
 The default is not to put a space before a statement termination
@@ -431,7 +626,7 @@ semicolon, like this:
 
 If you prefer a space, like this:
 
 
 If you prefer a space, like this:
 
-       $i = 1 ; 
+    $i = 1 ; 
 
 enter B<-sts>.
 
 
 enter B<-sts>.
 
@@ -466,6 +661,8 @@ If block comments may only be indented if they have some space
 characters before the leading C<#> character in the input file, use
 B<-isbc>.
 
 characters before the leading C<#> character in the input file, use
 B<-isbc>.
 
+The manual shows many other options for controlling comments.
+
 =head2 Outdenting Long Quotes
 
 Long quoted strings may exceed the specified line length limit.  The
 =head2 Outdenting Long Quotes
 
 Long quoted strings may exceed the specified line length limit.  The
@@ -491,6 +688,12 @@ the quote.  If you prefer to leave the quote indented, like this:
 
 use B<-nolq>.
 
 
 use B<-nolq>.
 
+=head2 Many Other Parameters
+
+This document has only covered the most popular parameters.  The manual
+contains many more and should be consulted if you did not find what you need
+here.
+
 =head2 Example F<.perltidyrc> files
 
 Now gather together all of the parameters you prefer and enter them
 =head2 Example F<.perltidyrc> files
 
 Now gather together all of the parameters you prefer and enter them
@@ -554,8 +757,8 @@ for a F<.perltidyrc> file containing these parameters:
 =head2 Additional Information
 
 This document has covered the main parameters.  Many more parameters are
 =head2 Additional Information
 
 This document has covered the main parameters.  Many more parameters are
-available for special purposes and for fine-tuning a style.  For 
-complete information see the perltidy manual
+available for special purposes and for fine-tuning a style.  For complete
+information see the perltidy manual
 http://perltidy.sourceforge.net/perltidy.html
 
 For an introduction to using perltidy, see the tutorial 
 http://perltidy.sourceforge.net/perltidy.html
 
 For an introduction to using perltidy, see the tutorial 
index df8fcf2937c2b8e5f7050bdfbf7d2711cb5c6c89..ed2465098c93692eebbd8fe2dd5473d6ca9c89fc 100644 (file)
@@ -8,7 +8,11 @@ lextest  - needed by testfa. and testff.t
 
 bbtidy.pl - a main program which works as a filter under BBEdit+MacPerl
 
 
 bbtidy.pl - a main program which works as a filter under BBEdit+MacPerl
 
-perltidy.bat - sample batch file for msdos installations
+pt.bat - sample batch file for msdos installations
+        (change name to perltidy.bat)
+
+perltidyrc_dump.pl - a program to dump a .perltidyrc file
+    see comments inside for usage
 
 Some examples of a user defined callback object to parse perl:
 --------------------------------------------------------------
 
 Some examples of a user defined callback object to parse perl:
 --------------------------------------------------------------
index b38452d6a894a92b11c49a01c623a9bc3f7a6314..e764397491f354668a0311cca11a2e9bba55c2a8 100644 (file)
@@ -8,7 +8,7 @@
 #
 # where -l specifies the maximum comment line length.
 #
 #
 # where -l specifies the maximum comment line length.
 #
-# You will be given an opportunity to accept or reject eacy proposed
+# You will be given an opportunity to accept or reject each proposed
 # change.
 #
 # This file demonstrates using Perl::Tidy to walk through a perl file
 # change.
 #
 # This file demonstrates using Perl::Tidy to walk through a perl file
@@ -224,9 +224,9 @@ sub queryu {
 }
 
 sub ifyes {
 }
 
 sub ifyes {
-    my $ans   = queryu(@_);
     my $count = 0;
   ASK:
     my $count = 0;
   ASK:
+    my $ans   = queryu(@_);
     if    ( $ans =~ /^Y/ ) { return 1 }
     elsif ( $ans =~ /^N/ ) { return 0 }
     else {
     if    ( $ans =~ /^Y/ ) { return 1 }
     elsif ( $ans =~ /^N/ ) { return 0 }
     else {
diff --git a/examples/perltidy.bat b/examples/perltidy.bat
deleted file mode 100644 (file)
index 5ac12a6..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-@echo off\r
-rem batch file to run perltidy under msdos\r
-perl -S perltidy %1 %2 %3 %4 %5 %6 %7 %8 %9\r
diff --git a/examples/perltidyrc_dump.pl b/examples/perltidyrc_dump.pl
new file mode 100644 (file)
index 0000000..4ec2115
--- /dev/null
@@ -0,0 +1,316 @@
+#!/usr/bin/perl -w
+use strict;
+
+# This program reads .perltidyrc files and writes them back out
+# into a standard format (but comments will be lost).
+#
+# It also demonstrates how to use the perltidy 'options-dump' and related call
+# parameters to read a .perltidyrc file, convert to long names, put it in a
+# hash, and write back to standard output in sorted order.  Requires
+# Perl::Tidy.
+#
+# Steve Hancock, June 2006
+#
+my $usage = <<EOM;
+ usage:
+ perltidyrc_dump.pl [-d -s -q -h] [ filename ]
+  filename is the name of a .perltidyrc config file to dump, or
+   if no filename is given, find and dump the system default .perltidyrc.
+  -d delete options which are the same as Perl::Tidy defaults 
+     (default is to keep them)
+  -s write short parameter names
+     (default is long names with short name in side comment)
+  -q quiet: no comments 
+  -h help
+EOM
+use Getopt::Std;
+my %my_opts;
+my $cmdline = $0 . " " . join " ", @ARGV;
+getopts( 'hdsq', \%my_opts ) or die "$usage";
+if ( $my_opts{h} ) { die "$usage" }
+if ( @ARGV > 1 )   { die "$usage" }
+
+my $config_file = $ARGV[0];
+my (
+    $error_message, $rOpts,          $rGetopt_flags,
+    $rsections,     $rabbreviations, $rOpts_default,
+    $rabbreviations_default,
+
+) = read_perltidyrc($config_file);
+
+# always check the error message first
+if ($error_message) {
+    die "$error_message\n";
+}
+
+# make a list of perltidyrc options which are same as default
+my %equals_default;
+foreach my $long_name ( keys %{$rOpts} ) {
+    my $val = $rOpts->{$long_name};
+    if ( defined( $rOpts_default->{$long_name} ) ) {
+        my $val2 = $rOpts_default->{$long_name};
+        if ( defined($val2) && defined($val) ) {
+            $equals_default{$long_name} = ( $val2 eq $val );
+        }
+    }
+}
+
+# Optional: minimize the perltidyrc file length by deleting long_names
+# in $rOpts which are also in $rOpts_default and have the same value.
+# This would be useful if a perltidyrc file has been constructed from a
+# full parameter dump, for example.
+if ( $my_opts{d} ) {
+    foreach my $long_name ( keys %{$rOpts} ) {
+        delete $rOpts->{$long_name} if $equals_default{$long_name};
+    }
+}
+
+# find user-defined abbreviations
+my %abbreviations_user;
+foreach my $key ( keys %$rabbreviations ) {
+    unless ( $rabbreviations_default->{$key} ) {
+        $abbreviations_user{$key} = $rabbreviations->{$key};
+    }
+}
+
+# dump the options, if any
+if ( %$rOpts || %abbreviations_user ) {
+    dump_options( $cmdline, \%my_opts, $rOpts, $rGetopt_flags, $rsections,
+        $rabbreviations, \%equals_default, \%abbreviations_user );
+}
+else {
+    if ($config_file) {
+        print STDERR <<EOM;
+No configuration parameters seen in file: $config_file
+EOM
+    }
+    else {
+        print STDERR <<EOM;
+No .perltidyrc file found, use perltidy -dpro to see locations checked.
+EOM
+    }
+}
+
+sub dump_options {
+
+    # write the options back out as a valid .perltidyrc file
+    # This version writes long names by sections
+    my ( $cmdline, $rmy_opts, $rOpts, $rGetopt_flags, $rsections,
+        $rabbreviations, $requals_default, $rabbreviations_user )
+      = @_;
+
+    # $rOpts is a reference to the hash returned by Getopt::Long
+    # $rGetopt_flags are the flags passed to Getopt::Long
+    # $rsections is a hash giving manual section {long_name}
+
+    # build a hash giving section->long_name->parameter_value
+    # so that we can write parameters by section
+    my %section_and_name;
+    my $rsection_name_value = \%section_and_name;
+    my %saw_section;
+    foreach my $long_name ( keys %{$rOpts} ) {
+        my $section = $rsections->{$long_name};
+        $section = "UNKNOWN" unless ($section);    # shouldn't happen
+
+        # build a hash giving section->long_name->parameter_value
+        $rsection_name_value->{$section}->{$long_name} = $rOpts->{$long_name};
+
+        # remember what sections are in this hash
+        $saw_section{$section}++;
+    }
+
+    # build a table for long_name->short_name abbreviations
+    my %short_name;
+    foreach my $abbrev ( keys %{$rabbreviations} ) {
+        foreach my $abbrev ( sort keys %$rabbreviations ) {
+            my @list = @{ $$rabbreviations{$abbrev} };
+
+            # an abbreviation may expand into one or more other words,
+            # but only those that expand to a single word (which must be
+            # one of the long names) are the short names that we want
+            # here.
+            next unless @list == 1;
+            my $long_name = $list[0];
+            $short_name{$long_name} = $abbrev;
+        }
+    }
+
+    unless ( $rmy_opts->{q} ) {
+        my $date = localtime();
+        print "# perltidy configuration file created $date\n";
+        print "# using: $cmdline\n";
+    }
+
+    # loop to write section-by-section
+    foreach my $section ( sort keys %saw_section ) {
+        unless ( $rmy_opts->{q} ) {
+            print "\n";
+
+            # remove leading section number, which is there
+            # for sorting, i.e.,
+            # 1. Basic formatting options -> Basic formatting options
+            my $trimmed_section = $section;
+            $trimmed_section =~ s/^\d+\. //;
+            print "# $trimmed_section\n";
+        }
+
+        # loop over all long names for this section
+        my $rname_value = $rsection_name_value->{$section};
+        foreach my $long_name ( sort keys %{$rname_value} ) {
+
+            # pull out getopt flag and actual parameter value
+            my $flag  = $rGetopt_flags->{$long_name};
+            my $value = $rname_value->{$long_name};
+
+            # turn this it back into a parameter
+            my $prefix       = '--';
+            my $short_prefix = '-';
+            my $suffix       = "";
+            if ($flag) {
+                if ( $flag =~ /^=/ ) {
+                    if ( $value !~ /^\d+$/ ) { $value = '"' . $value . '"' }
+                    $suffix = "=" . $value;
+                }
+                elsif ( $flag =~ /^!/ ) {
+                    $prefix       .= "no" unless ($value);
+                    $short_prefix .= "n"  unless ($value);
+                }
+                elsif ( $flag =~ /^:/ ) {
+                    if ( $value !~ /^\d+$/ ) { $value = '"' . $value . '"' }
+                    $suffix = "=" . $value;
+                }
+                else {
+
+                    # shouldn't happen
+                    print
+"# ERROR in dump_options: unrecognized flag $flag for $long_name\n";
+                }
+            }
+
+            # print the long version of the parameter
+            # with the short version as a side comment
+            my $short_name   = $short_name{$long_name};
+            my $short_option = $short_prefix . $short_name . $suffix;
+            my $long_option  = $prefix . $long_name . $suffix;
+            my $note = $requals_default->{$long_name} ? "  [=default]" : "";
+            if ( $rmy_opts->{s} ) {
+                print $short_option. "\n";
+            }
+            else {
+                my $side_comment = "";
+                unless ( $rmy_opts->{q} ) {
+                    my $spaces = 40 - length($long_option);
+                    $spaces = 2 if ( $spaces < 2 );
+                    $side_comment =
+                      ' ' x $spaces . '# ' . $short_option . $note;
+                }
+                print $long_option . $side_comment . "\n";
+            }
+        }
+    }
+
+    if ( %{$rabbreviations_user} ) {
+        unless ( $rmy_opts->{q} ) {
+            print "\n";
+            print "# Abbreviations\n";
+        }
+        foreach my $key ( keys %$rabbreviations_user ) {
+            my @vals = @{ $rabbreviations_user->{$key} };
+            print $key. ' {' . join( ' ', @vals ) . '}' . "\n";
+        }
+    }
+}
+
+sub read_perltidyrc {
+
+    # Example routine to have Perl::Tidy read and validate perltidyrc
+    # file, and return related flags and abbreviations.
+    #
+    # input parameter -
+    #   $config_file is the name of a .perltidyrc file we want to read
+    #   or a reference to a string or array containing the .perltidyrc file
+    #   if not defined, Perl::Tidy will try to find the user's .perltidyrc
+    # output parameters -
+    #   $error_message will be blank unless an error occurs
+    #   $rOpts - reference to the hash of options in the .perlticyrc
+    # NOTE:
+    #   Perl::Tidy will croak or die on certain severe errors
+
+    my ($config_file) = @_;
+    my $error_message = "";
+    my %Opts;    # any options found will be put here
+
+    # the module must be installed for this to work
+    eval "use Perl::Tidy";
+    if ($@) {
+        $error_message = "Perl::Tidy not installed\n";
+        return ( $error_message, \%Opts );
+    }
+
+    # be sure this version supports this
+    my $version = $Perl::Tidy::VERSION;
+    if ( $version < 20060528 ) {
+        $error_message = "perltidy version $version cannot read options\n";
+        return ( $error_message, \%Opts );
+    }
+
+    my $stderr = "";    # try to capture error messages
+    my $argv   = "";    # do not let perltidy see our @ARGV
+
+    # we are going to make two calls to perltidy...
+    # first with an empty .perltidyrc to get the default parameters
+    my $empty_file = "";    # this will be our .perltidyrc file
+    my %Opts_default;       # this will receive the default options hash
+    my %abbreviations_default;
+    Perl::Tidy::perltidy(
+        perltidyrc         => \$empty_file,
+        dump_options       => \%Opts_default,
+        dump_options_type  => 'full',                  # 'full' gives everything
+        dump_abbreviations => \%abbreviations_default,
+        stderr             => \$stderr,
+        argv               => \$argv,
+    );
+
+    # now we call with a .perltidyrc file to get its parameters
+    my %Getopt_flags;
+    my %sections;
+    my %abbreviations;
+    Perl::Tidy::perltidy(
+        perltidyrc            => $config_file,
+        dump_options          => \%Opts,
+        dump_options_type     => 'perltidyrc',      # default is 'perltidyrc'
+        dump_getopt_flags     => \%Getopt_flags,
+        dump_options_category => \%sections,
+        dump_abbreviations    => \%abbreviations,
+        stderr                => \$stderr,
+        argv                  => \$argv,
+    );
+
+    # try to capture any errors generated by perltidy call
+    # but for severe errors it will typically croak
+    $error_message .= $stderr;
+
+    # debug: show how everything is stored by printing it out
+    my $DEBUG = 0;
+    if ($DEBUG) {
+        print "---Getopt Parameters---\n";
+        foreach my $key ( sort keys %Getopt_flags ) {
+            print "$key$Getopt_flags{$key}\n";
+        }
+        print "---Manual Sections---\n";
+        foreach my $key ( sort keys %sections ) {
+            print "$key -> $sections{$key}\n";
+        }
+        print "---Abbreviations---\n";
+        foreach my $key ( sort keys %abbreviations ) {
+            my @names = @{ $abbreviations{$key} };
+            print "$key -> {@names}\n";
+            unless ( $abbreviations_default{$key} ) {
+                print "NOTE: $key is user defined\n";
+            }
+        }
+    }
+
+    return ( $error_message, \%Opts, \%Getopt_flags, \%sections,
+        \%abbreviations, \%Opts_default, \%abbreviations_default, );
+}
diff --git a/examples/pt.bat b/examples/pt.bat
new file mode 100644 (file)
index 0000000..5ac12a6
--- /dev/null
@@ -0,0 +1,3 @@
+@echo off\r
+rem batch file to run perltidy under msdos\r
+perl -S perltidy %1 %2 %3 %4 %5 %6 %7 %8 %9\r
index 70ee6200656f8f4c53d68ab5e1eb09c71cfa849b..e69780c75b3de53dccf003943ac5c5cfa5ad9be7 100644 (file)
@@ -2,7 +2,7 @@
 #
 #    perltidy - a perl script indenter and formatter
 #
 #
 #    perltidy - a perl script indenter and formatter
 #
-#    Copyright (c) 2000-2003 by Steve Hancock
+#    Copyright (c) 2000-2006 by Steve Hancock
 #    Distributed under the GPL license agreement; see file COPYING
 #
 #    This program is free software; you can redistribute it and/or modify
 #    Distributed under the GPL license agreement; see file COPYING
 #
 #    This program is free software; you can redistribute it and/or modify
@@ -34,6 +34,7 @@
 #        create a Perl::Tidy module which can operate on strings, arrays, etc.
 #      Yves Orton supplied coding to help detect Windows versions.
 #      Axel Rose supplied a patch for MacPerl.
 #        create a Perl::Tidy module which can operate on strings, arrays, etc.
 #      Yves Orton supplied coding to help detect Windows versions.
 #      Axel Rose supplied a patch for MacPerl.
+#      Sebastien Aperghis-Tramoni supplied a patch for the defined or operator.
 #      Many others have supplied key ideas, suggestions, and bug reports;
 #        see the CHANGES file.
 #
 #      Many others have supplied key ideas, suggestions, and bug reports;
 #        see the CHANGES file.
 #
@@ -62,7 +63,7 @@ use IO::File;
 use File::Basename;
 
 BEGIN {
 use File::Basename;
 
 BEGIN {
-    ( $VERSION = q($Id: Tidy.pm,v 1.46 2003/10/21 14:09:29 perltidy Exp $) ) =~ s/^.*\s+(\d+)\/(\d+)\/(\d+).*$/$1$2$3/; # all one line for MakeMaker
+    ( $VERSION = q($Id: Tidy.pm,v 1.49 2006/06/14 01:56:24 perltidy Exp $) ) =~ s/^.*\s+(\d+)\/(\d+)\/(\d+).*$/$1$2$3/; # all one line for MakeMaker
 }
 
 sub streamhandle {
 }
 
 sub streamhandle {
@@ -318,20 +319,27 @@ sub make_temporary_filename {
     sub perltidy {
 
         my %defaults = (
     sub perltidy {
 
         my %defaults = (
-            argv        => undef,
-            destination => undef,
-            formatter   => undef,
-            logfile     => undef,
-            errorfile   => undef,
-            perltidyrc  => undef,
-            source      => undef,
-            stderr      => undef,
+            argv                  => undef,
+            destination           => undef,
+            formatter             => undef,
+            logfile               => undef,
+            errorfile             => undef,
+            perltidyrc            => undef,
+            source                => undef,
+            stderr                => undef,
+            dump_options          => undef,
+            dump_options_type     => undef,
+            dump_getopt_flags     => undef,
+            dump_options_category => undef,
+            dump_options_range    => undef,
+            dump_abbreviations    => undef,
         );
 
         # don't overwrite callers ARGV
         local @ARGV = @ARGV;
 
         my %input_hash = @_;
         );
 
         # don't overwrite callers ARGV
         local @ARGV = @ARGV;
 
         my %input_hash = @_;
+
         if ( my @bad_keys = grep { !exists $defaults{$_} } keys %input_hash ) {
             local $" = ')(';
             my @good_keys = sort keys %defaults;
         if ( my @bad_keys = grep { !exists $defaults{$_} } keys %input_hash ) {
             local $" = ')(';
             my @good_keys = sort keys %defaults;
@@ -345,6 +353,25 @@ perltidy only understands : (@good_keys)
 EOM
         }
 
 EOM
         }
 
+        my $get_hash_ref = sub {
+            my ($key) = @_;
+            my $hash_ref = $input_hash{$key};
+            if ( defined($hash_ref) ) {
+                unless ( ref($hash_ref) eq 'HASH' ) {
+                    my $what   = ref($hash_ref);
+                    my $but_is =
+                      $what ? "but is ref to $what" : "but is not a reference";
+                    croak <<EOM;
+------------------------------------------------------------------------
+error in call to perltidy:
+-$key must be reference to HASH $but_is
+------------------------------------------------------------------------
+EOM
+                }
+            }
+            return $hash_ref;
+        };
+
         %input_hash = ( %defaults, %input_hash );
         my $argv               = $input_hash{'argv'};
         my $destination_stream = $input_hash{'destination'};
         %input_hash = ( %defaults, %input_hash );
         my $argv               = $input_hash{'argv'};
         my $destination_stream = $input_hash{'destination'};
@@ -355,6 +382,34 @@ EOM
         my $stderr_stream      = $input_hash{'stderr'};
         my $user_formatter     = $input_hash{'formatter'};
 
         my $stderr_stream      = $input_hash{'stderr'};
         my $user_formatter     = $input_hash{'formatter'};
 
+        # various dump parameters
+        my $dump_options_type     = $input_hash{'dump_options_type'};
+        my $dump_options          = $get_hash_ref->('dump_options');
+        my $dump_getopt_flags     = $get_hash_ref->('dump_getopt_flags');
+        my $dump_options_category = $get_hash_ref->('dump_options_category');
+        my $dump_abbreviations    = $get_hash_ref->('dump_abbreviations');
+        my $dump_options_range    = $get_hash_ref->('dump_options_range');
+
+        # validate dump_options_type
+        if ( defined($dump_options) ) {
+            unless ( defined($dump_options_type) ) {
+                $dump_options_type = 'perltidyrc';
+            }
+            unless ( $dump_options_type =~ /^(perltidyrc|full)$/ ) {
+                croak <<EOM;
+------------------------------------------------------------------------
+Please check value of -dump_options_type in call to perltidy;
+saw: '$dump_options_type' 
+expecting: 'perltidyrc' or 'full'
+------------------------------------------------------------------------
+EOM
+
+            }
+        }
+        else {
+            $dump_options_type = "";
+        }
+
         if ($user_formatter) {
 
             # if the user defines a formatter, there is no output stream,
         if ($user_formatter) {
 
             # if the user defines a formatter, there is no output stream,
@@ -433,12 +488,61 @@ EOM
         }
 
         # handle command line options
         }
 
         # handle command line options
-        my ( $rOpts, $config_file, $rraw_options, $saw_extrude ) =
-          process_command_line(
-            $perltidyrc_stream, $is_Windows,
-            $Windows_type,      $rpending_complaint
+        my ( $rOpts, $config_file, $rraw_options, $saw_extrude, $roption_string,
+            $rexpansion, $roption_category, $roption_range )
+          = process_command_line(
+            $perltidyrc_stream,  $is_Windows, $Windows_type,
+            $rpending_complaint, $dump_options_type,
           );
 
           );
 
+        # return or exit immediately after all dumps
+        my $quit_now = 0;
+
+        # Getopt parameters and their flags
+        if ( defined($dump_getopt_flags) ) {
+            $quit_now = 1;
+            foreach my $op ( @{$roption_string} ) {
+                my $opt  = $op;
+                my $flag = "";
+                if ( $opt =~ /(.*)(!|=.*|:.*)$/ ) {
+                    $opt  = $1;
+                    $flag = $2;
+                }
+                $dump_getopt_flags->{$opt} = $flag;
+            }
+        }
+
+        if ( defined($dump_options_category) ) {
+            $quit_now = 1;
+            %{$dump_options_category} = %{$roption_category};
+        }
+
+        if ( defined($dump_options_range) ) {
+            $quit_now = 1;
+            %{$dump_options_range} = %{$roption_range};
+        }
+
+        if ( defined($dump_abbreviations) ) {
+            $quit_now = 1;
+            %{$dump_abbreviations} = %{$rexpansion};
+        }
+
+        if ( defined($dump_options) ) {
+            $quit_now = 1;
+            %{$dump_options} = %{$rOpts};
+        }
+
+        return if ($quit_now);
+
+        # dump from command line
+        if ( $rOpts->{'dump-options'} ) {
+            dump_options( $rOpts, $roption_string );
+            exit 1;
+        }
+
+        check_options( $rOpts, $is_Windows, $Windows_type,
+            $rpending_complaint );
+
         if ($user_formatter) {
             $rOpts->{'format'} = 'user';
         }
         if ($user_formatter) {
             $rOpts->{'format'} = 'user';
         }
@@ -974,14 +1078,16 @@ sub write_logfile_header {
         "To find error messages search for 'WARNING' with your editor\n");
 }
 
         "To find error messages search for 'WARNING' with your editor\n");
 }
 
-sub process_command_line {
-
-    my ( $perltidyrc_stream, $is_Windows, $Windows_type, $rpending_complaint ) =
-      @_;
-
-    use Getopt::Long;
+sub generate_options {
 
     ######################################################################
 
     ######################################################################
+    # Generate and return references to:
+    #  @option_string - the list of options to be passed to Getopt::Long
+    #  @defaults - the list of default options
+    #  %expansion - a hash showing how all abbreviations are expanded
+    #  %category - a hash giving the general category of each option
+    #  %option_range - a hash giving the valid ranges of certain options
+
     # Note: a few options are not documented in the man page and usage
     # message. This is because these are experimental or debug options and
     # may or may not be retained in future versions.
     # Note: a few options are not documented in the man page and usage
     # message. This is because these are experimental or debug options and
     # may or may not be retained in future versions.
@@ -1013,9 +1119,30 @@ sub process_command_line {
     # Define the option string passed to GetOptions.
     #---------------------------------------------------------------
 
     # Define the option string passed to GetOptions.
     #---------------------------------------------------------------
 
-    my @option_string = ();
-    my %expansion     = ();
-    my $rexpansion    = \%expansion;
+    my @option_string   = ();
+    my %expansion       = ();
+    my %option_category = ();
+    my %option_range    = ();
+    my $rexpansion      = \%expansion;
+
+    # names of categories in manual
+    # leading integers will allow sorting
+    my @category_name = (
+        '0. I/O control',
+        '1. Basic formatting options',
+        '2. Code indentation control',
+        '3. Whitespace control',
+        '4. Comment controls',
+        '5. Linebreak controls',
+        '6. Controlling list formatting',
+        '7. Retaining or ignoring existing line breaks',
+        '8. Blank line control',
+        '9. Other controls',
+        '10. HTML options',
+        '11. pod2html options',
+        '12. Controlling HTML properties',
+        '13. Debugging',
+    );
 
     #  These options are parsed directly by perltidy:
     #    help h
 
     #  These options are parsed directly by perltidy:
     #    help h
@@ -1032,10 +1159,21 @@ sub process_command_line {
       recombine!
     );
 
       recombine!
     );
 
+    my $category = 13;    # Debugging
+    foreach (@option_string) {
+        my $opt = $_;     # must avoid changing the actual flag
+        $opt =~ s/!$//;
+        $option_category{$opt} = $category_name[$category];
+    }
+
+    $category = 11;                                       # HTML
+    $option_category{html} = $category_name[$category];
+
     # routine to install and check options
     my $add_option = sub {
         my ( $long_name, $short_name, $flag ) = @_;
         push @option_string, $long_name . $flag;
     # routine to install and check options
     my $add_option = sub {
         my ( $long_name, $short_name, $flag ) = @_;
         push @option_string, $long_name . $flag;
+        $option_category{$long_name} = $category_name[$category];
         if ($short_name) {
             if ( $expansion{$short_name} ) {
                 my $existing_name = $expansion{$short_name}[0];
         if ($short_name) {
             if ( $expansion{$short_name} ) {
                 my $existing_name = $expansion{$short_name}[0];
@@ -1058,139 +1196,261 @@ sub process_command_line {
 
     # Install long option names which have a simple abbreviation.
     # Options with code '!' get standard negation ('no' for long names,
 
     # Install long option names which have a simple abbreviation.
     # Options with code '!' get standard negation ('no' for long names,
-    # 'n' for abbreviations)
-    $add_option->( 'DEBUG',                                     'D',     '!' );
-    $add_option->( 'DIAGNOSTICS',                               'I',     '!' );
-    $add_option->( 'add-newlines',                              'anl',   '!' );
+    # 'n' for abbreviations).  Categories follow the manual.
+
+    ###########################
+    $category = 0;    # I/O_Control
+    ###########################
+    $add_option->( 'backup-and-modify-in-place', 'b',     '!' );
+    $add_option->( 'backup-file-extension',      'bext',  '=s' );
+    $add_option->( 'force-read-binary',          'f',     '!' );
+    $add_option->( 'format',                     'fmt',   '=s' );
+    $add_option->( 'logfile',                    'log',   '!' );
+    $add_option->( 'logfile-gap',                'g',     ':i' );
+    $add_option->( 'outfile',                    'o',     '=s' );
+    $add_option->( 'output-file-extension',      'oext',  '=s' );
+    $add_option->( 'output-path',                'opath', '=s' );
+    $add_option->( 'profile',                    'pro',   '=s' );
+    $add_option->( 'quiet',                      'q',     '!' );
+    $add_option->( 'standard-error-output',      'se',    '!' );
+    $add_option->( 'standard-output',            'st',    '!' );
+    $add_option->( 'warning-output',             'w',     '!' );
+
+    ########################################
+    $category = 1;    # Basic formatting options
+    ########################################
+    $add_option->( 'check-syntax',             'syn',  '!' );
+    $add_option->( 'entab-leading-whitespace', 'et',   '=i' );
+    $add_option->( 'indent-columns',           'i',    '=i' );
+    $add_option->( 'maximum-line-length',      'l',    '=i' );
+    $add_option->( 'output-line-ending',       'ole',  '=s' );
+    $add_option->( 'perl-syntax-check-flags',  'pscf', '=s' );
+    $add_option->( 'preserve-line-endings',    'ple',  '!' );
+    $add_option->( 'tabs',                     't',    '!' );
+
+    ########################################
+    $category = 2;    # Code indentation control
+    ########################################
+    $add_option->( 'continuation-indentation',           'ci',   '=i' );
+    $add_option->( 'starting-indentation-level',         'sil',  '=i' );
+    $add_option->( 'line-up-parentheses',                'lp',   '!' );
+    $add_option->( 'outdent-keyword-list',               'okwl', '=s' );
+    $add_option->( 'outdent-keywords',                   'okw',  '!' );
+    $add_option->( 'outdent-labels',                     'ola',  '!' );
+    $add_option->( 'outdent-long-quotes',                'olq',  '!' );
+    $add_option->( 'indent-closing-brace',               'icb',  '!' );
+    $add_option->( 'closing-token-indentation',          'cti',  '=i' );
+    $add_option->( 'closing-paren-indentation',          'cpi',  '=i' );
+    $add_option->( 'closing-brace-indentation',          'cbi',  '=i' );
+    $add_option->( 'closing-square-bracket-indentation', 'csbi', '=i' );
+    $add_option->( 'brace-left-and-indent',              'bli',  '!' );
+    $add_option->( 'brace-left-and-indent-list',         'blil', '=s' );
+
+    ########################################
+    $category = 3;    # Whitespace control
+    ########################################
     $add_option->( 'add-semicolons',                            'asc',   '!' );
     $add_option->( 'add-whitespace',                            'aws',   '!' );
     $add_option->( 'add-semicolons',                            'asc',   '!' );
     $add_option->( 'add-whitespace',                            'aws',   '!' );
-    $add_option->( 'backup-and-modify-in-place',                'b',     '!' );
-    $add_option->( 'backup-file-extension',                     'bext',  '=s' );
-    $add_option->( 'blanks-before-blocks',                      'bbb',   '!' );
-    $add_option->( 'blanks-before-comments',                    'bbc',   '!' );
-    $add_option->( 'blanks-before-subs',                        'bbs',   '!' );
     $add_option->( 'block-brace-tightness',                     'bbt',   '=i' );
     $add_option->( 'block-brace-tightness',                     'bbt',   '=i' );
-    $add_option->( 'block-brace-vertical-tightness',            'bbvt',  '=i' );
-    $add_option->( 'block-brace-vertical-tightness-list',       'bbvtl', '=s' );
-    $add_option->( 'brace-left-and-indent',                     'bli',   '!' );
-    $add_option->( 'brace-left-and-indent-list',                'blil',  '=s' );
     $add_option->( 'brace-tightness',                           'bt',    '=i' );
     $add_option->( 'brace-tightness',                           'bt',    '=i' );
-    $add_option->( 'brace-vertical-tightness',                  'bvt',   '=i' );
-    $add_option->( 'brace-vertical-tightness-closing',          'bvtc',  '=i' );
-    $add_option->( 'break-at-old-comma-breakpoints',            'boc',   '!' );
-    $add_option->( 'break-at-old-keyword-breakpoints',          'bok',   '!' );
-    $add_option->( 'break-at-old-logical-breakpoints',          'bol',   '!' );
-    $add_option->( 'break-at-old-trinary-breakpoints',          'bot',   '!' );
-    $add_option->( 'check-multiline-quotes',                    'chk',   '!' );
-    $add_option->( 'check-syntax',                              'syn',   '!' );
-    $add_option->( 'closing-side-comment-else-flag',            'csce',  '=i' );
-    $add_option->( 'closing-side-comment-interval',             'csci',  '=i' );
-    $add_option->( 'closing-side-comment-list',                 'cscl',  '=s' );
-    $add_option->( 'closing-side-comment-maximum-text',         'csct',  '=i' );
-    $add_option->( 'closing-side-comment-prefix',               'cscp',  '=s' );
-    $add_option->( 'closing-side-comment-warnings',             'cscw',  '!' );
-    $add_option->( 'closing-side-comments',                     'csc',   '!' );
-    $add_option->( 'closing-token-indentation',                 'cti',   '=i' );
-    $add_option->( 'closing-paren-indentation',                 'cpi',   '=i' );
-    $add_option->( 'closing-brace-indentation',                 'cbi',   '=i' );
-    $add_option->( 'closing-square-bracket-indentation',        'csbi',  '=i' );
-    $add_option->( 'continuation-indentation',                  'ci',    '=i' );
-    $add_option->( 'comma-arrow-breakpoints',                   'cab',   '=i' );
-    $add_option->( 'cuddled-else',                              'ce',    '!' );
-    $add_option->( 'delete-block-comments',                     'dbc',   '!' );
-    $add_option->( 'delete-closing-side-comments',              'dcsc',  '!' );
-    $add_option->( 'delete-old-newlines',                       'dnl',   '!' );
     $add_option->( 'delete-old-whitespace',                     'dws',   '!' );
     $add_option->( 'delete-old-whitespace',                     'dws',   '!' );
-    $add_option->( 'delete-pod',                                'dp',    '!' );
     $add_option->( 'delete-semicolons',                         'dsm',   '!' );
     $add_option->( 'delete-semicolons',                         'dsm',   '!' );
-    $add_option->( 'delete-side-comments',                      'dsc',   '!' );
-    $add_option->( 'dump-defaults',                             'ddf',   '!' );
-    $add_option->( 'dump-long-names',                           'dln',   '!' );
-    $add_option->( 'dump-options',                              'dop',   '!' );
-    $add_option->( 'dump-profile',                              'dpro',  '!' );
-    $add_option->( 'dump-short-names',                          'dsn',   '!' );
-    $add_option->( 'dump-token-types',                          'dtt',   '!' );
-    $add_option->( 'dump-want-left-space',                      'dwls',  '!' );
-    $add_option->( 'dump-want-right-space',                     'dwrs',  '!' );
-    $add_option->( 'entab-leading-whitespace',                  'et',    '=i' );
-    $add_option->( 'force-read-binary',                         'f',     '!' );
-    $add_option->( 'format',                                    'fmt',   '=s' );
-    $add_option->( 'fuzzy-line-length',                         'fll',   '!' );
-    $add_option->( 'hanging-side-comments',                     'hsc',   '!' );
-    $add_option->( 'help',                                      'h',     '' );
-    $add_option->( 'ignore-old-line-breaks',                    'iob',   '!' );
-    $add_option->( 'indent-block-comments',                     'ibc',   '!' );
-    $add_option->( 'indent-closing-brace',                      'icb',   '!' );
-    $add_option->( 'indent-columns',                            'i',     '=i' );
-    $add_option->( 'indent-spaced-block-comments',              'isbc',  '!' );
-    $add_option->( 'line-up-parentheses',                       'lp',    '!' );
-    $add_option->( 'logfile',                                   'log',   '!' );
-    $add_option->( 'logfile-gap',                               'g',     ':i' );
-    $add_option->( 'long-block-line-count',                     'lbl',   '=i' );
-    $add_option->( 'look-for-autoloader',                       'lal',   '!' );
-    $add_option->( 'look-for-hash-bang',                        'x',     '!' );
-    $add_option->( 'look-for-selfloader',                       'lsl',   '!' );
-    $add_option->( 'maximum-consecutive-blank-lines',           'mbl',   '=i' );
-    $add_option->( 'maximum-fields-per-table',                  'mft',   '=i' );
-    $add_option->( 'maximum-line-length',                       'l',     '=i' );
-    $add_option->( 'minimum-space-to-comment',                  'msc',   '=i' );
+    $add_option->( 'nospace-after-keyword',                     'nsak',  '=s' );
     $add_option->( 'nowant-left-space',                         'nwls',  '=s' );
     $add_option->( 'nowant-right-space',                        'nwrs',  '=s' );
     $add_option->( 'nowant-left-space',                         'nwls',  '=s' );
     $add_option->( 'nowant-right-space',                        'nwrs',  '=s' );
-    $add_option->( 'nospace-after-keyword',                     'nsak',  '=s' );
-    $add_option->( 'opening-brace-always-on-right',             'bar',   '' );
-    $add_option->( 'opening-brace-on-new-line',                 'bl',    '!' );
-    $add_option->( 'opening-sub-brace-on-new-line',             'sbl',   '!' );
-    $add_option->( 'outdent-keyword-list',                      'okwl',  '=s' );
-    $add_option->( 'outdent-keywords',                          'okw',   '!' );
-    $add_option->( 'outdent-labels',                            'ola',   '!' );
-    $add_option->( 'outdent-long-comments',                     'olc',   '!' );
-    $add_option->( 'outdent-long-quotes',                       'olq',   '!' );
-    $add_option->( 'outdent-static-block-comments',             'osbc',  '!' );
-    $add_option->( 'outfile',                                   'o',     '=s' );
-    $add_option->( 'output-file-extension',                     'oext',  '=s' );
-    $add_option->( 'output-line-ending',                        'ole',   '=s' );
-    $add_option->( 'output-path',                               'opath', '=s' );
     $add_option->( 'paren-tightness',                           'pt',    '=i' );
     $add_option->( 'paren-tightness',                           'pt',    '=i' );
-    $add_option->( 'paren-vertical-tightness',                  'pvt',   '=i' );
-    $add_option->( 'paren-vertical-tightness-closing',          'pvtc',  '=i' );
-    $add_option->( 'pass-version-line',                         'pvl',   '!' );
-    $add_option->( 'perl-syntax-check-flags',                   'pscf',  '=s' );
-    $add_option->( 'preserve-line-endings',                     'ple',   '!' );
-    $add_option->( 'profile',                                   'pro',   '=s' );
-    $add_option->( 'quiet',                                     'q',     '!' );
-    $add_option->( 'short-concatenation-item-length',           'scl',   '=i' );
-    $add_option->( 'show-options',                              'opt',   '!' );
     $add_option->( 'space-after-keyword',                       'sak',   '=s' );
     $add_option->( 'space-for-semicolon',                       'sfs',   '!' );
     $add_option->( 'space-after-keyword',                       'sak',   '=s' );
     $add_option->( 'space-for-semicolon',                       'sfs',   '!' );
+    $add_option->( 'space-function-paren',                      'sfp',   '!' );
+    $add_option->( 'space-keyword-paren',                       'skp',   '!' );
     $add_option->( 'space-terminal-semicolon',                  'sts',   '!' );
     $add_option->( 'square-bracket-tightness',                  'sbt',   '=i' );
     $add_option->( 'square-bracket-vertical-tightness',         'sbvt',  '=i' );
     $add_option->( 'square-bracket-vertical-tightness-closing', 'sbvtc', '=i' );
     $add_option->( 'space-terminal-semicolon',                  'sts',   '!' );
     $add_option->( 'square-bracket-tightness',                  'sbt',   '=i' );
     $add_option->( 'square-bracket-vertical-tightness',         'sbvt',  '=i' );
     $add_option->( 'square-bracket-vertical-tightness-closing', 'sbvtc', '=i' );
-    $add_option->( 'standard-error-output',                     'se',    '!' );
-    $add_option->( 'standard-output',                           'st',    '!' );
-    $add_option->( 'starting-indentation-level',                'sil',   '=i' );
-    $add_option->( 'static-block-comment-prefix',               'sbcp',  '=s' );
-    $add_option->( 'static-block-comments',                     'sbc',   '!' );
-    $add_option->( 'static-side-comment-prefix',                'sscp',  '=s' );
-    $add_option->( 'static-side-comments',                      'ssc',   '!' );
-    $add_option->( 'swallow-optional-blank-lines',              'sob',   '!' );
-    $add_option->( 'tabs',                                      't',     '!' );
-    $add_option->( 'tee-block-comments',                        'tbc',   '!' );
-    $add_option->( 'tee-pod',                                   'tp',    '!' );
-    $add_option->( 'tee-side-comments',                         'tsc',   '!' );
     $add_option->( 'trim-qw',                                   'tqw',   '!' );
     $add_option->( 'trim-qw',                                   'tqw',   '!' );
-    $add_option->( 'version',                                   'v',     '' );
-    $add_option->( 'vertical-tightness',                        'vt',    '=i' );
-    $add_option->( 'vertical-tightness-closing',                'vtc',   '=i' );
-    $add_option->( 'want-break-after',                          'wba',   '=s' );
-    $add_option->( 'want-break-before',                         'wbb',   '=s' );
     $add_option->( 'want-left-space',                           'wls',   '=s' );
     $add_option->( 'want-right-space',                          'wrs',   '=s' );
     $add_option->( 'want-left-space',                           'wls',   '=s' );
     $add_option->( 'want-right-space',                          'wrs',   '=s' );
-    $add_option->( 'warning-output',                            'w',     '!' );
+
+    ########################################
+    $category = 4;    # Comment controls
+    ########################################
+    $add_option->( 'closing-side-comment-else-flag',    'csce', '=i' );
+    $add_option->( 'closing-side-comment-interval',     'csci', '=i' );
+    $add_option->( 'closing-side-comment-list',         'cscl', '=s' );
+    $add_option->( 'closing-side-comment-maximum-text', 'csct', '=i' );
+    $add_option->( 'closing-side-comment-prefix',       'cscp', '=s' );
+    $add_option->( 'closing-side-comment-warnings',     'cscw', '!' );
+    $add_option->( 'closing-side-comments',             'csc',  '!' );
+    $add_option->( 'format-skipping',                   'fs',   '!' );
+    $add_option->( 'format-skipping-begin',             'fsb',  '=s' );
+    $add_option->( 'format-skipping-end',               'fse',  '=s' );
+    $add_option->( 'hanging-side-comments',             'hsc',  '!' );
+    $add_option->( 'indent-block-comments',             'ibc',  '!' );
+    $add_option->( 'indent-spaced-block-comments',      'isbc', '!' );
+    $add_option->( 'minimum-space-to-comment',          'msc',  '=i' );
+    $add_option->( 'outdent-long-comments',             'olc',  '!' );
+    $add_option->( 'outdent-static-block-comments',     'osbc', '!' );
+    $add_option->( 'static-block-comment-prefix',       'sbcp', '=s' );
+    $add_option->( 'static-block-comments',             'sbc',  '!' );
+    $add_option->( 'static-side-comment-prefix',        'sscp', '=s' );
+    $add_option->( 'static-side-comments',              'ssc',  '!' );
+
+    ########################################
+    $category = 5;    # Linebreak controls
+    ########################################
+    $add_option->( 'add-newlines',                        'anl',   '!' );
+    $add_option->( 'block-brace-vertical-tightness',      'bbvt',  '=i' );
+    $add_option->( 'block-brace-vertical-tightness-list', 'bbvtl', '=s' );
+    $add_option->( 'brace-vertical-tightness',            'bvt',   '=i' );
+    $add_option->( 'brace-vertical-tightness-closing',    'bvtc',  '=i' );
+    $add_option->( 'cuddled-else',                        'ce',    '!' );
+    $add_option->( 'delete-old-newlines',                 'dnl',   '!' );
+    $add_option->( 'opening-brace-always-on-right',       'bar',   '' );
+    $add_option->( 'opening-brace-on-new-line',           'bl',    '!' );
+    $add_option->( 'opening-hash-brace-right',            'ohbr',  '!' );
+    $add_option->( 'opening-paren-right',                 'opr',   '!' );
+    $add_option->( 'opening-square-bracket-right',        'osbr',  '!' );
+    $add_option->( 'opening-sub-brace-on-new-line',       'sbl',   '!' );
+    $add_option->( 'paren-vertical-tightness',            'pvt',   '=i' );
+    $add_option->( 'paren-vertical-tightness-closing',    'pvtc',  '=i' );
+    $add_option->( 'stack-closing-hash-brace',            'schb',  '!' );
+    $add_option->( 'stack-closing-paren',                 'scp',   '!' );
+    $add_option->( 'stack-closing-square-bracket',        'scsb',  '!' );
+    $add_option->( 'stack-opening-hash-brace',            'sohb',  '!' );
+    $add_option->( 'stack-opening-paren',                 'sop',   '!' );
+    $add_option->( 'stack-opening-square-bracket',        'sosb',  '!' );
+    $add_option->( 'vertical-tightness',                  'vt',    '=i' );
+    $add_option->( 'vertical-tightness-closing',          'vtc',   '=i' );
+    $add_option->( 'want-break-after',                    'wba',   '=s' );
+    $add_option->( 'want-break-before',                   'wbb',   '=s' );
+
+    ########################################
+    $category = 6;    # Controlling list formatting
+    ########################################
+    $add_option->( 'break-at-old-comma-breakpoints', 'boc', '!' );
+    $add_option->( 'comma-arrow-breakpoints',        'cab', '=i' );
+    $add_option->( 'maximum-fields-per-table',       'mft', '=i' );
+
+    ########################################
+    $category = 7;    # Retaining or ignoring existing line breaks
+    ########################################
+    $add_option->( 'break-at-old-keyword-breakpoints', 'bok', '!' );
+    $add_option->( 'break-at-old-logical-breakpoints', 'bol', '!' );
+    $add_option->( 'break-at-old-trinary-breakpoints', 'bot', '!' );
+    $add_option->( 'ignore-old-breakpoints',           'iob', '!' );
+
+    ########################################
+    $category = 8;    # Blank line control
+    ########################################
+    $add_option->( 'blanks-before-blocks',            'bbb', '!' );
+    $add_option->( 'blanks-before-comments',          'bbc', '!' );
+    $add_option->( 'blanks-before-subs',              'bbs', '!' );
+    $add_option->( 'long-block-line-count',           'lbl', '=i' );
+    $add_option->( 'maximum-consecutive-blank-lines', 'mbl', '=i' );
+    $add_option->( 'swallow-optional-blank-lines',    'sob', '!' );
+
+    ########################################
+    $category = 9;    # Other controls
+    ########################################
+    $add_option->( 'delete-block-comments',        'dbc',  '!' );
+    $add_option->( 'delete-closing-side-comments', 'dcsc', '!' );
+    $add_option->( 'delete-pod',                   'dp',   '!' );
+    $add_option->( 'delete-side-comments',         'dsc',  '!' );
+    $add_option->( 'tee-block-comments',           'tbc',  '!' );
+    $add_option->( 'tee-pod',                      'tp',   '!' );
+    $add_option->( 'tee-side-comments',            'tsc',  '!' );
+    $add_option->( 'look-for-autoloader',          'lal',  '!' );
+    $add_option->( 'look-for-hash-bang',           'x',    '!' );
+    $add_option->( 'look-for-selfloader',          'lsl',  '!' );
+    $add_option->( 'pass-version-line',            'pvl',  '!' );
+
+    ########################################
+    $category = 13;    # Debugging
+    ########################################
+    $add_option->( 'DEBUG',                           'D',    '!' );
+    $add_option->( 'DIAGNOSTICS',                     'I',    '!' );
+    $add_option->( 'check-multiline-quotes',          'chk',  '!' );
+    $add_option->( 'dump-defaults',                   'ddf',  '!' );
+    $add_option->( 'dump-long-names',                 'dln',  '!' );
+    $add_option->( 'dump-options',                    'dop',  '!' );
+    $add_option->( 'dump-profile',                    'dpro', '!' );
+    $add_option->( 'dump-short-names',                'dsn',  '!' );
+    $add_option->( 'dump-token-types',                'dtt',  '!' );
+    $add_option->( 'dump-want-left-space',            'dwls', '!' );
+    $add_option->( 'dump-want-right-space',           'dwrs', '!' );
+    $add_option->( 'fuzzy-line-length',               'fll',  '!' );
+    $add_option->( 'help',                            'h',    '' );
+    $add_option->( 'short-concatenation-item-length', 'scl',  '=i' );
+    $add_option->( 'show-options',                    'opt',  '!' );
+    $add_option->( 'version',                         'v',    '' );
+
+    #---------------------------------------------------------------------
 
     # The Perl::Tidy::HtmlWriter will add its own options to the string
     Perl::Tidy::HtmlWriter->make_getopt_long_names( \@option_string );
 
 
     # The Perl::Tidy::HtmlWriter will add its own options to the string
     Perl::Tidy::HtmlWriter->make_getopt_long_names( \@option_string );
 
+    ########################################
+    # Set categories 10, 11, 12
+    ########################################
+    # Based on their known order
+    $category = 12;    # HTML properties
+    foreach my $opt (@option_string) {
+        my $long_name = $opt;
+        $long_name =~ s/(!|=.*|:.*)$//;
+        unless ( defined( $option_category{$long_name} ) ) {
+            if ( $long_name =~ /^html-linked/ ) {
+                $category = 10;    # HTML options
+            }
+            elsif ( $long_name =~ /^pod2html/ ) {
+                $category = 11;    # Pod2html
+            }
+            $option_category{$long_name} = $category_name[$category];
+        }
+    }
+
+    #---------------------------------------------------------------
+    # Assign valid ranges to certain options
+    #---------------------------------------------------------------
+    # In the future, these may be used to make preliminary checks
+    # hash keys are long names
+    # If key or value is undefined:
+    #   strings may have any value
+    #   integer ranges are >=0
+    # If value is defined:
+    #   value is [qw(any valid words)] for strings
+    #   value is [min, max] for integers
+    #   if min is undefined, there is no lower limit
+    #   if max is undefined, there is no upper limit
+    # Parameters not listed here have defaults
+    $option_range{'format'}             = [qw(tidy html user)];
+    $option_range{'output-line-ending'} = [qw(dos win mac unix)];
+
+    $option_range{'block-brace-tightness'}    = [ 0, 2 ];
+    $option_range{'brace-tightness'}          = [ 0, 2 ];
+    $option_range{'paren-tightness'}          = [ 0, 2 ];
+    $option_range{'square-bracket-tightness'} = [ 0, 2 ];
+
+    $option_range{'block-brace-vertical-tightness'}            = [ 0, 2 ];
+    $option_range{'brace-vertical-tightness'}                  = [ 0, 2 ];
+    $option_range{'brace-vertical-tightness-closing'}          = [ 0, 2 ];
+    $option_range{'paren-vertical-tightness'}                  = [ 0, 2 ];
+    $option_range{'paren-vertical-tightness-closing'}          = [ 0, 2 ];
+    $option_range{'square-bracket-vertical-tightness'}         = [ 0, 2 ];
+    $option_range{'square-bracket-vertical-tightness-closing'} = [ 0, 2 ];
+    $option_range{'vertical-tightness'}                        = [ 0, 2 ];
+    $option_range{'vertical-tightness-closing'}                = [ 0, 2 ];
+
+    $option_range{'closing-brace-indentation'}          = [ 0, 3 ];
+    $option_range{'closing-paren-indentation'}          = [ 0, 3 ];
+    $option_range{'closing-square-bracket-indentation'} = [ 0, 3 ];
+    $option_range{'closing-token-indentation'}          = [ 0, 3 ];
+
+    $option_range{'closing-side-comment-else-flag'} = [ 0, 2 ];
+    $option_range{'comma-arrow-breakpoints'}        = [ 0, 3 ];
+
+# Note: we could actually allow negative ci if someone really wants it:
+# $option_range{'continuation-indentation'}                  = [ undef, undef ];
+
     #---------------------------------------------------------------
     # Assign default values to the above options here, except
     # for 'outfile' and 'help'.
     #---------------------------------------------------------------
     # Assign default values to the above options here, except
     # for 'outfile' and 'help'.
@@ -1261,6 +1521,7 @@ sub process_command_line {
       trim-qw
       format=tidy
       backup-file-extension=bak
       trim-qw
       format=tidy
       backup-file-extension=bak
+      format-skipping
 
       pod2html
       html-table-of-contents
 
       pod2html
       html-table-of-contents
@@ -1269,21 +1530,6 @@ sub process_command_line {
 
     push @defaults, "perl-syntax-check-flags=-c -T";
 
 
     push @defaults, "perl-syntax-check-flags=-c -T";
 
-    #---------------------------------------------------------------
-    # set the defaults by passing the above list through GetOptions
-    #---------------------------------------------------------------
-    my %Opts = ();
-    {
-        local @ARGV;
-        my $i;
-
-        for $i (@defaults) { push @ARGV, "--" . $i }
-
-        if ( !GetOptions( \%Opts, @option_string ) ) {
-            die "Programming Bug: error in setting default options";
-        }
-    }
-
     #---------------------------------------------------------------
     # Define abbreviations which will be expanded into the above primitives.
     # These may be defined recursively.
     #---------------------------------------------------------------
     # Define abbreviations which will be expanded into the above primitives.
     # These may be defined recursively.
@@ -1350,6 +1596,21 @@ sub process_command_line {
         'vertical-tightness-closing=1' => [qw(pvtc=1 bvtc=1 sbvtc=1)],
         'vertical-tightness-closing=2' => [qw(pvtc=2 bvtc=2 sbvtc=2)],
 
         'vertical-tightness-closing=1' => [qw(pvtc=1 bvtc=1 sbvtc=1)],
         'vertical-tightness-closing=2' => [qw(pvtc=2 bvtc=2 sbvtc=2)],
 
+        'otr'                   => [qw(opr ohbr osbr)],
+        'opening-token-right'   => [qw(opr ohbr osbr)],
+        'notr'                  => [qw(nopr nohbr nosbr)],
+        'noopening-token-right' => [qw(nopr nohbr nosbr)],
+
+        'sot'                    => [qw(sop sohb sosb)],
+        'nsot'                   => [qw(nsop nsohb nsosb)],
+        'stack-opening-tokens'   => [qw(sop sohb sosb)],
+        'nostack-opening-tokens' => [qw(nsop nsohb nsosb)],
+
+        'sct'                    => [qw(scp schb scsb)],
+        'stack-closing-tokens'   => => [qw(scp schb scsb)],
+        'nsct'                   => [qw(nscp nschb nscsb)],
+        'nostack-opening-tokens' => [qw(nscp nschb nscsb)],
+
         # 'mangle' originally deleted pod and comments, but to keep it
         # reversible, it no longer does.  But if you really want to
         # delete them, just use:
         # 'mangle' originally deleted pod and comments, but to keep it
         # reversible, it no longer does.  But if you really want to
         # delete them, just use:
@@ -1421,6 +1682,57 @@ sub process_command_line {
 
     # Uncomment next line to dump all expansions for debugging:
     # dump_short_names(\%expansion);
 
     # Uncomment next line to dump all expansions for debugging:
     # dump_short_names(\%expansion);
+    return (
+        \@option_string,   \@defaults, \%expansion,
+        \%option_category, \%option_range
+    );
+
+}    # end of generate_options
+
+sub process_command_line {
+
+    my (
+        $perltidyrc_stream,  $is_Windows, $Windows_type,
+        $rpending_complaint, $dump_options_type
+    ) = @_;
+
+    use Getopt::Long;
+
+    my (
+        $roption_string,   $rdefaults, $rexpansion,
+        $roption_category, $roption_range
+    ) = generate_options();
+
+    #---------------------------------------------------------------
+    # set the defaults by passing the above list through GetOptions
+    #---------------------------------------------------------------
+    my %Opts = ();
+    {
+        local @ARGV;
+        my $i;
+
+        # do not load the defaults if we are just dumping perltidyrc
+        unless ( $dump_options_type eq 'perltidyrc' ) {
+            for $i (@$rdefaults) { push @ARGV, "--" . $i }
+        }
+
+        # Patch to save users Getopt::Long configuration
+        # and set to Getopt::Long defaults.  Use eval to avoid
+        # breaking old versions of Perl without these routines.
+        my $glc;
+        eval { $glc = Getopt::Long::Configure() };
+        unless ($@) {
+            eval { Getopt::Long::ConfigDefaults() };
+        }
+        else { $glc = undef }
+
+        if ( !GetOptions( \%Opts, @$roption_string ) ) {
+            die "Programming Bug: error in setting default options";
+        }
+
+        # Patch to put the previous Getopt::Long configuration back
+        eval { Getopt::Long::Configure($glc) } if defined $glc;
+    }
 
     my $word;
     my @raw_options        = ();
 
     my $word;
     my @raw_options        = ();
@@ -1472,15 +1784,15 @@ sub process_command_line {
             exit 1;
         }
         elsif ( $i =~ /^-(dump-defaults|ddf)$/ ) {
             exit 1;
         }
         elsif ( $i =~ /^-(dump-defaults|ddf)$/ ) {
-            dump_defaults(@defaults);
+            dump_defaults(@$rdefaults);
             exit 1;
         }
         elsif ( $i =~ /^-(dump-long-names|dln)$/ ) {
             exit 1;
         }
         elsif ( $i =~ /^-(dump-long-names|dln)$/ ) {
-            dump_long_names(@option_string);
+            dump_long_names(@$roption_string);
             exit 1;
         }
         elsif ( $i =~ /^-(dump-short-names|dsn)$/ ) {
             exit 1;
         }
         elsif ( $i =~ /^-(dump-short-names|dsn)$/ ) {
-            dump_short_names( \%expansion );
+            dump_short_names($rexpansion);
             exit 1;
         }
         elsif ( $i =~ /^-(dump-token-types|dtt)$/ ) {
             exit 1;
         }
         elsif ( $i =~ /^-(dump-token-types|dtt)$/ ) {
@@ -1545,22 +1857,47 @@ EOM
 
         if ($fh_config) {
 
 
         if ($fh_config) {
 
-            my $rconfig_list =
-              read_config_file( $fh_config, $config_file, \%expansion );
+            my ( $rconfig_list, $death_message ) =
+              read_config_file( $fh_config, $config_file, $rexpansion );
+            die $death_message if ($death_message);
 
             # process any .perltidyrc parameters right now so we can
             # localize errors
             if (@$rconfig_list) {
                 local @ARGV = @$rconfig_list;
 
 
             # process any .perltidyrc parameters right now so we can
             # localize errors
             if (@$rconfig_list) {
                 local @ARGV = @$rconfig_list;
 
-                expand_command_abbreviations( \%expansion, \@raw_options,
+                expand_command_abbreviations( $rexpansion, \@raw_options,
                     $config_file );
 
                     $config_file );
 
-                if ( !GetOptions( \%Opts, @option_string ) ) {
+                if ( !GetOptions( \%Opts, @$roption_string ) ) {
                     die
 "Error in this config file: $config_file  \nUse -npro to ignore this file, -h for help'\n";
                 }
 
                     die
 "Error in this config file: $config_file  \nUse -npro to ignore this file, -h for help'\n";
                 }
 
+                # Anything left in this local @ARGV is an error and must be
+                # invalid bare words from the configuration file.  We cannot
+                # check this earlier because bare words may have been valid
+                # values for parameters.  We had to wait for GetOptions to have
+                # a look at @ARGV.
+                if (@ARGV) {
+                    my $count = @ARGV;
+                    my $str   = "\'" . pop(@ARGV) . "\'";
+                    while ( my $param = pop(@ARGV) ) {
+                        if ( length($str) < 70 ) {
+                            $str .= ", '$param'";
+                        }
+                        else {
+                            $str .= ", ...";
+                            last;
+                        }
+                    }
+                    die <<EOM;
+There are $count unrecognized values in the configuration file '$config_file':
+$str
+Use leading dashes for parameters.  Use -npro to ignore this file.
+EOM
+                }
+
                 # Undo any options which cause premature exit.  They are not
                 # appropriate for a config file, and it could be hard to
                 # diagnose the cause of the premature exit.
                 # Undo any options which cause premature exit.  They are not
                 # appropriate for a config file, and it could be hard to
                 # diagnose the cause of the premature exit.
@@ -1592,19 +1929,22 @@ EOM
     #---------------------------------------------------------------
     # now process the command line parameters
     #---------------------------------------------------------------
     #---------------------------------------------------------------
     # now process the command line parameters
     #---------------------------------------------------------------
-    expand_command_abbreviations( \%expansion, \@raw_options, $config_file );
+    expand_command_abbreviations( $rexpansion, \@raw_options, $config_file );
 
 
-    if ( !GetOptions( \%Opts, @option_string ) ) {
+    if ( !GetOptions( \%Opts, @$roption_string ) ) {
         die "Error on command line; for help try 'perltidy -h'\n";
     }
 
         die "Error on command line; for help try 'perltidy -h'\n";
     }
 
-    if ( $Opts{'dump-options'} ) {
-        dump_options( \%Opts );
-        exit 1;
-    }
+    return ( \%Opts, $config_file, \@raw_options, $saw_extrude, $roption_string,
+        $rexpansion, $roption_category, $roption_range );
+}    # end of process_command_line
+
+sub check_options {
+
+    my ( $rOpts, $is_Windows, $Windows_type, $rpending_complaint ) = @_;
 
     #---------------------------------------------------------------
 
     #---------------------------------------------------------------
-    # Now we have to handle any interactions among the options..
+    # check and handle any interactions among the basic options..
     #---------------------------------------------------------------
 
     # Since -vt, -vtc, and -cti are abbreviations, but under
     #---------------------------------------------------------------
 
     # Since -vt, -vtc, and -cti are abbreviations, but under
@@ -1613,149 +1953,147 @@ EOM
     # won't be seen.  Therefore, we will catch them here if
     # they get through.
 
     # won't be seen.  Therefore, we will catch them here if
     # they get through.
 
-    if ( defined $Opts{'vertical-tightness'} ) {
-        my $vt = $Opts{'vertical-tightness'};
-        $Opts{'paren-vertical-tightness'}          = $vt;
-        $Opts{'square-bracket-vertical-tightness'} = $vt;
-        $Opts{'brace-vertical-tightness'}          = $vt;
+    if ( defined $rOpts->{'vertical-tightness'} ) {
+        my $vt = $rOpts->{'vertical-tightness'};
+        $rOpts->{'paren-vertical-tightness'}          = $vt;
+        $rOpts->{'square-bracket-vertical-tightness'} = $vt;
+        $rOpts->{'brace-vertical-tightness'}          = $vt;
     }
 
     }
 
-    if ( defined $Opts{'vertical-tightness-closing'} ) {
-        my $vtc = $Opts{'vertical-tightness-closing'};
-        $Opts{'paren-vertical-tightness-closing'}          = $vtc;
-        $Opts{'square-bracket-vertical-tightness-closing'} = $vtc;
-        $Opts{'brace-vertical-tightness-closing'}          = $vtc;
+    if ( defined $rOpts->{'vertical-tightness-closing'} ) {
+        my $vtc = $rOpts->{'vertical-tightness-closing'};
+        $rOpts->{'paren-vertical-tightness-closing'}          = $vtc;
+        $rOpts->{'square-bracket-vertical-tightness-closing'} = $vtc;
+        $rOpts->{'brace-vertical-tightness-closing'}          = $vtc;
     }
 
     }
 
-    if ( defined $Opts{'closing-token-indentation'} ) {
-        my $cti = $Opts{'closing-token-indentation'};
-        $Opts{'closing-square-bracket-indentation'} = $cti;
-        $Opts{'closing-brace-indentation'}          = $cti;
-        $Opts{'closing-paren-indentation'}          = $cti;
+    if ( defined $rOpts->{'closing-token-indentation'} ) {
+        my $cti = $rOpts->{'closing-token-indentation'};
+        $rOpts->{'closing-square-bracket-indentation'} = $cti;
+        $rOpts->{'closing-brace-indentation'}          = $cti;
+        $rOpts->{'closing-paren-indentation'}          = $cti;
     }
 
     # In quiet mode, there is no log file and hence no way to report
     # results of syntax check, so don't do it.
     }
 
     # In quiet mode, there is no log file and hence no way to report
     # results of syntax check, so don't do it.
-    if ( $Opts{'quiet'} ) {
-        $Opts{'check-syntax'} = 0;
+    if ( $rOpts->{'quiet'} ) {
+        $rOpts->{'check-syntax'} = 0;
     }
 
     # can't check syntax if no output
     }
 
     # can't check syntax if no output
-    if ( $Opts{'format'} ne 'tidy' ) {
-        $Opts{'check-syntax'} = 0;
+    if ( $rOpts->{'format'} ne 'tidy' ) {
+        $rOpts->{'check-syntax'} = 0;
     }
 
     # Never let Windows 9x/Me systems run syntax check -- this will prevent a
     # wide variety of nasty problems on these systems, because they cannot
     # reliably run backticks.  Don't even think about changing this!
     }
 
     # Never let Windows 9x/Me systems run syntax check -- this will prevent a
     # wide variety of nasty problems on these systems, because they cannot
     # reliably run backticks.  Don't even think about changing this!
-    if (   $Opts{'check-syntax'}
+    if (   $rOpts->{'check-syntax'}
         && $is_Windows
         && ( !$Windows_type || $Windows_type =~ /^(9|Me)/ ) )
     {
         && $is_Windows
         && ( !$Windows_type || $Windows_type =~ /^(9|Me)/ ) )
     {
-        $Opts{'check-syntax'} = 0;
+        $rOpts->{'check-syntax'} = 0;
     }
 
     # It's really a bad idea to check syntax as root unless you wrote
     # the script yourself.  FIXME: not sure if this works with VMS
     unless ($is_Windows) {
 
     }
 
     # It's really a bad idea to check syntax as root unless you wrote
     # the script yourself.  FIXME: not sure if this works with VMS
     unless ($is_Windows) {
 
-        if ( $< == 0 && $Opts{'check-syntax'} ) {
-            $Opts{'check-syntax'} = 0;
+        if ( $< == 0 && $rOpts->{'check-syntax'} ) {
+            $rOpts->{'check-syntax'} = 0;
             $$rpending_complaint .=
 "Syntax check deactivated for safety; you shouldn't run this as root\n";
         }
     }
 
     # see if user set a non-negative logfile-gap
             $$rpending_complaint .=
 "Syntax check deactivated for safety; you shouldn't run this as root\n";
         }
     }
 
     # see if user set a non-negative logfile-gap
-    if ( defined( $Opts{'logfile-gap'} ) && $Opts{'logfile-gap'} >= 0 ) {
+    if ( defined( $rOpts->{'logfile-gap'} ) && $rOpts->{'logfile-gap'} >= 0 ) {
 
         # a zero gap will be taken as a 1
 
         # a zero gap will be taken as a 1
-        if ( $Opts{'logfile-gap'} == 0 ) {
-            $Opts{'logfile-gap'} = 1;
+        if ( $rOpts->{'logfile-gap'} == 0 ) {
+            $rOpts->{'logfile-gap'} = 1;
         }
 
         # setting a non-negative logfile gap causes logfile to be saved
         }
 
         # setting a non-negative logfile gap causes logfile to be saved
-        $Opts{'logfile'} = 1;
+        $rOpts->{'logfile'} = 1;
     }
 
     # not setting logfile gap, or setting it negative, causes default of 50
     else {
     }
 
     # not setting logfile gap, or setting it negative, causes default of 50
     else {
-        $Opts{'logfile-gap'} = 50;
+        $rOpts->{'logfile-gap'} = 50;
     }
 
     # set short-cut flag when only indentation is to be done.
     # Note that the user may or may not have already set the
     # indent-only flag.
     }
 
     # set short-cut flag when only indentation is to be done.
     # Note that the user may or may not have already set the
     # indent-only flag.
-    if (   !$Opts{'add-whitespace'}
-        && !$Opts{'delete-old-whitespace'}
-        && !$Opts{'add-newlines'}
-        && !$Opts{'delete-old-newlines'} )
+    if (   !$rOpts->{'add-whitespace'}
+        && !$rOpts->{'delete-old-whitespace'}
+        && !$rOpts->{'add-newlines'}
+        && !$rOpts->{'delete-old-newlines'} )
     {
     {
-        $Opts{'indent-only'} = 1;
+        $rOpts->{'indent-only'} = 1;
     }
 
     # -isbc implies -ibc
     }
 
     # -isbc implies -ibc
-    if ( $Opts{'indent-spaced-block-comments'} ) {
-        $Opts{'indent-block-comments'} = 1;
+    if ( $rOpts->{'indent-spaced-block-comments'} ) {
+        $rOpts->{'indent-block-comments'} = 1;
     }
 
     # -bli flag implies -bl
     }
 
     # -bli flag implies -bl
-    if ( $Opts{'brace-left-and-indent'} ) {
-        $Opts{'opening-brace-on-new-line'} = 1;
+    if ( $rOpts->{'brace-left-and-indent'} ) {
+        $rOpts->{'opening-brace-on-new-line'} = 1;
     }
 
     }
 
-    if (   $Opts{'opening-brace-always-on-right'}
-        && $Opts{'opening-brace-on-new-line'} )
+    if (   $rOpts->{'opening-brace-always-on-right'}
+        && $rOpts->{'opening-brace-on-new-line'} )
     {
         warn <<EOM;
  Conflict: you specified both 'opening-brace-always-on-right' (-bar) and 
   'opening-brace-on-new-line' (-bl).  Ignoring -bl. 
 EOM
     {
         warn <<EOM;
  Conflict: you specified both 'opening-brace-always-on-right' (-bar) and 
   'opening-brace-on-new-line' (-bl).  Ignoring -bl. 
 EOM
-        $Opts{'opening-brace-on-new-line'} = 0;
+        $rOpts->{'opening-brace-on-new-line'} = 0;
     }
 
     # it simplifies things if -bl is 0 rather than undefined
     }
 
     # it simplifies things if -bl is 0 rather than undefined
-    if ( !defined( $Opts{'opening-brace-on-new-line'} ) ) {
-        $Opts{'opening-brace-on-new-line'} = 0;
+    if ( !defined( $rOpts->{'opening-brace-on-new-line'} ) ) {
+        $rOpts->{'opening-brace-on-new-line'} = 0;
     }
 
     # -sbl defaults to -bl if not defined
     }
 
     # -sbl defaults to -bl if not defined
-    if ( !defined( $Opts{'opening-sub-brace-on-new-line'} ) ) {
-        $Opts{'opening-sub-brace-on-new-line'} =
-          $Opts{'opening-brace-on-new-line'};
+    if ( !defined( $rOpts->{'opening-sub-brace-on-new-line'} ) ) {
+        $rOpts->{'opening-sub-brace-on-new-line'} =
+          $rOpts->{'opening-brace-on-new-line'};
     }
 
     # set shortcut flag if no blanks to be written
     }
 
     # set shortcut flag if no blanks to be written
-    unless ( $Opts{'maximum-consecutive-blank-lines'} ) {
-        $Opts{'swallow-optional-blank-lines'} = 1;
+    unless ( $rOpts->{'maximum-consecutive-blank-lines'} ) {
+        $rOpts->{'swallow-optional-blank-lines'} = 1;
     }
 
     }
 
-    if ( $Opts{'entab-leading-whitespace'} ) {
-        if ( $Opts{'entab-leading-whitespace'} < 0 ) {
+    if ( $rOpts->{'entab-leading-whitespace'} ) {
+        if ( $rOpts->{'entab-leading-whitespace'} < 0 ) {
             warn "-et=n must use a positive integer; ignoring -et\n";
             warn "-et=n must use a positive integer; ignoring -et\n";
-            $Opts{'entab-leading-whitespace'} = undef;
+            $rOpts->{'entab-leading-whitespace'} = undef;
         }
 
         # entab leading whitespace has priority over the older 'tabs' option
         }
 
         # entab leading whitespace has priority over the older 'tabs' option
-        if ( $Opts{'tabs'} ) { $Opts{'tabs'} = 0; }
+        if ( $rOpts->{'tabs'} ) { $rOpts->{'tabs'} = 0; }
     }
 
     }
 
-    if ( $Opts{'output-line-ending'} ) {
+    if ( $rOpts->{'output-line-ending'} ) {
         unless ( is_unix() ) {
             warn "ignoring -ole; only works under unix\n";
         unless ( is_unix() ) {
             warn "ignoring -ole; only works under unix\n";
-            $Opts{'output-line-ending'} = undef;
+            $rOpts->{'output-line-ending'} = undef;
         }
     }
         }
     }
-    if ( $Opts{'preserve-line-endings'} ) {
+    if ( $rOpts->{'preserve-line-endings'} ) {
         unless ( is_unix() ) {
             warn "ignoring -ple; only works under unix\n";
         unless ( is_unix() ) {
             warn "ignoring -ple; only works under unix\n";
-            $Opts{'preserve-line-endings'} = undef;
+            $rOpts->{'preserve-line-endings'} = undef;
         }
     }
 
         }
     }
 
-    return ( \%Opts, $config_file, \@raw_options, $saw_extrude );
-
-}    # end of process_command_line
+}
 
 sub expand_command_abbreviations {
 
 
 sub expand_command_abbreviations {
 
@@ -1911,37 +2249,55 @@ sub check_vms_filename {
 
 sub Win_OS_Type {
 
 
 sub Win_OS_Type {
 
+    # TODO: are these more standard names?
+    # Win32s Win95 Win98 WinMe WinNT3.51 WinNT4 Win2000 WinXP/.Net Win2003
+
     # Returns a string that determines what MS OS we are on.
     # Returns a string that determines what MS OS we are on.
-    # Returns win32s,95,98,Me,NT3.51,NT4,2000,XP/.Net
-    # Returns nothing if not an MS system.
-    # Contributed by: Yves Orton
+    # Returns win32s,95,98,Me,NT3.51,NT4,2000,XP/.Net,Win2003
+    # Returns blank string if not an MS system.
+    # Original code contributed by: Yves Orton
+    # We need to know this to decide where to look for config files
 
     my $rpending_complaint = shift;
 
     my $rpending_complaint = shift;
-    return unless $^O =~ /win32|dos/i;    # is it a MS box?
+    my $os                 = "";
+    return $os unless $^O =~ /win32|dos/i;    # is it a MS box?
 
 
-    # It _should_ have Win32 unless something is really weird
-    return unless eval('require Win32');
+    # Systems built from Perl source may not have Win32.pm
+    # But probably have Win32::GetOSVersion() anyway so the
+    # following line is not 'required':
+    # return $os unless eval('require Win32');
 
     # Use the standard API call to determine the version
 
     # Use the standard API call to determine the version
-    my ( $undef, $major, $minor, $build, $id ) = Win32::GetOSVersion();
+    my ( $undef, $major, $minor, $build, $id );
+    eval { ( $undef, $major, $minor, $build, $id ) = Win32::GetOSVersion() };
 
 
-    return "win32s" unless $id;           # If id==0 then its a win32s box.
-    my $os = {                            # Magic numbers from MSDN
-                                          # documentation of GetOSVersion
+    #
+    #    NAME                   ID   MAJOR  MINOR
+    #    Windows NT 4           2      4       0
+    #    Windows 2000           2      5       0
+    #    Windows XP             2      5       1
+    #    Windows Server 2003    2      5       2
+
+    return "win32s" unless $id;    # If id==0 then its a win32s box.
+    $os = {                        # Magic numbers from MSDN
+                                   # documentation of GetOSVersion
         1 => {
             0  => "95",
             10 => "98",
             90 => "Me"
         },
         2 => {
         1 => {
             0  => "95",
             10 => "98",
             90 => "Me"
         },
         2 => {
-            0  => "2000",
+            0  => "2000",          # or NT 4, see below
             1  => "XP/.Net",
             1  => "XP/.Net",
+            2  => "Win2003",
             51 => "NT3.51"
         }
     }->{$id}->{$minor};
 
             51 => "NT3.51"
         }
     }->{$id}->{$minor};
 
-    # This _really_ shouldnt happen. At least not for quite a while
+    # If $os is undefined, the above code is out of date.  Suggested updates
+    # are welcome.
     unless ( defined $os ) {
     unless ( defined $os ) {
+        $os = "";
         $$rpending_complaint .= <<EOS;
 Error trying to discover Win_OS_Type: $id:$major:$minor Has no name of record!
 We won't be able to look for a system-wide config file.
         $$rpending_complaint .= <<EOS;
 Error trying to discover Win_OS_Type: $id:$major:$minor Has no name of record!
 We won't be able to look for a system-wide config file.
@@ -2085,7 +2441,7 @@ sub Win_Config_Locs {
     if ( $os =~ /9[58]|Me/ ) {
         $system = "C:/Windows";
     }
     if ( $os =~ /9[58]|Me/ ) {
         $system = "C:/Windows";
     }
-    elsif ( $os =~ /NT|XP|2000/ ) {
+    elsif ( $os =~ /NT|XP|200?/ ) {
         $system = ( $os =~ /XP/ ) ? "C:/Windows/" : "C:/WinNT/";
         $allusers =
           ( $os =~ /NT/ )
         $system = ( $os =~ /XP/ ) ? "C:/Windows/" : "C:/WinNT/";
         $allusers =
           ( $os =~ /NT/ )
@@ -2094,9 +2450,8 @@ sub Win_Config_Locs {
     }
     else {
 
     }
     else {
 
-        # This currently would only happen on a win32s computer.
-        # I dont have one to test So I am unsure how to proceed.
-        # Sorry. :-)
+        # This currently would only happen on a win32s computer.  I dont have
+        # one to test, so I am unsure how to proceed.  Suggestions welcome!
         $$rpending_complaint .=
 "I dont know a sensible place to look for config files on an $os system.\n";
         return;
         $$rpending_complaint .=
 "I dont know a sensible place to look for config files on an $os system.\n";
         return;
@@ -2124,13 +2479,17 @@ sub read_config_file {
     my ( $fh, $config_file, $rexpansion ) = @_;
     my @config_list = ();
 
     my ( $fh, $config_file, $rexpansion ) = @_;
     my @config_list = ();
 
+    # file is bad if non-empty $death_message is returned
+    my $death_message = "";
+
     my $name = undef;
     my $line_no;
     while ( $_ = $fh->getline() ) {
         $line_no++;
         chomp;
         next if /^\s*#/;    # skip full-line comment
     my $name = undef;
     my $line_no;
     while ( $_ = $fh->getline() ) {
         $line_no++;
         chomp;
         next if /^\s*#/;    # skip full-line comment
-        $_ = strip_comment( $_, $config_file, $line_no );
+        ( $_, $death_message ) = strip_comment( $_, $config_file, $line_no );
+        last if ($death_message);
         s/^\s*(.*?)\s*$/$1/;    # trim both ends
         next unless $_;
 
         s/^\s*(.*?)\s*$/$1/;    # trim both ends
         next unless $_;
 
@@ -2145,17 +2504,19 @@ sub read_config_file {
             # handle a new alias definition
             if ($newname) {
                 if ($name) {
             # handle a new alias definition
             if ($newname) {
                 if ($name) {
-                    die
+                    $death_message =
 "No '}' seen after $name and before $newname in config file $config_file line $.\n";
 "No '}' seen after $name and before $newname in config file $config_file line $.\n";
+                    last;
                 }
                 $name = $newname;
 
                 if ( ${$rexpansion}{$name} ) {
                     local $" = ')(';
                     my @names = sort keys %$rexpansion;
                 }
                 $name = $newname;
 
                 if ( ${$rexpansion}{$name} ) {
                     local $" = ')(';
                     my @names = sort keys %$rexpansion;
-                    print "Here is a list of all installed aliases\n(@names)\n";
-                    die
-"Attempting to redefine alias ($name) in config file $config_file line $.\n";
+                    $death_message =
+                        "Here is a list of all installed aliases\n(@names)\n"
+                      . "Attempting to redefine alias ($name) in config file $config_file line $.\n";
+                    last;
                 }
                 ${$rexpansion}{$name} = [];
             }
                 }
                 ${$rexpansion}{$name} = [];
             }
@@ -2165,11 +2526,12 @@ sub read_config_file {
 
                 my ( $rbody_parts, $msg ) = parse_args($body);
                 if ($msg) {
 
                 my ( $rbody_parts, $msg ) = parse_args($body);
                 if ($msg) {
-                    die <<EOM;
-Error reading file $config_file at line number $line_no.
+                    $death_message = <<EOM;
+Error reading file '$config_file' at line number $line_no.
 $msg
 Please fix this line or use -npro to avoid reading this file
 EOM
 $msg
 Please fix this line or use -npro to avoid reading this file
 EOM
+                    last;
                 }
 
                 if ($name) {
                 }
 
                 if ($name) {
@@ -2178,7 +2540,6 @@ EOM
                     foreach (@$rbody_parts) { s/^\-+//; }
                     push @{ ${$rexpansion}{$name} }, @$rbody_parts;
                 }
                     foreach (@$rbody_parts) { s/^\-+//; }
                     push @{ ${$rexpansion}{$name} }, @$rbody_parts;
                 }
-
                 else {
                     push( @config_list, @$rbody_parts );
                 }
                 else {
                     push( @config_list, @$rbody_parts );
                 }
@@ -2186,30 +2547,32 @@ EOM
 
             if ($curly) {
                 unless ($name) {
 
             if ($curly) {
                 unless ($name) {
-                    die
+                    $death_message =
 "Unexpected '}' seen in config file $config_file line $.\n";
 "Unexpected '}' seen in config file $config_file line $.\n";
+                    last;
                 }
                 $name = undef;
             }
         }
     }
     eval { $fh->close() };
                 }
                 $name = undef;
             }
         }
     }
     eval { $fh->close() };
-    return ( \@config_list );
+    return ( \@config_list, $death_message );
 }
 
 sub strip_comment {
 
     my ( $instr, $config_file, $line_no ) = @_;
 }
 
 sub strip_comment {
 
     my ( $instr, $config_file, $line_no ) = @_;
+    my $msg = "";
 
     # nothing to do if no comments
     if ( $instr !~ /#/ ) {
 
     # nothing to do if no comments
     if ( $instr !~ /#/ ) {
-        return $instr;
+        return ( $instr, $msg );
     }
 
     # use simple method of no quotes
     elsif ( $instr !~ /['"]/ ) {
         $instr =~ s/\s*\#.*$//;    # simple trim
     }
 
     # use simple method of no quotes
     elsif ( $instr !~ /['"]/ ) {
         $instr =~ s/\s*\#.*$//;    # simple trim
-        return $instr;
+        return ( $instr, $msg );
     }
 
     # handle comments and quotes
     }
 
     # handle comments and quotes
@@ -2229,7 +2592,7 @@ sub strip_comment {
 
             # error..we reached the end without seeing the ending quote char
             else {
 
             # error..we reached the end without seeing the ending quote char
             else {
-                die <<EOM;
+                $msg = <<EOM;
 Error reading file $config_file at line number $line_no.
 Did not see ending quote character <$quote_char> in this text:
 $instr
 Error reading file $config_file at line number $line_no.
 Did not see ending quote character <$quote_char> in this text:
 $instr
@@ -2256,7 +2619,7 @@ EOM
             }
         }
     }
             }
         }
     }
-    return $outstr;
+    return ( $outstr, $msg );
 }
 
 sub parse_args {
 }
 
 sub parse_args {
@@ -2287,7 +2650,7 @@ sub parse_args {
 
             # error..we reached the end without seeing the ending quote char
             else {
 
             # error..we reached the end without seeing the ending quote char
             else {
-                if ($part) { push @body_parts, $part; }
+                if ( length($part) ) { push @body_parts, $part; }
                 $msg = <<EOM;
 Did not see ending quote character <$quote_char> in this text:
 $body
                 $msg = <<EOM;
 Did not see ending quote character <$quote_char> in this text:
 $body
@@ -2302,14 +2665,14 @@ EOM
                 $quote_char = $1;
             }
             elsif ( $body =~ /\G(\s+)/gc ) {
                 $quote_char = $1;
             }
             elsif ( $body =~ /\G(\s+)/gc ) {
-                if ($part) { push @body_parts, $part; }
+                if ( length($part) ) { push @body_parts, $part; }
                 $part = "";
             }
             elsif ( $body =~ /\G(.)/gc ) {
                 $part .= $1;
             }
             else {
                 $part = "";
             }
             elsif ( $body =~ /\G(.)/gc ) {
                 $part .= $1;
             }
             else {
-                if ($part) { push @body_parts, $part; }
+                if ( length($part) ) { push @body_parts, $part; }
                 last;
             }
         }
                 last;
             }
         }
@@ -2346,11 +2709,43 @@ sub dump_defaults {
 }
 
 sub dump_options {
 }
 
 sub dump_options {
-    my ($rOpts) = @_;
-    local $" = "\n";
-    print STDOUT "Final parameter set for this run\n";
-    foreach ( sort keys %{$rOpts} ) {
-        print STDOUT "$_=$rOpts->{$_}\n";
+
+    # write the options back out as a valid .perltidyrc file
+    my ( $rOpts, $roption_string ) = @_;
+    my %Getopt_flags;
+    my $rGetopt_flags = \%Getopt_flags;
+    foreach my $opt ( @{$roption_string} ) {
+        my $flag = "";
+        if ( $opt =~ /(.*)(!|=.*)$/ ) {
+            $opt  = $1;
+            $flag = $2;
+        }
+        if ( defined( $rOpts->{$opt} ) ) {
+            $rGetopt_flags->{$opt} = $flag;
+        }
+    }
+    print STDOUT "# Final parameter set for this run:\n";
+    foreach my $key ( sort keys %{$rOpts} ) {
+        my $flag   = $rGetopt_flags->{$key};
+        my $value  = $rOpts->{$key};
+        my $prefix = '--';
+        my $suffix = "";
+        if ($flag) {
+            if ( $flag =~ /^=/ ) {
+                if ( $value !~ /^\d+$/ ) { $value = '"' . $value . '"' }
+                $suffix = "=" . $value;
+            }
+            elsif ( $flag =~ /^!/ ) {
+                $prefix .= "no" unless ($value);
+            }
+            else {
+
+                # shouldn't happen
+                print
+                  "# ERROR in dump_options: unrecognized flag $flag for $key\n";
+            }
+        }
+        print STDOUT $prefix . $key . $suffix . "\n";
     }
 }
 
     }
 }
 
@@ -2358,7 +2753,7 @@ sub show_version {
     print <<"EOM";
 This is perltidy, v$VERSION 
 
     print <<"EOM";
 This is perltidy, v$VERSION 
 
-Copyright 2000-2003, Steve Hancock
+Copyright 2000-2006, Steve Hancock
 
 Perltidy is free software and may be copied under the terms of the GNU
 General Public License, which is included in the distribution files.
 
 Perltidy is free software and may be copied under the terms of the GNU
 General Public License, which is included in the distribution files.
@@ -3909,7 +4304,7 @@ BEGIN {
     #    my @list = qw" == != < > <= <=> ";
     #    @token_long_names{@list} = ('numerical-comparison') x scalar(@list);
     #
     #    my @list = qw" == != < > <= <=> ";
     #    @token_long_names{@list} = ('numerical-comparison') x scalar(@list);
     #
-    #    my @list = qw" && || ! &&= ||= ";
+    #    my @list = qw" && || ! &&= ||= //= ";
     #    @token_long_names{@list} = ('logical') x scalar(@list);
     #
     #    my @list = qw" . .= =~ !~ x x= ";
     #    @token_long_names{@list} = ('logical') x scalar(@list);
     #
     #    my @list = qw" . .= =~ !~ x x= ";
@@ -4475,8 +4870,7 @@ sub write_frame_html {
     my (
         $title,        $frame_filename, $top_basename,
         $toc_basename, $src_basename,   $src_frame_name
     my (
         $title,        $frame_filename, $top_basename,
         $toc_basename, $src_basename,   $src_frame_name
-      )
-      = @_;
+    ) = @_;
 
     my $fh = IO::File->new( $frame_filename, 'w' )
       or die "Cannot open $toc_basename:$!\n";
 
     my $fh = IO::File->new( $frame_filename, 'w' )
       or die "Cannot open $toc_basename:$!\n";
@@ -5036,6 +5430,10 @@ use vars qw{
   @nonblank_lines_at_depth
   $starting_in_quote
 
   @nonblank_lines_at_depth
   $starting_in_quote
 
+  $in_format_skipping_section
+  $format_skipping_pattern_begin
+  $format_skipping_pattern_end
+
   $forced_breakpoint_count
   $forced_breakpoint_undo_count
   @forced_breakpoint_undo_stack
   $forced_breakpoint_count
   $forced_breakpoint_undo_count
   @forced_breakpoint_undo_stack
@@ -5106,6 +5504,7 @@ use vars qw{
   @dont_align
   @want_comma_break
 
   @dont_align
   @want_comma_break
 
+  $is_static_block_comment
   $index_start_one_line_block
   $semicolons_before_block_self_destruct
   $index_max_forced_break
   $index_start_one_line_block
   $semicolons_before_block_self_destruct
   $index_max_forced_break
@@ -5124,6 +5523,11 @@ use vars qw{
   %opening_vertical_tightness
   %closing_vertical_tightness
   %closing_token_indentation
   %opening_vertical_tightness
   %closing_vertical_tightness
   %closing_token_indentation
+
+  %opening_token_right
+  %stack_opening_token
+  %stack_closing_token
+
   $block_brace_vertical_tightness_pattern
 
   $rOpts_add_newlines
   $block_brace_vertical_tightness_pattern
 
   $rOpts_add_newlines
@@ -5148,7 +5552,10 @@ use vars qw{
   $rOpts_maximum_line_length
   $rOpts_short_concatenation_item_length
   $rOpts_swallow_optional_blank_lines
   $rOpts_maximum_line_length
   $rOpts_short_concatenation_item_length
   $rOpts_swallow_optional_blank_lines
-  $rOpts_ignore_old_line_breaks
+  $rOpts_ignore_old_breakpoints
+  $rOpts_format_skipping
+  $rOpts_space_function_paren
+  $rOpts_space_keyword_paren
 
   $half_maximum_line_length
 
 
   $half_maximum_line_length
 
@@ -5179,17 +5586,17 @@ BEGIN {
     $bli_list_string = 'if else elsif unless while for foreach do : sub';
 
     @_ = qw(
     $bli_list_string = 'if else elsif unless while for foreach do : sub';
 
     @_ = qw(
-      .. :: << >> ** && .. ||  -> => += -= .= %= &= |= ^= *= <>
+      .. :: << >> ** && .. || // -> => += -= .= %= &= |= ^= *= <>
       <= >= == =~ !~ != ++ -- /= x=
     );
     @is_digraph{@_} = (1) x scalar(@_);
 
       <= >= == =~ !~ != ++ -- /= x=
     );
     @is_digraph{@_} = (1) x scalar(@_);
 
-    @_ = qw( ... **= <<= >>= &&= ||= <=> );
+    @_ = qw( ... **= <<= >>= &&= ||= //= <=> );
     @is_trigraph{@_} = (1) x scalar(@_);
 
     @_ = qw(
       = **= += *= &= <<= &&=
     @is_trigraph{@_} = (1) x scalar(@_);
 
     @_ = qw(
       = **= += *= &= <<= &&=
-      -= /= |= >>= ||=
+      -= /= |= >>= ||= //=
       .= %= ^=
       x=
     );
       .= %= ^=
       x=
     );
@@ -5205,7 +5612,7 @@ BEGIN {
     );
     @is_keyword_returning_list{@_} = (1) x scalar(@_);
 
     );
     @is_keyword_returning_list{@_} = (1) x scalar(@_);
 
-    @_ = qw(is if unless and or last next redo return);
+    @_ = qw(is if unless and or err last next redo return);
     @is_if_unless_and_or_last_next_redo_return{@_} = (1) x scalar(@_);
 
     @_ = qw(last next redo return);
     @is_if_unless_and_or_last_next_redo_return{@_} = (1) x scalar(@_);
 
     @_ = qw(last next redo return);
@@ -5223,9 +5630,13 @@ BEGIN {
     @_ = qw(if unless);
     @is_if_unless{@_} = (1) x scalar(@_);
 
     @_ = qw(if unless);
     @is_if_unless{@_} = (1) x scalar(@_);
 
-    @_ = qw(and or);
+    @_ = qw(and or err);
     @is_and_or{@_} = (1) x scalar(@_);
 
     @is_and_or{@_} = (1) x scalar(@_);
 
+    # Identify certain operators which often occur in chains
+    @_ = qw(&& || and or : ? .);
+    @is_chain_operator{@_} = (1) x scalar(@_);
+
     # We can remove semicolons after blocks preceded by these keywords
     @_ = qw(BEGIN END CHECK INIT AUTOLOAD DESTROY continue if elsif else
       unless while until for foreach);
     # We can remove semicolons after blocks preceded by these keywords
     @_ = qw(BEGIN END CHECK INIT AUTOLOAD DESTROY continue if elsif else
       unless while until for foreach);
@@ -5426,6 +5837,7 @@ sub new {
     $first_added_semicolon_at   = 0;
     $last_added_semicolon_at    = 0;
     $last_line_had_side_comment = 0;
     $first_added_semicolon_at   = 0;
     $last_added_semicolon_at    = 0;
     $last_line_had_side_comment = 0;
+    $is_static_block_comment    = 0;
     %postponed_breakpoint       = ();
 
     # variables for adding side comments
     %postponed_breakpoint       = ();
 
     # variables for adding side comments
@@ -5433,7 +5845,8 @@ sub new {
     %block_opening_line_number = ();
     $csc_new_statement_ok      = 1;
 
     %block_opening_line_number = ();
     $csc_new_statement_ok      = 1;
 
-    %saved_opening_indentation = ();
+    %saved_opening_indentation  = ();
+    $in_format_skipping_section = 0;
 
     reset_block_text_accumulator();
 
 
     reset_block_text_accumulator();
 
@@ -6365,6 +6778,10 @@ sub check_options {
     make_static_side_comment_pattern();
     make_closing_side_comment_prefix();
     make_closing_side_comment_list_pattern();
     make_static_side_comment_pattern();
     make_closing_side_comment_prefix();
     make_closing_side_comment_list_pattern();
+    $format_skipping_pattern_begin =
+      make_format_skipping_pattern( 'format-skipping-begin', '#<<<' );
+    $format_skipping_pattern_end =
+      make_format_skipping_pattern( 'format-skipping-end', '#>>>' );
 
     # If closing side comments ARE selected, then we can safely
     # delete old closing side comments unless closing side comment
 
     # If closing side comments ARE selected, then we can safely
     # delete old closing side comments unless closing side comment
@@ -6493,6 +6910,7 @@ EOM
     if ( $_ = $rOpts->{'nowant-right-space'} ) {
         s/^\s+//;
         s/\s+$//;
     if ( $_ = $rOpts->{'nowant-right-space'} ) {
         s/^\s+//;
         s/\s+$//;
+        @_ = split /\s+/;
         @want_right_space{@_} = (-1) x scalar(@_);
     }
     if ( $rOpts->{'dump-want-left-space'} ) {
         @want_right_space{@_} = (-1) x scalar(@_);
     }
     if ( $rOpts->{'dump-want-left-space'} ) {
@@ -6507,7 +6925,7 @@ EOM
 
     # default keywords for which space is introduced before an opening paren
     # (at present, including them messes up vertical alignment)
 
     # default keywords for which space is introduced before an opening paren
     # (at present, including them messes up vertical alignment)
-    @_ = qw(my local our and or eq ne if else elsif until
+    @_ = qw(my local our and or err eq ne if else elsif until
       unless while for foreach return switch case given when);
     @space_after_keyword{@_} = (1) x scalar(@_);
 
       unless while for foreach return switch case given when);
     @space_after_keyword{@_} = (1) x scalar(@_);
 
@@ -6557,7 +6975,9 @@ EOM
     # make note if breaks are before certain key types
     %want_break_before = ();
 
     # make note if breaks are before certain key types
     %want_break_before = ();
 
-    foreach my $tok ( '.', ',', ':', '?', '&&', '||', 'and', 'or', 'xor' ) {
+    foreach
+      my $tok ( '.', ',', ':', '?', '&&', '||', 'and', 'or', 'err', 'xor' )
+    {
         $want_break_before{$tok} =
           $left_bond_strength{$tok} < $right_bond_strength{$tok};
     }
         $want_break_before{$tok} =
           $left_bond_strength{$tok} < $right_bond_strength{$tok};
     }
@@ -6628,7 +7048,6 @@ EOM
     }
 
     my $ole = $rOpts->{'output-line-ending'};
     }
 
     my $ole = $rOpts->{'output-line-ending'};
-    ##if ($^O =~ /^(VMS|
     if ($ole) {
         my %endings = (
             dos  => "\015\012",
     if ($ole) {
         my %endings = (
             dos  => "\015\012",
@@ -6697,7 +7116,10 @@ EOM
       $rOpts->{'short-concatenation-item-length'};
     $rOpts_swallow_optional_blank_lines =
       $rOpts->{'swallow-optional-blank-lines'};
       $rOpts->{'short-concatenation-item-length'};
     $rOpts_swallow_optional_blank_lines =
       $rOpts->{'swallow-optional-blank-lines'};
-    $rOpts_ignore_old_line_breaks = $rOpts->{'ignore-old-line-breaks'};
+    $rOpts_ignore_old_breakpoints = $rOpts->{'ignore-old-breakpoints'};
+    $rOpts_format_skipping        = $rOpts->{'format-skipping'};
+    $rOpts_space_function_paren   = $rOpts->{'space-function-paren'};
+    $rOpts_space_keyword_paren    = $rOpts->{'space-keyword-paren'};
     $half_maximum_line_length     = $rOpts_maximum_line_length / 2;
 
     # Note that both opening and closing tokens can access the opening
     $half_maximum_line_length     = $rOpts_maximum_line_length / 2;
 
     # Note that both opening and closing tokens can access the opening
@@ -6727,22 +7149,45 @@ EOM
         ']' => $rOpts->{'closing-square-bracket-indentation'},
         '>' => $rOpts->{'closing-paren-indentation'},
     );
         ']' => $rOpts->{'closing-square-bracket-indentation'},
         '>' => $rOpts->{'closing-paren-indentation'},
     );
+
+    %opening_token_right = (
+        '(' => $rOpts->{'opening-paren-right'},
+        '{' => $rOpts->{'opening-hash-brace-right'},
+        '[' => $rOpts->{'opening-square-bracket-right'},
+    );
+
+    %stack_opening_token = (
+        '(' => $rOpts->{'stack-opening-paren'},
+        '{' => $rOpts->{'stack-opening-hash-brace'},
+        '[' => $rOpts->{'stack-opening-square-bracket'},
+    );
+
+    %stack_closing_token = (
+        ')' => $rOpts->{'stack-closing-paren'},
+        '}' => $rOpts->{'stack-closing-hash-brace'},
+        ']' => $rOpts->{'stack-closing-square-bracket'},
+    );
 }
 
 sub make_static_block_comment_pattern {
 
     # create the pattern used to identify static block comments
 }
 
 sub make_static_block_comment_pattern {
 
     # create the pattern used to identify static block comments
-    $static_block_comment_pattern = '^(\s*)##';
+    $static_block_comment_pattern = '^\s*##';
 
     # allow the user to change it
     if ( $rOpts->{'static-block-comment-prefix'} ) {
         my $prefix = $rOpts->{'static-block-comment-prefix'};
         $prefix =~ s/^\s*//;
 
     # allow the user to change it
     if ( $rOpts->{'static-block-comment-prefix'} ) {
         my $prefix = $rOpts->{'static-block-comment-prefix'};
         $prefix =~ s/^\s*//;
-        if ( $prefix !~ /^#/ ) {
-            die "ERROR: the -sbcp prefix '$prefix' must begin with '#'\n";
+        my $pattern = $prefix;
 
 
+        # user may give leading caret to force matching left comments only
+        if ( $prefix !~ /^\^#/ ) {
+            if ( $prefix !~ /^#/ ) {
+                die
+"ERROR: the -sbcp prefix is '$prefix' but must begin with '#' or '^#'\n";
+            }
+            $pattern = '^\s*' . $prefix;
         }
         }
-        my $pattern = '^(\s*)' . $prefix;
         eval "'##'=~/$pattern/";
         if ($@) {
             die
         eval "'##'=~/$pattern/";
         if ($@) {
             die
@@ -6752,6 +7197,23 @@ sub make_static_block_comment_pattern {
     }
 }
 
     }
 }
 
+sub make_format_skipping_pattern {
+    my ( $opt_name, $default ) = @_;
+    my $param = $rOpts->{$opt_name};
+    unless ($param) { $param = $default }
+    $param =~ s/^\s*//;
+    if ( $param !~ /^#/ ) {
+        die "ERROR: the $opt_name parameter '$param' must begin with '#'\n";
+    }
+    my $pattern = '^' . $param . '\s';
+    eval "'#'=~/$pattern/";
+    if ($@) {
+        die
+"ERROR: the $opt_name parameter '$param' causes the invalid regex '$pattern'\n";
+    }
+    return $pattern;
+}
+
 sub make_closing_side_comment_list_pattern {
 
     # turn any input list into a regex for recognizing selected block types
 sub make_closing_side_comment_list_pattern {
 
     # turn any input list into a regex for recognizing selected block types
@@ -6766,12 +7228,8 @@ sub make_closing_side_comment_list_pattern {
 
 sub make_bli_pattern {
 
 
 sub make_bli_pattern {
 
-    if (
-        defined(
-                 $rOpts->{'brace-left-and-indent-list'}
-              && $rOpts->{'brace-left-and-indent-list'}
-        )
-      )
+    if ( defined( $rOpts->{'brace-left-and-indent-list'} )
+        && $rOpts->{'brace-left-and-indent-list'} )
     {
         $bli_list_string = $rOpts->{'brace-left-and-indent-list'};
     }
     {
         $bli_list_string = $rOpts->{'brace-left-and-indent-list'};
     }
@@ -6785,12 +7243,8 @@ sub make_block_brace_vertical_tightness_pattern {
     $block_brace_vertical_tightness_pattern =
       '^((if|else|elsif|unless|while|for|foreach|do|\w+:)$|sub)';
 
     $block_brace_vertical_tightness_pattern =
       '^((if|else|elsif|unless|while|for|foreach|do|\w+:)$|sub)';
 
-    if (
-        defined(
-                 $rOpts->{'block-brace-vertical-tightness-list'}
-              && $rOpts->{'block-brace-vertical-tightness-list'}
-        )
-      )
+    if ( defined( $rOpts->{'block-brace-vertical-tightness-list'} )
+        && $rOpts->{'block-brace-vertical-tightness-list'} )
     {
         $block_brace_vertical_tightness_pattern =
           make_block_pattern( '-bbvtl',
     {
         $block_brace_vertical_tightness_pattern =
           make_block_pattern( '-bbvtl',
@@ -6957,7 +7411,8 @@ EOM
 
     sub is_essential_whitespace {
 
 
     sub is_essential_whitespace {
 
-        # Essential whitespace means whitespace which cannot be safely deleted.
+        # Essential whitespace means whitespace which cannot be safely deleted
+        # without risking the introduction of a syntax error.
         # We are given three tokens and their types:
         # ($tokenl, $typel) is the token to the left of the space in question
         # ($tokenr, $typer) is the token to the right of the space in question
         # We are given three tokens and their types:
         # ($tokenl, $typel) is the token to the left of the space in question
         # ($tokenr, $typer) is the token to the right of the space in question
@@ -6965,6 +7420,9 @@ EOM
         #
         # This is a slow routine but is not needed too often except when -mangle
         # is used.
         #
         # This is a slow routine but is not needed too often except when -mangle
         # is used.
+        #
+        # Note: This routine should almost never need to be changed.  It is
+        # for avoiding syntax problems rather than for formatting.
         my ( $tokenll, $typell, $tokenl, $typel, $tokenr, $typer ) = @_;
 
         # never combine two bare words or numbers
         my ( $tokenll, $typell, $tokenl, $typel, $tokenr, $typer ) = @_;
 
         # never combine two bare words or numbers
@@ -7128,9 +7586,9 @@ sub set_white_space_flag {
         @is_closing_type{@_} = (1) x scalar(@_);
 
         my @spaces_both_sides = qw"
         @is_closing_type{@_} = (1) x scalar(@_);
 
         my @spaces_both_sides = qw"
-          + - * / % ? = . : x < > | & ^ .. << >> ** && .. ||  => += -=
+          + - * / % ? = . : x < > | & ^ .. << >> ** && .. || // => += -=
           .= %= x= &= |= ^= *= <> <= >= == =~ !~ /= != ... <<= >>=
           .= %= x= &= |= ^= *= <> <= >= == =~ !~ /= != ... <<= >>=
-          &&= ||= <=> A k f w F n C Y U G v
+          &&= ||= //= <=> A k f w F n C Y U G v
           ";
 
         my @spaces_left_side = qw"
           ";
 
         my @spaces_left_side = qw"
@@ -7377,39 +7835,36 @@ sub set_white_space_flag {
         if ( $token eq '(' ) {
 
             # This will have to be tweaked as tokenization changes.
         if ( $token eq '(' ) {
 
             # This will have to be tweaked as tokenization changes.
-            # We want a space after certain block types:
+            # We usually want a space at '} (', for example:
             #     map { 1 * $_; } ( $y, $M, $w, $d, $h, $m, $s );
             #
             # But not others:
             #     map { 1 * $_; } ( $y, $M, $w, $d, $h, $m, $s );
             #
             # But not others:
-            #     &{ $_->[1] } ( delete $_[$#_]{ $_->[0] } );
-            # At present, the & block is not marked as a code block, so
-            # this works:
-            if ( $last_type eq '}' ) {
+            #     &{ $_->[1] }( delete $_[$#_]{ $_->[0] } );
+            # At present, the above & block is marked as type L/R so this case
+            # won't go through here.
+            if ( $last_type eq '}' ) { $ws = WS_YES }
 
 
-                if ( $is_sort_map_grep{$last_block_type} ) {
-                    $ws = WS_YES;
-                }
-                else {
-                    $ws = WS_NO;
-                }
+            # NOTE: some older versions of Perl had occasional problems if
+            # spaces are introduced between keywords or functions and opening
+            # parens.  So the default is not to do this except is certain
+            # cases.  The current Perl seems to tolerate spaces.
+
+            # Space between keyword and '('
+            elsif ( $last_type eq 'k' ) {
+                $ws = WS_NO
+                  unless ( $rOpts_space_keyword_paren
+                    || $space_after_keyword{$last_token} );
             }
 
             }
 
+            # Space between function and '('
             # -----------------------------------------------------
             # 'w' and 'i' checks for something like:
             #   myfun(    &myfun(   ->myfun(
             # -----------------------------------------------------
             # -----------------------------------------------------
             # 'w' and 'i' checks for something like:
             #   myfun(    &myfun(   ->myfun(
             # -----------------------------------------------------
-            if (   ( $last_type =~ /^[wkU]$/ )
+            elsif (( $last_type =~ /^[wU]$/ )
                 || ( $last_type =~ /^[wi]$/ && $last_token =~ /^(\&|->)/ ) )
             {
                 || ( $last_type =~ /^[wi]$/ && $last_token =~ /^(\&|->)/ ) )
             {
-
-                # Do not introduce new space between keyword or function
-                # ( except in special cases) because this can
-                # introduce errors in some cases ( prnterr1.t )
-                unless ( $last_type eq 'k'
-                    && $space_after_keyword{$last_token} )
-                {
-                    $ws = WS_NO;
-                }
+                $ws = WS_NO unless ($rOpts_space_function_paren);
             }
 
             # space between something like $i and ( in
             }
 
             # space between something like $i and ( in
@@ -7422,7 +7877,6 @@ sub set_white_space_flag {
 
             # allow constant function followed by '()' to retain no space
             elsif ( $last_type eq 'C' && $$rtokens[ $j + 1 ] eq ')' ) {
 
             # allow constant function followed by '()' to retain no space
             elsif ( $last_type eq 'C' && $$rtokens[ $j + 1 ] eq ')' ) {
-                ;
                 $ws = WS_NO;
             }
         }
                 $ws = WS_NO;
             }
         }
@@ -7626,8 +8080,7 @@ sub set_white_space_flag {
                 $nesting_blocks,        $no_internal_newlines,
                 $slevel,                $token,
                 $type,                  $type_sequence,
                 $nesting_blocks,        $no_internal_newlines,
                 $slevel,                $token,
                 $type,                  $type_sequence,
-              )
-              = @saved_token;
+            ) = @saved_token;
         }
     }
 
         }
     }
 
@@ -7772,12 +8225,13 @@ sub set_white_space_flag {
         my $next_nonblank_token_type;
         my $rwhite_space_flag;
 
         my $next_nonblank_token_type;
         my $rwhite_space_flag;
 
-        $jmax                  = @$rtokens - 1;
-        $block_type            = "";
-        $container_type        = "";
-        $container_environment = "";
-        $type_sequence         = "";
-        $no_internal_newlines  = 1 - $rOpts_add_newlines;
+        $jmax                    = @$rtokens - 1;
+        $block_type              = "";
+        $container_type          = "";
+        $container_environment   = "";
+        $type_sequence           = "";
+        $no_internal_newlines    = 1 - $rOpts_add_newlines;
+        $is_static_block_comment = 0;
 
         # Handle a continued quote..
         if ($in_continued_quote) {
 
         # Handle a continued quote..
         if ($in_continued_quote) {
@@ -7807,6 +8261,36 @@ sub set_white_space_flag {
             }
         }
 
             }
         }
 
+        # Write line verbatim if we are in a formatting skip section
+        if ($in_format_skipping_section) {
+            write_unindented_line("$input_line");
+            $last_line_had_side_comment = 0;
+
+            # Note: extra space appended to comment simplifies pattern matching
+            if (   $jmax == 0
+                && $$rtoken_type[0] eq '#'
+                && ( $$rtokens[0] . " " ) =~ /$format_skipping_pattern_end/o )
+            {
+                $in_format_skipping_section = 0;
+                write_logfile_entry("Exiting formatting skip section\n");
+            }
+            return;
+        }
+
+        # See if we are entering a formatting skip section
+        if (   $rOpts_format_skipping
+            && $jmax == 0
+            && $$rtoken_type[0] eq '#'
+            && ( $$rtokens[0] . " " ) =~ /$format_skipping_pattern_begin/o )
+        {
+            flush();
+            $in_format_skipping_section = 1;
+            write_logfile_entry("Entering formatting skip section\n");
+            write_unindented_line("$input_line");
+            $last_line_had_side_comment = 0;
+            return;
+        }
+
         # delete trailing blank tokens
         if ( $jmax > 0 && $$rtoken_type[$jmax] eq 'b' ) { $jmax-- }
 
         # delete trailing blank tokens
         if ( $jmax > 0 && $$rtoken_type[$jmax] eq 'b' ) { $jmax-- }
 
@@ -7825,8 +8309,7 @@ sub set_white_space_flag {
             return;
         }
 
             return;
         }
 
-        # see if this is a static block comment (starts with ##)
-        my $is_static_block_comment                       = 0;
+        # see if this is a static block comment (starts with ## by default)
         my $is_static_block_comment_without_leading_space = 0;
         if (   $jmax == 0
             && $$rtoken_type[0] eq '#'
         my $is_static_block_comment_without_leading_space = 0;
         if (   $jmax == 0
             && $$rtoken_type[0] eq '#'
@@ -7835,7 +8318,7 @@ sub set_white_space_flag {
         {
             $is_static_block_comment                       = 1;
             $is_static_block_comment_without_leading_space =
         {
             $is_static_block_comment                       = 1;
             $is_static_block_comment_without_leading_space =
-              ( length($1) <= 0 );
+              substr( $input_line, 0, 1 ) eq '#';
         }
 
         # create a hanging side comment if appropriate
         }
 
         # create a hanging side comment if appropriate
@@ -7940,7 +8423,7 @@ sub set_white_space_flag {
         #       /([\$*])(([\w\:\']*)\bVERSION)\b.*\=/
         #   Examples:
         #     *VERSION = \'1.01';
         #       /([\$*])(([\w\:\']*)\bVERSION)\b.*\=/
         #   Examples:
         #     *VERSION = \'1.01';
-        #     ( $VERSION ) = '$Revision: 1.46 $ ' =~ /\$Revision:\s+([^\s]+)/;
+        #     ( $VERSION ) = '$Revision: 1.49 $ ' =~ /\$Revision:\s+([^\s]+)/;
         #   We will pass such a line straight through without breaking
         #   it unless -npvl is used
 
         #   We will pass such a line straight through without breaking
         #   it unless -npvl is used
 
@@ -8622,7 +9105,7 @@ sub set_white_space_flag {
         }
 
         # mark old line breakpoints in current output stream
         }
 
         # mark old line breakpoints in current output stream
-        if ( $max_index_to_go >= 0 && !$rOpts_ignore_old_line_breaks ) {
+        if ( $max_index_to_go >= 0 && !$rOpts_ignore_old_breakpoints ) {
             $old_breakpoint_to_go[$max_index_to_go] = 1;
         }
     }
             $old_breakpoint_to_go[$max_index_to_go] = 1;
         }
     }
@@ -8885,326 +9368,308 @@ sub undo_lp_ci {
       @reduced_spaces_to_go[ @$ri_first[ $line_1 .. $n ] ];
 }
 
       @reduced_spaces_to_go[ @$ri_first[ $line_1 .. $n ] ];
 }
 
-{
+sub set_logical_padding {
 
 
-    # Identify certain operators which often occur in chains.
-    # We will try to improve alignment when these lead a line.
-    my %is_chain_operator;
+    # Look at a batch of lines and see if extra padding can improve the
+    # alignment when there are certain leading operators. Here is an
+    # example, in which some extra space is introduced before
+    # '( $year' to make it line up with the subsequent lines:
+    #
+    #       if (   ( $Year < 1601 )
+    #           || ( $Year > 2899 )
+    #           || ( $EndYear < 1601 )
+    #           || ( $EndYear > 2899 ) )
+    #       {
+    #           &Error_OutOfRange;
+    #       }
+    #
+    my ( $ri_first, $ri_last ) = @_;
+    my $max_line = @$ri_first - 1;
 
 
-    BEGIN {
-        @_ = qw(&& || and or : ? .);
-        @is_chain_operator{@_} = (1) x scalar(@_);
-    }
+    my ( $ibeg, $ibeg_next, $ibegm, $iend, $iendm, $ipad, $line, $pad_spaces,
+        $tok_next, $has_leading_op_next, $has_leading_op );
 
 
-    sub set_logical_padding {
+    # looking at each line of this batch..
+    foreach $line ( 0 .. $max_line - 1 ) {
 
 
-        # Look at a batch of lines and see if extra padding can improve the
-        # alignment when there are certain leading operators. Here is an
-        # example, in which some extra space is introduced before
-        # '( $year' to make it line up with the subsequent lines:
-        #
-        #       if (   ( $Year < 1601 )
-        #           || ( $Year > 2899 )
-        #           || ( $EndYear < 1601 )
-        #           || ( $EndYear > 2899 ) )
-        #       {
-        #           &Error_OutOfRange;
-        #       }
-        #
-        my ( $ri_first, $ri_last ) = @_;
-        my $max_line = @$ri_first - 1;
+        # see if the next line begins with a logical operator
+        $ibeg                = $$ri_first[$line];
+        $iend                = $$ri_last[$line];
+        $ibeg_next           = $$ri_first[ $line + 1 ];
+        $tok_next            = $tokens_to_go[$ibeg_next];
+        $has_leading_op_next = $is_chain_operator{$tok_next};
+        next unless ($has_leading_op_next);
 
 
-        my ( $ibeg, $ibeg_next, $ibegm, $iend, $iendm, $ipad, $line,
-            $pad_spaces, $tok_next, $has_leading_op_next, $has_leading_op );
+        # next line must not be at lesser depth
+        next
+          if ( $nesting_depth_to_go[$ibeg] > $nesting_depth_to_go[$ibeg_next] );
 
 
-        # looking at each line of this batch..
-        foreach $line ( 0 .. $max_line - 1 ) {
+        # identify the token in this line to be padded on the left
+        $ipad = undef;
 
 
-            # see if the next line begins with a logical operator
-            $ibeg                = $$ri_first[$line];
-            $iend                = $$ri_last[$line];
-            $ibeg_next           = $$ri_first[ $line + 1 ];
-            $tok_next            = $tokens_to_go[$ibeg_next];
-            $has_leading_op_next = $is_chain_operator{$tok_next};
-            next unless ($has_leading_op_next);
+        # handle lines at same depth...
+        if ( $nesting_depth_to_go[$ibeg] == $nesting_depth_to_go[$ibeg_next] ) {
 
 
-            # next line must not be at lesser depth
-            next
-              if ( $nesting_depth_to_go[$ibeg] >
-                $nesting_depth_to_go[$ibeg_next] );
+            # if this is not first line of the batch ...
+            if ( $line > 0 ) {
 
 
-            # identify the token in this line to be padded on the left
-            $ipad = undef;
+                # and we have leading operator
+                next if $has_leading_op;
 
 
-            # handle lines at same depth...
-            if ( $nesting_depth_to_go[$ibeg] ==
-                $nesting_depth_to_go[$ibeg_next] )
-            {
+                # and ..
+                # 1. the previous line is at lesser depth, or
+                # 2. the previous line ends in an assignment
+                #
+                # Example 1: previous line at lesser depth
+                #       if (   ( $Year < 1601 )      # <- we are here but
+                #           || ( $Year > 2899 )      #  list has not yet
+                #           || ( $EndYear < 1601 )   # collapsed vertically
+                #           || ( $EndYear > 2899 ) )
+                #       {
+                #
+                # Example 2: previous line ending in assignment:
+                #    $leapyear =
+                #        $year % 4   ? 0     # <- We are here
+                #      : $year % 100 ? 1
+                #      : $year % 400 ? 0
+                #      : 1;
+                next
+                  unless (
+                    $is_assignment{ $types_to_go[$iendm] }
+                    || ( $nesting_depth_to_go[$ibegm] <
+                        $nesting_depth_to_go[$ibeg] )
+                  );
+
+                # we will add padding before the first token
+                $ipad = $ibeg;
+            }
 
 
-                # if this is not first line of the batch ...
-                if ( $line > 0 ) {
+            # for first line of the batch..
+            else {
 
 
-                    # and we have leading operator
-                    next if $has_leading_op;
+                # WARNING: Never indent if first line is starting in a
+                # continued quote, which would change the quote.
+                next if $starting_in_quote;
 
 
-                    # and ..
-                    # 1. the previous line is at lesser depth, or
-                    # 2. the previous line ends in an assignment
-                    #
-                    # Example 1: previous line at lesser depth
-                    #       if (   ( $Year < 1601 )      # <- we are here but
-                    #           || ( $Year > 2899 )      #  list has not yet
-                    #           || ( $EndYear < 1601 )   # collapsed vertically
-                    #           || ( $EndYear > 2899 ) )
-                    #       {
-                    #
-                    # Example 2: previous line ending in assignment:
-                    #    $leapyear =
-                    #        $year % 4   ? 0     # <- We are here
-                    #      : $year % 100 ? 1
-                    #      : $year % 400 ? 0
-                    #      : 1;
-                    next
-                      unless (
-                        $is_assignment{ $types_to_go[$iendm] }
-                        || ( $nesting_depth_to_go[$ibegm] <
-                            $nesting_depth_to_go[$ibeg] )
-                      );
+                # if this is text after closing '}'
+                # then look for an interior token to pad
+                if ( $types_to_go[$ibeg] eq '}' ) {
 
 
-                    # we will add padding before the first token
-                    $ipad = $ibeg;
                 }
 
                 }
 
-                # for first line of the batch..
+                # otherwise, we might pad if it looks really good
                 else {
 
                 else {
 
-                    # WARNING: Never indent if first line is starting in a
-                    # continued quote, which would change the quote.
-                    next if $starting_in_quote;
-
-                    # if this is text after closing '}'
-                    # then look for an interior token to pad
-                    if ( $types_to_go[$ibeg] eq '}' ) {
-
+                    # we might pad token $ibeg, so be sure that it
+                    # is at the same depth as the next line.
+                    next
+                      if ( $nesting_depth_to_go[ $ibeg + 1 ] !=
+                        $nesting_depth_to_go[$ibeg_next] );
+
+                    # We can pad on line 1 of a statement if at least 3
+                    # lines will be aligned. Otherwise, it
+                    # can look very confusing.
+                    if ( $max_line > 2 ) {
+                        my $leading_token = $tokens_to_go[$ibeg_next];
+
+                        # never indent line 1 of a '.' series because
+                        # previous line is most likely at same level.
+                        # TODO: we should also look at the leasing_spaces
+                        # of the last output line and skip if it is same
+                        # as this line.
+                        next if ( $leading_token eq '.' );
+
+                        my $count = 1;
+                        foreach my $l ( 2 .. 3 ) {
+                            my $ibeg_next_next = $$ri_first[ $line + $l ];
+                            next
+                              unless $tokens_to_go[$ibeg_next_next] eq
+                              $leading_token;
+                            $count++;
+                        }
+                        next unless $count == 3;
+                        $ipad = $ibeg;
                     }
                     }
-
-                    # otherwise, we might pad if it looks really good
                     else {
                     else {
-
-                        # we might pad token $ibeg, so be sure that it
-                        # is at the same depth as the next line.
-                        next
-                          if ( $nesting_depth_to_go[ $ibeg + 1 ] !=
-                            $nesting_depth_to_go[$ibeg_next] );
-
-                        # We can pad on line 1 of a statement if at least 3
-                        # lines will be aligned. Otherwise, it
-                        # can look very confusing.
-                        if ( $max_line > 2 ) {
-                            my $leading_token = $tokens_to_go[$ibeg_next];
-
-                            # never indent line 1 of a '.' series because
-                            # previous line is most likely at same level.
-                            # TODO: we should also look at the leasing_spaces
-                            # of the last output line and skip if it is same
-                            # as this line.
-                            next if ( $leading_token eq '.' );
-
-                            my $count = 1;
-                            foreach my $l ( 2 .. 3 ) {
-                                my $ibeg_next_next = $$ri_first[ $line + $l ];
-                                next
-                                  unless $tokens_to_go[$ibeg_next_next] eq
-                                  $leading_token;
-                                $count++;
-                            }
-                            next unless $count == 3;
-                            $ipad = $ibeg;
-                        }
-                        else {
-                            next;
-                        }
+                        next;
                     }
                 }
             }
                     }
                 }
             }
+        }
 
 
-            # find interior token to pad if necessary
-            if ( !defined($ipad) ) {
+        # find interior token to pad if necessary
+        if ( !defined($ipad) ) {
 
 
-                for ( my $i = $ibeg ; ( $i < $iend ) && !$ipad ; $i++ ) {
+            for ( my $i = $ibeg ; ( $i < $iend ) && !$ipad ; $i++ ) {
 
 
-                    # find any unclosed container
-                    next
-                      unless ( $type_sequence_to_go[$i]
-                        && $mate_index_to_go[$i] > $iend );
-
-                    # find next nonblank token to pad
-                    $ipad = $i + 1;
-                    if ( $types_to_go[$ipad] eq 'b' ) {
-                        $ipad++;
-                        last if ( $ipad > $iend );
-                    }
+                # find any unclosed container
+                next
+                  unless ( $type_sequence_to_go[$i]
+                    && $mate_index_to_go[$i] > $iend );
+
+                # find next nonblank token to pad
+                $ipad = $i + 1;
+                if ( $types_to_go[$ipad] eq 'b' ) {
+                    $ipad++;
+                    last if ( $ipad > $iend );
                 }
                 }
-                last unless $ipad;
             }
             }
+            last unless $ipad;
+        }
 
 
-            # next line must not be at greater depth
-            my $iend_next = $$ri_last[ $line + 1 ];
-            next
-              if ( $nesting_depth_to_go[ $iend_next + 1 ] >
-                $nesting_depth_to_go[$ipad] );
-
-            # lines must be somewhat similar to be padded..
-            my $inext_next = $ibeg_next + 1;
-            if ( $types_to_go[$inext_next] eq 'b' ) {
-                $inext_next++;
-            }
-            my $type = $types_to_go[$ipad];
-
-            # see if there are multiple continuation lines
-            my $logical_continuation_lines = 1;
-            if ( $line + 2 <= $max_line ) {
-                my $leading_token  = $tokens_to_go[$ibeg_next];
-                my $ibeg_next_next = $$ri_first[ $line + 2 ];
-                if (   $tokens_to_go[$ibeg_next_next] eq $leading_token
-                    && $nesting_depth_to_go[$ibeg_next] eq
-                    $nesting_depth_to_go[$ibeg_next_next] )
-                {
-                    $logical_continuation_lines++;
-                }
+        # next line must not be at greater depth
+        my $iend_next = $$ri_last[ $line + 1 ];
+        next
+          if ( $nesting_depth_to_go[ $iend_next + 1 ] >
+            $nesting_depth_to_go[$ipad] );
+
+        # lines must be somewhat similar to be padded..
+        my $inext_next = $ibeg_next + 1;
+        if ( $types_to_go[$inext_next] eq 'b' ) {
+            $inext_next++;
+        }
+        my $type = $types_to_go[$ipad];
+
+        # see if there are multiple continuation lines
+        my $logical_continuation_lines = 1;
+        if ( $line + 2 <= $max_line ) {
+            my $leading_token  = $tokens_to_go[$ibeg_next];
+            my $ibeg_next_next = $$ri_first[ $line + 2 ];
+            if (   $tokens_to_go[$ibeg_next_next] eq $leading_token
+                && $nesting_depth_to_go[$ibeg_next] eq
+                $nesting_depth_to_go[$ibeg_next_next] )
+            {
+                $logical_continuation_lines++;
             }
             }
-            if (
+        }
+        if (
 
 
-                # either we have multiple continuation lines to follow
-                # and we are not padding the first token
-                ( $logical_continuation_lines > 1 && $ipad > 0 )
+            # either we have multiple continuation lines to follow
+            # and we are not padding the first token
+            ( $logical_continuation_lines > 1 && $ipad > 0 )
 
 
-                # or..
-                || (
+            # or..
+            || (
 
 
-                    # types must match
-                    $types_to_go[$inext_next] eq $type
+                # types must match
+                $types_to_go[$inext_next] eq $type
 
 
-                    # and keywords must match if keyword
-                    && !(
-                           $type eq 'k'
-                        && $tokens_to_go[$ipad] ne $tokens_to_go[$inext_next]
-                    )
+                # and keywords must match if keyword
+                && !(
+                       $type eq 'k'
+                    && $tokens_to_go[$ipad] ne $tokens_to_go[$inext_next]
                 )
                 )
-              )
-            {
+            )
+          )
+        {
 
 
-                #----------------------begin special check---------------
-                #
-                # One more check is needed before we can make the pad.
-                # If we are in a list with some long items, we want each
-                # item to stand out.  So in the following example, the
-                # first line begining with '$casefold->' would look good
-                # padded to align with the next line, but then it
-                # would be indented more than the last line, so we
-                # won't do it.
-                #
-                #  ok(
-                #      $casefold->{code}         eq '0041'
-                #        && $casefold->{status}  eq 'C'
-                #        && $casefold->{mapping} eq '0061',
-                #      'casefold 0x41'
-                #  );
-                #
-                # Note:
-                # It would be faster, and almost as good, to use a comma
-                # count, and not pad if comma_count > 1 and the previous
-                # line did not end with a comma.
-                #
-                my $ok_to_pad = 1;
+            #----------------------begin special check---------------
+            #
+            # One more check is needed before we can make the pad.
+            # If we are in a list with some long items, we want each
+            # item to stand out.  So in the following example, the
+            # first line begining with '$casefold->' would look good
+            # padded to align with the next line, but then it
+            # would be indented more than the last line, so we
+            # won't do it.
+            #
+            #  ok(
+            #      $casefold->{code}         eq '0041'
+            #        && $casefold->{status}  eq 'C'
+            #        && $casefold->{mapping} eq '0061',
+            #      'casefold 0x41'
+            #  );
+            #
+            # Note:
+            # It would be faster, and almost as good, to use a comma
+            # count, and not pad if comma_count > 1 and the previous
+            # line did not end with a comma.
+            #
+            my $ok_to_pad = 1;
 
 
-                my $ibg   = $$ri_first[ $line + 1 ];
-                my $depth = $nesting_depth_to_go[ $ibg + 1 ];
+            my $ibg   = $$ri_first[ $line + 1 ];
+            my $depth = $nesting_depth_to_go[ $ibg + 1 ];
 
 
-                # just use simplified formula for leading spaces to avoid
-                # needless sub calls
-                my $lsp = $levels_to_go[$ibg] + $ci_levels_to_go[$ibg];
+            # just use simplified formula for leading spaces to avoid
+            # needless sub calls
+            my $lsp = $levels_to_go[$ibg] + $ci_levels_to_go[$ibg];
 
 
-                # look at each line beyond the next ..
-                my $l = $line + 1;
-                foreach $l ( $line + 2 .. $max_line ) {
-                    my $ibg = $$ri_first[$l];
+            # look at each line beyond the next ..
+            my $l = $line + 1;
+            foreach $l ( $line + 2 .. $max_line ) {
+                my $ibg = $$ri_first[$l];
 
 
-                    # quit looking at the end of this container
-                    last
-                      if ( $nesting_depth_to_go[ $ibg + 1 ] < $depth )
-                      || ( $nesting_depth_to_go[$ibg] < $depth );
+                # quit looking at the end of this container
+                last
+                  if ( $nesting_depth_to_go[ $ibg + 1 ] < $depth )
+                  || ( $nesting_depth_to_go[$ibg] < $depth );
 
 
-                    # cannot do the pad if a later line would be
-                    # outdented more
-                    if ( $levels_to_go[$ibg] + $ci_levels_to_go[$ibg] < $lsp ) {
-                        $ok_to_pad = 0;
-                        last;
-                    }
+                # cannot do the pad if a later line would be
+                # outdented more
+                if ( $levels_to_go[$ibg] + $ci_levels_to_go[$ibg] < $lsp ) {
+                    $ok_to_pad = 0;
+                    last;
                 }
                 }
+            }
 
 
-                # don't pad if we end in a broken list
-                if ( $l == $max_line ) {
-                    my $i2 = $$ri_last[$l];
-                    if ( $types_to_go[$i2] eq '#' ) {
-                        my $i1 = $$ri_first[$l];
-                        next
-                          if (
-                            terminal_type( \@types_to_go, \@block_type_to_go,
-                                $i1, $i2 ) eq ','
-                          );
-                    }
+            # don't pad if we end in a broken list
+            if ( $l == $max_line ) {
+                my $i2 = $$ri_last[$l];
+                if ( $types_to_go[$i2] eq '#' ) {
+                    my $i1 = $$ri_first[$l];
+                    next
+                      if (
+                        terminal_type( \@types_to_go, \@block_type_to_go, $i1,
+                            $i2 ) eq ','
+                      );
                 }
                 }
-                next unless $ok_to_pad;
+            }
+            next unless $ok_to_pad;
 
 
-                #----------------------end special check---------------
+            #----------------------end special check---------------
 
 
-                my $length_1 = total_line_length( $ibeg,      $ipad - 1 );
-                my $length_2 = total_line_length( $ibeg_next, $inext_next - 1 );
-                $pad_spaces = $length_2 - $length_1;
+            my $length_1 = total_line_length( $ibeg,      $ipad - 1 );
+            my $length_2 = total_line_length( $ibeg_next, $inext_next - 1 );
+            $pad_spaces = $length_2 - $length_1;
 
 
-                # make sure this won't change if -lp is used
-                my $indentation_1 = $leading_spaces_to_go[$ibeg];
-                if ( ref($indentation_1) ) {
-                    if ( $indentation_1->get_RECOVERABLE_SPACES() == 0 ) {
-                        my $indentation_2 = $leading_spaces_to_go[$ibeg_next];
-                        unless ( $indentation_2->get_RECOVERABLE_SPACES() == 0 )
-                        {
-                            $pad_spaces = 0;
-                        }
+            # make sure this won't change if -lp is used
+            my $indentation_1 = $leading_spaces_to_go[$ibeg];
+            if ( ref($indentation_1) ) {
+                if ( $indentation_1->get_RECOVERABLE_SPACES() == 0 ) {
+                    my $indentation_2 = $leading_spaces_to_go[$ibeg_next];
+                    unless ( $indentation_2->get_RECOVERABLE_SPACES() == 0 ) {
+                        $pad_spaces = 0;
                     }
                 }
                     }
                 }
+            }
 
 
-                # we might be able to handle a pad of -1 by removing a blank
-                # token
-                if ( $pad_spaces < 0 ) {
-                    if ( $pad_spaces == -1 ) {
-                        if ( $ipad > $ibeg && $types_to_go[ $ipad - 1 ] eq 'b' )
-                        {
-                            $tokens_to_go[ $ipad - 1 ] = '';
-                        }
+            # we might be able to handle a pad of -1 by removing a blank
+            # token
+            if ( $pad_spaces < 0 ) {
+                if ( $pad_spaces == -1 ) {
+                    if ( $ipad > $ibeg && $types_to_go[ $ipad - 1 ] eq 'b' ) {
+                        $tokens_to_go[ $ipad - 1 ] = '';
                     }
                     }
-                    $pad_spaces = 0;
                 }
                 }
+                $pad_spaces = 0;
+            }
 
 
-                # now apply any padding for alignment
-                if ( $ipad >= 0 && $pad_spaces ) {
-                    my $length_t = total_line_length( $ibeg, $iend );
-                    if ( $pad_spaces + $length_t <= $rOpts_maximum_line_length )
-                    {
-                        $tokens_to_go[$ipad] =
-                          ' ' x $pad_spaces . $tokens_to_go[$ipad];
-                    }
+            # now apply any padding for alignment
+            if ( $ipad >= 0 && $pad_spaces ) {
+                my $length_t = total_line_length( $ibeg, $iend );
+                if ( $pad_spaces + $length_t <= $rOpts_maximum_line_length ) {
+                    $tokens_to_go[$ipad] =
+                      ' ' x $pad_spaces . $tokens_to_go[$ipad];
                 }
             }
         }
                 }
             }
         }
-        continue {
-            $iendm          = $iend;
-            $ibegm          = $ibeg;
-            $has_leading_op = $has_leading_op_next;
-        }    # end of loop over lines
-        return;
     }
     }
+    continue {
+        $iendm          = $iend;
+        $ibegm          = $ibeg;
+        $has_leading_op = $has_leading_op_next;
+    }    # end of loop over lines
+    return;
 }
 
 sub correct_lp_indentation {
 }
 
 sub correct_lp_indentation {
@@ -10334,10 +10799,7 @@ sub send_lines_to_vertical_aligner {
                 && $rOpts->{'outdent-long-comments'}
 
                 # but not if this is a static block comment
                 && $rOpts->{'outdent-long-comments'}
 
                 # but not if this is a static block comment
-                && !(
-                       $rOpts->{'static-block-comments'}
-                    && $tokens_to_go[$ibeg] =~ /$static_block_comment_pattern/o
-                )
+                && !$is_static_block_comment
               )
         );
 
               )
         );
 
@@ -10578,320 +11040,398 @@ sub lookup_opening_indentation {
     return ( $rindentation_list->[ $nline + 1 ], $offset );
 }
 
     return ( $rindentation_list->[ $nline + 1 ], $offset );
 }
 
-sub set_adjusted_indentation {
-
-    # This routine has the final say regarding the actual indentation of
-    # a line.  It starts with the basic indentation which has been
-    # defined for the leading token, and then takes into account any
-    # options that the user has set regarding special indenting and
-    # outdenting.
-
-    my ( $ibeg, $iend, $rfields, $rpatterns, $ri_first, $ri_last,
-        $rindentation_list )
-      = @_;
-
-    # we need to know the last token of this line
-    my ( $terminal_type, $i_terminal ) =
-      terminal_type( \@types_to_go, \@block_type_to_go, $ibeg, $iend );
-
-    my $is_outdented_line = 0;
+{
+    my %is_if_elsif_else_unless_while_until_for_foreach;
 
 
-    my $is_semicolon_terminated = $terminal_type eq ';'
-      && $nesting_depth_to_go[$iend] < $nesting_depth_to_go[$ibeg];
+    BEGIN {
 
 
-    # Most lines are indented according to the initial token.
-    # But it is common to outdent to the level just after the
-    # terminal token in certain cases...
-    # adjust_indentation flag:
-    #       0 - do not adjust
-    #       1 - outdent
-    #       2 - vertically align with opening token
-    #       3 - indent
-    my $adjust_indentation         = 0;
-    my $default_adjust_indentation = $adjust_indentation;
+        # These block types may have text between the keyword and opening
+        # curly.  Note: 'else' does not, but must be included to allow trailing
+        # if/elsif text to be appended.
+        # patch for SWITCH/CASE: added 'case' and 'when'
+        @_ = qw(if elsif else unless while until for foreach case when);
+        @is_if_elsif_else_unless_while_until_for_foreach{@_} = (1) x scalar(@_);
+    }
 
 
-    my ( $opening_indentation, $opening_offset );
+    sub set_adjusted_indentation {
 
 
-    # if we are at a closing token of some type..
-    if ( $types_to_go[$ibeg] =~ /^[\)\}\]]$/ ) {
+        # This routine has the final say regarding the actual indentation of
+        # a line.  It starts with the basic indentation which has been
+        # defined for the leading token, and then takes into account any
+        # options that the user has set regarding special indenting and
+        # outdenting.
 
 
-        # get the indentation of the line containing the corresponding
-        # opening token
-        ( $opening_indentation, $opening_offset ) =
-          get_opening_indentation( $ibeg, $ri_first, $ri_last,
-            $rindentation_list );
-
-        # First set the default behavior:
-        # default behavior is to outdent closing lines
-        # of the form:   ");  };  ];  )->xxx;"
-        if (
-            $is_semicolon_terminated
+        my ( $ibeg, $iend, $rfields, $rpatterns, $ri_first, $ri_last,
+            $rindentation_list )
+          = @_;
 
 
-            # and 'cuddled parens' of the form:   ")->pack("
-            || (
-                   $terminal_type      eq '('
-                && $types_to_go[$ibeg] eq ')'
-                && ( $nesting_depth_to_go[$iend] + 1 ==
-                    $nesting_depth_to_go[$ibeg] )
-            )
-          )
-        {
-            $adjust_indentation = 1;
-        }
+        # we need to know the last token of this line
+        my ( $terminal_type, $i_terminal ) =
+          terminal_type( \@types_to_go, \@block_type_to_go, $ibeg, $iend );
 
 
-        # TESTING: outdent something like '),'
-        if (
-            $terminal_type eq ','
+        my $is_outdented_line = 0;
 
 
-            # allow just one character before the comma
-            && $i_terminal == $ibeg + 1
+        my $is_semicolon_terminated = $terminal_type eq ';'
+          && $nesting_depth_to_go[$iend] < $nesting_depth_to_go[$ibeg];
 
 
-            # requre LIST environment; otherwise, we may outdent too much --
-            # this can happen in calls without parentheses (overload.t);
-            && $container_environment_to_go[$i_terminal] eq 'LIST'
-          )
-        {
-            $adjust_indentation = 1;
-        }
+        ##########################################################
+        # Section 1: set a flag and a default indentation
+        #
+        # Most lines are indented according to the initial token.
+        # But it is common to outdent to the level just after the
+        # terminal token in certain cases...
+        # adjust_indentation flag:
+        #       0 - do not adjust
+        #       1 - outdent
+        #       2 - vertically align with opening token
+        #       3 - indent
+        ##########################################################
+        my $adjust_indentation         = 0;
+        my $default_adjust_indentation = $adjust_indentation;
+
+        my ( $opening_indentation, $opening_offset );
+
+        # if we are at a closing token of some type..
+        if ( $types_to_go[$ibeg] =~ /^[\)\}\]]$/ ) {
+
+            # get the indentation of the line containing the corresponding
+            # opening token
+            ( $opening_indentation, $opening_offset ) =
+              get_opening_indentation( $ibeg, $ri_first, $ri_last,
+                $rindentation_list );
+
+            # First set the default behavior:
+            # default behavior is to outdent closing lines
+            # of the form:   ");  };  ];  )->xxx;"
+            if (
+                $is_semicolon_terminated
 
 
-        # undo continuation indentation of a terminal closing token if
-        # it is the last token before a level decrease.  This will allow
-        # a closing token to line up with its opening counterpart, and
-        # avoids a indentation jump larger than 1 level.
-        if (   $types_to_go[$i_terminal] =~ /^[\}\]\)R]$/
-            && $i_terminal == $ibeg )
-        {
-            my $ci              = $ci_levels_to_go[$ibeg];
-            my $lev             = $levels_to_go[$ibeg];
-            my $next_type       = $types_to_go[ $ibeg + 1 ];
-            my $i_next_nonblank =
-              ( ( $next_type eq 'b' ) ? $ibeg + 2 : $ibeg + 1 );
-            if (   $i_next_nonblank <= $max_index_to_go
-                && $levels_to_go[$i_next_nonblank] < $lev )
+                # and 'cuddled parens' of the form:   ")->pack("
+                || (
+                       $terminal_type      eq '('
+                    && $types_to_go[$ibeg] eq ')'
+                    && ( $nesting_depth_to_go[$iend] + 1 ==
+                        $nesting_depth_to_go[$ibeg] )
+                )
+              )
             {
                 $adjust_indentation = 1;
             }
             {
                 $adjust_indentation = 1;
             }
-        }
-
-        $default_adjust_indentation = $adjust_indentation;
 
 
-        # Now modify default behavior according to user request:
-        # handle option to indent non-blocks of the form );  };  ];
-        # But don't do special indentation to something like ')->pack('
-        if ( !$block_type_to_go[$ibeg] ) {
-            my $cti = $closing_token_indentation{ $tokens_to_go[$ibeg] };
+            # TESTING: outdent something like '),'
             if (
             if (
-                $cti == 1
-                && (   $i_terminal <= $ibeg + 1
-                    || $is_semicolon_terminated )
+                $terminal_type eq ','
+
+                # allow just one character before the comma
+                && $i_terminal == $ibeg + 1
+
+                # requre LIST environment; otherwise, we may outdent too much --
+                # this can happen in calls without parentheses (overload.t);
+                && $container_environment_to_go[$i_terminal] eq 'LIST'
               )
             {
               )
             {
-                $adjust_indentation = 2;
+                $adjust_indentation = 1;
             }
             }
-            elsif ($cti == 2
-                && $is_semicolon_terminated
-                && $i_terminal == $ibeg + 1 )
+
+            # undo continuation indentation of a terminal closing token if
+            # it is the last token before a level decrease.  This will allow
+            # a closing token to line up with its opening counterpart, and
+            # avoids a indentation jump larger than 1 level.
+            if (   $types_to_go[$i_terminal] =~ /^[\}\]\)R]$/
+                && $i_terminal == $ibeg )
             {
             {
-                $adjust_indentation = 3;
+                my $ci              = $ci_levels_to_go[$ibeg];
+                my $lev             = $levels_to_go[$ibeg];
+                my $next_type       = $types_to_go[ $ibeg + 1 ];
+                my $i_next_nonblank =
+                  ( ( $next_type eq 'b' ) ? $ibeg + 2 : $ibeg + 1 );
+                if (   $i_next_nonblank <= $max_index_to_go
+                    && $levels_to_go[$i_next_nonblank] < $lev )
+                {
+                    $adjust_indentation = 1;
+                }
+            }
+
+            $default_adjust_indentation = $adjust_indentation;
+
+            # Now modify default behavior according to user request:
+            # handle option to indent non-blocks of the form );  };  ];
+            # But don't do special indentation to something like ')->pack('
+            if ( !$block_type_to_go[$ibeg] ) {
+                my $cti = $closing_token_indentation{ $tokens_to_go[$ibeg] };
+                if ( $cti == 1 ) {
+                    if (   $i_terminal <= $ibeg + 1
+                        || $is_semicolon_terminated )
+                    {
+                        $adjust_indentation = 2;
+                    }
+                    else {
+                        $adjust_indentation = 0;
+                    }
+                }
+                elsif ( $cti == 2 ) {
+                    if ($is_semicolon_terminated) {
+                        $adjust_indentation = 3;
+                    }
+                    else {
+                        $adjust_indentation = 0;
+                    }
+                }
+                elsif ( $cti == 3 ) {
+                    $adjust_indentation = 3;
+                }
+            }
+
+            # handle option to indent blocks
+            else {
+                if (
+                    $rOpts->{'indent-closing-brace'}
+                    && (
+                        $i_terminal == $ibeg    #  isolated terminal '}'
+                        || $is_semicolon_terminated
+                    )
+                  )                             #  } xxxx ;
+                {
+                    $adjust_indentation = 3;
+                }
             }
         }
 
             }
         }
 
-        # handle option to indent blocks
-        else {
-            if (
-                $rOpts->{'indent-closing-brace'}
-                && (
-                    $i_terminal == $ibeg    #  isolated terminal '}'
-                    || $is_semicolon_terminated
-                )
-              )                             #  } xxxx ;
-            {
+        # if at ');', '};', '>;', and '];' of a terminal qw quote
+        elsif ($$rpatterns[0] =~ /^qb*;$/
+            && $$rfields[0] =~ /^([\)\}\]\>]);$/ )
+        {
+            if ( $closing_token_indentation{$1} == 0 ) {
+                $adjust_indentation = 1;
+            }
+            else {
                 $adjust_indentation = 3;
             }
         }
                 $adjust_indentation = 3;
             }
         }
-    }
 
 
-    # if at ');', '};', '>;', and '];' of a terminal qw quote
-    elsif ( $$rpatterns[0] =~ /^qb*;$/ && $$rfields[0] =~ /^([\)\}\]\>]);$/ ) {
-        if ( $closing_token_indentation{$1} == 0 ) {
-            $adjust_indentation = 1;
+        ##########################################################
+        # Section 2: set indentation according to flag set above
+        #
+        # Select the indentation object to define leading
+        # whitespace.  If we are outdenting something like '} } );'
+        # then we want to use one level below the last token
+        # ($i_terminal) in order to get it to fully outdent through
+        # all levels.
+        ##########################################################
+        my $indentation;
+        my $lev;
+        my $level_end = $levels_to_go[$iend];
+
+        if ( $adjust_indentation == 0 ) {
+            $indentation = $leading_spaces_to_go[$ibeg];
+            $lev         = $levels_to_go[$ibeg];
         }
         }
-        else {
-            $adjust_indentation = 3;
+        elsif ( $adjust_indentation == 1 ) {
+            $indentation = $reduced_spaces_to_go[$i_terminal];
+            $lev         = $levels_to_go[$i_terminal];
         }
         }
-    }
-
-    # Handle variation in indentation styles...
-    # Select the indentation object to define leading
-    # whitespace.  If we are outdenting something like '} } );'
-    # then we want to use one level below the last token
-    # ($i_terminal) in order to get it to fully outdent through
-    # all levels.
-    my $indentation;
-    my $lev;
-    my $level_end = $levels_to_go[$iend];
-
-    if ( $adjust_indentation == 0 ) {
-        $indentation = $leading_spaces_to_go[$ibeg];
-        $lev         = $levels_to_go[$ibeg];
-    }
-    elsif ( $adjust_indentation == 1 ) {
-        $indentation = $reduced_spaces_to_go[$i_terminal];
-        $lev         = $levels_to_go[$i_terminal];
-    }
 
 
-    # handle indented closing token which aligns with opening token
-    elsif ( $adjust_indentation == 2 ) {
+        # handle indented closing token which aligns with opening token
+        elsif ( $adjust_indentation == 2 ) {
 
 
-        # handle option to align closing token with opening token
-        $lev = $levels_to_go[$ibeg];
+            # handle option to align closing token with opening token
+            $lev = $levels_to_go[$ibeg];
 
 
-        # calculate spaces needed to align with opening token
-        my $space_count = get_SPACES($opening_indentation) + $opening_offset;
+            # calculate spaces needed to align with opening token
+            my $space_count =
+              get_SPACES($opening_indentation) + $opening_offset;
 
 
-        # Indent less than the previous line.
-        #
-        # Problem: For -lp we don't exactly know what it was if there were
-        # recoverable spaces sent to the aligner.  A good solution would be to
-        # force a flush of the vertical alignment buffer, so that we would
-        # know.  For now, this rule is used for -lp:
-        #
-        # When the last line did not start with a closing token we will be
-        # optimistic that the aligner will recover everything wanted.
-        #
-        # This rule will prevent us from breaking a hierarchy of closing
-        # tokens, and in a worst case will leave a closing paren too far
-        # indented, but this is better than frequently leaving it not indented
-        # enough.
-        my $last_spaces = get_SPACES($last_indentation_written);
-        if ( $last_leading_token !~ /^[\}\]\)]$/ ) {
-            $last_spaces += get_RECOVERABLE_SPACES($last_indentation_written);
-        }
-
-        # reset the indentation to the new space count if it works
-        # only options are all or none: nothing in-between looks good
-        $lev = $levels_to_go[$ibeg];
-        if ( $space_count < $last_spaces ) {
-            if ($rOpts_line_up_parentheses) {
-                my $lev = $levels_to_go[$ibeg];
-                $indentation =
-                  new_lp_indentation_item( $space_count, $lev, 0, 0, 0 );
+            # Indent less than the previous line.
+            #
+            # Problem: For -lp we don't exactly know what it was if there
+            # were recoverable spaces sent to the aligner.  A good solution
+            # would be to force a flush of the vertical alignment buffer, so
+            # that we would know.  For now, this rule is used for -lp:
+            #
+            # When the last line did not start with a closing token we will
+            # be optimistic that the aligner will recover everything wanted.
+            #
+            # This rule will prevent us from breaking a hierarchy of closing
+            # tokens, and in a worst case will leave a closing paren too far
+            # indented, but this is better than frequently leaving it not
+            # indented enough.
+            my $last_spaces = get_SPACES($last_indentation_written);
+            if ( $last_leading_token !~ /^[\}\]\)]$/ ) {
+                $last_spaces +=
+                  get_RECOVERABLE_SPACES($last_indentation_written);
+            }
+
+            # reset the indentation to the new space count if it works
+            # only options are all or none: nothing in-between looks good
+            $lev = $levels_to_go[$ibeg];
+            if ( $space_count < $last_spaces ) {
+                if ($rOpts_line_up_parentheses) {
+                    my $lev = $levels_to_go[$ibeg];
+                    $indentation =
+                      new_lp_indentation_item( $space_count, $lev, 0, 0, 0 );
+                }
+                else {
+                    $indentation = $space_count;
+                }
             }
             }
+
+            # revert to default if it doesnt work
             else {
             else {
-                $indentation = $space_count;
+                $space_count = leading_spaces_to_go($ibeg);
+                if ( $default_adjust_indentation == 0 ) {
+                    $indentation = $leading_spaces_to_go[$ibeg];
+                }
+                elsif ( $default_adjust_indentation == 1 ) {
+                    $indentation = $reduced_spaces_to_go[$i_terminal];
+                    $lev         = $levels_to_go[$i_terminal];
+                }
             }
         }
 
             }
         }
 
-        # revert to default if it doesnt work
+        # Full indentaion of closing tokens (-icb and -icp or -cti=2)
         else {
         else {
-            $space_count = leading_spaces_to_go($ibeg);
-            if ( $default_adjust_indentation == 0 ) {
-                $indentation = $leading_spaces_to_go[$ibeg];
-            }
-            elsif ( $default_adjust_indentation == 1 ) {
-                $indentation = $reduced_spaces_to_go[$i_terminal];
-                $lev         = $levels_to_go[$i_terminal];
+
+            # handle -icb (indented closing code block braces)
+            # Updated method for indented block braces: indent one full level if
+            # there is no continuation indentation.  This will occur for major
+            # structures such as sub, if, else, but not for things like map
+            # blocks.
+            #
+            # Note: only code blocks without continuation indentation are
+            # handled here (if, else, unless, ..). In the following snippet,
+            # the terminal brace of the sort block will have continuation
+            # indentation as shown so it will not be handled by the coding
+            # here.  We would have to undo the continuation indentation to do
+            # this, but it probably looks ok as is.  This is a possible future
+            # update for semicolon terminated lines.
+            #
+            #     if ($sortby eq 'date' or $sortby eq 'size') {
+            #         @files = sort {
+            #             $file_data{$a}{$sortby} <=> $file_data{$b}{$sortby}
+            #                 or $a cmp $b
+            #                 } @files;
+            #         }
+            #
+            if (   $block_type_to_go[$ibeg]
+                && $ci_levels_to_go[$i_terminal] == 0 )
+            {
+                my $spaces = get_SPACES( $leading_spaces_to_go[$i_terminal] );
+                $indentation = $spaces + $rOpts_indent_columns;
+
+                # NOTE: for -lp we could create a new indentation object, but
+                # there is probably no need to do it
             }
             }
-        }
-    }
 
 
-    # Full indentaion of closing tokens (-icb and -icp or -cti=2)
-    else {
+            # handle -icp and any -icb block braces which fall through above
+            # test such as the 'sort' block mentioned above.
+            else {
 
 
-        # There are two ways to handle -icb and -icp...
-        # One way is to use the indentation of the previous line:
-        # $indentation = $last_indentation_written;
+                # There are currently two ways to handle -icp...
+                # One way is to use the indentation of the previous line:
+                # $indentation = $last_indentation_written;
 
 
-        # The other way is to use the indentation that the previous line
-        # would have had if it hadn't been adjusted:
-        $indentation = $last_unadjusted_indentation;
+                # The other way is to use the indentation that the previous line
+                # would have had if it hadn't been adjusted:
+                $indentation = $last_unadjusted_indentation;
 
 
-        # Current method: use the minimum of the two. This avoids inconsistent
-        # indentation.
-        if ( get_SPACES($last_indentation_written) < get_SPACES($indentation) )
-        {
-            $indentation = $last_indentation_written;
+                # Current method: use the minimum of the two. This avoids
+                # inconsistent indentation.
+                if ( get_SPACES($last_indentation_written) <
+                    get_SPACES($indentation) )
+                {
+                    $indentation = $last_indentation_written;
+                }
+            }
+
+            # use previous indentation but use own level
+            # to cause list to be flushed properly
+            $lev = $levels_to_go[$ibeg];
         }
 
         }
 
-        # use previous indentation but use own level
-        # to cause list to be flushed properly
-        $lev = $levels_to_go[$ibeg];
-    }
+        # remember indentation except for multi-line quotes, which get
+        # no indentation
+        unless ( $ibeg == 0 && $starting_in_quote ) {
+            $last_indentation_written    = $indentation;
+            $last_unadjusted_indentation = $leading_spaces_to_go[$ibeg];
+            $last_leading_token          = $tokens_to_go[$ibeg];
+        }
 
 
-    # remember indentation except for multi-line quotes, which get
-    # no indentation
-    unless ( $types_to_go[$ibeg] eq 'Q' && $lev == 0 ) {
-        $last_indentation_written    = $indentation;
-        $last_unadjusted_indentation = $leading_spaces_to_go[$ibeg];
-        $last_leading_token          = $tokens_to_go[$ibeg];
-    }
+        # be sure lines with leading closing tokens are not outdented more
+        # than the line which contained the corresponding opening token.
 
 
-    # be sure lines with leading closing tokens are not outdented more
-    # than the line which contained the corresponding opening token.
-    my $is_isolated_block_brace =
-      ( $iend == $ibeg ) && $block_type_to_go[$ibeg];
-    if ( !$is_isolated_block_brace && defined($opening_indentation) ) {
-        if ( get_SPACES($opening_indentation) > get_SPACES($indentation) ) {
-            $indentation = $opening_indentation;
+        #############################################################
+        # updated per bug report in alex_bug.pl: we must not
+        # mess with the indentation of closing logical braces so
+        # we must treat something like '} else {' as if it were
+        # an isolated brace my $is_isolated_block_brace = (
+        # $iend == $ibeg ) && $block_type_to_go[$ibeg];
+        my $is_isolated_block_brace = $block_type_to_go[$ibeg]
+          && ( $iend == $ibeg
+            || $is_if_elsif_else_unless_while_until_for_foreach{
+                $block_type_to_go[$ibeg] } );
+        #############################################################
+        if ( !$is_isolated_block_brace && defined($opening_indentation) ) {
+            if ( get_SPACES($opening_indentation) > get_SPACES($indentation) ) {
+                $indentation = $opening_indentation;
+            }
         }
         }
-    }
 
 
-    # remember the indentation of each line of this batch
-    push @{$rindentation_list}, $indentation;
+        # remember the indentation of each line of this batch
+        push @{$rindentation_list}, $indentation;
 
 
-    # outdent lines with certain leading tokens...
-    if (
+        # outdent lines with certain leading tokens...
+        if (
 
 
-        # must be first word of this batch
-        $ibeg == 0
+            # must be first word of this batch
+            $ibeg == 0
 
 
-        # and ...
-        && (
+            # and ...
+            && (
 
 
-            # certain leading keywords if requested
-            (
-                   $rOpts->{'outdent-keywords'}
-                && $types_to_go[$ibeg] eq 'k'
-                && $outdent_keyword{ $tokens_to_go[$ibeg] }
-            )
+                # certain leading keywords if requested
+                (
+                       $rOpts->{'outdent-keywords'}
+                    && $types_to_go[$ibeg] eq 'k'
+                    && $outdent_keyword{ $tokens_to_go[$ibeg] }
+                )
 
 
-            # or labels if requested
-            || ( $rOpts->{'outdent-labels'} && $types_to_go[$ibeg] eq 'J' )
+                # or labels if requested
+                || ( $rOpts->{'outdent-labels'} && $types_to_go[$ibeg] eq 'J' )
 
 
-            # or static block comments if requested
-            || (   $types_to_go[$ibeg] eq '#'
-                && $rOpts->{'outdent-static-block-comments'}
-                && $tokens_to_go[$ibeg] =~ /$static_block_comment_pattern/o
-                && $rOpts->{'static-block-comments'} )
-        )
-      )
+                # or static block comments if requested
+                || (   $types_to_go[$ibeg] eq '#'
+                    && $rOpts->{'outdent-static-block-comments'}
+                    && $is_static_block_comment )
+            )
+          )
 
 
-    {
-        my $space_count = leading_spaces_to_go($ibeg);
-        if ( $space_count > 0 ) {
-            $space_count -= $rOpts_continuation_indentation;
-            $is_outdented_line = 1;
-            if ( $space_count < 0 ) { $space_count = 0 }
+        {
+            my $space_count = leading_spaces_to_go($ibeg);
+            if ( $space_count > 0 ) {
+                $space_count -= $rOpts_continuation_indentation;
+                $is_outdented_line = 1;
+                if ( $space_count < 0 ) { $space_count = 0 }
 
 
-            # do not promote a spaced static block comment to non-spaced;
-            # this is not normally necessary but could be for some
-            # unusual user inputs (such as -ci = -i)
-            if ( $types_to_go[$ibeg] eq '#' && $space_count == 0 ) {
-                $space_count = 1;
-            }
+                # do not promote a spaced static block comment to non-spaced;
+                # this is not normally necessary but could be for some
+                # unusual user inputs (such as -ci = -i)
+                if ( $types_to_go[$ibeg] eq '#' && $space_count == 0 ) {
+                    $space_count = 1;
+                }
 
 
-            if ($rOpts_line_up_parentheses) {
-                $indentation =
-                  new_lp_indentation_item( $space_count, $lev, 0, 0, 0 );
-            }
-            else {
-                $indentation = $space_count;
+                if ($rOpts_line_up_parentheses) {
+                    $indentation =
+                      new_lp_indentation_item( $space_count, $lev, 0, 0, 0 );
+                }
+                else {
+                    $indentation = $space_count;
+                }
             }
         }
             }
         }
-    }
 
 
-    return ( $indentation, $lev, $level_end, $is_semicolon_terminated,
-        $is_outdented_line );
+        return ( $indentation, $lev, $level_end, $is_semicolon_terminated,
+            $is_outdented_line );
+    }
 }
 
 sub set_vertical_tightness_flags {
 }
 
 sub set_vertical_tightness_flags {
@@ -11015,6 +11555,99 @@ sub set_vertical_tightness_flags {
                 }
             }
         }
                 }
             }
         }
+
+        # Opening Token Right
+        # If requested, move an isolated trailing opening token to the end of
+        # the previous line which ended in a comma.  We could do this
+        # in sub recombine_breakpoints but that would cause problems
+        # with -lp formatting.  The problem is that indentation will
+        # quickly move far to the right in nested expressions.  By
+        # doing it after indentation has been set, we avoid changes
+        # to the indentation.  Actual movement of the token takes place
+        # in sub write_leader_and_string.
+        if (
+            $opening_token_right{ $tokens_to_go[$ibeg_next] }
+
+            # previous line is not opening
+            # (use -sot to combine with it)
+            && !$is_opening_token{$token_end}
+
+            # previous line ended in one of these
+            # (add other cases if necessary; '=>' and '.' are not necessary
+            ##&& ($is_opening_token{$token_end} || $token_end eq ',')
+            && !$block_type_to_go[$ibeg_next]
+
+            # this is a line with just an opening token
+            && (   $iend_next == $ibeg_next
+                || $iend_next == $ibeg_next + 1
+                && $types_to_go[$iend_next] eq '#' )
+
+            # looks bad if we align vertically with the wrong container
+            && $tokens_to_go[$ibeg] ne $tokens_to_go[$ibeg_next]
+          )
+        {
+            my $valid_flag = 1;
+            my $spaces = ( $types_to_go[ $ibeg_next - 1 ] eq 'b' ) ? 1 : 0;
+            @{$rvertical_tightness_flags} =
+              ( 2, $spaces, $type_sequence_to_go[$ibeg_next], $valid_flag, );
+        }
+
+        # Stacking of opening and closing tokens
+        my $stackable;
+        my $token_beg_next = $tokens_to_go[$ibeg_next];
+
+        # patch to make something like 'qw(' behave like an opening paren
+        # (aran.t)
+        if ( $types_to_go[$ibeg_next] eq 'q' ) {
+            if ( $token_beg_next =~ /^q.([\[\(\{])$/ ) {
+                $token_beg_next = $1;
+            }
+        }
+
+        if (   $is_closing_token{$token_end}
+            && $is_closing_token{$token_beg_next} )
+        {
+            $stackable = $stack_closing_token{$token_beg_next}
+              unless ( $block_type_to_go[$ibeg_next] )
+              ;    # shouldn't happen; just checking
+        }
+        elsif ($is_opening_token{$token_end}
+            && $is_opening_token{$token_beg_next} )
+        {
+            $stackable = $stack_opening_token{$token_beg_next}
+              unless ( $block_type_to_go[$ibeg_next] )
+              ;    # shouldn't happen; just checking
+        }
+
+        if ($stackable) {
+
+            my $is_semicolon_terminated;
+            if ( $n + 1 == $n_last_line ) {
+                my ( $terminal_type, $i_terminal ) = terminal_type(
+                    \@types_to_go, \@block_type_to_go,
+                    $ibeg_next,    $iend_next
+                );
+                $is_semicolon_terminated = $terminal_type eq ';'
+                  && $nesting_depth_to_go[$iend_next] <
+                  $nesting_depth_to_go[$ibeg_next];
+            }
+
+            # this must be a line with just an opening token
+            # or end in a semicolon
+            if (
+                $is_semicolon_terminated
+                || (   $iend_next == $ibeg_next
+                    || $iend_next == $ibeg_next + 1
+                    && $types_to_go[$iend_next] eq '#' )
+              )
+            {
+                my $valid_flag = 1;
+                my $spaces = ( $types_to_go[ $ibeg_next - 1 ] eq 'b' ) ? 1 : 0;
+                @{$rvertical_tightness_flags} =
+                  ( 2, $spaces, $type_sequence_to_go[$ibeg_next], $valid_flag,
+                  );
+            }
+        }
     }
 
     # Check for a last line with isolated opening BLOCK curly
     }
 
     # Check for a last line with isolated opening BLOCK curly
@@ -11038,12 +11671,12 @@ sub set_vertical_tightness_flags {
     BEGIN {
 
         @_ = qw#
     BEGIN {
 
         @_ = qw#
-          = **= += *= &= <<= &&= -= /= |= >>= ||= .= %= ^= x=
-          { ? : => =~ && ||
+          = **= += *= &= <<= &&= -= /= |= >>= ||= //= .= %= ^= x=
+          { ? : => =~ && || //
           #;
         @is_vertical_alignment_type{@_} = (1) x scalar(@_);
 
           #;
         @is_vertical_alignment_type{@_} = (1) x scalar(@_);
 
-        @_ = qw(if unless and or eq ne for foreach while until);
+        @_ = qw(if unless and or err eq ne for foreach while until);
         @is_vertical_alignment_keyword{@_} = (1) x scalar(@_);
     }
 
         @is_vertical_alignment_keyword{@_} = (1) x scalar(@_);
     }
 
@@ -11375,7 +12008,7 @@ sub terminal_type {
             # it is very good to break AFTER various assignment operators
             @_ = qw(
               = **= += *= &= <<= &&=
             # it is very good to break AFTER various assignment operators
             @_ = qw(
               = **= += *= &= <<= &&=
-              -= /= |= >>= ||=
+              -= /= |= >>= ||= //=
               .= %= ^=
               x=
             );
               .= %= ^=
               x=
             );
@@ -11383,12 +12016,16 @@ sub terminal_type {
             @right_bond_strength{@_} =
               ( 0.4 * WEAK + 0.6 * VERY_WEAK ) x scalar(@_);
 
             @right_bond_strength{@_} =
               ( 0.4 * WEAK + 0.6 * VERY_WEAK ) x scalar(@_);
 
-            # break BEFORE '&&' and '||'
+            # break BEFORE '&&' and '||' and '//'
             # set strength of '||' to same as '=' so that chains like
             # $a = $b || $c || $d   will break before the first '||'
             $right_bond_strength{'||'} = NOMINAL;
             $left_bond_strength{'||'}  = $right_bond_strength{'='};
 
             # set strength of '||' to same as '=' so that chains like
             # $a = $b || $c || $d   will break before the first '||'
             $right_bond_strength{'||'} = NOMINAL;
             $left_bond_strength{'||'}  = $right_bond_strength{'='};
 
+            # same thing for '//'
+            $right_bond_strength{'//'} = NOMINAL;
+            $left_bond_strength{'//'}  = $right_bond_strength{'='};
+
             # set strength of && a little higher than ||
             $right_bond_strength{'&&'} = NOMINAL;
             $left_bond_strength{'&&'}  = $left_bond_strength{'||'} + 0.1;
             # set strength of && a little higher than ||
             $right_bond_strength{'&&'} = NOMINAL;
             $left_bond_strength{'&&'}  = $left_bond_strength{'||'} + 0.1;
@@ -11417,12 +12054,14 @@ sub terminal_type {
             $right_bond_strength{','} = VERY_WEAK;
 
             # Set bond strengths of certain keywords
             $right_bond_strength{','} = VERY_WEAK;
 
             # Set bond strengths of certain keywords
-            # make 'or', 'and' slightly weaker than a ','
+            # make 'or', 'err', 'and' slightly weaker than a ','
             $left_bond_strength{'and'}  = VERY_WEAK - 0.01;
             $left_bond_strength{'or'}   = VERY_WEAK - 0.02;
             $left_bond_strength{'and'}  = VERY_WEAK - 0.01;
             $left_bond_strength{'or'}   = VERY_WEAK - 0.02;
+            $left_bond_strength{'err'}  = VERY_WEAK - 0.02;
             $left_bond_strength{'xor'}  = NOMINAL;
             $right_bond_strength{'and'} = NOMINAL;
             $right_bond_strength{'or'}  = NOMINAL;
             $left_bond_strength{'xor'}  = NOMINAL;
             $right_bond_strength{'and'} = NOMINAL;
             $right_bond_strength{'or'}  = NOMINAL;
+            $right_bond_strength{'err'} = NOMINAL;
             $right_bond_strength{'xor'} = STRONG;
         }
 
             $right_bond_strength{'xor'} = STRONG;
         }
 
@@ -11656,7 +12295,7 @@ sub terminal_type {
                     $bond_str += $and_bias;
                     $and_bias += $delta_bias;
                 }
                     $bond_str += $and_bias;
                     $and_bias += $delta_bias;
                 }
-                elsif ($next_nonblank_token eq 'or'
+                elsif ($next_nonblank_token =~ /^(or|err)$/
                     && $want_break_before{$next_nonblank_token} )
                 {
                     $bond_str += $or_bias;
                     && $want_break_before{$next_nonblank_token} )
                 {
                     $bond_str += $or_bias;
@@ -11667,6 +12306,12 @@ sub terminal_type {
                 elsif ( $is_keyword_returning_list{$next_nonblank_token} ) {
                     $bond_str = $list_str if ( $bond_str > $list_str );
                 }
                 elsif ( $is_keyword_returning_list{$next_nonblank_token} ) {
                     $bond_str = $list_str if ( $bond_str > $list_str );
                 }
+                elsif ( $token eq 'err'
+                    && !$want_break_before{$token} )
+                {
+                    $bond_str += $or_bias;
+                    $or_bias  += $delta_bias;
+                }
             }
 
             if ( $type eq ':'
             }
 
             if ( $type eq ':'
@@ -11847,18 +12492,18 @@ sub terminal_type {
                     ##if ( $next_next_type ne '=>' ) {
                     # these are ok: '->xxx', '=>', '('
 
                     ##if ( $next_next_type ne '=>' ) {
                     # these are ok: '->xxx', '=>', '('
 
-                  # We'll check for an old breakpoint and keep a leading
-                  # bareword if it was that way in the input file.  Presumably
-                  # it was ok that way.  For example, the following would remain
-                  # unchanged:
-                  #
-                  # @months = (
-                  #   January,   February, March,    April,
-                  #   May,       June,     July,     August,
-                  #   September, October,  November, December,
-                  # );
-                  #
-                  # This should be sufficient:
+                    # We'll check for an old breakpoint and keep a leading
+                    # bareword if it was that way in the input file.
+                    # Presumably it was ok that way.  For example, the
+                    # following would remain unchanged:
+                    #
+                    # @months = (
+                    #   January,   February, March,    April,
+                    #   May,       June,     July,     August,
+                    #   September, October,  November, December,
+                    # );
+                    #
+                    # This should be sufficient:
                     if ( !$old_breakpoint_to_go[$i]
                         && ( $next_next_type eq ',' || $next_next_type eq '}' )
                       )
                     if ( !$old_breakpoint_to_go[$i]
                         && ( $next_next_type eq ',' || $next_next_type eq '}' )
                       )
@@ -11880,9 +12525,10 @@ sub terminal_type {
                 }
             }
 
                 }
             }
 
-          # in fact, use strict hates bare words on any new line.  For example,
-          # a break before the underscore here provokes the wrath of use strict:
-          #    if ( -r $fn && ( -s _ || $AllowZeroFilesize)) {
+            # in fact, use strict hates bare words on any new line.  For
+            # example, a break before the underscore here provokes the
+            # wrath of use strict:
+            # if ( -r $fn && ( -s _ || $AllowZeroFilesize)) {
             elsif ( $type eq 'F' ) {
                 $bond_str = NO_BREAK;
             }
             elsif ( $type eq 'F' ) {
                 $bond_str = NO_BREAK;
             }
@@ -11896,8 +12542,9 @@ sub terminal_type {
                 }
             }
 
                 }
             }
 
-        # Do not break between a possible filehandle and a ? or /
-        # and do not introduce a break after it if there is no blank (extrude.t)
+            # Do not break between a possible filehandle and a ? or / and do
+            # not introduce a break after it if there is no blank
+            # (extrude.t)
             elsif ( $type eq 'Z' ) {
 
                 # dont break..
             elsif ( $type eq 'Z' ) {
 
                 # dont break..
@@ -12142,7 +12789,7 @@ sub pad_array_to_go {
     my %is_logical_container;
 
     BEGIN {
     my %is_logical_container;
 
     BEGIN {
-        @_ = qw# if elsif unless while and or not && | || ? : ! #;
+        @_ = qw# if elsif unless while and or err not && | || ? : ! #;
         @is_logical_container{@_} = (1) x scalar(@_);
     }
 
         @is_logical_container{@_} = (1) x scalar(@_);
     }
 
@@ -13078,8 +13725,7 @@ sub find_token_starting_list {
             $item_count,          $identifier_count, $rcomma_index,
             $next_nonblank_type,  $list_type,        $interrupted,
             $rdo_not_break_apart, $must_break_open,
             $item_count,          $identifier_count, $rcomma_index,
             $next_nonblank_type,  $list_type,        $interrupted,
             $rdo_not_break_apart, $must_break_open,
-          )
-          = @_;
+        ) = @_;
 
         # nothing to do if no commas seen
         return if ( $item_count < 1 );
 
         # nothing to do if no commas seen
         return if ( $item_count < 1 );
@@ -14172,7 +14818,8 @@ sub recombine_breakpoints {
     my ( $ri_first, $ri_last ) = @_;
     my $more_to_do = 1;
 
     my ( $ri_first, $ri_last ) = @_;
     my $more_to_do = 1;
 
-    # Keep looping until there are no more possible recombinations
+    # We keep looping over all of the lines of this batch
+    # until there are no more possible recombinations
     my $nmax_last = @$ri_last;
     while ($more_to_do) {
         my $n_best = 0;
     my $nmax_last = @$ri_last;
     while ($more_to_do) {
         my $n_best = 0;
@@ -14180,7 +14827,7 @@ sub recombine_breakpoints {
         my $n;
         my $nmax = @$ri_last - 1;
 
         my $n;
         my $nmax = @$ri_last - 1;
 
-        # safety check..
+        # safety check for infinite loop
         unless ( $nmax < $nmax_last ) {
 
             # shouldn't happen because splice below decreases nmax on each pass:
         unless ( $nmax < $nmax_last ) {
 
             # shouldn't happen because splice below decreases nmax on each pass:
@@ -14189,47 +14836,116 @@ sub recombine_breakpoints {
         }
         $nmax_last  = $nmax;
         $more_to_do = 0;
         }
         $nmax_last  = $nmax;
         $more_to_do = 0;
+        my $previous_outdentable_closing_paren;
+        my $leading_amp_count = 0;
+        my $this_line_is_semicolon_terminated;
 
 
-        # loop over all remaining lines...
+        # loop over all remaining lines in this batch
         for $n ( 1 .. $nmax ) {
 
             #----------------------------------------------------------
         for $n ( 1 .. $nmax ) {
 
             #----------------------------------------------------------
-            # Indexes of the endpoints of the two lines are:
+            # If we join the current pair of lines,
+            # line $n-1 will become the left part of the joined line
+            # line $n will become the right part of the joined line
+            #
+            # Here are Indexes of the endpoint tokens of the two lines:
             #
             #  ---left---- | ---right---
             #  $if   $imid | $imidr   $il
             #
             # We want to decide if we should join tokens $imid to $imidr
             #
             #  ---left---- | ---right---
             #  $if   $imid | $imidr   $il
             #
             # We want to decide if we should join tokens $imid to $imidr
+            #
+            # We will apply a number of ad-hoc tests to see if joining
+            # here will look ok.  The code will just issue a 'next'
+            # command if the join doesn't look good.  If we get through
+            # the gauntlet of tests, the lines will be recombined.
             #----------------------------------------------------------
             my $if    = $$ri_first[ $n - 1 ];
             my $il    = $$ri_last[$n];
             my $imid  = $$ri_last[ $n - 1 ];
             my $imidr = $$ri_first[$n];
 
             #----------------------------------------------------------
             my $if    = $$ri_first[ $n - 1 ];
             my $il    = $$ri_last[$n];
             my $imid  = $$ri_last[ $n - 1 ];
             my $imidr = $$ri_first[$n];
 
-#print "RECOMBINE: n=$n imid=$imid if=$if type=$types_to_go[$if] =$tokens_to_go[$if] next_type=$types_to_go[$imidr] next_tok=$tokens_to_go[$imidr]\n";
+            #my $depth_increase=( $nesting_depth_to_go[$imidr] -
+            #        $nesting_depth_to_go[$if] );
 
 
-            #----------------------------------------------------------
-            # Start of special recombination rules
-            # These are ad-hoc rules which have been found to work ok.
-            # Skip to next pair to avoid re-combination.
-            #----------------------------------------------------------
+##print "RECOMBINE: n=$n imid=$imid if=$if type=$types_to_go[$if] =$tokens_to_go[$if] next_type=$types_to_go[$imidr] next_tok=$tokens_to_go[$imidr]\n";
+
+            # If line $n is the last line, we set some flags and
+            # do any special checks for it
+            if ( $n == $nmax ) {
+
+                # a terminal '{' should stay where it is
+                next if $types_to_go[$imidr] eq '{';
+
+                # set flag if statement $n ends in ';'
+                $this_line_is_semicolon_terminated = $types_to_go[$il] eq ';'
 
 
-            # a terminal '{' should stay where it is
-            next if ( $n == $nmax && $types_to_go[$imidr] eq '{' );
+                  # with possible side comment
+                  || ( $types_to_go[$il] eq '#'
+                    && $il - $imidr >= 2
+                    && $types_to_go[ $il - 2 ] eq ';'
+                    && $types_to_go[ $il - 1 ] eq 'b' );
+            }
 
             #----------------------------------------------------------
 
             #----------------------------------------------------------
-            # examine token at $imid  (right end of first line of pair)
+            # Section 1: examine token at $imid (right end of first line
+            # of pair)
             #----------------------------------------------------------
 
             # an isolated '}' may join with a ';' terminated segment
             if ( $types_to_go[$imid] eq '}' ) {
             #----------------------------------------------------------
 
             # an isolated '}' may join with a ';' terminated segment
             if ( $types_to_go[$imid] eq '}' ) {
+
+                # Check for cases where combining a semicolon terminated
+                # statement with a previous isolated closing paren will
+                # allow the combined line to be outdented.  This is
+                # generally a good move.  For example, we can join up
+                # the last two lines here:
+                #  (
+                #      $dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
+                #      $size, $atime, $mtime, $ctime, $blksize, $blocks
+                #    )
+                #    = stat($file);
+                #
+                # to get:
+                #  (
+                #      $dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
+                #      $size, $atime, $mtime, $ctime, $blksize, $blocks
+                #  ) = stat($file);
+                #
+                # which makes the parens line up.
+                #
+                # Another example, from Joe Matarazzo, probably looks best
+                # with the 'or' clause appended to the trailing paren:
+                #  $self->some_method(
+                #      PARAM1 => 'foo',
+                #      PARAM2 => 'bar'
+                #  ) or die "Some_method didn't work";
+                #
+                $previous_outdentable_closing_paren =
+                  $this_line_is_semicolon_terminated    # ends in ';'
+                  && $if == $imid    # only one token on last line
+                  && $tokens_to_go[$imid] eq ')'    # must be structural paren
+
+                  # only &&, ||, and : if no others seen
+                  # (but note: our count made below could be wrong
+                  # due to intervening comments)
+                  && ( $leading_amp_count == 0
+                    || $types_to_go[$imidr] !~ /^(:|\&\&|\|\|)$/ )
+
+                  # but leading colons probably line up with with a
+                  # previous colon or question (count could be wrong).
+                  && $types_to_go[$imidr] ne ':'
+
+                  # only one step in depth allowed.  this line must not
+                  # begin with a ')' itself.
+                  && ( $nesting_depth_to_go[$imid] ==
+                    $nesting_depth_to_go[$il] + 1 );
+
                 next
                   unless (
                 next
                   unless (
+                    $previous_outdentable_closing_paren
 
 
-                    # join } and ;
-                    ( ( $if == $imid ) && ( $types_to_go[$il] eq ';' ) )
-
-                    # handle '.' and '?' below
+                    # handle '.' and '?' specially below
                     || ( $types_to_go[$imidr] =~ /^[\.\?]$/ )
                   );
             }
                     || ( $types_to_go[$imidr] =~ /^[\.\?]$/ )
                   );
             }
@@ -14250,7 +14966,7 @@ sub recombine_breakpoints {
                     next
                       unless ( ( $if == ( $imid - 1 ) )
                         && ( $il == ( $imidr + 1 ) )
                     next
                       unless ( ( $if == ( $imid - 1 ) )
                         && ( $il == ( $imidr + 1 ) )
-                        && ( $types_to_go[$il] eq ';' ) );
+                        && $this_line_is_semicolon_terminated );
 
                     # override breakpoint
                     $forced_breakpoint_to_go[$imid] = 0;
 
                     # override breakpoint
                     $forced_breakpoint_to_go[$imid] = 0;
@@ -14341,11 +15057,19 @@ sub recombine_breakpoints {
             }
 
             #----------------------------------------------------------
             }
 
             #----------------------------------------------------------
-            # examine token at $imidr (left end of second line of pair)
+            # Section 2: Now examine token at $imidr (left end of second
+            # line of pair)
             #----------------------------------------------------------
 
             #----------------------------------------------------------
 
+            # join lines identified above as capable of
+            # causing an outdented line with leading closing paren
+            if ($previous_outdentable_closing_paren) {
+                $forced_breakpoint_to_go[$imid] = 0;
+            }
+
             # do not recombine lines with leading &&, ||, or :
             # do not recombine lines with leading &&, ||, or :
-            if ( $types_to_go[$imidr] =~ /^(|:|\&\&|\|\|)$/ ) {
+            elsif ( $types_to_go[$imidr] =~ /^(:|\&\&|\|\|)$/ ) {
+                $leading_amp_count++;
                 next if $want_break_before{ $types_to_go[$imidr] };
             }
 
                 next if $want_break_before{ $types_to_go[$imidr] };
             }
 
@@ -14399,15 +15123,16 @@ sub recombine_breakpoints {
                 next
                   unless (
 
                 next
                   unless (
 
-     #      ... unless there is just one and we can reduce this to
-     #      two lines if we do.  For example, this :
-     #
-     #                $bodyA .=
-     #                  '($dummy, $pat) = &get_next_tex_cmd;' . '$args .= $pat;'
-     #
-     #      looks better than this:
-     #                $bodyA .= '($dummy, $pat) = &get_next_tex_cmd;'
-     #                   . '$args .= $pat;'
+                   # ... unless there is just one and we can reduce
+                   # this to two lines if we do.  For example, this
+                   #
+                   #
+                   #  $bodyA .=
+                   #    '($dummy, $pat) = &get_next_tex_cmd;' . '$args .= $pat;'
+                   #
+                   #  looks better than this:
+                   #  $bodyA .= '($dummy, $pat) = &get_next_tex_cmd;'
+                   #    . '$args .= $pat;'
 
                     (
                            $n == 2
 
                     (
                            $n == 2
@@ -14415,11 +15140,9 @@ sub recombine_breakpoints {
                         && $types_to_go[$if] ne $types_to_go[$imidr]
                     )
 
                         && $types_to_go[$if] ne $types_to_go[$imidr]
                     )
 
-                    #
                     #      ... or this would strand a short quote , like this
                     #                . "some long qoute"
                     #                . "\n";
                     #      ... or this would strand a short quote , like this
                     #                . "some long qoute"
                     #                . "\n";
-                    #
 
                     || (   $types_to_go[$i_next_nonblank] eq 'Q'
                         && $i_next_nonblank >= $il - 1
 
                     || (   $types_to_go[$i_next_nonblank] eq 'Q'
                         && $i_next_nonblank >= $il - 1
@@ -14438,37 +15161,38 @@ sub recombine_breakpoints {
                     # 'or' after an 'if' or 'unless'.  We should consider the
                     # possible vertical alignment, and visual clutter.
 
                     # 'or' after an 'if' or 'unless'.  We should consider the
                     # possible vertical alignment, and visual clutter.
 
-  #     This looks best with the 'and' on the same line as the 'if':
-  #
-  #         $a = 1
-  #           if $seconds and $nu < 2;
-  #
-  #     But this looks better as shown:
-  #
-  #         $a = 1
-  #           if !$this->{Parents}{$_}
-  #           or $this->{Parents}{$_} eq $_;
-  #
-  #     Eventually, it would be nice to look for similarities (such as 'this' or
-  #     'Parents'), but for now I'm using a simple rule that says that the
-  #     resulting line length must not be more than half the maximum line length
-  #     (making it 80/2 = 40 characters by default).
-
+                    #     This looks best with the 'and' on the same
+                    #     line as the 'if':
+                    #
+                    #         $a = 1
+                    #           if $seconds and $nu < 2;
+                    #
+                    #     But this looks better as shown:
+                    #
+                    #         $a = 1
+                    #           if !$this->{Parents}{$_}
+                    #           or $this->{Parents}{$_} eq $_;
+                    #
+                    #     Eventually, it would be nice to look for
+                    #     similarities (such as 'this' or 'Parents'), but
+                    #     for now I'm using a simple rule that says that
+                    #     the resulting line length must not be more than
+                    #     half the maximum line length (making it 80/2 =
+                    #     40 characters by default).
                     next
                       unless (
                     next
                       unless (
-                        $n == $nmax    # if this is the last line
-                        && $types_to_go[$il] eq ';'    # ending in ';'
-                        && $types_to_go[$if] eq 'k'    # after 'if' or 'unless'
-                                                       #   /^(if|unless)$/
-                        && $is_if_unless{ $tokens_to_go[$if] }
-
-                        # and if this doesn't make a long last line
-                        && total_line_length( $if, $il ) <=
-                        $half_maximum_line_length
+                        $this_line_is_semicolon_terminated
+                        && (
+
+                            # following 'if' or 'unless'
+                            $types_to_go[$if] eq 'k'
+                            && $is_if_unless{ $tokens_to_go[$if] }
+
+                        )
                       );
 
                     # override breakpoint
                       );
 
                     # override breakpoint
-                    $forced_breakpoint_to_go[$imid] = 0;
+                    ##$forced_breakpoint_to_go[$imid] = 0;
                 }
 
                 # handle leading "if" and "unless"
                 }
 
                 # handle leading "if" and "unless"
@@ -14477,20 +15201,17 @@ sub recombine_breakpoints {
                     # FIXME: This is still experimental..may not be too useful
                     next
                       unless (
                     # FIXME: This is still experimental..may not be too useful
                     next
                       unless (
-                        $n == $nmax    # if this is the last line
-                        && $types_to_go[$il] eq ';'    # ending in ';'
-                        && $types_to_go[$if] eq 'k'
+                        $this_line_is_semicolon_terminated
 
 
-                        #   /^(and|or)$/
+                        #  previous line begins with 'and' or 'or'
+                        && $types_to_go[$if] eq 'k'
                         && $is_and_or{ $tokens_to_go[$if] }
 
                         && $is_and_or{ $tokens_to_go[$if] }
 
-                        # and if this doesn't make a long last line
-                        && total_line_length( $if, $il ) <=
-                        $half_maximum_line_length
                       );
 
                     # override breakpoint
                       );
 
                     # override breakpoint
-                    $forced_breakpoint_to_go[$imid] = 0;
+                    ##$forced_breakpoint_to_go[$imid] = 0;
+
                 }
 
                 # handle all other leading keywords
                 }
 
                 # handle all other leading keywords
@@ -14498,45 +15219,44 @@ sub recombine_breakpoints {
 
                     # keywords look best at start of lines,
                     # but combine things like "1 while"
 
                     # keywords look best at start of lines,
                     # but combine things like "1 while"
-
                     unless ( $is_assignment{ $types_to_go[$imid] } ) {
                         next
                           if ( ( $types_to_go[$imid] ne 'k' )
                     unless ( $is_assignment{ $types_to_go[$imid] } ) {
                         next
                           if ( ( $types_to_go[$imid] ne 'k' )
-                            && ( $tokens_to_go[$imidr] !~ /^(while)$/ ) );
+                            && ( $tokens_to_go[$imidr] ne 'while' ) );
                     }
                 }
             }
 
             # similar treatment of && and || as above for 'and' and 'or':
                     }
                 }
             }
 
             # similar treatment of && and || as above for 'and' and 'or':
+            # NOTE: This block of code is currently bypassed because
+            # of a previous block but is retained for possible future use.
             elsif ( $types_to_go[$imidr] =~ /^(&&|\|\|)$/ ) {
 
                 # maybe looking at something like:
             elsif ( $types_to_go[$imidr] =~ /^(&&|\|\|)$/ ) {
 
                 # maybe looking at something like:
-                #   unless $TEXTONLY || $item =~ m%</?(hr>|p>|a|img)%i;
+                # unless $TEXTONLY || $item =~ m%</?(hr>|p>|a|img)%i;
 
                 next
                   unless (
 
                 next
                   unless (
-                    $n == $nmax    # if this is the last line
-                    && $types_to_go[$il] eq ';'    # ending in ';'
-                    && $types_to_go[$if] eq 'k'    # after an 'if' or 'unless'
-                                                   #   /^(if|unless)$/
+                    $this_line_is_semicolon_terminated
+
+                    # previous line begins with an 'if' or 'unless' keyword
+                    && $types_to_go[$if] eq 'k'
                     && $is_if_unless{ $tokens_to_go[$if] }
 
                     && $is_if_unless{ $tokens_to_go[$if] }
 
-                    # and if this doesn't make a long last line
-                    && total_line_length( $if, $il ) <=
-                    $half_maximum_line_length
                   );
 
                 # override breakpoint
                   );
 
                 # override breakpoint
-                $forced_breakpoint_to_go[$imid] = 0;
+                ##$forced_breakpoint_to_go[$imid] = 0;
             }
 
             }
 
-            # honor hard breakpoints
-            next if ( $forced_breakpoint_to_go[$imid] > 0 );
-
             #----------------------------------------------------------
             #----------------------------------------------------------
-            # end of special recombination rules
+            # Section 3:
+            # Combine the lines if we arrive here and it is possible
             #----------------------------------------------------------
 
             #----------------------------------------------------------
 
+            # honor hard breakpoints
+            next if ( $forced_breakpoint_to_go[$imid] > 0 );
+
             my $bs = $bond_strength_to_go[$imid];
 
             # combined line cannot be too long
             my $bs = $bond_strength_to_go[$imid];
 
             # combined line cannot be too long
@@ -14559,8 +15279,6 @@ sub recombine_breakpoints {
                         && $tokens_to_go[$if] eq 'if'
                         && $tokens_to_go[$imid] ne '('
                     )
                         && $tokens_to_go[$if] eq 'if'
                         && $tokens_to_go[$imid] ne '('
                     )
-
-                    #
                   );
             }
 
                   );
             }
 
@@ -14781,24 +15499,37 @@ sub set_continuation_breaks {
 
                 # set flags to remember if a break here will produce a
                 # leading alignment of certain common tokens
 
                 # set flags to remember if a break here will produce a
                 # leading alignment of certain common tokens
-                if (
-                       $line_count > 0
+                if (   $line_count > 0
                     && $i_test < $imax
                     && ( $lowest_strength - $last_break_strength <= $max_bias )
                     && $i_test < $imax
                     && ( $lowest_strength - $last_break_strength <= $max_bias )
-                    && ( $nesting_depth_to_go[$i_begin] >=
-                        $nesting_depth_to_go[$i_next_nonblank] )
-                    && (
-                        (
-                               $types_to_go[$i_begin] =~ /^(\.|\&\&|\|\||:)$/
-                            && $types_to_go[$i_begin] eq $next_nonblank_type
-                        )
-                        || (   $tokens_to_go[$i_begin] =~ /^(and|or)$/
-                            && $tokens_to_go[$i_begin] eq $next_nonblank_token )
-                    )
                   )
                 {
                   )
                 {
-                    $leading_alignment_token = $next_nonblank_token;
-                    $leading_alignment_type  = $next_nonblank_type;
+                    my $i_last_end = $i_begin - 1;
+                    if ( $types_to_go[$i_last_end] eq 'b' ) { $i_last_end -= 1 }
+                    my $tok_beg  = $tokens_to_go[$i_begin];
+                    my $type_beg = $types_to_go[$i_begin];
+                    if (
+
+                        # check for leading alignment of certain tokens
+                        (
+                               $tok_beg eq $next_nonblank_token
+                            && $is_chain_operator{$tok_beg}
+                            && (   $type_beg eq 'k'
+                                || $type_beg eq $tok_beg )
+                            && $nesting_depth_to_go[$i_begin] >=
+                            $nesting_depth_to_go[$i_next_nonblank]
+                        )
+
+                        || (   $tokens_to_go[$i_last_end] eq $token
+                            && $is_chain_operator{$token}
+                            && ( $type eq 'k' || $type eq $token )
+                            && $nesting_depth_to_go[$i_last_end] >=
+                            $nesting_depth_to_go[$i_test] )
+                      )
+                    {
+                        $leading_alignment_token = $next_nonblank_token;
+                        $leading_alignment_type  = $next_nonblank_type;
+                    }
                 }
             }
 
                 }
             }
 
@@ -15148,8 +15879,7 @@ sub new {
         $ci_level,            $available_spaces, $index,
         $gnu_sequence_number, $align_paren,      $stack_depth,
         $starting_index,
         $ci_level,            $available_spaces, $index,
         $gnu_sequence_number, $align_paren,      $stack_depth,
         $starting_index,
-      )
-      = @_;
+    ) = @_;
     my $closed            = -1;
     my $arrow_count       = 0;
     my $comma_count       = 0;
     my $closed            = -1;
     my $arrow_count       = 0;
     my $comma_count       = 0;
@@ -15690,6 +16420,7 @@ use vars qw(
   $cached_line_flag
   $cached_seqno
   $cached_line_valid
   $cached_line_flag
   $cached_seqno
   $cached_line_valid
+  $cached_line_leading_space_count
 
   $rOpts
 
 
   $rOpts
 
@@ -15737,11 +16468,12 @@ sub initialize {
     $side_comment_history[2] = [ -100, 0 ];
 
     # write_leader_and_string cache:
     $side_comment_history[2] = [ -100, 0 ];
 
     # write_leader_and_string cache:
-    $cached_line_text  = "";
-    $cached_line_type  = 0;
-    $cached_line_flag  = 0;
-    $cached_seqno      = 0;
-    $cached_line_valid = 0;
+    $cached_line_text                = "";
+    $cached_line_type                = 0;
+    $cached_line_flag                = 0;
+    $cached_seqno                    = 0;
+    $cached_line_valid               = 0;
+    $cached_line_leading_space_count = 0;
 
     # frequently used parameters
     $rOpts_indent_columns           = $rOpts->{'indent-columns'};
 
     # frequently used parameters
     $rOpts_indent_columns           = $rOpts->{'indent-columns'};
@@ -15928,8 +16660,7 @@ sub append_line {
         $is_forced_break,           $outdent_long_lines,
         $is_terminal_statement,     $do_not_pad,
         $rvertical_tightness_flags, $level_jump,
         $is_forced_break,           $outdent_long_lines,
         $is_terminal_statement,     $do_not_pad,
         $rvertical_tightness_flags, $level_jump,
-      )
-      = @_;
+    ) = @_;
 
     # number of fields is $jmax
     # number of tokens between fields is $jmax-1
 
     # number of fields is $jmax
     # number of tokens between fields is $jmax-1
@@ -16699,6 +17430,13 @@ sub check_fit {
 
         next if $pad < 0;
 
 
         next if $pad < 0;
 
+        ## This patch helps sometimes, but it doesn't check to see if
+        ## the line is too long even without the side comment.  It needs
+        ## to be reworked.
+        ##don't let a long token with no trailing side comment push
+        ##side comments out, or end a group.  (sidecmt1.t)
+        ##next if ($j==$jmax-1 && length($$rfields[$jmax])==0);
+
         # This line will need space; lets see if we want to accept it..
         if (
 
         # This line will need space; lets see if we want to accept it..
         if (
 
@@ -16782,7 +17520,9 @@ sub flush {
 
     if ( $maximum_line_index < 0 ) {
         if ($cached_line_type) {
 
     if ( $maximum_line_index < 0 ) {
         if ($cached_line_type) {
-            $file_writer_object->write_code_line( $cached_line_text . "\n" );
+            entab_and_output( $cached_line_text,
+                $cached_line_leading_space_count,
+                $last_group_level_written );
             $cached_line_type = 0;
             $cached_line_text = "";
         }
             $cached_line_type = 0;
             $cached_line_text = "";
         }
@@ -17248,15 +17988,13 @@ sub write_leader_and_string {
         $rvertical_tightness_flags )
       = @_;
 
         $rvertical_tightness_flags )
       = @_;
 
-    my $leading_string = get_leading_string($leading_space_count);
-
     # handle outdenting of long lines:
     if ($outdent_long_lines) {
         my $excess =
           length($str) - $side_comment_length + $leading_space_count -
           $rOpts_maximum_line_length;
         if ( $excess > 0 ) {
     # handle outdenting of long lines:
     if ($outdent_long_lines) {
         my $excess =
           length($str) - $side_comment_length + $leading_space_count -
           $rOpts_maximum_line_length;
         if ( $excess > 0 ) {
-            $leading_string         = "";
+            $leading_space_count    = 0;
             $last_outdented_line_at =
               $file_writer_object->get_output_line_number();
 
             $last_outdented_line_at =
               $file_writer_object->get_output_line_number();
 
@@ -17267,6 +18005,12 @@ sub write_leader_and_string {
         }
     }
 
         }
     }
 
+    # Make preliminary leading whitespace.  It could get changed
+    # later by entabbing, so we have to keep track of any changes
+    # to the leading_space_count from here on.
+    my $leading_string =
+      $leading_space_count > 0 ? ( ' ' x $leading_space_count ) : "";
+
     # Unpack any recombination data; it was packed by
     # sub send_lines_to_vertical_aligner. Contents:
     #
     # Unpack any recombination data; it was packed by
     # sub send_lines_to_vertical_aligner. Contents:
     #
@@ -17284,10 +18028,12 @@ sub write_leader_and_string {
 
     # handle any cached line ..
     # either append this line to it or write it out
 
     # handle any cached line ..
     # either append this line to it or write it out
-    if ($cached_line_text) {
+    if ( length($cached_line_text) ) {
 
         if ( !$cached_line_valid ) {
 
         if ( !$cached_line_valid ) {
-            $file_writer_object->write_code_line( $cached_line_text . "\n" );
+            entab_and_output( $cached_line_text,
+                $cached_line_leading_space_count,
+                $last_group_level_written );
         }
 
         # handle cached line with opening container token
         }
 
         # handle cached line with opening container token
@@ -17303,11 +18049,13 @@ sub write_leader_and_string {
             }
 
             if ( $gap >= 0 ) {
             }
 
             if ( $gap >= 0 ) {
-                $leading_string = $cached_line_text . ' ' x $gap;
+                $leading_string      = $cached_line_text . ' ' x $gap;
+                $leading_space_count = $cached_line_leading_space_count;
             }
             else {
             }
             else {
-                $file_writer_object->write_code_line(
-                    $cached_line_text . "\n" );
+                entab_and_output( $cached_line_text,
+                    $cached_line_leading_space_count,
+                    $last_group_level_written );
             }
         }
 
             }
         }
 
@@ -17316,30 +18064,34 @@ sub write_leader_and_string {
             my $test_line = $cached_line_text . ' ' x $cached_line_flag . $str;
 
             if ( length($test_line) <= $rOpts_maximum_line_length ) {
             my $test_line = $cached_line_text . ' ' x $cached_line_flag . $str;
 
             if ( length($test_line) <= $rOpts_maximum_line_length ) {
-                $str            = $test_line;
-                $leading_string = "";
+                $str                 = $test_line;
+                $leading_string      = "";
+                $leading_space_count = $cached_line_leading_space_count;
             }
             else {
             }
             else {
-                $file_writer_object->write_code_line(
-                    $cached_line_text . "\n" );
+                entab_and_output( $cached_line_text,
+                    $cached_line_leading_space_count,
+                    $last_group_level_written );
             }
         }
     }
     $cached_line_type = 0;
     $cached_line_text = "";
 
             }
         }
     }
     $cached_line_type = 0;
     $cached_line_text = "";
 
+    # make the line to be written
     my $line = $leading_string . $str;
 
     # write or cache this line
     if ( !$rvertical_tightness_flags || $side_comment_length > 0 ) {
     my $line = $leading_string . $str;
 
     # write or cache this line
     if ( !$rvertical_tightness_flags || $side_comment_length > 0 ) {
-        $file_writer_object->write_code_line( $line . "\n" );
+        entab_and_output( $line, $leading_space_count, $group_level );
     }
     else {
     }
     else {
-        $cached_line_text  = $line;
-        $cached_line_type  = $open_or_close;
-        $cached_line_flag  = $tightness_flag;
-        $cached_seqno      = $seqno;
-        $cached_line_valid = $valid;
+        $cached_line_text                = $line;
+        $cached_line_type                = $open_or_close;
+        $cached_line_flag                = $tightness_flag;
+        $cached_seqno                    = $seqno;
+        $cached_line_valid               = $valid;
+        $cached_line_leading_space_count = $leading_space_count;
     }
 
     $last_group_level_written = $group_level;
     }
 
     $last_group_level_written = $group_level;
@@ -17347,6 +18099,75 @@ sub write_leader_and_string {
     $extra_indent_ok          = 0;
 }
 
     $extra_indent_ok          = 0;
 }
 
+sub entab_and_output {
+    my ( $line, $leading_space_count, $level ) = @_;
+
+    # The line is currently correct if there is no tabbing (recommended!)
+    # We may have to lop off some leading spaces and replace with tabs.
+    if ( $leading_space_count > 0 ) {
+
+        # Nothing to do if no tabs
+        if ( !( $rOpts_tabs || $rOpts_entab_leading_whitespace )
+            || $rOpts_indent_columns <= 0 )
+        {
+
+            # nothing to do
+        }
+
+        # Handle entab option
+        elsif ($rOpts_entab_leading_whitespace) {
+            my $space_count =
+              $leading_space_count % $rOpts_entab_leading_whitespace;
+            my $tab_count =
+              int( $leading_space_count / $rOpts_entab_leading_whitespace );
+            my $leading_string = "\t" x $tab_count . ' ' x $space_count;
+            if ( $line =~ /^\s{$leading_space_count,$leading_space_count}/ ) {
+                substr( $line, 0, $leading_space_count ) = $leading_string;
+            }
+            else {
+
+                # REMOVE AFTER TESTING
+                # shouldn't happen - program error counting whitespace
+                # we'll skip entabbing
+                warning(
+"Error entabbing in entab_and_output: expected count=$leading_space_count\n"
+                );
+            }
+        }
+
+        # Handle option of one tab per level
+        else {
+            my $leading_string = ( "\t" x $level );
+            my $space_count    =
+              $leading_space_count - $level * $rOpts_indent_columns;
+
+            # shouldn't happen:
+            if ( $space_count < 0 ) {
+                warning(
+"Error entabbing in append_line: for level=$group_level count=$leading_space_count\n"
+                );
+                $leading_string = ( ' ' x $leading_space_count );
+            }
+            else {
+                $leading_string .= ( ' ' x $space_count );
+            }
+            if ( $line =~ /^\s{$leading_space_count,$leading_space_count}/ ) {
+                substr( $line, 0, $leading_space_count ) = $leading_string;
+            }
+            else {
+
+                # REMOVE AFTER TESTING
+                # shouldn't happen - program error counting whitespace
+                # we'll skip entabbing
+                warning(
+"Error entabbing in entab_and_output: expected count=$leading_space_count\n"
+                );
+            }
+        }
+    }
+    $file_writer_object->write_code_line( $line . "\n" );
+}
+
 {    # begin get_leading_string
 
     my @leading_string_cache;
 {    # begin get_leading_string
 
     my @leading_string_cache;
@@ -17867,6 +18688,7 @@ use vars qw{
   $last_nonblank_prototype
   $statement_type
   $identifier
   $last_nonblank_prototype
   $statement_type
   $identifier
+  $in_attribute_list
   $in_quote
   $quote_type
   $quote_character
   $in_quote
   $quote_type
   $quote_character
@@ -18002,6 +18824,7 @@ sub new {
     # _in_data              flag set if we are in __DATA__ section
     # _in_end               flag set if we are in __END__ section
     # _in_format            flag set if we are in a format description
     # _in_data              flag set if we are in __DATA__ section
     # _in_end               flag set if we are in __END__ section
     # _in_format            flag set if we are in a format description
+    # _in_attribute_list    flag telling if we are looking for attributes
     # _in_quote             flag telling if we are chasing a quote
     # _starting_level       indentation level of first line
     # _input_tabstr         string denoting one indentation level of input file
     # _in_quote             flag telling if we are chasing a quote
     # _starting_level       indentation level of first line
     # _input_tabstr         string denoting one indentation level of input file
@@ -18018,6 +18841,7 @@ sub new {
         _in_format            => 0,
         _in_error             => 0,
         _in_pod               => 0,
         _in_format            => 0,
         _in_error             => 0,
         _in_pod               => 0,
+        _in_attribute_list    => 0,
         _in_quote             => 0,
         _quote_target         => "",
         _line_start_quote     => -1,
         _in_quote             => 0,
         _quote_target         => "",
         _line_start_quote     => -1,
@@ -18234,8 +19058,12 @@ EOM
     if ( $tokenizer_self->{_in_quote} ) {
         my $line_start_quote = $tokenizer_self->{_line_start_quote};
         my $quote_target     = $tokenizer_self->{_quote_target};
     if ( $tokenizer_self->{_in_quote} ) {
         my $line_start_quote = $tokenizer_self->{_line_start_quote};
         my $quote_target     = $tokenizer_self->{_quote_target};
+        my $what             =
+          ( $tokenizer_self->{_in_attribute_list} )
+          ? "attribute list"
+          : "quote/pattern";
         warning(
         warning(
-"hit EOF seeking end of quote/pattern starting at line $line_start_quote ending in $quote_target\n"
+"hit EOF seeking end of $what starting at line $line_start_quote ending in $quote_target\n"
         );
     }
 
         );
     }
 
@@ -18352,7 +19180,7 @@ sub get_line {
         _rnesting_tokens          => undef,
         _rci_levels               => undef,
         _rnesting_blocks          => undef,
         _rnesting_tokens          => undef,
         _rci_levels               => undef,
         _rnesting_blocks          => undef,
-        _python_indentation_level => -1,                      ## 0,
+        _python_indentation_level => -1,                   ## 0,
         _starting_in_quote        =>
           ( $tokenizer_self->{_in_quote} && ( $quote_type eq 'Q' ) ),
         _ending_in_quote      => 0,
         _starting_in_quote        =>
           ( $tokenizer_self->{_in_quote} && ( $quote_type eq 'Q' ) ),
         _ending_in_quote      => 0,
@@ -18430,7 +19258,9 @@ sub get_line {
             $tokenizer_self->{_in_pod} = 0;
         }
         if ( $input_line =~ /^\#\!.*perl\b/ ) {
             $tokenizer_self->{_in_pod} = 0;
         }
         if ( $input_line =~ /^\#\!.*perl\b/ ) {
-            warning("Hash-bang in pod can cause perl to fail! \n");
+            warning(
+                "Hash-bang in pod can cause older versions of perl to fail! \n"
+            );
         }
 
         return $line_of_tokens;
         }
 
         return $line_of_tokens;
@@ -18892,9 +19722,9 @@ sub dump_token_types {
 Here is a list of the token types currently used for lines of type 'CODE'.  
 For the following tokens, the "type" of a token is just the token itself.  
 
 Here is a list of the token types currently used for lines of type 'CODE'.  
 For the following tokens, the "type" of a token is just the token itself.  
 
-.. :: << >> ** && .. ||  -> => += -= .= %= &= |= ^= *= <>
+.. :: << >> ** && .. || // -> => += -= .= %= &= |= ^= *= <>
 ( ) <= >= == =~ !~ != ++ -- /= x=
 ( ) <= >= == =~ !~ != ++ -- /= x=
-... **= <<= >>= &&= ||= <=> 
+... **= <<= >>= &&= ||= //= <=> 
 , + - / * | % ! x ~ = \ ? : . < > ^ &
 
 The following additional token types are defined:
 , + - / * | % ! x ~ = \ ? : . < > ^ &
 
 The following additional token types are defined:
@@ -19002,6 +19832,7 @@ sub prepare_for_a_new_file {
     $last_last_nonblank_type_sequence  = '';
     $last_nonblank_prototype           = "";
     $identifier                        = '';
     $last_last_nonblank_type_sequence  = '';
     $last_nonblank_prototype           = "";
     $identifier                        = '';
+    $in_attribute_list                 = 0;     # ATTRS
     $in_quote   = 0;     # flag telling if we are chasing a quote, and what kind
     $quote_type = 'Q';
     $quote_character = "";    # character we seek if chasing a quote
     $in_quote   = 0;     # flag telling if we are chasing a quote, and what kind
     $quote_type = 'Q';
     $quote_character = "";    # character we seek if chasing a quote
@@ -19195,6 +20026,7 @@ sub reset_indentation_level {
 ##      '^='  => undef,
 ##      '|='  => undef,
 ##      '||=' => undef,
 ##      '^='  => undef,
 ##      '|='  => undef,
 ##      '||=' => undef,
+##      '//=' => undef,
 ##      '~'   => undef,
 
         '>' => sub {
 ##      '~'   => undef,
 
         '>' => sub {
@@ -19365,6 +20197,9 @@ sub reset_indentation_level {
             if ( $last_nonblank_type eq ',' ) {
                 complain("Repeated ','s \n");
             }
             if ( $last_nonblank_type eq ',' ) {
                 complain("Repeated ','s \n");
             }
+
+            # patch for operator_expected: note if we are in the list (use.t)
+            if ( $statement_type eq 'use' ) { $statement_type = '_use' }
 ##                FIXME: need to move this elsewhere, perhaps check after a '('
 ##                elsif ($last_nonblank_token eq '(') {
 ##                    warning("Leading ','s illegal in some versions of perl\n");
 ##                FIXME: need to move this elsewhere, perhaps check after a '('
 ##                elsif ($last_nonblank_token eq '(') {
 ##                    warning("Leading ','s illegal in some versions of perl\n");
@@ -19687,7 +20522,8 @@ sub reset_indentation_level {
             # ATTRS: check for a ':' which introduces an attribute list
             # (this might eventually get its own token type)
             elsif ( $statement_type =~ /^sub/ ) {
             # ATTRS: check for a ':' which introduces an attribute list
             # (this might eventually get its own token type)
             elsif ( $statement_type =~ /^sub/ ) {
-                $type = 'A';
+                $type              = 'A';
+                $in_attribute_list = 1;
             }
 
             # check for scalar attribute, such as
             }
 
             # check for scalar attribute, such as
@@ -19695,7 +20531,8 @@ sub reset_indentation_level {
             elsif ($is_my_our{$statement_type}
                 && $current_depth[QUESTION_COLON] == 0 )
             {
             elsif ($is_my_our{$statement_type}
                 && $current_depth[QUESTION_COLON] == 0 )
             {
-                $type = 'A';
+                $type              = 'A';
+                $in_attribute_list = 1;
             }
 
             # otherwise, it should be part of a ?/: operator
             }
 
             # otherwise, it should be part of a ?/: operator
@@ -19873,6 +20710,10 @@ sub reset_indentation_level {
             if ( $last_nonblank_type eq $tok ) {
                 complain("Repeated '=>'s \n");
             }
             if ( $last_nonblank_type eq $tok ) {
                 complain("Repeated '=>'s \n");
             }
+
+            # patch for operator_expected: note if we are in the list (use.t)
+            # TODO: make version numbers a new token type
+            if ( $statement_type eq 'use' ) { $statement_type = '_use' }
         },
 
         # type = 'mm' for pre-decrement, '--' for post-decrement
         },
 
         # type = 'mm' for pre-decrement, '--' for post-decrement
@@ -19895,6 +20736,11 @@ sub reset_indentation_level {
             error_if_expecting_TERM()
               if ( $expecting == TERM );
         },
             error_if_expecting_TERM()
               if ( $expecting == TERM );
         },
+
+        '//' => sub {
+            error_if_expecting_TERM()
+              if ( $expecting == TERM );
+        },
     };
 
     # ------------------------------------------------------------
     };
 
     # ------------------------------------------------------------
@@ -19916,7 +20762,7 @@ sub reset_indentation_level {
     @is_not_zero_continuation_block_type{@_} = (1) x scalar(@_);
 
     my %is_logical_container;
     @is_not_zero_continuation_block_type{@_} = (1) x scalar(@_);
 
     my %is_logical_container;
-    @_ = qw(if elsif unless while and or not && !  || for foreach);
+    @_ = qw(if elsif unless while and or err not && !  || for foreach);
     @is_logical_container{@_} = (1) x scalar(@_);
 
     my %is_binary_type;
     @is_logical_container{@_} = (1) x scalar(@_);
 
     my %is_binary_type;
@@ -19924,7 +20770,7 @@ sub reset_indentation_level {
     @is_binary_type{@_} = (1) x scalar(@_);
 
     my %is_binary_keyword;
     @is_binary_type{@_} = (1) x scalar(@_);
 
     my %is_binary_keyword;
-    @_ = qw(and or eq ne cmp);
+    @_ = qw(and or err eq ne cmp);
     @is_binary_keyword{@_} = (1) x scalar(@_);
 
     # 'L' is token for opening { at hash key
     @is_binary_keyword{@_} = (1) x scalar(@_);
 
     # 'L' is token for opening { at hash key
@@ -20332,10 +21178,25 @@ EOM
             # I have allowed tokens starting with <, such as <=,
             # because I don't think these could be valid angle operators.
             # test file: storrs4.pl
             # I have allowed tokens starting with <, such as <=,
             # because I don't think these could be valid angle operators.
             # test file: storrs4.pl
-            my $test_tok = $tok . $$rtokens[ $i + 1 ];
+            my $test_tok   = $tok . $$rtokens[ $i + 1 ];
+            my $combine_ok = $is_digraph{$test_tok};
+
+            # check for special cases which cannot be combined
+            if ($combine_ok) {
+
+                # '//' must be defined_or operator if an operator is expected.
+                # TODO: Code for other ambiguous digraphs (/=, x=, **, *=)
+                # could be migrated here for clarity
+                if ( $test_tok eq '//' ) {
+                    my $next_type = $$rtokens[ $i + 1 ];
+                    my $expecting =
+                      operator_expected( $prev_type, $tok, $next_type );
+                    $combine_ok = 0 unless ( $expecting == OPERATOR );
+                }
+            }
 
             if (
 
             if (
-                $is_digraph{$test_tok}
+                $combine_ok
                 && ( $test_tok ne '/=' )    # might be pattern
                 && ( $test_tok ne 'x=' )    # might be $x
                 && ( $test_tok ne '**' )    # typeglob?
                 && ( $test_tok ne '/=' )    # might be pattern
                 && ( $test_tok ne 'x=' )    # might be $x
                 && ( $test_tok ne '**' )    # typeglob?
@@ -20355,6 +21216,7 @@ EOM
                     $i++;
                 }
             }
                     $i++;
                 }
             }
+
             $type      = $tok;
             $next_tok  = $$rtokens[ $i + 1 ];
             $next_type = $$rtoken_type[ $i + 1 ];
             $type      = $tok;
             $next_tok  = $$rtokens[ $i + 1 ];
             $next_type = $$rtoken_type[ $i + 1 ];
@@ -20370,6 +21232,9 @@ EOM
                 print "TOKENIZE:(@debug_list)\n";
             };
 
                 print "TOKENIZE:(@debug_list)\n";
             };
 
+            # turn off attribute list on first non-blank, non-bareword
+            if ( $pre_type ne 'w' ) { $in_attribute_list = 0 }
+
             ###############################################################
             # We have the next token, $tok.
             # Now we have to examine this token and decide what it is
             ###############################################################
             # We have the next token, $tok.
             # Now we have to examine this token and decide what it is
@@ -20383,6 +21248,25 @@ EOM
                 my ( $next_nonblank_token, $i_next ) =
                   find_next_nonblank_token( $i, $rtokens );
 
                 my ( $next_nonblank_token, $i_next ) =
                   find_next_nonblank_token( $i, $rtokens );
 
+                # ATTRS: handle sub and variable attributes
+                if ($in_attribute_list) {
+
+                    # treat bare word followed by open paren like qw(
+                    if ( $next_nonblank_token eq '(' ) {
+                        $in_quote                = $quote_items{q};
+                        $allowed_quote_modifiers = $quote_modifiers{q};
+                        $type                    = 'q';
+                        $quote_type              = 'q';
+                        next;
+                    }
+
+                    # handle bareword not followed by open paren
+                    else {
+                        $type = 'w';
+                        next;
+                    }
+                }
+
                 # quote a word followed by => operator
                 if ( $next_nonblank_token eq '=' ) {
 
                 # quote a word followed by => operator
                 if ( $next_nonblank_token eq '=' ) {
 
@@ -21293,6 +22177,7 @@ EOM
             push( @tokens, substr( $input_line, $$rtoken_map[$im], $num ) );
         }
 
             push( @tokens, substr( $input_line, $$rtoken_map[$im], $num ) );
         }
 
+        $tokenizer_self->{_in_attribute_list} = $in_attribute_list;
         $tokenizer_self->{_in_quote}          = $in_quote;
         $tokenizer_self->{_rhere_target_list} = \@here_target_list;
 
         $tokenizer_self->{_in_quote}          = $in_quote;
         $tokenizer_self->{_rhere_target_list} = \@here_target_list;
 
@@ -21758,6 +22643,8 @@ sub operator_expected {
     my ( $prev_type, $tok, $next_type ) = @_;
     my $op_expected = UNKNOWN;
 
     my ( $prev_type, $tok, $next_type ) = @_;
     my $op_expected = UNKNOWN;
 
+#print "tok=$tok last type=$last_nonblank_type last tok=$last_nonblank_token\n";
+
 # Note: function prototype is available for token type 'U' for future
 # program development.  It contains the leading and trailing parens,
 # and no blanks.  It might be used to eliminate token type 'C', for
 # Note: function prototype is available for token type 'U' for future
 # program development.  It contains the leading and trailing parens,
 # and no blanks.  It might be used to eliminate token type 'C', for
@@ -21829,9 +22716,14 @@ sub operator_expected {
     {
         $op_expected = OPERATOR;
 
     {
         $op_expected = OPERATOR;
 
-        # in a 'use' statement, numbers and v-strings are not really
+        # in a 'use' statement, numbers and v-strings are not true
         # numbers, so to avoid incorrect error messages, we will
         # mark them as unknown for now (use.t)
         # numbers, so to avoid incorrect error messages, we will
         # mark them as unknown for now (use.t)
+        # TODO: it would be much nicer to create a new token V for VERSION
+        # number in a use statement.  Then this could be a check on type V
+        # and related patches which change $statement_type for '=>'
+        # and ',' could be removed.  Further, it would clean things up to
+        # scan the 'use' statement with a separate subroutine.
         if (   ( $statement_type eq 'use' )
             && ( $last_nonblank_type =~ /^[nv]$/ ) )
         {
         if (   ( $statement_type eq 'use' )
             && ( $last_nonblank_type =~ /^[nv]$/ ) )
         {
@@ -21841,7 +22733,21 @@ sub operator_expected {
 
     # no operator after many keywords, such as "die", "warn", etc
     elsif ( $expecting_term_token{$last_nonblank_token} ) {
 
     # no operator after many keywords, such as "die", "warn", etc
     elsif ( $expecting_term_token{$last_nonblank_token} ) {
-        $op_expected = TERM;
+
+        # patch for dor.t (defined or).
+        # perl functions which may be unary operators
+        # TODO: This list is incomplete, and these should be put
+        # into a hash.
+        if (   $tok eq '/'
+            && $next_type          eq '/'
+            && $last_nonblank_type eq 'k'
+            && $last_nonblank_token =~ /^eof|undef|shift|pop$/ )
+        {
+            $op_expected = OPERATOR;
+        }
+        else {
+            $op_expected = TERM;
+        }
     }
 
     # no operator after things like + - **  (i.e., other operators)
     }
 
     # no operator after things like + - **  (i.e., other operators)
@@ -21870,7 +22776,17 @@ sub operator_expected {
     # (This statement is order dependent, and must come after checking
     # $last_nonblank_token).
     elsif ( $last_nonblank_type eq '}' ) {
     # (This statement is order dependent, and must come after checking
     # $last_nonblank_token).
     elsif ( $last_nonblank_type eq '}' ) {
-        $op_expected = TERM;
+
+        # patch for dor.t (defined or).
+        if (   $tok eq '/'
+            && $next_type           eq '/'
+            && $last_nonblank_token eq ']' )
+        {
+            $op_expected = OPERATOR;
+        }
+        else {
+            $op_expected = TERM;
+        }
     }
 
     # something else..what did I forget?
     }
 
     # something else..what did I forget?
@@ -22322,9 +23238,18 @@ sub find_angle_operator_termination {
             my $pos_beg = $$rtoken_map[$i];
             my $str     = substr( $input_line, $pos_beg, ( $pos - $pos_beg ) );
 
             my $pos_beg = $$rtoken_map[$i];
             my $str     = substr( $input_line, $pos_beg, ( $pos - $pos_beg ) );
 
+            # Reject if the closing '>' follows a '-' as in:
+            # if ( VERSION < 5.009 && $op-> name eq 'aassign' ) { }
+            if ( $expecting eq UNKNOWN ) {
+                my $check = substr( $input_line, $pos - 2, 1 );
+                if ( $check eq '-' ) {
+                    return ( $i, $type );
+                }
+            }
+
             ######################################debug#####
             #write_diagnostics( "ANGLE? :$str\n");
             ######################################debug#####
             #write_diagnostics( "ANGLE? :$str\n");
-            #print "ANGLE: found $1 at pos=$pos\n";
+            #print "ANGLE: found $1 at pos=$pos str=$str check=$check\n";
             ######################################debug#####
             $type = 'Q';
             my $error;
             ######################################debug#####
             $type = 'Q';
             my $error;
@@ -22769,6 +23694,7 @@ sub scan_number_do {
 
     # handle v-string without leading 'v' character ('Two Dot' rule)
     # (vstring.t)
 
     # handle v-string without leading 'v' character ('Two Dot' rule)
     # (vstring.t)
+    # TODO: v-strings may contain underscores
     pos($input_line) = $pos_beg;
     if ( $input_line =~ /\G((\d+)?\.\d+(\.\d+)+)/g ) {
         $pos = pos($input_line);
     pos($input_line) = $pos_beg;
     if ( $input_line =~ /\G((\d+)?\.\d+(\.\d+)+)/g ) {
         $pos = pos($input_line);
@@ -22893,11 +23819,11 @@ sub scan_bare_identifier_do {
 
             # check for v-string with leading 'v' type character
             # (This seems to have presidence over filehandle, type 'Y')
 
             # check for v-string with leading 'v' type character
             # (This seems to have presidence over filehandle, type 'Y')
-            if ( $tok =~ /^v\d+$/ ) {
+            if ( $tok =~ /^v\d[_\d]*$/ ) {
 
                 # we only have the first part - something like 'v101' -
                 # look for more
 
                 # we only have the first part - something like 'v101' -
                 # look for more
-                if ( $input_line =~ m/\G(\.\d+)+/gc ) {
+                if ( $input_line =~ m/\G(\.\d[_\d]*)+/gc ) {
                     $pos  = pos($input_line);
                     $numc = $pos - $pos_beg;
                     $tok  = substr( $input_line, $pos_beg, $numc );
                     $pos  = pos($input_line);
                     $numc = $pos - $pos_beg;
                     $tok  = substr( $input_line, $pos_beg, $numc );
@@ -23229,7 +24155,8 @@ sub scan_id_do {
 
             # catch case of line with leading ATTR ':' after anonymous sub
             if ( $pos == $pos_beg && $tok eq ':' ) {
 
             # catch case of line with leading ATTR ':' after anonymous sub
             if ( $pos == $pos_beg && $tok eq ':' ) {
-                $type = 'A';
+                $type              = 'A';
+                $in_attribute_list = 1;
             }
 
             # We must convert back from character position
             }
 
             # We must convert back from character position
@@ -24033,12 +24960,12 @@ BEGIN {
     @closing_brace_names = qw# '}' ']' ')' ':' #;
 
     my @digraphs = qw(
     @closing_brace_names = qw# '}' ']' ')' ':' #;
 
     my @digraphs = qw(
-      .. :: << >> ** && .. ||  -> => += -= .= %= &= |= ^= *= <>
+      .. :: << >> ** && .. || // -> => += -= .= %= &= |= ^= *= <>
       <= >= == =~ !~ != ++ -- /= x=
     );
     @is_digraph{@digraphs} = (1) x scalar(@digraphs);
 
       <= >= == =~ !~ != ++ -- /= x=
     );
     @is_digraph{@digraphs} = (1) x scalar(@digraphs);
 
-    my @trigraphs = qw( ... **= <<= >>= &&= ||= <=> );
+    my @trigraphs = qw( ... **= <<= >>= &&= ||= //= <=> );
     @is_trigraph{@trigraphs} = (1) x scalar(@trigraphs);
 
     # make a hash of all valid token types for self-checking the tokenizer
     @is_trigraph{@trigraphs} = (1) x scalar(@trigraphs);
 
     # make a hash of all valid token types for self-checking the tokenizer
@@ -24297,6 +25224,7 @@ BEGIN {
       case
       given
       when
       case
       given
       when
+      err
     );
 
     # patched above for SWITCH/CASE
     );
 
     # patched above for SWITCH/CASE
@@ -24362,8 +25290,8 @@ BEGIN {
     # note: pp and mm are pre-increment and decrement
     # f=semicolon in for,  F=file test operator
     my @value_requestor_type = qw#
     # note: pp and mm are pre-increment and decrement
     # f=semicolon in for,  F=file test operator
     my @value_requestor_type = qw#
-      L { ( [ ~ !~ =~ ; . .. ... A : && ! || = + - x
-      **= += -= .= /= *= %= x= &= |= ^= <<= >>= &&= ||=
+      L { ( [ ~ !~ =~ ; . .. ... A : && ! || // = + - x
+      **= += -= .= /= *= %= x= &= |= ^= <<= >>= &&= ||= //=
       <= >= == != => \ > < % * / ? & | ** <=>
       f F pp mm Y p m U J G
       #;
       <= >= == != => \ > < % * / ? & | ** <=>
       f F pp mm Y p m U J G
       #;
@@ -24515,14 +25443,16 @@ Perl::Tidy - Parses and beautifies perl source
     use Perl::Tidy;
 
     Perl::Tidy::perltidy(
     use Perl::Tidy;
 
     Perl::Tidy::perltidy(
-        source      => $source,
-        destination => $destination,
-        stderr      => $stderr,
-        argv        => $argv,
-        perltidyrc  => $perltidyrc,
-        logfile     => $logfile,
-        errorfile   => $errorfile,
-        formatter   => $formatter,  # callback object (see below)
+        source            => $source,
+        destination       => $destination,
+        stderr            => $stderr,
+        argv              => $argv,
+        perltidyrc        => $perltidyrc,
+        logfile           => $logfile,
+        errorfile         => $errorfile,
+        formatter         => $formatter,           # callback object (see below)
+        dump_options      => $dump_options,
+        dump_options_type => $dump_options_type,
     );
 
 =head1 DESCRIPTION
     );
 
 =head1 DESCRIPTION
@@ -24542,12 +25472,17 @@ The following list of parameters may be any of a the following: a
 filename, an ARRAY reference, a SCALAR reference, or an object with
 either a B<getline> or B<print> method, as appropriate.
 
 filename, an ARRAY reference, a SCALAR reference, or an object with
 either a B<getline> or B<print> method, as appropriate.
 
-        source          - the source of the script to be formatted
-        destination     - the destination of the formatted output
-        stderr          - standard error output
-        perltidyrc      - the .perltidyrc file
-        logfile         - the .LOG file stream, if any 
-        errorfile       - the .ERR file stream, if any
+        source            - the source of the script to be formatted
+        destination       - the destination of the formatted output
+        stderr            - standard error output
+        perltidyrc        - the .perltidyrc file
+        logfile           - the .LOG file stream, if any 
+        errorfile         - the .ERR file stream, if any
+        dump_options      - ref to a hash to receive parameters (see below), 
+        dump_options_type - controls contents of dump_options
+        dump_getopt_flags - ref to a hash to receive Getopt flags
+        dump_options_category - ref to a hash giving category of options
+        dump_abbreviations    - ref to a hash giving all abbreviations
 
 The following chart illustrates the logic used to decide how to
 treat a parameter.
 
 The following chart illustrates the logic used to decide how to
 treat a parameter.
@@ -24592,6 +25527,49 @@ string, or a reference to an array.  If it is a string or reference to a
 string, it will be parsed into an array of items just as if it were a
 command line string.
 
 string, it will be parsed into an array of items just as if it were a
 command line string.
 
+=item dump_options
+
+If the B<dump_options> parameter is given, it must be the reference to a hash.
+In this case, the parameters contained in any perltidyrc configuration file
+will be placed in this hash and perltidy will return immediately.  This is
+equivalent to running perltidy with --dump-options, except that the perameters
+are returned in a hash rather than dumped to standard output.  Also, by default
+only the parameters in the perltidyrc file are returned, but this can be
+changed (see the next parameter).  This parameter provides a convenient method
+for external programs to read a perltidyrc file.  An example program using
+this feature, F<perltidyrc_dump.pl>, is included in the distribution.
+
+Any combination of the B<dump_> parameters may be used together.
+
+=item dump_options_type
+
+This parameter is a string which can be used to control the parameters placed
+in the hash reference supplied by B<dump_options>.  The possible values are
+'perltidyrc' (default) and 'full'.  The 'full' parameter causes both the
+default options plus any options found in a perltidyrc file to be returned.
+
+=item dump_getopt_flags
+
+If the B<dump_getopt_flags> parameter is given, it must be the reference to a
+hash.  This hash will receive all of the parameters that perltidy understands
+and flags that are passed to Getopt::Long.  This parameter may be
+used alone or with the B<dump_options> flag.  Perltidy will
+exit immediately after filling this hash.  See the demo program
+F<perltidyrc_dump.pl> for example usage.
+
+=item dump_options_category
+
+If the B<dump_options_category> parameter is given, it must be the reference to a
+hash.  This hash will receive a hash with keys equal to all long parameter names
+and values equal to the title of the corresponding section of the perltidy manual.
+See the demo program F<perltidyrc_dump.pl> for example usage.
+
+=item dump_abbreviations
+
+If the B<dump_abbreviations> parameter is given, it must be the reference to a
+hash.  This hash will receive all abbreviations used by Perl::Tidy.  See the
+demo program F<perltidyrc_dump.pl> for example usage.
+
 =back
 
 =head1 EXAMPLE
 =back
 
 =head1 EXAMPLE
@@ -24767,7 +25745,7 @@ to perltidy.
 
 =head1 VERSION
 
 
 =head1 VERSION
 
-This man page documents Perl::Tidy version 20031021.
+This man page documents Perl::Tidy version 20060614.
 
 =head1 AUTHOR
 
 
 =head1 AUTHOR