-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathvnl-align
executable file
·198 lines (153 loc) · 4.91 KB
/
vnl-align
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#!/usr/bin/env perl
use strict;
use warnings;
use Text::Table;
my $usage = "Usage: $0 [logfile]\n";
if( exists $ARGV[0] && ($ARGV[0] eq '-h' || $ARGV[0] eq '--help'))
{
print $usage;
exit 0;
}
my $table = undef;
# This exists to support interstitial comments that are output without
# alignment. Each chunk is:
#
# - integer index of the line start
# - trailing comment
#
# Lines preceding the legend are stored in the chunk that has index < 0
my @chunks = ( [-1, ''] );
my $Nlines_here = 0;
my @legend;
while(<>)
{
if( !defined $table )
{
if( !/^#[^#!]/ )
{
# don't have a legend yet, and this is a ##/#! comment, not a legend
$chunks[-1][1] .= $_;
}
else
{
# got legend
push @chunks, [0,''];
$Nlines_here = 1;
chomp;
s/^# *//;
@legend = split;
$legend[0] = "# $legend[0]";
$table = Text::Table->new(@legend);
}
next;
}
if( /^#/ || /^\s*$/ )
{
# comment. Add to the comment we're accumulating
$chunks[-1][1] .= $_;
next;
}
# data line
chomp;
my @fields = split;
$table->add(@fields);
if( length($chunks[-1][1]) == 0 )
{
# Data line and we don't have a trailing comment yet. Accumulate
$Nlines_here++;
}
else
{
# Our chunk already has a trailing comment, But the new line is a data
# line. I start a new chunk
push @chunks, [$chunks[-1][0] + $Nlines_here,
''];
$Nlines_here = 1;
}
}
for my $ichunk (0..$#chunks)
{
my $chunk = $chunks[$ichunk];
if( $chunk->[0] >= 0)
{
# This isn't a comment-only chunk. Those are the pre-legend ##/#! lines
if($chunk->[0] == 0)
{
# Treat the legend specially: I want to center-justify the labels.
# Can't figure out how to use the library to do that, so I'm doing
# that manually
for my $icol(0..$#legend)
{
my $textwidth = length($legend[$icol]);
my ($fieldstart,$fieldwidth) = $table->colrange($icol);
# I want to center the thing. First column is different
if($icol == 0 )
{
# line is '# xxx'
my ($text) = $legend[$icol] =~ /^# (.*)/;
$textwidth -= 2;
# margin+textwidth+margin = fieldwidth
my $margin0 = int(($fieldwidth - $textwidth) / 2); # rounds down
my $margin1 = $fieldwidth - $textwidth - $margin0; # rounds up
if($margin1 == 1)
{
$margin1++;
$margin0--;
}
print( '#' . (' ' x ($margin1-1)) . $text . (' ' x $margin0));
}
else
{
# margin+textwidth+margin = fieldwidth
my $text = $legend[$icol];
my $margin0 = int(($fieldwidth - $textwidth) / 2); # rounds down
my $margin1 = $fieldwidth - $textwidth - $margin0; # rounds up
print( (' ' x $margin1) . $text . (' ' x $margin0));
}
print( ($icol == $#legend) ? "\n" : ' ');
}
# done with the legend. Process this chunk from the next line
$chunk->[0]++;
}
print $table->table($chunk->[0],
$ichunk != $#chunks ?
($chunks[$ichunk+1][0] - $chunk->[0]) :
$Nlines_here);
}
print $chunk->[1];
}
__END__
=head1 NAME
vnl-align - aligns vnlog columns for easy interpretation by humans
=head1 SYNOPSIS
$ cat tst.vnl
# w x y z
-10 40 asdf -
-20 50 - 0.300000
-30 10 whoa 0.500000
$ vnl-align tst.vnl
# w x y z
-10 40 asdf -
-20 50 - 0.300000
-30 10 whoa 0.500000
=head1 DESCRIPTION
The basic usage is
vnl-align logfile
The arguments are assumed to be the vnlog files. If no arguments are given,
the input comes from STDIN.
This is very similar to C<column -t>, but handles C<#> lines properly:
1. The first C<#> line is the legend. For the purposes of alignment, the leading
C<#> character and the first column label are treated as one column
2. All other C<#> lines are output verbatim.
=head1 REPOSITORY
https://github.com/dkogan/vnlog/
=head1 AUTHOR
Dima Kogan C<< <[email protected]> >>
=head1 LICENSE AND COPYRIGHT
Copyright 2016 California Institute of Technology.
Copyright 2018 Dima Kogan C<< <[email protected]> >>
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at your option) any
later version.
=cut