line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Text::Autoformat; |
2
|
|
|
|
|
|
|
$Text::Autoformat::VERSION = '1.74'; |
3
|
4
|
|
|
4
|
|
68513
|
use 5.006; |
|
4
|
|
|
|
|
12
|
|
4
|
4
|
|
|
4
|
|
18
|
use strict; |
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
93
|
|
5
|
4
|
|
|
4
|
|
16
|
use warnings; |
|
4
|
|
|
|
|
17
|
|
|
4
|
|
|
|
|
104
|
|
6
|
4
|
|
|
4
|
|
21
|
use Carp; |
|
4
|
|
|
|
|
5
|
|
|
4
|
|
|
|
|
390
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
require Exporter; |
9
|
|
|
|
|
|
|
|
10
|
4
|
|
|
4
|
|
4000
|
use Text::Reform qw( form tag break_at break_with break_wrap break_TeX ); |
|
4
|
|
|
|
|
29993
|
|
|
4
|
|
|
|
|
28
|
|
11
|
4
|
|
|
4
|
|
3226
|
use Text::Autoformat::Hang; |
|
4
|
|
|
|
|
11
|
|
|
4
|
|
|
|
|
138
|
|
12
|
4
|
|
|
4
|
|
2331
|
use Text::Autoformat::NullHang; |
|
4
|
|
|
|
|
10
|
|
|
4
|
|
|
|
|
2668
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
15
|
|
|
|
|
|
|
our @EXPORT = qw( autoformat ); |
16
|
|
|
|
|
|
|
our @EXPORT_OK = |
17
|
|
|
|
|
|
|
qw( form tag break_at break_with break_wrap break_TeX ignore_headers ); |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
my %std_highlight_ignore = map {$_=>1} qw { |
21
|
|
|
|
|
|
|
a an at as and are |
22
|
|
|
|
|
|
|
but by |
23
|
|
|
|
|
|
|
ere |
24
|
|
|
|
|
|
|
for from |
25
|
|
|
|
|
|
|
in into is |
26
|
|
|
|
|
|
|
of on onto or over |
27
|
|
|
|
|
|
|
per |
28
|
|
|
|
|
|
|
the to that than |
29
|
|
|
|
|
|
|
until unto upon |
30
|
|
|
|
|
|
|
via |
31
|
|
|
|
|
|
|
with while whilst within without |
32
|
|
|
|
|
|
|
}; |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
my $STD_HIGHLIGHT_IGNORES = sub { |
35
|
|
|
|
|
|
|
my ($word) = @_; |
36
|
|
|
|
|
|
|
return $std_highlight_ignore{lc $word} ? recase($word,'lower') : recase($word,'title'); |
37
|
|
|
|
|
|
|
}; |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
my @entities = qw { |
40
|
|
|
|
|
|
|
Á á Â â Æ æ |
41
|
|
|
|
|
|
|
À à Α α Ã ã |
42
|
|
|
|
|
|
|
Ä ä Β β Ç ç |
43
|
|
|
|
|
|
|
Χ χ Δ δ É é |
44
|
|
|
|
|
|
|
Ê ê È è Ε ε |
45
|
|
|
|
|
|
|
Η η Ð ð Ë ë |
46
|
|
|
|
|
|
|
Γ γ Í í Î î |
47
|
|
|
|
|
|
|
Ì ì Ι ι Ï ï |
48
|
|
|
|
|
|
|
Κ κ Λ λ Μ μ |
49
|
|
|
|
|
|
|
Ñ ñ Ν ν Ó ó |
50
|
|
|
|
|
|
|
Ô ô Œ œ Ò ò |
51
|
|
|
|
|
|
|
Ω ω Ο ο Õ õ |
52
|
|
|
|
|
|
|
Ö ö Φ φ Π π |
53
|
|
|
|
|
|
|
″ ′ Ψ ψ Ρ ρ |
54
|
|
|
|
|
|
|
Š š Σ σ Τ τ |
55
|
|
|
|
|
|
|
Θ θ Þ þ Ú ú |
56
|
|
|
|
|
|
|
Û û Ù ù Υ υ |
57
|
|
|
|
|
|
|
Ü ü Ξ ξ Ý ý |
58
|
|
|
|
|
|
|
Ÿ ÿ Ζ ζ |
59
|
|
|
|
|
|
|
}; |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
my %lower_entities = @entities; |
62
|
|
|
|
|
|
|
my %upper_entities = reverse @entities; |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
my %casing = ( |
65
|
|
|
|
|
|
|
lower => [ \%lower_entities, \%lower_entities, |
66
|
|
|
|
|
|
|
sub { $_ = lc }, sub { $_ = lc } ], |
67
|
|
|
|
|
|
|
upper => [ \%upper_entities, \%upper_entities, |
68
|
|
|
|
|
|
|
sub { $_ = uc }, sub { $_ = uc } ], |
69
|
|
|
|
|
|
|
title => [ \%upper_entities, \%lower_entities, |
70
|
|
|
|
|
|
|
sub { $_ = ucfirst lc }, sub { $_ = lc } ], |
71
|
|
|
|
|
|
|
); |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
my $default_margin = 72; |
74
|
|
|
|
|
|
|
my $default_widow = 10; |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
$Text::Autoformat::widow_slack = 0.1; |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
sub defn($) |
80
|
|
|
|
|
|
|
{ |
81
|
130
|
50
|
|
130
|
0
|
548
|
return $_[0] if defined $_[0]; |
82
|
0
|
|
|
|
|
0
|
return ""; |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
my $ignore_headers = qr/ |
86
|
|
|
|
|
|
|
\A |
87
|
|
|
|
|
|
|
(?: From \b .* $)? |
88
|
|
|
|
|
|
|
(?: [^:\n]+ : .* \n |
89
|
|
|
|
|
|
|
(?: [ \t] .* \n)* |
90
|
|
|
|
|
|
|
)+ |
91
|
|
|
|
|
|
|
\s* |
92
|
|
|
|
|
|
|
\Z |
93
|
|
|
|
|
|
|
/mx; |
94
|
|
|
|
|
|
|
my $ignore_indent = qr/^[^\S\n].*(\n[^\S\n].*)*$/; |
95
|
|
|
|
|
|
|
|
96
|
6
|
100
|
|
6
|
0
|
40
|
sub ignore_headers { $_[0] && /$ignore_headers/ } |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# BITS OF A TEXT LINE |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
my $quotechar = qq{[!#%=|:;]}; |
101
|
|
|
|
|
|
|
my $quotechunk = qq{(?:$quotechar(?![a-z])|(?:[a-z]\\w*)?>+)}; |
102
|
|
|
|
|
|
|
my $QUOTER = qq{(?:(?i)(?:$quotechunk(?:[ \\t]*$quotechunk)*))}; |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
my $separator = q/(?:[-_]{2,}|[=#*]{3,}|[+~]{4,})/; |
105
|
|
|
|
|
|
|
|
106
|
4
|
|
|
4
|
|
6741
|
use overload; |
|
4
|
|
|
|
|
4705
|
|
|
4
|
|
|
|
|
28
|
|
107
|
|
|
|
|
|
|
sub autoformat # ($text, %args) |
108
|
|
|
|
|
|
|
{ |
109
|
4
|
|
|
4
|
0
|
988
|
my ($text,%args,$toSTDOUT); |
110
|
|
|
|
|
|
|
|
111
|
4
|
|
|
|
|
13
|
foreach ( @_ ) |
112
|
|
|
|
|
|
|
{ |
113
|
7
|
100
|
33
|
|
|
52
|
if (ref eq 'HASH') |
|
|
50
|
33
|
|
|
|
|
114
|
3
|
|
|
|
|
19
|
{ %args = (%args, %$_) } |
115
|
|
|
|
|
|
|
elsif (!defined($text) && !ref || overload::Method($_,'""')) |
116
|
4
|
|
|
|
|
11
|
{ $text = "$_" } |
117
|
|
|
|
|
|
|
else { |
118
|
0
|
|
|
|
|
0
|
croak q{Usage: autoformat([text],[{options}])} |
119
|
|
|
|
|
|
|
} |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
|
122
|
4
|
50
|
|
|
|
18
|
unless (defined $text) { |
123
|
0
|
|
|
|
|
0
|
$text = join("",); |
124
|
0
|
|
|
|
|
0
|
$toSTDOUT = !defined wantarray(); |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
|
127
|
4
|
100
|
|
|
|
23
|
return $text unless $text =~ /\S/; |
128
|
|
|
|
|
|
|
|
129
|
3
|
100
|
|
|
|
12
|
$args{right} = $default_margin unless exists $args{right}; |
130
|
3
|
50
|
|
|
|
13
|
$args{justify} = "" unless exists $args{justify}; |
131
|
3
|
50
|
50
|
|
|
20
|
$args{widow} = 0 if ($args{justify}||"") =~ /full/; |
132
|
3
|
50
|
|
|
|
11
|
$args{widow} = $default_widow unless exists $args{widow}; |
133
|
3
|
50
|
|
|
|
11
|
$args{case} = '' unless exists $args{case}; |
134
|
3
|
100
|
|
|
|
10
|
$args{lists} = 1 unless exists $args{lists}; |
135
|
3
|
50
|
|
|
|
12
|
$args{squeeze} = 1 unless exists $args{squeeze}; |
136
|
3
|
50
|
|
|
|
11
|
$args{gap} = 0 unless exists $args{gap}; |
137
|
3
|
50
|
|
|
|
20
|
$args{break} = break_at('-') unless exists $args{break}; |
138
|
3
|
|
|
|
|
43
|
$args{impfill} = ! exists $args{fill}; |
139
|
3
|
|
|
|
|
8
|
$args{expfill} = $args{fill}; |
140
|
3
|
50
|
|
|
|
13
|
$args{tabspace} = 8 unless exists $args{tabspace}; |
141
|
3
|
50
|
|
|
|
9
|
$args{renumber} = 1 unless exists $args{renumber}; |
142
|
3
|
50
|
|
|
|
10
|
$args{autocentre} = 1 unless exists $args{autocentre}; |
143
|
3
|
50
|
|
|
|
10
|
$args{_centred} = 1 if $args{justify} =~ /cent(er(ed)?|red?)/; |
144
|
3
|
|
100
|
|
|
21
|
$args{all} ||= $args{mail}; |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
# SPECIAL IGNORANCE... |
147
|
3
|
100
|
|
|
|
9
|
if ($args{ignore}) { |
148
|
2
|
|
|
|
|
4
|
$args{all} = 1; |
149
|
2
|
|
|
|
|
6
|
$args{ignore} = _build_ignore( $args{ignore} ); |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
else { |
152
|
1
|
|
|
1
|
|
5
|
$args{ignore} = sub{0}; |
|
1
|
|
|
|
|
3
|
|
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
|
155
|
3
|
100
|
|
|
|
13
|
if ( $args{mail} ) { |
156
|
1
|
|
|
|
|
2
|
my $ignore = $args{ignore}; |
157
|
1
|
100
|
|
7
|
|
4
|
$args{ignore} = sub { $ignore->(@_) || ignore_headers(@_) }; |
|
7
|
|
|
|
|
16
|
|
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
# DETABIFY |
161
|
3
|
|
|
|
|
27
|
my @rawlines = split /\n/, $text; |
162
|
4
|
|
|
4
|
|
5693
|
use Text::Tabs; $tabstop = $args{tabspace}; |
|
4
|
|
|
|
|
3102
|
|
|
4
|
|
|
|
|
18173
|
|
|
3
|
|
|
|
|
7
|
|
163
|
3
|
|
|
|
|
15
|
@rawlines = expand(@rawlines); |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
# HANDLE QUOTING CHANGE |
166
|
3
|
50
|
|
|
|
199
|
my $quoter = exists $args{quoter} ? $args{quoter} : $QUOTER; |
167
|
3
|
|
|
|
|
9
|
$quoter =~ s//$QUOTER/g; |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
# PARSE EACH LINE |
170
|
|
|
|
|
|
|
|
171
|
3
|
|
|
|
|
5
|
my $pre = 0; |
172
|
3
|
|
|
|
|
5
|
my @lines; |
173
|
3
|
|
|
|
|
8
|
foreach (@rawlines) |
174
|
|
|
|
|
|
|
{ |
175
|
26
|
|
|
|
|
73
|
push @lines, { raw => $_ }; |
176
|
26
|
50
|
|
|
|
431
|
s/\A([ \t]*)($quoter?)([ \t]*)// |
177
|
|
|
|
|
|
|
or die "Internal Error ($@) on '$_'"; |
178
|
26
|
|
|
|
|
67
|
$lines[-1]{presig} = $lines[-1]{prespace} = defn $1; |
179
|
26
|
|
|
|
|
61
|
$lines[-1]{presig} .= $lines[-1]{quoter} = defn $2; |
180
|
26
|
|
|
|
|
53
|
$lines[-1]{presig} .= $lines[-1]{quotespace} = defn $3; |
181
|
|
|
|
|
|
|
|
182
|
26
|
|
|
|
|
102
|
$lines[-1]{hang} = Text::Autoformat::Hang->new($_, $args{lists}); |
183
|
|
|
|
|
|
|
|
184
|
26
|
50
|
|
|
|
247
|
s/([ \t]*)(.*?)(\s*)$// |
185
|
|
|
|
|
|
|
or die "Internal Error ($@) on '$_'"; |
186
|
26
|
|
|
|
|
84
|
$lines[-1]{hangspace} = defn $1; |
187
|
26
|
|
|
|
|
52
|
$lines[-1]{text} = defn $2; |
188
|
26
|
|
66
|
|
|
104
|
$lines[-1]{empty} = $lines[-1]{hang}->empty() && $2 !~ /\S/; |
189
|
26
|
|
|
|
|
189
|
$lines[-1]{separator} = $lines[-1]{text} =~ /^$separator$/; |
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
# SUBDIVIDE DOCUMENT INTO COHERENT SUBSECTIONS |
193
|
|
|
|
|
|
|
|
194
|
3
|
|
|
|
|
6
|
my @chunks; |
195
|
3
|
|
|
|
|
9
|
push @chunks, [shift @lines]; |
196
|
3
|
|
|
|
|
8
|
foreach my $line (@lines) |
197
|
|
|
|
|
|
|
{ |
198
|
23
|
100
|
33
|
|
|
204
|
if ($line->{separator} || |
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
66
|
|
|
|
|
199
|
|
|
|
|
|
|
$line->{quoter} ne $chunks[-1][-1]->{quoter} || |
200
|
|
|
|
|
|
|
$line->{empty} || |
201
|
|
|
|
|
|
|
@chunks && $chunks[-1][-1]->{empty}) |
202
|
|
|
|
|
|
|
{ |
203
|
10
|
|
|
|
|
24
|
push @chunks, [$line]; |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
else |
206
|
|
|
|
|
|
|
{ |
207
|
13
|
|
|
|
|
17
|
push @{$chunks[-1]}, $line; |
|
13
|
|
|
|
|
34
|
|
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
# DETECT CENTRED PARAS |
214
|
|
|
|
|
|
|
|
215
|
3
|
|
|
|
|
7
|
CHUNK: foreach my $chunk ( @chunks ) |
216
|
|
|
|
|
|
|
{ |
217
|
13
|
50
|
66
|
|
|
90
|
next CHUNK if !$args{autocentre} || @$chunk < 2 || $chunk->[0]{hang}; |
|
|
|
66
|
|
|
|
|
218
|
0
|
|
|
|
|
0
|
my @length; |
219
|
0
|
|
|
|
|
0
|
my $ave = 0; |
220
|
0
|
|
|
|
|
0
|
foreach my $line (@$chunk) |
221
|
|
|
|
|
|
|
{ |
222
|
|
|
|
|
|
|
my $prespace = $line->{quoter} ? $line->{quotespace} |
223
|
0
|
0
|
|
|
|
0
|
: $line->{prespace}; |
224
|
|
|
|
|
|
|
my $pagewidth = |
225
|
0
|
|
|
|
|
0
|
2*length($prespace) + length($line->{text}); |
226
|
0
|
|
|
|
|
0
|
push @length, [length $prespace,$pagewidth]; |
227
|
0
|
|
|
|
|
0
|
$ave += $pagewidth; |
228
|
|
|
|
|
|
|
} |
229
|
0
|
|
|
|
|
0
|
$ave /= @length; |
230
|
0
|
|
|
|
|
0
|
my $diffpre = 0; |
231
|
0
|
|
|
|
|
0
|
foreach my $l (0..$#length) |
232
|
|
|
|
|
|
|
{ |
233
|
0
|
0
|
|
|
|
0
|
next CHUNK unless abs($length[$l][1]-$ave) <= 2; |
234
|
0
|
0
|
0
|
|
|
0
|
$diffpre ||= $length[$l-1][0] != $length[$l][0] |
235
|
|
|
|
|
|
|
if $l > 0; |
236
|
|
|
|
|
|
|
} |
237
|
0
|
0
|
|
|
|
0
|
next CHUNK unless $diffpre; |
238
|
0
|
|
|
|
|
0
|
foreach my $line (@$chunk) |
239
|
|
|
|
|
|
|
{ |
240
|
0
|
|
|
|
|
0
|
$line->{centred} = 1; |
241
|
|
|
|
|
|
|
($line->{quoter} ? $line->{quotespace} |
242
|
0
|
0
|
|
|
|
0
|
: $line->{prespace}) = ""; |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
# REDIVIDE INTO PARAGRAPHS |
247
|
|
|
|
|
|
|
|
248
|
3
|
|
|
|
|
6
|
my @paras; |
249
|
3
|
|
|
|
|
5
|
foreach my $chunk ( @chunks ) |
250
|
|
|
|
|
|
|
{ |
251
|
13
|
|
|
|
|
17
|
my $first = 1; |
252
|
13
|
|
|
|
|
16
|
my $firstfrom; |
253
|
13
|
|
|
|
|
18
|
foreach my $line ( @{$chunk} ) |
|
13
|
|
|
|
|
21
|
|
254
|
|
|
|
|
|
|
{ |
255
|
26
|
100
|
66
|
|
|
145
|
if ($first || |
|
|
|
66
|
|
|
|
|
|
|
|
33
|
|
|
|
|
256
|
|
|
|
|
|
|
$line->{quoter} ne $paras[-1]->{quoter} || |
257
|
|
|
|
|
|
|
$paras[-1]->{separator} || |
258
|
|
|
|
|
|
|
!$line->{hang}->empty |
259
|
|
|
|
|
|
|
) |
260
|
|
|
|
|
|
|
{ |
261
|
13
|
|
|
|
|
22
|
push @paras, $line; |
262
|
13
|
|
|
|
|
16
|
$first = 0; |
263
|
13
|
|
|
|
|
27
|
$firstfrom = length($line->{raw}) - length($line->{text}); |
264
|
|
|
|
|
|
|
} |
265
|
|
|
|
|
|
|
else |
266
|
|
|
|
|
|
|
{ |
267
|
13
|
|
|
|
|
30
|
my $extraspace = length($line->{raw}) - length($line->{text}) - $firstfrom; |
268
|
13
|
100
|
|
|
|
30
|
$extraspace = 0 if $extraspace < 0; |
269
|
13
|
|
|
|
|
42
|
$paras[-1]->{text} .= "\n" . q{ }x$extraspace . $line->{text}; |
270
|
13
|
|
|
|
|
42
|
$paras[-1]->{raw} .= "\n" . $line->{raw}; |
271
|
|
|
|
|
|
|
} |
272
|
|
|
|
|
|
|
} |
273
|
|
|
|
|
|
|
} |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
# SELECT PARAS TO HANDLE |
276
|
|
|
|
|
|
|
|
277
|
3
|
|
|
|
|
6
|
my $remainder = ""; |
278
|
3
|
50
|
|
|
|
9
|
if ($args{all}) { # STOP AT MAIL TERMINATOR IF $args{mail} |
279
|
3
|
|
|
|
|
5
|
my $lastignored = 1; |
280
|
3
|
|
|
|
|
18
|
for my $index (0..$#paras) { |
281
|
13
|
|
|
|
|
31
|
local $_ = $paras[$index]{raw} . "\n"; |
282
|
13
|
|
|
|
|
31
|
$paras[$index]{ignore} = $args{ignore}($lastignored); |
283
|
13
|
|
100
|
|
|
46
|
$lastignored &&= $paras[$index]{ignore}; |
284
|
13
|
50
|
66
|
|
|
59
|
next unless $args{mail} && /^--\s*$/; |
285
|
0
|
|
|
|
|
0
|
$remainder = join "\n", map { $_->{raw} } splice @paras, $index; |
|
0
|
|
|
|
|
0
|
|
286
|
0
|
0
|
|
|
|
0
|
$remainder .= "\n" unless $remainder =~ /\n\z/; |
287
|
0
|
|
|
|
|
0
|
last; |
288
|
|
|
|
|
|
|
} |
289
|
|
|
|
|
|
|
} |
290
|
|
|
|
|
|
|
else { # JUST THE FIRST PARA |
291
|
0
|
|
|
|
|
0
|
$remainder = join "\n", map { $_->{raw} } @paras[1..$#paras]; |
|
0
|
|
|
|
|
0
|
|
292
|
0
|
0
|
|
|
|
0
|
$remainder .= "\n" unless $remainder =~ /\n\z/; |
293
|
0
|
|
|
|
|
0
|
@paras = ( $paras[0] ); |
294
|
|
|
|
|
|
|
} |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
# RE-CASE TEXT |
297
|
3
|
50
|
|
|
|
11
|
if ($args{case}) { |
298
|
0
|
|
|
|
|
0
|
foreach my $para ( @paras ) { |
299
|
0
|
0
|
|
|
|
0
|
next if $para->{ignore}; |
300
|
0
|
0
|
|
|
|
0
|
if (ref $args{case} eq 'CODE') { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
301
|
0
|
|
|
|
|
0
|
$para->{text} = entitle($para->{text}, $args{case}); |
302
|
|
|
|
|
|
|
} |
303
|
|
|
|
|
|
|
elsif ($args{case} =~ /upper/i) { |
304
|
0
|
|
|
|
|
0
|
$para->{text} = recase($para->{text}, 'upper'); |
305
|
|
|
|
|
|
|
} |
306
|
|
|
|
|
|
|
elsif ($args{case} =~ /lower/i) { |
307
|
0
|
|
|
|
|
0
|
$para->{text} = recase($para->{text}, 'lower'); |
308
|
|
|
|
|
|
|
} |
309
|
|
|
|
|
|
|
elsif ($args{case} =~ /title/i) { |
310
|
0
|
|
|
|
|
0
|
$para->{text} = entitle($para->{text}, 0); |
311
|
|
|
|
|
|
|
} |
312
|
|
|
|
|
|
|
elsif ($args{case} =~ /highlight/i) { |
313
|
0
|
|
|
|
|
0
|
$para->{text} = entitle($para->{text}, $STD_HIGHLIGHT_IGNORES); |
314
|
|
|
|
|
|
|
} |
315
|
|
|
|
|
|
|
elsif ($args{case} =~ /sentence(\s*)/i) { |
316
|
0
|
|
|
|
|
0
|
my $trailer = $1; |
317
|
0
|
0
|
0
|
|
|
0
|
$args{squeeze}=0 if $trailer && $trailer ne " "; |
318
|
0
|
|
|
|
|
0
|
ensentence(); |
319
|
0
|
|
|
|
|
0
|
$para->{text} =~ s/(\S+(\s+|$))/ensentence($1, $trailer)/ge; |
|
0
|
|
|
|
|
0
|
|
320
|
|
|
|
|
|
|
} |
321
|
0
|
|
|
|
|
0
|
$para->{text} =~ s/\b([A-Z])[.]/\U$1./gi; # ABBREVS |
322
|
|
|
|
|
|
|
} |
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
# ALIGN QUOTERS |
326
|
|
|
|
|
|
|
# DETERMINE HANGING MARKER TYPE (BULLET, ALPHA, ROMAN, ETC.) |
327
|
|
|
|
|
|
|
|
328
|
3
|
|
|
|
|
6
|
my %sigs; |
329
|
3
|
|
|
|
|
4
|
my $lastquoted = 0; |
330
|
3
|
|
|
|
|
4
|
my $lastprespace = 0; |
331
|
3
|
|
|
|
|
9
|
for my $i ( 0..$#paras ) |
332
|
|
|
|
|
|
|
{ |
333
|
13
|
|
|
|
|
19
|
my $para = $paras[$i]; |
334
|
13
|
100
|
|
|
|
33
|
next if $para->{ignore}; |
335
|
|
|
|
|
|
|
|
336
|
9
|
50
|
|
|
|
20
|
if ($para->{quoter}) |
337
|
|
|
|
|
|
|
{ |
338
|
0
|
0
|
|
|
|
0
|
if ($lastquoted) { $para->{prespace} = $lastprespace } |
|
0
|
|
|
|
|
0
|
|
339
|
0
|
|
|
|
|
0
|
else { $lastquoted = 1; $lastprespace = $para->{prespace} } |
|
0
|
|
|
|
|
0
|
|
340
|
|
|
|
|
|
|
} |
341
|
|
|
|
|
|
|
else |
342
|
|
|
|
|
|
|
{ |
343
|
9
|
|
|
|
|
14
|
$lastquoted = 0; |
344
|
|
|
|
|
|
|
} |
345
|
|
|
|
|
|
|
} |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
# RENUMBER PARAGRAPHS |
348
|
|
|
|
|
|
|
|
349
|
3
|
|
|
|
|
7
|
for my $para ( @paras ) { |
350
|
13
|
100
|
|
|
|
32
|
next if $para->{ignore}; |
351
|
9
|
|
|
|
|
36
|
my $sig = $para->{presig} . $para->{hang}->signature(); |
352
|
9
|
|
|
|
|
11
|
push @{$sigs{$sig}{hangref}}, $para; |
|
9
|
|
|
|
|
25
|
|
353
|
|
|
|
|
|
|
$sigs{$sig}{hangfields} = $para->{hang}->fields()-1 |
354
|
9
|
100
|
|
|
|
38
|
unless defined $sigs{$sig}{hangfields}; |
355
|
|
|
|
|
|
|
} |
356
|
|
|
|
|
|
|
|
357
|
3
|
|
|
|
|
16
|
while (my ($sig,$val) = each %sigs) { |
358
|
3
|
50
|
|
|
|
17
|
next unless $sig =~ /rom/; |
359
|
0
|
|
|
|
|
0
|
field: for my $field ( 0..$val->{hangfields} ) |
360
|
|
|
|
|
|
|
{ |
361
|
0
|
|
|
|
|
0
|
my $romlen = 0; |
362
|
0
|
|
|
|
|
0
|
foreach my $para ( @{$val->{hangref}} ) |
|
0
|
|
|
|
|
0
|
|
363
|
|
|
|
|
|
|
{ |
364
|
0
|
|
|
|
|
0
|
my $hang = $para->{hang}; |
365
|
0
|
|
|
|
|
0
|
my $fieldtype = $hang->field($field); |
366
|
|
|
|
|
|
|
next field |
367
|
0
|
0
|
0
|
|
|
0
|
unless $fieldtype && $fieldtype =~ /rom|let/; |
368
|
0
|
0
|
|
|
|
0
|
if ($fieldtype eq 'let') { |
369
|
0
|
|
|
|
|
0
|
foreach my $para ( @{$val->{hangref}} ) { |
|
0
|
|
|
|
|
0
|
|
370
|
0
|
|
|
|
|
0
|
$hang->field($field=>'let') |
371
|
|
|
|
|
|
|
} |
372
|
|
|
|
|
|
|
} |
373
|
|
|
|
|
|
|
else { |
374
|
0
|
|
|
|
|
0
|
$romlen += length $hang->val($field); |
375
|
|
|
|
|
|
|
} |
376
|
|
|
|
|
|
|
} |
377
|
|
|
|
|
|
|
# NO ROMAN LETTER > 1 CHAR -> ALPHABETICS |
378
|
0
|
0
|
|
|
|
0
|
if ($romlen <= @{$val->{hangref}}) { |
|
0
|
|
|
|
|
0
|
|
379
|
0
|
|
|
|
|
0
|
foreach my $para ( @{$val->{hangref}} ) { |
|
0
|
|
|
|
|
0
|
|
380
|
0
|
|
|
|
|
0
|
$para->{hang}->field($field=>'let') |
381
|
|
|
|
|
|
|
} |
382
|
|
|
|
|
|
|
} |
383
|
|
|
|
|
|
|
} |
384
|
|
|
|
|
|
|
} |
385
|
|
|
|
|
|
|
|
386
|
3
|
|
|
|
|
5
|
my %prev; |
387
|
|
|
|
|
|
|
|
388
|
3
|
|
|
|
|
6
|
for my $para ( @paras ) { |
389
|
13
|
100
|
|
|
|
34
|
next if $para->{ignore}; |
390
|
9
|
|
|
|
|
27
|
my $sig = $para->{presig} . $para->{hang}->signature(); |
391
|
9
|
50
|
|
|
|
26
|
if ($args{renumber}) { |
392
|
9
|
50
|
|
|
|
24
|
unless ($para->{quoter}) { |
393
|
9
|
|
|
|
|
48
|
$para->{hang}->incr($prev{""}, $prev{$sig}); |
394
|
|
|
|
|
|
|
$prev{""} = $prev{$sig} = $para->{hang} |
395
|
9
|
50
|
|
|
|
32
|
unless $para->{hang}->empty; |
396
|
|
|
|
|
|
|
} |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
# COLLECT MAXIMAL HANG LENGTHS BY SIGNATURE |
400
|
|
|
|
|
|
|
|
401
|
9
|
|
|
|
|
28
|
my $siglen = $para->{hang}->length(); |
402
|
|
|
|
|
|
|
$sigs{$sig}{hanglen} = $siglen |
403
|
|
|
|
|
|
|
if ! $sigs{$sig}{hanglen} || |
404
|
9
|
50
|
33
|
|
|
37
|
$sigs{$sig}{hanglen} < $siglen; |
405
|
|
|
|
|
|
|
} |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
# PROPAGATE MAXIMAL HANG LENGTH |
408
|
|
|
|
|
|
|
|
409
|
3
|
|
|
|
|
14
|
while (my ($sig,$val) = each %sigs) |
410
|
|
|
|
|
|
|
{ |
411
|
3
|
|
|
|
|
5
|
foreach (@{$val->{hangref}}) { |
|
3
|
|
|
|
|
7
|
|
412
|
9
|
|
|
|
|
26
|
$_->{hanglen} = $val->{hanglen}; |
413
|
|
|
|
|
|
|
} |
414
|
|
|
|
|
|
|
} |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
# BUILD FORMAT FOR EACH PARA THEN FILL IT |
417
|
|
|
|
|
|
|
|
418
|
3
|
|
|
|
|
6
|
$text = ""; |
419
|
3
|
50
|
33
|
|
|
20
|
my $gap = @paras && $paras[0]->{empty} ? 0 : $args{gap}; |
420
|
3
|
|
|
|
|
7
|
for my $para ( @paras ) |
421
|
|
|
|
|
|
|
{ |
422
|
13
|
100
|
|
|
|
28
|
if ($para->{empty}) { |
423
|
5
|
|
|
|
|
13
|
$gap += 1 + ($para->{text} =~ tr/\n/\n/); |
424
|
|
|
|
|
|
|
} |
425
|
13
|
100
|
|
|
|
29
|
if ($para->{ignore}) { |
426
|
4
|
50
|
|
|
|
19
|
$text .= (!$para->{empty} ? "\n"x($args{gap}-$gap > 0 ? ($args{gap}-$gap) : 0) : "") ; |
|
|
50
|
|
|
|
|
|
427
|
4
|
|
|
|
|
8
|
$text .= $para->{raw}; |
428
|
4
|
50
|
|
|
|
14
|
$text .= "\n" unless $para->{raw} =~ /\n\z/; |
429
|
|
|
|
|
|
|
} |
430
|
|
|
|
|
|
|
else { |
431
|
|
|
|
|
|
|
my $leftmargin = $args{left} ? " "x($args{left}-1) |
432
|
9
|
50
|
|
|
|
25
|
: $para->{prespace}; |
433
|
9
|
|
33
|
|
|
43
|
my $hlen = $para->{hanglen} || $para->{hang}->length; |
434
|
9
|
50
|
|
|
|
25
|
my $hfield = ($hlen==1 ? '~' : '>'x$hlen); |
435
|
9
|
|
|
|
|
14
|
my @hang; |
436
|
9
|
50
|
|
|
|
19
|
push @hang, $para->{hang}->stringify if $hlen; |
437
|
|
|
|
|
|
|
my $format = $leftmargin |
438
|
|
|
|
|
|
|
. quotemeta($para->{quoter}) |
439
|
|
|
|
|
|
|
. $para->{quotespace} |
440
|
|
|
|
|
|
|
. $hfield |
441
|
9
|
|
|
|
|
26
|
. $para->{hangspace}; |
442
|
9
|
|
|
|
|
25
|
my $rightslack = int (($args{right}-length $leftmargin)*$Text::Autoformat::widow_slack); |
443
|
9
|
|
|
|
|
17
|
my ($widow_okay, $rightindent, $firsttext, $newtext) = (0,0); |
444
|
9
|
|
33
|
|
|
11
|
do { |
445
|
|
|
|
|
|
|
my $tlen = $args{right}-$rightindent-length($leftmargin |
446
|
|
|
|
|
|
|
. $para->{quoter} |
447
|
|
|
|
|
|
|
. $para->{quotespace} |
448
|
|
|
|
|
|
|
. $hfield |
449
|
9
|
|
|
|
|
25
|
. $para->{hangspace}); |
450
|
9
|
50
|
|
|
|
30
|
next if blockquote($text,$para, $format, $tlen, \@hang, \%args); |
451
|
|
|
|
|
|
|
my $tfield = ( $tlen==1 ? '~' |
452
|
|
|
|
|
|
|
: $para->{centred}||$args{_centred} ? '|'x$tlen |
453
|
|
|
|
|
|
|
: $args{justify} eq 'right' ? ']'x$tlen |
454
|
|
|
|
|
|
|
: $args{justify} eq 'full' ? '['x($tlen-2) . ']]' |
455
|
9
|
50
|
33
|
|
|
124
|
: $para->{centred}||$args{_centred} ? '|'x$tlen |
|
|
50
|
33
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
456
|
|
|
|
|
|
|
: '['x$tlen |
457
|
|
|
|
|
|
|
); |
458
|
9
|
|
|
|
|
20
|
my $tryformat = "$format$tfield"; |
459
|
|
|
|
|
|
|
$newtext = (!$para->{empty} ? "\n"x($args{gap} > $gap ? ($args{gap}-$gap) : 0) : "") |
460
|
|
|
|
|
|
|
. form( { squeeze=>$args{squeeze}, trim=>1, |
461
|
|
|
|
|
|
|
break=>$args{break}, |
462
|
|
|
|
|
|
|
fill => !(!($args{expfill} |
463
|
|
|
|
|
|
|
|| $args{impfill} && |
464
|
|
|
|
|
|
|
!$para->{centred})) |
465
|
|
|
|
|
|
|
}, |
466
|
|
|
|
|
|
|
$tryformat, @hang, |
467
|
9
|
50
|
33
|
|
|
115
|
$para->{text}); |
|
|
100
|
|
|
|
|
|
468
|
9
|
|
33
|
|
|
4978
|
$firsttext ||= $newtext; |
469
|
9
|
|
|
|
|
40
|
(my $widow) = $newtext =~ /([^\n]*)$/; |
470
|
9
|
|
|
|
|
21
|
$widow =~ s/^\s+//; |
471
|
9
|
|
66
|
|
|
55
|
$widow_okay = $para->{empty} || length($widow) >= $args{widow}; |
472
|
|
|
|
|
|
|
} until $widow_okay || ++$rightindent > $rightslack; |
473
|
|
|
|
|
|
|
|
474
|
9
|
50
|
|
|
|
34
|
$text .= $widow_okay ? $newtext : $firsttext; |
475
|
|
|
|
|
|
|
} |
476
|
13
|
100
|
|
|
|
39
|
$gap = 0 unless $para->{empty}; |
477
|
|
|
|
|
|
|
} |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
# RETURN FORMATTED TEXT |
481
|
|
|
|
|
|
|
|
482
|
3
|
50
|
|
|
|
9
|
if ($toSTDOUT) { print STDOUT $text . $remainder; return } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
483
|
3
|
|
|
|
|
96
|
return $text . $remainder; |
484
|
|
|
|
|
|
|
} |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
sub _build_ignore { |
487
|
4
|
|
|
4
|
|
6
|
my $ignore_arg = shift; |
488
|
4
|
|
|
|
|
7
|
my $ig_type = ref $ignore_arg; |
489
|
4
|
|
|
|
|
5
|
my $ignore; |
490
|
4
|
100
|
|
|
|
13
|
if ($ig_type eq 'Regexp') { |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
491
|
3
|
|
|
|
|
5
|
my $regex = $ignore_arg; |
492
|
3
|
|
|
16
|
|
13
|
$ignore = sub { /$regex/ }; |
|
16
|
|
|
|
|
82
|
|
493
|
|
|
|
|
|
|
} elsif ($ig_type eq 'ARRAY') { |
494
|
1
|
|
|
|
|
3
|
my @elements = map { _build_ignore($_) } @$ignore_arg; |
|
2
|
|
|
|
|
7
|
|
495
|
|
|
|
|
|
|
$ignore = sub { |
496
|
5
|
100
|
|
5
|
|
7
|
for my $sub (@elements) { return 1 if $sub->(@_) } |
|
9
|
|
|
|
|
16
|
|
497
|
3
|
|
|
|
|
8
|
return 0; |
498
|
1
|
|
|
|
|
6
|
}; |
499
|
|
|
|
|
|
|
} |
500
|
|
|
|
|
|
|
elsif ($ignore_arg =~ /^indent/i) { |
501
|
0
|
0
|
|
0
|
|
0
|
$ignore = sub { ignore_headers(@_) || /$ignore_indent/ }; |
|
0
|
|
|
|
|
0
|
|
502
|
|
|
|
|
|
|
} |
503
|
|
|
|
|
|
|
else { |
504
|
0
|
|
|
|
|
0
|
$ignore = $ignore_arg; |
505
|
|
|
|
|
|
|
} |
506
|
4
|
50
|
|
|
|
10
|
croak "Expected suboutine reference as value for -ignore option" |
507
|
|
|
|
|
|
|
if ref $ignore ne 'CODE'; |
508
|
4
|
|
|
|
|
12
|
return $ignore; |
509
|
|
|
|
|
|
|
} |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
my $alpha = qr/[^\W\d_]/; |
512
|
|
|
|
|
|
|
my $notalpha = qr/[\W\d_]/; |
513
|
4
|
|
|
4
|
|
4301
|
my $word = qr/\pL(?:\pL'?)*/; |
|
4
|
|
|
|
|
36
|
|
|
4
|
|
|
|
|
58
|
|
514
|
|
|
|
|
|
|
my $upper = qr/[^\Wa-z\d_]/; |
515
|
|
|
|
|
|
|
my $lower = qr/[^\WA-Z\d_]/; |
516
|
|
|
|
|
|
|
my $mixed = qr/$alpha*?(?:$lower$upper|$upper$lower)$alpha*/; |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
sub recase { |
519
|
0
|
|
|
0
|
0
|
0
|
my ($origtext, $case) = @_; |
520
|
0
|
|
|
|
|
0
|
my ($entities, $other_entities, $first, $rest) = @{$casing{$case}}; |
|
0
|
|
|
|
|
0
|
|
521
|
|
|
|
|
|
|
|
522
|
0
|
|
|
|
|
0
|
my $text = ""; |
523
|
0
|
|
|
|
|
0
|
my @pieces = split /(&[a-z]+;)/i, $origtext; |
524
|
0
|
0
|
|
|
|
0
|
push @pieces, "" if @pieces % 2; |
525
|
0
|
0
|
|
|
|
0
|
return $text unless @pieces; |
526
|
0
|
|
|
|
|
0
|
local $_ = shift @pieces; |
527
|
0
|
0
|
|
|
|
0
|
if (length $_) { |
528
|
0
|
|
|
|
|
0
|
$entities = $other_entities; |
529
|
0
|
|
|
|
|
0
|
&$first; |
530
|
0
|
|
|
|
|
0
|
$text .= $_; |
531
|
|
|
|
|
|
|
} |
532
|
0
|
0
|
|
|
|
0
|
return $text unless @pieces; |
533
|
0
|
|
|
|
|
0
|
$_ = shift @pieces; |
534
|
0
|
|
0
|
|
|
0
|
$text .= $entities->{$_} || $_; |
535
|
0
|
|
|
|
|
0
|
while (@pieces) { |
536
|
0
|
|
|
|
|
0
|
$_ = shift @pieces; &$rest; $text .= $_; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
537
|
0
|
|
0
|
|
|
0
|
$_ = shift @pieces; $text .= $other_entities->{$_} || $_; |
|
0
|
|
|
|
|
0
|
|
538
|
|
|
|
|
|
|
} |
539
|
0
|
|
|
|
|
0
|
return $text; |
540
|
|
|
|
|
|
|
} |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
my $alword = qr{(?:\pL|&[a-z]+;)(?:[\pL']|&[a-z]+;)*}i; |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
sub entitle { |
545
|
0
|
|
|
0
|
0
|
0
|
my ($text, $retitler_ref) = @_; |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
# put into lowercase if on stop list, else titlecase |
548
|
0
|
|
|
|
|
0
|
$text =~ s{($alword)} |
549
|
0
|
0
|
|
|
|
0
|
{ $retitler_ref ? $retitler_ref->($1) : recase($1,'title') }gex; |
550
|
|
|
|
|
|
|
|
551
|
0
|
0
|
|
|
|
0
|
if ($retitler_ref == $STD_HIGHLIGHT_IGNORES) { |
552
|
|
|
|
|
|
|
# First and final words always capitalized... |
553
|
0
|
|
|
|
|
0
|
$text =~ s/^($alword) /recase($1,'title')/ex; |
|
0
|
|
|
|
|
0
|
|
554
|
0
|
|
|
|
|
0
|
$text =~ s/ ($alword)$/recase($1,'title')/ex; |
|
0
|
|
|
|
|
0
|
|
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
# treat parethesized portion as a complete title |
557
|
0
|
|
|
|
|
0
|
$text =~ s/\( ($alword) /'('.recase($1,'title')/ex; |
|
0
|
|
|
|
|
0
|
|
558
|
0
|
|
|
|
|
0
|
$text =~ s/($alword) \) /recase($1,'title').')'/ex; |
|
0
|
|
|
|
|
0
|
|
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
# capitalize first word following colon or semi-colon |
561
|
0
|
|
|
|
|
0
|
$text =~ s/ ( [:;] \s+ ) ($alword) /$1 . recase($2,'title')/ex; |
|
0
|
|
|
|
|
0
|
|
562
|
|
|
|
|
|
|
} |
563
|
|
|
|
|
|
|
|
564
|
0
|
|
|
|
|
0
|
return $text; |
565
|
|
|
|
|
|
|
} |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
my $gen_abbrev = join '|', |
568
|
|
|
|
|
|
|
qw{ etc[.] pp[.] ph[.]?d[.] }, |
569
|
|
|
|
|
|
|
'(?:[A-Z][.])(?:[A-Z][.])+', |
570
|
|
|
|
|
|
|
'(^[^a-zA-Z]*([a-z][.])+)'; |
571
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
my $term = q{(?:[.]|[!?]+)}; |
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
my $eos = 1; |
575
|
|
|
|
|
|
|
my $brsent = 0; |
576
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
sub ensentence { |
578
|
0
|
0
|
|
0
|
0
|
0
|
do { $eos = 1; return } unless @_; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
579
|
0
|
|
|
|
|
0
|
my ($str, $trailer) = @_; |
580
|
0
|
0
|
|
|
|
0
|
if ($str =~ /^([^a-z]*)I[^a-z]*?($term?)[^a-z]*$/i) { |
581
|
0
|
|
|
|
|
0
|
$eos = $2; |
582
|
0
|
|
|
|
|
0
|
$brsent = $1 =~ /^[[(]/; |
583
|
0
|
|
|
|
|
0
|
return uc $str |
584
|
|
|
|
|
|
|
} |
585
|
0
|
0
|
|
|
|
0
|
unless ($str =~ /[a-z].*[A-Z]|[A-Z].*[a-z]/) { |
586
|
0
|
|
|
|
|
0
|
$str = lc $str; |
587
|
|
|
|
|
|
|
} |
588
|
0
|
0
|
|
|
|
0
|
if ($eos) { |
589
|
0
|
|
|
|
|
0
|
$str =~ s/([a-z])/uc $1/ie; |
|
0
|
|
|
|
|
0
|
|
590
|
0
|
|
|
|
|
0
|
$brsent = $str =~ /^[[(]/; |
591
|
|
|
|
|
|
|
} |
592
|
0
|
|
0
|
|
|
0
|
$eos = $str !~ /^($gen_abbrev)[^a-z]*\s/i |
593
|
|
|
|
|
|
|
&& $str =~ /[a-z][^a-z]*$term([^a-z]*)\s/ |
594
|
|
|
|
|
|
|
&& !($1=~/[])]/ && !$brsent); |
595
|
0
|
0
|
0
|
|
|
0
|
$str =~ s/\s+$/$trailer/ if $eos && $trailer; |
596
|
0
|
|
|
|
|
0
|
return $str; |
597
|
|
|
|
|
|
|
} |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
# blockquote($text,$para, $format, $tlen, \@hang, \%args); |
600
|
|
|
|
|
|
|
sub blockquote { |
601
|
9
|
|
|
9
|
0
|
19
|
my ($dummy, $para, $format, $tlen, $hang, $args) = @_; |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
$para->{text} =~ |
604
|
9
|
50
|
|
|
|
45
|
/ \A(\s*) # $1 - leading whitespace (quotation) |
605
|
|
|
|
|
|
|
(["']|``) # $2 - opening quotemark |
606
|
|
|
|
|
|
|
(.*) # $3 - quotation |
607
|
|
|
|
|
|
|
(''|\2) # $4 closing quotemark |
608
|
|
|
|
|
|
|
\s*?\n # trailing whitespace |
609
|
|
|
|
|
|
|
(\1[ ]+) # $5 - leading whitespace (attribution) |
610
|
|
|
|
|
|
|
(--|-) # $6 - attribution introducer |
611
|
|
|
|
|
|
|
(.*?$) # $7 - attribution line 1 |
612
|
|
|
|
|
|
|
((\5.*?$)*) # $8 - attributions lines 2-N |
613
|
|
|
|
|
|
|
\s*\Z |
614
|
|
|
|
|
|
|
/xsm |
615
|
|
|
|
|
|
|
or return; |
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
#print "[$1][$2][$3][$4][$5][$6][$7]\n"; |
618
|
0
|
|
|
|
|
|
my $indent = length $1; |
619
|
0
|
|
|
|
|
|
my $text = $2.$3.$4; |
620
|
0
|
|
|
|
|
|
my $qindent = length $2; |
621
|
0
|
|
|
|
|
|
my $aindent = length $5; |
622
|
0
|
|
|
|
|
|
my $attribintro = $6; |
623
|
0
|
|
|
|
|
|
my $attrib = $7.$8; |
624
|
0
|
|
|
|
|
|
$text =~ s/\n/ /g; |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
$_[0] .= |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
form {squeeze=>$args->{squeeze}, trim=>1, |
629
|
|
|
|
|
|
|
fill => $args->{expfill} |
630
|
|
|
|
|
|
|
}, |
631
|
0
|
|
|
|
|
|
$format . q{ }x$indent . q{<}x$tlen, |
632
|
|
|
|
|
|
|
@$hang, $text, |
633
|
|
|
|
|
|
|
$format . q{ }x($qindent) . q{[}x($tlen-$qindent), |
634
|
|
|
|
|
|
|
@$hang, $text, |
635
|
|
|
|
|
|
|
{squeeze=>0}, |
636
|
|
|
|
|
|
|
$format . q{ } x $aindent . q{>> } . q{[}x($tlen-$aindent-3), |
637
|
|
|
|
|
|
|
@$hang, $attribintro, $attrib; |
638
|
0
|
|
|
|
|
|
return 1; |
639
|
|
|
|
|
|
|
} |
640
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
1; |
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
__END__ |