#! /bin/sh
#
# rcbook.t - make a cookbook with nroff or the typesetter
#   linked to rcbook.n
#
# Brian Reid, November 1985
# Copyright (C) USENET Community Trust
#
# Modified by:  David Messer, Febuary 1987
#
# Modified by:  John Rupley, November 1995, May 1999, February 2004
#		details in files 
#			~/src/recipes/Rupley/1NOTE
#			~/src/recipes/Rupley/2NOTE
#			~/src/recipes/Rupley/Test-dir/1NOTE
# NOTE: need gnu ptx = gptx on PATH

COOKBOOK='>Cookbook.nroff'
UPDATE=0
PREPROCESS='tbl|eqn -Tascii |'
POSTPROCESS=''
TROFF="nroff -man -C -i -rC1 -rcR=0 -U"  # specify options for groff-nroff
FRACTIONS=0
PTX="gptx -G " 			# gptx: -G opt -> approximation of ATT ptx
RCINDEX="-f -r -w 56"		# ptx: additional options

case $0 in
	*.t)	TROFF=""
		COOKBOOK='>Cookbook.ps'
		PREPROCESS='tbl|eqn -Tps |'
		POSTPROCESS='|grops -pletter '
		FRACTIONS=1
		RCINDEX="-f -r -t -w 95"	# gptx: -t opt obsolete
		;;
	esac

PATH=
export PATH

TITLE=""

TMAC=/tmac.$$
STARTREC=/Startrec.$$
CONTENTS=/Contents.$$
TOCFILTER=/Tocfilter.$$
TOCMOD=/Tocmod.$$
TOC=/Toc.$$
RECIPES=/Recipes.$$
BADWDS=/rcibadwds.$$
PUNCHR=/rcipunchr.$$
INDEX=/rciindex.$$
INDEXFILE=/INDEXFILE.$$
INDEXFILTER=/rciindexfilter.$$
#COVER=/Cover.$$
COVER=

TMPFILE=/xart.$$
VERBATIM=

TFLAG=
METFLAG="-rM"
KEEPDIR=
OPTIONS="$RCINDEX"		# default or command-line ptx options

# set exit trap
trap "rm -f /*.$$; exit" 0 1 2 3 15

while [ $# -gt 0 ];
do
    case $1 in
	    -t) shift; TFLAG="$1";;	#use for any addnl troff options
	    -v) VERBATIM=0;;
	    -V) VERBATIM=1;;
	    -m) METFLAG="-rM1";;
	    -f) FRACTIONS=0;;
	    -p*) shift; POSTPROCESS="$POSTPROCESS $1";;
	    -P*) shift; POSTPROCESS="$1"; COOKBOOK="";;
	    -O*) shift; OPTIONS="$OPTIONS $1";;		#options for ptx
	    -N) COOKBOOK=`echo $COOKBOOK|sed -e "s/Cookbook/Update/"`
			UPDATE=1;;
	    -*) echo $0: Unknown option $1 1>&2
			exit 1;;
	    "") KEEPDIR=;;
	    *) KEEPDIR=$1;;
    esac
    shift
done


# setup awk program for deletion of header and footer material
# in a recipe file, as for a usenet posting;
# should have no effect on other files;
# if problem, toggle extractor 0=on/1=off with:
#	set of VERBATIM=0/1	(makefile variable E X T R A C T O R)
# or
#	rcbook.t -[v,V]		# command-line toggle: v=on=0, V=off=1

cat > $TMPFILE << 'extractor.awk'
BEGIN {Seen = 0}
/^\.RH MOD\.RECIPES/ {Seen = 1}
/^-- *$/ {Seen = 0}
/^\/\* End of text from/ {Seen = 0}
Seen == 1 {print $0}
extractor.awk


#  today's date information in flexible format
#  Thu Mar 27 22:56:49 PST 1986
set `date`
YEAR="$6"
YR=`expr $YEAR - 2000`
TODAY="$3 $2 $YEAR"

if [ ! -d $KEEPDIR ]; then
	echo Your keep directory $KEEPDIR does not seem to exist. 1>&2
	exit 1
fi;


echo Typesetting $POSTPROCESS $COOKBOOK from files in $KEEPDIR 1>&2


