[comp.sources.misc] v08i091: Literate Programming aid

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (10/04/89)

Posting-number: Volume 8, Issue 91
Submitted-by: bba@mtuxo.UUCP (Binayak Banerjee +1 201 957 2109)
Archive-name: lit

#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#
#	Run the following text with /bin/sh to create:
#	  README
#	  lit.1
#	  lit.sh
#
echo "x - extracting README (Text)"
sed 's/^X//' << 'SHAR_EOF' > README &&
XA Request
X---------
XThis  code  is  placed  in   the  public  domain.  The  following
Xcourtesies are requested:
X
Xa. Don't pretend you wrote it.
Xb. If you  modify it, identify your changes. I  want no credit or
X   blame for your code.
Xc. If you extend the functionality  of the code, please send me a
X   copy.
X
XBinayak Banerjee (Mon Oct  2 13:33:45 EDT 1989)
XBinayak_Banerjee@ATT.COM
X------------------------
X
XLit is  my apology  for a literate  programming device.  I really
Xwanted something  similar to cweb,  without having to pay  for it
Xout of  my own pocket. As  no one was  rushing to buy me  cweb, I
Xwrote Lit.
X
XAlthough it is very crude, it is much better than nothing. I have
Xused it for two rather substantial projects -- and it worked very
Xwell.
X
XIt  works best  when used  in an  environment with  the following
Xfacilities:
X
X	1. troff
X	2. vgrind
X	3. Nawk (new awk)
X
XIf  you don't  have these  -- don't  panic. It  will still  work,
Xthough not as nicely.
X
XINSTALLATION:
X
Xa.  Copy lit.sh to lit (or whatever name you wish to use)
X
Xb.  Edit the  definitions at  the top  of lit.sh  make sure  that
XTROFF, VGRIND, and  AWK point to the appropriate  places for you.
XAlso make  sure that TROFFARG  and VGRINDARG are  the appropriate
Xdefault options to troff and VGRIND.
X
XPORTING
X
XHere are some hints on adapting this to your environment:
X
Xa.  No troff
X
X	i.  Have nroff
X
X	Simple -- just set TROFF=nroff in lit.sh
X
X	ii. Some other markup language
X
X	Find  the comments  BEGIN CODE  and END  CODE in  lit.sh.
X	Change the  directives to something appropriate  for your
X	system. set TROFF=your-system as well.
X
Xb.  No vgrind
X
X	Set  VGRIND=/bin/cat. You  won't get  the nice  boldfaced
X	keywords,  but  it will  still  be  much nicer  than  raw
X	listings. You may  also wish to redefine vS and  vE as DS
X	and DE.
X
Xc.  No nawk.
X
X	Change  all occurrences  of  FNR in  lit.sh  to just  NR.
X	Change all  occurrences of FILENAME to  "input file". Set
X	awk  to  point  to  your  old awk.  You  will  lose  some
X	debugging info -- but no real functionality.
SHAR_EOF
chmod 0600 README || echo "restore of README fails"
echo "x - extracting lit.1 (Text)"
sed 's/^X//' << 'SHAR_EOF' > lit.1 &&
X.\" A Request
X.\" ---------
X.\" This  code  is  placed  in   the  public  domain.  The  following
X.\" courtesies are requested:
X.\" 
X.\" a. Don't pretend you wrote it.
X.\" b. If you  modify it, identify your changes. I  want no credit or
X.\"    blame for your code.
X.\" c. If you extend the functionality  of the code, please send me a
X.\"    copy.
X.\" 
X.\" Binayak Banerjee (Mon Oct  2 13:33:45 EDT 1989)
X.\" Binayak_Banerjee@ATT.COM
X.\" ------------------------
X.\" 
X.tr ~
X.TH LIT 1L "Unsupported"
X.UC 4
X.SH NAME
Xlit \- literate programming
X.SH SYNOPSIS
X.B "lit -v"
Xfile ...
X.br
X.B "lit -c"
X[
X.B \-l
X\fIlanguage\fP ] file ...
X.br
X.B "lit -t"
X[
X.B \-p
X\fIpass\fP] [
X.B \-T
X\fItroff-args\fP] [
X.B \-V
X\fIvgrind-args\fP
X] file ...
X.SH DESCRIPTION
X.I Lit
XTakes an input file in a format that interleaves text and code.  It outputs
Xeither the code or the text as requested.
X.PP
XThe
X.B \-v
Xoption checks the input file for correct syntax.  It reports
Xon unbalanced pairs of `.vS' and `.vE'.
X.PP
XThe
X.B \-c
Xoption copies the code into the specied files.  If the
X.B \-l
Xoption is given, then language specific processing is done.
XAt present, only \fB-l\fPC has an effect.  This option adds
X``\fB#line\fP'' directives to the generated code.
X.PP
XThe
X.B \-t
Xoption will process the input files in order to generate the
Xprinted textual representation of the input.  It preprocesses
Xthe input, and then filters it through
X\fIvgrind\fP and \fItroff\fP.  The
X.B \-p
Xoption controls the pipeline. E.g. -p~1 yields the
Xpreprocessed input, -p~2 yields the output of \fIvgrind(1),\fP and -p~3
X(The default) passes it through \fItroff(1)\fP as well.
XArguments to \fItroff\fP and \fIvgrind\fP can be supplied via
Xthe
X.B \-T
Xand the
X.B \-V
Xoptions.  Multipart arguments must be quoted,
XE.g.~\fB-T"-man~-o2-7".\fP  Notice that the leading dash is
Xretained.
X.SH "INPUT FORMAT"
XThe input format consists of \fItroff(1)\fP input.  Segments
Xof embedded code are marked off as follows:
X.sp
X.RS
X.nf
X\&.vS \fBfilename\fP
X\&\fI... Embedded code fragments.\fP
X\&.vE
X.RE
X.fi
X.sp
XThe code fragments between the \fB.vS\fP and \fB.vE\fP are copied
Xto specified file.  If \fBfilename\fP is not specified, the last
Xspecified \fBfilename\fP will be used.
X.SH "MAKING AN INDEX"
XThis facility is due to \fIvgrind,\fP rather than to \fIlit\fP.
XVgrind generates troff input that optionally yields an index
Xof functions.  One can also write a troff function that takes
Xadvantage of this:
X.sp
X.RS
X.nf
X\&.de IX
X\&.if \\\\nx .tm \\\\$1 \\n%
X\&..
X.RE
X.fi
X.sp
XAn item would be entered in the index by adding a line similar to
Xthe following one, anyplace in the text.
X.sp
X.RS
X\&.IX "\fIIndex Item\fP"
X.RE
X.sp
X.PP
XThe index is run off as follows:
X.sp
X.RS
X$ lit -t -T"-mm -rx1" > /dev/null 2> Index
X.br
X$ vgrind Index
X.RE
X.sp
X.SH "SEE ALSO"
Xweb(6), tangle(1), weave(1) from the \fBTeX\fP distribution.
X.br
Xvgrind(1), and troff(1).
X.SH "AUTHOR"
X.RS
XBinayak Banerjee
X.br
XAT&T Bell Labs
X.br
XMiddletown, NJ 07748
X.br
X\fIBinayak_Banerjee@ATT.COM\fP
X.RE
SHAR_EOF
chmod 0700 lit.1 || echo "restore of lit.1 fails"
echo "x - extracting lit.sh (Text)"
sed 's/^X//' << 'SHAR_EOF' > lit.sh &&
X#! /bin/sh
X# A Request
X# ---------
X# This  code  is  placed  in   the  public  domain.  The  following
X# courtesies are requested:
X# 
X# a. Don't pretend you wrote it.
X# b. If you  modify it, identify your changes. I  want no credit or
X#    blame for your code.
X# c. If you extend the functionality  of the code, please send me a
X#    copy.
X# 
X# Binayak Banerjee (Mon Oct  2 13:33:45 EDT 1989)
X# Binayak_Banerjee@ATT.COM
X# ------------------------
X
X
X# Modify these to suit.
X
XTROFF=/usr/bin/troff
XVGRIND=${HOME}/bin/vgrind
XAWK=$TOOLS/bin/nawk
X
X# Default values of arguments
X
XPASS=3			# Default for -p
XTROFFARG="-mm -Tpost"	# Default for -T
XVGRINDARG="-lc"		# Default for -V
X
X# Temp files
Xtmpawk=/tmp/lita$$
Xwhat=
X
X# Usage Info
X
XU1="-c [-l language] file ..."
XU2="-t [-T troff-args] [-V vgrind-args] [-p 1|2|3] file ..."
XU3="-v file ..."
XUSAGE="USAGE:\n\t$0 $U1\n\t$0 $U2\n\t$0 $U3"
X
Xtrap "rm -f $tmpawk" 0
X
Xif [ $# -lt 2 ]; then
X	echo "$USAGE"
X	exit 2
Xfi
X
Xif [ "$1" = "-c" ]; then
Xcat <<'Stinky' > $tmpawk
XBEGIN {
X	state = "ignore"
X}
X
X/^\.vS/ {
X	if ($2 == "") {
X		if (outfile == "") {
X			print "# Didn't supply filename"
X			printf("echo 'ERROR(%s,%d):No filename given' >&2\n",FILENAME,FNR)
X			outfile="/dev/null"
X			isseen["/dev/null"] = "yes"
X		}
X	} else outfile = $2
X
X	if (isseen[outfile] == "yes") {
X		print "# Appending to",outfile
X		printf "echo '*%s(%d)\\c'\n", FILENAME,NR
X		print "cat - << 'END-OF-INPUT' >>",outfile
X		if (lang ~ /^[cC]$/) {
X			printf "# line %d \"%s\"\n",FNR+1,FILENAME
X		}
X	} else {
X		isseen[outfile] = "yes"
X		print "# Dumping to",outfile
X		printf "echo '*%s(%d)\\c'\n", FILENAME,NR
X		print "cat - << 'END-OF-INPUT' >",outfile
X		if (lang ~ /^[cC]$/) {
X			printf "# line %d \"%s\"\n",FNR+1,FILENAME
X		}
X	}
X	state = "echo"
X	next
X}
X
X/^\.vE/ {
X	state = "ignore"
X	print "END-OF-INPUT"
X	next
X}
X
Xstate == "echo" {
X	print
X	next
X}
X
X{ next }
XEND { print "echo" }
XStinky
X	what="code"
Xelif [ "$1" = "-t" ]; then
Xcat <<'Stinky' > $tmpawk
X$1 == ".vS" {
X		# BEGIN CODE
X		print ".sp"
X		print ".nf"
X		print $0
X		next
X}
X$1 == ".vE" {
X		# END CODE
X		print $0
X		print ".sp"
X		print ".fi"
X		next
X}
X{ print $0 }
XStinky
X	what="text"
Xelif [ "$1" = "-v" ]; then
Xcat <<'Stinky' > $tmpawk
XBEGIN {
X	print "Verifying...."
X	stktop = 0;
X}
X/^\.vS/ {
X		file[++stktop] = FILENAME
X		linenum[stktop] = FNR
X}
X/^\.vE/ {
X		if (stktop <= 0) {
X			printf("vE with no vS in %s, line %d\n",FILENAME,FNR)
X			stktop = 0
X		} else {
X			stktop--
X		}
X}
X{ next }
XEND {
X	if (stktop > 0) {
X		print "vS without corresponding vE"
X		while (stktop > 0) {
X			print file[stktop],linenum[stktop]
X			stktop--
X		}
X	}
X}
XStinky
X	# This is easy enough to do here
X	shift
X	$AWK -f $tmpawk $*
X	exit
Xelse
X	echo "$USAGE"
X	exit 2
Xfi
X
X# DEBUGGING
X# cp $tmpawk AWK.TMP
X
X# Parse arguments
X
X# Getopt is dumb.  Do it by hand.
X# set -- `getopt "l:T:V:p:" $*`
X
X# if [ $? != 0 ]
X#	 then
X#	 echo $USAGE
X#	 exit 2
X# fi
X
Xshift
Xwhile [ -n "$1" ]; do
X	case $1 in
X	-l*)
X		LANG=`expr "$1" : '-l\(.*\)' `
X		if [ "$?" != 0 ]; then
X			LANG=$2; shift
X		fi
X		shift;;
X	-p*)
X		PASS=`expr "$1" : '-p\(.*\)' `
X		if [ "$?" != 0 ]; then
X			PASS=$2; shift
X		fi
X		shift;;
X	-T*)
X		TROFFARG=`expr "$1" : '-T\(.*\)' `
X		if [ "$?" != 0 ]; then
X			TROFFARG=$2; shift
X		fi
X		shift;;
X	-V*)
X		VGRINDARG=`expr "$1" : '-T\(.*\)' `
X		if [ "$?" != 0 ]; then
X			VGRINDARG=$2; shift
X		fi
X		shift;;
X	 -*)
X		echo "$USAGE"
X		exit 1;;
X	  *)
X		break;;
X	esac
Xdone
X
Xtroff="$TROFF $TROFFARG"
Xvgrind="$VGRIND -ft $VGRINDARG -"
X
X# Now handle case where text is desired.
X
Xif [ "$what" = "text" ]; then
X	case "$PASS" in
X		1) troff="/bin/cat";vgrind="/bin/cat";;
X		2) troff="/bin/cat";;
X		*) : ;;
X	esac
X
X	$AWK -f "$tmpawk" $* |
X			$vgrind |
X			$troff
X
Xelse
X	if [ "$LANG" ]; then
X		LANG="lang=$LANG"
X	fi
X
X	$AWK -f "$tmpawk" $LANG $* | /bin/sh
Xfi
X
Xexit 0
SHAR_EOF
chmod 0755 lit.sh || echo "restore of lit.sh fails"
exit 0