Utility to Reformat Comment Lines

The Problem
These days, my work requires writing scripts in Tcl, bash, or Python. These scripts have one attribute in common: they use the hash sign (#) to start a comment. I often need to “reflow” my comments, i.e. reformat the comment lines to fit a number of columns (72 in my case) within my vi editor. For example, given the following comment lines:

# Extracts from a line the prefix and the rest of the line, with
# extra spaces trimmed.
# The prefix consists of any white space
# preceding the hash (#) and a space.
# Assume that the block of comment lines has the same indentation level.

I would like a tool to reformat them to something like:

# Extracts from a line the prefix and the rest of the line, with
# extra spaces trimmed. The prefix consists of any white space
# preceding the hash (#) and a space. Assume that the block of
# comment lines has the same indentation level.

The Solution
After my search for such a tool failed, partly because I did not look that hard, I decided to write that tool myself. After some research, I learned that Perl’s Text::Wrap module can satisfy my need. Thus, I wrote a short script called ‘cf’ — short for comment format or comment flow. Before using this script, you should place it in a directory in your path (~/bin for me). To use it within vi, it helps to turn on line numbering (via the ‘:set nu’ command). If the comments spans from line 4 to line 7, then to reflow it, you should issue the following command:
:4,7!cf

Limitations of cf
Cf assumes the comment lines share the same indentation level. If they don’t, the result will be unpredictable. Secondly, to simplify my script, I assume the users want to wrap the comments within 72 columns. If this is not the case, you can edit the script and change it to suit your need.

The Script

#!/usr/bin/env perl -n

# cf -- comment formatter
# by Hai Vu
# Last update: 2008-12-15
#
# A Perl script to reformat a comment block to wrap the text to fit
# within a number of columns. I design this script to work as a
# filter within the vi/vim editor. For example, to use this script to
# reformat from line 4 to line 8, issue the following command: line 4
# to line 8, issue the following command:
# :4,8!cf

use Text::Wrap;

# ----------------------------------------------------------------------
# Extracts from a line the prefix and the rest of the line, with
# extra spaces trimmed. The prefix consists of any white space
# preceding the hash (#) and a space. Assume that the block of
# comment lines has the same indentation level.

# Perform the regular expression to extract the comment character (#)
# including the preceding white spaces, and the rest of the line.
chomp;
/^(\s*# )\s*(\S.*\S)\s*$/;
$prefix = $1;
$line = $2;

# Add the line to the array for later processing
push(@lines, $line);

# ----------------------------------------------------------------------
# At the end of the input, wrap the lines, then print them out with the
# prefix.

END {
    # Set the width
    $columns = 72;
    local($Text::Wrap::columns) = $columns - length($prefix);

    # Wrap the text and print
    $text = wrap($prefix, $prefix, @lines);
    print $text;
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s