File: vnl-align

package info (click to toggle)
vnlog 1.42-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 992 kB
  • sloc: perl: 4,682; ansic: 752; python: 462; sh: 116; makefile: 7
file content (198 lines) | stat: -rwxr-xr-x 5,019 bytes parent folder | download | duplicates (4)
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/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<< <dima@secretsauce.net> >>

=head1 LICENSE AND COPYRIGHT

Copyright 2016 California Institute of Technology.
Copyright 2018 Dima Kogan C<< <dima@secretsauce.net> >>

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