#!/usr/bin/perl # Warren Block # ts=4 use strict; use warnings; use Getopt::Std; use File::Basename; # convert leading tabs to 8 spaces, ignoring special sections our ($opt_h, $opt_d, $opt_r); my $version = '$Rev$'; my $ignore = 0; my @ignoreblock_tags; my $ignoreblockstart; my $ignoreblockend; my $prog = basename($0); sub usage { $version =~ tr/A-Z:$/a-z/d; print <. -h show summary of command line options and exit -d detab: convert leading tabs to blocks of 8 spaces -r retab: convert leading blocks of 8 spaces to tabs USAGE exit 0; } sub initialize { # create regex for sgml block start and end @ignoreblock_tags = qw/ literallayout screen programlisting /; $ignoreblockstart = '(?:'; for my $tag (@ignoreblock_tags) { $ignoreblockend .= "|<\/$tag>"; } $ignoreblockend .= ')'; } sub tabinate { my $txt = shift; return $txt if $ignore; if ( $opt_d ) { $txt =~ s/\t/ /g; } elsif ( $opt_r ) { $txt =~ s/( {8})/\t/g; } return $txt; } getopts('hdr'); usage() if $opt_h || ($#ARGV < 0); # usage() unless $opt_d || $opt_r; # main initialize(); while (<>) { # don't chomp, leave linefeeds if ( /^\s*$/ ) { print; next; } if ( /^(\s*)(\s*.*)$/ ) { my $indent = $1; my $text = $2; } else { # no indent print } if ( /($ignoreblockstart)/ ) { # operate on this line, but start ignoring print tabinate($_); $ignore = 1; next; } if ( /($ignoreblockend)/ ) { # don't operate on this line, but start paying attention print; $ignore = 0; next; } print tabinate($_); }