Update Text::Balanced to 2.02
Steffen Mueller [Sun, 30 Aug 2009 16:25:03 +0000 (18:25 +0200)]
At the same time, remove PERL_CORE boilerplate from the test scripts.

15 files changed:
MANIFEST
Porting/Maintainers.pl
ext/Text-Balanced/Changes
ext/Text-Balanced/README
ext/Text-Balanced/lib/Text/Balanced.pm
ext/Text-Balanced/t/00-load.t [deleted file]
ext/Text-Balanced/t/01_compile.t [new file with mode: 0644]
ext/Text-Balanced/t/02_extbrk.t [moved from ext/Text-Balanced/t/extbrk.t with 95% similarity]
ext/Text-Balanced/t/03_extcbk.t [moved from ext/Text-Balanced/t/extcbk.t with 96% similarity]
ext/Text-Balanced/t/04_extdel.t [moved from ext/Text-Balanced/t/extdel.t with 95% similarity]
ext/Text-Balanced/t/05_extmul.t [moved from ext/Text-Balanced/t/extmul.t with 98% similarity]
ext/Text-Balanced/t/06_extqlk.t [moved from ext/Text-Balanced/t/extqlk.t with 97% similarity]
ext/Text-Balanced/t/07_exttag.t [moved from ext/Text-Balanced/t/exttag.t with 97% similarity]
ext/Text-Balanced/t/08_extvar.t [moved from ext/Text-Balanced/t/extvar.t with 96% similarity]
ext/Text-Balanced/t/09_gentag.t [moved from ext/Text-Balanced/t/gentag.t with 96% similarity]

index 6d95df1..77aea81 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -1499,18 +1499,18 @@ ext/Test-Harness/t/utils.t                              Test::Harness test
 ext/Test-Harness/t/yamlish-output.t                    Test::Harness test
 ext/Test-Harness/t/yamlish.t                           Test::Harness test
 ext/Test-Harness/t/yamlish-writer.t                    Test::Harness test
-ext/Text-Balanced/Changes      Text::Balanced
-ext/Text-Balanced/lib/Text/Balanced.pm         Text::Balanced
-ext/Text-Balanced/README       Text::Balanced
-ext/Text-Balanced/t/00-load.t  See if Text::Balanced works
-ext/Text-Balanced/t/extbrk.t   See if Text::Balanced works
-ext/Text-Balanced/t/extcbk.t   See if Text::Balanced works
-ext/Text-Balanced/t/extdel.t   See if Text::Balanced works
-ext/Text-Balanced/t/extmul.t   See if Text::Balanced works
-ext/Text-Balanced/t/extqlk.t   See if Text::Balanced works
-ext/Text-Balanced/t/exttag.t   See if Text::Balanced works
-ext/Text-Balanced/t/extvar.t   See if Text::Balanced works
-ext/Text-Balanced/t/gentag.t   See if Text::Balanced works
+ext/Text-Balanced/Changes              Text::Balanced
+ext/Text-Balanced/lib/Text/Balanced.pm Text::Balanced
+ext/Text-Balanced/README               Text::Balanced
+ext/Text-Balanced/t/01_compile.t       See if Text::Balanced works
+ext/Text-Balanced/t/02_extbrk.t                See if Text::Balanced works
+ext/Text-Balanced/t/03_extcbk.t                See if Text::Balanced works
+ext/Text-Balanced/t/04_extdel.t                See if Text::Balanced works
+ext/Text-Balanced/t/05_extmul.t                See if Text::Balanced works
+ext/Text-Balanced/t/06_extqlk.t                See if Text::Balanced works
+ext/Text-Balanced/t/07_exttag.t                See if Text::Balanced works
+ext/Text-Balanced/t/08_extvar.t                See if Text::Balanced works
+ext/Text-Balanced/t/09_gentag.t                See if Text::Balanced works
 ext/Text-Soundex/Changes       Changelog for Text::Soundex
 ext/Text-Soundex/README                README for Text::Soundex
 ext/Text-Soundex/Soundex.pm    Text::Soundex extension Perl module
index 32b6334..e9fa90b 100755 (executable)
@@ -1727,13 +1727,9 @@ package Maintainers;
     'Text::Balanced' =>
        {
        'MAINTAINER'    => 'dmanura',
-       'DISTRIBUTION'  => 'DCONWAY/Text-Balanced-v2.0.0.tar.gz',
+       'DISTRIBUTION'  => 'ADAMK/Text-Balanced-2.02.tar.gz',
        'FILES'         => q[ext/Text-Balanced],
-       'EXCLUDED'      => [ qw( t/pod-coverage.t t/pod.t ) ],
-       'MAP'           => {
-                            # VMS doesn't like multiple dots?
-                            't/00.load.t' => 'lib/Text/Balanced/t/00-load.t',
-                          },
+       'EXCLUDED'      => [ qw( t/97_meta.t t/98_pod.t t/99_pmv.t ) ],
        'CPAN'          => 1,
        'UPSTREAM'      => undef,
        },
index 49957dc..640686e 100644 (file)
-Revision history for Perl extension Text::Balanced.
-
-1.00  Mon Aug 11 12:42:56 1997
-
-       - original version
-
-
-1.01  Mon Sep  8 18:09:18 EST 1997
-
-       - changed "quotemeta" to "quotemeta $_" to work 
-         around bug in Perl 5.002 and 5.003
-
-
-1.10  Tue Sep 30 17:23:23 EST 1997
-
-       - reworked extract_quotelike to correct handling of some obscure cases
-
-
-1.21  Sat Oct  4 17:21:54 EST 1997
-
-       - synchronised with Parse::RecDescent distribution (version number
-         will now reflect that package)
-
-1.23  Fri Oct 17 10:26:38 EST 1997
-
-       - changed behaviour in scalar and void contexts. Scalar contexts
-         now return only the extracted string. Void contexts now remove
-         the extracted string from the first argument (or $_).
-
-1.24
-
-       - changed behaviour in scalar contexts. Scalar contexts
-         now return the extracted string _and_ remove it from the
-         first argument (or $_).
-
-       - changed return values on failure (all contexts return undef
-         for invalid return fields)
-
-       - fixed some lurking bugs with trailing modifier handling
-       
-       - added :ALL tag to simplify wholesale importing of functions
-
-       - fixed serious bug with embedded division operators ("/")
-         This now also allows the ?...? form of pattern matching!
-
-1.35   Wed Jun 24 09:53:31 1998
-
-       - fixed handling of :: quantifiers in extract_variable()
-
-       - numerous trivial lexical changes to make xemacs happy
-
-
-1.36   Tue Jul 14 12:26:04 1998
-
-       - Reinstated POD file missing from previous distribution
-
-       - Added undocumented fourth parameter to extract_codeblock
-         so as to correctly handle (?) and (s?) modifiers in
-         RecDescent grammars.
-
-
-1.40   Tue Aug  4 13:54:52 1998
-
-        - Added (optional) handling of embedded quoted text to
-          extract_delimited (see revised entry in Balanced.pod)
-
-        - Added extract_tagged which extracts text between arbitrary,
-          optionally nested start and end tags (see new entry in
-          Balanced.pod).
-
-        - Added delimited_pat which builds a pattern which matches a
-          string delimited by any of the delimiters specified (see new
-          entry in Balanced.pod).
-
-       - Added test.pl
-
-
-1.41   Mon Aug 10 14:51:50 1998
-
-       - Reinstated change to extract_codeblock from 1.36 which were
-         mysteriously lost in 1.40
-
-
-1.50   Thu Aug 27 09:20:19 1998
-
-       - Improved the structure of the regex generated by
-         delimited_pat (and used in extract_delimited). It's
-         considerably more complex, but also more robust and 
-         much faster in the worst case.
-
-       - Altered extract_variable to accept whitespace in variables,
-         e.g. '$ a -> {'b'}     ->  [2]'
-         
+Revision history for Perl extension Text-Balanced.
+
+2.02   Thu 20 Jul 2009
+       - Fixed the mixed "Damian Conway <adamk@cpan.org>" AUTHOR setting.
+         For the record, I am NOT the author, I'm just the maintainer.
+         Unfortunately, Makefile.PL does not have a MAINTAINER setting and
+         this way all the emails about this module come to me.
+
+2.01   Tue 28 Jul 2009
+       - Taken over by Adam Kennedy to move it to a long-term maintenance mode
+       - Removing use warnings to restore 5.005 compatibility
+       - Removing Module::Build for higher back-compatibility
+       - Removing version.pm for higher back-compatibility
+       - use Exporter -> use Exporter () to avoid some pathalogical cases
+       - Upgraded the bundled author tests to be friendlier
+       - Changes order now a more normal reverse chronological
 
+2.0.0  Wed Dec 20 10:50:24 2006
+       - Added patches from bleadperl version (thanks Rafael!)
+       - Fixed bug in second bracketed delimiters (thanks David)
 
-1.51   Sat Feb 13 10:31:55 1999
+1.99.1 Thu Nov 16 09:29:14 2006
+       - Included dependency on version.pm (thanks Andy)
 
-       - Fixed bugs in prefix matching in extract_variable:
-               * incorrectly used default if '' specified
-               * now handles $#array correctly
+1.99.0 Thu Nov 16 07:32:06 2006
+       - Removed reliance on expensive $& variable (thanks John)
+       - Made Makefile.PL play nice with core versions (thanks Schwern!)
 
-       - Fixed bugs in extract_codeblock:
-                 * Now handles !~ properly
-                 * Now handles embedded comments better.
-                 * Now handles "raw" pattern matches better.
+1.98   Fri May  5 14:58:49 2006
+       - Reinstated full test suite (thanks Steve!)
 
-       - Added support for single strings or qr's as
-         'reject' and 'ignore' args to extract_tagged()
+1.97   Mon May  1 21:58:04 2006
+       - Removed three-part version number and dependency on version.pm
 
-       - Added gen_extract_tagged() to "precompile"
-         a specific tag extractor for repeated use
-         (approximately 3 times faster!)
+1.96.0 Mon May  1 21:52:37 2006
+       - Fixed major bug in extract_multiple handling of unknowns
+       - Fixed return value on failure (thanks Eric)
+       - Fixed bug differentiating heredocs and left-shift operators
+         (thanks Anthony)
 
