line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
=head1 NAME
|
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
PostScript::Columns - Squeeze a text file into multiple columns.
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
use PostScript::ColDoc;
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
$psdoc= pscolumns(
|
11
|
|
|
|
|
|
|
-margins => [30,20], # NSEW or NS,EW or N,EW,S or N,E,W,S (like CSS)
|
12
|
|
|
|
|
|
|
-headfont => 'NimbusMonL-Bold',
|
13
|
|
|
|
|
|
|
-headsize => 12,
|
14
|
|
|
|
|
|
|
-head => $head,
|
15
|
|
|
|
|
|
|
-font => 'NimbusMonL-Regu',
|
16
|
|
|
|
|
|
|
-size => 10,
|
17
|
|
|
|
|
|
|
-text => $text,
|
18
|
|
|
|
|
|
|
# default font/size for foot:
|
19
|
|
|
|
|
|
|
-foot => "Page \$p of \$pp", # will interpolate later :)
|
20
|
|
|
|
|
|
|
);
|
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
# use all defaults, no footer
|
23
|
|
|
|
|
|
|
$doc= pscolumns(
|
24
|
|
|
|
|
|
|
-size => 5,
|
25
|
|
|
|
|
|
|
-head => "Left\nLeft Also\tTest Document\tRight",
|
26
|
|
|
|
|
|
|
-text => $text,
|
27
|
|
|
|
|
|
|
-foot => scalar(localtime)."\tFoot\tPage \$p of \$pp",
|
28
|
|
|
|
|
|
|
);
|
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
Creates a PostScript document with a user-defined header and footer,
|
34
|
|
|
|
|
|
|
then attempts to squeeze the data into as many columns as possible.
|
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
=head1 AVAILABLE FONTS
|
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
Only the monospace PostScript fonts are available:
|
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
=over 4
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
=item C
|
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=item C
|
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
=item C
|
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
=item C
|
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
=back
|
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
=head1 OPTIONS
|
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=over 4
|
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=item -margins
|
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
Array ref that specifies page margins, in I (1/72 of an inch).
|
59
|
|
|
|
|
|
|
North, East, West South are expressed as
|
60
|
|
|
|
|
|
|
four elements: [ N, E, S, W ], three elements [ N, E_W, S ], two elements [ N_S, E_W ],
|
61
|
|
|
|
|
|
|
or one element [ N_S_E_W ].
|
62
|
|
|
|
|
|
|
(This is the same order that CSS uses.)
|
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
B Different printers may require drastically different margins.
|
65
|
|
|
|
|
|
|
You'll have to experiment each time you use this module with a new printer.
|
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=item -headfont
|
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
Name of the font to use for the header (see L<"AVAILABLE FONTS">).
|
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=item -headsize
|
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
Size of the font to use for the header (in points).
|
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
=item -head
|
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
String to use as header.
|
78
|
|
|
|
|
|
|
Upper-right, centered, and upper-left fields are tab-separated.
|
79
|
|
|
|
|
|
|
In the string, C<$p> will be replaced by the current page number,
|
80
|
|
|
|
|
|
|
and C<$pp> with the total number of pages.
|
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=item -font
|
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
Name of the font to use for the text (see L<"AVAILABLE FONTS">).
|
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=item -size
|
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
Size of the font to use for the text (in points).
|
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
=item -text
|
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
Columnar text.
|
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=item -footfont
|
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
Name of the font to use for the footer (see L<"AVAILABLE FONTS">).
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=item -footsize
|
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
Size of the font to use for the footer (in points).
|
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=item -foot
|
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
String to use as footer.
|
105
|
|
|
|
|
|
|
Lower-right, centered, and lower-left fields are tab-separated.
|
106
|
|
|
|
|
|
|
In the string, C<$p> will be replaced by the current page number,
|
107
|
|
|
|
|
|
|
and C<$pp> with the total number of pages.
|
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=back
|
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
=head1 AUTHOR
|
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
v, Efive@rant.scriptmania.comE
|
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
=head1 SEE ALSO
|
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
perl(1).
|
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
=cut
|
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
package PostScript::Columns;
|
122
|
|
|
|
|
|
|
|
123
|
1
|
|
|
1
|
|
734
|
use strict;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
35
|
|
124
|
1
|
|
|
1
|
|
5
|
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
71
|
|
125
|
1
|
|
|
1
|
|
4
|
use vars qw(%wratio);
|
|
1
|
|
|
|
|
10
|
|
|
1
|
|
|
|
|
2602
|
|
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
$VERSION = '1.23';
|
128
|
|
|
|
|
|
|
require Exporter;
|
129
|
|
|
|
|
|
|
@ISA = qw(Exporter);
|
130
|
|
|
|
|
|
|
@EXPORT = qw(pscolumns);
|
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
sub pscolumns
|
133
|
|
|
|
|
|
|
{ # Hey! I know what's mine! ;)
|
134
|
1
|
|
|
1
|
0
|
686
|
my %arg= @_;
|
135
|
1
|
|
|
|
|
915
|
my($now,$who)= (scalar localtime, getlogin);
|
136
|
|
|
|
|
|
|
## initial metrics
|
137
|
1
|
50
|
|
|
|
4
|
my($margin_N,$margin_E,$margin_S,$margin_W)= @{$arg{-margins}||[]};
|
|
1
|
|
|
|
|
11
|
|
138
|
1
|
50
|
|
|
|
4
|
$margin_N= 30 unless defined $margin_N;
|
139
|
1
|
50
|
|
|
|
3
|
$margin_E= 20 unless defined $margin_E;
|
140
|
1
|
50
|
|
|
|
4
|
$margin_S= $margin_N unless defined $margin_S;
|
141
|
1
|
50
|
|
|
|
5
|
$margin_W= $margin_E unless defined $margin_W;
|
142
|
1
|
50
|
|
|
|
5
|
my $font= ( $wratio{$arg{-font}} ? $arg{-font} : 'NimbusMonL-Regu' );
|
143
|
1
|
|
50
|
|
|
4
|
my $font_Y= $arg{-size} || 7;
|
144
|
1
|
|
|
|
|
5
|
my $font_X= $font_Y * $wratio{$font};
|
145
|
1
|
|
50
|
|
|
6
|
my $line_Y= $arg{-linewidth} || 0.2;
|
146
|
|
|
|
|
|
|
## head metrics
|
147
|
1
|
|
|
|
|
7
|
my @head_right= split /\t/, $arg{-head};
|
148
|
1
|
|
|
|
|
4
|
my @head_left= split /\n/, $head_right[0];
|
149
|
1
|
|
|
|
|
4
|
my @head_center= split /\n/, $head_right[1];
|
150
|
1
|
|
|
|
|
4
|
@head_right= split /\n/, $head_right[2];
|
151
|
1
|
|
|
|
|
8
|
my($head_lines)= sort {$b<=>$a}
|
|
3
|
|
|
|
|
6
|
|
152
|
|
|
|
|
|
|
(scalar @head_left, scalar @head_center, scalar @head_right);
|
153
|
1
|
|
50
|
|
|
13
|
my $head_font= $arg{-headfont} || 'NimbusMonL-Bold';
|
154
|
1
|
|
50
|
|
|
6
|
my $head_font_Y= $arg{-headsize} || 10;
|
155
|
1
|
|
|
|
|
3
|
my $head_font_X= $head_font_Y * $wratio{$head_font};
|
156
|
1
|
|
|
|
|
2
|
my $head_Y= $head_font_Y * $head_lines;
|
157
|
|
|
|
|
|
|
## foot metrics
|
158
|
1
|
|
|
|
|
5
|
my @foot_right= split /\t/, $arg{-foot};
|
159
|
1
|
|
|
|
|
3
|
my @foot_left= split /\n/, $foot_right[0];
|
160
|
1
|
|
|
|
|
2
|
my @foot_center= split /\n/, $foot_right[1];
|
161
|
1
|
|
|
|
|
4
|
@foot_right= split /\n/, $foot_right[2];
|
162
|
1
|
|
|
|
|
4
|
my($foot_lines)= sort {$b<=>$a}
|
|
3
|
|
|
|
|
4
|
|
163
|
|
|
|
|
|
|
(scalar @foot_left, scalar @foot_center, scalar @foot_right);
|
164
|
1
|
|
50
|
|
|
5
|
my $foot_font= $arg{-footfont} || 'NimbusMonL-Regu';
|
165
|
1
|
|
50
|
|
|
12
|
my $foot_font_Y= $arg{-footsize} || 8;
|
166
|
1
|
|
|
|
|
2
|
my $foot_font_X= $foot_font_Y * $wratio{$foot_font};
|
167
|
1
|
|
|
|
|
1
|
my $foot_Y= $foot_font_Y * $foot_lines;
|
168
|
|
|
|
|
|
|
## text metrics
|
169
|
1
|
|
50
|
|
|
4
|
local $_= $arg{-text} || ' '; s/\t/ /g;
|
|
1
|
|
|
|
|
52
|
|
170
|
1
|
|
|
|
|
475
|
my @text= split /\n/;
|
171
|
1
|
|
|
|
|
25
|
my($maxlen)= sort {$b<=>$a} map {length} @text;
|
|
7387
|
|
|
|
|
6449
|
|
|
968
|
|
|
|
|
1018
|
|
172
|
1
|
|
|
|
|
30
|
my $col_X= $maxlen * $font_X;
|
173
|
1
|
|
|
|
|
3
|
my $paper_Y= 792;
|
174
|
1
|
|
|
|
|
3
|
my $paper_X= 612;
|
175
|
1
|
|
|
|
|
2
|
my $right= $paper_X-$margin_E;
|
176
|
1
|
|
|
|
|
3
|
my $head_top= $paper_Y-$margin_N;
|
177
|
1
|
|
|
|
|
4
|
my $head_line_top= $head_top-$head_Y+($head_font_Y/2);
|
178
|
1
|
|
|
|
|
4
|
my $text_top= $head_top-$head_Y-($font_Y/2);
|
179
|
1
|
|
|
|
|
2
|
my $foot_top= $foot_Y+$margin_S;
|
180
|
1
|
|
|
|
|
2
|
my $foot_line_top= $foot_top+($foot_font_Y);
|
181
|
1
|
|
|
|
|
4
|
my $text_Y= $text_top-$foot_line_top-4;
|
182
|
1
|
|
|
|
|
2
|
my $text_X= $paper_X-$margin_E-$margin_W;
|
183
|
1
|
|
|
|
|
3
|
my $rows= int( $text_Y / $font_Y );
|
184
|
1
|
|
50
|
|
|
10
|
my $cols= int( $text_X / $col_X ) || 1;
|
185
|
1
|
|
|
|
|
1
|
$col_X= $text_X / $cols;
|
186
|
1
|
|
|
|
|
3
|
my $pagelines= $rows * $cols;
|
187
|
1
|
|
|
|
|
4
|
my $pp= int( ( @text / $pagelines ) +0.999 );
|
188
|
1
|
|
|
|
|
27
|
my $ps= <<".";
|
189
|
|
|
|
|
|
|
%!PS-Adobe-3.0
|
190
|
|
|
|
|
|
|
%%Title: Columnar Document
|
191
|
|
|
|
|
|
|
%%Creator: PostScript::Columns v$VERSION
|
192
|
|
|
|
|
|
|
%%CreationDate: $now
|
193
|
|
|
|
|
|
|
%%For: $who
|
194
|
|
|
|
|
|
|
%%BoundingBox: 0 0 $paper_X $paper_Y
|
195
|
|
|
|
|
|
|
%%Pages: $pp
|
196
|
|
|
|
|
|
|
%Columns: $cols @ $col_X pt
|
197
|
|
|
|
|
|
|
%%EndComments
|
198
|
|
|
|
|
|
|
.
|
199
|
1
|
|
|
|
|
26
|
my $ps_head= "/$head_font findfont $head_font_Y scalefont setfont\n";
|
200
|
1
|
|
|
|
|
7
|
for my $y (map {$head_top-$head_font_Y*$_} reverse (0..$head_lines-1))
|
|
2
|
|
|
|
|
8
|
|
201
|
|
|
|
|
|
|
{
|
202
|
2
|
|
|
|
|
5
|
local $_= pop @head_left;
|
203
|
2
|
|
|
|
|
8
|
s/(\(|\)|\\)/\\$1/g;
|
204
|
2
|
50
|
|
|
|
10
|
$ps_head.= "$margin_W $y moveto ($_) show\n" if $_;
|
205
|
2
|
|
|
|
|
4
|
$_= pop @head_center;
|
206
|
2
|
|
|
|
|
6
|
my $x= ( $paper_X - ($head_font_X * length) )/2;
|
207
|
2
|
|
|
|
|
4
|
s/(\(|\)|\\)/\\$1/g;
|
208
|
2
|
100
|
|
|
|
9
|
$ps_head.= "$x $y moveto ($_) show\n" if $_;
|
209
|
2
|
|
|
|
|
21
|
$_= pop @head_right;
|
210
|
2
|
|
|
|
|
5
|
$x= $paper_X - $margin_E - ($head_font_X * length);
|
211
|
2
|
|
|
|
|
4
|
s/(\(|\)|\\)/\\$1/g;
|
212
|
2
|
100
|
|
|
|
9
|
$ps_head.= "$x $y moveto ($_) show\n" if $_;
|
213
|
|
|
|
|
|
|
}
|
214
|
1
|
|
|
|
|
11
|
$ps_head.= "$margin_W $head_line_top moveto $right $head_line_top ".
|
215
|
|
|
|
|
|
|
"lineto $line_Y setlinewidth stroke\n".
|
216
|
|
|
|
|
|
|
"/$foot_font findfont $foot_font_Y scalefont setfont\n";
|
217
|
1
|
|
|
|
|
4
|
for my $y (map {$foot_top-$foot_font_Y*$_} (0..$foot_lines-1))
|
|
1
|
|
|
|
|
3
|
|
218
|
|
|
|
|
|
|
{
|
219
|
1
|
|
|
|
|
3
|
local $_= shift @foot_left;
|
220
|
1
|
|
|
|
|
3
|
s/(\(|\)|\\)/\\$1/g;
|
221
|
1
|
50
|
|
|
|
8
|
$ps_head.= "$margin_W $y moveto ($_) show\n" if $_;
|
222
|
1
|
|
|
|
|
3
|
$_= shift @foot_center;
|
223
|
1
|
|
|
|
|
3
|
my $x= ( $paper_X - ($foot_font_X * length) )/2;
|
224
|
1
|
|
|
|
|
4
|
s/(\(|\)|\\)/\\$1/g;
|
225
|
1
|
50
|
|
|
|
8
|
$ps_head.= "$x $y moveto ($_) show\n" if $_;
|
226
|
1
|
|
|
|
|
3
|
$_= shift @foot_right;
|
227
|
1
|
|
|
|
|
2
|
$x= $paper_X - $margin_E - ($foot_font_X * length);
|
228
|
1
|
|
|
|
|
3
|
s/(\(|\)|\\)/\\$1/g;
|
229
|
1
|
50
|
|
|
|
8
|
$ps_head.= "$x $y moveto ($_) show\n" if $_;
|
230
|
|
|
|
|
|
|
}
|
231
|
1
|
|
|
|
|
6
|
$ps_head.= "$margin_W $foot_line_top moveto $right $foot_line_top ".
|
232
|
|
|
|
|
|
|
"lineto $line_Y setlinewidth stroke\n";
|
233
|
1
|
|
|
|
|
3
|
$ps_head.= "/$font findfont $font_Y scalefont setfont\n";
|
234
|
1
|
|
|
|
|
11
|
$ps_head=~ s/\$pp\b/$pp/g;
|
235
|
1
|
|
|
|
|
7
|
my $p;
|
236
|
1
|
|
|
|
|
4
|
PAGE: while(@text)
|
237
|
|
|
|
|
|
|
{
|
238
|
4
|
|
|
|
|
5
|
$p++;
|
239
|
4
|
|
|
|
|
25
|
(my $thishead= $ps_head)=~ s/\$p\b/$p/g;
|
240
|
4
|
|
|
|
|
18
|
$ps.= "\n%%Page: (Page $p) $p\n".$thishead;
|
241
|
4
|
|
|
|
|
11
|
for my $x (map {$margin_W+$col_X*$_} (0..$cols-1))
|
|
8
|
|
|
|
|
19
|
|
242
|
|
|
|
|
|
|
{
|
243
|
8
|
|
|
|
|
49
|
for my $y (map {$text_top-$font_Y*$_} (0..$rows-1))
|
|
1096
|
|
|
|
|
1225
|
|
244
|
|
|
|
|
|
|
{
|
245
|
968
|
50
|
|
|
|
2039
|
next unless local $_= shift @text;
|
246
|
968
|
50
|
|
|
|
2185
|
last if /\x0c/; # end col at formfeed
|
247
|
968
|
|
|
|
|
2478
|
s/(\(|\)|\\)/\\$1/g;
|
248
|
968
|
|
|
|
|
3211
|
$ps.= "$x $y moveto ($_) show\n";
|
249
|
968
|
100
|
|
|
|
2558
|
last PAGE unless @text;
|
250
|
|
|
|
|
|
|
}
|
251
|
|
|
|
|
|
|
}
|
252
|
3
|
|
|
|
|
13
|
$ps.= "showpage\n";
|
253
|
|
|
|
|
|
|
}
|
254
|
1
|
|
|
|
|
11
|
$ps.= "showpage\n";
|
255
|
1
|
|
|
|
|
159
|
return $ps;
|
256
|
|
|
|
|
|
|
}
|
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
%wratio=
|
259
|
|
|
|
|
|
|
( # Hmmm.... not a lot of variance. Keep?
|
260
|
|
|
|
|
|
|
'NimbusMonL-Regu' => 0.6,
|
261
|
|
|
|
|
|
|
'NimbusMonL-Bold' => 0.6,
|
262
|
|
|
|
|
|
|
'NimbusMonL-ReguObli' => 0.6,
|
263
|
|
|
|
|
|
|
'NimbusMonL-BoldObli' => 0.6,
|
264
|
|
|
|
|
|
|
);
|
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
1;
|