1151497Sru#! /usr/bin/perl
275584Sru# grog -- guess options for groff command
375584Sru# Inspired by doctype script in Kernighan & Pike, Unix Programming
475584Sru# Environment, pp 306-8.
575584Sru
675584Sru$prog = $0;
775584Sru$prog =~ s@.*/@@;
875584Sru
975584Sru$sp = "[\\s\\n]";
1075584Sru
1175584Srupush(@command, "groff");
1275584Sru
1375584Sruwhile ($ARGV[0] =~ /^-./) {
1475584Sru    $arg = shift(@ARGV);
1575584Sru    $sp = "" if $arg eq "-C";
1675584Sru    &usage(0) if $arg eq "-v" || $arg eq "--version";
1775584Sru    &help() if $arg eq "--help";
1875584Sru    last if $arg eq "--";
1975584Sru    push(@command, $arg);
2075584Sru}
2175584Sru
22104862Sru@ARGV = ('-') unless @ARGV;
23104862Sruforeach $arg (@ARGV) {
24104862Sru    &process($arg, 0);
2575584Sru}
2675584Sru
2775584Srusub process {
2875584Sru    local($filename, $level) = @_;
2975584Sru    local(*FILE);
3075584Sru
3175584Sru    if (!open(FILE, $filename eq "-" ? $filename : "< $filename")) {
3275584Sru	print STDERR "$prog: can't open \`$filename': $!\n";
3375584Sru	exit 1 unless $level;
3475584Sru	return;
3575584Sru    }
3675584Sru    while (<FILE>) {
3775584Sru	if (/^\.TS$sp/) {
3875584Sru	    $_ = <FILE>;
3975584Sru	    if (!/^\./) {
4075584Sru		$tbl++;
4175584Sru		$soelim++ if $level;
4275584Sru	    }
4375584Sru	}
4475584Sru	elsif (/^\.EQ$sp/) {
4575584Sru	    $_ = <FILE>;
4675584Sru	    if (!/^\./ || /^\.[0-9]/) {
4775584Sru		$eqn++;
4875584Sru		$soelim++ if $level;
4975584Sru	    }
5075584Sru	}
5175584Sru	elsif (/^\.GS$sp/) {
5275584Sru	    $_ = <FILE>;
5375584Sru	    if (!/^\./) {
5475584Sru		$grn++;
5575584Sru		$soelim++ if $level;
5675584Sru	    }
5775584Sru	}
5875584Sru	elsif (/^\.G1$sp/) {
5975584Sru	    $_ = <FILE>;
6075584Sru	    if (!/^\./) {
6175584Sru		$grap++;
6275584Sru		$pic++;
6375584Sru		$soelim++ if $level;
6475584Sru	    }
6575584Sru	}
6675584Sru	elsif (/^\.PS$sp([ 0-9.<].*)?$/) {
6775584Sru	    if (/^\.PS\s*<\s*(\S+)/) {
6875584Sru		$pic++;
6975584Sru		$soelim++ if $level;
7075584Sru		&process($1, $level);
7175584Sru	    }
7275584Sru	    else {
7375584Sru		$_ = <FILE>;
7475584Sru		if (!/^\./ || /^\.ps/) {
7575584Sru		    $pic++;
7675584Sru		    $soelim++ if $level;
7775584Sru		}
7875584Sru	    }
7975584Sru	}
80104862Sru	elsif (/^\.R1$sp/) {
8175584Sru	    $refer++;
8275584Sru	    $soelim++ if $level;
8375584Sru	}
84104862Sru	elsif (/^\.\[/) {
85104862Sru	    $refer_open++;
86104862Sru	    $soelim++ if $level;
87104862Sru	}
88104862Sru	elsif (/^\.\]/) {
89104862Sru	    $refer_close++;
90104862Sru	    $soelim++ if $level;
91104862Sru	}
9275584Sru	elsif (/^\.[PLI]P$sp/) {
9375584Sru	    $PP++;
9475584Sru	}
9575584Sru	elsif (/^\.P$/) {
9675584Sru	    $P++;
9775584Sru	}
9875584Sru	elsif (/^\.(PH|SA)$sp/) {
9975584Sru	    $mm++;
10075584Sru	}
10175584Sru	elsif (/^\.TH$sp/) {
10275584Sru	    $TH++;
10375584Sru	}
10475584Sru	elsif (/^\.SH$sp/) {
10575584Sru	    $SH++;
10675584Sru	}
10775584Sru	elsif (/^\.([pnil]p|sh)$sp/) {
10875584Sru	    $me++;
10975584Sru	}
11075584Sru	elsif (/^\.Dd$sp/) {
11175584Sru	    $mdoc++;
11275584Sru	}
11375584Sru	elsif (/^\.(Tp|Dp|De|Cx|Cl)$sp/) {
11475584Sru	    $mdoc_old = 1;
11575584Sru	}
11675584Sru	# In the old version of -mdoc `Oo' is a toggle, in the new it's
11775584Sru	# closed by `Oc'.
11875584Sru	elsif (/^\.Oo$sp/) {
11975584Sru	    $Oo++;
12079543Sru	    s/^\.Oo/\. /;
12179543Sru	    redo;
12275584Sru	}
12379543Sru	# The test for `Oo' and `Oc' not starting a line (as allowed by the
12479543Sru	# new implementation of -mdoc) is not complete; it assumes that
12579543Sru	# macro arguments are well behaved, i.e., "" is used within "..." to
12679543Sru	# indicate a doublequote as a string element, and weird features
12779543Sru	# like `.foo a"b' are not used.
12879543Sru	elsif (/^\..* Oo( |$)/) {
12979543Sru	    s/\\\".*//;
13079543Sru	    s/\"[^\"]*\"//g;
13179543Sru	    s/\".*//;
13279543Sru	    if (s/ Oo( |$)/ /) {
13379543Sru		$Oo++;
13479543Sru	    }
13579543Sru	    redo;
13679543Sru	}
13775584Sru	elsif (/^\.Oc$sp/) {
13875584Sru	    $Oo--;
13979543Sru	    s/^\.Oc/\. /;
14079543Sru	    redo;
14175584Sru	}
14279543Sru	elsif (/^\..* Oc( |$)/) {
14379543Sru	    s/\\\".*//;
14479543Sru	    s/\"[^\"]*\"//g;
14579543Sru	    s/\".*//;
14679543Sru	    if (s/ Oc( |$)/ /) {
14779543Sru		$Oo--;
14879543Sru	    }
14979543Sru	    redo;
15079543Sru	}
151104862Sru	elsif (/^\.(PRINTSTYLE|START)$sp/) {
152104862Sru	    $mom++;
153104862Sru	}
15475584Sru	if (/^\.so$sp/) {
15575584Sru	    chop;
15675584Sru	    s/^.so *//;
15775584Sru	    s/\\\".*//;
15875584Sru	    s/ .*$//;
15975584Sru	    &process($_, $level + 1) unless /\\/ || $_ eq "";
16075584Sru	}
16175584Sru    }
16275584Sru    close(FILE);
16375584Sru}
16475584Sru
16575584Srusub usage {
16675584Sru    local($exit_status) = $_;
16775584Sru    print "GNU grog (groff) version @VERSION@\n";
16875584Sru    exit $exit_status;
16975584Sru}
17075584Sru
17175584Srusub help {
17275584Sru    print "usage: grog [ option ...] [files...]\n";
17375584Sru    exit 0;
17475584Sru}
17575584Sru
176104862Sru$refer ||= $refer_open && $refer_close;
177104862Sru
17875584Sruif ($pic || $tbl || $eqn || $grn || $grap || $refer) {
17975584Sru    $s = "-";
18075584Sru    $s .= "s" if $soelim;
18175584Sru    $s .= "R" if $refer;
18275584Sru    # grap must be run before pic
18375584Sru    $s .= "G" if $grap;
18475584Sru    $s .= "p" if $pic;
18575584Sru    $s .= "g" if $grn;
18675584Sru    $s .= "t" if $tbl;
18775584Sru    $s .= "e" if $eqn;
18875584Sru    push(@command, $s);
18975584Sru}
19075584Sru
19175584Sruif ($me > 0) {
19275584Sru    push(@command, "-me");
19375584Sru}
19475584Sruelsif ($SH > 0 && $TH > 0) {
19575584Sru    push(@command, "-man");
19675584Sru}
197104862Sruelse ($mom > 0) {
198104862Sru    push(@command, "-mom");
199104862Sru}
20075584Sruelsif ($PP > 0) {
20175584Sru    push(@command, "-ms");
20275584Sru}
20375584Sruelsif ($P > 0 || $mm > 0) {
20475584Sru    push(@command, "-mm");
20575584Sru}
20675584Sruelsif ($mdoc > 0) {
20775584Sru    push(@command, ($mdoc_old || $Oo > 0) ? "-mdoc-old" : "-mdoc");
20875584Sru}
20975584Sru
21075584Srupush(@command, "--") if @ARGV && $ARGV[0] =~ /^-./;
21175584Sru
21275584Srupush(@command, @ARGV);
21375584Sru
21475584Sru# We could implement an option to execute the command here.
21575584Sru
21675584Sruforeach (@command) {
21775584Sru    next unless /[\$\\\"\';&()|<> \t\n]/;
21875584Sru    s/\'/\'\\\'\'/;
21975584Sru    $_ = "'" . $_ . "'";
22075584Sru}
22175584Sru
22275584Sruprint join(' ', @command), "\n";
223