Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Comment Block Creator

by jpfarmer (Pilgrim)
on Dec 03, 2003 at 17:05 UTC ( [id://311946]=sourcecode: print w/replies, xml ) Need Help??
Category:
Author/Contact Info jpfarmer
Description:

In my code, I like to use very visible comments to indicated major program components (subroutines, a block of global variables, etc). The format I prefer looks like this:

#######################
# This subroutine...  #
#######################

However, these are a pain to create because you have to manage the space padding. It's more work than I care to put into it. So, I wrote a Perl program that will parse my program for specially formatted comments, then format them they way I like them.

Any feedback is greatly appreciated.

#!/usr/bin/perl

use warnings;
use strict;
use Fcntl ':flock';
use File::Copy;
use Tie::File;

############################################################
# Author: jpfarmer @ Perlmonks                             #
# http://www.perlmonks.org/index.pl?node_id=126392         #
#                                                          #
# This program takes one argument, the name of the source  #
# to clean up.  It copies that file to <filename>.bak      #
# and then operates on the original.  It creates formatted #
# comments when they are properly marked.  Example:        #
#                                                          #
#   #/*                                                    #
#   # This subroutine ...                                  #
#   #*/                                                    #
#                                                          #
# becomes                                                  #
#                                                          #
#  #######################                                 #
#  # This subroutine ... #                                 #
#  #######################                                 #
#                                                          #
############################################################

####################
# Global Variables #
####################
our $fn = shift @ARGV;
our $fn_bak = "$fn.bak";
our $border_char = '#';
our @program;

####################
# Begin Program    #
####################

# Backup program
copy($fn, $fn_bak);

# Tie the file to an array so we can manipulate it easily.
tie @program, 'Tie::File', $fn;

# Begin iterating over the file and converting comments.
# If the comments are improperly formed, then we do not
# do anything.  Better to do nothing then to blow something
# up.

my $slurp_start;
my $slurp_end;
my @slurp_lines;

for (my $i = 0; $i < $#program; $i++){
    my $line = $program[$i];
    if (! defined $slurp_start){
    # Skip to the next line if this isn't a comment
    next unless ($line =~ m{^#});
                
    # If we end up with a comment, we need to figure out if
        # it is telling us to start slurping
    next unless ($line =~ m{^#/\*});
    
    # If we get to this point, we need to start slurping.
    # So, we mark the beginning index and next.
    $slurp_start = $i;
    print STDERR "Found a block starting at line $i.\n";
    next;
    } else{
    # We need to see if we've come across either an uncommented
    # or a block end.  A block end means we need to set $slurp_end
    # and make our changes.  If it's uncommened, we'll undef slurp_sta
+rt 
    # and slurp_end and empty slurp_lines.  If it's just a commented
    # line, chomp it and store it.
    if ($line =~ m/^[^#]/){
        $slurp_start = undef;
        $slurp_end = undef;
            @slurp_lines = ();
        next;       
    } elsif ($line =~ m{^#\*/}){
        $slurp_end = $i;
            print STDERR "Block ended at line $i.\n";            
        &create_block;
        next;
    } else {
        chomp $line;
        push(@slurp_lines, $line);
            print STDERR "$line\n";                
    }
    }
            
}

######################################################################
+##
# This takes no arguments, and operates on global variables.  It takes
+ #
# a discovered block comment, and processes it commiting the changes  
+ #
# to the file.                                                        
+ #
######################################################################
+##
sub create_block {
    # First, we need to calculate the length of the longest line, then
+ 
    # add 2 to it (for a trailing space and the boundry marker) to fin
+d
    # our box width.
    my $box_width = &max(map {length($_) + 2} @slurp_lines);

    # Now, replace the first and last lines with solid bars
    # $border_char
    $program[$slurp_start] = $program[$slurp_end] = $border_char x $bo
+x_width;
    
    # Finally, stick the remaining lines in between border_chars
    for (my $i = ($slurp_start + 1); $i < $slurp_end; $i++){
    $program[$i] = sprintf("%-" . ($box_width - 2) . "s #", $program[$
+i]);
    }

    # Clear out the globals, and we're done.
    $slurp_start = undef;
    $slurp_end = undef;
    @slurp_lines = ();
}

####################################################################
# This takes one argument, an array, and returns the maximum value #
# The code is swiped from the perlsub page.                        #
####################################################################
sub max(@list) {
    my $max = shift(@_);
    foreach my $foo (@_) {
    $max = $foo if $max < $foo;
    }
    return $max;
}
Replies are listed 'Best First'.
Re: Comment Block Creator
by diotalevi (Canon) on Dec 03, 2003 at 20:01 UTC

    Goodness, I like perl. Here's the same thing in a fraction of the lines. It probably works.

    use List::Util 'max'; use File::Copy 'copy'; use File::Slurp qw'read_file write_file'; @ARGV == 1 or die "$^X $0 filename.pl\n"; my $file = shift; copy $file, "$file.bak" or die "Couldn't copy $file to $file.bak: $!"; my $source = read_file( $file ); $source =~ s(^#/*.*\n((?s:.+?))^#*/.*\n){ my @lines = map /^\s*#\s*(.+?)[\s#]*$/, split /\n/, $1; my $len = 1 + max( map length(), @lines ); join "\n", "#" x $len, map( sprintf("%-" . ($len - 1) . "s #"), @lines ), "#" x $len }meg and write_file( $file, $source ) or die "Couldn't write changed source to $file: $!";
Re: Comment Block Creator
by duff (Parson) on Dec 03, 2003 at 22:04 UTC

    Interesting if a bit long. I normally use Damian Conway's Text::Autoformat for reformatting emails and such in vi. It seems like it would be a useful addition to create a mode for it to handle your commenting style as well so that comment edits are painless. Heck, it may already handle this format and I just don't know.

    Update: I just tried it and it works fine as long as you're willing to live without the trailing # on each line. I.e.,

    ###################################################################### # Hello there, this is a test. # And this too is a test. More testing, # more testing, more testing ... What a bore! :-) # ######################################################################

    is reformatted as

    ###################################################################### # Hello there, this is a test. And this too is a test. More testing, # more testing, more testing ... What a bore! :-) # ######################################################################
Re: Comment Block Creator
by Anonymous Monk on Dec 03, 2003 at 20:02 UTC

    But doesn't that still make it a pain when you have to update the comments in a comment block?

      Sort of. I have some routines to handle that (that remove the old comments and reformat), but I did them quickly and they don't always work, so I took them out before posting so I wouldn't be ripped apart in a public forum.

•Re: Comment Block Creator
by merlyn (Sage) on Dec 04, 2003 at 13:27 UTC
    My comment? I think it's ugly. Please don't use this on anything you upload to the CPAN, or contribute here. It's OK to use in the privacy of your own cube... just don't let it get out into the wild.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      I think your comment is a little snide and extremely discouraging.

      I'm making a concerted attempt to create thoroughly commented code, and am trying to keep it formatted so it's clear to read. If the format is offensive to you, I'd appreciate suggestions on how to make it less so, but a blanket "it's too ugly to be used in public" reply makes me want to do exactly what you suggest and avoid contributing any code.

      In any event, I'll think two or three times before sharing anything in the future.

        I didn't intend for you to stop sharing!

        But you did post here, and posting here implies inviting critique and comment. Hence my comment.

        The problem with "fancy comments" is that they are either making into comments what should be POD or a separate document, or they are making it hard to rewrite the code, because you don't want to touch the "sacred" fancy comments. Also, being set off that way, you might trust the comments more than the code, and many years of programming has lead me to believe that in "live" code, the comments eventually lie, because someone has edited the code and not the comments.

        Keep your comment style simple. Keep it describing the "what" and not the "how", unless the "how" is particularly tricky. (And most "how" comments should be inline anyway.) Keep it describing any tricky presumptions, assertions, or dependencies. Keep it being for other programmers, not for users of the code (which should be in POD anyway).

        I think once you figure out what really does need commenting, you'll comment less and code more.

        -- Randal L. Schwartz, Perl hacker
        Be sure to read my standard disclaimer if this is a reply.

        Please don't let the lack of social skills of a few discourage you too greatly.

        On the other hand, many experienced programmers find the kind of comment block formatting you are doing to be both excessive and hard to maintain. At the very least, consider leaving the right side of the comment box open rather than closed. Many editors can reflow text with comment characters on the left, making updates relatively painless. But closed-box comments require additional effort and/or tools to maintain, which hinders their usefulness.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://311946]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (3)
As of 2025-11-18 15:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What's your view on AI coding assistants?





    Results (72 votes). Check out past polls.

    Notices?
    hippoepoptai's answer Re: how do I set a cookie and redirect was blessed by hippo!
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.