Initial Commit
This commit is contained in:
84
database/perl/lib/Text/Abbrev.pm
Normal file
84
database/perl/lib/Text/Abbrev.pm
Normal file
@@ -0,0 +1,84 @@
|
||||
package Text::Abbrev;
|
||||
require 5.005; # Probably works on earlier versions too.
|
||||
require Exporter;
|
||||
|
||||
our $VERSION = '1.02';
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Text::Abbrev - abbrev - create an abbreviation table from a list
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Text::Abbrev;
|
||||
abbrev $hashref, LIST
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Stores all unambiguous truncations of each element of LIST
|
||||
as keys in the associative array referenced by C<$hashref>.
|
||||
The values are the original list elements.
|
||||
|
||||
=head1 EXAMPLE
|
||||
|
||||
$hashref = abbrev qw(list edit send abort gripe);
|
||||
|
||||
%hash = abbrev qw(list edit send abort gripe);
|
||||
|
||||
abbrev $hashref, qw(list edit send abort gripe);
|
||||
|
||||
abbrev(*hash, qw(list edit send abort gripe));
|
||||
|
||||
=cut
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT = qw(abbrev);
|
||||
|
||||
# Usage:
|
||||
# abbrev \%foo, LIST;
|
||||
# ...
|
||||
# $long = $foo{$short};
|
||||
|
||||
sub abbrev {
|
||||
my ($word, $hashref, $glob, %table, $returnvoid);
|
||||
|
||||
@_ or return; # So we don't autovivify onto @_ and trigger warning
|
||||
if (ref($_[0])) { # hash reference preferably
|
||||
$hashref = shift;
|
||||
$returnvoid = 1;
|
||||
} elsif (ref \$_[0] eq 'GLOB') { # is actually a glob (deprecated)
|
||||
$hashref = \%{shift()};
|
||||
$returnvoid = 1;
|
||||
}
|
||||
%{$hashref} = ();
|
||||
|
||||
WORD: foreach $word (@_) {
|
||||
for (my $len = (length $word) - 1; $len > 0; --$len) {
|
||||
my $abbrev = substr($word,0,$len);
|
||||
my $seen = ++$table{$abbrev};
|
||||
if ($seen == 1) { # We're the first word so far to have
|
||||
# this abbreviation.
|
||||
$hashref->{$abbrev} = $word;
|
||||
} elsif ($seen == 2) { # We're the second word to have this
|
||||
# abbreviation, so we can't use it.
|
||||
delete $hashref->{$abbrev};
|
||||
} else { # We're the third word to have this
|
||||
# abbreviation, so skip to the next word.
|
||||
next WORD;
|
||||
}
|
||||
}
|
||||
}
|
||||
# Non-abbreviations always get entered, even if they aren't unique
|
||||
foreach $word (@_) {
|
||||
$hashref->{$word} = $word;
|
||||
}
|
||||
return if $returnvoid;
|
||||
if (wantarray) {
|
||||
%{$hashref};
|
||||
} else {
|
||||
$hashref;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
2383
database/perl/lib/Text/Balanced.pm
Normal file
2383
database/perl/lib/Text/Balanced.pm
Normal file
File diff suppressed because it is too large
Load Diff
303
database/perl/lib/Text/ParseWords.pm
Normal file
303
database/perl/lib/Text/ParseWords.pm
Normal file
@@ -0,0 +1,303 @@
|
||||
package Text::ParseWords;
|
||||
|
||||
use strict;
|
||||
require 5.006;
|
||||
our $VERSION = "3.30";
|
||||
|
||||
|
||||
use Exporter;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT = qw(shellwords quotewords nested_quotewords parse_line);
|
||||
our @EXPORT_OK = qw(old_shellwords);
|
||||
our $PERL_SINGLE_QUOTE;
|
||||
|
||||
|
||||
sub shellwords {
|
||||
my (@lines) = @_;
|
||||
my @allwords;
|
||||
|
||||
foreach my $line (@lines) {
|
||||
$line =~ s/^\s+//;
|
||||
my @words = parse_line('\s+', 0, $line);
|
||||
pop @words if (@words and !defined $words[-1]);
|
||||
return() unless (@words || !length($line));
|
||||
push(@allwords, @words);
|
||||
}
|
||||
return(@allwords);
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub quotewords {
|
||||
my($delim, $keep, @lines) = @_;
|
||||
my($line, @words, @allwords);
|
||||
|
||||
foreach $line (@lines) {
|
||||
@words = parse_line($delim, $keep, $line);
|
||||
return() unless (@words || !length($line));
|
||||
push(@allwords, @words);
|
||||
}
|
||||
return(@allwords);
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub nested_quotewords {
|
||||
my($delim, $keep, @lines) = @_;
|
||||
my($i, @allwords);
|
||||
|
||||
for ($i = 0; $i < @lines; $i++) {
|
||||
@{$allwords[$i]} = parse_line($delim, $keep, $lines[$i]);
|
||||
return() unless (@{$allwords[$i]} || !length($lines[$i]));
|
||||
}
|
||||
return(@allwords);
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub parse_line {
|
||||
my($delimiter, $keep, $line) = @_;
|
||||
my($word, @pieces);
|
||||
|
||||
no warnings 'uninitialized'; # we will be testing undef strings
|
||||
|
||||
while (length($line)) {
|
||||
# This pattern is optimised to be stack conservative on older perls.
|
||||
# Do not refactor without being careful and testing it on very long strings.
|
||||
# See Perl bug #42980 for an example of a stack busting input.
|
||||
$line =~ s/^
|
||||
(?:
|
||||
# double quoted string
|
||||
(") # $quote
|
||||
((?>[^\\"]*(?:\\.[^\\"]*)*))" # $quoted
|
||||
| # --OR--
|
||||
# singe quoted string
|
||||
(') # $quote
|
||||
((?>[^\\']*(?:\\.[^\\']*)*))' # $quoted
|
||||
| # --OR--
|
||||
# unquoted string
|
||||
( # $unquoted
|
||||
(?:\\.|[^\\"'])*?
|
||||
)
|
||||
# followed by
|
||||
( # $delim
|
||||
\Z(?!\n) # EOL
|
||||
| # --OR--
|
||||
(?-x:$delimiter) # delimiter
|
||||
| # --OR--
|
||||
(?!^)(?=["']) # a quote
|
||||
)
|
||||
)//xs or return; # extended layout
|
||||
my ($quote, $quoted, $unquoted, $delim) = (($1 ? ($1,$2) : ($3,$4)), $5, $6);
|
||||
|
||||
|
||||
return() unless( defined($quote) || length($unquoted) || length($delim));
|
||||
|
||||
if ($keep) {
|
||||
$quoted = "$quote$quoted$quote";
|
||||
}
|
||||
else {
|
||||
$unquoted =~ s/\\(.)/$1/sg;
|
||||
if (defined $quote) {
|
||||
$quoted =~ s/\\(.)/$1/sg if ($quote eq '"');
|
||||
$quoted =~ s/\\([\\'])/$1/g if ( $PERL_SINGLE_QUOTE && $quote eq "'");
|
||||
}
|
||||
}
|
||||
$word .= substr($line, 0, 0); # leave results tainted
|
||||
$word .= defined $quote ? $quoted : $unquoted;
|
||||
|
||||
if (length($delim)) {
|
||||
push(@pieces, $word);
|
||||
push(@pieces, $delim) if ($keep eq 'delimiters');
|
||||
undef $word;
|
||||
}
|
||||
if (!length($line)) {
|
||||
push(@pieces, $word);
|
||||
}
|
||||
}
|
||||
return(@pieces);
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub old_shellwords {
|
||||
|
||||
# Usage:
|
||||
# use ParseWords;
|
||||
# @words = old_shellwords($line);
|
||||
# or
|
||||
# @words = old_shellwords(@lines);
|
||||
# or
|
||||
# @words = old_shellwords(); # defaults to $_ (and clobbers it)
|
||||
|
||||
no warnings 'uninitialized'; # we will be testing undef strings
|
||||
local *_ = \join('', @_) if @_;
|
||||
my (@words, $snippet);
|
||||
|
||||
s/\A\s+//;
|
||||
while ($_ ne '') {
|
||||
my $field = substr($_, 0, 0); # leave results tainted
|
||||
for (;;) {
|
||||
if (s/\A"(([^"\\]|\\.)*)"//s) {
|
||||
($snippet = $1) =~ s#\\(.)#$1#sg;
|
||||
}
|
||||
elsif (/\A"/) {
|
||||
require Carp;
|
||||
Carp::carp("Unmatched double quote: $_");
|
||||
return();
|
||||
}
|
||||
elsif (s/\A'(([^'\\]|\\.)*)'//s) {
|
||||
($snippet = $1) =~ s#\\(.)#$1#sg;
|
||||
}
|
||||
elsif (/\A'/) {
|
||||
require Carp;
|
||||
Carp::carp("Unmatched single quote: $_");
|
||||
return();
|
||||
}
|
||||
elsif (s/\A\\(.?)//s) {
|
||||
$snippet = $1;
|
||||
}
|
||||
elsif (s/\A([^\s\\'"]+)//) {
|
||||
$snippet = $1;
|
||||
}
|
||||
else {
|
||||
s/\A\s+//;
|
||||
last;
|
||||
}
|
||||
$field .= $snippet;
|
||||
}
|
||||
push(@words, $field);
|
||||
}
|
||||
return @words;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Text::ParseWords - parse text into an array of tokens or array of arrays
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Text::ParseWords;
|
||||
@lists = nested_quotewords($delim, $keep, @lines);
|
||||
@words = quotewords($delim, $keep, @lines);
|
||||
@words = shellwords(@lines);
|
||||
@words = parse_line($delim, $keep, $line);
|
||||
@words = old_shellwords(@lines); # DEPRECATED!
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The &nested_quotewords() and "ewords() functions accept a delimiter
|
||||
(which can be a regular expression)
|
||||
and a list of lines and then breaks those lines up into a list of
|
||||
words ignoring delimiters that appear inside quotes. "ewords()
|
||||
returns all of the tokens in a single long list, while &nested_quotewords()
|
||||
returns a list of token lists corresponding to the elements of @lines.
|
||||
&parse_line() does tokenizing on a single string. The &*quotewords()
|
||||
functions simply call &parse_line(), so if you're only splitting
|
||||
one line you can call &parse_line() directly and save a function
|
||||
call.
|
||||
|
||||
The $keep argument is a boolean flag. If true, then the tokens are
|
||||
split on the specified delimiter, but all other characters (including
|
||||
quotes and backslashes) are kept in the tokens. If $keep is false then the
|
||||
&*quotewords() functions remove all quotes and backslashes that are
|
||||
not themselves backslash-escaped or inside of single quotes (i.e.,
|
||||
"ewords() tries to interpret these characters just like the Bourne
|
||||
shell). NB: these semantics are significantly different from the
|
||||
original version of this module shipped with Perl 5.000 through 5.004.
|
||||
As an additional feature, $keep may be the keyword "delimiters" which
|
||||
causes the functions to preserve the delimiters in each string as
|
||||
tokens in the token lists, in addition to preserving quote and
|
||||
backslash characters.
|
||||
|
||||
&shellwords() is written as a special case of "ewords(), and it
|
||||
does token parsing with whitespace as a delimiter-- similar to most
|
||||
Unix shells.
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
The sample program:
|
||||
|
||||
use Text::ParseWords;
|
||||
@words = quotewords('\s+', 0, q{this is "a test" of\ quotewords \"for you});
|
||||
$i = 0;
|
||||
foreach (@words) {
|
||||
print "$i: <$_>\n";
|
||||
$i++;
|
||||
}
|
||||
|
||||
produces:
|
||||
|
||||
0: <this>
|
||||
1: <is>
|
||||
2: <a test>
|
||||
3: <of quotewords>
|
||||
4: <"for>
|
||||
5: <you>
|
||||
|
||||
demonstrating:
|
||||
|
||||
=over 4
|
||||
|
||||
=item 0Z<>
|
||||
|
||||
a simple word
|
||||
|
||||
=item 1Z<>
|
||||
|
||||
multiple spaces are skipped because of our $delim
|
||||
|
||||
=item 2Z<>
|
||||
|
||||
use of quotes to include a space in a word
|
||||
|
||||
=item 3Z<>
|
||||
|
||||
use of a backslash to include a space in a word
|
||||
|
||||
=item 4Z<>
|
||||
|
||||
use of a backslash to remove the special meaning of a double-quote
|
||||
|
||||
=item 5Z<>
|
||||
|
||||
another simple word (note the lack of effect of the
|
||||
backslashed double-quote)
|
||||
|
||||
=back
|
||||
|
||||
Replacing C<quotewords('\s+', 0, q{this is...})>
|
||||
with C<shellwords(q{this is...})>
|
||||
is a simpler way to accomplish the same thing.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Text::CSV> - for parsing CSV files
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Maintainer: Alexandr Ciornii <alexchornyATgmail.com>.
|
||||
|
||||
Previous maintainer: Hal Pomeranz <pomeranz@netcom.com>, 1994-1997 (Original
|
||||
author unknown). Much of the code for &parse_line() (including the
|
||||
primary regexp) from Joerk Behrends <jbehrends@multimediaproduzenten.de>.
|
||||
|
||||
Examples section another documentation provided by John Heidemann
|
||||
<johnh@ISI.EDU>
|
||||
|
||||
Bug reports, patches, and nagging provided by lots of folks-- thanks
|
||||
everybody! Special thanks to Michael Schwern <schwern@envirolink.org>
|
||||
for assuring me that a &nested_quotewords() would be useful, and to
|
||||
Jeff Friedl <jfriedl@yahoo-inc.com> for telling me not to worry about
|
||||
error-checking (sort of-- you had to be there).
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This library is free software; you may redistribute and/or modify it
|
||||
under the same terms as Perl itself.
|
||||
|
||||
=cut
|
||||
192
database/perl/lib/Text/Tabs.pm
Normal file
192
database/perl/lib/Text/Tabs.pm
Normal file
@@ -0,0 +1,192 @@
|
||||
package Text::Tabs;
|
||||
|
||||
require Exporter;
|
||||
|
||||
@ISA = (Exporter);
|
||||
@EXPORT = qw(expand unexpand $tabstop);
|
||||
|
||||
use vars qw($VERSION $SUBVERSION $tabstop $debug);
|
||||
$VERSION = 2013.0523;
|
||||
$SUBVERSION = 'modern';
|
||||
|
||||
use strict;
|
||||
|
||||
use 5.010_000;
|
||||
|
||||
BEGIN {
|
||||
$tabstop = 8;
|
||||
$debug = 0;
|
||||
}
|
||||
|
||||
my $CHUNK = qr/\X/;
|
||||
|
||||
sub _xlen (_) { scalar(() = $_[0] =~ /$CHUNK/g) }
|
||||
sub _xpos (_) { _xlen( substr( $_[0], 0, pos($_[0]) ) ) }
|
||||
|
||||
sub expand {
|
||||
my @l;
|
||||
my $pad;
|
||||
for ( @_ ) {
|
||||
my $s = '';
|
||||
for (split(/^/m, $_, -1)) {
|
||||
my $offs = 0;
|
||||
s{\t}{
|
||||
# this works on both 5.10 and 5.11
|
||||
$pad = $tabstop - (_xlen(${^PREMATCH}) + $offs) % $tabstop;
|
||||
# this works on 5.11, but fails on 5.10
|
||||
#XXX# $pad = $tabstop - (_xpos() + $offs) % $tabstop;
|
||||
$offs += $pad - 1;
|
||||
" " x $pad;
|
||||
}peg;
|
||||
$s .= $_;
|
||||
}
|
||||
push(@l, $s);
|
||||
}
|
||||
return @l if wantarray;
|
||||
return $l[0];
|
||||
}
|
||||
|
||||
sub unexpand
|
||||
{
|
||||
my (@l) = @_;
|
||||
my @e;
|
||||
my $x;
|
||||
my $line;
|
||||
my @lines;
|
||||
my $lastbit;
|
||||
my $ts_as_space = " " x $tabstop;
|
||||
for $x (@l) {
|
||||
@lines = split("\n", $x, -1);
|
||||
for $line (@lines) {
|
||||
$line = expand($line);
|
||||
@e = split(/(${CHUNK}{$tabstop})/,$line,-1);
|
||||
$lastbit = pop(@e);
|
||||
$lastbit = ''
|
||||
unless defined $lastbit;
|
||||
$lastbit = "\t"
|
||||
if $lastbit eq $ts_as_space;
|
||||
for $_ (@e) {
|
||||
if ($debug) {
|
||||
my $x = $_;
|
||||
$x =~ s/\t/^I\t/gs;
|
||||
print "sub on '$x'\n";
|
||||
}
|
||||
s/ +$/\t/;
|
||||
}
|
||||
$line = join('',@e, $lastbit);
|
||||
}
|
||||
$x = join("\n", @lines);
|
||||
}
|
||||
return @l if wantarray;
|
||||
return $l[0];
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
sub expand
|
||||
{
|
||||
my (@l) = @_;
|
||||
for $_ (@l) {
|
||||
1 while s/(^|\n)([^\t\n]*)(\t+)/
|
||||
$1. $2 . (" " x
|
||||
($tabstop * length($3)
|
||||
- (length($2) % $tabstop)))
|
||||
/sex;
|
||||
}
|
||||
return @l if wantarray;
|
||||
return $l[0];
|
||||
}
|
||||
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Text::Tabs - expand and unexpand tabs like unix expand(1) and unexpand(1)
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Text::Tabs;
|
||||
|
||||
$tabstop = 4; # default = 8
|
||||
@lines_without_tabs = expand(@lines_with_tabs);
|
||||
@lines_with_tabs = unexpand(@lines_without_tabs);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Text::Tabs does most of what the unix utilities expand(1) and unexpand(1)
|
||||
do. Given a line with tabs in it, C<expand> replaces those tabs with
|
||||
the appropriate number of spaces. Given a line with or without tabs in
|
||||
it, C<unexpand> adds tabs when it can save bytes by doing so,
|
||||
like the C<unexpand -a> command.
|
||||
|
||||
Unlike the old unix utilities, this module correctly accounts for
|
||||
any Unicode combining characters (such as diacriticals) that may occur
|
||||
in each line for both expansion and unexpansion. These are overstrike
|
||||
characters that do not increment the logical position. Make sure
|
||||
you have the appropriate Unicode settings enabled.
|
||||
|
||||
=head1 EXPORTS
|
||||
|
||||
The following are exported:
|
||||
|
||||
=over 4
|
||||
|
||||
=item expand
|
||||
|
||||
=item unexpand
|
||||
|
||||
=item $tabstop
|
||||
|
||||
The C<$tabstop> variable controls how many column positions apart each
|
||||
tabstop is. The default is 8.
|
||||
|
||||
Please note that C<local($tabstop)> doesn't do the right thing and if you want
|
||||
to use C<local> to override C<$tabstop>, you need to use
|
||||
C<local($Text::Tabs::tabstop)>.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXAMPLE
|
||||
|
||||
#!perl
|
||||
# unexpand -a
|
||||
use Text::Tabs;
|
||||
|
||||
while (<>) {
|
||||
print unexpand $_;
|
||||
}
|
||||
|
||||
Instead of the shell's C<expand> command, use:
|
||||
|
||||
perl -MText::Tabs -n -e 'print expand $_'
|
||||
|
||||
Instead of the shell's C<unexpand -a> command, use:
|
||||
|
||||
perl -MText::Tabs -n -e 'print unexpand $_'
|
||||
|
||||
=head1 SUBVERSION
|
||||
|
||||
This module comes in two flavors: one for modern perls (5.10 and above)
|
||||
and one for ancient obsolete perls. The version for modern perls has
|
||||
support for Unicode. The version for old perls does not. You can tell
|
||||
which version you have installed by looking at C<$Text::Tabs::SUBVERSION>:
|
||||
it is C<old> for obsolete perls and C<modern> for current perls.
|
||||
|
||||
This man page is for the version for modern perls and so that's probably
|
||||
what you've got.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
Text::Tabs handles only tabs (C<"\t">) and combining characters (C</\pM/>). It doesn't
|
||||
count backwards for backspaces (C<"\t">), omit other non-printing control characters (C</\pC/>),
|
||||
or otherwise deal with any other zero-, half-, and full-width characters.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
Copyright (C) 1996-2002,2005,2006 David Muir Sharnoff.
|
||||
Copyright (C) 2005 Aristotle Pagaltzis
|
||||
Copyright (C) 2012-2013 Google, Inc.
|
||||
This module may be modified, used, copied, and redistributed at your own risk.
|
||||
Although allowed by the preceding license, please do not publicly
|
||||
redistribute modified versions of this code with the name "Text::Tabs"
|
||||
unless it passes the unmodified Text::Tabs test suite.
|
||||
2363
database/perl/lib/Text/Template.pm
Normal file
2363
database/perl/lib/Text/Template.pm
Normal file
File diff suppressed because it is too large
Load Diff
157
database/perl/lib/Text/Template/Preprocess.pm
Normal file
157
database/perl/lib/Text/Template/Preprocess.pm
Normal file
@@ -0,0 +1,157 @@
|
||||
|
||||
package Text::Template::Preprocess;
|
||||
$Text::Template::Preprocess::VERSION = '1.59';
|
||||
# ABSTRACT: Expand template text with embedded Perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Text::Template;
|
||||
our @ISA = qw(Text::Template);
|
||||
|
||||
sub fill_in {
|
||||
my $self = shift;
|
||||
my (%args) = @_;
|
||||
|
||||
my $pp = $args{PREPROCESSOR} || $self->{PREPROCESSOR};
|
||||
|
||||
if ($pp) {
|
||||
local $_ = $self->source();
|
||||
my $type = $self->{TYPE};
|
||||
|
||||
# print "# fill_in: before <$_>\n";
|
||||
&$pp;
|
||||
|
||||
# print "# fill_in: after <$_>\n";
|
||||
$self->set_source_data($_, $type);
|
||||
}
|
||||
|
||||
$self->SUPER::fill_in(@_);
|
||||
}
|
||||
|
||||
sub preprocessor {
|
||||
my ($self, $pp) = @_;
|
||||
|
||||
my $old_pp = $self->{PREPROCESSOR};
|
||||
|
||||
$self->{PREPROCESSOR} = $pp if @_ > 1; # OK to pass $pp=undef
|
||||
|
||||
$old_pp;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=encoding UTF-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Text::Template::Preprocess - Expand template text with embedded Perl
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
version 1.59
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Text::Template::Preprocess;
|
||||
|
||||
my $t = Text::Template::Preprocess->new(...); # identical to Text::Template
|
||||
|
||||
# Fill in template, but preprocess each code fragment with pp().
|
||||
my $result = $t->fill_in(..., PREPROCESSOR => \&pp);
|
||||
|
||||
my $old_pp = $t->preprocessor(\&new_pp);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
C<Text::Template::Preprocess> provides a new C<PREPROCESSOR> option to
|
||||
C<fill_in>. If the C<PREPROCESSOR> option is supplied, it must be a
|
||||
reference to a preprocessor subroutine. When filling out a template,
|
||||
C<Text::Template::Preprocessor> will use this subroutine to preprocess
|
||||
the program fragment prior to evaluating the code.
|
||||
|
||||
The preprocessor subroutine will be called repeatedly, once for each
|
||||
program fragment. The program fragment will be in C<$_>. The
|
||||
subroutine should modify the contents of C<$_> and return.
|
||||
C<Text::Template::Preprocess> will then execute contents of C<$_> and
|
||||
insert the result into the appropriate part of the template.
|
||||
|
||||
C<Text::Template::Preprocess> objects also support a utility method,
|
||||
C<preprocessor()>, which sets a new preprocessor for the object. This
|
||||
preprocessor is used for all subsequent calls to C<fill_in> except
|
||||
where overridden by an explicit C<PREPROCESSOR> option.
|
||||
C<preprocessor()> returns the previous default preprocessor function,
|
||||
or undefined if there wasn't one. When invoked with no arguments,
|
||||
C<preprocessor()> returns the object's current default preprocessor
|
||||
function without changing it.
|
||||
|
||||
In all other respects, C<Text::Template::Preprocess> is identical to
|
||||
C<Text::Template>.
|
||||
|
||||
=head1 WHY?
|
||||
|
||||
One possible purpose: If your files contain a lot of JavaScript, like
|
||||
this:
|
||||
|
||||
Plain text here...
|
||||
{ perl code }
|
||||
<script language=JavaScript>
|
||||
if (br== "n3") {
|
||||
// etc.
|
||||
}
|
||||
</script>
|
||||
{ more perl code }
|
||||
More plain text...
|
||||
|
||||
You don't want C<Text::Template> to confuse the curly braces in the
|
||||
JavaScript program with executable Perl code. One strategy:
|
||||
|
||||
sub quote_scripts {
|
||||
s(<script(.*?)</script>)(q{$1})gsi;
|
||||
}
|
||||
|
||||
Then use C<PREPROCESSOR =E<gt> \"e_scripts>. This will transform
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Text::Template>
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The development version is on github at L<https://https://github.com/mschout/perl-text-template>
|
||||
and may be cloned from L<git://https://github.com/mschout/perl-text-template.git>
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
Please report any bugs or feature requests on the bugtracker website
|
||||
L<https://github.com/mschout/perl-text-template/issues>
|
||||
|
||||
When submitting a bug or request, please include a test-file or a
|
||||
patch to an existing test-file that illustrates the bug or desired
|
||||
feature.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Mark Jason Dominus, Plover Systems
|
||||
|
||||
Please send questions and other remarks about this software to
|
||||
C<mjd-perl-template+@plover.com>
|
||||
|
||||
You can join a very low-volume (E<lt>10 messages per year) mailing
|
||||
list for announcements about this package. Send an empty note to
|
||||
C<mjd-perl-template-request@plover.com> to join.
|
||||
|
||||
For updates, visit C<http://www.plover.com/~mjd/perl/Template/>.
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2013 by Mark Jason Dominus <mjd@cpan.org>.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
300
database/perl/lib/Text/Wrap.pm
Normal file
300
database/perl/lib/Text/Wrap.pm
Normal file
@@ -0,0 +1,300 @@
|
||||
package Text::Wrap;
|
||||
|
||||
use warnings::register;
|
||||
require Exporter;
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT = qw(wrap fill);
|
||||
@EXPORT_OK = qw($columns $break $huge);
|
||||
|
||||
$VERSION = 2013.0523;
|
||||
$SUBVERSION = 'modern';
|
||||
|
||||
use 5.010_000;
|
||||
|
||||
use vars qw($VERSION $SUBVERSION $columns $debug $break $huge $unexpand $tabstop $separator $separator2);
|
||||
use strict;
|
||||
|
||||
BEGIN {
|
||||
$columns = 76; # <= screen width
|
||||
$debug = 0;
|
||||
$break = '(?=\s)\X';
|
||||
$huge = 'wrap'; # alternatively: 'die' or 'overflow'
|
||||
$unexpand = 1;
|
||||
$tabstop = 8;
|
||||
$separator = "\n";
|
||||
$separator2 = undef;
|
||||
}
|
||||
|
||||
my $CHUNK = qr/\X/;
|
||||
|
||||
sub _xlen(_) { scalar(() = $_[0] =~ /$CHUNK/g) }
|
||||
|
||||
sub _xpos(_) { _xlen( substr( $_[0], 0, pos($_[0]) ) ) }
|
||||
|
||||
use Text::Tabs qw(expand unexpand);
|
||||
|
||||
sub wrap
|
||||
{
|
||||
my ($ip, $xp, @t) = @_;
|
||||
|
||||
local($Text::Tabs::tabstop) = $tabstop;
|
||||
my $r = "";
|
||||
my $tail = pop(@t);
|
||||
my $t = expand(join("", (map { /\s+\z/ ? ( $_ ) : ($_, ' ') } @t), $tail));
|
||||
my $lead = $ip;
|
||||
my $nll = $columns - _xlen(expand($xp)) - 1;
|
||||
if ($nll <= 0 && $xp ne '') {
|
||||
my $nc = _xlen(expand($xp)) + 2;
|
||||
warnings::warnif "Increasing \$Text::Wrap::columns from $columns to $nc to accommodate length of subsequent tab";
|
||||
$columns = $nc;
|
||||
$nll = 1;
|
||||
}
|
||||
my $ll = $columns - _xlen(expand($ip)) - 1;
|
||||
$ll = 0 if $ll < 0;
|
||||
my $nl = "";
|
||||
my $remainder = "";
|
||||
|
||||
use re 'taint';
|
||||
|
||||
pos($t) = 0;
|
||||
while ($t !~ /\G(?:$break)*\Z/gc) {
|
||||
if ($t =~ /\G((?:(?=[^\n])\X){0,$ll})($break|\n+|\z)/xmgc) {
|
||||
$r .= $unexpand
|
||||
? unexpand($nl . $lead . $1)
|
||||
: $nl . $lead . $1;
|
||||
$remainder = $2;
|
||||
} elsif ($huge eq 'wrap' && $t =~ /\G((?:(?=[^\n])\X){$ll})/gc) {
|
||||
$r .= $unexpand
|
||||
? unexpand($nl . $lead . $1)
|
||||
: $nl . $lead . $1;
|
||||
$remainder = defined($separator2) ? $separator2 : $separator;
|
||||
} elsif ($huge eq 'overflow' && $t =~ /\G((?:(?=[^\n])\X)*?)($break|\n+|\z)/xmgc) {
|
||||
$r .= $unexpand
|
||||
? unexpand($nl . $lead . $1)
|
||||
: $nl . $lead . $1;
|
||||
$remainder = $2;
|
||||
} elsif ($huge eq 'die') {
|
||||
die "couldn't wrap '$t'";
|
||||
} elsif ($columns < 2) {
|
||||
warnings::warnif "Increasing \$Text::Wrap::columns from $columns to 2";
|
||||
$columns = 2;
|
||||
return ($ip, $xp, @t);
|
||||
} else {
|
||||
die "This shouldn't happen";
|
||||
}
|
||||
|
||||
$lead = $xp;
|
||||
$ll = $nll;
|
||||
$nl = defined($separator2)
|
||||
? ($remainder eq "\n"
|
||||
? "\n"
|
||||
: $separator2)
|
||||
: $separator;
|
||||
}
|
||||
$r .= $remainder;
|
||||
|
||||
print "-----------$r---------\n" if $debug;
|
||||
|
||||
print "Finish up with '$lead'\n" if $debug;
|
||||
|
||||
my($opos) = pos($t);
|
||||
|
||||
$r .= $lead . substr($t, pos($t), length($t) - pos($t))
|
||||
if pos($t) ne length($t);
|
||||
|
||||
print "-----------$r---------\n" if $debug;;
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
sub fill
|
||||
{
|
||||
my ($ip, $xp, @raw) = @_;
|
||||
my @para;
|
||||
my $pp;
|
||||
|
||||
for $pp (split(/\n\s+/, join("\n",@raw))) {
|
||||
$pp =~ s/\s+/ /g;
|
||||
my $x = wrap($ip, $xp, $pp);
|
||||
push(@para, $x);
|
||||
}
|
||||
|
||||
# if paragraph_indent is the same as line_indent,
|
||||
# separate paragraphs with blank lines
|
||||
|
||||
my $ps = ($ip eq $xp) ? "\n\n" : "\n";
|
||||
return join ($ps, @para);
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Text::Wrap - line wrapping to form simple paragraphs
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<Example 1>
|
||||
|
||||
use Text::Wrap;
|
||||
|
||||
$initial_tab = "\t"; # Tab before first line
|
||||
$subsequent_tab = ""; # All other lines flush left
|
||||
|
||||
print wrap($initial_tab, $subsequent_tab, @text);
|
||||
print fill($initial_tab, $subsequent_tab, @text);
|
||||
|
||||
$lines = wrap($initial_tab, $subsequent_tab, @text);
|
||||
|
||||
@paragraphs = fill($initial_tab, $subsequent_tab, @text);
|
||||
|
||||
B<Example 2>
|
||||
|
||||
use Text::Wrap qw(wrap $columns $huge);
|
||||
|
||||
$columns = 132; # Wrap at 132 characters
|
||||
$huge = 'die';
|
||||
$huge = 'wrap';
|
||||
$huge = 'overflow';
|
||||
|
||||
B<Example 3>
|
||||
|
||||
use Text::Wrap;
|
||||
|
||||
$Text::Wrap::columns = 72;
|
||||
print wrap('', '', @text);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
C<Text::Wrap::wrap()> is a very simple paragraph formatter. It formats a
|
||||
single paragraph at a time by breaking lines at word boundaries.
|
||||
Indentation is controlled for the first line (C<$initial_tab>) and
|
||||
all subsequent lines (C<$subsequent_tab>) independently. Please note:
|
||||
C<$initial_tab> and C<$subsequent_tab> are the literal strings that will
|
||||
be used: it is unlikely you would want to pass in a number.
|
||||
|
||||
C<Text::Wrap::fill()> is a simple multi-paragraph formatter. It formats
|
||||
each paragraph separately and then joins them together when it's done. It
|
||||
will destroy any whitespace in the original text. It breaks text into
|
||||
paragraphs by looking for whitespace after a newline. In other respects,
|
||||
it acts like wrap().
|
||||
|
||||
C<wrap()> compresses trailing whitespace into one newline, and C<fill()>
|
||||
deletes all trailing whitespace.
|
||||
|
||||
Both C<wrap()> and C<fill()> return a single string.
|
||||
|
||||
Unlike the old Unix fmt(1) utility, this module correctly accounts for
|
||||
any Unicode combining characters (such as diacriticals) that may occur
|
||||
in each line for both expansion and unexpansion. These are overstrike
|
||||
characters that do not increment the logical position. Make sure
|
||||
you have the appropriate Unicode settings enabled.
|
||||
|
||||
=head1 OVERRIDES
|
||||
|
||||
C<Text::Wrap::wrap()> has a number of variables that control its behavior.
|
||||
Because other modules might be using C<Text::Wrap::wrap()> it is suggested
|
||||
that you leave these variables alone! If you can't do that, then
|
||||
use C<local($Text::Wrap::VARIABLE) = YOURVALUE> when you change the
|
||||
values so that the original value is restored. This C<local()> trick
|
||||
will not work if you import the variable into your own namespace.
|
||||
|
||||
Lines are wrapped at C<$Text::Wrap::columns> columns (default value: 76).
|
||||
C<$Text::Wrap::columns> should be set to the full width of your output
|
||||
device. In fact, every resulting line will have length of no more than
|
||||
C<$columns - 1>.
|
||||
|
||||
It is possible to control which characters terminate words by
|
||||
modifying C<$Text::Wrap::break>. Set this to a string such as
|
||||
C<'[\s:]'> (to break before spaces or colons) or a pre-compiled regexp
|
||||
such as C<qr/[\s']/> (to break before spaces or apostrophes). The
|
||||
default is simply C<'\s'>; that is, words are terminated by spaces.
|
||||
(This means, among other things, that trailing punctuation such as
|
||||
full stops or commas stay with the word they are "attached" to.)
|
||||
Setting C<$Text::Wrap::break> to a regular expression that doesn't
|
||||
eat any characters (perhaps just a forward look-ahead assertion) will
|
||||
cause warnings.
|
||||
|
||||
Beginner note: In example 2, above C<$columns> is imported into
|
||||
the local namespace, and set locally. In example 3,
|
||||
C<$Text::Wrap::columns> is set in its own namespace without importing it.
|
||||
|
||||
C<Text::Wrap::wrap()> starts its work by expanding all the tabs in its
|
||||
input into spaces. The last thing it does it to turn spaces back
|
||||
into tabs. If you do not want tabs in your results, set
|
||||
C<$Text::Wrap::unexpand> to a false value. Likewise if you do not
|
||||
want to use 8-character tabstops, set C<$Text::Wrap::tabstop> to
|
||||
the number of characters you do want for your tabstops.
|
||||
|
||||
If you want to separate your lines with something other than C<\n>
|
||||
then set C<$Text::Wrap::separator> to your preference. This replaces
|
||||
all newlines with C<$Text::Wrap::separator>. If you just want to
|
||||
preserve existing newlines but add new breaks with something else, set
|
||||
C<$Text::Wrap::separator2> instead.
|
||||
|
||||
When words that are longer than C<$columns> are encountered, they
|
||||
are broken up. C<wrap()> adds a C<"\n"> at column C<$columns>.
|
||||
This behavior can be overridden by setting C<$huge> to
|
||||
'die' or to 'overflow'. When set to 'die', large words will cause
|
||||
C<die()> to be called. When set to 'overflow', large words will be
|
||||
left intact.
|
||||
|
||||
Historical notes: 'die' used to be the default value of
|
||||
C<$huge>. Now, 'wrap' is the default value.
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
Code:
|
||||
|
||||
print wrap("\t","",<<END);
|
||||
This is a bit of text that forms
|
||||
a normal book-style indented paragraph
|
||||
END
|
||||
|
||||
Result:
|
||||
|
||||
" This is a bit of text that forms
|
||||
a normal book-style indented paragraph
|
||||
"
|
||||
|
||||
Code:
|
||||
|
||||
$Text::Wrap::columns=20;
|
||||
$Text::Wrap::separator="|";
|
||||
print wrap("","","This is a bit of text that forms a normal book-style paragraph");
|
||||
|
||||
Result:
|
||||
|
||||
"This is a bit of|text that forms a|normal book-style|paragraph"
|
||||
|
||||
=head1 SUBVERSION
|
||||
|
||||
This module comes in two flavors: one for modern perls (5.10 and above)
|
||||
and one for ancient obsolete perls. The version for modern perls has
|
||||
support for Unicode. The version for old perls does not. You can tell
|
||||
which version you have installed by looking at C<$Text::Wrap::SUBVERSION>:
|
||||
it is C<old> for obsolete perls and C<modern> for current perls.
|
||||
|
||||
This man page is for the version for modern perls and so that's probably
|
||||
what you've got.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
For correct handling of East Asian half- and full-width characters,
|
||||
see L<Text::WrapI18N>. For more detailed controls: L<Text::Format>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
David Muir Sharnoff <cpan@dave.sharnoff.org> with help from Tim Pierce and
|
||||
many many others.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
Copyright (C) 1996-2009 David Muir Sharnoff.
|
||||
Copyright (C) 2012-2013 Google, Inc.
|
||||
This module may be modified, used, copied, and redistributed at your own risk.
|
||||
Although allowed by the preceding license, please do not publicly
|
||||
redistribute modified versions of this code with the name "Text::Wrap"
|
||||
unless it passes the unmodified Text::Wrap test suite.
|
||||
Reference in New Issue
Block a user