+1.95   Mon Apr 28 00:22:04 2003
+       - Constrainted _match_quote to only match at word boundaries
+         (so "exemplum(hic)" doesn't match "m(hic)")
+         (thanks Craig)
 
-1.52   Thu Mar  4 12:43:38 1999
+1.94   Sun Apr 13 02:18:41 2003
+       - rereleased in attempt to fix CPAN problems
 
-       - Added CSV parsing example to documentation of extract_multiple.
+1.91   Fri Mar 28 23:19:17 2003
+       - Fixed error count on t/extract_variable.t
+       - Fixed bug in extract_codelike when non-standard delimiters used
 
-       - Fixed a bug with extract_codeblock in "RecDescent" mode
-         (it would accept "subrule(s?)" and "subrule(?)", but
-          not "subrule(s)"). Thanks, Jan.
+1.90   Tue Mar 25 11:14:38 2003
+       - Fixed subtle bug in gen_extract_tagged (thanks Martin)
+       - Doc fix: removed suggestion that extract_tagged defaults
+         to matching HTML tags
+       - Doc fix: clarified general matching behaviour
+       - Fixed bug in parsing /.../ after a (
+       - Doc fix: documented extract_variable
+       - Fixed extract_variable handling of $h{qr}, $h{tr}, etc.
+         (thanks, Briac)
+       - Fixed incorrect handling of $::var (thanks Tim)
 
+1.89   Sun Nov 18 22:49:50 2001
+       - Fixed extvar.t tests
 
-1.66   Fri Jul  2 13:29:22 1999
+1.87   Thu Nov 15 21:25:35 2001
+       - Made extract_multiple aware of skipped prefixes returned
+         by subroutine extractors (such as extract_quotelike, etc.)
+       - Made extract_variable aware of punctuation variables
+       - Corified tests
 
-       - Added ability to use quotelike operators in extract_bracketed
+1.86   Mon Sep  3 06:57:08 2001
+       - Revised licence for inclusion in core distribution
+       - Consolidated POD in .pm file
+       - renamed tests to let DOS cope with them
 
-       - Fixed bug under 5.003 ('foreach my $func' not understood)
+1.85   Sun Jun  3 07:47:18 2001
+       - Fixed bug in extract_variable recognizing method calls that
+         start with an underscore (thanks Jeff)
 
-       - Added escape specification as fourth arg to &extract_delimited
+1.82   Sun Jan 14 16:56:04 2001
+       - Fixed nit in extract_variable.t
+         (tested more cases than it promised to)
+       - Fixed bug extracting prefix in extract_quotelike (Thanks Michael)
+       - Added handling of Perl 4 package qualifier: $Package'var, etc.
+       - Added handling of here docs (see documentation for limitations)
+       - Added reporting of failure position via $@->{pos} (see documentation)
 
-       - Fixed handling of &delimited_pat and &extract_delimited
-         when delimiter is same as escape
+1.84   Thu Apr 26 11:58:13 2001
+       - Fixed bug in certain extractions not matching strings
+         with embedded newlines (thanks Robin)
 
-       - Fixed handling of ->, =>, and >> in &extract_code
-         when delimiters are "<>"
+1.83   Mon Jan 15 12:43:12 2001
+       - Fixed numerous bugs in here doc extraction (many thanks Tim)
 
+1.81   Wed Sep 13 11:58:49 2000
+       - Fixed test count in extract_codeblock.t
+       - Fixed improbable bug with trailing ->'s in extract_variable
+       - Fixed (HT|X)ML tag extraction in extract_tagged (thanks, Tim)
+       - Added explanatory note about prefix matching (thanks again, Tim)
+       - Added handling of globs and sub refs to extract_variable
+       - Pod tweak (thanks Abigail)
+       - Allowed right tags to be run-time evaluated, so
+         extract_tagged($text, '/([a-z]+)', '/end$1') works
+         as expected.
+       - Added optional blessing of matches via extract_multiple
+       - Fixed bug in autogeneration of closing tags in extract_tagged
+         (Thanks, Coke)
+       - Fixed bug in interaction between extract_multiple and
+         gen_extract_tagged (Thanks Anthony)
 
-1.76   Fri Nov 19 06:51:54 1999
+1.77   Mon Nov 22 06:08:23 1999
+       - Fixed major bug in extract_codeblock (would not
+         terminate if there was trailing whitespace)
+       - Improved /.../ pattern parsing within codeblocks
 
+1.76   Fri Nov 19 06:51:54 1999
        - IMPORTANT: Now requires 5.005 or better.
-
        - IMPORTANT: Made extract methods sensitive to the pos()
          value of the text they are parsing. In other words,
          all extract subroutines now act like patterns of the form
          /\G.../gc. See documentation for details.
-
        - IMPORTANT: Changed semantics of extract_multiple, in line
          with the above change, and to simplify the semantics to
          something vaguely predictable. See documentation for details.
-
        - Added ability to use qr/../'s and raw strings as extractors
          in extract_multiple. See documentation.
-
        - Added fourth argument to extract_codeblock to allow
          outermost brackets to be separately specified. See
          documentation for details.
-
        - Reimplemented internals of all extraction subroutines
          for significant speed-ups (between 100% and 2000%
          improvement).
-
        - Fixed nasty bug in extract_variable and extract_codeblock
          (they were returning prefix as well in scalar context)
-
        - Allowed read-only strings to be used as arguments in
          scalar contexts.
-
        - Renamed delimited_pat to gen-delimited pat (in line with
          gen_extract_tagged). Old name still works, but is now deprecated.
-
-       - Tweaked all extraction subs so they correctly handle 
+       - Tweaked all extraction subs so they correctly handle
          zero-length prefix matches after another zero-length match.
 
+1.66   Fri Jul  2 13:29:22 1999
+       - Added ability to use quotelike operators in extract_bracketed
+       - Fixed bug under 5.003 ('foreach my $func' not understood)
+       - Added escape specification as fourth arg to &extract_delimited
+       - Fixed handling of &delimited_pat and &extract_delimited
+         when delimiter is same as escape
+       - Fixed handling of ->, =>, and >> in &extract_code
+         when delimiters are "<>"
 
-1.77   Mon Nov 22 06:08:23 1999
-
-       - Fixed major bug in extract_codeblock (would not 
-         terminate if there was trailing whitespace)
-
-       - Improved /.../ pattern parsing within codeblocks
-
-
-1.81   Wed Sep 13 11:58:49 2000
-
-       - Fixed test count in extract_codeblock.t
-
-       - Fixed improbable bug with trailing ->'s in extract_variable
-
-       - Fixed (HT|X)ML tag extraction in extract_tagged (thanks, Tim)
-
-       - Added explanatory note about prefix matching (thanks again, Tim)
-
-       - Added handling of globs and sub refs to extract_variable
-
-       - Pod tweak (thanks Abigail)
-
-       - Allowed right tags to be run-time evaluated, so
-         extract_tagged($text, '/([a-z]+)', '/end$1') works
-         as expected.
-
-       - Added optional blessing of matches via extract_multiple
-
-       - Fixed bug in autogeneration of closing tags in extract_tagged
-         (Thanks, Coke)
-
-       - Fixed bug in interaction between extract_multiple and
-         gen_extract_tagged (Thanks Anthony)
-
-
-1.82   Sun Jan 14 16:56:04 2001
-
-       - Fixed nit in extract_variable.t
-         (tested more cases than it promised to)
-
-       - Fixed bug extracting prefix in extract_quotelike (Thanks Michael)
-
-       - Added handling of Perl 4 package qualifier: $Package'var, etc.
-
-       - Added handling of here docs (see documentation for limitations)
-
-       - Added reporting of failure position via $@->{pos} (see documentation)
-
-
-1.83   Mon Jan 15 12:43:12 2001
-
-       - Fixed numerous bugs in here doc extraction (many thanks Tim)
-
-
-1.84   Thu Apr 26 11:58:13 2001
-
-       - Fixed bug in certain extractions not matching strings
-         with embedded newlines (thanks Robin)
-
-
-1.85   Sun Jun  3 07:47:18 2001
-
-       - Fixed bug in extract_variable recognizing method calls that
-         start with an underscore (thanks Jeff)
-
-
-1.86   Mon Sep  3 06:57:08 2001
-
-       - Revised licence for inclusion in core distribution
-
-       - Consolidated POD in .pm file
-
-       - renamed tests to let DOS cope with them
-
-
-1.87   Thu Nov 15 21:25:35 2001
-
-       - Made extract_multiple aware of skipped prefixes returned
-         by subroutine extractors (such as extract_quotelike, etc.)
-
-       - Made extract_variable aware of punctuation variables
-
-       - Corified tests
-
-
-1.89   Sun Nov 18 22:49:50 2001
-
-       - Fixed extvar.t tests
-
-
-1.90   Tue Mar 25 11:14:38 2003
-
-       - Fixed subtle bug in gen_extract_tagged (thanks Martin)
-
-       - Doc fix: removed suggestion that extract_tagged defaults
-         to matching HTML tags
-
-       - Doc fix: clarified general matching behaviour
-
-       - Fixed bug in parsing /.../ after a (
-
-       - Doc fix: documented extract_variable
-
-       - Fixed extract_variable handling of $h{qr}, $h{tr}, etc.
-         (thanks, Briac)
-
-       - Fixed incorrect handling of $::var (thanks Tim)
-
-
-1.91   Fri Mar 28 23:19:17 2003
-
-       - Fixed error count on t/extract_variable.t
-
-       - Fixed bug in extract_codelike when non-standard delimiters used
-
-
-1.94   Sun Apr 13 02:18:41 2003
-
-       - rereleased in attempt to fix CPAN problems
-
-
-1.95   Mon Apr 28 00:22:04 2003
-
-       - Constrainted _match_quote to only match at word boundaries
-         (so "exemplum(hic)" doesn't match "m(hic)")
-         (thanks Craig)
-
-
-
-1.96.0  Mon May  1 21:52:37 2006
-
-       - Fixed major bug in extract_multiple handling of unknowns
-
-       - Fixed return value on failure (thanks Eric)
-
-    - Fixed bug differentiating heredocs and left-shift operators
-      (thanks Anthony)
-
-1.97   Mon May  1 21:58:04 2006
-
-    - Removed three-part version number and dependency on version.pm
-
-
-1.98  Fri May  5 14:58:49 2006
-
-    - Reinstated full test suite (thanks Steve!)
-
+1.52   Thu Mar  4 12:43:38 1999
+       - Added CSV parsing example to documentation of extract_multiple.
+       - Fixed a bug with extract_codeblock in "RecDescent" mode
+         (it would accept "subrule(s?)" and "subrule(?)", but
+          not "subrule(s)"). Thanks, Jan.
 
+1.51   Sat Feb 13 10:31:55 1999
+       - Fixed bugs in prefix matching in extract_variable:
+               * incorrectly used default if '' specified
+       * now handles $#array correctly
+       - Fixed bugs in extract_codeblock:
+         * Now handles !~ properly
+         * Now handles embedded comments better.
+         * Now handles "raw" pattern matches better.
+       - Added support for single strings or qr's as
+         'reject' and 'ignore' args to extract_tagged()
+       - Added gen_extract_tagged() to "precompile"
+         a specific tag extractor for repeated use
+         (approximately 3 times faster!)
 
-1.99.0  Thu Nov 16 07:32:06 2006
+1.50   Thu Aug 27 09:20:19 1998
+       - Improved the structure of the regex generated by
+         delimited_pat (and used in extract_delimited). It's
+         considerably more complex, but also more robust and
+         much faster in the worst case.
+       - Altered extract_variable to accept whitespace in variables,
+         e.g. '$ a -> {'b'}     ->  [2]'
 
-    - Removed reliance on expensive $& variable (thanks John)
+1.41   Mon Aug 10 14:51:50 1998
+       - Reinstated change to extract_codeblock from 1.36 which were
+         mysteriously lost in 1.40
 
-    - Made Makefile.PL play nice with core versions (thanks Schwern!)
+1.40   Tue Aug  4 13:54:52 1998
+       - Added (optional) handling of embedded quoted text to
+         extract_delimited (see revised entry in Balanced.pod)
+       - Added extract_tagged which extracts text between arbitrary,
+         optionally nested start and end tags (see new entry in
+         Balanced.pod).
+       - Added delimited_pat which builds a pattern which matches a
+         string delimited by any of the delimiters specified (see new
+         entry in Balanced.pod).
+       - Added test.pl
 
+1.36   Tue Jul 14 12:26:04 1998
+       - Reinstated POD file missing from previous distribution
+       - Added undocumented fourth parameter to extract_codeblock
+         so as to correctly handle (?) and (s?) modifiers in
+         RecDescent grammars.
 
-1.99.1  Thu Nov 16 09:29:14 2006
+1.35   Wed Jun 24 09:53:31 1998
+       - fixed handling of :: quantifiers in extract_variable()
+       - numerous trivial lexical changes to make xemacs happy
 
-    - Included dependency on version.pm (thanks Andy)
+1.24
+       - changed behaviour in scalar contexts. Scalar contexts
+         now return the extracted string _and_ remove it from the
+         first argument (or $_).
+       - changed return values on failure (all contexts return undef
+         for invalid return fields)
+       - fixed some lurking bugs with trailing modifier handling
+       - added :ALL tag to simplify wholesale importing of functions
+       - fixed serious bug with embedded division operators ("/")
+         This now also allows the ?...? form of pattern matching!
 
+1.23   Fri Oct 17 10:26:38 EST 1997
+       - changed behaviour in scalar and void contexts. Scalar contexts
+         now return only the extracted string. Void contexts now remove
+         the extracted string from the first argument (or $_).
 
+1.21   Sat Oct  4 17:21:54 EST 1997
+       - synchronised with Parse::RecDescent distribution (version number
+         will now reflect that package)
 
-2.0.0  Wed Dec 20 10:50:24 2006
+1.10   Tue Sep 30 17:23:23 EST 1997
+       - reworked extract_quotelike to correct handling of some obscure cases
 
-    - Added patches from bleadperl version (thanks Rafael!)
+1.01   Mon Sep  8 18:09:18 EST 1997
+       - changed "quotemeta" to "quotemeta $_" to work
+         around bug in Perl 5.002 and 5.003
 
-    - Fixed bug in second bracketed delimiters (thanks David)
+1.00   Mon Aug 11 12:42:56 1997
+       - original version
index 386bd5a..f5f48ed 100644 (file)
-Text::Balanced version 2.0.0
-
+NAME
     Text::Balanced - Extract delimited text sequences from strings.
 
-SUMMARY
+SYNOPSIS
+     use Text::Balanced qw (
+                            extract_delimited
+                            extract_bracketed
+                            extract_quotelike
+                            extract_codeblock
+                            extract_variable
+                            extract_tagged
+                            extract_multiple
+                            gen_delimited_pat
+                            gen_extract_tagged
+                           );
+
+     # Extract the initial substring of $text that is delimited by
+     # two (unescaped) instances of the first character in $delim.
+
+            ($extracted, $remainder) = extract_delimited($text,$delim);
+
+
+     # Extract the initial substring of $text that is bracketed
+     # with a delimiter(s) specified by $delim (where the string
+     # in $delim contains one or more of '(){}[]<>').
+
+            ($extracted, $remainder) = extract_bracketed($text,$delim);
+
+
+     # Extract the initial substring of $text that is bounded by
+     # an XML tag.
+
+            ($extracted, $remainder) = extract_tagged($text);
+
+
+     # Extract the initial substring of $text that is bounded by
+     # a C<BEGIN>...C<END> pair. Don't allow nested C<BEGIN> tags
+
+            ($extracted, $remainder) =
+                    extract_tagged($text,"BEGIN","END",undef,{bad=>["BEGIN"]});
+
+
+     # Extract the initial substring of $text that represents a
+     # Perl "quote or quote-like operation"
+
+            ($extracted, $remainder) = extract_quotelike($text);
+
+
+     # Extract the initial substring of $text that represents a block
+     # of Perl code, bracketed by any of character(s) specified by $delim
+     # (where the string $delim contains one or more of '(){}[]<>').
+
+            ($extracted, $remainder) = extract_codeblock($text,$delim);
+
+
+     # Extract the initial substrings of $text that would be extracted by
+     # one or more sequential applications of the specified functions
+     # or regular expressions
+
+            @extracted = extract_multiple($text,
+                                          [ \&extract_bracketed,
+                                            \&extract_quotelike,
+                                            \&some_other_extractor_sub,
+                                            qr/[xyz]*/,
+                                            'literal',
+                                          ]);
+
+    # Create a string representing an optimized pattern (a la Friedl) # that
+    matches a substring delimited by any of the specified characters # (in
+    this case: any type of quote or a slash)
+
+            $patstring = gen_delimited_pat(q{'"`/});
+
+    # Generate a reference to an anonymous sub that is just like
+    extract_tagged # but pre-compiled and optimized for a specific pair of
+    tags, and consequently # much faster (i.e. 3 times faster). It uses qr//
+    for better performance on # repeated calls, so it only works under Perl
+    5.005 or later.
+
+            $extract_head = gen_extract_tagged('<HEAD>','</HEAD>');
+
+            ($extracted, $remainder) = $extract_head->($text);
+
+DESCRIPTION
+    The various "extract_..." subroutines may be used to extract a delimited
+    substring, possibly after skipping a specified prefix string. By
+    default, that prefix is optional whitespace ("/\s*/"), but you can
+    change it to whatever you wish (see below).
+
+    The substring to be extracted must appear at the current "pos" location
+    of the string's variable (or at index zero, if no "pos" position is
+    defined). In other words, the "extract_..." subroutines *don't* extract
+    the first occurrence of a substring anywhere in a string (like an
+    unanchored regex would). Rather, they extract an occurrence of the
+    substring appearing immediately at the current matching position in the
+    string (like a "\G"-anchored regex would).
+
+  General behaviour in list contexts
+    In a list context, all the subroutines return a list, the first three
+    elements of which are always:
+
+    [0] The extracted string, including the specified delimiters. If the
+        extraction fails "undef" is returned.
+
+    [1] The remainder of the input string (i.e. the characters after the
+        extracted string). On failure, the entire string is returned.
+
+    [2] The skipped prefix (i.e. the characters before the extracted
+        string). On failure, "undef" is returned.
+
+    Note that in a list context, the contents of the original input text
+    (the first argument) are not modified in any way.
+
+    However, if the input text was passed in a variable, that variable's
+    "pos" value is updated to point at the first character after the
+    extracted text. That means that in a list context the various
+    subroutines can be used much like regular expressions. For example:
+
+            while ( $next = (extract_quotelike($text))[0] )
+            {
+                    # process next quote-like (in $next)
+            }
+
+  General behaviour in scalar and void contexts
+    In a scalar context, the extracted string is returned, having first been
+    removed from the input text. Thus, the following code also processes
+    each quote-like operation, but actually removes them from $text:
+
+            while ( $next = extract_quotelike($text) )
+            {
+                    # process next quote-like (in $next)
+            }
+
+    Note that if the input text is a read-only string (i.e. a literal), no
+    attempt is made to remove the extracted text.
+
+    In a void context the behaviour of the extraction subroutines is exactly
+    the same as in a scalar context, except (of course) that the extracted
+    substring is not returned.
+
+  A note about prefixes
+    Prefix patterns are matched without any trailing modifiers ("/gimsox"
+    etc.) This can bite you if you're expecting a prefix specification like
+    '.*?(?=<H1>)' to skip everything up to the first <H1> tag. Such a prefix
+    pattern will only succeed if the <H1> tag is on the current line, since
+    . normally doesn't match newlines.
+
+    To overcome this limitation, you need to turn on /s matching within the
+    prefix pattern, using the "(?s)" directive: '(?s).*?(?=<H1>)'
+
+  "extract_delimited"
+    The "extract_delimited" function formalizes the common idiom of
+    extracting a single-character-delimited substring from the start of a
+    string. For example, to extract a single-quote delimited string, the
+    following code is typically used:
+
+            ($remainder = $text) =~ s/\A('(\\.|[^'])*')//s;
+            $extracted = $1;
+
+    but with "extract_delimited" it can be simplified to:
+
+            ($extracted,$remainder) = extract_delimited($text, "'");
+
+    "extract_delimited" takes up to four scalars (the input text, the
+    delimiters, a prefix pattern to be skipped, and any escape characters)
+    and extracts the initial substring of the text that is appropriately
+    delimited. If the delimiter string has multiple characters, the first
+    one encountered in the text is taken to delimit the substring. The third
+    argument specifies a prefix pattern that is to be skipped (but must be
+    present!) before the substring is extracted. The final argument
+    specifies the escape character to be used for each delimiter.
+
+    All arguments are optional. If the escape characters are not specified,
+    every delimiter is escaped with a backslash ("\"). If the prefix is not
+    specified, the pattern '\s*' - optional whitespace - is used. If the
+    delimiter set is also not specified, the set "/["'`]/" is used. If the
+    text to be processed is not specified either, $_ is used.
+
+    In list context, "extract_delimited" returns a array of three elements,
+    the extracted substring (*including the surrounding delimiters*), the
+    remainder of the text, and the skipped prefix (if any). If a suitable
+    delimited substring is not found, the first element of the array is the
+    empty string, the second is the complete original text, and the prefix
+    returned in the third element is an empty string.
+
+    In a scalar context, just the extracted substring is returned. In a void
+    context, the extracted substring (and any prefix) are simply removed
+    from the beginning of the first argument.
+
+    Examples:
+
+            # Remove a single-quoted substring from the very beginning of $text:
+
+                    $substring = extract_delimited($text, "'", '');
+
+            # Remove a single-quoted Pascalish substring (i.e. one in which
+            # doubling the quote character escapes it) from the very
+            # beginning of $text:
+
+                    $substring = extract_delimited($text, "'", '', "'");
+
+            # Extract a single- or double- quoted substring from the
+            # beginning of $text, optionally after some whitespace
+            # (note the list context to protect $text from modification):
+
+                    ($substring) = extract_delimited $text, q{"'};
+
+            # Delete the substring delimited by the first '/' in $text:
+
+                    $text = join '', (extract_delimited($text,'/','[^/]*')[2,1];
+
+    Note that this last example is *not* the same as deleting the first
+    quote-like pattern. For instance, if $text contained the string:
+
+            "if ('./cmd' =~ m/$UNIXCMD/s) { $cmd = $1; }"
+
+    then after the deletion it would contain:
+
+            "if ('.$UNIXCMD/s) { $cmd = $1; }"
+
+    not:
+
+            "if ('./cmd' =~ ms) { $cmd = $1; }"
+
+    See "extract_quotelike" for a (partial) solution to this problem.
+
+  "extract_bracketed"
+    Like "extract_delimited", the "extract_bracketed" function takes up to
+    three optional scalar arguments: a string to extract from, a delimiter
+    specifier, and a prefix pattern. As before, a missing prefix defaults to
+    optional whitespace and a missing text defaults to $_. However, a
+    missing delimiter specifier defaults to '{}()[]<>' (see below).
+
+    "extract_bracketed" extracts a balanced-bracket-delimited substring
+    (using any one (or more) of the user-specified delimiter brackets:
+    '(..)', '{..}', '[..]', or '<..>'). Optionally it will also respect
+    quoted unbalanced brackets (see below).
+
+    A "delimiter bracket" is a bracket in list of delimiters passed as
+    "extract_bracketed"'s second argument. Delimiter brackets are specified
+    by giving either the left or right (or both!) versions of the required
+    bracket(s). Note that the order in which two or more delimiter brackets
+    are specified is not significant.
+
+    A "balanced-bracket-delimited substring" is a substring bounded by
+    matched brackets, such that any other (left or right) delimiter bracket
+    *within* the substring is also matched by an opposite (right or left)
+    delimiter bracket *at the same level of nesting*. Any type of bracket
+    not in the delimiter list is treated as an ordinary character.
+
+    In other words, each type of bracket specified as a delimiter must be
+    balanced and correctly nested within the substring, and any other kind
+    of ("non-delimiter") bracket in the substring is ignored.
+
+    For example, given the string:
+
+            $text = "{ an '[irregularly :-(] {} parenthesized >:-)' string }";
+
+    then a call to "extract_bracketed" in a list context:
+
+            @result = extract_bracketed( $text, '{}' );
+
+    would return:
+
+            ( "{ an '[irregularly :-(] {} parenthesized >:-)' string }" , "" , "" )
+
+    since both sets of '{..}' brackets are properly nested and evenly
+    balanced. (In a scalar context just the first element of the array would
+    be returned. In a void context, $text would be replaced by an empty
+    string.)
+
+    Likewise the call in:
+
+            @result = extract_bracketed( $text, '{[' );
+
+    would return the same result, since all sets of both types of specified
+    delimiter brackets are correctly nested and balanced.
+
+    However, the call in:
+
+            @result = extract_bracketed( $text, '{([<' );
+
+    would fail, returning:
+
+            ( undef , "{ an '[irregularly :-(] {} parenthesized >:-)' string }"  );
+
+    because the embedded pairs of '(..)'s and '[..]'s are "cross-nested" and
+    the embedded '>' is unbalanced. (In a scalar context, this call would
+    return an empty string. In a void context, $text would be unchanged.)
+
+    Note that the embedded single-quotes in the string don't help in this
+    case, since they have not been specified as acceptable delimiters and
+    are therefore treated as non-delimiter characters (and ignored).
+
+    However, if a particular species of quote character is included in the
+    delimiter specification, then that type of quote will be correctly
+    handled. for example, if $text is:
+
+            $text = '<A HREF=">>>>">link</A>';
+
+    then
+
+            @result = extract_bracketed( $text, '<">' );
+
+    returns:
+
+            ( '<A HREF=">>>>">', 'link</A>', "" )
+
+    as expected. Without the specification of """ as an embedded quoter:
+
+            @result = extract_bracketed( $text, '<>' );
+
+    the result would be:
+
+            ( '<A HREF=">', '>>>">link</A>', "" )
+
+    In addition to the quote delimiters "'", """, and "`", full Perl
+    quote-like quoting (i.e. q{string}, qq{string}, etc) can be specified by
+    including the letter 'q' as a delimiter. Hence:
+
+            @result = extract_bracketed( $text, '<q>' );
+
+    would correctly match something like this:
+
+            $text = '<leftop: conj /and/ conj>';
+
+    See also: "extract_quotelike" and "extract_codeblock".
+
+  "extract_variable"
+    "extract_variable" extracts any valid Perl variable or variable-involved
+    expression, including scalars, arrays, hashes, array accesses, hash
+    look-ups, method calls through objects, subroutine calls through
+    subroutine references, etc.
+
+    The subroutine takes up to two optional arguments:
+
+    1.  A string to be processed ($_ if the string is omitted or "undef")
+
+    2.  A string specifying a pattern to be matched as a prefix (which is to
+        be skipped). If omitted, optional whitespace is skipped.
+
+    On success in a list context, an array of 3 elements is returned. The
+    elements are:
+
+    [0] the extracted variable, or variablish expression
+
+    [1] the remainder of the input text,
+
+    [2] the prefix substring (if any),
+
+    On failure, all of these values (except the remaining text) are "undef".
+
+    In a scalar context, "extract_variable" returns just the complete
+    substring that matched a variablish expression. "undef" is returned on
+    failure. In addition, the original input text has the returned substring
+    (and any prefix) removed from it.
+
+    In a void context, the input text just has the matched substring (and
+    any specified prefix) removed.
+
+  "extract_tagged"
+    "extract_tagged" extracts and segments text between (balanced) specified
+    tags.
+
+    The subroutine takes up to five optional arguments:
+
+    1.  A string to be processed ($_ if the string is omitted or "undef")
+
+    2.  A string specifying a pattern to be matched as the opening tag. If
+        the pattern string is omitted (or "undef") then a pattern that
+        matches any standard XML tag is used.
+
+    3.  A string specifying a pattern to be matched at the closing tag. If
+        the pattern string is omitted (or "undef") then the closing tag is
+        constructed by inserting a "/" after any leading bracket characters
+        in the actual opening tag that was matched (*not* the pattern that
+        matched the tag). For example, if the opening tag pattern is
+        specified as '{{\w+}}' and actually matched the opening tag
+        "{{DATA}}", then the constructed closing tag would be "{{/DATA}}".
+
+    4.  A string specifying a pattern to be matched as a prefix (which is to
+        be skipped). If omitted, optional whitespace is skipped.
+
+    5.  A hash reference containing various parsing options (see below)
+
+    The various options that can be specified are:
+
+    "reject => $listref"
+        The list reference contains one or more strings specifying patterns
+        that must *not* appear within the tagged text.
+
+        For example, to extract an HTML link (which should not contain
+        nested links) use:
+
+                extract_tagged($text, '<A>', '</A>', undef, {reject => ['<A>']} );
+
+    "ignore => $listref"
+        The list reference contains one or more strings specifying patterns
+        that are *not* be be treated as nested tags within the tagged text
+        (even if they would match the start tag pattern).
+
+        For example, to extract an arbitrary XML tag, but ignore "empty"
+        elements:
+
+                extract_tagged($text, undef, undef, undef, {ignore => ['<[^>]*/>']} );
+
+        (also see "gen_delimited_pat" below).
+
+    "fail => $str"
+        The "fail" option indicates the action to be taken if a matching end
+        tag is not encountered (i.e. before the end of the string or some
+        "reject" pattern matches). By default, a failure to match a closing
+        tag causes "extract_tagged" to immediately fail.
+
+        However, if the string value associated with <reject> is "MAX", then
+        "extract_tagged" returns the complete text up to the point of
+        failure. If the string is "PARA", "extract_tagged" returns only the
+        first paragraph after the tag (up to the first line that is either
+        empty or contains only whitespace characters). If the string is "",
+        the the default behaviour (i.e. failure) is reinstated.
+
+        For example, suppose the start tag "/para" introduces a paragraph,
+        which then continues until the next "/endpara" tag or until another
+        "/para" tag is encountered:
+
+                $text = "/para line 1\n\nline 3\n/para line 4";
+
+                extract_tagged($text, '/para', '/endpara', undef,
+                                        {reject => '/para', fail => MAX );
+
+                # EXTRACTED: "/para line 1\n\nline 3\n"
+
+        Suppose instead, that if no matching "/endpara" tag is found, the
+        "/para" tag refers only to the immediately following paragraph:
+
+                $text = "/para line 1\n\nline 3\n/para line 4";
+
+                extract_tagged($text, '/para', '/endpara', undef,
+                                {reject => '/para', fail => MAX );
+
+                # EXTRACTED: "/para line 1\n"
+
+        Note that the specified "fail" behaviour applies to nested tags as
+        well.
+
+    On success in a list context, an array of 6 elements is returned. The
+    elements are:
+
+    [0] the extracted tagged substring (including the outermost tags),
+
+    [1] the remainder of the input text,
+
+    [2] the prefix substring (if any),
+
+    [3] the opening tag
+
+    [4] the text between the opening and closing tags
+
+    [5] the closing tag (or "" if no closing tag was found)
+
+    On failure, all of these values (except the remaining text) are "undef".
+
+    In a scalar context, "extract_tagged" returns just the complete
+    substring that matched a tagged text (including the start and end tags).
+    "undef" is returned on failure. In addition, the original input text has
+    the returned substring (and any prefix) removed from it.
+
+    In a void context, the input text just has the matched substring (and
+    any specified prefix) removed.
+
+  "gen_extract_tagged"
+    (Note: This subroutine is only available under Perl5.005)
+
+    "gen_extract_tagged" generates a new anonymous subroutine which extracts
+    text between (balanced) specified tags. In other words, it generates a
+    function identical in function to "extract_tagged".
+
+    The difference between "extract_tagged" and the anonymous subroutines
+    generated by "gen_extract_tagged", is that those generated subroutines:
+
+    *   do not have to reparse tag specification or parsing options every
+        time they are called (whereas "extract_tagged" has to effectively
+        rebuild its tag parser on every call);
+
+    *   make use of the new qr// construct to pre-compile the regexes they
+        use (whereas "extract_tagged" uses standard string variable
+        interpolation to create tag-matching patterns).
+
+    The subroutine takes up to four optional arguments (the same set as
+    "extract_tagged" except for the string to be processed). It returns a
+    reference to a subroutine which in turn takes a single argument (the
+    text to be extracted from).
+
+    In other words, the implementation of "extract_tagged" is exactly
+    equivalent to:
+
+            sub extract_tagged
+            {
+                    my $text = shift;
+                    $extractor = gen_extract_tagged(@_);
+                    return $extractor->($text);
+            }
+
+    (although "extract_tagged" is not currently implemented that way, in
+    order to preserve pre-5.005 compatibility).
+
+    Using "gen_extract_tagged" to create extraction functions for specific
+    tags is a good idea if those functions are going to be called more than
+    once, since their performance is typically twice as good as the more
+    general-purpose "extract_tagged".
+
+  "extract_quotelike"
+    "extract_quotelike" attempts to recognize, extract, and segment any one
+    of the various Perl quotes and quotelike operators (see perlop(3))
+    Nested backslashed delimiters, embedded balanced bracket delimiters (for
+    the quotelike operators), and trailing modifiers are all caught. For
+    example, in:
+
+            extract_quotelike 'q # an octothorpe: \# (not the end of the q!) #'
+            
+        extract_quotelike '  "You said, \"Use sed\"."  '
+
+            extract_quotelike ' s{([A-Z]{1,8}\.[A-Z]{3})} /\L$1\E/; '
+
+            extract_quotelike ' tr/\\\/\\\\/\\\//ds; '
+
+    the full Perl quotelike operations are all extracted correctly.
+
+    Note too that, when using the /x modifier on a regex, any comment
+    containing the current pattern delimiter will cause the regex to be
+    immediately terminated. In other words:
+
+            'm /
+                    (?i)            # CASE INSENSITIVE
+                    [a-z_]          # LEADING ALPHABETIC/UNDERSCORE
+                    [a-z0-9]*       # FOLLOWED BY ANY NUMBER OF ALPHANUMERICS
+               /x'
+
+    will be extracted as if it were:
+
+            'm /
+                    (?i)            # CASE INSENSITIVE
+                    [a-z_]          # LEADING ALPHABETIC/'
+
+    This behaviour is identical to that of the actual compiler.
+
+    "extract_quotelike" takes two arguments: the text to be processed and a
+    prefix to be matched at the very beginning of the text. If no prefix is
+    specified, optional whitespace is the default. If no text is given, $_
+    is used.
+
+    In a list context, an array of 11 elements is returned. The elements
+    are:
+
+    [0] the extracted quotelike substring (including trailing modifiers),
+
+    [1] the remainder of the input text,
+
+    [2] the prefix substring (if any),
+
+    [3] the name of the quotelike operator (if any),
+
+    [4] the left delimiter of the first block of the operation,
+
+    [5] the text of the first block of the operation (that is, the contents
+        of a quote, the regex of a match or substitution or the target list
+        of a translation),
+
+    [6] the right delimiter of the first block of the operation,
+
+    [7] the left delimiter of the second block of the operation (that is, if
+        it is a "s", "tr", or "y"),
+
+    [8] the text of the second block of the operation (that is, the
+        replacement of a substitution or the translation list of a
+        translation),
+
+    [9] the right delimiter of the second block of the operation (if any),
+
+    [10]
+        the trailing modifiers on the operation (if any).
+
+    For each of the fields marked "(if any)" the default value on success is
+    an empty string. On failure, all of these values (except the remaining
+    text) are "undef".
+
+    In a scalar context, "extract_quotelike" returns just the complete
+    substring that matched a quotelike operation (or "undef" on failure). In
+    a scalar or void context, the input text has the same substring (and any
+    specified prefix) removed.
+
+    Examples:
+
+            # Remove the first quotelike literal that appears in text
+
+                    $quotelike = extract_quotelike($text,'.*?');
+
+            # Replace one or more leading whitespace-separated quotelike
+            # literals in $_ with "<QLL>"
+
+                    do { $_ = join '<QLL>', (extract_quotelike)[2,1] } until $@;
+
+
+            # Isolate the search pattern in a quotelike operation from $text
+
+                    ($op,$pat) = (extract_quotelike $text)[3,5];
+                    if ($op =~ /[ms]/)
+                    {
+                            print "search pattern: $pat\n";
+                    }
+                    else
+                    {
+                            print "$op is not a pattern matching operation\n";
+                    }
+
+  "extract_quotelike" and "here documents"
+    "extract_quotelike" can successfully extract "here documents" from an
+    input string, but with an important caveat in list contexts.
+
+    Unlike other types of quote-like literals, a here document is rarely a
+    contiguous substring. For example, a typical piece of code using here
+    document might look like this:
+
+            <<'EOMSG' || die;
+            This is the message.
+            EOMSG
+            exit;
+
+    Given this as an input string in a scalar context, "extract_quotelike"
+    would correctly return the string "<<'EOMSG'\nThis is the
+    message.\nEOMSG", leaving the string " || die;\nexit;" in the original
+    variable. In other words, the two separate pieces of the here document
+    are successfully extracted and concatenated.
+
+    In a list context, "extract_quotelike" would return the list
+
+    [0] "<<'EOMSG'\nThis is the message.\nEOMSG\n" (i.e. the full extracted
+        here document, including fore and aft delimiters),
+
+    [1] " || die;\nexit;" (i.e. the remainder of the input text,
+        concatenated),
+
+    [2] "" (i.e. the prefix substring -- trivial in this case),
+
+    [3] "<<" (i.e. the "name" of the quotelike operator)
+
+    [4] "'EOMSG'" (i.e. the left delimiter of the here document, including
+        any quotes),
+
+    [5] "This is the message.\n" (i.e. the text of the here document),
+
+    [6] "EOMSG" (i.e. the right delimiter of the here document),
+
+    [7..10]
+        "" (a here document has no second left delimiter, second text,
+        second right delimiter, or trailing modifiers).
+
+    However, the matching position of the input variable would be set to
+    "exit;" (i.e. *after* the closing delimiter of the here document), which
+    would cause the earlier " || die;\nexit;" to be skipped in any sequence
+    of code fragment extractions.
+
+    To avoid this problem, when it encounters a here document whilst
+    extracting from a modifiable string, "extract_quotelike" silently
+    rearranges the string to an equivalent piece of Perl:
+
+            <<'EOMSG'
+            This is the message.
+            EOMSG
+            || die;
+            exit;
+
+    in which the here document *is* contiguous. It still leaves the matching
+    position after the here document, but now the rest of the line on which
+    the here document starts is not skipped.
+
+    To prevent <extract_quotelike> from mucking about with the input in this
+    way (this is the only case where a list-context "extract_quotelike" does
+    so), you can pass the input variable as an interpolated literal:
+
+            $quotelike = extract_quotelike("$var");
+
+  "extract_codeblock"
+    "extract_codeblock" attempts to recognize and extract a balanced bracket
+    delimited substring that may contain unbalanced brackets inside Perl
+    quotes or quotelike operations. That is, "extract_codeblock" is like a
+    combination of "extract_bracketed" and "extract_quotelike".
+
+    "extract_codeblock" takes the same initial three parameters as
+    "extract_bracketed": a text to process, a set of delimiter brackets to
+    look for, and a prefix to match first. It also takes an optional fourth
+    parameter, which allows the outermost delimiter brackets to be specified
+    separately (see below).
+
+    Omitting the first argument (input text) means process $_ instead.
+    Omitting the second argument (delimiter brackets) indicates that only
+    '{' is to be used. Omitting the third argument (prefix argument) implies
+    optional whitespace at the start. Omitting the fourth argument
+    (outermost delimiter brackets) indicates that the value of the second
+    argument is to be used for the outermost delimiters.
+
+    Once the prefix an dthe outermost opening delimiter bracket have been
+    recognized, code blocks are extracted by stepping through the input text
+    and trying the following alternatives in sequence:
+
+    1.  Try and match a closing delimiter bracket. If the bracket was the
+        same species as the last opening bracket, return the substring to
+        that point. If the bracket was mismatched, return an error.
+
+    2.  Try to match a quote or quotelike operator. If found, call
+        "extract_quotelike" to eat it. If "extract_quotelike" fails, return
+        the error it returned. Otherwise go back to step 1.
+
+    3.  Try to match an opening delimiter bracket. If found, call
+        "extract_codeblock" recursively to eat the embedded block. If the
+        recursive call fails, return an error. Otherwise, go back to step 1.
+
+    4.  Unconditionally match a bareword or any other single character, and
+        then go back to step 1.
+
+    Examples:
+
+            # Find a while loop in the text
+
+                    if ($text =~ s/.*?while\s*\{/{/)
+                    {
+                            $loop = "while " . extract_codeblock($text);
+                    }
+
+            # Remove the first round-bracketed list (which may include
+            # round- or curly-bracketed code blocks or quotelike operators)
+
+                    extract_codeblock $text, "(){}", '[^(]*';
+
+    The ability to specify a different outermost delimiter bracket is useful
+    in some circumstances. For example, in the Parse::RecDescent module,
+    parser actions which are to be performed only on a successful parse are
+    specified using a "<defer:...>" directive. For example:
+
+            sentence: subject verb object
+                            <defer: {$::theVerb = $item{verb}} >
+
+    Parse::RecDescent uses "extract_codeblock($text, '{}<>')" to extract the
+    code within the "<defer:...>" directive, but there's a problem.
+
+    A deferred action like this:
+
+                            <defer: {if ($count>10) {$count--}} >
+
+    will be incorrectly parsed as:
+
+                            <defer: {if ($count>
+
+    because the "less than" operator is interpreted as a closing delimiter.
+
+    But, by extracting the directive using
+    "extract_codeblock($text, '{}', undef, '<>')" the '>' character is only
+    treated as a delimited at the outermost level of the code block, so the
+    directive is parsed correctly.
+
+  "extract_multiple"
+    The "extract_multiple" subroutine takes a string to be processed and a
+    list of extractors (subroutines or regular expressions) to apply to that
+    string.
+
+    In an array context "extract_multiple" returns an array of substrings of
+    the original string, as extracted by the specified extractors. In a
+    scalar context, "extract_multiple" returns the first substring
+    successfully extracted from the original string. In both scalar and void
+    contexts the original string has the first successfully extracted
+    substring removed from it. In all contexts "extract_multiple" starts at
+    the current "pos" of the string, and sets that "pos" appropriately after
+    it matches.
+
+    Hence, the aim of of a call to "extract_multiple" in a list context is
+    to split the processed string into as many non-overlapping fields as
+    possible, by repeatedly applying each of the specified extractors to the
+    remainder of the string. Thus "extract_multiple" is a generalized form
+    of Perl's "split" subroutine.
+
+    The subroutine takes up to four optional arguments:
+
+    1.  A string to be processed ($_ if the string is omitted or "undef")
+
+    2.  A reference to a list of subroutine references and/or qr// objects
+        and/or literal strings and/or hash references, specifying the
+        extractors to be used to split the string. If this argument is
+        omitted (or "undef") the list:
+
+                [
+                        sub { extract_variable($_[0], '') },
+                        sub { extract_quotelike($_[0],'') },
+                        sub { extract_codeblock($_[0],'{}','') },
+                ]
+
+        is used.
+
+    3.  An number specifying the maximum number of fields to return. If this
+        argument is omitted (or "undef"), split continues as long as
+        possible.
+
+        If the third argument is *N*, then extraction continues until *N*
+        fields have been successfully extracted, or until the string has
+        been completely processed.
+
+        Note that in scalar and void contexts the value of this argument is
+        automatically reset to 1 (under "-w", a warning is issued if the
+        argument has to be reset).
+
+    4.  A value indicating whether unmatched substrings (see below) within
+        the text should be skipped or returned as fields. If the value is
+        true, such substrings are skipped. Otherwise, they are returned.
+
+    The extraction process works by applying each extractor in sequence to
+    the text string.
+
+    If the extractor is a subroutine it is called in a list context and is
+    expected to return a list of a single element, namely the extracted
+    text. It may optionally also return two further arguments: a string
+    representing the text left after extraction (like $' for a pattern
+    match), and a string representing any prefix skipped before the
+    extraction (like $` in a pattern match). Note that this is designed to
+    facilitate the use of other Text::Balanced subroutines with
+    "extract_multiple". Note too that the value returned by an extractor
+    subroutine need not bear any relationship to the corresponding substring
+    of the original text (see examples below).
+
+    If the extractor is a precompiled regular expression or a string, it is
+    matched against the text in a scalar context with a leading '\G' and the
+    gc modifiers enabled. The extracted value is either $1 if that variable
+    is defined after the match, or else the complete match (i.e. $&).
+
+    If the extractor is a hash reference, it must contain exactly one
+    element. The value of that element is one of the above extractor types
+    (subroutine reference, regular expression, or string). The key of that
+    element is the name of a class into which the successful return value of
+    the extractor will be blessed.
+
+    If an extractor returns a defined value, that value is immediately
+    treated as the next extracted field and pushed onto the list of fields.
+    If the extractor was specified in a hash reference, the field is also
+    blessed into the appropriate class,
+
+    If the extractor fails to match (in the case of a regex extractor), or
+    returns an empty list or an undefined value (in the case of a subroutine
+    extractor), it is assumed to have failed to extract. If none of the
+    extractor subroutines succeeds, then one character is extracted from the
+    start of the text and the extraction subroutines reapplied. Characters
+    which are thus removed are accumulated and eventually become the next
+    field (unless the fourth argument is true, in which case they are
+    discarded).
+
+    For example, the following extracts substrings that are valid Perl
+    variables:
+
+            @fields = extract_multiple($text,
+                                       [ sub { extract_variable($_[0]) } ],
+                                       undef, 1);
+
+    This example separates a text into fields which are quote delimited,
+    curly bracketed, and anything else. The delimited and bracketed parts
+    are also blessed to identify them (the "anything else" is unblessed):
+
+            @fields = extract_multiple($text,
+                       [
+                            { Delim => sub { extract_delimited($_[0],q{'"}) } },
+                            { Brack => sub { extract_bracketed($_[0],'{}') } },
+                       ]);
+
+    This call extracts the next single substring that is a valid Perl
+    quotelike operator (and removes it from $text):
+
+            $quotelike = extract_multiple($text,
+                                          [
+                                            sub { extract_quotelike($_[0]) },
+                                          ], undef, 1);
+
+    Finally, here is yet another way to do comma-separated value parsing:
+
+            @fields = extract_multiple($csv_text,
+                                      [
+                                            sub { extract_delimited($_[0],q{'"}) },
+                                            qr/([^,]+)(.*)/,
+                                      ],
+                                      undef,1);
+
+    The list in the second argument means: *"Try and extract a ' or "
+    delimited string, otherwise extract anything up to a comma..."*. The
+    undef third argument means: *"...as many times as possible..."*, and the
+    true value in the fourth argument means *"...discarding anything else
+    that appears (i.e. the commas)"*.
+
+    If you wanted the commas preserved as separate fields (i.e. like split
+    does if your split pattern has capturing parentheses), you would just
+    make the last parameter undefined (or remove it).
+
+  "gen_delimited_pat"
+    The "gen_delimited_pat" subroutine takes a single (string) argument and
+    > builds a Friedl-style optimized regex that matches a string delimited
+    by any one of the characters in the single argument. For example:
+
+            gen_delimited_pat(q{'"})
+
+    returns the regex:
+
+            (?:\"(?:\\\"|(?!\").)*\"|\'(?:\\\'|(?!\').)*\')
+
+    Note that the specified delimiters are automatically quotemeta'd.
+
+    A typical use of "gen_delimited_pat" would be to build special purpose
+    tags for "extract_tagged". For example, to properly ignore "empty" XML
+    elements (which might contain quoted strings):
+
+            my $empty_tag = '<(' . gen_delimited_pat(q{'"}) . '|.)+/>';
+
+            extract_tagged($text, undef, undef, undef, {ignore => [$empty_tag]} );
+
+    "gen_delimited_pat" may also be called with an optional second argument,
+    which specifies the "escape" character(s) to be used for each delimiter.
+    For example to match a Pascal-style string (where ' is the delimiter and
+    '' is a literal ' within the string):
+
+            gen_delimited_pat(q{'},q{'});
+
+    Different escape characters can be specified for different delimiters.
+    For example, to specify that '/' is the escape for single quotes and '%'
+    is the escape for double quotes:
+
+            gen_delimited_pat(q{'"},q{/%});
+
+    If more delimiters than escape chars are specified, the last escape char
+    is used for the remaining delimiters. If no escape char is specified for
+    a given specified delimiter, '\' is used.
+
+  "delimited_pat"
+    Note that "gen_delimited_pat" was previously called "delimited_pat".
+    That name may still be used, but is now deprecated.
+
+DIAGNOSTICS
+    In a list context, all the functions return "(undef,$original_text)" on
+    failure. In a scalar context, failure is indicated by returning "undef"
+    (in this case the input text is not modified in any way).
+
+    In addition, on failure in *any* context, the $@ variable is set.
+    Accessing "$@->{error}" returns one of the error diagnostics listed
+    below. Accessing "$@->{pos}" returns the offset into the original string
+    at which the error was detected (although not necessarily where it
+    occurred!) Printing $@ directly produces the error message, with the
+    offset appended. On success, the $@ variable is guaranteed to be
+    "undef".
+
+    The available diagnostics are:
+
+    "Did not find a suitable bracket: "%s""
+        The delimiter provided to "extract_bracketed" was not one of
+        '()[]<>{}'.
+
+    "Did not find prefix: /%s/"
+        A non-optional prefix was specified but wasn't found at the start of
+        the text.
+
+    "Did not find opening bracket after prefix: "%s""
+        "extract_bracketed" or "extract_codeblock" was expecting a
+        particular kind of bracket at the start of the text, and didn't find
+        it.
+
+    "No quotelike operator found after prefix: "%s""
+        "extract_quotelike" didn't find one of the quotelike operators "q",
+        "qq", "qw", "qx", "s", "tr" or "y" at the start of the substring it
+        was extracting.
+
+    "Unmatched closing bracket: "%c""
+        "extract_bracketed", "extract_quotelike" or "extract_codeblock"
+        encountered a closing bracket where none was expected.
+
+    "Unmatched opening bracket(s): "%s""
+        "extract_bracketed", "extract_quotelike" or "extract_codeblock" ran
+        out of characters in the text before closing one or more levels of
+        nested brackets.
+
+    "Unmatched embedded quote (%s)"
+        "extract_bracketed" attempted to match an embedded quoted substring,
+        but failed to find a closing quote to match it.
+
+    "Did not find closing delimiter to match '%s'"
+        "extract_quotelike" was unable to find a closing delimiter to match
+        the one that opened the quote-like operation.
+
+    "Mismatched closing bracket: expected "%c" but found "%s""
+        "extract_bracketed", "extract_quotelike" or "extract_codeblock"
+        found a valid bracket delimiter, but it was the wrong species. This
+        usually indicates a nesting error, but may indicate incorrect
+        quoting or escaping.
+
+    "No block delimiter found after quotelike "%s""
+        "extract_quotelike" or "extract_codeblock" found one of the
+        quotelike operators "q", "qq", "qw", "qx", "s", "tr" or "y" without
+        a suitable block after it.
 
-    Text::Balanced::extract_delimited
-    
-        `extract_delimited' extracts the initial substring of a string
-        which is delimited by a user-specified set of single-character
-        delimiters, whilst ignoring any backslash-escaped delimiter
-        characters.
+    "Did not find leading dereferencer"
+        "extract_variable" was expecting one of '$', '@', or '%' at the
+        start of a variable, but didn't find any of them.
 
-    Text::Balanced::extract_bracketed
-    
-        `extract_bracketed' extracts a balanced-bracket-delimited substring
-        (using any one (or more) of the user-specified delimiter brackets:
-        '(..)', '{..}', '[..]', or '<..>').
-    
-    Text::Balanced::extract_quotelike
-    
-        `extract_quotelike' attempts to recognize and extract any one of the
-        various Perl quote and quotelike operators (see "perlop(3)"). Embedded
-        backslashed delimiters, nested bracket delimiters (for the
-        quotelike operators), and trailing modifiers are all correctly handled.
-    
-    Text::Balanced::extract_codeblock
-    
-        `extract_codeblock' attempts to recognize and extract a
-        balanced bracket-delimited substring which may also contain
-        unbalanced brackets inside Perl quotes or quotelike
-        operations. That is, `extract_codeblock' is like a combination
-        of `extract_bracketed' and `extract_quotelike'.
+    "Bad identifier after dereferencer"
+        "extract_variable" found a '$', '@', or '%' indicating a variable,
+        but that character was not followed by a legal Perl identifier.
 
-    Text::Balanced::extract_tagged
-    
-        `extract_tagged' attempts to recognize and extract a
-        substring between two arbitrary "tag" patterns (a start tag
-       and an end tag).
+    "Did not find expected opening bracket at %s"
+        "extract_codeblock" failed to find any of the outermost opening
+        brackets that were specified.
 
+    "Improperly nested codeblock at %s"
+        A nested code block was found that started with a delimiter that was
+        specified as being only to be used as an outermost bracket.
 
-INSTALLATION
+    "Missing second block for quotelike "%s""
+        "extract_codeblock" or "extract_quotelike" found one of the
+        quotelike operators "s", "tr" or "y" followed by only one block.
 
-To install this module, run the following commands:
+    "No match found for opening bracket"
+        "extract_codeblock" failed to find a closing bracket to match the
+        outermost opening bracket.
 
-    perl Makefile.PL
-    make
-    make test
-    make install
+    "Did not find opening tag: /%s/"
+        "extract_tagged" did not find a suitable opening tag (after any
+        specified prefix was removed).
 
+    "Unable to construct closing tag to match: /%s/"
+        "extract_tagged" matched the specified opening tag and tried to
+        modify the matched text to produce a matching closing tag (because
+        none was specified). It failed to generate the closing tag, almost
+        certainly because the opening tag did not start with a bracket of
+        some kind.
 
-Alternatively, to install with Module::Build, you can use the following commands:
+    "Found invalid nested tag: %s"
+        "extract_tagged" found a nested tag that appeared in the "reject"
+        list (and the failure mode was not "MAX" or "PARA").
 
-    perl Build.PL
-    ./Build
-    ./Build test
-    ./Build install
+    "Found unbalanced nested tag: %s"
+        "extract_tagged" found a nested opening tag that was not matched by
+        a corresponding nested closing tag (and the failure mode was not
+        "MAX" or "PARA").
 
+    "Did not find closing tag"
+        "extract_tagged" reached the end of the text without finding a
+        closing tag to match the original opening tag (and the failure mode
+        was not "MAX" or "PARA").
 
+AUTHOR
+    Damian Conway (damian@conway.org)
 
-DEPENDENCIES
+BUGS AND IRRITATIONS
+    There are undoubtedly serious bugs lurking somewhere in this code, if
+    only because parts of it give the impression of understanding a great
+    deal more about Perl than they really do.
 
-None.
+    Bug reports and other feedback are most welcome.
 
+COPYRIGHT
+    Copyright 1997 - 2001 Damian Conway. All Rights Reserved.
 
-COPYRIGHT AND LICENCE
+    Some (minor) parts copyright 2009 Adam Kennedy.
 
-Copyright (C) 2006, Damian Conway
+    This module is free software. It may be used, redistributed and/or
+    modified under the same terms as Perl itself.
 
-This library is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
index 16a559b..07d9567 100644 (file)
@@ -1,32 +1,32 @@
+package Text::Balanced;
+
 # EXTRACT VARIOUSLY DELIMITED TEXT SEQUENCES FROM STRINGS.
 # FOR FULL DOCUMENTATION SEE Balanced.pod
 
 use 5.005;
 use strict;
-
-package Text::Balanced;
-
-use Exporter;
+use Exporter ();
 use SelfLoader;
-use vars qw { $VERSION @ISA %EXPORT_TAGS };
-
-use version; $VERSION = qv('2.0.0');
-@ISA           = qw ( Exporter );
-                    
-%EXPORT_TAGS   = ( ALL => [ qw(
-                               &extract_delimited
-                               &extract_bracketed
-                               &extract_quotelike
-                               &extract_codeblock
-                               &extract_variable
-                               &extract_tagged
-                               &extract_multiple
 
-                               &gen_delimited_pat
-                               &gen_extract_tagged
-
-                               &delimited_pat
-                              ) ] );
+use vars qw { $VERSION @ISA %EXPORT_TAGS };
+BEGIN {
+       $VERSION     = '2.02';
+       @ISA         = 'Exporter';
+       %EXPORT_TAGS = (
+               ALL => [ qw{
+                       &extract_delimited
+                       &extract_bracketed
+                       &extract_quotelike
+                       &extract_codeblock
+                       &extract_variable
+                       &extract_tagged
+                       &extract_multiple
+                       &gen_delimited_pat
+                       &gen_extract_tagged
+                       &delimited_pat
+               } ],
+       );
+}
 
 Exporter::export_ok_tags('ALL');
 
@@ -41,46 +41,44 @@ sub _match_quotelike($$$$);
 
 sub _failmsg {
        my ($message, $pos) = @_;
-       $@ = bless { error=>$message, pos=>$pos }, "Text::Balanced::ErrorMsg";
+       $@ = bless {
+               error => $message,
+               pos   => $pos,
+       }, 'Text::Balanced::ErrorMsg';
 }
 
-sub _fail
-{
+sub _fail {
        my ($wantarray, $textref, $message, $pos) = @_;
        _failmsg $message, $pos if $message;
-       return (undef,$$textref,undef) if $wantarray;
+       return (undef, $$textref, undef) if $wantarray;
        return undef;
 }
 
-sub _succeed
-{
+sub _succeed {
        $@ = undef;
        my ($wantarray,$textref) = splice @_, 0, 2;
-       my ($extrapos, $extralen) = @_>18 ? splice(@_, -2, 2) : (0,0);
+       my ($extrapos, $extralen) = @_ > 18
+               ? splice(@_, -2, 2)
+               : (0, 0);
        my ($startlen, $oppos) = @_[5,6];
        my $remainderpos = $_[2];
-       if ($wantarray)
-       {
+       if ( $wantarray ) {
                my @res;
-               while (my ($from, $len) = splice @_, 0, 2)
-               {
-                       push @res, substr($$textref,$from,$len);
+               while (my ($from, $len) = splice @_, 0, 2) {
+                       push @res, substr($$textref, $from, $len);
                }
-               if ($extralen) {        # CORRECT FILLET
+               if ( $extralen ) { # CORRECT FILLET
                        my $extra = substr($res[0], $extrapos-$oppos, $extralen, "\n");
                        $res[1] = "$extra$res[1]";
                        eval { substr($$textref,$remainderpos,0) = $extra;
                               substr($$textref,$extrapos,$extralen,"\n")} ;
                                #REARRANGE HERE DOC AND FILLET IF POSSIBLE
                        pos($$textref) = $remainderpos-$extralen+1; # RESET \G
-               }
-               else {
+               } else {
                        pos($$textref) = $remainderpos;             # RESET \G
                }
                return @res;
-       }
-       else
-       {
+       } else {
                my $match = substr($$textref,$_[0],$_[1]);
                substr($match,$extrapos-$_[0]-$startlen,$extralen,"") if $extralen;
                my $extra = $extralen
@@ -120,7 +118,6 @@ sub gen_delimited_pat($;$)  # ($delimiters;$escapes)
 
 *delimited_pat = \&gen_delimited_pat;
 
-
 # THE EXTRACTION FUNCTIONS
 
 sub extract_delimited (;$$$$)
@@ -862,8 +859,7 @@ sub _match_quotelike($$$$)  # ($textref, $prepat, $allow_raw_match)
               );
 }
 
-my $def_func = 
-[
+my $def_func = [
        sub { extract_variable($_[0], '') },
        sub { extract_quotelike($_[0],'') },
        sub { extract_codeblock($_[0],'{}','') },
@@ -977,7 +973,6 @@ sub extract_multiple (;$$$$)        # ($text, $functions_ref, $max_fields, $ignoreunkno
        return $fields[0];
 }
 
-
 sub gen_extract_tagged # ($opentag, $closetag, $pre, \%options)
 {
        my $ldel    = $_[0];
@@ -1029,11 +1024,12 @@ use overload '""' => sub { "$_[0]->{error}, detected at offset $_[0]->{pos}" };
 
 __END__
 
+=pod
+
 =head1 NAME
 
 Text::Balanced - Extract delimited text sequences from strings.
 
-
 =head1 SYNOPSIS
 
  use Text::Balanced qw (
@@ -1044,7 +1040,6 @@ Text::Balanced - Extract delimited text sequences from strings.
                        extract_variable
                        extract_tagged
                        extract_multiple
-
                        gen_delimited_pat
                        gen_extract_tagged
                       );
@@ -1106,7 +1101,6 @@ Text::Balanced - Extract delimited text sequences from strings.
 
        $patstring = gen_delimited_pat(q{'"`/});
 
-
 # Generate a reference to an anonymous sub that is just like extract_tagged
 # but pre-compiled and optimized for a specific pair of tags, and consequently
 # much faster (i.e. 3 times faster). It uses qr// for better performance on
@@ -1116,7 +1110,6 @@ Text::Balanced - Extract delimited text sequences from strings.
 
        ($extracted, $remainder) = $extract_head->($text);
 
-
 =head1 DESCRIPTION
 
 The various C<extract_...> subroutines may be used to
@@ -1135,8 +1128,6 @@ they extract an occurrence of the substring appearing
 immediately at the current matching position in the
 string (like a C<\G>-anchored regex would).
 
-
-
 =head2 General behaviour in list contexts
 
 In a list context, all the subroutines return a list, the first three
@@ -1174,7 +1165,6 @@ subroutines can be used much like regular expressions. For example:
                # process next quote-like (in $next)
        }
 
-
 =head2 General behaviour in scalar and void contexts
 
 In a scalar context, the extracted string is returned, having first been
@@ -1204,7 +1194,6 @@ pattern will only succeed if the <H1> tag is on the current line, since
 To overcome this limitation, you need to turn on /s matching within
 the prefix pattern, using the C<(?s)> directive: '(?s).*?(?=<H1>)'
 
-
 =head2 C<extract_delimited>
 
 The C<extract_delimited> function formalizes the common idiom
@@ -1237,7 +1226,7 @@ pattern C<'\s*'> - optional whitespace - is used. If the delimiter set
 is also not specified, the set C</["'`]/> is used. If the text to be processed
 is not specified either, C<$_> is used.
 
-In list context, C<extract_delimited> returns an array of three
+In list context, C<extract_delimited> returns a array of three
 elements, the extracted substring (I<including the surrounding
 delimiters>), the remainder of the text, and the skipped prefix (if
 any). If a suitable delimited substring is not found, the first
@@ -1267,7 +1256,6 @@ Examples:
 
                ($substring) = extract_delimited $text, q{"'};
 
-
        # Delete the substring delimited by the first '/' in $text:
 
                $text = join '', (extract_delimited($text,'/','[^/]*')[2,1];
@@ -1285,10 +1273,8 @@ not:
 
        "if ('./cmd' =~ ms) { $cmd = $1; }"
        
-
 See L<"extract_quotelike"> for a (partial) solution to this problem.
 
-
 =head2 C<extract_bracketed>
 
 Like C<"extract_delimited">, the C<extract_bracketed> function takes
@@ -1392,7 +1378,6 @@ would correctly match something like this:
 
 See also: C<"extract_quotelike"> and C<"extract_codeblock">.
 
-
 =head2 C<extract_variable>
 
 C<extract_variable> extracts any valid Perl variable or
@@ -1511,7 +1496,6 @@ For example, to extract an arbitrary XML tag, but ignore "empty" elements:
 
 (also see L<"gen_delimited_pat"> below).
 
-
 =item C<fail =E<gt> $str>
 
 The C<fail> option indicates the action to be taken if a matching end
@@ -1591,7 +1575,6 @@ text has the returned substring (and any prefix) removed from it.
 In a void context, the input text just has the matched substring (and
 any specified prefix) removed.
 
-
 =head2 C<gen_extract_tagged>
 
 (Note: This subroutine is only available under Perl5.005)
@@ -1745,7 +1728,6 @@ For each of the fields marked "(if any)" the default value on success is
 an empty string.
 On failure, all of these values (except the remaining text) are C<undef>.
 
-
 In a scalar context, C<extract_quotelike> returns just the complete substring
 that matched a quotelike operation (or C<undef> on failure). In a scalar or
 void context, the input text has the same substring (and any specified
@@ -1775,7 +1757,6 @@ Examples:
                         print "$op is not a pattern matching operation\n";
                 }
 
-
 =head2 C<extract_quotelike> and "here documents"
 
 C<extract_quotelike> can successfully extract "here documents" from an input
@@ -1861,7 +1842,6 @@ you can pass the input variable as an interpolated literal:
 
         $quotelike = extract_quotelike("$var");
 
-
 =head2 C<extract_codeblock>
 
 C<extract_codeblock> attempts to recognize and extract a balanced
@@ -1912,7 +1892,6 @@ then go back to step 1.
 
 =back
 
-
 Examples:
 
         # Find a while loop in the text
@@ -1997,7 +1976,6 @@ C<undef>) the list:
 
 is used.
 
-
 =item 3.
 
 An number specifying the maximum number of fields to return. If this
@@ -2102,7 +2080,6 @@ If you wanted the commas preserved as separate fields (i.e. like split
 does if your split pattern has capturing parentheses), you would
 just make the last parameter undefined (or remove it).
 
-
 =head2 C<gen_delimited_pat>
 
 The C<gen_delimited_pat> subroutine takes a single (string) argument and
@@ -2125,7 +2102,6 @@ for C<extract_tagged>. For example, to properly ignore "empty" XML elements
 
         extract_tagged($text, undef, undef, undef, {ignore => [$empty_tag]} );
 
-
 C<gen_delimited_pat> may also be called with an optional second argument,
 which specifies the "escape" character(s) to be used for each delimiter.
 For example to match a Pascal-style string (where ' is the delimiter
@@ -2279,17 +2255,12 @@ C<extract_tagged> reached the end of the text without finding a closing tag
 to match the original opening tag (and the failure mode was not
 "MAX" or "PARA").
 
-
-
-
 =back
 
-
 =head1 AUTHOR
 
 Damian Conway (damian@conway.org)
 
-
 =head1 BUGS AND IRRITATIONS
 
 There are undoubtedly serious bugs lurking somewhere in this code, if
@@ -2298,9 +2269,13 @@ more about Perl than they really do.
 
 Bug reports and other feedback are most welcome.
 
-
 =head1 COPYRIGHT
 
- Copyright (c) 1997-2001, Damian Conway. All Rights Reserved.
- This module is free software. It may be used, redistributed
-     and/or modified under the same terms as Perl itself.
+Copyright 1997 - 2001 Damian Conway. All Rights Reserved.
+
+Some (minor) parts copyright 2009 Adam Kennedy.
+
+This module is free software. It may be used, redistributed
+and/or modified under the same terms as Perl itself.
+
+=cut
diff --git a/ext/Text-Balanced/t/00-load.t b/ext/Text-Balanced/t/00-load.t
deleted file mode 100644 (file)
index a8268a7..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-use Test::More tests => 1;
-
-BEGIN {
-use_ok( 'Text::Balanced' );
-diag( "Testing Text::Balanced $Text::Balanced::VERSION" )
-    unless $ENV{PERL_CORE};
-}
diff --git a/ext/Text-Balanced/t/01_compile.t b/ext/Text-Balanced/t/01_compile.t
new file mode 100644 (file)
index 0000000..77c1099
--- /dev/null
@@ -0,0 +1,11 @@
+#!/usr/bin/perl
+
+use strict;
+BEGIN {
+       $|  = 1;
+       $^W = 1;
+}
+
+use Test::More tests => 1;
+
+use_ok( 'Text::Balanced' );
similarity index 95%
rename from ext/Text-Balanced/t/extbrk.t
rename to ext/Text-Balanced/t/02_extbrk.t
index e2763e8..a36025d 100644 (file)
@@ -1,10 +1,3 @@
-BEGIN {
-    if ($ENV{PERL_CORE}) {
-        chdir('t') if -d 't';
-        @INC = qw(../lib);
-    }
-}
-
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl test.pl'
 
similarity index 96%
rename from ext/Text-Balanced/t/extcbk.t
rename to ext/Text-Balanced/t/03_extcbk.t
index 30b7e50..83081ae 100644 (file)
@@ -1,10 +1,3 @@
-BEGIN {
-    if ($ENV{PERL_CORE}) {
-        chdir('t') if -d 't';
-        @INC = qw(../lib);
-    }
-}
-
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl test.pl'
 
similarity index 95%
rename from ext/Text-Balanced/t/extdel.t
rename to ext/Text-Balanced/t/04_extdel.t
index 6db547f..c5ca88e 100644 (file)
@@ -1,10 +1,3 @@
-BEGIN {
-    if ($ENV{PERL_CORE}) {
-        chdir('t') if -d 't';
-        @INC = qw(../lib);
-    }
-}
-
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl test.pl'
 
similarity index 98%
rename from ext/Text-Balanced/t/extmul.t
rename to ext/Text-Balanced/t/05_extmul.t
index 98b6272..2ac1b19 100644 (file)
@@ -1,10 +1,3 @@
-BEGIN {
-    if ($ENV{PERL_CORE}) {
-        chdir('t') if -d 't';
-        @INC = qw(../lib);
-    }
-}
-
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl test.pl'
 
similarity index 97%
rename from ext/Text-Balanced/t/extqlk.t
rename to ext/Text-Balanced/t/06_extqlk.t
index 97dc517..6badc0e 100644 (file)
@@ -1,10 +1,3 @@
-BEGIN {
-    if ($ENV{PERL_CORE}) {
-        chdir('t') if -d 't';
-        @INC = qw(../lib);
-    }
-}
-
 #! /usr/local/bin/perl -ws
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl test.pl'
similarity index 97%
rename from ext/Text-Balanced/t/exttag.t
rename to ext/Text-Balanced/t/07_exttag.t
index d412c23..16a48b2 100644 (file)
@@ -1,10 +1,3 @@
-BEGIN {
-    if ($ENV{PERL_CORE}) {
-        chdir('t') if -d 't';
-        @INC = qw(../lib);
-    }
-}
-
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl test.pl'
 
similarity index 96%
rename from ext/Text-Balanced/t/extvar.t
rename to ext/Text-Balanced/t/08_extvar.t
index 5f37d8c..a33ac91 100644 (file)
@@ -1,10 +1,3 @@
-BEGIN {
-    if ($ENV{PERL_CORE}) {
-        chdir('t') if -d 't';
-        @INC = qw(../lib);
-    }
-}
-
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl test.pl'
 
similarity index 96%
rename from ext/Text-Balanced/t/gentag.t
rename to ext/Text-Balanced/t/09_gentag.t
index f5fd5dc..0dd55a5 100644 (file)
@@ -1,10 +1,3 @@
-BEGIN {
-    if ($ENV{PERL_CORE}) {
-        chdir('t') if -d 't';
-        @INC = qw(../lib);
-    }
-}
-
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl test.pl'