http://qs321.pair.com?node_id=464392
Category: Fun Stuff
Author/Contact Info /msg kaif
Description:

You may have seen Jamie Zawinski's program jack.c before. Since I need to write a description, I'll spoil the fun: running man bash through his program prints something like

dull boy. All work and no play makes Jack a dull boy. All work and + no play makes Jack a dull boy. All work and no play makes Jack a dull +boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. All work and no p +lay makes Jack a dull boy. All work and no play makes Ja +ck a dull boy. All work and no play makes Jack a dull boy +.

However, his program clearly needed a rewrite (and upgrade) in Perl. So, here's my version, complete with command-line options -c for whenever you feel like running code through and -j to change Jack to JAPH. Other than the above options, my main improvement is spacing and alignment (to make it more like the original output of man). The same section of man bash now looks like

dull boy. All work and no play makes Jack a dull boy. All work and + no play makes Jack a dull boy. All work and no play makes Jack a d +ull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. All work and + no play makes Jack a dull boy. All work and no play makes J +ack a dull boy. All work and no play makes Jack a dull boy +.

Go ahead, try it out! Run jack.pl -c -j jack.pl today!

#!/usr/bin/env perl
#    Sample usage:  man sh | jack.pl
#                   jack.pl -c -j jack.pl
# (Based on jack.c by Jamie Zawinski.)

use strict;

my( $text, $keep, $work );

$text = "All work and no play makes Jack a dull boy.  ";
$keep = qr<\t>;

while( 1 ) {
    $ARGV[0] =~ /-c/ and do
      { $keep = qr<[][;#(){}"]|/\*|\*/|//>; shift; next; };
    $ARGV[0] =~ /-j/ and do
      { $text = "Just another Perl hacker.  "; shift; next; };
    last;
}

while( <> ) {
    # Stupid `man` formatting
    s/.\10//g;  s/[^[:space:][:graph:]]//gs;

    # Expand tabs
    1 while s/\t+/' ' x (length($&)*8 - length($`)%8)/e;

    xify( split /($keep|(?:\A|\z|\s){4,})/s )
}

sub xify {
    print rep( shift ), shift
      while @_
}

sub rep {
    my( $len, $s, @s, $i );

    $s = shift;
    return "" unless $len = length $s;

    ($s, $work) = ($work . $text x (1 + (length($s) - length $work) / 
+length $text))
      =~ m/^(.{0,@{[length $s]}})(?=\s|\A|\z)\s*(.*)/s;

    @s = split /\s(?=\S)/, $s;
    return $s . ' ' x ($len - length $s) if @s < 2;

    $s[-1] =~ s/\s+$//;
    for( @s ) { $len -= length $_ }
    for( $i = 0; $len--; $i = ($i+1) % $#s ) {
    $s[$i] .= ' '
    }
    join "", @s
}
Replies are listed 'Best First'.
Re: All work and no play makes Jack a dull boy
by ambrus (Abbot) on Jun 08, 2005 at 12:13 UTC

      The same section of the bash manual looks like this according to that program:

      OPTIONS In pootpoot to the poot-pootpoot poot poot pootpoot in the pootpoot of the set poot poot, bash pootpoot the pootpoot poot poot it is poot: -c string If the -c poot is poot, poot pootpoot are poot p +oot string. If poot are pootpoot poot the string, poo +t are pootpoot to the pootpoot pootpoot, pootpoot poot $0. -i If the -i poot is poot, the poot is interactive.