#!/usr/bin/perl

# Copyright (C) 2005 John C. Luciani Jr.

# This program may be distributed or modified under the terms of
# version 0.1 of the No-Fee Software License published by
# John C. Luciani Jr.

use strict;
use warnings;
use Carp;

# Formats column data into data records.

# The column data is arranged using one value per row in a file.  Each
# column is separated by an empty line. After the file is read a
# data records are output using the column data.

# Missing column data is output as empty strings.

my @Col;
my $New_col = 1; # =1 start a new column 
while (<>) {
    s/\#.*//; # Remove comments
    s/^\s*//; # Remove leading spaces
    s/\s*$//; # Revove trailing spaces

    # If this line is empty then set the new column flag and read the
    # next line.  Using the flag allows multiple empty lines (or lines
    # containing only comments) to be treated as one.

    $New_col = 1, next unless length; 

    # if the new column flag was set then push an anonymous array onto
    # column array (@Col) and reset the flag.

    push(@Col, []), $New_col = 0 if $New_col;
    push @ { $Col[$#Col] }, $_; # push a value onto the most recent column
}

while (1) {
    my $not_done = 0;
    foreach my $col_num (0..$#Col) {
	my $col_ref = $Col[$col_num];  # reference to the current column

	# column values are separated by vertical bars and undefined
	# values are output as empty strings. If any column array
	# contains a value then we are not done processing the column
	# data ($not_done = 1).

	my $col_val = shift @$col_ref;
	printf("%s%s", 
	       $col_num == 0 ? '' : ' | ',
	       defined $col_val ? $col_val : '');
	$not_done = 1 unless $#$col_ref == -1
    }
    print "\n";
    last unless $not_done;
}


# Style (adapted from the Perl Cookbook, First Edition, Recipe 12.4)

# 1. Names of functions and local variables are all lowercase.
# 2. The program's persistent variables (either file lexicals
#    or package globals) are capitalized.
# 3. Identifiers with multiple words have each of these
#    separated by an underscore to make it easier to read.
# 4. Constants are all uppercase.
# 5. If the arrow operator (->) is followed by either a
#    method name or a variable containing a method name then
#    there is a space before and after the operator.


