I'll throw my hat in the ring as well!



#!/usr/local/bin/ruby -w

USAGE =<<'EOF'
Usage: virtcol.rb [-w width] [file] ...
 * Width: minimum 5, default 50
 * STDIN read if no files specified.
EOF

############################################################################
#
# Read input from a line
#        "nnnnn<Tab>Now is the time ... aid of the party"
# and produce
#
# nnnnn   Now is the time for all good
#         men to come to the aid of
#         the party.
############################################################################
#
class VirtualColumnDemo
  DEFAULT_WIDTH = 40

  # 'input' is an array of lines in the format described above.
  def initialize(input, width=DEFAULT_WIDTH)
    # Convert the raw input into an array of Lines.
    @lines = input.map { |il| Line.new(il, width) }
  end

  def VirtualColumnDemo.from_file(file, width=DEFAULT_WIDTH)
    lines = file.readlines
    VirtualColumnDemo.new(lines, width)
  end

  # Pretty-print each line of data followed by a blank line.
  def display
    for line in @lines
      puts line.generate_text
      puts
    end
  end

  private


############################################################################
#
  # Encapsulates a single piece of data containing the left column 'header'
  # and right column 'text'.

############################################################################
#
  class Line
    attr_accessor :width
    attr_reader :header, :text

    def initialize(raw_line, width)
      @width = width
      @header, @text = raw_line.chomp.split(/\t/)
      @header ||= ""
      @text   ||= ""
    end

    # -> Array of lines fully formatted.
    def generate_text
      # Split the text at the first space before 'width'.  If there is none,
      # take the one after; failing that, the end of the String.
      text = @text.dup
      split_text = []
      while text.length > 0
        last_space = text.rindex(/\s/, width) || text.index(/\s/, width-1)
|| -1
        new_line = text.slice!(0..last_space)
        split_text << new_line.strip
      end
      split_text = [""] if split_text == []

      # Now add header before first line and 8 spaces before each other.
      output = split_text
      output.each_with_index do |line,i|
        if i == 0
          line.replace( ("%-8s" % @header) + line )
        else
          line.replace("        " + line)
        end
      end

      # That's it.
      output
    end
  end
end


############################################################################
#
#
#                                   (MAIN)
#
############################################################################
#

# Sort out arguments.
width = 40                    # Default value
if ARGV[0] == "-w"
  ARGV.shift
  begin
    width = Integer(ARGV.shift)
  rescue
    $stderr.puts "\n*** Ignoring width field; it doesn't compute.\n\n"
  end
end
width = [5, width].max

# Run the demo.
vc = VirtualColumnDemo.from_file(ARGF, width)
vc.display