V10/cmd/docsubmit/otroff.awk
BEGIN {seen[""] = 0
monkdel = "\(\)\[\]<>{\}\"\"\'\'\`\'"
EQstr="(^\\.EQ)|(\\|begin *[(<[{'\"\`]equation *)|(\\|equation[^_])"
ENstr="(^\\.EN)|(\\|end *[(<[{'\"\`]equation)"
TSstr="(^\\.TS)|(\\|begin *[(<[{'\"\`]table *)|(\\|table[^_])"
TEstr="(^\\.TE)|(\\|end *[(<[{'\"\`]table)"
GSstr="(^\\.GS)|(\\|begin *[(<[{'\"\`]ped *)|(\\|ped[^_])"
GEstr="(^\\.GE)|(\\|end *[(<[{'\"\`]ped)"
PSstr="(^\\.(PS|G1))|(\\|begin *[(<[{'\"\`](picture|graph) *)|(\\|(picture|graph)[^_])"
PEstr="(^\\.(P[EF]|G2))|(\\|end *[(<[{'\"\`](picture|graph))"
ISstr="(^\\.IS)|(\\|begin *[(<[{'\"\`]ideal *)|(\\|ideal[^_])"
IEstr="(^\\.I[EF])|(\\|end *[(<[{'\"\`]ideal)"
picoutput = "This paper appears to have pic output included.\nWe do not accept papers with pic output.\nPlease resubmit it with the pic input instead.\nIf the pic input is in separate files, you can include it by saying:\n.PS <picfile"
tbloutput = "This paper appears to have tbl output included.\nWe do not accept papers with tbl output.\nPlease resubmit it with the tbl input instead.\n"
tpedoutput = "This paper appears to have tped output included.\nWe do not accept papers with tped output.\nPlease resubmit it with the tped input instead.\n"
intbl = ineq = tped = 0
ndelim=""
macs=".BM .BP .BI"
n=split(macs,arr," ")
for(i=1;i<=n;i++)
incmacro[arr[i]]=1
}
/^\.ig/ {
while(getline>0 && $0 !~ /^\.\./);
next
}
# inmacro seeded with .BM .BP .PI also has
# macros including picture macro, try to open all args
/^\./ {
if(($1 in incmacro) && (NF > 1)){
tryall()
next
}
}
# .so - get input file
# or .de that includes .so - try to get file as arg2
/^\.so/ || $1 in hasso {
getfile($2)
next
}
/\|comment/ {
comment("")
next
}
/\|(insert|source)/ {
mgetfile()
next
}
/\|author/ {
author("")
next
}
/\|title[^a-z_]/ {
title("")
next
}
# bwk macro
/^\.ge/ {
system( "trget " NF " " $2 " " $3 " " $4 " " $5 )
close( "trget " NF " " $2 " " $3 " " $4 " " $5 )
next
}
# bwk macro
/^\.ru/ {
system( $2 " " $3 " " $4 " " $5 " " $6 " " $7 " " $8 " " $9 )
close( $2 " " $3 " " $4 " " $5 " " $6 " " $7 " " $8 " " $9 )
next
}
# inline .sy - execute
/^\.sy/ {
system( $2 " " $3 " " $4 " " $5 " " $6 " " $7 " " $8 " " $9 )
close( $2 " " $3 " " $4 " " $5 " " $6 " " $7 " " $8 " " $9 )
next
}
/^\.bm/ {
next
}
# switch in and out of eqn
$0 ~ EQstr { ineq = 1
print $0
if($0 !~ /^\./ && $0 !~ /\|begin/)
ndelim=getdel()
next
}
$0 ~ ENstr { ineq = 0}
# switch in and out of tbl
$0 ~ TSstr { intbl = 1
print $0
if($0 !~ /^\./ && $0 !~ /\|begin/)
ndelim=getdel()
next
}
$0 ~ TEstr { intbl = 0}
# all tbl output has this - unlikely otherwise - reject
/^\.de 35/ {
if(intbl){
print tbloutput|"cat 1>&2"
exit 1
}
}
# save eqn delimiters - # bad for tbl, pic - warn
/^[ ]*delim[ ]*/ {
if(ineq){
if($2 ~ /#/)
print "eqn delimiters in " $0 " will break tbl, pic etc"|"cat 1>&2"
delim = $0
}
}
# macro definition - check for embedded picture macros
# bitmaps, or .so
/^\.(de|am)/ {
if($0 ~ /IS/)
print ".IS is defined in " file " check it for ideal"|"cat 1>&2"
print $0
xname = $2
while((getline) > 0){
if($0 ~ /^\.ig/){
while((getline) >0 && $0 !~ /^\.\./);
continue
}
if($0 ~ /^\.\./)break
if($0 ~ /^\.(BM|BP|PI)/)incmacro["." xname]=1
if($0 ~ /^\.so/){
hasso["." xname] = 1
print "The .so embedded in macro " xname " may cause files not to be shipped " | "cat 1>&2"
defso = 1
}
print $0
}
}
# .PS <file
# check if file contains .PS
# replace .PS <file with file (and .PS in needed)
# copy other files if copy thru included
/^\.PS[ \t]*</ {
gsub(/ /,"")
a=substr($0,index($0,"<")+1)
if((getline<a) >0){
pflag=0
start=1
if($0 ~ /^\./){
print $0
pflag=1
if($0 !~ /^\.PS/){
while(getline<a > 0){
if($0 !~ /^\./)break
print $0
if($0 ~ /^\.PS/)pflag=0
}
if(pflag)print ".PS"
start=0
}
}
else{ print ".PS"
start=0
}
pflag = getpic(a,start,0,"")
if(pflag)print ".PE"
close(a)
}
else {
print "couldn't open pic file:" a|"cat 1>&2"
print "from line: " $0|"cat 1>&2"
exit 1
}
next
}
# tped .GS may name file to include
# if so, copy file; replace full path with file name
# else toggle tped flag
$0 ~ GSstr {
if($0 ~ /^\.GS/ && NF > 1){
for(t=2; t<=NF;t++){
if($t !~ "-" && $t !~ "="){
system( "cp " $t " " dir )
close( "cp " $t " " dir )
if($0 ~ "/"){
nstat=split($0,stat,"/")
cmd = ""
for(xx=1;xx<t;xx++)
cmd= cmd $xx " "
print cmd stat[nstat]
}
else print $0
next
}
}
}
intped=1
print $0
if($0 !~ /^\./ && $0 !~ /\|begin/)
ndelim=getdel()
next
}
$0 ~ GEstr {
intped=0
}
# .sp -1 clue of included tped output
/^\.sp -1/ {
if(intped){
print tpedout|"cat 1>&2"
exit 1
}
}
# grap/pic may include file
$0 ~ PSstr {
getpic("",0,1,"")
next
}
# ideal - may include file
$0 ~ ISstr {
print $0
if($0 !~ /^\./ && $0 !~ /\|begin/)
idelim=getdel()
else idelim=IEstr
while(getline){
if($0 ~ idelim){
print $0
next
}
else if($0 ~ /^[\.]+include/)
doinclude($1, $2, 0)
else print $0
}
}
# macro called that includes .so probably not included
/^\./ {
if($1 in hasso)
print $2 "with embedded .so called"| "cat 1>&2"
}
/.*/ {
if(ndelim != "")
if($0 ~ ndelim){
ineq=intbl=0
ndelim=""
}
print $0
}
function havecopy(cmd, file, i, ofile, quotes,n,rname,NAME,j){
if(file ~ /"/){
quotes=1
n = split(file, name, "\"")
if(n>1)rname = name[2]
}
else {
rname = file
quotes=0
}
if(rname ~ "/"){
n = split(rname,nn, "/")
NAME=nn[n]
}
else NAME=rname
if(i > 2)for(j=2;j<i;j++)cmd = cmd " " $j
if(quotes)cmd = cmd " \"" NAME "\""
else cmd = cmd " " NAME
if(NF >= i+1)
for(j=i+1; j<=NF; j++)cmd = cmd " " $j
if(ofile != "")print cmd >>ofile
else print cmd
if(rname in seen)return
getpic(rname,1,0,dir "/" NAME)
close(rname)
close(dir "/" NAME)
seen[rname]=1
}
function tryall( cmd,i,tryit,found){
cmd=$1
found=0
for(i=2;i<=NF;i++){
if((getline tryit <$i)>0){
found=1
cmd= cmd " " getcopy($i)
}
else cmd = cmd " " $i
close($i)
}
print cmd
if(!found){
print "no files found in " cmd|"cat 1>&2"
}
}
function getcopy(file, rname,quotes,n,NAME){
rname=file
quotes=0
if(file ~ /"/){
quotes=1
n=split(file,name,"\"")
if(n>1)rname=name[2]
}
system( "cp " rname " " dir )
close( "cp " rname " " dir )
if(rname ~ "/"){
n = split(rname,nn, "/")
NAME=nn[n]
}
else NAME=rname
if(quotes)return("\"" NAME "\"")
else return(NAME)
}
function getfile(file, File, eflag,first,indef,xname,fintbl,finpic,saveline){
if(file ~ /\/usr\/lib\//|| file ~ /\/exptools\//){
print $0
return
}
saveline=$0
if((getline <file) > 0){
if($0 ~ /@\(#\)dcs:[cC][Ss]macros/){
print saveline
return
}
if($0 ~ /^\.lf/){
File=$NF
saveline=$0
if((getline <File)<=0){
print "This paper contains preprocessor output evidenced by " saveline| "cat 1>&2"
print "and I can't find the source file " File|"cat 1>&2"
while((getline < file) >0 && $0 ~ /^\.lf/)
print $0| "cat 1>&2"
print "paper not submitted" | "cat 1>&2"
exit 1
}
}
else File = file
}
else {
print "cannot open file " file | "cat 1>&2"
return
}
if(File in seen){
close(File)
return
}
if(delim != "" && !ismonk){
print ".EQ\ndelim off\n.EN"
eflag=1
}
seen[File] = 1
first=1
while(1){
if(first==0)if((getline <File)<=0)break
first = 0
if($0 ~ /^\.ig/){
while((getline<File)>0 && $0 !~ /^\.\./);
continue
}
if($0 ~ /^\.(de|am)/){
if(fintbl && $0 ~ /^\.de 35/){
print tbloutput|"cat 1>&2"
print "The tbl output is in the .so file named:" File|"cat 1>&2"
exit 1
}
indef=1
xname = $2
}
if(indef && $0 ~ /^\.(BM|BP|PI)/)incmacro["." xname]=1
if($0 ~ /^\.\.$/)indef=0
if($0 ~ /^\.sy/ && indef == 0){
print "the .sy commands in this paper will not be handled" indef|"cat 1>&2"
if(debug ~ /-d/){
print $0
continue
}
print "paper not submitted" | "cat 1>&2"
exit 1
}
if($0 ~ TSstr)fintbl=1
if($0 ~ TEstr)fintbl=0
if($0 ~ PSstr)getpic(File,0,1,"")
else if($0 ~ /\|comment/)comment(File)
else if($0 ~ /\|(insert|source)/)mgetfile()
else if($0 ~ /\|author/)author(File)
else if($0 ~ /\|title[^a-z_]/)title(File)
else if(($1 in incmacro)&& (NF > 1)&&!indef)
tryall()
else if($0 ~ /^\.so/){
if(!indef)getfile($2)
else hasso["." xname]=1
}
else print $0
}
close(File)
if(eflag){
print ".EQ\n" delim "\n.EN"
eflat = 0
}
}
function doinclude(cmd, fname, fileflag, file){
if(fname ~ "/"){
n=split(fname,name,"/")
if(fileflag)print cmd " " name[n] >(dir "/" file)
else print cmd " " name[n]
}
else if(fileflag)print cmd " " fname >(dir "/" file)
else print cmd " " fname
while((getline<fname)>0){
if($0 ~ /^[\.]+include/)
doinclude($1, $2, 1, fname)
else print $0 >(dir "/" fname)
}
close(fname)
}
function getpic(file,flag,iscmd, ofile, rfile, inmonk, pflag, i, pdelim){
pflag = 1
inmonk=0
if(iscmd && $0 !~ /^\./ && $0 !~ /\|begin/){
i=$0
pdelim=getdel()
$0=i
}
else pdelim=PEstr
rfile=file
while(1){
if(flag){
if(rfile == ""){
if(getline <= 0)break
}
else if((getline<rfile)<=0){
if(!inmonk)break
inmonk=0
close(rfile)
rfile=file
if(ofile != "")print "...\\\"end insert" >>ofile
else print "...\\\"end insert"
continue
}
}
flag=1
if($0 ~ /\|(insert|source)/){
if(ofile != "")print "...\\\"begin insert" >>ofile
else print "...\\\"begin insert"
rfile=getname()
inmonk=1
continue
}
if(!inmonk && $0 ~ pdelim){
pflag=0
if(ofile != "")print $0 >>ofile
else print $0
break
}
if($0 ~ /(copy|include)/){
for(i=1;i<NF;i++)
if($i ~ /(copy|include)/)break
i++
if (($i !~ "thru") && ($i !~ "through")) {
havecopy($1, $i, i, ofile);
}
else {
if(ofile != "")print $0 >>ofile
else print $0
}
}
else if($0 ~ /^\.sp -1/){ #sign in pic output included
print picoutput|"cat 1>&2"
exit 1
}
else {
if(ofile != "")print $0 >>ofile
else print $0
}
}
return(pflag)
}
function getdel(){
if($0 !~ /^\|/ && $0 ~ /..*\|/)sub(/^..*\|/,"\|")
sub(/\|[a-z \t]*/,"")
ldelim = substr($0, 0, 1)
sub(/./,"")
b = substr(monkdel,index(monkdel,ldelim)+1,1)
prdelim = b
return("\\" b)
}
function comment(fname, rdelim){ #print comment to avoid losing lines
print $0
rdelim = getdel()
if($0 ~ rdelim)return
if(fname == ""){
while(getline > 0){
print $0
if($0 ~ rdelim)break
}
}
else while((getline<fname)>0){
print $0
if($0 ~ rdelim)break
}
}
# reorder author/title in monk
function author(fname, rdelim){
if(titleflag)print $0
else if(sauthor == "")sauthor = $0
else sauthor = sauthor "\n" $0
rdelim = getdel()
if($0 !~ rdelim){
while(1){
if(fname == ""){
if(getline <= 0)break
}
else {
if((getline<fname) <= 0)break
}
if(titleflag)print $0
else sauthor = sauthor "\n" $0
if($0 ~ rdelim)break
}
}
}
function title(fname, rdelim){
print $0
rdelim = getdel()
if($0 !~ rdelim){
if(fname == "")
while(getline > 0){
print $0
if($0 ~ rdelim)break
}
else while((getline<fname) > 0){
print $0
if($0 ~ rdelim)break
}
}
if(sauthor != ""){
print sauthor
sauthor = ""
}
titleflag=1
}
function mgetfile( rname){
rname=getname()
if(rname in seen)return
ismonk=1
getfile(rname)
}
function getname( del,n){
del=getdel()
n=split($0, xa, del)
if(n>0)return(xa[1])
else return($0)
}