# construct a troff input file of:
#	UNIX man macros
#	recipe macros, from USENET alt.gourmand software
#	modifications of certain macros in above, as needed for 
#		customized formatting of Cookbook

cat << 'tmac.recip' | sed -e "s/REPLACE-TODAY/\"${TODAY}\"/" -e "s/REPLACE-TITLE/${TITLE}/" -e "/^[ 	]*$/d" -e '/^\.\\"./d' -e "/^\.ig/,/^\.\./d" > $TMAC
.\" read in alt.gourmand recipe macros, modified minimally
.\" Macro package Copyright (C) 1986 USENET Community Trust
.\" tmac.recip version 3, June 1986
.\"
.\" French stuff - THIS MAY NOY BE NEEDED WITH (EXTENDED) GROFF CHARSET
.\" and a proper-name o' from alt.gourmand
.ds A` A\h'-.5'\v'-.2m'\(ga\v'.2m'\h'.25'
.ds E' E\h'-.5'\v'-.2m'\(aa\v'.2m'\h'.25'
.ds E` E\h'-.5'\v'-.2m'\(ga\v'.2m'\h'.25'
.ds U^ U\h'-.55'\v'-.2m'^\v'.2m'\h'.25'
.ds E^ E\h'-.45'\v'-.2m'^\v'.2m'\h'.15'
.ds A^ A\h'-.55'\v'-.2m'^\v'.2m'\h'.25'
.ds O^ O\h'-.55'\v'-.2m'^\v'.2m'\h'.25'
.\" .ds C, \o'C\(,a'
.ds C, \(,C
.ds a` \o'a\(ga'
.ds e' \o'e\(aa'
.ds e` \o'e\(ga'
.ds u^ \o'u^'
.ds e^ \o'e^'
.ds a^ \o'a^'
.ds o^ \o'o^'
.\" .ds c, \o'c\(,a'
.ds c, \(,c
.ds o' \o'o\(aa'

.\"
.\"	# Recipe Heading
.de RH
.ie '\\$5'' .ds YR 1985
.el .ds YR \\$5
.ie n .ds YC Copyright \\*(YR Nemo
.el .ds YC Copyright \(co \\*(YR Nemo
.ie n .TH \\$2 "\\$3" "" REPLACE-TODAY "REPLACE-TITLE (\\$4)"
.el .TH \\$2 "\\$3" "" REPLACE-TODAY "REPLACE-TITLE (\\$4)"
.ds ]H \\$2
..

.de RZ
.SH \\s14\\$1
.rs
.ie n .sp 1
.el   .sp 6p
.in \\n[IN]	\" this is a hack - better to use nr register???
\\*(]H \- \\$2
.fi
.PP
..

.\"	# Ingredient
.de IG
.ds =1 \\$1
.ds =2 \\$2
.if \\n(.$>2 .if  \\nM .ds =1 \\$3
.TP 10
\&\\*(=1
.I \\*(=2
..

.\"	# Step
.de SK
.IP "(\\$1)" 5n
..

.\"	# Ingredient header
.de IH
.ds =1 \\$1
.if \\n(.$>1 .if \\nM .ds =1 \\$2
.SH INGREDIENTS (\\*(=1)
.fi
.PD 0
..

.\"	# Procedure header
.de PH
.PD
.ie '\\$1'' .SH PROCEDURE
.el .SH PROCEDURE \\$1
.RS 5
..

.\"	# Temperature value
.de To
.ds =2
.if \\n($>2 .ds =2 \\$3
.ie n .ds =1 \\$1 deg. F
.el .ds =1 \\$1\(deF
.ie n .if \\n(.$>1 .if \\nM .ds =1 \\$2 deg. C
.el .if \\n(.$>1 .if \\nM .ds =1 \\$2\(deC
\\*(=1\\*(=2
..

.\"	# inline value selector
.de AB
.ds =1 \\$1
.if \\nM .ds =1 \\$2
.ds =2
.if \\n($>2 .ds =2 \\$3
\\*(=1\\*(=2
..

.\"	# Notes
.de NX
.PD
.SH NOTES
..

.\"	# Wrapup
.de WR
.RE 5
.PD
.SH CONTRIBUTOR
.nf
..

.\" these CS macros courtesy of Bernie Cosell and Matt Bishop
.de CS  \" do the fancy "go into cs mode right" guy
.   ie \\n(.z .cs \\$1 \\$2 \\$3
.   el              \!.CS \\$1 \\$2 \\$3
..

.de FW \" Go into fixed-width mode: put both italic and bold fonts in it
.   CS B 21 \\(.s
.   CS I 21 \\(.s
.   ss 24
.   lg 0
..

.de Fw \" Leave fixed-width mode
.   CS B
.   CS I
.   ss 12
.   lg 1
..

.\" redefine RZ macro, to send data to stderr,
.\" for capture and later processing to generate TOC and index files
.de RZ
.SH \\s14\\$1
.rs
.ie n .sp 1
.el   .sp 6p
.in \\n[IN]	\" this is a hack - better to use nr register???
\\*(]H \- \\$2 \\$3 \\$4 \\$5
.fi
.PP
.ds ]A \\$1
.\" send data for TOC and index to standard error, for later processing
.tm \\\\"\\n%	\\s14\\*(]A	\\s10\\*(]H\\\\"
.\" apparently have a 256 char limit on .tm string
.tm - \\$2 
.tm x \\$3
.tm x \\$4
.tm x \\$5
.\".tm - \\*(]B \\*(]C
..
tmac.recip


# two files, $PUNCHR and $BADWDS, used in running ptx, the index generator

cat > $PUNCHR << 'endflag'	#added more punctuation chars
()/.,:;
endflag

tr ' ' '\12' << 'endflag' | sort -u > $BADWDS		#added more bad words
& - a about addictive after against all also amazingly an and
another any are as at back basic be because been before being best-ever
between both but by came can center classic cloying come con cook
cooked cooking could countries day decadent delicate delicious did
dinner dish dishes do down each earthy easy-to-make even extremely fattening
filling first flavor flavorful food for from get go good great had has have
he hearty her here him his hot how i if in incredible into intoxicating is
it its just know large last life light like little long luscious made
make makes man many may me men might more most mr much must my never
new no not now of off old on one only or other our out over own people
picture-perfect prizewinning recipe recipes refreshing rich right said
same see she should since smothered so some state still succulent such
take than that the their them then there these they thick this those
three through time to too two ultimate under universe up us used very
was way we well were what when where which while who will with
wonderful work world would year years you your
a` au aux beaten chopped cold covered de fine flavor flavored fully
high high ingredient ingredients l# la liquid melted optional
optionally oven partially partly served small temperature temperature
varied various whole
endflag


# filter to process captured RZ output into index

sed -e "s%PTX%$PTX%" -e "s%TOC%$TOC%" -e "s%BADWDS%$BADWDS%" -e "s%PUNCHR%$PUNCHR%" -e "s%OPTIONS%$OPTIONS%" -e "s%INDEXFILE%$INDEXFILE%" > $INDEXFILTER << 'Indexfilter'
<TOC egrep -v '^[^-x\\]' |
sed -e 's/^x //' |
awk -F"	" '
/^- /	{
# read description line and 3 hardwired continuation lines, even if blank
	line = $0
	getline
	line = line " " $0
	getline
	line = line " " $0
	getline
	line = line " " $0
	print line
	next
}
	{
	print
}' |
sed -e 's/[\][\"]//g' -e 's/^- //' -e 's/\\s[0-9][0-9]*//g' |
awk -F"	" '
/^[0-9]/ {
	num = $1
	file = $NF
	getline
	# concatenate two lead fields into one with hyphen, for ptx input
	printf "%s-%s %s\n", num, file, $0
}' |
# use mnemonics for special French characters; only have lower case text
sed     -e "s/\\\\o\'a\\\(ga\'/a\`/g" \
	-e "s/\\\\o\'e\\\(aa\'/e\'/g" \
	-e "s/\\\\o\'e\\\(ga\'/e\`/g" \
	-e "s/\\\\o\'u^\'/u^/g" \
	-e "s/\\\\o\'e^\'/e^/g" \
	-e "s/\\\\o\'a^\'/a^/g" \
	-e "s/\\\\o\'o^\'/o^/g" \
	-e "s/\\\\(,c/c%/g" |
#	-e "s/\\\\o\'c\\\\(,a\'/c%/g" |
# get rid of \f? commands for italics, etc, which really foul up ptx output
sed -e 's/\\fI//g' -e 's/\\fP//g' |
# convert French "l'" to separate word "l# ", so ptx indexes on following noun
sed -e "s/l\'/l# /g" |
PTX -f -r -i BADWDS -b PUNCHR OPTIONS |
# get rid of lines from ptx with keyword based on punc char in troff command
# such as, \(aa, which splits into \(" and keyword "aa......
egrep -v '\\[*(,.:;)]+\"\ ' |
# reconvert "l# " to "l'"
sed -e "s/l# /l\'/g" -e "s/l#\"/l'\"/g"|
#reconvert French characters
sed     -e "s/a\`/\\\\o\'a\\\(ga\'/g" \
	-e "s/e\'/\\\\o\'e\\\(aa\'/g" \
	-e "s/e\`/\\\\o\'e\\\(ga\'/g" \
	-e "s/u^/\\\\o\'u^\'/g" \
	-e "s/e^/\\\\o\'e^\'/g" \
	-e "s/a^/\\\\o\'a^\'/g" \
	-e "s/o^/\\\\o\'o^\'/g" \
	-e "s/c%/\\\\(,c/g" |
#	-e "s/c%/\\\\o\'c\\\\(,a\'/g" |
# remove concatenation introduced above and change ptx leader
sed -e 's/\([0-9][0-9]*\)-/\1 /' -e 's/^\.xx/.XX/' >INDEXFILE
Indexfilter
chmod +x $INDEXFILTER


# construct troff input file containing index

sed -e "s%INDEXFILTER%$INDEXFILTER%" -e "s%INDEXFILE%$INDEXFILE%" -e "s/DATE/$TODAY/g" -e "s/YEAR/$YEAR/g" > $INDEX << 'Index'
.de XX
.tr ~ 
.ta 2.1iR 2.3i 5.2i 5.5i
.ie !"\\$2""	\\$1~~~~~\\$2	\\$3~~~~~~\\$4	\\$5	\\$6
.el	\\$1	\\$3~~~~~~\\$4	\\$5	\\$6
..
.\" should call RH -> TH with page reg %  numeric format
.\" note that have flushed CONTENTS and reset % with ".bp 0"
.af % 1
.RH MOD.RECIPES-SOURCE INDEX Recipes "DATE" YEAR
.af % i
.ll 6.5i
.nf
.br
.ps 10
.vs 10p
.sy INDEXFILTER		\"process the RZ output for index
.so INDEXFILE		\"import the results
.fi
Index


# filter to process captured RZ output into table of contents

sed -e "s%TOCMOD%$TOCMOD%" -e "s%TOC%$TOC%" > $TOCFILTER << 'tocfilter'
<TOC egrep -v '^[^-x\\]' |
sed -e 's/[\][\"]//g' -e 's/^x //' |
awk -F"        " '
/^- /    {
# read description line and 3 hardwired continuation lines, even if blank
	line = $0
	getline
	line = line " " $0
	getline
	line = line " " $0
	getline
	line = line " " $0
	print line
	next
}
	{
	print
}' |
awk -F"	" '
/^[0-9]/ {
	print ".sp"
	print ".ta .5i 7.iR"
	print ".nf"
	print ".in -.5i"
	print $0
	print ".in"
	print ".fi"
	print ".ta"
}
/^[^0-9]/ {
	print $0
}' >TOCMOD
tocfilter
chmod +x $TOCFILTER


# construct troff input file containing table of contents

sed -e "s/DATE/$TODAY/g" -e "s/YEAR/$YEAR/g" -e "s%TOCFILTER%$TOCFILTER%" -e "s%TOCMOD%$TOCMOD%" > $CONTENTS << 'Contents'
.RH MOD.RECIPES-SOURCE "CONTENTS" Recipes "DATE" YEAR
.af % i
.ps 10
.vs 12p
.sy TOCFILTER		\"process the RZ output for TOC
.so TOCMOD		\"import the results
Contents


# be sure $COVER points to the troff file for cover page == rcbook.cover
# COVER="./rcbook.cover"


# construct small troff input file to separate sections:
# flush to output; remove traps; reset page number register;

cat > $STARTREC << 'Startrec'
.fl
.wh 0
.bp 0
.sp |3i
.ps 12
.ce
THIS PAGE ENDS A SECTION
.sp 2
.ce
IT IS INTENTIONALLY BLANK
Startrec


# set up for test on file creation/modification date if doing an update

if  [ $UPDATE -eq 1 ]
then
	UPDATE_TEST="-newer Last.update"
fi


# construct troff input file of all recipe pages
# no limit on number of files in $KEEPDIR directory
# i.e., no blown sh/ksh command line buffer
#	put list of files into readline, 
#	then cat file specified on each line into preprocessors/formatters
# NOTE: two subroutines preprocess files, triggered by set of:
#	FRACTIONS	
#	VERBATIM

find $KEEPDIR -name [a-z]\* $UPDATE_TEST -print | 
egrep "$KEEPDIR/[^/]+$" |
sort | 
while read line
do
	case $FRACTIONS in
	  1) cat $line ;;
	  *) cat $line |
		 sed -e 's/\([0-9a-zA-Z]\)\(\\([1-3]\)/\1 \2/g' \
			-e 's|\\(12|1/2|' -e 's|\\(14|1/4|' -e 's|\\(34|3/4|' \
			-e 's|``|"|'     -e "s|''|\"|" ;;
	esac |
	# strip comments and .ig sections
	sed -e "/^\.ig/,/^\.\./d" -e "/^\.\\\"/d" |
	case $VERBATIM in
	  0) awk -f $TMPFILE;;
	  1) awk '{print}';;
	esac |
	# switch alt.gourmand use of .TE -> .To, to avoid table conflict
	awk '/^\.TE / {if (NF > 1) sub("\.TE", ".To")}; {print}' |
	# conversions for special French characters as in alt.gourmand
	# and a proper-name o' also from alt.gourmand
	sed	-e "s/\\\\z\\\(aae/\\\*\(e\'/g" \
		-e "s/\\\\z\\\(aao/\\\*\(o\'/g" \
		-e "s/\\\\z\\\(gaa/\\\*\(a\`/g" 
done > $RECIPES


# troff the stuff
# capture stderr output produced when troffing the files $RECIPES, 
# 	for processing by filters to give TOC and index
# import processed stuff into the files $CONTENTS and $INDEX;
#	this is done during the troff run, i.e., capture stuff during
#	troff run, then use it later within the same troff run
# NOTE: error information sent to stderr will be captured in $TOC
#	and not displayed unless grep it as below

echo " \
cat $COVER $TMAC $STARTREC $RECIPES $ENDREC $CONTENTS $INDEX |"
echo " \
sed -e filter-with-quotes |"
echo " \
eval $PREPROCESS $TROFF $METFLAG $TFLAG - 2>$TOC $POSTPROCESS $COOKBOOK"

cat $COVER $TMAC $STARTREC $RECIPES $STARTREC $CONTENTS $STARTREC $INDEX | 
sed -e '/^\.\\"/d' -e '/^\.ig/,/\.\./d' |
eval $PREPROCESS $TROFF $METFLAG $TFLAG - 2>$TOC $POSTPROCESS $COOKBOOK

if [ $? -gt 0 ]
then
	echo "formatting failed"; egrep -v '^\\|^- |^x ' $TOC
else
	echo "any errors?-- "; egrep -v '^\\|^- |^x ' $TOC
	echo $POSTPROCESS $COOKBOOK created 1>&2
fi

#
#DEBUG - REMOVE "exit" below to get debug files saved into working directory

# save the table of contents and index information for general use
cp -p $TOC Scr.toc

exit

# save the input to troff processing for debuging
cat $COVER $TMAC $STARTREC $RECIPES $ENDREC $CONTENTS $INDEX | 
sed -e '/^\.\\"/d' -e '/^\.ig/,/\.\./d' >Scr.troffinp
# and save other stuff for debuging
cp -p $INDEXFILTER Scr.idxfilt
cp -p $INDEXFILE Scr.idxfile
cp -p $TOCFILTER Scr.tocfilt
cp -p $TOCMOD Scr.tocmod

