From 6ba17b6389bbe60d3bb74654a6889117abc83236 Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Fri, 15 Mar 2024 08:04:56 +0000 Subject: [PATCH] Initial import of nuweb-1.62 This is just the following tarball expanded: https://sourceforge.net/projects/nuweb/files/nuweb-1.62.tar.gz/download --- Makefile | 94 + README | 70 + arena.c | 50 + bibnames.sty | 11 + global.c | 56 + global.h | 158 + htdocs/index.html | 75 + html.c | 442 ++ html.sty | 1082 +++++ input.c | 155 + latex.c | 1086 +++++ litprog.bib | 1090 +++++ main.c | 211 + master.bib | 10010 ++++++++++++++++++++++++++++++++++++++++++++ misc.bib | 31 + names.c | 628 +++ nuweb.el | 809 ++++ nuweb.w | 6868 ++++++++++++++++++++++++++++++ nuwebdoc.tex | 822 ++++ nuwebsty.w | 92 + output.c | 101 + pass1.c | 234 ++ scraps.c | 1676 ++++++++ test/00/t0001a.sh | 113 + test/00/t0002a.sh | 119 + test/00/t0003a.sh | 122 + test/00/t0004a.sh | 179 + test/00/t0005a.sh | 224 + test/00/t0006a.sh | 119 + test/00/t0007a.sh | 192 + test/00/t0008a.sh | 179 + test/00/t0009a.sh | 145 + test/00/t0010a.sh | 135 + test/00/t0011a.sh | 97 + test/00/t0012a.sh | 204 + test/00/t0013a.sh | 158 + test/00/t0014a.sh | 125 + test/00/t0015a.sh | 152 + test/00/t0016a.sh | 259 ++ test/00/t0017a.sh | 318 ++ test/00/t0018a.sh | 150 + test/00/t0019a.sh | 158 + test/00/t0020a.sh | 126 + test/00/t0021a.sh | 126 + test/00/t0022a.sh | 111 + test/00/t0023a.sh | 110 + test/00/t0024a.sh | 397 ++ test/00/t0025a.sh | 426 ++ test/00/t0026a.sh | 118 + test/00/t0027a.sh | 127 + test/00/t0028a.sh | 157 + test/00/t0029a.sh | 301 ++ test/00/t0032a.sh | 194 + test/00/t0033a.sh | 257 ++ test/00/t0034a.sh | 195 + test/00/t0035a.sh | 150 + test/00/t0036a.sh | 129 + test/00/t0037a.sh | 119 + 58 files changed, 32042 insertions(+) create mode 100755 Makefile create mode 100755 README create mode 100644 arena.c create mode 100644 bibnames.sty create mode 100644 global.c create mode 100644 global.h create mode 100644 htdocs/index.html create mode 100644 html.c create mode 100644 html.sty create mode 100644 input.c create mode 100644 latex.c create mode 100644 litprog.bib create mode 100644 main.c create mode 100644 master.bib create mode 100644 misc.bib create mode 100644 names.c create mode 100644 nuweb.el create mode 100644 nuweb.w create mode 100644 nuwebdoc.tex create mode 100644 nuwebsty.w create mode 100644 output.c create mode 100644 pass1.c create mode 100644 scraps.c create mode 100644 test/00/t0001a.sh create mode 100644 test/00/t0002a.sh create mode 100644 test/00/t0003a.sh create mode 100644 test/00/t0004a.sh create mode 100644 test/00/t0005a.sh create mode 100644 test/00/t0006a.sh create mode 100644 test/00/t0007a.sh create mode 100644 test/00/t0008a.sh create mode 100644 test/00/t0009a.sh create mode 100644 test/00/t0010a.sh create mode 100644 test/00/t0011a.sh create mode 100644 test/00/t0012a.sh create mode 100644 test/00/t0013a.sh create mode 100644 test/00/t0014a.sh create mode 100644 test/00/t0015a.sh create mode 100644 test/00/t0016a.sh create mode 100644 test/00/t0017a.sh create mode 100644 test/00/t0018a.sh create mode 100644 test/00/t0019a.sh create mode 100644 test/00/t0020a.sh create mode 100644 test/00/t0021a.sh create mode 100644 test/00/t0022a.sh create mode 100644 test/00/t0023a.sh create mode 100644 test/00/t0024a.sh create mode 100644 test/00/t0025a.sh create mode 100644 test/00/t0026a.sh create mode 100644 test/00/t0027a.sh create mode 100644 test/00/t0028a.sh create mode 100644 test/00/t0029a.sh create mode 100644 test/00/t0032a.sh create mode 100644 test/00/t0033a.sh create mode 100644 test/00/t0034a.sh create mode 100644 test/00/t0035a.sh create mode 100644 test/00/t0036a.sh create mode 100644 test/00/t0037a.sh diff --git a/Makefile b/Makefile new file mode 100755 index 0000000..cfcfe80 --- /dev/null +++ b/Makefile @@ -0,0 +1,94 @@ +CC = cc + +CFLAGS = -g + +TARGET = nuweb +VERSION = 1.62 + +OBJS = main.o pass1.o latex.o html.o output.o input.o scraps.o names.o \ + arena.o global.o + +SRCS = main.c pass1.c latex.c html.c output.c input.c scraps.c names.c \ + arena.c global.c + +HDRS = global.h + +BIBS = litprog.bib master.bib misc.bib + +STYS = bibnames.sty html.sty + +DIST = Makefile README nuweb.w nuwebsty.w test htdocs nuweb.el \ + $(TARGET)doc.tex $(SRCS) $(HDRS) $(BIBS) $(STYS) + +%.tex: %.w + ./nuweb -r $< + latex $(basename $<) + ./nuweb -r $< + +%: %.tex + latex2html -split 0 $(basename $<) + +%.hw: %.w + cp $< $@ + +%.dvi: %.tex + latex $(basename $<) + bibtex $(basename $<) + latex $(basename $<) + latex $(basename $<) + +%.pdf: %.tex + pdflatex $(basename $<) + bibtex $(basename $<) + pdflatex $(basename $<) + pdflatex $(basename $<) + +all: + $(MAKE) $(TARGET).tex + $(MAKE) $(TARGET) + +tar: $(TARGET)doc.tex + mkdir $(TARGET)-$(VERSION) + cp -R $(DIST) $(TARGET)-$(VERSION) + tar -zcf $(TARGET)-$(VERSION).tar.gz $(TARGET)-$(VERSION) + rm -rf $(TARGET)-$(VERSION) + +distribution: all tar nuweb.pdf nuwebdoc.pdf + +$(TARGET)doc.tex: $(TARGET).tex + sed -e '/^\\ifshowcode$$/,/^\\fi$$/d' $< > $@ + +check: nuweb + @declare -i n=0; \ + declare -i f=0; \ + for i in test/*/*.sh ; do \ + echo "Testing $$i"; \ + sh $$i; \ + if test $$? -ne 0; \ + then echo " $$i failed" ; \ + f+=1; \ + fi; \ + n+=1; \ + done; \ + echo "$$n done"; \ + echo "$$f failed" + +clean: + -rm -f *.o *.tex *.log *.dvi *.pdf *~ *.blg *.lint *.bbl *.aux *.brf *.out *.toc + +veryclean: clean + -rm -f *.c *.h + +view: $(TARGET).dvi + xdvi $(TARGET).dvi + +print: $(TARGET).dvi + lpr -d $(TARGET).dvi + +lint: + lint $(SRCS) > nuweb.lint + +$(OBJS): global.h + +$(TARGET): $(OBJS) + $(CC) -o $(TARGET) $(OBJS) diff --git a/README b/README new file mode 100755 index 0000000..272fc1a --- /dev/null +++ b/README @@ -0,0 +1,70 @@ +We've bundled up the web source (nuweb.w), the generated .c files and +the assorted auxiliary files for latex'ing with a Makefile. + +Note that it's still not completely portable to every system without +change. In particular, it expects file-names to use '/' to delimit +directories which is OK unless you are on Windows (where it's '\') or +VMS (which uses ':' and ']') and it thinks tab stops are set every +eight spaces. + +To print the documentation, you must first run LaTeX on the file +nuwebdoc.tex. To fix up all the citations, you'll need several runs. + + latex nuwebdoc + bibtex nuwebdoc + latex nuwebdoc + latex nuwebdoc + +Note that the distributed nuwebdoc.tex is basically Chapter 1 of the +complete nuweb.tex generated by running nuweb against itself. + +To actually build the nuweb executable, type "make nuweb" which should +build an executable file called "nuweb". After that, you should be +able to use the makefile to control everything very nicely. + +To view the nuweb sources using an HTML viewer, copy nuweb.w to +nuweb.hw, and then add the html document-style option to nuweb.hw. +After producing the LaTeX source file nuweb.tex, convert it to HTML +using LaTeX2HTML. + +For the latest version check the SourceForge page: + http://nuweb.sourceforge.net/ + +Changes in Version 1.62: +Worked round issue with large number of scraps, cause obscure; +see bug #29. + +Changes in Version 1.61: +Moved versioning system to git. +Corrected link failure with latest GCC, and clang on some systems. + +Changes in Version 1.60: +Made version number consistent between nuweb.w and tag. +Corrected link to Z in htdocs/index.html. +Makefile runs bibtex pass when creating .dvi, .pdf. +master.bib no longer calls up nonexistent file. + +Changes in Version 1.59: +Fixed compiler warnings in both gcc and clang. + +Changes in Version 1.58: +Suppress indentation for one fragment or argument +Allow fragment expansion in tex. + +Changes in Version 1.57: +Fixed SF3416213, \it deprecated in LaTeX2e, use \itshape +Fixed SF3431294, Fragment page number refs don't work in memoir class +Fixed SF3432035, -d output file flag doesn't work +Removed use of hyperref parameter dvipdfm (-> error in TeX Live 2011) + +Changes in Version 1.56: +Added minor command @t to include fragment title in output files. +Fragment use embedded in fragment argument is no longer commented. +Make tar now produces top level versioned directory. + +Changes in Version 1.55: +Fixed bug 3168635 (doesn't handle inability to create output files). + +Changes in Version 1.54: +Fixed bug 3158592 (SEGV) by reworking sentinel-based scrap processing. +Fixed bug 3160408 by defining MAX_NAME_LEN (to 1024) in global.h. diff --git a/arena.c b/arena.c new file mode 100644 index 0000000..13c46ad --- /dev/null +++ b/arena.c @@ -0,0 +1,50 @@ +#include "global.h" +typedef struct chunk { + struct chunk *next; + char *limit; + char *avail; +} Chunk; +static Chunk first = { NULL, NULL, NULL }; +static Chunk *arena = &first; +void *arena_getmem(n) + size_t n; +{ + char *q; + char *p = arena->avail; + n = (n + 7) & ~7; /* ensuring alignment to 8 bytes */ + q = p + n; + if (q <= arena->limit) { + arena->avail = q; + return p; + } + /* Find a new chunk of memory */ + { + Chunk *ap = arena; + Chunk *np = ap->next; + while (np) { + char *v = sizeof(Chunk) + (char *) np; + if (v + n <= np->limit) { + np->avail = v + n; + arena = np; + return v; + } + ap = np; + np = ap->next; + } + /* Allocate a new chunk of memory */ + { + size_t m = n + 10000; + np = (Chunk *) malloc(m); + np->limit = m + (char *) np; + np->avail = n + sizeof(Chunk) + (char *) np; + np->next = NULL; + ap->next = np; + arena = np; + return sizeof(Chunk) + (char *) np; + } + } +} +void arena_free() +{ + arena = &first; +} diff --git a/bibnames.sty b/bibnames.sty new file mode 100644 index 0000000..bb9b429 --- /dev/null +++ b/bibnames.sty @@ -0,0 +1,11 @@ +% +% These don't seem to get defined anywhere else, so... +% + +\def\noopsort#1{#1} +\def\emdash{\-} + +\def\tex#1{$T_{E}X$} +\def\WEB#1{WEB} +\def\mf#1{\sc metafont} +\def\TUB#1{TUB} diff --git a/global.c b/global.c new file mode 100644 index 0000000..54db28a --- /dev/null +++ b/global.c @@ -0,0 +1,56 @@ +#include "global.h" +/* Operating System Dependencies */ + +#if defined(VMS) +#define PATH_SEP(c) (c==']'||c==':') +#define PATH_SEP_CHAR "" +#define DEFAULT_PATH "" +#elif defined(MSDOS) +#define PATH_SEP(c) (c=='\\') +#define PATH_SEP_CHAR "\\" +#define DEFAULT_PATH "." +#else +#define PATH_SEP(c) (c=='/') +#define PATH_SEP_CHAR "/" +#define DEFAULT_PATH "." +#endif + +/* Global variable definitions */ +int tex_flag = TRUE; +int html_flag = FALSE; +int output_flag = TRUE; +int compare_flag = TRUE; +int verbose_flag = FALSE; +int number_flag = FALSE; +int scrap_flag = TRUE; +int dangling_flag = FALSE; +int xref_flag = FALSE; +int prepend_flag = FALSE; +char * dirpath = DEFAULT_PATH; /* Default directory path */ +char * path_sep = PATH_SEP_CHAR; +int listings_flag = FALSE; +int version_info_flag = FALSE; +char default_version_string[] = "no version"; +char * version_string = default_version_string; +int hyperref_flag = FALSE; +int hyperopt_flag = FALSE; +char * hyperoptions = ""; +int includepath_flag = FALSE; /* Do we have an include path? */ +struct incl * include_list = NULL; + /* The list of include paths */ +int nw_char='@'; +char *command_name = NULL; +unsigned char current_sector = 1; +unsigned char prev_sector = 1; +char blockBuff[6400]; +int extra_scraps = 0; + char *source_name = NULL; +int source_line = 0; +int already_warned = 0; +Name *file_names = NULL; +Name *macro_names = NULL; +Name *user_names = NULL; +int scrap_name_has_parameters; +int scrap_ended_with; + +label_node * label_tab = NULL; diff --git a/global.h b/global.h new file mode 100644 index 0000000..69608a5 --- /dev/null +++ b/global.h @@ -0,0 +1,158 @@ +/* Include files */ + +#include +#include +#include +#include +#include +#include + +/* Type declarations */ +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#define MAX_INDENT 500 +typedef struct scrap_node { + struct scrap_node *next; + int scrap; + char quoted; +} Scrap_Node; +typedef struct name { + char *spelling; + struct name *llink; + struct name *rlink; + Scrap_Node *defs; + Scrap_Node *uses; + char * arg[9]; + int mark; + char tab_flag; + char indent_flag; + char debug_flag; + unsigned char comment_flag; + unsigned char sector; +} Name; +#define ARG_CHR '\001' +typedef struct arglist +{Name * name; +struct arglist * args; +struct arglist * next; +} Arglist; +typedef struct embed { + Scrap_Node * defs; + Arglist * args; +} Embed_Node; +typedef struct uses { + struct uses *next; + Name *defn; +} Uses; +typedef struct l_node +{ + struct l_node * left, * right; + int scrap, seq; + char name[1]; +} label_node; + +/* Limits */ + +#ifndef MAX_NAME_LEN +#define MAX_NAME_LEN 1024 +#endif + +/* Global variable declarations */ +extern int tex_flag; /* if FALSE, don't emit the documentation file */ +extern int html_flag; /* if TRUE, emit HTML instead of LaTeX scraps. */ +extern int output_flag; /* if FALSE, don't emit the output files */ +extern int compare_flag; /* if FALSE, overwrite without comparison */ +extern int verbose_flag; /* if TRUE, write progress information */ +extern int number_flag; /* if TRUE, use a sequential numbering scheme */ +extern int scrap_flag; /* if FALSE, don't print list of scraps */ +extern int dangling_flag; /* if FALSE, don't print dangling identifiers */ +extern int xref_flag; /* If TRUE, print cross-references in scrap comments */ +extern int prepend_flag; /* If TRUE, prepend a path to the output file names */ +extern char * dirpath; /* The prepended directory path */ +extern char * path_sep; /* How to join path to filename */ +extern int listings_flag; /* if TRUE, use listings package for scrap formatting */ +extern int version_info_flag; /* If TRUE, set up version string */ +extern char * version_string; /* What to print for @v */ +extern int hyperref_flag; /* Are we preparing for hyperref + package. */ +extern int hyperopt_flag; /* Are we preparing for hyperref options */ +extern char * hyperoptions; /* The options to pass to the + hyperref package */ +extern int includepath_flag; /* Do we have an include path? */ +extern struct incl{char * name; struct incl * next;} * include_list; + /* The list of include paths */ +extern int nw_char; +extern char *command_name; +extern unsigned char current_sector; +extern unsigned char prev_sector; +extern char blockBuff[6400]; +extern int extra_scraps; +extern char *source_name; /* name of the current file */ +extern int source_line; /* current line in the source file */ +extern int already_warned; +extern Name *file_names; +extern Name *macro_names; +extern Name *user_names; +extern int scrap_name_has_parameters; +extern int scrap_ended_with; +extern label_node * label_tab; + +/* Function prototypes */ +extern void pass1(); +extern void write_tex(); +void initialise_delimit_scrap_array(void); +void update_delimit_scrap(); +extern int has_sector(Name *, unsigned char); +extern void write_html(); +extern void write_files(); +extern void source_open(); /* pass in the name of the source file */ +extern int source_get(); /* no args; returns the next char or EOF */ +extern int source_last; /* what last source_get() returned. */ +extern int source_peek; /* The next character to get */ +extern void source_ungetc(int*); +extern void init_scraps(); +extern int collect_scrap(); +extern int write_scraps(); +extern void write_scrap_ref(); +extern void write_single_scrap_ref(); +extern int num_scraps(); +extern void add_to_use(Name * name, int current_scrap); +Arglist * instance(); +extern void collect_numbers(); +extern Name *collect_file_name(); +extern Name *collect_macro_name(); +extern Arglist *collect_scrap_name(); +extern Name *name_add(); +extern Name *prefix_add(); +extern char *save_string(); +extern void reverse_lists(); +extern int robs_strcmp(char*, char*); +extern Name *install_args(); +extern void search(); +extern void format_uses_refs(FILE *, int); +extern void format_defs_refs(FILE *, int); +void write_label(char label_name[], FILE * file); +extern void *arena_getmem(); +extern void arena_free(); + +/* Operating System Dependencies */ + +#if defined(VMS) +#define PATH_SEP(c) (c==']'||c==':') +#define PATH_SEP_CHAR "" +#define DEFAULT_PATH "" +#elif defined(MSDOS) +#define PATH_SEP(c) (c=='\\') +#define PATH_SEP_CHAR "\\" +#define DEFAULT_PATH "." +#else +#define PATH_SEP(c) (c=='/') +#define PATH_SEP_CHAR "/" +#define DEFAULT_PATH "." +#endif +typedef int *Parameters; diff --git a/htdocs/index.html b/htdocs/index.html new file mode 100644 index 0000000..f1c6295 --- /dev/null +++ b/htdocs/index.html @@ -0,0 +1,75 @@ + + +The nuweb system for Literate Programming + + +

The nuweb system for Literate Programming

+ + + + +
+ SourceForge Logo + +project + +bug-tracker + +mailing-lists +
+ +

History

+ +The nuweb system for Literate Programming was initially +developed several years ago by Preston Briggs, and was later +extended as part of Marc Mengel's Master's Thesis to help work with both +specifications in Z +(in effect, LaTeX source in a LaTeX/nuweb document) and the code that +implements the specification in a common document. + +

+At that time Preston wasn't interested in making new nuweb +releases, so Marc took over maintenance of it, with his permission. + +

+Keith added new-style fragment parameters and a set of tests. + +

+At present, Simon Wright is the only maintainer. + +

Downloads

+ +Folks interested in starting to use nuweb should download + +the latest tar archive with sources already unpacked from +the nuweb.w file, a Makefile, etc. + +

+Those who already have nuweb running can simply download +the latest tar +archive , or checkout the module from +the GIT +Repository. + +

Browsing

+ +You can browse the nuweb +source/document [PDF, about 2 MB] , or just +the User's Guide [PDF] portion. + +

Feedback

+ +Please post bug reports at the +Sourceforge Bugs +tracker, and feature requests at +the Feature +Requests tracker. + +Send comments, questions, etc to +the nuweb-users +mailing list. + + + diff --git a/html.c b/html.c new file mode 100644 index 0000000..dcd35ed --- /dev/null +++ b/html.c @@ -0,0 +1,442 @@ +#include "global.h" +static int scraps = 1; +static void copy_scrap(); /* formats the body of a scrap */ +static void display_scrap_ref(); /* formats a scrap reference */ +static void display_scrap_numbers(); /* formats a list of scrap numbers */ +static void print_scrap_numbers(); /* pluralizes scrap formats list */ +static void format_entry(); /* formats an index entry */ +static void format_user_entry(); +void write_html(file_name, html_name) + char *file_name; + char *html_name; +{ + FILE *html_file = fopen(html_name, "w"); + FILE *tex_file = html_file; + if (hyperref_flag) { + fputs("\\newcommand{\\NWtarget}[2]{\\hypertarget{#1}{#2}}\n", tex_file); + fputs("\\newcommand{\\NWlink}[2]{\\hyperlink{#1}{#2}}\n", tex_file); + } else { + fputs("\\newcommand{\\NWtarget}[2]{#2}\n", tex_file); + fputs("\\newcommand{\\NWlink}[2]{#2}\n", tex_file); + } + fputs("\\newcommand{\\NWtxtMacroDefBy}{Fragment defined by}\n", tex_file); + fputs("\\newcommand{\\NWtxtMacroRefIn}{Fragment referenced in}\n", tex_file); + fputs("\\newcommand{\\NWtxtMacroNoRef}{Fragment never referenced}\n", tex_file); + fputs("\\newcommand{\\NWtxtDefBy}{Defined by}\n", tex_file); + fputs("\\newcommand{\\NWtxtRefIn}{Referenced in}\n", tex_file); + fputs("\\newcommand{\\NWtxtNoRef}{Not referenced}\n", tex_file); + fputs("\\newcommand{\\NWtxtFileDefBy}{File defined by}\n", tex_file); + fputs("\\newcommand{\\NWtxtIdentsUsed}{Uses:}\n", tex_file); + fputs("\\newcommand{\\NWtxtIdentsNotUsed}{Never used}\n", tex_file); + fputs("\\newcommand{\\NWtxtIdentsDefed}{Defines:}\n", tex_file); + fputs("\\newcommand{\\NWsep}{${\\diamond}$}\n", tex_file); + fputs("\\newcommand{\\NWnotglobal}{(not defined globally)}\n", tex_file); + fputs("\\newcommand{\\NWuseHyperlinks}{", tex_file); + if (hyperoptions[0] != '\0') + { + fprintf(tex_file, "\\usepackage[%s]{hyperref}", hyperoptions); + } + fputs("}\n", tex_file); + + if (html_file) { + if (verbose_flag) + fprintf(stderr, "writing %s\n", html_name); + source_open(file_name); + { + int c = source_get(); + while (c != EOF) { + if (c == nw_char) + { + c = source_get(); + switch (c) { + case 'r': + c = source_get(); + nw_char = c; + update_delimit_scrap(); + break; + case 'O': + case 'o': { + Name *name = collect_file_name(); + { + fputs("\\begin{rawhtml}\n", html_file); + fputs("
\n", html_file);
+                          }
+                            fputs("\"%s\" ", name->spelling);
+                            write_single_scrap_ref(html_file, scraps);
+                            fputs(" =\n", html_file);
+                          
+                          scraps++;
+                          {
+                            copy_scrap(html_file, TRUE);
+                            fputs("<>
\n", html_file); + } + { + if (name->defs->next) { + fputs("\\end{rawhtml}\\NWtxtFileDefBy\\begin{rawhtml} ", html_file); + print_scrap_numbers(html_file, name->defs); + fputs("
\n", html_file); + } + } + { + fputs("\\end{rawhtml}\n", html_file); + c = source_get(); /* Get rid of current at command. */ + } + } + break; + case 'Q': + case 'q': + case 'D': + case 'd': { + Name *name = collect_macro_name(); + { + fputs("\\begin{rawhtml}\n", html_file); + fputs("
\n", html_file);
+                          }
+                            fputs("<\\end{rawhtml}", html_file);
+                            fputs(name->spelling, html_file);
+                            fputs("\\begin{rawhtml} ", html_file);
+                            write_single_scrap_ref(html_file, scraps);
+                            fputs("> =\n", html_file);
+                          
+                          scraps++;
+                          {
+                            copy_scrap(html_file, TRUE);
+                            fputs("<>
\n", html_file); + } + { + if (name->defs->next) { + fputs("\\end{rawhtml}\\NWtxtMacroDefBy\\begin{rawhtml} ", html_file); + print_scrap_numbers(html_file, name->defs); + fputs("
\n", html_file); + } + } + { + if (name->uses) { + fputs("\\end{rawhtml}\\NWtxtMacroRefIn\\begin{rawhtml} ", html_file); + print_scrap_numbers(html_file, name->uses); + } + else { + fputs("\\end{rawhtml}{\\NWtxtMacroNoRef}.\\begin{rawhtml}", html_file); + fprintf(stderr, "%s: <%s> never referenced.\n", + command_name, name->spelling); + } + fputs("
\n", html_file); + } + { + fputs("\\end{rawhtml}\n", html_file); + c = source_get(); /* Get rid of current at command. */ + } + } + break; + case 'f': { + if (file_names) { + fputs("\\begin{rawhtml}\n", html_file); + fputs("
\n", html_file); + format_entry(file_names, html_file, TRUE); + fputs("
\n", html_file); + fputs("\\end{rawhtml}\n", html_file); + } + c = source_get(); + } + break; + case 'm': { + if (macro_names) { + fputs("\\begin{rawhtml}\n", html_file); + fputs("
\n", html_file); + format_entry(macro_names, html_file, FALSE); + fputs("
\n", html_file); + fputs("\\end{rawhtml}\n", html_file); + } + c = source_get(); + } + break; + case 'u': { + if (user_names) { + fputs("\\begin{rawhtml}\n", html_file); + fputs("
\n", html_file); + format_user_entry(user_names, html_file, 0/* Dummy */); + fputs("
\n", html_file); + fputs("\\end{rawhtml}\n", html_file); + } + c = source_get(); + } + break; + default: + if (c==nw_char) + putc(c, html_file); + c = source_get(); + break; + } + } + else { + putc(c, html_file); + c = source_get(); + } + } + } + fclose(html_file); + } + else + fprintf(stderr, "%s: can't open %s\n", command_name, html_name); +} +static void display_scrap_ref(html_file, num) + FILE *html_file; + int num; +{ + fputs("", html_file); + write_single_scrap_ref(html_file, num); + fputs("", html_file); +} +static void display_scrap_numbers(html_file, scraps) + FILE *html_file; + Scrap_Node *scraps; +{ + display_scrap_ref(html_file, scraps->scrap); + scraps = scraps->next; + while (scraps) { + fputs(", ", html_file); + display_scrap_ref(html_file, scraps->scrap); + scraps = scraps->next; + } +} +static void print_scrap_numbers(html_file, scraps) + FILE *html_file; + Scrap_Node *scraps; +{ + display_scrap_numbers(html_file, scraps); + fputs(".\n", html_file); +} +static void copy_scrap(file, prefix) + FILE *file; + int prefix; +{ + int indent = 0; + int c = source_get(); + while (1) { + switch (c) { + case '<' : fputs("<", file); + indent++; + break; + case '>' : fputs(">", file); + indent++; + break; + case '&' : fputs("&", file); + indent++; + break; + case '\n': fputc(c, file); + indent = 0; + break; + case '\t': { + int delta = 8 - (indent % 8); + indent += delta; + while (delta > 0) { + putc(' ', file); + delta--; + } + } + break; + default: + if (c==nw_char) + { + { + c = source_get(); + switch (c) { + case '+': + case '-': + case '*': + case '|': { + do { + do + c = source_get(); + while (c != nw_char); + c = source_get(); + } while (c != '}' && c != ']' && c != ')' ); + } + case ',': + case '}': + case ']': + case ')': return; + case '_': { + static int toggle; + toggle = ~toggle; + if( toggle ) { + fputs( "", file ); + } else { + fputs( "", file ); + } + } + break; + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + fputc(nw_char, file); + fputc(c, file); + break; + case '<': { + Arglist * args = collect_scrap_name(-1); + Name *name = args->name; + fputs("<\\end{rawhtml}", file); + fputs(name->spelling, file); + if (scrap_name_has_parameters) { + + char sep; + + sep = '('; + fputs("\\begin{rawhtml}", file); + do { + + fputc(sep,file); + + fprintf(file, "%d ", scraps, scraps); + + source_last = '{'; + copy_scrap(file, TRUE); + + ++scraps; + sep = ','; + + } while ( source_last != ')' && source_last != EOF ); + fputs(" ) ",file); + do + c = source_get(); + while(c != nw_char && c != EOF); + if (c == nw_char) { + c = source_get(); + } + fputs("\\end{rawhtml}", file); + + } + fputs("\\begin{rawhtml} ", file); + if (name->defs) + { + Scrap_Node *p = name->defs; + display_scrap_ref(file, p->scrap); + if (p->next) + fputs(", ... ", file); + } + else { + putc('?', file); + fprintf(stderr, "%s: never defined <%s>\n", + command_name, name->spelling); + } + fputs(">", file); + } + break; + case '%': { + do + c = source_get(); + while (c != '\n'); + } + break; + default: + if (c==nw_char) + { + fputc(c, file); + break; + } + /* ignore these since pass1 will have warned about them */ + break; + } + } + break; + } + putc(c, file); + indent++; + break; + } + c = source_get(); + } +} +static void format_entry(name, html_file, file_flag) + Name *name; + FILE *html_file; + int file_flag; +{ + while (name) { + format_entry(name->llink, html_file, file_flag); + { + fputs("
", html_file); + if (file_flag) { + fprintf(html_file, "\"%s\"\n
", name->spelling); + { + fputs("\\end{rawhtml}\\NWtxtDefBy\\begin{rawhtml} ", html_file); + print_scrap_numbers(html_file, name->defs); + } + } + else { + fputs("<\\end{rawhtml}", html_file); + fputs(name->spelling, html_file); + fputs("\\begin{rawhtml} ", html_file); + { + if (name->defs) + display_scrap_numbers(html_file, name->defs); + else + putc('?', html_file); + } + fputs(">\n
", html_file); + { + Scrap_Node *p = name->uses; + if (p) { + fputs("\\end{rawhtml}\\NWtxtRefIn\\begin{rawhtml} ", html_file); + print_scrap_numbers(html_file, p); + } + else + fputs("\\end{rawhtml}{\\NWtxtNoRef}.\\begin{rawhtml}", html_file); + } + } + putc('\n', html_file); + } + name = name->rlink; + } +} +static void format_user_entry(name, html_file, sector) + Name *name; + FILE *html_file; + int sector; +{ + while (name) { + format_user_entry(name->llink, html_file, sector); + { + Scrap_Node *uses = name->uses; + if (uses) { + Scrap_Node *defs = name->defs; + fprintf(html_file, "
%s:\n
", name->spelling); + if (uses->scrap < defs->scrap) { + display_scrap_ref(html_file, uses->scrap); + uses = uses->next; + } + else { + if (defs->scrap == uses->scrap) + uses = uses->next; + fputs("", html_file); + display_scrap_ref(html_file, defs->scrap); + fputs("", html_file); + defs = defs->next; + } + while (uses || defs) { + fputs(", ", html_file); + if (uses && (!defs || uses->scrap < defs->scrap)) { + display_scrap_ref(html_file, uses->scrap); + uses = uses->next; + } + else { + if (uses && defs->scrap == uses->scrap) + uses = uses->next; + fputs("", html_file); + display_scrap_ref(html_file, defs->scrap); + fputs("", html_file); + defs = defs->next; + } + } + fputs(".\n", html_file); + } + } + name = name->rlink; + } +} diff --git a/html.sty b/html.sty new file mode 100644 index 0000000..e5323e9 --- /dev/null +++ b/html.sty @@ -0,0 +1,1082 @@ +% +% $Id: html.sty,v 1.2 2010-03-11 21:53:56 simonjwright Exp $ +% LaTeX2HTML Version 99.1 : html.sty +% +% This file contains definitions of LaTeX commands which are +% processed in a special way by the translator. +% For example, there are commands for embedding external hypertext links, +% for cross-references between documents or for including raw HTML. +% This file includes the comments.sty file v2.0 by Victor Eijkhout +% In most cases these commands do nothing when processed by LaTeX. +% +% Place this file in a directory accessible to LaTeX (i.e., somewhere +% in the TEXINPUTS path.) +% +% NOTE: This file works with LaTeX 2.09 or (the newer) LaTeX2e. +% If you only have LaTeX 2.09, some complex LaTeX2HTML features +% like support for segmented documents are not available. + +% Changes: +% See the change log at end of file. + + +% Exit if the style file is already loaded +% (suggested by Lee Shombert +\ifx \htmlstyloaded\relax \endinput\else\let\htmlstyloaded\relax\fi +\makeatletter + +% protect against the hyperref package being loaded already + +\ifx\undefined\hyperref + \let\html@new=\newcommand +\else + \let\html@new=\renewcommand +\fi + +\providecommand{\latextohtml}{\LaTeX2\texttt{HTML}} + +%%% LINKS TO EXTERNAL DOCUMENTS +% +% This can be used to provide links to arbitrary documents. +% The first argumment should be the text that is going to be +% highlighted and the second argument a URL. +% The hyperlink will appear as a hyperlink in the HTML +% document and as a footnote in the dvi or ps files. +% +\html@new{\htmladdnormallinkfoot}[2]{#1\footnote{#2}} + + +% This is an alternative definition of the command above which +% will ignore the URL in the dvi or ps files. +\html@new{\htmladdnormallink}[2]{#1} + + +% This command takes as argument a URL pointing to an image. +% The image will be embedded in the HTML document but will +% be ignored in the dvi and ps files. +% +\html@new{\htmladdimg}[1]{} + + +%%% CROSS-REFERENCES BETWEEN (LOCAL OR REMOTE) DOCUMENTS +% +% This can be used to refer to symbolic labels in other Latex +% documents that have already been processed by the translator. +% The arguments should be: +% #1 : the URL to the directory containing the external document +% #2 : the path to the labels.pl file of the external document. +% If the external document lives on a remote machine then labels.pl +% must be copied on the local machine. +% +%e.g. \externallabels{http://cbl.leeds.ac.uk/nikos/WWW/doc/tex2html/latex2html} +% {/usr/cblelca/nikos/tmp/labels.pl} +% The arguments are ignored in the dvi and ps files. +% +\newcommand{\externallabels}[2]{} + + +% This complements the \externallabels command above. The argument +% should be a label defined in another latex document and will be +% ignored in the dvi and ps files. +% +\newcommand{\externalref}[1]{} + + +% Suggested by Uffe Engberg (http://www.brics.dk/~engberg/) +% This allows the same effect for citations in external bibliographies. +% An \externallabels command must be given, locating a labels.pl file +% which defines the location and keys used in the external .html file. +% +\newcommand{\externalcite}{\nocite} + +% This allows a section-heading in the TOC or mini-TOC to be just +% a hyperlink to an external document. +% +% \htmladdTOClink[]{}{}{<URL>} +% where <section-level> is 'chapter' , 'section' , 'subsection' etc. +% and <path_to_labels> is the path to find a labels.pl file, +% so that external cross-referencing may work, as with \externallabels +% +\newcommand{\htmladdTOClink}[4][]{} + + +%%% HTMLRULE +% This command adds a horizontal rule and is valid even within +% a figure caption. +% Here we introduce a stub for compatibility. +\newcommand{\htmlrule}{\protect\HTMLrule} +\newcommand{\HTMLrule}{\@ifstar\htmlrulestar\htmlrulestar} +\newcommand{\htmlrulestar}[1]{} + +%%% HTMLCLEAR +% This command puts in a <BR> tag, with CLEAR="ALL" +\newcommand{\htmlclear}{} + +% This command adds information within the <BODY> ... </BODY> tag +% +\newcommand{\bodytext}[1]{} +\newcommand{\htmlbody}{} + + +%%% HYPERREF +% Suggested by Eric M. Carol <eric@ca.utoronto.utcc.enfm> +% Similar to \ref but accepts conditional text. +% The first argument is HTML text which will become ``hyperized'' +% (underlined). +% The second and third arguments are text which will appear only in the paper +% version (DVI file), enclosing the fourth argument which is a reference to a label. +% +%e.g. \hyperref{using the tracer}{using the tracer (see Section}{)}{trace} +% where there is a corresponding \label{trace} +% +% avoid possible confict with hyperref package +\ifx\undefined\hyperref + \newcommand{\hyperrefhyper}[4]{#4}% + \def\next{\newcommand}% +\else + \let\hyperrefhyper\hyperref + \def\next{\renewcommand}% +\fi +\next{\hyperref}{\hyperrefi[]}\let\next=\relax + +\def\hyperrefi[#1]{{\def\next{#1}\def\tmp{}% + \ifx\next\tmp\aftergroup\hyperrefdef + \else\def\tmp{ref}\ifx\next\tmp\aftergroup\hyperrefref + \else\def\tmp{pageref}\ifx\next\tmp\aftergroup\hyperrefpageref + \else\def\tmp{page}\ifx\next\tmp\aftergroup\hyperrefpage + \else\def\tmp{noref}\ifx\next\tmp\aftergroup\hyperrefnoref + \else\def\tmp{no}\ifx\next\tmp\aftergroup\hyperrefno + \else\def\tmp{hyper}\ifx\next\tmp\aftergroup\hyperrefhyper + \else\def\tmp{html}\ifx\next\tmp\aftergroup\hyperrefhtml + \else\typeout{*** unknown option \next\space to hyperref ***}% + \fi\fi\fi\fi\fi\fi\fi\fi}} +\newcommand{\hyperrefdef}[4]{#2\ref{#4}#3} +\newcommand{\hyperrefpageref}[4]{#2\pageref{#4}#3} +\newcommand{\hyperrefnoref}[3]{#2} +\let\hyperrefref=\hyperrefdef +\let\hyperrefpage=\hyperrefpageref +\let\hyperrefno=\hyperrefnoref +\ifx\undefined\hyperrefhyper\newcommand{\hyperrefhyper}[4]{#4}\fi +\let\hyperrefhtml=\hyperrefdef + +%%% HYPERCITE --- added by RRM +% Suggested by Stephen Simpson <simpson@math.psu.edu> +% effects the same ideas as in \hyperref, but for citations. +% It does not allow an optional argument to the \cite, in LaTeX. +% +% \hypercite{<html-text>}{<LaTeX-text>}{<opt-text>}{<key>} +% +% uses the pre/post-texts in LaTeX, with a \cite{<key>} +% +% \hypercite[ext]{<html-text>}{<LaTeX-text>}{<key>} +% \hypercite[ext]{<html-text>}{<LaTeX-text>}[<prefix>]{<key>} +% +% uses the pre/post-texts in LaTeX, with a \nocite{<key>} +% the actual reference comes from an \externallabels file. +% +\newcommand{\hypercite}{\hypercitei[]} +\def\hypercitei[#1]{{\def\next{#1}\def\tmp{}% + \ifx\next\tmp\aftergroup\hypercitedef + \else\def\tmp{int}\ifx\next\tmp\aftergroup\hyperciteint + \else\def\tmp{cite}\ifx\next\tmp\aftergroup\hypercitecite + \else\def\tmp{ext}\ifx\next\tmp\aftergroup\hyperciteext + \else\def\tmp{nocite}\ifx\next\tmp\aftergroup\hypercitenocite + \else\def\tmp{no}\ifx\next\tmp\aftergroup\hyperciteno + \else\typeout{*** unknown option \next\space to hypercite ***}% + \fi\fi\fi\fi\fi\fi}} +\newcommand{\hypercitedef}[4]{#2{\def\tmp{#3}\def\emptyopt{}% + \ifx\tmp\emptyopt\cite{#4}\else\cite[#3]{#4}\fi}} +\newcommand{\hypercitenocite}[2]{#2\hypercitenocitex[]} +\def\hypercitenocitex[#1]#2{\nocite{#2}} +\let\hypercitecite=\hypercitedef +\let\hyperciteint=\hypercitedef +\let\hyperciteext=\hypercitenocite +\let\hyperciteno=\hypercitenocite + +%%% HTMLREF +% Reference in HTML version only. +% Mix between \htmladdnormallink and \hyperref. +% First arg is text for in both versions, second is label for use in HTML +% version. +\html@new{\htmlref}[2]{#1} + +%%% HTMLCITE +% Reference in HTML version only. +% Mix between \htmladdnormallink and \hypercite. +% First arg is text for in both versions, second is citation for use in HTML +% version. +\newcommand{\htmlcite}[2]{#1} + + +%%% HTMLIMAGE +% This command can be used inside any environment that is converted +% into an inlined image (eg a "figure" environment) in order to change +% the way the image will be translated. The argument of \htmlimage +% is really a string of options separated by commas ie +% [scale=<scale factor>],[external],[thumbnail=<reduction factor> +% The scale option allows control over the size of the final image. +% The ``external'' option will cause the image not to be inlined +% (images are inlined by default). External images will be accessible +% via a hypertext link. +% The ``thumbnail'' option will cause a small inlined image to be +% placed in the caption. The size of the thumbnail depends on the +% reduction factor. The use of the ``thumbnail'' option implies +% the ``external'' option. +% +% Example: +% \htmlimage{scale=1.5,external,thumbnail=0.2} +% will cause a small thumbnail image 1/5th of the original size to be +% placed in the final document, pointing to an external image 1.5 +% times bigger than the original. +% +\newcommand{\htmlimage}[1]{} + + +% \htmlborder causes a border to be placed around an image or table +% when the image is placed within a <TABLE> cell. +\newcommand{\htmlborder}[1]{} + +% Put \begin{makeimage}, \end{makeimage} around LaTeX to ensure its +% translation into an image. +% This shields sensitive text from being translated. +\newenvironment{makeimage}{}{} + + +% A dummy environment that can be useful to alter the order +% in which commands are processed, in LaTeX2HTML +\newenvironment{tex2html_deferred}{}{} + + +%%% HTMLADDTONAVIGATION +% This command appends its argument to the buttons in the navigation +% panel. It is ignored by LaTeX. +% +% Example: +% \htmladdtonavigation{\htmladdnormallink +% {\htmladdimg{http://server/path/to/gif}} +% {http://server/path}} +\newcommand{\htmladdtonavigation}[1]{} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% based upon Eijkhout's comment.sty v2.0 +% with modifications to avoid conflicts with later versions +% of this package, should a user be requiring it. +% Ross Moore, 10 March 1999 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Comment.sty version 2.0, 19 June 1992 +% selectively in/exclude pieces of text: the user can define new +% comment versions, and each is controlled separately. +% This style can be used with plain TeX or LaTeX, and probably +% most other packages too. +% +% Examples of use in LaTeX and TeX follow \endinput +% +% Author +% Victor Eijkhout +% Department of Computer Science +% University Tennessee at Knoxville +% 104 Ayres Hall +% Knoxville, TN 37996 +% USA +% +% eijkhout@cs.utk.edu +% +% Usage: all text included in between +% \comment ... \endcomment +% or \begin{comment} ... \end{comment} +% is discarded. The closing command should appear on a line +% of its own. No starting spaces, nothing after it. +% This environment should work with arbitrary amounts +% of comment. +% +% Other 'comment' environments are defined by +% and are selected/deselected with +% \includecomment{versiona} +% \excludecoment{versionb} +% +% These environments are used as +% \versiona ... \endversiona +% or \begin{versiona} ... \end{versiona} +% with the closing command again on a line of its own. +% +% Basic approach: +% to comment something out, scoop up every line in verbatim mode +% as macro argument, then throw it away. +% For inclusions, both the opening and closing comands +% are defined as noop +% +% Changed \next to \html@next to prevent clashes with other sty files +% (mike@emn.fr) +% Changed \html@next to \htmlnext so the \makeatletter and +% \makeatother commands could be removed (they were causing other +% style files - changebar.sty - to crash) (nikos@cbl.leeds.ac.uk) +% Changed \htmlnext back to \html@next... + +\def\makeinnocent#1{\catcode`#1=12 } +\def\csarg#1#2{\expandafter#1\csname#2\endcsname} + +\def\ThrowAwayComment#1{\begingroup + \def\CurrentComment{#1}% + \let\do\makeinnocent \dospecials + \makeinnocent\^^L% and whatever other special cases +%%RRM +%% use \xhtmlComment for \xComment +%% use \html@next for \next + \endlinechar`\^^M \catcode`\^^M=12 \xhtmlComment} +{\catcode`\^^M=12 \endlinechar=-1 % + \gdef\xhtmlComment#1^^M{\def\test{#1}\edef\test{\meaning\test} + \csarg\ifx{PlainEnd\CurrentComment Test}\test + \let\html@next\endgroup + \else \csarg\ifx{LaLaEnd\CurrentComment Test}\test + \edef\html@next{\endgroup\noexpand\end{\CurrentComment}} + \else \csarg\ifx{LaInnEnd\CurrentComment Test}\test + \edef\html@next{\endgroup\noexpand\end{\CurrentComment}} + \else \let\html@next\xhtmlComment + \fi \fi \fi \html@next} +} + +%%\def\includecomment %%RRM +\def\htmlincludecomment + #1{\expandafter\def\csname#1\endcsname{}% + \expandafter\def\csname end#1\endcsname{}} +%%\def\excludecomment %%RRM +\def\htmlexcludecomment + #1{\expandafter\def\csname#1\endcsname{\ThrowAwayComment{#1}}% + {\escapechar=-1\relax + \edef\tmp{\string\\end#1}% + \csarg\xdef{PlainEnd#1Test}{\meaning\tmp}% + \edef\tmp{\string\\end\string\{#1\string\}}% + \csarg\xdef{LaLaEnd#1Test}{\meaning\tmp}% + \edef\tmp{\string\\end \string\{#1\string\}}% + \csarg\xdef{LaInnEnd#1Test}{\meaning\tmp}% + }} + +%%\excludecomment{comment} %%RRM +\htmlexcludecomment{comment} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% end Comment.sty +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\let\includecomment=\htmlincludecomment +\let\excludecomment=\htmlexcludecomment + +% +% Alternative code by Robin Fairbairns, 22 September 1997 +% revised to cope with % and unnested { }, by Ross Moore, 4 July 1998 +% further revised to cope with & and # in tables, 10 March 1999 +% +\def\raw@catcodes{\catcode`\%=12 \catcode`\{=12 \catcode`\}=12 + \catcode`\&=12 \catcode`\#=12 } +\newcommand\@gobbleenv{\bgroup\raw@catcodes + \let\reserved@a\@currenvir\@gobble@nv} +\bgroup + \def\expansionhead{\gdef\@gobble@nv@i##1} + \def\expansiontail{{\def\reserved@b{##1}\@gobble@nv@ii}} + \def\expansionheadii{\long\gdef\@gobble@nv##1\end} + \def\expansiontailii{{\@gobble@nv@i}} + \def\expansionmidii{##2} + \raw@catcodes\relax + \expandafter\expansionhead\expandafter}\expansiontail +\egroup +\long\gdef\@gobble@nv#1\end#2{\@gobble@nv@i} +%\long\def\@gobble@nv#1\end#2{\def\reserved@b{#2}% +\def\@gobble@nv@ii{% + \ifx\reserved@a\reserved@b + \edef\reserved@a{\egroup\noexpand\end{\reserved@a}}% + \expandafter\reserved@a + \else + \expandafter\@gobble@nv + \fi} + +\renewcommand{\htmlexcludecomment}[1]{% + \csname newenvironment\endcsname{#1}{\@gobbleenv}{}} +\newcommand{\htmlreexcludecomment}[1]{% + \csname renewenvironment\endcsname{#1}{\@gobbleenv}{}} + +%%% RAW HTML +% +% Enclose raw HTML between a \begin{rawhtml} and \end{rawhtml}. +% The html environment ignores its body +% +\htmlexcludecomment{rawhtml} + + +%%% HTML ONLY +% +% Enclose LaTeX constructs which will only appear in the +% HTML output and will be ignored by LaTeX with +% \begin{htmlonly} and \end{htmlonly} +% +\htmlexcludecomment{htmlonly} +% Shorter version +\newcommand{\html}[1]{} + +% for images.tex only +\htmlexcludecomment{imagesonly} + +%%% LaTeX ONLY +% Enclose LaTeX constructs which will only appear in the +% DVI output and will be ignored by latex2html with +%\begin{latexonly} and \end{latexonly} +% +\newenvironment{latexonly}{}{} +% Shorter version +\newcommand{\latex}[1]{#1} + + +%%% LaTeX or HTML +% Combination of \latex and \html. +% Say \latexhtml{this should be latex text}{this html text} +% +%\newcommand{\latexhtml}[2]{#1} +\long\def\latexhtml#1#2{#1} + + +%%% tracing the HTML conversions +% This alters the tracing-level within the processing +% performed by latex2html by adjusting $VERBOSITY +% (see latex2html.config for the appropriate values) +% +\newcommand{\htmltracing}[1]{} +\newcommand{\htmltracenv}[1]{} + + +%%% \strikeout for HTML only +% uses <STRIKE>...</STRIKE> tags on the argument +% LaTeX just gobbles it up. +\newcommand{\strikeout}[1]{} + +%%% \htmlurl and \url +% implement \url as the simplest thing, if not already defined +% let \htmlurl#1 be equivalent to it +% +\def\htmlurlx#1{\begin{small}\texttt{#1}\end{small}}% +\expandafter\ifx\csname url\endcsname\relax + \let\htmlurl=\htmlurlx \else \let\htmlurl=\url \fi + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% JCL - stop input here if LaTeX2e is not present +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\ifx\if@compatibility\undefined + %LaTeX209 + \makeatother\relax\expandafter\endinput +\fi +\if@compatibility + %LaTeX2e in LaTeX209 compatibility mode + \makeatother\relax\expandafter\endinput +\fi + +%\let\real@TeXlogo = \TeX +%\DeclareRobustCommand{\TeX}{\relax\real@TeXlogo} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Start providing LaTeX2e extension: +% This is currently: +% - additional optional argument for \htmladdimg +% - support for segmented documents +% + +%\ProvidesPackage{html} +% [1996/12/22 v1.1 hypertext commands for latex2html (nd, hws, rrm)] +\ProvidesPackage{html} + [1999/03/12 v1.37 hypertext commands for latex2html (nd, hws, rrm)] + +% +% Ensure that \includecomment and \excludecomment are bound +% to the version defined here. +% +\AtBeginDocument{% + \let\includecomment=\htmlincludecomment + \let\excludecomment=\htmlexcludecomment + \htmlreexcludecomment{comment}} + +%%% bind \htmlurl to \url if that is later loaded +% +\expandafter\ifx\csname url\endcsname\relax + \AtBeginDocument{\@ifundefined{url}{}{\let\htmlurl=\url}}\fi + +%%%%MG + +% This command takes as argument a URL pointing to an image. +% The image will be embedded in the HTML document but will +% be ignored in the dvi and ps files. The optional argument +% denotes additional HTML tags. +% +% Example: \htmladdimg[ALT="portrait" ALIGN=CENTER]{portrait.gif} +% +\renewcommand{\htmladdimg}[2][]{} + +%%% HTMLRULE for LaTeX2e +% This command adds a horizontal rule and is valid even within +% a figure caption. +% +% This command is best used with LaTeX2e and HTML 3.2 support. +% It is like \hrule, but allows for options via key--value pairs +% as follows: \htmlrule[key1=value1, key2=value2, ...] . +% Use \htmlrule* to suppress the <BR> tag. +% Eg. \htmlrule[left, 15, 5pt, "none", NOSHADE] produces +% <BR CLEAR="left"><HR NOSHADE SIZE="15">. +% Renew the necessary part. +\renewcommand{\htmlrulestar}[1][all]{} + +%%% HTMLCLEAR for LaTeX2e +% This command puts in a <BR> tag, with optional CLEAR="<attrib>" +% +\renewcommand{\htmlclear}[1][all]{} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% renew some definitions to allow optional arguments +% +% The description of the options is missing, as yet. +% +\renewcommand{\latextohtml}{\textup{\LaTeX2\texttt{HTML}}} +\renewcommand{\htmladdnormallinkfoot}[3][]{#2\footnote{#3}} +\renewcommand{\htmladdnormallink}[3][]{#2} +\renewcommand{\htmlbody}[1][]{} +\renewcommand{\externallabels}[3][]{} +\renewcommand{\externalref}[2][]{} +\renewcommand{\externalcite}[1][]{\nocite} +\renewcommand{\hyperref}[1][]{\hyperrefi[#1]} +\renewcommand{\hypercite}[1][]{\hypercitei[#1]} +\renewcommand{\hypercitenocite}[2]{#2\hypercitenocitex} +\renewcommand{\hypercitenocitex}[2][]{\nocite{#2}} +\let\hyperciteno=\hypercitenocite +\let\hyperciteext=\hypercitenocite +\renewcommand{\htmlref}[2][]{#2{\def\tmp{#1}\ifx\tmp\@empty + \aftergroup\htmlrefdef\else\aftergroup\htmlrefext\fi}} +\newcommand{\htmlrefdef}[1]{} +\newcommand{\htmlrefext}[2][]{} +\renewcommand{\htmlcite}[2][]{#2{\def\tmp{#1}\ifx\tmp\@empty + \aftergroup\htmlcitedef\else\aftergroup\htmlciteext\fi}} +\newcommand{\htmlcitedef}[1]{ \nocite{#1}} +\newcommand{\htmlciteext}[2][]{} +\renewcommand{\htmlimage}[2][]{} +\renewcommand{\htmlborder}[2][]{} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% HTML HTMLset HTMLsetenv +% +% These commands do nothing in LaTeX, but can be used to place +% HTML tags or set Perl variables during the LaTeX2HTML processing; +% They are intended for expert use only. + +\newcommand{\HTMLcode}[2][]{} +\ifx\undefined\HTML\newcommand{\HTML}[2][]{}\else +\typeout{*** Warning: \string\HTML\space had an incompatible definition ***}% +\typeout{*** instead use \string\HTMLcode\space for raw HTML code ***}% +\fi +\newcommand{\HTMLset}[3][]{} +\newcommand{\HTMLsetenv}[3][]{} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% The following commands pertain to document segmentation, and +% were added by Herbert Swan <dprhws@edp.Arco.com> (with help from +% Michel Goossens <goossens@cern.ch>): +% +% +% This command inputs internal latex2html tables so that large +% documents can to partitioned into smaller (more manageable) +% segments. +% +\newcommand{\internal}[2][internals]{} + +% +% Define a dummy stub \htmlhead{}. This command causes latex2html +% to define the title of the start of a new segment. It is not +% normally placed in the user's document. Rather, it is passed to +% latex2html via a .ptr file written by \segment. +% +\newcommand{\htmlhead}[3][]{} + +% In the LaTeX2HTML version this will eliminate the title line +% generated by a \segment command, but retains the title string +% for use in other places. +% +\newcommand{\htmlnohead}{} + + +% In the LaTeX2HTML version this put a URL into a <BASE> tag +% within the <HEAD>...</HEAD> portion of a document. +% +\newcommand{\htmlbase}[1]{} + + +% Include style information into the stylesheet; e.g. CSS +% +\newcommand{\htmlsetstyle}[3][]{} +\newcommand{\htmladdtostyle}[3][]{} + +% Define a style-class for information in a particular language +% +\newcommand{\htmllanguagestyle}[2][]{} + + +% +% The dummy command \endpreamble is needed by latex2html to +% mark the end of the preamble in document segments that do +% not contain a \begin{document} +% +\newcommand{\startdocument}{} + + +% \tableofchildlinks, \htmlinfo +% by Ross Moore --- extensions dated 27 September 1997 +% +% These do nothing in LaTeX but for LaTeX2HTML they mark +% where the table of child-links and info-page should be placed, +% when the user wants other than the default. +% \tableofchildlinks % put mini-TOC at this location +% \tableofchildlinks[off] % not on current page +% \tableofchildlinks[none] % not on current and subsequent pages +% \tableofchildlinks[on] % selectively on current page +% \tableofchildlinks[all] % on current and all subsequent pages +% \htmlinfo % put info-page at this location +% \htmlinfo[off] % no info-page in current document +% \htmlinfo[none] % no info-page in current document +% *-versions omit the preceding <BR> tag. +% +\newcommand{\tableofchildlinks}{% + \@ifstar\tableofchildlinksstar\tableofchildlinksstar} +\newcommand{\tableofchildlinksstar}[1][]{} + +\newcommand{\htmlinfo}{\@ifstar\htmlinfostar\htmlinfostar} +\newcommand{\htmlinfostar}[1][]{} + + +% This redefines \begin to allow for an optional argument +% which is used by LaTeX2HTML to specify `style-sheet' information + +\let\realLaTeX@begin=\begin +\renewcommand{\begin}[1][]{\realLaTeX@begin} + + +% +% Allocate a new set of section counters, which will get incremented +% for "*" forms of sectioning commands, and for a few miscellaneous +% commands. +% + +\@ifundefined{c@part}{\newcounter{part}}{}% +\newcounter{lpart} +\newcounter{lchapter}[part] +\@ifundefined{c@chapter}% + {\let\Hchapter\relax \newcounter{chapter}\newcounter{lsection}[part]}% + {\let\Hchapter=\chapter \newcounter{lsection}[chapter]} +\newcounter{lsubsection}[section] +\newcounter{lsubsubsection}[subsection] +\newcounter{lparagraph}[subsubsection] +\newcounter{lsubparagraph}[paragraph] +%\newcounter{lequation} + +% +% Redefine "*" forms of sectioning commands to increment their +% respective counters. +% +\let\Hpart=\part +%\let\Hchapter=\chapter +\let\Hsection=\section +\let\Hsubsection=\subsection +\let\Hsubsubsection=\subsubsection +\let\Hparagraph=\paragraph +\let\Hsubparagraph=\subparagraph +\let\Hsubsubparagraph=\subsubparagraph + +\ifx\c@subparagraph\undefined + \newcounter{lsubsubparagraph}[lsubparagraph] +\else + \newcounter{lsubsubparagraph}[subparagraph] +\fi + +% +% The following definitions are specific to LaTeX2e: +% (They must be commented out for LaTeX 2.09) +% +\expandafter\ifx\csname part\endcsname\relax\else +\renewcommand{\part}{\@ifstar{\stepcounter{lpart}% + \bgroup\def\tmp{*}\H@part}{\bgroup\def\tmp{}\H@part}}\fi +\newcommand{\H@part}[1][]{\def\tmp@a{#1}\check@align + \expandafter\egroup\expandafter\Hpart\tmp} + +\ifx\Hchapter\relax\else + \def\chapter{\resetsections \@ifstar{\stepcounter{lchapter}% + \bgroup\def\tmp{*}\H@chapter}{\bgroup\def\tmp{}\H@chapter}}\fi +\newcommand{\H@chapter}[1][]{\def\tmp@a{#1}\check@align + \expandafter\egroup\expandafter\Hchapter\tmp} + +\renewcommand{\section}{\resetsubsections + \@ifstar{\stepcounter{lsection}\bgroup\def\tmp{*}% + \H@section}{\bgroup\def\tmp{}\H@section}} +\newcommand{\H@section}[1][]{\def\tmp@a{#1}\check@align + \expandafter\egroup\expandafter\Hsection\tmp} + +\renewcommand{\subsection}{\resetsubsubsections + \@ifstar{\stepcounter{lsubsection}\bgroup\def\tmp{*}% + \H@subsection}{\bgroup\def\tmp{}\H@subsection}} +\newcommand{\H@subsection}[1][]{\def\tmp@a{#1}\check@align + \expandafter\egroup\expandafter\Hsubsection\tmp} + +\renewcommand{\subsubsection}{\resetparagraphs + \@ifstar{\stepcounter{lsubsubsection}\bgroup\def\tmp{*}% + \H@subsubsection}{\bgroup\def\tmp{}\H@subsubsection}} +\newcommand{\H@subsubsection}[1][]{\def\tmp@a{#1}\check@align + \expandafter\egroup\expandafter\Hsubsubsection\tmp} + +\renewcommand{\paragraph}{\resetsubparagraphs + \@ifstar{\stepcounter{lparagraph}\bgroup\def\tmp{*}% + \H@paragraph}{\bgroup\def\tmp{}\H@paragraph}} +\newcommand\H@paragraph[1][]{\def\tmp@a{#1}\check@align + \expandafter\egroup\expandafter\Hparagraph\tmp} + +\ifx\Hsubparagraph\relax\else\@ifundefined{subparagraph}{}{% +\renewcommand{\subparagraph}{\resetsubsubparagraphs + \@ifstar{\stepcounter{lsubparagraph}\bgroup\def\tmp{*}% + \H@subparagraph}{\bgroup\def\tmp{}\H@subparagraph}}}\fi +\newcommand\H@subparagraph[1][]{\def\tmp@a{#1}\check@align + \expandafter\egroup\expandafter\Hsubparagraph\tmp} + +\ifx\Hsubsubparagraph\relax\else\@ifundefined{subsubparagraph}{}{% +\def\subsubparagraph{% + \@ifstar{\stepcounter{lsubsubparagraph}\bgroup\def\tmp{*}% + \H@subsubparagraph}{\bgroup\def\tmp{}\H@subsubparagraph}}}\fi +\newcommand\H@subsubparagraph[1][]{\def\tmp@a{#1}\check@align + \expandafter\egroup\expandafter\Hsubsubparagraph\tmp} + +\def\check@align{\def\empty{}\ifx\tmp@a\empty + \else\def\tmp@b{center}\ifx\tmp@a\tmp@b\let\tmp@a\empty + \else\def\tmp@b{left}\ifx\tmp@a\tmp@b\let\tmp@a\empty + \else\def\tmp@b{right}\ifx\tmp@a\tmp@b\let\tmp@a\empty + \else\expandafter\def\expandafter\tmp@a\expandafter{\expandafter[\tmp@a]}% + \fi\fi\fi \def\empty{}\ifx\tmp\empty\let\tmp=\tmp@a \else + \expandafter\def\expandafter\tmp\expandafter{\expandafter*\tmp@a}% + \fi\fi} +% +\def\resetsections{\setcounter{section}{0}\setcounter{lsection}{0}% + \reset@dependents{section}\resetsubsections } +\def\resetsubsections{\setcounter{subsection}{0}\setcounter{lsubsection}{0}% + \reset@dependents{subsection}\resetsubsubsections } +\def\resetsubsubsections{\setcounter{subsubsection}{0}\setcounter{lsubsubsection}{0}% + \reset@dependents{subsubsection}\resetparagraphs } +% +\def\resetparagraphs{\setcounter{lparagraph}{0}\setcounter{lparagraph}{0}% + \reset@dependents{paragraph}\resetsubparagraphs } +\def\resetsubparagraphs{\ifx\c@subparagraph\undefined\else + \setcounter{subparagraph}{0}\fi \setcounter{lsubparagraph}{0}% + \reset@dependents{subparagraph}\resetsubsubparagraphs } +\def\resetsubsubparagraphs{\ifx\c@subsubparagraph\undefined\else + \setcounter{subsubparagraph}{0}\fi \setcounter{lsubsubparagraph}{0}} +% +\def\reset@dependents#1{\begingroup\let \@elt \@stpelt + \csname cl@#1\endcsname\endgroup} +% +% +% Define a helper macro to dump a single \secounter command to a file. +% +\newcommand{\DumpPtr}[2]{% +\count255=\arabic{#1}\def\dummy{dummy}\def\tmp{#2}% +\ifx\tmp\dummy\def\ctr{#1}\else + \def\ctr{#2}\advance\count255 by \arabic{#2}\fi +\immediate\write\ptrfile{% +\noexpand\setcounter{\ctr}{\number\count255}}} +%\expandafter\noexpand\expandafter\setcounter\expandafter{\ctr}{\number\count255}}} + +% +% Define a helper macro to dump all counters to the file. +% The value for each counter will be the sum of the l-counter +% actual LaTeX section counter. +% Also dump an \htmlhead{section-command}{section title} command +% to the file. +% +\newwrite\ptrfile +\def\DumpCounters#1#2#3#4{% +\begingroup\let\protect=\noexpand +\immediate\openout\ptrfile = #1.ptr +\DumpPtr{part}{lpart}% +\ifx\Hchapter\relax\else\DumpPtr{chapter}{lchapter}\fi +\DumpPtr{section}{lsection}% +\DumpPtr{subsection}{lsubsection}% +\DumpPtr{subsubsection}{lsubsubsection}% +\DumpPtr{paragraph}{lparagraph}% +\DumpPtr{subparagraph}{lsubparagraph}% +\DumpPtr{equation}{dummy}% +\DumpPtr{footnote}{dummy}% +\def\tmp{#4}\ifx\tmp\@empty +\immediate\write\ptrfile{\noexpand\htmlhead{#2}{#3}}\else +\immediate\write\ptrfile{\noexpand\htmlhead[#4]{#2}{#3}}\fi +\dumpcitestatus \dumpcurrentcolor +\immediate\closeout\ptrfile +\endgroup } + + +%% interface to natbib.sty + +\def\dumpcitestatus{} +\def\loadcitestatus{\def\dumpcitestatus{% + \ifciteindex\immediate\write\ptrfile{\noexpand\citeindextrue}% + \else\immediate\write\ptrfile{\noexpand\citeindexfalse}\fi }% +} +\@ifpackageloaded{natbib}{\loadcitestatus}{% + \AtBeginDocument{\@ifpackageloaded{natbib}{\loadcitestatus}{}}} + + +%% interface to color.sty + +\def\dumpcurrentcolor{} +\def\loadsegmentcolors{% + \let\real@pagecolor=\pagecolor + \let\pagecolor\segmentpagecolor + \let\segmentcolor\color + \ifx\current@page@color\undefined \def\current@page@color{{}}\fi + \def\dumpcurrentcolor{\bgroup\def\@empty@{{}}% + \expandafter\def\expandafter\tmp\space####1@{\def\thiscol{####1}}% + \ifx\current@color\@empty@\def\thiscol{}\else + \expandafter\tmp\current@color @\fi + \immediate\write\ptrfile{\noexpand\segmentcolor{\thiscol}}% + \ifx\current@page@color\@empty@\def\thiscol{}\else + \expandafter\tmp\current@page@color @\fi + \immediate\write\ptrfile{\noexpand\segmentpagecolor{\thiscol}}% + \egroup}% + \global\let\loadsegmentcolors=\relax +} + +% These macros are needed within images.tex since this inputs +% the <segment>.ptr files for a segment, so that counters are +% colors are synchronised. +% +\newcommand{\segmentpagecolor}[1][]{% + \@ifpackageloaded{color}{\loadsegmentcolors\bgroup + \def\tmp{#1}\ifx\@empty\tmp\def\next{[]}\else\def\next{[#1]}\fi + \expandafter\segmentpagecolor@\next}% + {\@gobble}} +\def\segmentpagecolor@[#1]#2{\def\tmp{#1}\def\tmpB{#2}% + \ifx\tmpB\@empty\let\next=\egroup + \else + \let\realendgroup=\endgroup + \def\endgroup{\edef\next{\noexpand\realendgroup + \def\noexpand\current@page@color{\current@color}}\next}% + \ifx\tmp\@empty\real@pagecolor{#2}\def\model{}% + \else\real@pagecolor[#1]{#2}\def\model{[#1]}% + \fi + \edef\next{\egroup\def\noexpand\current@page@color{\current@page@color}% + \noexpand\real@pagecolor\model{#2}}% + \fi\next} +% +\newcommand{\segmentcolor}[2][named]{\@ifpackageloaded{color}% + {\loadsegmentcolors\segmentcolor[#1]{#2}}{}} + +\@ifpackageloaded{color}{\loadsegmentcolors}{\let\real@pagecolor=\@gobble + \AtBeginDocument{\@ifpackageloaded{color}{\loadsegmentcolors}{}}} + + +% Define the \segment[align]{file}{section-command}{section-title} command, +% and its helper macros. This command does four things: +% 1) Begins a new LaTeX section; +% 2) Writes a list of section counters to file.ptr, each +% of which represents the sum of the LaTeX section +% counters, and the l-counters, defined above; +% 3) Write an \htmlhead{section-title} command to file.ptr; +% 4) Inputs file.tex. + +\newcommand{\segment}{\@ifstar{\@@htmls}{\@@html}} +%\tracingall +\newcommand{\@endsegment}[1][]{} +\let\endsegment\@endsegment +\newcommand{\@@htmls}[1][]{\@@htmlsx{#1}} +\newcommand{\@@html}[1][]{\@@htmlx{#1}} +\def\@@htmlsx#1#2#3#4{\csname #3\endcsname* {#4}% + \DumpCounters{#2}{#3*}{#4}{#1}\input{#2}} +\def\@@htmlx#1#2#3#4{\csname #3\endcsname {#4}% + \DumpCounters{#2}{#3}{#4}{#1}\input{#2}} + +\makeatother +\endinput + + +% Modifications: +% +% (The listing of Initiales see Changes) + +% $Log: not supported by cvs2svn $ +% Revision 1.1 2001/02/02 21:25:31 mengel +% this bit too... +% +% Revision 1.37 1999/03/12 07:02:38 RRM +% -- change macro name from \addTOCsection to \htmladdTOClink +% -- it has 3 + 1 optional argument, to allow a local path to a labels.pl +% file for the external document, for cross-references +% +% Revision 1.36 1999/03/10 05:46:00 RRM +% -- extended the code for compatibilty with comment.sty +% -- allow excluded environments to work within tables, +% with the excluded material spanning headers and several cells +% thanks Avinash Chopde for recognising the need for this. +% -- added LaTeX support (ignores it) for \htmladdTOCsection +% thanks to Steffen Klupsch and Uli Wortmann for this idea. +% +% Revision 1.35 1999/03/08 11:16:16 RRM +% html.sty for LaTeX2HTML V99.1 +% +% -- ensure that html.sty can be loaded *after* hyperref.sty +% -- support new command \htmlclear for <BR> in HTML, ignored by LaTeX +% -- ensure {part} and {chapter} counters are defined, even if not used +% +% Revision 1.34 1998/09/19 10:37:29 RRM +% -- fixed typo with \next{\hyperref}{....} +% +% Revision 1.33 1998/09/08 12:47:51 RRM +% -- changed macro-names for the \hyperref and \hypercite options +% allows easier compatibility with other packages +% +% Revision 1.32 1998/08/24 12:15:14 RRM +% -- new command \htmllanguagestyle to associate a style class +% with text declared as a particular language +% +% Revision 1.31 1998/07/07 14:15:41 RRM +% -- new commands \htmlsetstyle and \htmladdtostyle +% +% Revision 1.30 1998/07/04 02:42:22 RRM +% -- cope with catcodes of % { } in rawhtml/comment/htmlonly environments +% +% Revision 1.29 1998/06/23 13:33:23 RRM +% -- use \begin{small} with the default for URLs +% +% Revision 1.28 1998/06/21 09:38:39 RRM +% -- implement \htmlurl to agree with \url if already defined +% or loaded subsequently (LaTeX-2e only) +% -- get LaTeX to print the revision number when loading +% +% Revision 1.27 1998/06/20 15:13:10 RRM +% -- \TeX is already protected in recent versions of LaTeX +% so \DeclareRobust doesn't work --- causes looping +% -- \part and \subparagraph need not be defined in some styles +% +% Revision 1.26 1998/06/01 08:36:49 latex2html +% -- implement optional argument for \endsegment +% -- made the counter value output from \DumpPtr more robust +% +% Revision 1.25 1998/05/09 05:43:35 latex2html +% -- conditionals for avoiding undefined counters +% +% Revision 1.23 1998/02/26 10:32:24 latex2html +% -- use \providecommand for \latextohtml +% -- implemented \HTMLcode to do what \HTML did previously +% \HTML still works, unless already defined by another package +% -- fixed problems remaining with undefined \chapter +% -- defined \endsegment +% +% Revision 1.22 1997/12/05 11:38:18 RRM +% -- implemented an optional argument to \begin for style-sheet info. +% -- modified use of an optional argument with sectioning-commands +% +% Revision 1.21 1997/11/05 10:28:56 RRM +% -- replaced redefinition of \@htmlrule with \htmlrulestar +% +% Revision 1.20 1997/10/28 02:15:58 RRM +% -- altered the way some special html-macros are defined, so that +% star-variants are explicitly defined for LaTeX +% -- it is possible for these to occur within images.tex +% e.g. \htmlinfostar \htmlrulestar \tableofchildlinksstar +% +% Revision 1.19 1997/10/11 05:47:48 RRM +% -- allow the dummy {tex2html_nowrap} environment in LaTeX +% use it to make its contents be evaluated in environment order +% +% Revision 1.18 1997/10/04 06:56:50 RRM +% -- uses Robin Fairbairns' code for ignored environments, +% replacing the previous comment.sty stuff. +% -- extensions to the \tableofchildlinks command +% -- extensions to the \htmlinfo command +% +% Revision 1.17 1997/07/08 11:23:39 RRM +% include value of footnote counter in .ptr files for segments +% +% Revision 1.16 1997/07/03 08:56:34 RRM +% use \textup within the \latextohtml macro +% +% Revision 1.15 1997/06/15 10:24:58 RRM +% new command \htmltracenv as environment-ordered \htmltracing +% +% Revision 1.14 1997/06/06 10:30:37 RRM +% - new command: \htmlborder puts environment into a <TABLE> cell +% with a border of specified width, + other attributes. +% - new commands: \HTML for setting arbitrary HTML tags, with attributes +% \HTMLset for setting Perl variables, while processing +% \HTMLsetenv same as \HTMLset , but it gets processed +% as if it were an environment. +% - new command: \latextohtml --- to set the LaTeX2HTML name/logo +% - fixed some remaining problems with \segmentcolor & \segmentpagecolor +% +% Revision 1.13 1997/05/19 13:55:46 RRM +% alterations and extra options to \hypercite +% +% Revision 1.12 1997/05/09 12:28:39 RRM +% - Added the optional argument to \htmlhead, also in \DumpCounters +% - Implemented \HTMLset as a no-op in LaTeX. +% - Fixed a bug in accessing the page@color settings. +% +% Revision 1.11 1997/03/26 09:32:40 RRM +% - Implements LaTeX versions of \externalcite and \hypercite commands. +% Thanks to Uffe Engberg and Stephen Simpson for the suggestions. +% +% Revision 1.10 1997/03/06 07:37:58 RRM +% Added the \htmltracing command, for altering $VERBOSITY . +% +% Revision 1.9 1997/02/17 02:26:26 RRM +% - changes to counter handling (RRM) +% - shuffled around some definitions +% - changed \htmlrule of 209 mode +% +% Revision 1.8 1997/01/26 09:04:12 RRM +% RRM: added optional argument to sectioning commands +% \htmlbase sets the <BASE HREF=...> tag +% \htmlinfo and \htmlinfo* allow the document info to be positioned +% +% Revision 1.7 1997/01/03 12:15:44 L2HADMIN +% % - fixes to the color and natbib interfaces +% % - extended usage of \hyperref, via an optional argument. +% % - extended use comment environments to allow shifting expansions +% % e.g. within \multicolumn (`bug' reported by Luc De Coninck). +% % - allow optional argument to: \htmlimage, \htmlhead, +% % \htmladdimg, \htmladdnormallink, \htmladdnormallinkfoot +% % - added new commands: \htmlbody, \htmlnohead +% % - added new command: \tableofchildlinks +% +% Revision 1.6 1996/12/25 03:04:54 JCL +% added patches to segment feature from Martin Wilck +% +% Revision 1.5 1996/12/23 01:48:06 JCL +% o introduced the environment makeimage, which may be used to force +% LaTeX2HTML to generate an image from the contents. +% There's no magic, all what we have now is a defined empty environment +% which LaTeX2HTML will not recognize and thus pass it to images.tex. +% o provided \protect to the \htmlrule commands to allow for usage +% within captions. +% +% Revision 1.4 1996/12/21 19:59:22 JCL +% - shuffled some entries +% - added \latexhtml command +% +% Revision 1.3 1996/12/21 12:22:59 JCL +% removed duplicate \htmlrule, changed \htmlrule back not to create a \hrule +% to allow occurrence in caption +% +% Revision 1.2 1996/12/20 04:03:41 JCL +% changed occurrence of \makeatletter, \makeatother +% added new \htmlrule command both for the LaTeX2.09 and LaTeX2e +% sections +% +% +% jcl 30-SEP-96 +% - Stuck the commands commonly used by both LaTeX versions to the top, +% added a check which stops input or reads further if the document +% makes use of LaTeX2e. +% - Introduced rrm's \dumpcurrentcolor and \bodytext +% hws 31-JAN-96 - Added support for document segmentation +% hws 10-OCT-95 - Added \htmlrule command +% jz 22-APR-94 - Added support for htmlref +% nd - Created diff --git a/input.c b/input.c new file mode 100644 index 0000000..5975e48 --- /dev/null +++ b/input.c @@ -0,0 +1,155 @@ +#include "global.h" +static FILE *source_file; /* the current input file */ +static int double_at; +static int include_depth; +static struct { + FILE *file; + char *name; + int line; +} stack[10]; + +int source_peek; +int source_last; +int source_get() +{ + int c; + source_last = c = source_peek; + switch (c) { + case EOF: { + fclose(source_file); + if (include_depth) { + include_depth--; + source_file = stack[include_depth].file; + source_line = stack[include_depth].line; + source_name = stack[include_depth].name; + source_peek = getc(source_file); + c = source_get(); + } + } + return c; + case '\n': source_line++; + default: + if (c==nw_char) + { + /* Handle an ``at'' character */ + { + c = getc(source_file); + if (double_at) { + source_peek = c; + double_at = FALSE; + c = nw_char; + } + else + switch (c) { + case 'i': { + char name[FILENAME_MAX]; + char fullname[FILENAME_MAX]; + struct incl * p = include_list; + + if (include_depth >= 10) { + fprintf(stderr, "%s: include nesting too deep (%s, %d)\n", + command_name, source_name, source_line); + exit(-1); + } + /* Collect include-file name */ + { + char *p = name; + do + c = getc(source_file); + while (c == ' ' || c == '\t'); + while (isgraph(c)) { + *p++ = c; + c = getc(source_file); + } + *p = '\0'; + if (c != '\n') { + fprintf(stderr, "%s: unexpected characters after file name (%s, %d)\n", + command_name, source_name, source_line); + exit(-1); + } + } + stack[include_depth].file = source_file; + fullname[0] = '\0'; + for (;;) { + strcat(fullname, name); + source_file = fopen(fullname, "r"); + if (source_file || !p) + break; + strcpy(fullname, p->name); + strcat(fullname, "/"); + p = p->next; + } + if (!source_file) { + fprintf(stderr, "%s: can't open include file %s\n", + command_name, name); + source_file = stack[include_depth].file; + } + else + { + stack[include_depth].name = source_name; + stack[include_depth].line = source_line + 1; + include_depth++; + source_line = 1; + source_name = save_string(fullname); + } + source_peek = getc(source_file); + c = source_get(); + } + break; + case '#': case 'f': case 'm': case 'u': case 'v': + case 'd': case 'o': case 'D': case 'O': case 's': + case 'q': case 'Q': case 'S': case 't': + case '+': + case '-': + case '*': + case '\'': + case '{': case '}': case '<': case '>': case '|': + case '(': case ')': case '[': case ']': + case '%': case '_': + case ':': case ',': case 'x': case 'c': + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + case 'r': + source_peek = c; + c = nw_char; + break; + default: + if (c==nw_char) + { + source_peek = c; + double_at = TRUE; + break; + } + fprintf(stderr, "%s: bad %c sequence %c[%d] (%s, line %d)\n", + command_name, nw_char, c, c, source_name, source_line); + exit(-1); + } + } + return c; + } + source_peek = getc(source_file); + return c; + } +} +void source_ungetc(int *c) +{ + ungetc(source_peek, source_file); + if(*c == '\n') + source_line--; + source_peek=*c; +} +void source_open(name) + char *name; +{ + source_file = fopen(name, "r"); + if (!source_file) { + fprintf(stderr, "%s: couldn't open %s\n", command_name, name); + exit(-1); + } + nw_char = '@'; + source_name = name; + source_line = 1; + source_peek = getc(source_file); + double_at = FALSE; + include_depth = 0; +} diff --git a/latex.c b/latex.c new file mode 100644 index 0000000..baf2b94 --- /dev/null +++ b/latex.c @@ -0,0 +1,1086 @@ +#include "global.h" +static int scraps = 1; +static void copy_scrap(); /* formats the body of a scrap */ +static void print_scrap_numbers(); /* formats a list of scrap numbers */ +static void format_entry(); /* formats an index entry */ +static void format_file_entry(); /* formats a file index entry */ +static void format_user_entry(); +static void write_arg(); +static void write_literal(); +static void write_ArglistElement(); +void write_tex(file_name, tex_name, sector) + char *file_name; + char *tex_name; + unsigned char sector; +{ + FILE *tex_file = fopen(tex_name, "w"); + if (tex_file) { + if (verbose_flag) + fprintf(stderr, "writing %s\n", tex_name); + source_open(file_name); + /* Write LaTeX limbo definitions */ + if (hyperref_flag) { + fputs("\\newcommand{\\NWtarget}[2]{\\hypertarget{#1}{#2}}\n", tex_file); + fputs("\\newcommand{\\NWlink}[2]{\\hyperlink{#1}{#2}}\n", tex_file); + } else { + fputs("\\newcommand{\\NWtarget}[2]{#2}\n", tex_file); + fputs("\\newcommand{\\NWlink}[2]{#2}\n", tex_file); + } + fputs("\\newcommand{\\NWtxtMacroDefBy}{Fragment defined by}\n", tex_file); + fputs("\\newcommand{\\NWtxtMacroRefIn}{Fragment referenced in}\n", tex_file); + fputs("\\newcommand{\\NWtxtMacroNoRef}{Fragment never referenced}\n", tex_file); + fputs("\\newcommand{\\NWtxtDefBy}{Defined by}\n", tex_file); + fputs("\\newcommand{\\NWtxtRefIn}{Referenced in}\n", tex_file); + fputs("\\newcommand{\\NWtxtNoRef}{Not referenced}\n", tex_file); + fputs("\\newcommand{\\NWtxtFileDefBy}{File defined by}\n", tex_file); + fputs("\\newcommand{\\NWtxtIdentsUsed}{Uses:}\n", tex_file); + fputs("\\newcommand{\\NWtxtIdentsNotUsed}{Never used}\n", tex_file); + fputs("\\newcommand{\\NWtxtIdentsDefed}{Defines:}\n", tex_file); + fputs("\\newcommand{\\NWsep}{${\\diamond}$}\n", tex_file); + fputs("\\newcommand{\\NWnotglobal}{(not defined globally)}\n", tex_file); + fputs("\\newcommand{\\NWuseHyperlinks}{", tex_file); + if (hyperoptions[0] != '\0') + { + /* Write the hyperlink usage macro */ + fprintf(tex_file, "\\usepackage[%s]{hyperref}", hyperoptions); + } + fputs("}\n", tex_file); + + /* Copy \verb|source_file| into \verb|tex_file| */ + { + int inBlock = FALSE; + int c = source_get(); + while (c != EOF) { + if (c == nw_char) + { + /* Interpret at-sequence */ + { + int big_definition = FALSE; + c = source_get(); + switch (c) { + case 'r': + c = source_get(); + nw_char = c; + update_delimit_scrap(); + break; + case 'O': big_definition = TRUE; + case 'o': { + Name *name = collect_file_name(); + /* Begin the scrap environment */ + { + if (big_definition) + { + if (inBlock) + { + /* End block */ + fputs("\\end{minipage}\\vspace{4ex}\n", tex_file); + fputs("\\end{flushleft}\n", tex_file); + inBlock = FALSE; + } + fputs("\\begin{flushleft} \\small", tex_file); + } + else + { + if (inBlock) + { + /* Switch block */ + fputs("\\par\\vspace{\\baselineskip}\n", tex_file); + } + else + { + /* Start block */ + fputs("\\begin{flushleft} \\small\n\\begin{minipage}{\\linewidth}", tex_file); + inBlock = TRUE; + } + } + fprintf(tex_file, "\\label{scrap%d}\\raggedright\\small\n", scraps); + } + fputs("\\NWtarget{nuweb", tex_file); + write_single_scrap_ref(tex_file, scraps); + fputs("}{} ", tex_file); + fprintf(tex_file, "\\verb%c\"%s\"%c\\nobreak\\ {\\footnotesize {", nw_char, name->spelling, nw_char); + write_single_scrap_ref(tex_file, scraps); + fputs("}}$\\equiv$\n", tex_file); + /* Fill in the middle of the scrap environment */ + { + fputs("\\vspace{-1ex}\n\\begin{list}{}{} \\item\n", tex_file); + extra_scraps = 0; + copy_scrap(tex_file, TRUE, name); + fputs("{\\NWsep}\n\\end{list}\n", tex_file); + } + /* Begin the cross-reference environment */ + { + fputs("\\vspace{-1.5ex}\n", tex_file); + fputs("\\footnotesize\n", tex_file); + fputs("\\begin{list}{}{\\setlength{\\itemsep}{-\\parsep}", + tex_file); + fputs("\\setlength{\\itemindent}{-\\leftmargin}}\n", tex_file);} + + if ( scrap_flag ) { + /* Write file defs */ + { + if (name->defs) { + if (name->defs->next) { + fputs("\\item \\NWtxtFileDefBy\\ ", tex_file); + print_scrap_numbers(tex_file, name->defs); + } + } else { + fprintf(stderr, + "would have crashed in 'Write file defs' for '%s'\n", + name->spelling); + } + } + } + format_defs_refs(tex_file, scraps); + format_uses_refs(tex_file, scraps++); + /* Finish the cross-reference environment */ + { + fputs("\n\\item{}", tex_file); + fputs("\n\\end{list}\n", tex_file); + } + /* Finish the scrap environment */ + { + scraps += extra_scraps; + if (big_definition) + fputs("\\vspace{4ex}\n\\end{flushleft}\n", tex_file); + else + { + /* End block */ + fputs("\\end{minipage}\\vspace{4ex}\n", tex_file); + fputs("\\end{flushleft}\n", tex_file); + inBlock = FALSE; + } + do + c = source_get(); + while (isspace(c)); + } + } + break; + case 'Q': + case 'D': big_definition = TRUE; + case 'q': + case 'd': { + Name *name = collect_macro_name(); + + /* Begin the scrap environment */ + { + if (big_definition) + { + if (inBlock) + { + /* End block */ + fputs("\\end{minipage}\\vspace{4ex}\n", tex_file); + fputs("\\end{flushleft}\n", tex_file); + inBlock = FALSE; + } + fputs("\\begin{flushleft} \\small", tex_file); + } + else + { + if (inBlock) + { + /* Switch block */ + fputs("\\par\\vspace{\\baselineskip}\n", tex_file); + } + else + { + /* Start block */ + fputs("\\begin{flushleft} \\small\n\\begin{minipage}{\\linewidth}", tex_file); + inBlock = TRUE; + } + } + fprintf(tex_file, "\\label{scrap%d}\\raggedright\\small\n", scraps); + } + fputs("\\NWtarget{nuweb", tex_file); + write_single_scrap_ref(tex_file, scraps); + fputs("}{} $\\langle\\,${\\itshape ", tex_file); + /* Write the macro's name */ + { + char * p = name->spelling; + int i = 0; + + while (*p != '\000') { + if (*p == ARG_CHR) { + write_arg(tex_file, name->arg[i++]); + p++; + } + else + fputc(*p++, tex_file); + } + } + fputs("}\\nobreak\\ {\\footnotesize {", tex_file); + write_single_scrap_ref(tex_file, scraps); + fputs("}}$\\,\\rangle\\equiv$\n", tex_file); + /* Fill in the middle of the scrap environment */ + { + fputs("\\vspace{-1ex}\n\\begin{list}{}{} \\item\n", tex_file); + extra_scraps = 0; + copy_scrap(tex_file, TRUE, name); + fputs("{\\NWsep}\n\\end{list}\n", tex_file); + } + /* Begin the cross-reference environment */ + { + fputs("\\vspace{-1.5ex}\n", tex_file); + fputs("\\footnotesize\n", tex_file); + fputs("\\begin{list}{}{\\setlength{\\itemsep}{-\\parsep}", + tex_file); + fputs("\\setlength{\\itemindent}{-\\leftmargin}}\n", tex_file);} + + /* Write macro defs */ + { + if (name->defs->next) { + fputs("\\item \\NWtxtMacroDefBy\\ ", tex_file); + print_scrap_numbers(tex_file, name->defs); + } + } + /* Write macro refs */ + { + if (name->uses) { + if (name->uses->next) { + fputs("\\item \\NWtxtMacroRefIn\\ ", tex_file); + print_scrap_numbers(tex_file, name->uses); + } + else { + fputs("\\item \\NWtxtMacroRefIn\\ ", tex_file); + fputs("\\NWlink{nuweb", tex_file); + write_single_scrap_ref(tex_file, name->uses->scrap); + fputs("}{", tex_file); + write_single_scrap_ref(tex_file, name->uses->scrap); + fputs("}", tex_file); + fputs(".\n", tex_file); + } + } + else { + fputs("\\item {\\NWtxtMacroNoRef}.\n", tex_file); + fprintf(stderr, "%s: <%s> never referenced.\n", + command_name, name->spelling); + } + } + format_defs_refs(tex_file, scraps); + format_uses_refs(tex_file, scraps++); + /* Finish the cross-reference environment */ + { + fputs("\n\\item{}", tex_file); + fputs("\n\\end{list}\n", tex_file); + } + /* Finish the scrap environment */ + { + scraps += extra_scraps; + if (big_definition) + fputs("\\vspace{4ex}\n\\end{flushleft}\n", tex_file); + else + { + /* End block */ + fputs("\\end{minipage}\\vspace{4ex}\n", tex_file); + fputs("\\end{flushleft}\n", tex_file); + inBlock = FALSE; + } + do + c = source_get(); + while (isspace(c)); + } + } + break; + case 's': + /* Step to next sector */ + + prev_sector += 1; + current_sector = prev_sector; + c = source_get(); + + break; + case 'S': + /* Close the current sector */ + current_sector = 1; + c = source_get(); + + break; + case '{': + case '[': + case '(': copy_scrap(tex_file, FALSE, NULL); + c = source_get(); + + break; + case '<': { + Parameters local_parameters = 0; + int changed; + char indent_chars[MAX_INDENT]; + Arglist *a; + Name *name; + Arglist * args; + a = collect_scrap_name(0); + name = a->name; + args = instance(a->args, NULL, NULL, &changed); + name->mark = TRUE; + write_scraps(tex_file, tex_name, name->defs, 0, indent_chars, 0, 0, 1, 0, + args, name->arg, local_parameters, tex_name); + name->mark = FALSE; + c = source_get(); + } + + break; + case 'x': { + /* Get label from */ + char label_name[MAX_NAME_LEN]; + char * p = label_name; + while (c = source_get(), c != nw_char) /* Here is 150a-01 */ + *p++ = c; + *p = '\0'; + c = source_get(); + + write_label(label_name, tex_file); + } + c = source_get(); + break; + case 'c': if (inBlock) + { + /* End block */ + fputs("\\end{minipage}\\vspace{4ex}\n", tex_file); + fputs("\\end{flushleft}\n", tex_file); + inBlock = FALSE; + } + else + { + /* Start block */ + fputs("\\begin{flushleft} \\small\n\\begin{minipage}{\\linewidth}", tex_file); + inBlock = TRUE; + } + c = source_get(); + break; + case 'f': { + if (file_names) { + fputs("\n{\\small\\begin{list}{}{\\setlength{\\itemsep}{-\\parsep}", + tex_file); + fputs("\\setlength{\\itemindent}{-\\leftmargin}}\n", tex_file); + format_file_entry(file_names, tex_file); + fputs("\\end{list}}", tex_file); + } + c = source_get(); + } + break; + case 'm': { + unsigned char sector = current_sector; + int c = source_get(); + if (c == '+') + sector = 0; + else + source_ungetc(&c); + if (has_sector(macro_names, sector)) { + fputs("\n{\\small\\begin{list}{}{\\setlength{\\itemsep}{-\\parsep}", + tex_file); + fputs("\\setlength{\\itemindent}{-\\leftmargin}}\n", tex_file); + format_entry(macro_names, tex_file, sector); + fputs("\\end{list}}", tex_file); + } else { + fputs("None.\n", tex_file); + } + } + c = source_get(); + + break; + case 'u': { + unsigned char sector = current_sector; + c = source_get(); + if (c == '+') { + sector = 0; + c = source_get(); + } + if (has_sector(user_names, sector)) { + fputs("\n{\\small\\begin{list}{}{\\setlength{\\itemsep}{-\\parsep}", + tex_file); + fputs("\\setlength{\\itemindent}{-\\leftmargin}}\n", tex_file); + format_user_entry(user_names, tex_file, sector); + fputs("\\end{list}}", tex_file); + } + } + break; + case 'v': fputs(version_string, tex_file); + c = source_get(); + + break; + default: + if (c==nw_char) + putc(c, tex_file); + c = source_get(); + break; + } + } + } + else { + putc(c, tex_file); + c = source_get(); + } + } + } + fclose(tex_file); + } + else + fprintf(stderr, "%s: can't open %s\n", command_name, tex_name); +} +static void write_arg(FILE * tex_file, char * p) +{ + fputs("\\hbox{\\slshape\\sffamily ", tex_file); + while (*p) + { + switch (*p) + { + case '$': + case '_': + case '^': + case '#': + fputc('\\', tex_file); + break; + default: + break; + } + fputc(*p, tex_file); + p++; + } + + fputs("\\/}", tex_file); +} +static void print_scrap_numbers(tex_file, scraps) + FILE *tex_file; + Scrap_Node *scraps; +{ + int page; + fputs("\\NWlink{nuweb", tex_file); + write_scrap_ref(tex_file, scraps->scrap, -1, &page); + fputs("}{", tex_file); + write_scrap_ref(tex_file, scraps->scrap, TRUE, &page); + fputs("}", tex_file); + scraps = scraps->next; + while (scraps) { + fputs("\\NWlink{nuweb", tex_file); + write_scrap_ref(tex_file, scraps->scrap, -1, &page); + fputs("}{", tex_file); + write_scrap_ref(tex_file, scraps->scrap, FALSE, &page); + scraps = scraps->next; + fputs("}", tex_file); + } + fputs(".\n", tex_file); +} +static char *orig_delimit_scrap[3][5] = { + /* {} mode: begin, end, insert nw_char, prefix, suffix */ + { "\\verb@", "@", "@{\\tt @}\\verb@", "\\mbox{}", "\\\\" }, + /* [] mode: begin, end, insert nw_char, prefix, suffix */ + { "", "", "@", "", "" }, + /* () mode: begin, end, insert nw_char, prefix, suffix */ + { "$", "$", "@", "", "" }, +}; + +static char *delimit_scrap[3][5]; +void initialise_delimit_scrap_array() { + int i,j; + for(i = 0; i < 3; i++) { + for(j = 0; j < 5; j++) { + if((delimit_scrap[i][j] = strdup(orig_delimit_scrap[i][j])) == NULL) { + fprintf(stderr, "Not enough memory for string allocation\n"); + exit(EXIT_FAILURE); + } + } + } + + /* replace verb by lstinline */ + if (listings_flag) { + free(delimit_scrap[0][0]); + if((delimit_scrap[0][0]=strdup("\\lstinline@")) == NULL) { + fprintf(stderr, "Not enough memory for string allocation\n"); + exit(EXIT_FAILURE); + } + free(delimit_scrap[0][2]); + if((delimit_scrap[0][2]=strdup("@{\\tt @}\\lstinline@")) == NULL) { + fprintf(stderr, "Not enough memory for string allocation\n"); + exit(EXIT_FAILURE); + } + } +} +int scrap_type = 0; +static void write_literal(FILE * tex_file, char * p, int mode) +{ + fputs(delimit_scrap[mode][0], tex_file); + while (*p!= '\000') { + if (*p == nw_char) + fputs(delimit_scrap[mode][2], tex_file); + else + fputc(*p, tex_file); + p++; + } + fputs(delimit_scrap[mode][1], tex_file); +} +static void copy_scrap(file, prefix, name) + FILE *file; + int prefix; + Name * name; +{ + int indent = 0; + int c; + char ** params = name->arg; + if (source_last == '{') scrap_type = 0; + if (source_last == '[') scrap_type = 1; + if (source_last == '(') scrap_type = 2; + c = source_get(); + if (prefix) fputs(delimit_scrap[scrap_type][3], file); + fputs(delimit_scrap[scrap_type][0], file); + while (1) { + switch (c) { + case '\n': fputs(delimit_scrap[scrap_type][1], file); + if (prefix) fputs(delimit_scrap[scrap_type][4], file); + fputs("\n", file); + if (prefix) fputs(delimit_scrap[scrap_type][3], file); + fputs(delimit_scrap[scrap_type][0], file); + indent = 0; + break; + case '\t': { + int delta = 8 - (indent % 8); + indent += delta; + while (delta > 0) { + putc(' ', file); + delta--; + } + } + break; + default: + if (c==nw_char) + { + /* Check at-sequence for end-of-scrap */ + { + c = source_get(); + switch (c) { + case 'c': { + fputs(delimit_scrap[scrap_type][1],file); + fprintf(file, "\\hbox{\\sffamily\\slshape (Comment)}"); + fputs(delimit_scrap[scrap_type][0], file); + } + + break; + case 'x': { + /* Get label from */ + char label_name[MAX_NAME_LEN]; + char * p = label_name; + while (c = source_get(), c != nw_char) /* Here is 150a-01 */ + *p++ = c; + *p = '\0'; + c = source_get(); + + write_label(label_name, file); + } + break; + case 'v': fputs(version_string, file); + + case 's': + break; + case '+': + case '-': + case '*': + case '|': { + do { + do + c = source_get(); + while (c != nw_char); + c = source_get(); + } while (c != '}' && c != ']' && c != ')' ); + } + case ',': + case ')': + case ']': + case '}': fputs(delimit_scrap[scrap_type][1], file); + return; + case '<': { + Arglist *args = collect_scrap_name(-1); + Name *name = args->name; + char * p = name->spelling; + Arglist *q = args->args; + int narg = 0; + + fputs(delimit_scrap[scrap_type][1],file); + if (prefix) + fputs("\\hbox{", file); + fputs("$\\langle\\,${\\itshape ", file); + while (*p != '\000') { + if (*p == ARG_CHR) { + if (q == NULL) { + write_literal(file, name->arg[narg], scrap_type); + } + else { + write_ArglistElement(file, q, params); + q = q->next; + } + p++; + narg++; + } + else + fputc(*p++, file); + } + fputs("}\\nobreak\\ ", file); + if (scrap_name_has_parameters) { + /* Format macro parameters */ + + char sep; + + sep = '('; + do { + fputc(sep,file); + + fputs("{\\footnotesize ", file); + write_single_scrap_ref(file, scraps + 1); + fprintf(file, "\\label{scrap%d}\n", scraps + 1); + fputs(" }", file); + + source_last = '{'; + copy_scrap(file, TRUE, NULL); + + ++scraps; + + sep = ','; + } while ( source_last != ')' && source_last != EOF ); + fputs(" ) ",file); + do + c = source_get(); + while(c != nw_char && c != EOF); + if (c == nw_char) { + c = source_get(); + } + + } + fprintf(file, "{\\footnotesize "); + if (name->defs) + /* Write abbreviated definition list */ + { + Scrap_Node *p = name->defs; + fputs("\\NWlink{nuweb", file); + write_single_scrap_ref(file, p->scrap); + fputs("}{", file); + write_single_scrap_ref(file, p->scrap); + fputs("}", file); + p = p->next; + if (p) + fputs(", \\ldots\\ ", file); + } + else { + putc('?', file); + fprintf(stderr, "%s: never defined <%s>\n", + command_name, name->spelling); + } + fputs("}$\\,\\rangle$", file); + if (prefix) + fputs("}", file); + fputs(delimit_scrap[scrap_type][0], file); + } + break; + case '%': { + do + c = source_get(); + while (c != '\n'); + } + break; + case '_': { + fputs(delimit_scrap[scrap_type][1],file); + fprintf(file, "\\hbox{\\sffamily\\bfseries "); + c = source_get(); + do { + fputc(c, file); + c = source_get(); + } while (c != nw_char); + c = source_get(); + fprintf(file, "}"); + fputs(delimit_scrap[scrap_type][0], file); + } + break; + case 't': { + fputs(delimit_scrap[scrap_type][1],file); + fprintf(file, "\\hbox{\\sffamily\\slshape fragment title}"); + fputs(delimit_scrap[scrap_type][0], file); + } + break; + case 'f': { + fputs(delimit_scrap[scrap_type][1],file); + fprintf(file, "\\hbox{\\sffamily\\slshape file name}"); + fputs(delimit_scrap[scrap_type][0], file); + } + break; + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + if (name == NULL + || name->arg[c - '1'] == NULL) { + fputs(delimit_scrap[scrap_type][2], file); + fputc(c, file); + } + else { + fputs(delimit_scrap[scrap_type][1], file); + write_arg(file, name->arg[c - '1']); + fputs(delimit_scrap[scrap_type][0], file); + } + break; + default: + if (c==nw_char) + { + fputs(delimit_scrap[scrap_type][2], file); + break; + } + /* ignore these since pass1 will have warned about them */ + break; + } + } + break; + } + putc(c, file); + indent++; + break; + } + c = source_get(); + } +} +void update_delimit_scrap() +{ + /* {}-mode begin */ + if (listings_flag) { + delimit_scrap[0][0][10] = nw_char; + } else { + delimit_scrap[0][0][5] = nw_char; + } + /* {}-mode end */ + delimit_scrap[0][1][0] = nw_char; + /* {}-mode insert nw_char */ + + delimit_scrap[0][2][0] = nw_char; + delimit_scrap[0][2][6] = nw_char; + + if (listings_flag) { + delimit_scrap[0][2][18] = nw_char; + } else { + delimit_scrap[0][2][13] = nw_char; + } + + /* []-mode insert nw_char */ + delimit_scrap[1][2][0] = nw_char; + + /* ()-mode insert nw_char */ + delimit_scrap[2][2][0] = nw_char; +} +static void +write_ArglistElement(FILE * file, Arglist * args, char ** params) +{ + Name *name = args->name; + Arglist *q = args->args; + + if (name == NULL) { + char * p = (char*)q; + + if (p[0] == ARG_CHR) { + write_arg(file, params[p[1] - '1']); + } else { + write_literal(file, (char *)q, 0); + } + } else if (name == (Name *)1) { + Scrap_Node * qq = (Scrap_Node *)q; + qq->quoted = TRUE; + fputs(delimit_scrap[scrap_type][0], file); + write_scraps(file, "", qq, + -1, "", 0, 0, 0, 0, + NULL, params, 0, ""); + fputs(delimit_scrap[scrap_type][1], file); + extra_scraps++; + qq->quoted = FALSE; + } else { + char * p = name->spelling; + fputs("$\\langle\\,${\\itshape ", file); + while (*p != '\000') { + if (*p == ARG_CHR) { + write_ArglistElement(file, q, params); + q = q->next; + p++; + } + else + fputc(*p++, file); + } + fputs("}\\nobreak\\ ", file); + if (scrap_name_has_parameters) { + int c; + + /* Format macro parameters */ + + char sep; + + sep = '('; + do { + fputc(sep,file); + + fputs("{\\footnotesize ", file); + write_single_scrap_ref(file, scraps + 1); + fprintf(file, "\\label{scrap%d}\n", scraps + 1); + fputs(" }", file); + + source_last = '{'; + copy_scrap(file, TRUE, NULL); + + ++scraps; + + sep = ','; + } while ( source_last != ')' && source_last != EOF ); + fputs(" ) ",file); + do + c = source_get(); + while(c != nw_char && c != EOF); + if (c == nw_char) { + c = source_get(); + } + + } + fprintf(file, "{\\footnotesize "); + if (name->defs) + /* Write abbreviated definition list */ + { + Scrap_Node *p = name->defs; + fputs("\\NWlink{nuweb", file); + write_single_scrap_ref(file, p->scrap); + fputs("}{", file); + write_single_scrap_ref(file, p->scrap); + fputs("}", file); + p = p->next; + if (p) + fputs(", \\ldots\\ ", file); + } + else { + putc('?', file); + fprintf(stderr, "%s: never defined <%s>\n", + command_name, name->spelling); + } + fputs("}$\\,\\rangle$", file); + } +} +static void format_file_entry(name, tex_file) + Name *name; + FILE *tex_file; +{ + while (name) { + format_file_entry(name->llink, tex_file); + /* Format a file index entry */ + fputs("\\item ", tex_file); + fprintf(tex_file, "\\verb%c\"%s\"%c ", nw_char, name->spelling, nw_char); + /* Write file's defining scrap numbers */ + { + Scrap_Node *p = name->defs; + fputs("{\\footnotesize {\\NWtxtDefBy}", tex_file); + if (p->next) { + /* fputs("s ", tex_file); */ + putc(' ', tex_file); + print_scrap_numbers(tex_file, p); + } + else { + putc(' ', tex_file); + fputs("\\NWlink{nuweb", tex_file); + write_single_scrap_ref(tex_file, p->scrap); + fputs("}{", tex_file); + write_single_scrap_ref(tex_file, p->scrap); + fputs("}", tex_file); + putc('.', tex_file); + } + putc('}', tex_file); + } + putc('\n', tex_file); + name = name->rlink; + } +} +static int load_entry(Name * name, Name ** nms, int n) +{ + while (name) { + n = load_entry(name->llink, nms, n); + nms[n++] = name; + name = name->rlink; + } + return n; +} +static void format_entry(name, tex_file, sector) + Name *name; + FILE *tex_file; + unsigned char sector; +{ + Name ** nms = malloc(num_scraps()*sizeof(Name *)); + int n = load_entry(name, nms, 0); + int i; + + /* Sort 'nms' of size 'n' for <Rob's ordering> */ + int j; + for (j = 1; j < n; j++) + { + int i = j - 1; + Name * kj = nms[j]; + + do + { + Name * ki = nms[i]; + + if (robs_strcmp(ki->spelling, kj->spelling) < 0) + break; + nms[i + 1] = ki; + i -= 1; + } while (i >= 0); + nms[i + 1] = kj; + } + + for (i = 0; i < n; i++) + { + Name * name = nms[i]; + + /* Format an index entry */ + if (name->sector == sector){ + fputs("\\item ", tex_file); + fputs("$\\langle\\,$", tex_file); + /* Write the macro's name */ + { + char * p = name->spelling; + int i = 0; + + while (*p != '\000') { + if (*p == ARG_CHR) { + write_arg(tex_file, name->arg[i++]); + p++; + } + else + fputc(*p++, tex_file); + } + } + fputs("\\nobreak\\ {\\footnotesize ", tex_file); + /* Write defining scrap numbers */ + { + Scrap_Node *p = name->defs; + if (p) { + int page; + fputs("\\NWlink{nuweb", tex_file); + write_scrap_ref(tex_file, p->scrap, -1, &page); + fputs("}{", tex_file); + write_scrap_ref(tex_file, p->scrap, TRUE, &page); + fputs("}", tex_file); + p = p->next; + while (p) { + fputs("\\NWlink{nuweb", tex_file); + write_scrap_ref(tex_file, p->scrap, -1, &page); + fputs("}{", tex_file); + write_scrap_ref(tex_file, p->scrap, FALSE, &page); + fputs("}", tex_file); + p = p->next; + } + } + else + putc('?', tex_file); + } + fputs("}$\\,\\rangle$ ", tex_file); + /* Write referencing scrap numbers */ + { + Scrap_Node *p = name->uses; + fputs("{\\footnotesize ", tex_file); + if (p) { + fputs("{\\NWtxtRefIn}", tex_file); + if (p->next) { + /* fputs("s ", tex_file); */ + putc(' ', tex_file); + print_scrap_numbers(tex_file, p); + } + else { + putc(' ', tex_file); + fputs("\\NWlink{nuweb", tex_file); + write_single_scrap_ref(tex_file, p->scrap); + fputs("}{", tex_file); + write_single_scrap_ref(tex_file, p->scrap); + fputs("}", tex_file); + putc('.', tex_file); + } + } + else + fputs("{\\NWtxtNoRef}.", tex_file); + putc('}', tex_file); + } + putc('\n', tex_file); + } + } +} +int has_sector(Name * name, unsigned char sector) +{ + while(name) { + if (name->sector == sector) + return TRUE; + if (has_sector(name->llink, sector)) + return TRUE; + name = name->rlink; + } + return FALSE; +} +static void format_user_entry(name, tex_file, sector) + Name *name; + FILE *tex_file; + unsigned char sector; +{ + while (name) { + format_user_entry(name->llink, tex_file, sector); + /* Format a user index entry */ + if (name->sector == sector){ + Scrap_Node *uses = name->uses; + if ( uses || dangling_flag ) { + int page; + Scrap_Node *defs = name->defs; + fprintf(tex_file, "\\item \\verb%c%s%c: ", nw_char,name->spelling,nw_char); + if (!uses) { + fputs("(\\underline{", tex_file); + fputs("\\NWlink{nuweb", tex_file); + write_single_scrap_ref(tex_file, defs->scrap); + fputs("}{", tex_file); + write_single_scrap_ref(tex_file, defs->scrap); + fputs("})}", tex_file); + page = -2; + defs = defs->next; + } + else + if (!defs || uses->scrap < defs->scrap) { + fputs("\\NWlink{nuweb", tex_file); + write_scrap_ref(tex_file, uses->scrap, -1, &page); + fputs("}{", tex_file); + write_scrap_ref(tex_file, uses->scrap, TRUE, &page); + fputs("}", tex_file); + uses = uses->next; + } + else { + if (defs->scrap == uses->scrap) + uses = uses->next; + fputs("\\underline{", tex_file); + + fputs("\\NWlink{nuweb", tex_file); + write_single_scrap_ref(tex_file, defs->scrap); + fputs("}{", tex_file); + write_single_scrap_ref(tex_file, defs->scrap); + fputs("}}", tex_file); + page = -2; + defs = defs->next; + } + while (uses || defs) { + if (uses && (!defs || uses->scrap < defs->scrap)) { + fputs("\\NWlink{nuweb", tex_file); + write_scrap_ref(tex_file, uses->scrap, -1, &page); + fputs("}{", tex_file); + write_scrap_ref(tex_file, uses->scrap, FALSE, &page); + fputs("}", tex_file); + uses = uses->next; + } + else { + if (uses && defs->scrap == uses->scrap) + uses = uses->next; + fputs(", \\underline{", tex_file); + + fputs("\\NWlink{nuweb", tex_file); + write_single_scrap_ref(tex_file, defs->scrap); + fputs("}{", tex_file); + write_single_scrap_ref(tex_file, defs->scrap); + fputs("}", tex_file); + + putc('}', tex_file); + page = -2; + defs = defs->next; + } + } + fputs(".\n", tex_file); + } + } + name = name->rlink; + } +} diff --git a/litprog.bib b/litprog.bib new file mode 100644 index 0000000..afc76be --- /dev/null +++ b/litprog.bib @@ -0,0 +1,1090 @@ +% /u/sy/beebe/tex/bib/litprog.bib, Wed Mar 11 07:57:40 1992 +% Edit by Nelson H. F. Beebe <beebe at eros.math.utah.edu> +% +%%% ==================================================================== +%%% BibTeX-file{ +%%% author = "Nelson H. F. Beebe", +%%% version = "1.38", +%%% date = "16 December 1993", +%%% time = "09:13:59 MST", +%%% filename = "litprog.bib", +%%% address = "Center for Scientific Computing +%%% Department of Mathematics +%%% University of Utah +%%% Salt Lake City, UT 84112 +%%% USA", +%%% telephone = "+1 801 581 5254", +%%% FAX = "+1 801 581 4148", +%%% checksum = "03487 1113 4110 36861", +%%% email = "beebe at eros.math.utah.edu (Internet)", +%%% codetable = "ISO/ASCII", +%%% keywords = "bibliography, literate programming", +%%% supported = "yes", +%%% docstring = "This BibTeX file records books and articles +%%% about literate programming. The ISBN fields will +%%% be printed if the is-alpha.bst or is-plain.bst +%%% style files are used. +%%% +%%% CONVENTIONS +%%% +%%% Books are tagged by the first author's last +%%% name, a colon, up to 3 upper-case letters +%%% taken from the first three upper-case words +%%% in the title (ignoring words like A, And, +%%% The), followed by the last two digits of +%%% the publication year. If there is a volume +%%% entry, it is appended to the tag, prefixed +%%% by a hyphen. +%%% +%%% For Dutch authors, a van part is included +%%% in the author tag. For names with accented +%%% letters, accents are dropped in the author +%%% tag. +%%% +%%% This scheme is systematic enough that it +%%% can be programmed: most of the +%%% Addison-Wesley book entries were created +%%% with an awk program from a dump of the AW +%%% database supplied by Mona Zeftel. Older +%%% entries in this bibliography were modified +%%% on 28-Nov-1990 to conform to this tagging +%%% scheme. +%%% +%%% The choice of a limit of 3 letters was +%%% determined from experiments on the +%%% Addison-Wesley collection. Long tags are +%%% undesirable because they are a nuisance to +%%% type, and also interfere with the tagged +%%% bibliography output produced using the +%%% LaTeX showtags style option. +%%% +%%% Journal article tags look like +%%% author:abbrev-volume-number-page, where the +%%% author part is the last name of the first +%%% author: for example, VanWyk:CACM-33-3-361. +%%% +%%% Technical report tags look like +%%% author:abbrev-number: for example, +%%% Billawala:STAN-CS-89-1256. +%%% +%%% The Como InProceedings entries look like +%%% author:TEX85-page: for example, +%%% Agostini:TEX85-117. Other InProceedings +%%% entries should follow a similar style. +%%% +%%% Entries are stored ordered by the BibTeX +%%% tag name, independent of the entry type +%%% (the GNU Emacs function sort-bibtex-entries +%%% can be used to ensure correct ordering). +%%% However, entries that are cross-referenced +%%% by others are stored at the end of the +%%% file, since that order is required by +%%% BibTeX. +%%% +%%% With few exceptions, value fields for +%%% acknowledgement, address, journal, and +%%% publisher keywords should use macros +%%% defined in the string preamble below. This +%%% helps to ensure consistency, and reduces +%%% the entry sizes. Address entries must +%%% always include the country. +%%% +%%% The checksum field above contains a CRC-16 +%%% checksum as the first value, followed by the +%%% equivalent of the standard UNIX wc (word +%%% count) utility output of lines, words, and +%%% characters. This is produced by Robert +%%% Solovay's checksum utility." +%%% } +%%% ==================================================================== + +%%% +%%% Thanks go to: +%%% Mark B. Motl <motl at cs.tamu.edu> for additions and corrections +%%% [05-Jul-1990] +%%% + +@Preamble{"\input bibnames.sty " + # "\hyphenation{Ker-n-i-ghan Port-able Post-Script Pren-tice Richt-er + Spring-er} " +} + +@String{ack-bc = "S. Bart Childs, + e-mail: \path|bart@cs.tamu.edu|"} +@String{ack-bnb = "Barbara N. Beeton + e-mail: \path|bnb@math.ams.com|"} +@String{ack-dl = "Dave Love, + e-mail: \path|d.love@daresbury.ac.uk|"} +@String{ack-eg = "Eitan M. Gurari, + e-mail: \path|gurari@cis.ohio-state.edu|"} +@String{ack-ma = "M. Afzal + e-mail: \path|M.Afzal@greenwich.ac.uk|"} +@String{ack-nhfb = "Nelson H. F. Beebe, + Center for Scientific Computing, + Department of Mathematics, + University of Utah, + Salt Lake City, UT 84112, USA, + Tel: +1 801 581 5254, + FAX: +1 801 581 4148, + e-mail: \path|beebe@math.utah.edu|"} +@String{ack-nr = "Norman Ramsey, + e-mail: \path|norman@bellcore.com|"} +@String{ack-pb = "Preston Briggs, + e-mail: \path|preston@cs.rice.edu|"} +@String{ack-pt = "Piet Tutelaers + e-mail: \path|rcpt@urc.tue.nl|"} + +@String{j-ACM-ADALET = "ACM Ada Letters"} +@String{j-ACM-COMPREV = "ACM Computing Reviews"} +@String{j-CACM = "Communications of the Association for Computing Machinery"} +@String{j-CJ = "The Computer Journal"} +@String{j-COMPLANG = "Computer Language"} +@String{j-COMPUTER = "Computer"} +@String{j-IEEE-SOFTWARE = "IEEE Software"} +@String{j-LNCS = "Lecture Notes in Computer Science"} +@String{j-OOP = "Journal of Object Oriented Programming"} +@String{j-SIGPLAN = "ACM SIGPLAN Notices"} +@String{j-SEJ = "Software Engineering Journal"} +@String{j-SP = "Journal of Structured Programming"} +@String{j-SPE = "Soft{\-}ware\emdash Prac{\-}tice and Experience"} +@String{j-TEXHAX = "{\TeX{}{\-}hax}"} +@String{j-TUGboat = "{\TUB{}}"} + +@String{pub-ACM = "ACM Press"} +@String{pub-ACM:adr = "New York, NY 10036, USA"} +@String{pub-AW = "Ad{\-d}i{\-s}on-Wes{\-l}ey"} +@String{pub-AW:adr = "Reading, MA, USA"} +@String{pub-IEEE-CSP = "IEEE CS Press"} +@String{pub-MH = "McGraw-Hill"} +@String{pub-MH:adr = "New York, NY, USA"} +@String{pub-PH = "Pren{\-}tice-Hall"} +@String{pub-PH:adr = "Englewood Cliffs, NJ 07632, USA"} +@String{pub-SUCSLI = "Stanford University Center for the Study of + Language and Information"} +@String{pub-SUCSLI:adr = "Stanford, CA, USA"} +@String{pub-TEXPLORATOR = "The {\TeX}plorators Corporation"} +@String{pub-TEXPLORATOR:adr = "3701 W. Alabama, Suite 450-273, + Houston, TX 77027, USA"} +@String{pub-VNR = "Van Nostrand Reinhold"} +@String{pub-VNR:adr = "New York, NY, USA"} + +@Article{Appelt:TB7-1-20, + author = "W. Appelt and K. Horn", + title = "{{Multiple changefiles in \WEB{}}}", + journal = j-TUGboat, + year = "1986", + volume = "7", + number = "1", + pages = "20", + month = Mar, +} + +@Article{Avenarius:SIGPLAN-25-1-52, + author = "Adrian Avenarius and Siegfried Oppermann", + title = "{\FWEB}: A Literate Programming System for + {Fortran 8X}", + journal = j-SIGPLAN, + year = "1990", + volume = "25", + number = "1", + pages = "52--58", + month = jan, +} + +@Inproceedings{Baecker:CHI86-51, + author = "Ronald Baecker and Aaron Marcus", + title = "Design Principles for the Enhanced Presentation of + Computer Program Source Text", + booktitle = "Proceedings {CHI}'86 (Human Factors in Computing + Systems)", + year = "1986", + pages = "51--58", + organization ="Association for Computing Machinery", + address = "New York, {NY}, {USA}", + month = apr, +} + +@Book{Baecker:HFT90, + author = "Ronald Baecker and Aaron Marcus", + title = "Human Factors and Typography for More Readable + Programs", + publisher = pub-AW, + year = "1990", + ISBN = "0-201-10745-7", + address = pub-AW:adr, +} + +@Article{Becker:TB7-2-109, + author = "Helmut Becker", + title = "{{\WEB{} system extensions}}", + journal = j-TUGboat, + year = "1986", + volume = "7", + number = "2", + pages = "109", + month = Jun, +} + +@Article{Ben-Ari:j-SPE-16-10-915, + author = "Mordechai Ben-Ari", + title = "{FOREET}: {A} Tool for Design and Documentation of + Fortran Programs", + journal = j-SPE, + volume = "16", + number = "10", + year = "1986", + pages = "915--924", + acknowledgement = ack-eg, +} + +@Article{Bentley:CACM-29-5-364, + author = "Jon Bentley", + title = "Programming Pearls\emdash{}Literate Programming", + journal = j-CACM, + year = "1986", + volume = "29", + number = "5", + pages = "364--369", + month = may, +} + +@Article{Bentley:CACM-29-6-471, + author = "Jon Bentley and Donald E. Knuth and Doug McIlroy", + title = "Programming Pearls\emdash{}A Literate Program", + journal = j-CACM, + year = "1986", + volume = "29", + number = "6", + pages = "471--483", + month = jun, +} + +@Article{Bentley:CACM-30-4-284, + author = "Jon Bentley and David Gries", + title = "Programming Pearls\emdash{}Abstract data types", + journal = j-CACM, + year = "1987", + volume = "30", + number = "4", + pages = "284--290", + month = apr, +} + +@Article{Bishop:SP-13-1-23, + author = "Judy M. Bishop and Kevin M. Gregson", + title = "Literate Programming and the {LIPED} Environment", + journal = j-SP, + year = "1992", + volume = "13", + number = "1", + pages = "23--34", + acknowledgement = ack-bnb # " and " # ack-pt, +} + +@TechReport{Briggs:NUWEB-93, + author = "Preston Briggs", + title = "Nuweb, {A} Simple Literate Programming Tool", + institution = "Rice University", + year = "1993", + type = "\path|cs.rice.edu:/public/preston|", + address = "Houston, TX", + acknowledgement = ack-bc, + bibdate = "Mon Oct 4 17:27:43 1993", +} + +@Phdthesis{Brown:lit-prog-thesis, + author = "Marcus E. Brown", + title = "An Interactive Environment for Literate Programming", + school = "Texas A\&M University", + address = "College Station, TX", + year = "1988", + month = aug, +} + +@InProceedings{Brown:PCE90-548, + author = "Marcus E. Brown and David Cordes", + title = "A Literate Programming Design Language", + booktitle = "Proc. Comp. Euro 90, IEEE International Conference", + year = "1990", + pages = "548--549", + publisher = pub-IEEE-CSP, + address = "Los Alamitos, CA", +} + +@Article{Brown:SP-11-1-11, + author = "Marcus E. Brown and Bart Childs", + title = "An Interactive Environment for Literate Programming", + journal = j-SP, + year = "1990", + volume = "11", + number = "1", + pages = "11--25", +} + +@Article{Brown:SP-11-2-85, + author = "Marcus E. Brown and David Cordes", + title = "Literate Programming Applied to Conventional + Software Design", + journal = j-SP, + year = "1990", + volume = "11", + number = "2", + pages = "85--98", +} + +@Article{Brown:j-LNCS-468-250, + author = "Marcus Brown", + title = "A Hypertext for Literate Programming", + journal = j-LNCS, + volume = "468", + year = "1990", + pages = "250--259", + acknowledgement = ack-eg, +} + +@Article{Childs:TB-13-3-261, + author = "Bart Childs", + title = "Literate Programming, {A} Practitioner's View", + journal = j-TUGboat, + year = "1992", + volume = "13", + number = "3", + pages = "261--268", + month = oct, + acknowledgement = ack-bc, + bibdate = "Mon Oct 4 17:21:07 1993", +} + +@TechReport{Childs:LP92, + author = "Bart Childs", + title = "An Introduction to the {WEB} Style of Literate + Programming", + institution = "Texas A\&M University", + year = "1992", + type = "\path|ftp.cs.tamu.edu:/pub/tex-web/web/DOCs|", + address = "College Station, TX", + acknowledgement = ack-bc, + bibdate = "Mon Oct 4 17:21:07 1993", +} + +@TechReport{Childs:LP93, + author = "Bart Childs", + title = "{GNU} Emacs Reference Card (with web-mode)", + institution = "Texas A\&M University", + year = "1993", + type = "\path|ftp.cs.tamu.edu:/pub/tex-web/web/DOCs|", + address = "College Station, TX", + acknowledgement = ack-bc, + bibdate = "Mon Oct 4 17:21:07 1993", +} + +@Article{Cordes:COMPUTER-24-6-52, + author = "David Cordes and Marcus Brown", + title = "The Literate-Programming Paradigm", + journal = j-COMPUTER, + year = "1991", + volume = "24", + number = "6", + pages = "52--61", + month = jun, +} + +@Article{Denning:CACM-30-7-593, + author = "Peter J. Denning", + title = "Announcing Literate Programming", + journal = j-CACM, + year = "1987", + volume = "30", + number = "7", + pages = "593", + month = jul, +} + +@Article{Fox:TB11-4-511-513, + author = "Jim Fox", + title = "{{Webless literate programming}}", + journal = j-TUGboat, + year = "1990", + volume = "11", + number = "4", + pages = "511--513", + month = Nov, +} + +@Article{Guntermann:TB7-3-134-2, + author = "Klaus Guntermann and Joachim Schrod", + title = "{{\WEB\ adapted to C}}", + journal = j-TUGboat, + year = "1986", + volume = "7", + number = "3", + pages = "134--137", + month = Oct, +} + +@Article{Gurari:ACMCSC-94-1991, + author = "Eitan M. Gurari and Jesse Wu", + title = "A {WYSIWYG} Literate Programming System (Preliminary + Report)", + journal = "Nineteenth ACM Computer Science Conference", + year = "1991", + pages = "94--104", + acknowledgement = ack-eg, +} + +@Book{Gurari:TLD94, + author = "Eitan M. Gurari", + title = "{\TeX} and {\LaTeX}: Drawing and Literate + Programming", + publisher = pub-MH, + ISBN = "0-07-025208-4", + LCCN = "Z253.4.T47G87, 686.2'2544536-dc20, 93-8603 CIP", + year = "1994", + price = "US\$34.95", + address = pub-MH:adr, + bibdate = "Wed Sep 29 17:55:14 1993", + acknowledgement = ack-nhfb, +} + +@Article{Hamilton:CACM-31-12-1376, + author = "Eric Hamilton", + title = "Literate Programming\emdash{}Expanding Generalized + Regular Expressions", + journal = j-CACM, + year = "1988", + volume = "31", + number = "12", + pages = "1376--1385", + month = dec, +} + +@Article{Hanson:CACM-30-7-594, + author = "David R. Hanson", + title = "Literate Programming\emdash{}Printing Common Words", + journal = j-CACM, + year = "1987", + volume = "30", + number = "7", + pages = "594--599", + month = jul, +} + +@Book{Holub:CDC90, + author = "Allen I. Holub", + title = "Compiler Design in {C}", + publisher = pub-PH, + year = "1990", + note = pub-PH # " Software Series, Editor: Brian W. Kernighan.", + ISBN = "0-13-155045-4", +} + +@Article{Hyman:COMPLANG-7-7-67, + author = "Marco S. Hyman", + title = "Literate {C++}", + journal = j-COMPLANG, + year = "1990", + volume = "7", + number = "7", + pages = "67--79", + month = jul, +} + +@Article{Jackson:CACM-30-12-1000, + author = "Michael A. Jackson", + title = "Literate Programming\emdash{}Processing Transactions", + journal = j-CACM, + year = "1987", + volume = "30", + number = "12", + pages = "1000--1010", + month = dec, +} + +@Article{Kennedy:TB9-2-124-125, + author = "David Kennedy", + title = "{{\TeX\ adapted to \CWEB{}}}", + journal = j-TUGboat, + year = "1988", + volume = "9", + number = "2", + pages = "124--125", + month = Aug, +} + +@Article{Knuth:CJ-27-2-97, + author = "Donald E. Knuth", + title = "Literate Programming", + journal = j-CJ, + year = "1984", + volume = "27", + number = "2", + pages = "97--111", + month = may, +} + +@Book{Knuth:CSS93, + author = "Donald E. Knuth and Silvio Levy", + title = "The {CWEB} System of Structured Documentation, Version + 3.0", + publisher = pub-AW, + year = "1993", + ISBN = "0-201-57569-8", + LCCN = "QA76.9.D3 K6 1993", + address = pub-AW:adr, + acknowledgement = ack-nhfb, + bibdate = "Thu Dec 16 09:04:49 1993", +} + +@Book{Knuth:LP92, + author = "Donald E. Knuth", + title = "Literate Programming", + publisher = pub-SUCSLI, + address = pub-SUCSLI:adr, + series = "CSLI Lecture Notes Number 27", + year = "1992", + ISBN = "0-937-07380-6 (paper), 0-937-07381-4 (cloth)", + LCCN = "QA76.6.K644", + pages = "xv + 368", + acknowledgement = ack-nhfb, +} + +@Article{Knuth:TB12-2-313, + author = "Donald Knuth", + title = "{{Fixed-point glue setting: Errata}}", + journal = j-TUGboat, + year = "1991", + volume = "12", + number = "2", + pages = "313", + month = Jun, +} + +@Article{Knuth:TB3-1-10, + author = "Donald Knuth", + title = "{{Fixed-point glue setting\emdash{}an example of {\tt + WEB}}}", + journal = j-TUGboat, + year = "1982", + volume = "3", + number = "1", + pages = "10", + month = Mar, +} + +@Techreport{Knuth:web83, + author = "Donald E. Knuth", + title = "The {\WEB{}} System of Structured Documentation", + institution = "Stanford University", + year = "1983", + type = "Stanford Computer Science Report", + number = "{CS}980", + address = "Stanford, {CA}", + month = sep, +} + +@Book{Knuth:SGB94, + author = "Donald E. Knuth", + title = "The Stanford GraphBase: {A} Platform for Combinatorial + Computing", + publisher = pub-ACM, + year = "1994", + address = pub-ACM:adr, + price = "US\$45.25", + bibdate = "Sat Oct 2 11:47:55 1993", + note = "[From the publisher]: \ldots{} represents Knuth's + final preparation for Volume 4 of {\em The Art of + Computer Programming}. Through the use of about 30 + examples, the book demonstrates the art of literate + programming. Each example is a programmatic essay, a + short story that can be read by human beings, as well + as read and interpreted by machines. In these + essays/programs, Knuth makes new contributions to the + exposition of several important algorithms and data + structures.", + acknowledgement = ack-pb, +} + +@Article{Krommes:fortran-web, + author = "John Krommes", + title = "{\FWEB} ({Krommes}) vs. {\FWEB} ({Avenarius} and + {Oppermann})", + journal = j-TEXHAX, + year = "1990", + volume = "90", + number = "19", + month = feb, +} + +@Article{Lecarme:j-ACM-COMPREV-26-1-75, + author = "O. Lecarme", + title = "Literate Programming", + journal = j-ACM-COMPREV, + volume = "26", + number = "1", + year = "1985", + pages = "75", + acknowledgement = ack-eg, +} + +@Article{Levy:TB8-1-12, + author = "Silvio Levy", + title = "{{\WEB{} adapted to C, another approach}}", + journal = j-TUGboat, + year = "1987", + volume = "8", + number = "1", + pages = "12--13", + month = Apr, +} + +@Article{Levy:j-COMPLANG-10-1-67, + author = "Silvio Levy", + title = "Literate Programming and Cweb", + journal = j-COMPLANG, + year = "1993", + volume = "10", + number = "1", + pages = "67--68, 70", + month = jan, + bibdate = "Thu Dec 3 09:11:03 1992", +} + +@Article{Lindsay:CACM-32-6-740, + author = "Donald C. Lindsay", + title = "Literate Programming\emdash{}A File Difference Program", + journal = j-CACM, + year = "1989", + volume = "32", + number = "6", + pages = "740--755", + month = jun, +} + +@Article{Lins:JSP-10-1-60, + author = "Charles Lins", + title = "A First Look at Literate Programming", + journal = j-SP, + year = "1989", + volume = "10", + number = "1", + pages = "60--62", +} + +@Article{Lins:JSP-10-2-107, + author = "Charles Lins", + title = "An Introduction to Literate Programming", + journal = j-SP, + year = "1989", + volume = "10", + number = "2", + pages = "107--112", +} + +@Article{Mittelbach:j-TUGboat-9-3-298, + author = "Frank Mittelbach", + title = "A New Implementation of the Array- and Tabular- + Environments", + journal = j-TUGboat, + volume = "9", + number = "3", + year = "1988", + pages = "298--314", + acknowledgement = ack-eg, +} + +@PhdThesis{Motl:LPE90, + author = "Mark B. Motl", + title = "A Literate Programming Environment Based on an + Extensible Editor", + school = "Texas A\&M University", + year = "1990", + address = "College Station, {TX}", + month = dec, + acknowledgement = ack-bc, + bibdate = "Mon Oct 4 17:21:07 1993", +} + +@TechReport{Motl:UMG91, + author = "Mark B. Motl and Bart Childs", + title = "A User's Manual for {GNU} Emacs' Web-mode", + institution = "Texas A\&M University", + year = "1991", + type = "\path|ftp.cs.tamu.edu:/pub/tex-web/web/DOCs|", + address = "College Station, {TX}", + acknowledgement = ack-bc, + bibdate = "Mon Oct 4 17:21:07 1993", +} + +@Article{Oman:CACM-33-5-506, + author = "Paul W. Oman and Curtis Cook", + title = "Typographic Style is More than Cosmetic", + journal = j-CACM, + year = "1990", + volume = "33", + number = "5", + pages = "506--520", + month = may, +} + +@Article{Oman:IEEESOFTWARE-7-1-39, + author = "Paul W. Oman and Curtis Cook", + title = "The Book Paradigm for Improved Maintenance", + journal = j-IEEE-SOFTWARE, + year = "1990", + volume = "7", + number = "1", + pages = "39--45", + month = jan, +} + +@Phdthesis{Oman:oman88a, + author = "Paul W. Oman", + title = "A Taxonomic Analysis of Typographic Programming Style", + school = "Oregon State University", + year = "1988", + address = "Corvallis, {OR}", + month = dec, +} + +@Techreport{Oman:OSUTR-88-60-20, + author = "Paul W. Oman and Curtis Cook", + title = "A Programming Style Taxonomy", + institution = "Oregon State University", + year = "1988", + type = "Technical Report", + number = "88-60-20", + address = "Corvallis, {OR}", +} + +@Article{Oman:SIGPLAN-23-12-69, + author = "Paul W. Oman and Curtis Cook", + title = "A Paradigm for Programming Style Research", + journal = j-SIGPLAN, + year = "1988", + volume = "23", + number = "12", + pages = "69--78", + month = dec, +} + +@InProceedings{Pappas:proc-ada-tech90-500, + author = "T. L. Pappas", + title = "Literate Programming for Reusability: {A} Queue + Package Example", + booktitle = "Proceedings of the Eighth Annual Conference on Ada + Technology", + year = "1990", + pages = "500--514", + organization = "ANCOST, Inc. (Sponsor)", + address = "Atlanta, Georgia, USA", + month = mar, + review = "This paper begins with a set of guidelines for writing + and documenting reusable Ada software. {\tt AdaWeb}, a + literate programming system combining Ada and {\TeX} is + described. A sample {\tt AdaWeb} package, {\em Bounded + Generic Queue Package}, is provided. Features of {\tt + AdaWeb} are explained as they are used in the literate + program.", +} + +@Book{PeytonJones:IFL92, + author = "Simon L. {Peyton Jones} and David R. Lester", + title = "Implementing functional languages", + publisher = pub-PH, + year = "1992", + address = pub-PH:adr, + ISBN = "0-13-721952-0", + price = "US\$42.00", + acknowledgement = ack-dl, + bibdate = "Thu Aug 26 10:51:16 1993", + note = "Presents literate programs in {\TeX} and Miranda.", +} + +@Book{Plauger:SCL92, + author = "P. J. Plauger", + title = "The {Standard C} Library", + publisher = pub-PH, + year = "1992", + ISBN = "0-13-838012-0", +} + +@Article{Ramsdell:TEXHAX-88-39, + author = "J. D. Ramsdell", + title = "Scheme{\TeX}{}\emdash{}Simple support for literate + programming in Lisp", + journal = j-TEXHAX, + year = "1988", + volume = "88", + number = "39", + month = apr, +} + +@Article{Ramsey:CACM-32-9-1051, + author = "Norman Ramsey", + title = "Weaving a Language-Independent {{\WEB}}", + journal = j-CACM, + year = "1989", + volume = "32", + number = "9", + pages = "1051--1055", + month = sep, +} + +@Article{Ramsey:j-SPE-21-7-677, + author = "Norman Ramsey and Carla Marceau", + title = "Literate Programming on a Team Project", + journal = j-SPE, + year = "1991", + volume = "21", + number = "7", + pages = "677-683", + month = jul, + acknowledgement = ack-bnb, +} + +@TechReport{Ramsey:LPT92, + author = "Norman Ramsey", + title = "Literate-Programming Tools Need Not Be Complex", + institution = "Department of Computer Science, Princeton University", + year = "1992", + number = "CS-TR-351-91", + keywords = "literate programming, readability, programming languages", + month = aug, + note = "Submitted to {\em IEEE Software}.", + type = "Report at \path|ftp.cs.princeton.edu| in + \path|/reports/1991/351.ps.Z|. Software at + \path|ftp.cs.princeton.edu| in + \path|/pub/noweb.shar.Z| and at \path|bellcore.com| + in \path|/pub/norman/noweb.shar.Z|.", + bibdate = "Tue Oct 12 10:28:45 1993", + acknowledgement = ack-bc # " and " # ack-nr, +} + +@InProceedings{Reenskaug:OOPSLA89-337, + author = "Trygve Reenskaug and Anne Lise Skaar", + title = "An Environment for Literate Smalltalk Programming", + booktitle = "OOPSLA'89 Proceedings", + year = "1989", + pages = "337--345", + abstract = "The programming environment described in this + paper is an adaptation of Donald Knuth's concept + of literate programming, applied to Smalltalk + programs. The environment provides a multi-media + document production system including media for + Smalltalk class and method definitions.\par There + are two outputs from the system. The first output + is a document which contains general descriptions + and discussions intermixed with precise + definitions of program fragments, test inputs and + test results. The second output consists of + compiled Smalltalk programs installed and ready + for execution.\par The main idea was to produce + program documentation that was just as + interesting and fascinating to read as ordinary + literature. Our experience showed an added + benefit, namely that the literate programming + environment was an active aid in the problem + solving process. The simultaneous programming and + documentation lead to significantly improved + quality of both programs and documentation.", +} + +@Article{Sametinger:j-OOP-4-8-24, + author = "J. Sametinger", + title = "A Hypertext System for Literate {C}++ Programming", + journal = j-OOP, + volume = "4", + number = "8", + year = "1992", + pages = "24--29", + acknowledgement = ack-eg, +} + +@Article{Sewell:TB8-2-118, + author = "E. Wayne Sewell", + title = "{{How to {\tt MANGLE} your software: the \WEB{} + system for Modula-2}}", + journal = j-TUGboat, + year = "1987", + volume = "8", + number = "2", + pages = "118--122", + month = Jul, +} + +@Article{Sewell:TB8-2-123, + author = "E. Wayne Sewell", + title = "{{The {\tt SCANTEX} processor}}", + journal = j-TUGboat, + year = "1987", + volume = "8", + number = "2", + pages = "123--128", + month = Jul, +} + +@Book{Sewell:WPL89, + author = "E. Wayne Sewell", + title = "Weaving a Program: Literate Programming in {\WEB}", + publisher = pub-VNR, + address = pub-VNR:adr, + year = "1989", + ISBN = "0-442-31946-0", +} + +@Article{Shum:SEJ-8-3-113, + author = "Stephen Shum and Curtis Cook", + title = "{AOPS}: an Abstraction-Oriented Programming System for + Literate Programming", + journal = j-SEJ, + year = "1993", + volume = "8", + number = "3", + pages = "113--120", + month = may, + acknowledgement = ack-ma, +} + +@Article{Smith:SP-13-1-35, + author = "Lisa M. Smith and Mansur H. Samadzadeh", + title = "Measuring Complexity and Stability of {WEB} programs", + journal = j-SP, + year = "1992", + volume = "13", + number = "1", + pages = "35--50", + acknowledgement = ack-pt, +} + +@Book{Spivak:LTW91, + author = "Michael D. Spivak", + title = "The {\LAMSTeX} Wizard's Manual", + publisher = pub-TEXPLORATOR, + address = pub-TEXPLORATOR:adr, + year = "1991", +} + +@Article{Thimbleby:CJ-29-3-201, + author = "Harold Thimbleby", + title = "Experiences of `Literate Programming' using + {{\tt cweb}} (a variant of {K}nuth's {\WEB{}})", + journal = j-CJ, + year = "1986", + volume = "29", + number = "3", + pages = "201--211", + month = jun, +} + +@TechReport{Thimbleby:cwebman, + author = "Harold W. Thimbleby", + title = "Literate Programming in C", + institution = "University of York", + address = "Department of Computer Science, University of York, + Heslington, York YO1 5DD, England", + year = "1984", + abstract = "{\bf Cweb} is a system of structured + documentation based of Knuth's {\tt WEB}. The + philosophy behind both {\bf cweb} and {\tt WEB} + is that an experienced programmer, who wants to + provide the best possible documentation of his or + her software products, needs two things + simultaneously: a language for formatting and a + language for programming. When both are + appropriately combined we obtain a system much + more useful than either language separately. + {\bf Cweb} combines {\bf C} source with ({\bf + di}){\bf troff} (or {\bf nroff}) documentation + (whereas {\tt WEB} operates with Pascal and + \TeX). The full facilities of {\bf C} and {\bf + troff} are available to the user.\par {\bf Cweb} + operates effectively with existing Unix text and + program development tools, such as {\bf make}, + {\bf tbl}, {\bf eqn}. If speed is important, {\bf + cweb} has a built-in formatter which is much + faster (and less resource consuming) the {\bf + troff} for drafting or using with a lineprinter.", +} + +@Article{Tung:JSP-10-2-113, + author = "{Sho-Huan} Tung", + title = "A Structured Method for Literate Programming", + journal = j-SP, + year = "1989", + volume = "10", + number = "2", + pages = "113--120", +} + +@InProceedings{vanAmmers:ECC92-371, + author = "Eric W. van Ammers and Mark R. Kramer", + title = "{VAMP}: {A} Tool for Literate Programming Independent + of Programming Language and Formatter", + booktitle = "Proceedings of the 6th Annual European Computer + Conference CompEuro'92", + year = "1992", + pages = "371--376", + month = may # " 4--8", + bibdate = "Mon Feb 8 09:15:57 1993", +} + +@Article{VandenBosch:j-ACM-COMPREV-31-7-343, + author = "P. N. Van den Bosch", + title = "Weaving a Program: Literate Programming in {WEB}", + journal = j-ACM-COMPREV, + volume = "31", + number = "7", + year = "1990", + pages = "343--344", + acknowledgement = ack-eg, +} + +@Article{VanWyk:CACM-33-3-361, + author = "Christopher J. {Van Wyk}", + title = "Literate Programming\emdash{}An Assessment", + journal = j-CACM, + year = "1990", + volume = "33", + number = "3", + pages = "361, 365", + month = mar, +} + +@Article{Waite:SIGPLAN-28-2-21, + author = "W. M. Waite", + title = "An Executable Language Definition", + journal = j-SIGPLAN, + year = "1993", + volume = "28", + number = "2", + pages = "21--40", + month = feb, + note = "This paper describes a subset of C, called C--, + defined as a literate program using the Eli and + FunnelWeb systems.", + bibdate = "Tue Mar 9 17:51:21 1993", + acknowledgement = ack-nhfb, +} + +@TechReport{Williams:FUM92, + author = "Ross Williams", + title = "FunnelWeb User's Manual", + institution = "University of Adelaide", + year = "1992", + type = "\path|ftp.adelaide.edu.au| in \path|/pub/compression| + and \path|/pub/funnelweb|", + address = "Adelaide, South Australia, Australia", + acknowledgement = ack-bc, + bibdate = "Mon Oct 4 17:25:40 1993", +} + +@Article{Wu:J-ACM-ADALET-9-5-84, + author = "Y. C. Wu and Ted P. Baker", + title = "A Source Code Documentation System for Ada", + journal = j-ACM-ADALET, + volume = "9", + number = "5", + year = "1989", + pages = "84--88", + acknowledgement = ack-eg, +} diff --git a/main.c b/main.c new file mode 100644 index 0000000..7c50281 --- /dev/null +++ b/main.c @@ -0,0 +1,211 @@ +#include "global.h" + +#include <stdlib.h> +int main(argc, argv) + int argc; + char **argv; +{ + int arg = 1; + /* Interpret command-line arguments */ + command_name = argv[0]; + while (arg < argc) { + char *s = argv[arg]; + if (*s++ == '-') { + /* Interpret the argument string \verb|s| */ + { + char c = *s++; + while (c) { + switch (c) { + case 'c': compare_flag = FALSE; + break; + case 'd': dangling_flag = TRUE; + break; + case 'h': hyperopt_flag = TRUE; + goto HasValue; + case 'I': includepath_flag = TRUE; + goto HasValue; + case 'l': listings_flag = TRUE; + break; + case 'n': number_flag = TRUE; + break; + case 'o': output_flag = FALSE; + break; + case 'p': prepend_flag = TRUE; + goto HasValue; + case 'r': hyperref_flag = TRUE; + break; + case 's': scrap_flag = FALSE; + break; + case 't': tex_flag = FALSE; + break; + case 'v': verbose_flag = TRUE; + break; + case 'V': version_info_flag = TRUE; + goto HasValue; + case 'x': xref_flag = TRUE; + break; + default: fprintf(stderr, "%s: unexpected argument ignored. ", + command_name); + fprintf(stderr, "Usage is: %s [-cdnostvx] " + "[-I path] [-V version] " + "[-h options] [-p path] file...\n", + command_name); + break; + } + c = *s++; + } +HasValue:; + } + arg++; + /* Perhaps get the prepend path */ + if (prepend_flag) + { + if (*s == '\0') + s = argv[arg++]; + dirpath = s; + prepend_flag = FALSE; + } + + /* Perhaps get the version info string */ + if (version_info_flag) + { + if (*s == '\0') + s = argv[arg++]; + version_string = s; + version_info_flag = FALSE; + } + + /* Perhaps get the hyperref options */ + if (hyperopt_flag) + { + if (*s == '\0') + s = argv[arg++]; + hyperoptions = s; + hyperopt_flag = FALSE; + hyperref_flag = TRUE; + } + + /* Perhaps add an include path */ + if (includepath_flag) + { + struct incl * le + = (struct incl *)arena_getmem(sizeof(struct incl)); + struct incl ** p = &include_list; + + if (*s == '\0') + s = argv[arg++]; + le->name = save_string(s); + le->next = NULL; + while (*p != NULL) + p = &((*p)->next); + *p = le; + includepath_flag = FALSE; + } + + } + else break; + } + /* Set locale information */ + + { + /* try to get locale information */ + char *s=getenv("LC_CTYPE"); + if (s==NULL) s=getenv("LC_ALL"); + + /* set it */ + if (s!=NULL) + if(setlocale(LC_CTYPE, s)==NULL) + fprintf(stderr, "Setting locale failed\n"); + } + + initialise_delimit_scrap_array(); + /* Process the remaining arguments (file names) */ + { + if (arg >= argc) { + fprintf(stderr, "%s: expected a file name. ", command_name); + fprintf(stderr, "Usage is: %s [-cnotv] [-p path] file-name...\n", command_name); + exit(-1); + } + do { + /* Handle the file name in \verb|argv[arg]| */ + { + char source_name[FILENAME_MAX]; + char tex_name[FILENAME_MAX]; + char aux_name[FILENAME_MAX]; + /* Build \verb|source_name| and \verb|tex_name| */ + { + char *p = argv[arg]; + char *q = source_name; + char *trim = q; + char *dot = NULL; + char c = *p++; + while (c) { + *q++ = c; + if (PATH_SEP(c)) { + trim = q; + dot = NULL; + } + else if (c == '.') + dot = q - 1; + c = *p++; + } + /* Add the source path to the include path list */ + if (trim != source_name) { + struct incl * le + = (struct incl *)arena_getmem(sizeof(struct incl)); + struct incl ** p = &include_list; + char sv = *trim; + + *trim = '\0'; + le->name = save_string(source_name); + le->next = NULL; + while (*p != NULL) + p = &((*p)->next); + *p = le; + *trim = sv; + } + + *q = '\0'; + if (dot) { + *dot = '\0'; /* produce HTML when the file extension is ".hw" */ + html_flag = dot[1] == 'h' && dot[2] == 'w' && dot[3] == '\0'; + sprintf(tex_name, "%s%s%s.tex", dirpath, path_sep, trim); + sprintf(aux_name, "%s%s%s.aux", dirpath, path_sep, trim); + *dot = '.'; + } + else { + sprintf(tex_name, "%s%s%s.tex", dirpath, path_sep, trim); + sprintf(aux_name, "%s%s%s.aux", dirpath, path_sep, trim); + *q++ = '.'; + *q++ = 'w'; + *q = '\0'; + } + } + /* Process a file */ + { + pass1(source_name); + current_sector = 1; + prev_sector = 1; + if (tex_flag) { + if (html_flag) { + int saved_number_flag = number_flag; + number_flag = TRUE; + collect_numbers(aux_name); + write_html(source_name, tex_name, 0/*Dummy */); + number_flag = saved_number_flag; + } + else { + collect_numbers(aux_name); + write_tex(source_name, tex_name); + } + } + if (output_flag) + write_files(file_names); + arena_free(); + } + } + arg++; + } while (arg < argc); + } + exit(0); +} diff --git a/master.bib b/master.bib new file mode 100644 index 0000000..0954e0e --- /dev/null +++ b/master.bib @@ -0,0 +1,10010 @@ +%% /u/sy/beebe/tex/bib/master.bib, Thu Nov 11 09:16:24 1993 +%% Edit by Nelson H. F. Beebe <beebe at plot79.math.utah.edu> +%%% ==================================================================== +%%% BibTeX-file{ +%%% author = "Nelson H. F. Beebe", +%%% version = "1.182", +%%% date = "06 April 1994", +%%% time = "23:52:12 MDT", +%%% filename = "master.bib", +%%% address = "Center for Scientific Computing +%%% Department of Mathematics +%%% University of Utah +%%% Salt Lake City, UT 84112 +%%% USA", +%%% telephone = "+1 801 581 5254", +%%% FAX = "+1 801 581 4148", +%%% checksum = "56856 10011 37289 315774", +%%% email = "beebe at math.utah.edu (Internet)", +%%% codetable = "ISO/ASCII", +%%% keywords = "bibliography", +%%% supported = "yes", +%%% docstring = "BibTeX bibliography for NHFB's personal +%%% collection of books and miscellaneous +%%% references. +%%% +%%% Citation tags should be chosen as +%%% "FirstAuthor:key-phrase", with the +%%% FirstAuthor capitalized (all caps if an +%%% acronym), and the key-phrase a (possibly +%%% hyphenated) phrase in lower case taken from +%%% the title. Normally, the key-phrase should +%%% be constructed from the initial letters of +%%% the first three capitalized names in the +%%% title, ignoring articles and prepositions, +%%% followed by the last two digits of the year +%%% of publication. +%%% +%%% Internet addresses and filenames should be +%%% entered with the \path macro, for example, +%%% \path|rms at prep.ai.mit.edu|. +%%% +%%% Em dashes in titles should use the control +%%% sequence \emdash, which allows line +%%% breaking on either side. +%%% +%%% Oren Patashnik recommends against using +%%% ties (~) ANYWHERE in the bibliography; +%%% BibTeX puts them in where needed. +%%% +%%% Journals should always be named using a +%%% string definition of the form j-XYZ. +%%% +%%% Publishers should similarly be named with a +%%% string definition of the form pub-XYZ, and +%%% their addresses in the form pub-XYZ:adr. +%%% +%%% Built-in BibTeX journal names should be +%%% avoided. +%%% +%%% The checksum field above contains a CRC-16 +%%% checksum as the first value, followed by the +%%% equivalent of the standard UNIX wc (word +%%% count) utility output of lines, words, and +%%% characters. This is produced by Robert +%%% Solovay's checksum utility." +%%% } +%%% ==================================================================== + +%% This handy macro allows |prep.ai.mit.edu| to (1) be set in typewriter +%% text, and (2) get automatically inserted discretionary hyphens to +%% make linebreaks at periods, slashes, and at-sign. It can be used for +%% mail addresses and UNIX filenames. If you need a literal | in the +%% text, write it as \|. + +@Preamble{"\input bibnames.sty " + # "\hyphenation{Kath-ryn Ker-n-i-ghan Krom-mes Lar-ra-bee Pat-rick + Port-able Post-Script Pren-tice Rich-ard Ro-bert Richt-er Sha-mos + Spring-er The-o-dore Uz-ga-lis} " +} + +%% NB: TeX normally will not hyphenate words connected by a dash, and +%% will normally allow a line break only after such a dash, not before. +%% However, style guides show examples of the em dash starting a line, +%% so a break before is probably okay. I have been unable to get TeX to +%% hyphenate automatically after an \emdash (either the macro, or ---), +%% so I have inserted explicit discretionary hyphens after such cases. + +@String{ack-nhfb = "Nelson H. F. Beebe, + Center for Scientific Computing, + Department of Mathematics, + University of Utah, + Salt Lake City, UT 84112, USA, + Tel: +1 801 581 5254, + FAX: +1 801 581 4148, + e-mail: \path|beebe@math.utah.edu|"} + +%% Some standard journal and publisher abbreviations... + +@String{j-BSTJ = "The Bell System Technical Journal"} +@String{j-CACM = "Communications of the Association for Computing + Machinery"} +@String{j-CBM = "Computers in Biology and Medicine"} +@String{j-CGIP = "Computer Graphics and Image Processing"} +@String{j-CJ = "The Computer Journal"} +@String{j-COMPCON-SPRING89 = "Digest of Papers of {COMPCON} Spring `89"} +@String{j-COMPLANG = "Computer Language"} +@String{j-COMPUTER = "Computer"} +@String{j-CS = "Computing Surveys"} +@String{j-DDJ = "Dr. Dobb's Journal"} +@String{j-GUTENBERG = "Cahiers GUTenberg"} +@String{j-IBM-JRD = "IBM J. Res. Develop."} +@String{j-IEEE-MICRO = "IEEE Micro"} +@String{j-IJSA = "International Journal of Supercomputer + Applications"} +@String{j-PROC-SID = "Proceedings of the Society for Information + Display"} +@String{j-SA = "Scientific American"} +@String{j-SIAM-J-COMP = "SIAM Journal of Computing"} +@String{j-SIGGRAPH = "ACM SIG{\-}GRAPH\emdash Com{\-}puter Graphics"} +@String{j-SIGPLAN = "ACM SIG{\-}PLAN Notices"} +@String{j-SPE = "Soft{\-}ware\emdash Prac{\-}tice and Experience"} +@String{j-SR = "Supercomputing Review"} +@String{j-SUNEXPERT = "SunExpert"} +@String{j-TEXHAX = "{\TeX{}{\-}hax}"} +@String{j-TEXNIQUES = "{\TeX}niques"} +@String{j-TOGS = "ACM Transactions on Graphics"} +@String{j-TUGboat = "{\TUB{}}"} +@String{j-USENIX-SCP = "{USENIX} Summer Conference Proceedings"} + +@String{pub-AAK = "Alfred A. Knopf"} +@String{pub-AAK:adr = "New York, NY, USA"} +@String{pub-ACM = "ACM Press"} +@String{pub-ACM:adr = "New York, NY 10036, USA"} +@String{pub-ADOBE = "{Adobe Systems Incorporated}"} +@String{pub-ADOBE:adr = "1585 Charleston Road, P.~O. Box 7900, Mountain + View, CA 94039-7900, USA, Tel: (415) 961-4400"} +@String{pub-AH = "Adam Hilger Ltd."} +@String{pub-AH:adr = "Bristol, UK"} +@String{pub-AMS = "American Mathematical Society"} +@String{pub-AMS:adr = "Providence, RI, USA"} +@String{pub-ANL = "Argonne National Laboratory"} +@String{pub-ANL:adr = "Argonne, IL, USA"} +@String{pub-ANSI = "American National Standards Institute"} +@String{pub-ANSI:adr = "1430 Broadway, New York, NY 10018, USA"} +@String{pub-AP = "Academic Press"} +@String{pub-AP:adr = "New York, NY, USA"} +@String{pub-ATT-BELL = "AT\&T Bell Laboratories"} +@String{pub-ATT-BELL:adr = "Murray Hill, NJ, USA"} +@String{pub-AW = "Ad{\-d}i{\-s}on-Wes{\-l}ey"} +@String{pub-AW:adr = "Reading, MA, USA"} +@String{pub-AWE = "Ad{\-}di{\-}son-Wes{\-}ley Europe"} +@String{pub-AWE:adr = "Amsterdam, The Netherlands"} +@String{pub-BANTAM = "Bantam Books"} +@String{pub-BANTAM:adr = "New York, NY, USA"} +@String{pub-BB = "Berkeley Books"} +@String{pub-BB:adr = "New York"} +@String{pub-BC = "Brooks\slash Cole"} +@String{pub-BC:adr = "Pacific Grove, CA, USA"} +@String{pub-BENCUM = "Benjamin/Cummings Pub. Co."} +@String{pub-BENCUM:adr = "Redwood City, CA, USA"} +@String{pub-BH = "Birkh{\"{a}}user"} +@String{pub-BH:adr = "Boston, MA, USA"} +@String{pub-BN = "Barnes and Noble"} +@String{pub-BN:adr = "New York, NY, USA"} +@String{pub-BOWK = "R. R. Bowker Company"} +@String{pub-BOWK:adr = "1180 Avenue of the Americas, New York, NY + 10036, USA"} +@String{pub-BRADY = "Robert J. Brady Co."} +@String{pub-BRADY:adr = "Bowie, MD 20715, USA"} +@String{pub-CBI = "Contemporary Books, Inc."} +@String{pub-CBI:adr = "180 North Michigan Avenue, Chicago, IL 60601, + USA"} +@String{pub-CBM = "CBM Books"} +@String{pub-CBM:adr = "A Division of Cardinal Business Media Inc., + 101 Witmer Road, Horsham, PA 19044, USA"} +@String{pub-CHARTWELL = "Chartwell Books, Inc."} +@String{pub-CHARTWELL:adr = "110 Enterprise Avenue, Secaucus, NJ 07094, USA"} +@String{pub-CIAOCO = "Editions Ciaoco"} +@String{pub-CIAOCO:adr = "Artel, Bruxelles, Belgium"} +@String{pub-CIPS = "Canadian Information Processing Society"} +@String{pub-CIPS:adr = "243 College St, 5th Floor, Toronto, Ontario + M5T~2Y1, Canada"} +@String{pub-CLSC = "College of Science Computer"} +@String{pub-CLSC:adr = "Department of Physics, University of Utah, Salt + Lake City, UT 84112, USA"} +@String{pub-COLLIER = "Collier Books, Macmillan Publishing Company"} +@String{pub-COLLIER:adr = "New York, NY, USA"} +@String{pub-COLLMAC = "Collier Macmillan Canada"} +@String{pub-COLLMAC:adr = "Toronto, Ontario, Canada"} +@String{pub-COLUMBIA = "Columbia University Press"} +@String{pub-COLUMBIA:adr = "New York, NY, USA"} +@String{pub-CP = "Clarendon Press"} +@String{pub-CP:adr = "Oxford, UK"} +@String{pub-CRC = "CRC Publishers"} +@String{pub-CRC:adr = "2000 Corporate Blvd., Boca Raton, FL 33431, USA"} +@String{pub-CSP = "Computer Science Press"} +@String{pub-CSP:adr = "11 Taft Court, Rockville, MD 20850, USA"} +@String{pub-CUP = "Cambridge University Press"} +@String{pub-CUP:adr = "Cambridge, UK"} +@String{pub-CWI = "Centrum voor Wiskunde en Informatica"} +@String{pub-CWI:adr = "P. O. Box 4079, 1009 AB Amsterdam, The + Netherlands"} +@String{pub-DOV = "Dover"} +@String{pub-DOV:adr = "New York, NY, USA"} +@String{pub-DP = "Digital Press"} +@String{pub-DP:adr = "12 Crosby Drive, Bedford, MA 01730, USA"} +@String{pub-EH = "Ellis Horwood"} +@String{pub-EH:adr = "New York, NY, USA"} +@String{pub-ELS = "Elsevier"} +@String{pub-ELS:adr = "Amsterdam, The Netherlands"} +@String{pub-FSF = "{Free} {Software} {Foundation}"} +@String{pub-FSF:adr = "675 Mass Ave, Cambridge, MA 02139, USA, + Tel: (617) 876-3296"} +@String{pub-GP = "Graphics Press"} +@String{pub-GP:adr = "Box 430, Cheshire, CT 06410, USA"} +@String{pub-HAYDEN = "Hayden Books"} +@String{pub-HAYDEN:adr = "4300 West 62nd Street, Indianapolis, IN + 46268, USA"} +@String{pub-HBJ = "Harcourt Brace Jovanovich"} +@String{pub-HBJ:adr = "Boston, MA, USA"} +@String{pub-HM = "Houghton Mifflin"} +@String{pub-HM:adr = "Boston, MA, USA"} +@String{pub-HRW = "Holt, Reinhart, and Winston"} +@String{pub-HRW:adr = "New York, NY, USA"} +@String{pub-HWS = "Howard W. Sams"} +@String{pub-HWS:adr = "Indianapolis, IN 46268, USA"} +@String{pub-IBM = "IBM Corporation"} +@String{pub-IBM:adr = "San Jose, CA, USA"} +@String{pub-IE = "InterEditions"} +@String{pub-IE:adr = "Paris, France"} +@String{pub-IEEE = "IEEE Computer Society Press"} +@String{pub-IEEE:adr = "1109 Spring Street, Suite 300, Silver + Spring, MD 20910, USA"} +@String{pub-INTEL = "Intel Corporation"} +@String{pub-INTEL:adr = "Santa Clara, CA, USA"} +@String{pub-ISO = "International Organization for Standardization"} +@String{pub-JH = "The Johns Hopkins University Press"} +@String{pub-JH:adr = "Baltimore, MD, USA"} +@String{pub-JPL = "Jet Propulsion Laboratory"} +@String{pub-JPL:adr = "Pasadena, CA, USA"} +@String{pub-JSA = "Japanese Standards Association"} +@String{pub-JSA:adr = "1-24, Akasaka 4 Chome, Minato-ku, Tokyo, 107 + Japan"} +@String{pub-JW = "John Wiley"} +@String{pub-JW:adr = "New York, NY, USA"} +@String{pub-KLUWER = "Kluwer Academic Publishers Group"} +@String{pub-KLUWER:adr = "Norwell, MA, USA, and Dordrecht, The Netherlands"} +@String{pub-LB = "Little, Brown and Company"} +@String{pub-LB:adr = "Boston, Toronto, London"} +@String{pub-MAC = "Macmillan Publishing Company"} +@String{pub-MAC:adr = "New York, NY, USA"} +@String{pub-MAC-ED = "Macmillan Education Ltd."} +@String{pub-MAC-ED:adr = "Houndmills, Basingstoke, Hampshire RG21 + 2XS, UK"} +@String{pub-MEGATEK = "Megatek Corporation"} +@String{pub-MEGATEK:adr = "9645 Scranton Rd, San Diego, CA 92121, USA"} +@String{pub-MH = "Mc{\-}Graw-Hill"} +@String{pub-MH:adr = "New York, NY, USA"} +@String{pub-MICROSOFT = "Microsoft Press"} +@String{pub-MICROSOFT:adr = "Bellevue, WA, USA"} +@String{pub-MIS = "MIS Press"} +@String{pub-MIS:adr = "P. O. Box 5277, Portland, OR 97208-5277, USA, + Tel: (503) 282-5215"} +@String{pub-MIT = "MIT Press"} +@String{pub-MIT:adr = "Cambridge, MA, USA"} +@String{pub-MK = "Morgan Kaufmann Publishers"} +@String{pub-MK:adr = "Los Altos, CA 94022, USA"} +@String{pub-MK:adrnew = "2929 Campus Drive, Suite 260, San Mateo, + CA 94403, USA"} +@String{pub-MORROW = "William Morrow and Company, Inc."} +@String{pub-MORROW:adr = "New York, NY, USA"} +@String{pub-MOTOROLA = "Motorola Corporation"} +@String{pub-MOTOROLA:adr = "Phoenix, AZ, USA"} +@String{pub-MT = "M\&T Books"} +@String{pub-MT:adr = "M\&T Publishing, Inc., 501 Galveston Drive, + Redwood City, CA 94063, USA"} +@String{pub-NH = "North-Hol{\-}land"} +@String{pub-NH:adr = "Amsterdam, The Netherlands"} +@String{pub-OMH = "Osborne\slash Mc{\-}Graw-Hill"} +@String{pub-OMH:adr = "Berkeley, CA, USA"} +@String{pub-OR = "O'Reilly \& {Associates, Inc.}"} +@String{pub-OR:adr = "981 Chestnut Street, Newton, MA 02164, USA"} +@String{pub-OUP = "Oxford University Press"} +@String{pub-OUP:adr = "Walton Street, Oxford OX2 6DP, UK"} +@String{pub-PEACHPIT = "Peachpit Press, Inc."} +@String{pub-PEACHPIT:adr = "1085 Keith Avenue, Berkeley, CA 94708, USA"} +@String{pub-PH = "Pren{\-}tice-Hall"} +@String{pub-PH:adr = "Englewood Cliffs, NJ 07632, USA"} +@String{pub-PHI = "Pren{\-}tice-Hall International"} +@String{pub-PHI:adr = "Englewood Cliffs, NJ 07632, USA"} +@String{pub-PITMAN = "Pitman Publishing Ltd."} +@String{pub-PITMAN:adr = "London, UK"} +@String{pub-PLUMHALL = "Plum Hall"} +@String{pub-PLUMHALL:adr = "1 Spruce Ave, Cardiff, NJ 08232, USA"} +@String{pub-PPB = "Professional Press Books"} +@String{pub-PPB:adr = "101 Witmer Road, Horsham, PA 19044, USA"} +@String{pub-PTI = "Personal {\TeX} Inc."} +@String{pub-PTI:adr = "12 Madrona Street, Mill Valley, CA 94941, USA"} +@String{pub-PTRPH = "P T R Pren{\-}tice-Hall"} +@String{pub-PTRPH:adr = "Englewood Cliffs, NJ 07632, USA"} +@String{pub-PUP = "Princeton University Press"} +@String{pub-PUP:adr = "Princeton, NJ, USA"} +@String{pub-PW = "Plume\slash Waite"} +@String{pub-PW:adr = "New York, NY, USA"} +@String{pub-REK = "Robert E. Krieger Publishing Company"} +@String{pub-REK:adr = "Huntington, NY, USA"} +@String{pub-RESTON = "Reston Publishing Co. Inc."} +@String{pub-RESTON:adr = "Reston, VA, USA"} +@String{pub-RH = "Random House"} +@String{pub-RH:adr = "New York, NY, USA"} +@String{pub-SERIF = "Serif Publishing"} +@String{pub-SERIF:adr = "A subsidiary of Xerox Corporation, 701 South + Aviation Boulevard, El Segundo, CA 90245, USA"} +@String{pub-SF = "Scott, Foresman and Company"} +@String{pub-SF:adr = "Glenview, IL, USA"} +@String{pub-SIAM = "Society for Industrial and Applied Mathematics"} +@String{pub-SIAM:adr = "Philadelphia, PA, USA"} +@String{pub-SILICON = "Silicon Press"} +@String{pub-SILICON:adr = "25 Beverly Road, Summit, NJ 07901, USA"} +@String{pub-SS = "Simon and Schuster"} +@String{pub-SS:adr = "New York, NY, USA"} +@String{pub-STAN-CS = "Stanford University, Department of Computer + Science"} +@String{pub-STAN-CS:adr = "Stanford, CA, USA"} +@String{pub-STAN-CSL = "Stanford University, Department of Computer + Science"} +@String{pub-STAN-CSL:adr = "Stanford, CA, USA"} +@String{pub-SUCSLI = "Stanford University Center for the Study of + Language and Information"} +@String{pub-SUCSLI:adr = "Stanford, CA, USA"} +@String{pub-SUN = "Sun Microsystems"} +@String{pub-SUN:adr = "2550 Garcia Avenue, Mountain View, CA 94043, USA"} +@String{pub-SV = "Spring{\-}er-Ver{\-}lag"} +@String{pub-SV:adr = "Berlin, Germany~/ Heidelberg, Germany~/ London, + UK~/ etc."} +@String{pub-SYBEX = "Sybex"} +@String{pub-SYBEX:adr = "2021 Challenger Driver, Suite 100, Alameda, + CA 94501, USA"} +@String{pub-TEXPLORATORS = "The {\TeX}plorators Corporation"} +@String{pub-TEXPLORATORS:adr = "3701 W. Alabama, Suite 450-273, + Houston, TX 77027, USA"} +@String{pub-TRILITHON = "Trilithon Press"} +@String{pub-TRILITHON:adr = "Los Altos, CA, USA"} +@String{pub-UCP = "University of California Press"} +@String{pub-UCP:adr = "Berkeley, CA, USA"} +@String{pub-UNIC = "UNI{$\bullet$}C"} +@String{pub-UNIC:adr = "Danmarks EDB-Center for Forskning og Uddannelse, + Copenhagen, Denmark"} +@String{pub-URW = "URW Verlag"} +@String{pub-URW:adr = "Hamburg, Germany"} +@String{pub-USGPO = "United States Government Printing Office"} +@String{pub-USGPO:adr = "Washington, DC, USA"} +@String{pub-USNPS = "U. S. Naval Postgraduate School"} +@String{pub-USNPS:adr = "Monterey, CA 93940, USA"} +@String{pub-USNWL = "U. S. Naval Weapons Laboratory"} +@String{pub-USNWL:adr = "Dahlgren, VA 22448, USA"} +@String{pub-UTP = "University of Texas Press"} +@String{pub-UTP:adr = "Austin, TX, USA"} +@String{pub-VINTAGE = "Vintage Books"} +@String{pub-VINTAGE:adr = "New York, NY, USA"} +@String{pub-VNR = "Van Nostrand Reinhold"} +@String{pub-VNR:adr = "New York, NY, USA"} +@String{pub-W = "Wiley"} +@String{pub-W:adr = "New York, NY, USA"} +@String{pub-WAB = "W. A. {Benjamin, Inc.}"} +@String{pub-WAB:adr = "New York, NY, USA"} +@String{pub-WADSWORTH = "Wadsworth"} +@String{pub-WADSWORTH:adr = "Pacific Grove, CA, USA"} +@String{pub-WEITEK = "Weitek Corporation"} +@String{pub-WEITEK:adr = "1060 E. Arques Ave., Sunnyvale, CA + 94086-BRM-9759, USA"} +@String{pub-WGP = "Wat{\-}son-Gup{\-}till Publications"} +@String{pub-WGP:adr = "1515 Broadway, New York, NY 10036, USA"} +@String{pub-WHF = "W. H. {Freeman and Company}"} +@String{pub-WHF:adr = "New York, NY, USA"} +@String{pub-WI = "Wiley-In{\-}ter{\-}sci{\-}ence"} +@String{pub-WI:adr = "New York, NY, USA"} +@String{pub-WINDCREST = "Windcrest\slash McGraw-Hill"} +@String{pub-WINDCREST:adr = "Blue Ridge Summit, PA, USA"} +@String{pub-WRC = "W. and R. Chambers Ltd."} +@String{pub-WRC:adr = "London, UK"} +@String{pub-YOURDON = "Yourdon Press"} +@String{pub-YOURDON:adr = "Englewood Cliffs, NJ 07632, USA"} + +% Here comes the bibliography entries sorted by citation key +% (M-X sort-bibtex-entries in GNU Emacs) + +@Article{Abe:index, + author = "Kris K. Abe and Daniel M. Berry", + title = "{\tt indx} and {\tt findphrases}, A System for + Generating Indexes for Ditroff Documents", + journal = j-SPE, + year = "1989", + volume = "19", + number = "1", + pages = "1--34", + month = jan, +} + +@Book{Abrahams:TI90, + key = "ABH90", + author = "Paul W. Abrahams with Karl Berry and Kathryn A. + Hargreaves", + title = "{\TeX} for the Impatient", + publisher = pub-AW, + year = "1990", + address = pub-AW:adr, + ISBN = "0-201-51375-7", + LCCN = "Z253.4.T47 A27 1990", + pages = "xvii + 357", + bibdate = "Tue Dec 14 22:55:21 1993", +} + +@Book{Abrahams:UI92, + author = "Paul W. Abrahams and Bruce R. Larson", + title = "{UNIX} for the Impatient", + publisher = pub-AW, + year = "1992", + address = pub-AW:adr, + ISBN = "0-201-55703-7", + LCCN = "QA76.76.O63 A27 1992", + pages = "xxvii + 559", + note = "Excellent, and thorough, coverage of {UNIX}, with + chapters on the file system, utilities, shells, + editors, Emacs, data manipulation, mail, network + communications and resources, the X Window System, and + a comparison of {MS-DOS} and {UNIX}.", +} + +@Misc{Abraxas:pcyacc, + author = "{Abraxas Software, Inc.}", + title = "{PCYACC} 2.0", + note = "7033 SW Macadam Ave., Portland, OR 97219.", + year = "1987", +} + +@Misc{ACW:software, + author = "The Austin Code Works", + title = "Purveyors of software", + note = "11100 Leafwood Lane, Austin, TX 78750-3409.", +} + +@Article{Ada79:rationale, + key = "Ada", + author = "Anonymous", + title = "Rationale for the Design of the {Ada} Programming + Language", + journal = j-SIGPLAN, + year = "1979", + volume = "14", + number = "6B", + month = jun, + note = "The final standard is \cite{ANSI:ada}.", +} + +@Article{Ada79:refman, + key = "Ada", + author = "Anonymous", + title = "Preliminary {Ada} Reference Manual", + journal = j-SIGPLAN, + year = "1979", + volume = "14", + number = "6A", + month = jun, + note = "The final standard is \cite{ANSI:ada}.", +} + +@Book{Adams:F9H92, + author = "Jeanne C. {Adams et al.}", + title = "Fortran 90 Handbook: Complete {ANSI}/{ISO} Reference", + publisher = pub-MH, + year = "1992", + ISBN = "0-07-000406-4", + LCCN = "QA76.73.F28 F67 1992", + address = pub-MH:adr, + pages = "xi + 740", + libnote = "Not yet in my library.", + bibdate = "Mon Jan 3 11:33:25 1994", +} + +@Book{Adobe:AT1.190, + author = pub-ADOBE, + title = "Adobe Type 1 Font Format---Version 1.1", + publisher = pub-AW, + address = pub-AW:adr, + year = "1990", + month = aug, + ISBN = "0-201-57044-0", + LCCN = "QA76.73.P67 A36 1990", + pages = "iii + 103", + price = "US\$14.95", + libnote = "Not yet in my library.", +} + +@Manual{Adobe:AT190, + author = pub-ADOBE, + title = "Adobe Type 1 Font Format", + organization = pub-ADOBE, + address = pub-ADOBE:adr, + year = "1990", + month = mar, + partnumber = "LPS0064", +} + +@Misc{Adobe:colophon, + author = pub-ADOBE, + title = "{Colophon}\emdash {Adobe} {Systems} {News} + {Publication}", +} + +@TechReport{Adobe:docstruct-spec, + author = "{PostScript Developer Support Group}", + title = "{Document Structuring Conventions} Specification, + Version 2.1", + institution = pub-ADOBE, + year = "1989", + number = "PN LPS5001", + address = pub-ADOBE:adr, + month = jan # " 16", + note = "Available electronically from + \path|ps-file-server@adobe.com| in response to an + e-mail request {\tt send Documents + \path|struct.ps.Zba|}. The request {\tt send Index} + will return a complete index for the server.", +} + +@Manual{Adobe:DPS88, + author = pub-ADOBE, + title = "The Display PostScript System Reference", + organization = pub-ADOBE, + year = "1988", + month = oct # " 10", +} + +@TechReport{Adobe:epsf-spec, + author = "{Adobe PostScript Developer Support Group}", + title = "{Encapsulated PostScript Files} Specification Version + 2.0", + institution = pub-ADOBE, + year = "1989", + number = "PN LPS5002", + address = pub-ADOBE:adr, + month = jun # " 5", + note = "Available electronically from + \path|ps-file-server@adobe.com| in response to an + e-mail request {\tt send Documents EPSF.ps.Zba}. The + request {\tt send Index} will return a complete index + for the server. The version 3.0 specification is + published in \cite[Appendix~H]{Adobe:PLR90}.", +} + +@Book{Adobe:PDP93, + author = "{Adobe Systems Incorporated}", + title = "Programming the Display PostScript System with {X}", + publisher = pub-AW, + year = "1993", + ISBN = "0-201-62203-3", + LCCN = "QA76.73.P67 D57 1993", + address = pub-AW:adr, + price = "US\$29.95", + bibdate = "Tue Dec 14 23:26:06 1993", +} + +@Book{Adobe:PLP88, + author = "Glenn C. Reid", + title = "PostScript Language Program Design", + publisher = pub-AW, + address = pub-AW:adr, + year = "1988", + ISBN = "0-201-14396-8", + LCCN = "QA76.73.P67 R45 1988", + pages = "xii + 224", + bibdate = "Tue Dec 14 22:55:22 1993", +} + +@Book{Adobe:PLR85, + author = pub-ADOBE, + title = "PostScript Language Reference Manual", + publisher = pub-AW, + address = pub-AW:adr, + year = "{\noopsort{1985a}}1985", + ISBN = "0-201-10174-2", + LCCN = "QA76.73.P67 A33 1985", + pages = "ix + 321", + bibdate = "Tue Dec 14 22:55:23 1993", +} + +@Book{Adobe:PLR90, + author = pub-ADOBE, + title = "PostScript Language Reference Manual", + edition = "Second", + publisher = pub-AW, + address = pub-AW:adr, + year = "1990", + ISBN = "0-201-18127-4", + LCCN = "QA76.73.P67 P67 1990", + pages = "viii + 764", + bibdate = "Tue Dec 14 22:33:36 1993", +} + +@Book{Adobe:PLT85, + author = pub-ADOBE, + title = "PostScript Language Tutorial and Cookbook", + publisher = pub-AW, + address = pub-AW:adr, + year = "{\noopsort{1985b}}1985", + ISBN = "0-201-10179-3", + LCCN = "QA76.73.P67 A34 1985", + pages = "x + 243", + bibdate = "Tue Dec 14 22:55:24 1993", +} + +@Book{Aho:APL87, + nb = "the author order is AKW, but the key looks better as + AWK", + key = "AWK87", + author = "Alfred V. Aho and Brian W. Kernighan and Peter J. + Weinberger", + title = "The {AWK} Programming Language", + publisher = pub-AW, + address = pub-AW:adr, + year = "1988", + ISBN = "0-201-07981-X", + LCCN = "QA76.73.A95 A35 1988", + pages = "x + 210", + bibdate = "Tue Dec 14 22:33:46 1993", +} + +@Book{Aho:CPT86, + author = "Alfred V. Aho and Ravi Sethi and Jeffrey D. Ullman", + title = "Compilers\emdash Prin\-ci\-ples, Techniques, and + Tools", + publisher = pub-AW, + address = pub-AW:adr, + year = "1986", + ISBN = "0-201-10088-6", + LCCN = "QA76.76.C65 A371 1986", + pages = "x + 796", + bibdate = "Tue Dec 14 22:33:59 1993", +} + +@Book{Aho:DAC74, + author = "Alfred V. Aho and John E. Hopcroft and Jeffrey D. + Ullman", + title = "The Design and Analysis of Computer Algorithms", + publisher = pub-AW, + address = pub-AW:adr, + year = "1974", + ISBN = "0-201-00029-6", + LCCN = "QA76.6 .A284 1974", + pages = "x + 470", + bibdate = "Tue Dec 14 22:34:07 1993", +} + +@Book{Aho:PCD77, + author = "Alfred V. Aho and Jeffrey D. Ullman", + title = "Principles of Compiler Design", + publisher = pub-AW, + address = pub-AW:adr, + year = "1977", + note = "See also the much expanded subsequent book + \cite{Aho:CPT86}.", + ISBN = "0-201-00022-9", + LCCN = "QA76.6 .A285 1977", + pages = "x + 604", + bibdate = "Tue Dec 14 22:34:24 1993", +} + +@Book{Aho:TPT72, + author = "Alfred V. Aho and Jeffrey D. Ullman", + title = "The Theory of Parsing, Translation, and Compiling. + I: Parsing", + publisher = pub-PH, + address = pub-PH:adr, + year = "{\noopsort{1972a}}1972", + volume = "I", + ISBN = "0-13-914556-7", + LCCN = "QA76.6 .A286 1972-73", + pages = "xviii + 542", + bibdate = "Wed Dec 15 15:01:28 1993", +} + +@Book{Aho:TPT73, + author = "Alfred V. Aho and Jeffrey D. Ullman", + title = "The Theory of Parsing, Translation, and Compiling. + II. Compiling", + publisher = pub-PH, + address = pub-PH:adr, + year = "{\noopsort{1972b}}1973", + volume = "II", + ISBN = "0-13-914564-8", + LCCN = "QA76.6 .A286 1972-73", + pages = "xiii + 460", + bibdate = "Wed Dec 15 15:01:25 1993", +} + +@Book{Akl:PSA85, + author = "Selim G. Akl", + title = "Parallel Sorting Algorithms", + publisher = pub-AP, + address = pub-AP:adr, + year = "1985", + ISBN = "0-12-047680-0", + LCCN = "QA76.5 .A363 1985", + pages = "xiii + 229", + bibdate = "Tue Dec 14 22:36:06 1993", +} + +@TechReport{Aldus:tiff, + author = "Aldus Corporation and Microsoft Corporation", + title = "Tag Image File Format ({TIFF}) Specification Revision + 5.0", + institution = "Aldus Corporation, 411 First Avenue South, Suite 200, + Seattle, WA 98104, Tel: (206) 622-5500, and Microsoft + Corporation, 16011 NE 36th Way, Box 97017, Redmond, WA + 98073-9717, Tel: (206) 882-8080", + year = "1988", + month = aug # " 8", +} + +@Book{Allen:AL78, + author = "John R. Allen", + title = "Anatomy of {LISP}", + publisher = pub-MH, + address = pub-MH:adr, + year = "1978", + ISBN = "0-07-001115-X", + LCCN = "QA76.73 .L23 A43 1978", + pages = "xviii + 446", + bibdate = "Tue Dec 14 22:36:12 1993", +} + +@Book{Anderson:LUG92, + author = "E. Anderson and Z. Bai and C. Bischof and J. Demmel + and J. Dongarra and J. Du Croz and A. Greenbaum and S. + Hammarling and A. McKenney and S. Ostrouchov and D. + Sorenson", + title = "{LAPACK} Users' Guide", + publisher = pub-SIAM, + year = "1992", + address = pub-SIAM:adr, + ISBN = "0-89871-294-7", + LCCN = "QA76.73.F25 L36 1992", + pages = "xv + 235", + bibdate = "Tue Dec 14 22:36:17 1993", +} + +@Proceedings{Andre:ridt, + title = "Raster Imaging and Digital Topography\emdash + Proceedings of the International Conference, Ecole + Polytechnique {F}{\'e}d{\'e}rale, Lausanne, + Switzerland, October 1989", + year = "1989", + editor = "Jacques Andr{\'e} and Roger Hersch", + publisher = pub-CUP, + address = pub-CUP:adr, + ISBN = "0-521-37490-1", + LCCN = "Z253.3 .R37 1989", + pages = "x + 292", +} + +@Book{Angell:PIC81, + author = "Ian O. Angell", + title = "A Practical Introduction to Computer Graphics", + publisher = pub-JW, + address = pub-JW:adr, + year = "1981", + ISBN = "0-470-27251-1", + LCCN = "T385 .A53 1981", + pages = "viii + 146", + bibdate = "Tue Dec 14 22:39:01 1993", +} + +@Book{Anklam:ECV82, + author = "Patricia Anklam and David Cutler and Roger {Heinen, + Jr.} and M. Donald MacLaren", + title = "Engineering a Compiler\emdash {VAX}-11 Code + Generation and Optimization", + publisher = pub-DP, + address = pub-DP:adr, + year = "1982", + ISBN = "0-93237-619-3", + LCCN = "QA76.8.V37 E53 1982", + pages = "xv + 269", + bibdate = "Tue Dec 14 22:39:30 1993", +} + +@Manual{ANSI:ada, + title = "Military Standard {Ada} Programming Language", + organization = pub-ANSI, + address = pub-ANSI:adr, + year = "1983", + month = feb # " 17", + note = "Also MIL-STD-1815A.", +} + +@Manual{ANSI:c86, + title = "Draft Proposed American National Standard Programming + Language C", + organization = pub-ANSI, + address = pub-ANSI:adr, + year = "1986", + month = oct # " 1", +} + +@Manual{ANSI:c88, + title = "Draft Proposed American National Standard Programming + Language C", + organization = pub-ANSI, + address = pub-ANSI:adr, + year = "1988", + month = jan # " 11", +} + +@Manual{ANSI:c88b, + title = "Draft Proposed American National Standard Programming + Language C", + organization = pub-ANSI, + address = pub-ANSI:adr, + year = "1988", + month = oct # " 31", +} + +@Manual{ANSI:c89, + title = "American National Standard Programming Language C, + {ANSI} X3.159-1989", + organization = pub-ANSI, + address = pub-ANSI:adr, + year = "1989", + month = dec # " 14", +} + +@Manual{ANSI:ftn66, + title = "{ANSI} {Fortran} {X}3.9-1966", + organization = pub-ANSI, + address = pub-ANSI:adr, + year = "1966", + note = "Approved March 7, 1966 (also known as Fortran 66). + See also subsequent clarifications \cite{ANSI:ftn69} + and \cite{ANSI:ftn71}.", +} + +@Article{ANSI:ftn69, + author = "ANSI Subcommittee X3J3", + title = "Clarification of {Fortran} Standards\emdash Ini\-tial + Progress", + journal = j-CACM, + year = "1969", + volume = "12", + pages = "289--294", + note = "See also \cite{ANSI:ftn66}.", +} + +@Article{ANSI:ftn71, + author = "ANSI Subcommittee X3J3", + title = "Clarification of {Fortran} Standards\emdash Second + Report", + journal = j-CACM, + year = "1971", + volume = "14", + pages = "628--642", + note = "See also \cite{ANSI:ftn66}.", +} + +@Article{ANSI:ftn76, + author = "ANSI Subcommittee X3J3", + title = "Draft Proposed {ANS} {Fortran}", + journal = j-SIGPLAN, + year = "1976", + volume = "11", + number = "3", + note = "See also final standard \cite{ANSI:ftn77}.", +} + +@Manual{ANSI:ftn77, + title = "{ANSI} {Fortran} X3.9--1978", + organization = pub-ANSI, + address = pub-ANSI:adr, + year = "1978", + note = "Approved April 3, 1978 (also known as Fortran 77).", +} + +@Manual{ANSI:ftn8x, + title = "Draft Proposed {ANSI} {Fortran} X3.9--198x", + organization = pub-ANSI, + address = pub-ANSI:adr, + year = "1987", + month = sep # " 18", + note = "See also \cite{Metcalf:F8E87}.", +} + +@Manual{ANSI:ftn9x, + title = "Draft Proposed {American National Standard} + Programming Language {Fortran} Extended X3.198--199x", + organization = pub-ANSI, + address = pub-ANSI:adr, + year = "1990", + month = sep # " 24", + note = "See also \cite{Metcalf:F8E87}.", +} + +@Manual{ANSI:ftn92, + title = "{American National Standard} + Programming Language {Fortran} Extended X3.198--1992", + organization = pub-ANSI, + address = pub-ANSI:adr, + year = "1992", + note = "This US Standard is identical to the international + standard, ISO 1539:1991. See also + \cite{Adams:F9H92,Brainerd:PGF90,Counihan:F9091,Metcalf:F9E90}.", +} + +@Manual{ANSI:gks, + title = "Information Systems\emdash Com\-puter Graphics\emdash + Graph\-i\-cal Kernel System ({GKS}). {ANSI} + X3.124-1985", + organization = pub-ANSI, + address = pub-ANSI:adr, + year = "1985", + note = "Includes Fortran bindings to GKS.", +} + +@Manual{ANSI:metafile, + title = "Information Systems\emdash Com\-puter Graphics\emdash + Meta\-file for the Storage and Transfer of Picture + Description Information. {ANSI} X3.122-1986", + organization = pub-ANSI, + address = pub-ANSI:adr, + year = "1986", +} + +@Manual{ANSI:pascal, + title = "The Pascal Programming Language. {ANSI\slash IEEE} + 770X3.97-1983", + organization = pub-ANSI, + address = pub-ANSI:adr, + year = "1983", + note = "See also \cite{Jensen:PUM74,Jensen:PUM85}.", +} + +@Manual{ANSI:phigs, + title = "Information Systems\emdash Com\-puter Graphics\emdash + Pro\-gram\-mer's Hierarchical Interactive Graphical + System. Draft proposal X3.144.1988", + organization = pub-ANSI, + address = pub-ANSI:adr, + year = "1988", +} + +@Manual{ANSI:phigs+, + title = "{PHIGS}+ Functional Description, Revision 2.0", + organization = pub-ANSI, + address = pub-ANSI:adr, + month = jul # " 20", + year = "1987", +} + +@Book{Appelt:TF88, + author = "Wolfgang Appelt", + title = "{\TeX{}} f{\"u}r Fortgeschrittene", + publisher = pub-AW, + address = pub-AW:adr, + year = "1988", + ISBN = "3-89319-115-1", + pages = "x + 179", + bibdate = "Wed Dec 15 08:47:26 1993", +} + +@Book{Apple:TIM87, + author = "{Apple Computer, Inc.}", + title = "Technical Introduction to the Macintosh Family", + publisher = pub-AW, + address = pub-AW:adr, + year = "1987", + price = "US\$19.95", + ISBN = "0-201-17765-X", + LCCN = "QA76.8.M3 T43 1987", + pages = "xix + 289", + bibdate = "Tue Dec 14 22:39:39 1993", +} + +@Book{Arbib:BTC81, + author = "Michael A. Arbib and A. J. Kfoury and Robert N. Moll", + title = "A Basis for Theoretical Computer Science", + publisher = pub-SV, + address = pub-SV:adr, + year = "1981", + ISBN = "0-387-90573-1", + LCCN = "QA267 .A715", + pages = "viii + 220", + bibdate = "Tue Dec 14 22:39:53 1993", +} + +@Book{Artwick:ACM84, + author = "Bruce A. Artwick", + title = "Applied Concepts in Microcomputer Graphics", + publisher = pub-PH, + address = pub-PH:adr, + year = "1984", + ISBN = "0-13-039322-3", + LCCN = "T385 .A77 1984", + pages = "ix + 374", + bibdate = "Wed Dec 15 08:17:32 1993", +} + +@Book{Artwick:ACM85, + author = "Bruce A. Artwick", + title = "Applied Concepts in Microcomputer Graphics", + publisher = pub-PH, + address = pub-PH:adr, + edition = "Second", + year = "1985", + ISBN = "0-13-039322-3", + LCCN = "T385 .A77 1985", + pages = "ix + 374", + bibdate = "Wed Dec 15 08:17:32 1993", +} + +@Book{Asente:XWS90, + author = "Paul J. Asente and Ralph R. Swick", + title = "{X} Window System Toolkit\emdash The Complete + Programmer's Guide and Specification", + publisher = pub-DP, + address = pub-DP:adr, + year = "1990", + ISBN = "1-55558-051-3", + LCCN = "QA76.76.W56 A74 1990", + pages = "xxxv + 967", + bibdate = "Tue Dec 14 22:40:01 1993", +} + +@Article{Asher:virtual-fonts, + author = "Graham Asher", + title = "Re: Virtual fonts: More fun for Grand Wizards", + journal = j-TEXHAX, + year = "1990", + volume = "90", + number = "17", + month = jan, +} + +@Book{ATT:AUS86-1, + key = "ATT", + author = "AT{\&T}", + title = "{AT}{\&T} {UNIX} System Readings and Applications", + publisher = pub-PH, + address = pub-PH:adr, + volume = "I", + year = "1986", + ISBN = "0-13-938532-0", + LCCN = "QA76.76.O63 U553 1986", + pages= "xiv + 397", + bibdate = "Wed Dec 15 15:20:25 1993", +} + +@Book{ATT:AUS86-2, + key = "ATT", + author = "AT{\&T}", + title = "{AT}{\&T} {UNIX} System Readings and Applications", + publisher = pub-PH, + address = pub-PH:adr, + volume = "II", + year = "1986", + ISBN = "0-13-939845-7", + LCCN = "QA76.76.O63 U553 1986", + pages= "xii + 324", + bibdate = "Wed Dec 15 15:20:31 1993", +} + +@Book{ATT:UPM83-1, + key = "ATT", + author = "AT{\&T}", + title = "{UNIX} Programmer's Manual", + publisher = pub-HRW, + address = pub-HRW:adr, + year = "1983", + volume = "1", + ISBN = "0-03-061742-1", + LCCN = "QA76.8.U65 B44 1983", + pages= "xiv + 425", + bibdate = "Wed Dec 15 15:22:57 1993", +} + +@Book{ATT:UPM83-2, + key = "ATT", + author = "AT{\&T}", + title = "{UNIX} Programmer's Manual", + publisher = pub-HRW, + address = pub-HRW:adr, + year = "1983", + volume = "2", + ISBN = "0-03-061743-X", + LCCN = "QA76.8.U65 B44 1983", + pages= "vii + 616", + bibdate = "Wed Dec 15 15:22:54 1993", +} + +@Book{ATT:UPM86-1, + key = "ATT", + author = "AT{\&T}", + title = "{UNIX} {Programmer}'s {Manual}\emdash {Commands} and + {Utilities}", + publisher = pub-HRW, + address = pub-HRW:adr, + volume = "1", + year = "1986", + ISBN = "0-03-009317-1", + LCCN = "QA76.76.O63 U548 1986", + pages= "xxix + 524", + bibdate = "Wed Dec 15 15:28:36 1993", +} + +@Book{ATT:UPM86-2, + key = "ATT", + author = "AT{\&T}", + title = "{UNIX} {Programmer}'s {Manual}\emdash {System} + {Calls} and {Library} {Routines}", + publisher = pub-HRW, + address = pub-HRW:adr, + volume = "2", + year = "1986", + ISBN = "0-03-009314-7", + LCCN = "QA76.76.O63 U548 1986", + pages= "xxxv + 465", + bibdate = "Wed Dec 15 15:29:11 1993", +} + +@Book{ATT:UPM86-3, + key = "ATT", + author = "AT{\&T}", + title = "{UNIX} {Programmer}'s {Manual}\emdash {System} + {Administration} {Facilities}", + publisher = pub-HRW, + address = pub-HRW:adr, + volume = "3", + year = "1986", + ISBN = "0-03-009313-9", + LCCN = "QA76.76.O63 U548 1986", + pages= "xiv + 142", + bibdate = "Wed Dec 15 15:29:15 1993", +} + +@Book{ATT:UPM86-4, + key = "ATT", + author = "AT{\&T}", + title = "{UNIX} {Programmer}'s {Manual}\emdash {Document} + {Preparation}", + publisher = pub-HRW, + address = pub-HRW:adr, + volume = "4", + year = "1986", + ISBN = "0-03-011207-9", + LCCN = "QA76.76.O63 U548 1986", + pages= "xiii + 355", + bibdate = "Thu Dec 16 08:26:01 1993", +} + +@Book{ATT:UPM86-5, + key = "ATT", + author = "AT{\&T}", + title = "{UNIX} {Programmer}'s {Manual}\emdash {Languages} and + {Support} {Tools}", + publisher = pub-HRW, + address = pub-HRW:adr, + volume = "5", + year = "1986", + ISBN = "0-03-011204-4", + LCCN = "QA76.76.O63 U548 1986", + pages= "xviii + 618", + bibdate = "Wed Dec 15 15:29:21 1993", +} + +@Book{ATT:USV86, + key = "ATT", + author = "AT{\&T}", + title = "{UNIX} {System} {V} {Programmer}'s {Guide}", + publisher = pub-HRW, + address = pub-HRW:adr, + year = "1986", + ISBN = "0-13-940438-4", + LCCN = "QA76.76.O63 U556 1987", + pages= "xiv + 832", + bibdate = "Wed Dec 15 15:30:20 1993", +} + +@Book{Austrian:HHF82, + author = "Geoffrey D. Austrian", + title = "Herman Hollerith\emdash Forgotten Giant of + Information Processing", + publisher = pub-COLUMBIA, + address = pub-COLUMBIA:adr, + year = "1982", + ISBN = "0-231-05146-8", + LCCN = "QA76.2.H64 .A97", + pages = "xvi + 418", + bibdate = "Tue Dec 14 22:40:03 1993", +} + +@Article{Avenarius:fortran-web, + author = "Adrian Avenarius and Siegfried Oppermann", + title = "{\FWEB}: A Literate Programming System for {Fortran + 8X}", + journal = j-SIGPLAN, + year = "1990", + volume = "25", + number = "1", + pages = "52--58", + month = jan, +} + +@Book{Bach:DUO86, + author = "Maurice J. Bach", + title = "The Design of the {UNIX} Operating System", + publisher = pub-PH, + address = pub-PH:adr, + year = "1986", + ISBN = "0-13-201799-7", + LCCN = "QA76.76.O63 B33 1986", + pages = "xiv + 471", + bibdate = "Tue Dec 14 22:40:07 1993", +} + +@Book{Backhouse:SPL79, + author = "Roland C. Backhouse", + title = "Syntax of Programming Language", + publisher = pub-PHI, + address = pub-PHI:adr, + year = "1979", + series = "Series in Computer Science, Editor: C. A. R. Hoare", + price = "US\$18.95", + ISBN = "0-13-879999-7", + LCCN = "QA76.7 .B3", + pages = "xv + 301", + bibdate = "Tue Dec 14 22:40:09 1993", +} + +@Article{Backus:fortran-history, + author = "John Backus", + title = "The History of {FORTRAN I}, {II}, and {III}.", + journal = j-SIGPLAN, + year = "1978", + volume = "13", + number = "8", + pages = "165--180", + month = aug, +} + +@Book{Baer:CSA80, + author = "Jean-Loup Baer", + title = "Computer Systems Architecture", + publisher = pub-CSP, + address = pub-CSP:adr, + year = "1980", + ISBN = "0-914894-15-3", + LCCN = "QA76.9.A73 B33", + pages = "xiii + 626", + bibdate = "Tue Dec 14 22:40:11 1993", +} + +@Article{Baeza-Yates:j-CACM-35-10-74, + author = "Ricardo Baeza-Yates and Gaston H. Gonnet", + title = "A New Approach to Text Searching", + journal = j-CACM, + year = "1992", + volume = "35", + number = "10", + pages = "74--82", + month = oct, + note = "This paper describes a new linear-time string search + algorithm that can handle limited regular-expression + pattern matching {\em without\/} backtracking. See + also \cite{Knuth:string-search}, + \cite{Boyer:string-search}, \cite{Karp:TR-31-81}, + \cite{Sunday:string-search}, and + \cite{Wu:j-CACM-35-10-83}.", + bibdate = "Sat Nov 7 11:35:45 1992", +} + +@Article{Bailey:IJSA-5-3-63, + author = "D. H. Bailey and E. Barszcz and J. T. Barton and D. + S. Browning and R. L. Carter and L. Dagum and R. A. + Fatoohi and P. O. Frederickson and T. A. Lasinski and + R. S. Schreiber and H. D. Simon and V. Venkatakrishnan + and S. K. Weeratunga", + title = "The {NAS} Parallel Benchmarks", + journal = j-IJSA, + year = "1991", + volume = "5", + number = "3", + pages = "63--73", + month = "Fall", +} + +@InProceedings{Bailey:PS92-155, + author = "David H. Bailey", + title = "Misleading Performance in the Supercomputing Field", + booktitle = "Proceedings Supercomputing '92", + year = "1992", + ISBN = "0-8186-2630-5, 0-89791-537-2", + LCCN = "QA76.5 S87a 1992", + publisher = pub-IEEE, + address = pub-IEEE:adr, + pages = "155--158", + bibdate = "Sat Feb 12 11:55:01 1994", +} + +@Book{Bak:VTG66, + author = "Thor A. Bak and Jonas Lichtenberg", + title = "Vectors, Tensors, and Groups", + publisher = pub-WAB, + address = pub-WAB:adr, + year = "1966", + volume = "1", + series = "Mathematics for Scientists", + LCCN = "QA37 .B35 1967", + bibdate = "Wed Dec 15 15:32:13 1993", +} + +@Book{Ballard:CV82, + author = "Dana H. Ballard and Christopher M. Brown", + title = "Computer Vision", + publisher = pub-PH, + address = pub-PH:adr, + year = "1982", + ISBN = "0-13-165316-4", + LCCN = "TA1632 .B34 1982", + pages = "xx + 523", + bibdate = "Tue Dec 14 22:40:13 1993", +} + +@Book{Barnsley:FE88, + author = "Michael Barnsley", + title = "Fractals Everywhere", + publisher = pub-AP, + address = pub-AP:adr, + year = "1988", + ISBN = "0-12-079062-9", + LCCN = "QA614.86 .B37 1988", + pages = "xii + 394", + bibdate = "Tue Dec 14 22:40:15 1993", +} + +@Book{Barstow:IPE84, + author = "David R. Barstow and Howard E. Shrobe and Erik + Sandewall", + title = "Interactive Programming Environments", + publisher = pub-MH, + address = pub-MH:adr, + year = "1984", + price = "US\$34.95", + ISBN = "0-07-003885-6", + LCCN = "QA76.6 .I5251 1984", + pages = "xii + 609", + bibdate = "Tue Dec 14 22:40:18 1993", +} + +@Book{Bartels:ISU87, + author = "Richard H. Bartels and John C. Beatty and Brian A. + Barsky", + title = "An Introduction to Splines for Use in Computer + Graphics and Geometric Modeling", + publisher = pub-MK, + address = pub-MK:adr, + year = "1987", + price = "US\$38.95", + ISBN = "0-934613-27-3", + LCCN = "T385 .B3651 1987", + pages = "xiv + 476", + bibdate = "Tue Dec 14 22:40:21 1993", +} + +@Book{Bartlett:FQ80, + author = "John Bartlett", + title = "Familiar Quotations", + publisher = pub-LB, + address = pub-LB:adr, + year = "1980", + edition = "Fifteenth", + ISBN = "0-316-08275-9", + LCCN = "PN6081 .B3 1980", + pages = "lviii + 1540", + bibdate = "Tue Dec 14 22:40:24 1993", +} + +@Book{Bauldry:CLM91, + author = "William C. Bauldry and Joseph R. Fiedler", + title = "Calculus Laboratories with {Maple}: {A} Tool, Not an + Oracle", + publisher = pub-BC, + year = "1991", + ISBN = "0-534-13788-1", + LCCN = "MLCM 90/01887 (Q)", + address = pub-BC:adr, + pages = "xii + 144", + libnote = "Not yet in my library.", + bibdate = "Wed Dec 15 08:46:50 1993", +} + +@Book{Becker:NSP88, + author = "Richard A. Becker and John M. Chambers and Allan R. + Wilks", + title = "The New {S} Programming Language", + publisher = pub-WADSWORTH # " and " # pub-BC, + year = "1988", + address = pub-WADSWORTH:adr, + ISBN = "0534-09192-X", + LCCN = "QA76.73.S15 B43 1988", + pages = "xvii + 702", + bibdate = "Tue Dec 14 22:40:43 1993", +} + +@Article{Beebe:dvi-drivers, + author = "Nelson H. F. Beebe", + title = "A {\TeX} {DVI} Driver Family", + journal = j-TEXNIQUES, + year = "1987", + volume = "5", + pages = "71--114", + month = aug, + note = "Proceedings of the Eighth Annual Meeting of the + \TeX{} Users Group", +} + +@TechReport{Beebe:plot79, + author = "Nelson H. F. Beebe", + title = "A User's Guide to {\PLOT}", + institution = "University of Utah", + year = "1980", +} + +@Article{Beebe:plot79-biomed, + author = "Nelson H. F. Beebe and R. P. C. Rodgers", + title = "{\PLOT}: a comprehensive portable {Fortran} + scientific line graphics system, as applied to + biomedical research", + journal = j-CBM, + year = "1989", + volume = "19", + number = "6", + pages = "385--402", +} + +@Manual{Beebe:sf3-installation, + title = "{SFTRAN} 3 Installation Guide", + author = "Nelson H. F. Beebe", + organization = pub-CLSC, + address = pub-CLSC:adr, + year = "1979", + month = jul, +} + +@Article{Beebe:tex-graphics, + author = "Nelson H. F. Beebe", + title = "{\TeX{}} and Graphics: The State of the Problem", + journal = j-GUTENBERG, + year = "1989", + volume = "2", + pages = "13--53", + note = "Presented to: Congr{\`{e}}s GUTenberg, Paris, France, + 16--17 May 1989", +} + +@TechReport{Bell:rs6000-tuning, + author = "Ron Bell", + title = "{IBM RISC System\slash 6000} Performance Tuning for + Numerically Intensive {Fortran} and {C} Programs", + institution = pub-IBM, + year = "1990", + number = "GG24-3611-00", + month = aug, +} + +@Article{Bentley:grap, + author = "Jon Louis Bentley and Brian W. Kernighan", + title = "{GRAP}\emdash A Language for typesetting graphs", + journal = j-CACM, + year = "1986", + volume = "29", + number = "8", + pages = "782--792", + month = aug, +} + +@Article{Bentley:mini-macro-processor, + author = "Jon Bentley", + title = "m1: A Mini Macro Processor", + journal = j-COMPLANG, + year = "1990", + volume = "7", + number = "6", + pages = "47--61", + month = jun, +} + +@Book{Bentley:MPP88, + author = "Jon Louis Bentley", + title = "More Programming Pearls: Confessions of a Coder", + publisher = pub-AW, + address = pub-AW:adr, + year = "1988", + libnote = "Not yet in my library.", + price = "US\$18.75", + ISBN = "0-201-11889-0", + LCCN = "QA76.6 .B452 1988", + pages = "viii + 207", + bibdate = "Tue Dec 14 22:40:50 1993", +} + +@Article{Bentley:pic, + author = "Jon Louis Bentley", + title = "Programming Pearls\emdash Little Languages", + journal = j-CACM, + year = "1986", + volume = "29", + number = "8", + pages = "711--721", + month = aug, + note = "Description of the {\em pic\/} language.", +} + +@Book{Bentley:PP86, + author = "Jon Louis Bentley", + title = "Programming Pearls", + publisher = pub-AW, + address = pub-AW:adr, + year = "1986", + ISBN = "0-201-10331-1", + LCCN = "QA76.6.B453 1986", + pages = "viii + 195", + bibdate = "Wed Dec 15 08:16:02 1993", +} + +@Book{Bentley:PP89, + author = "Jon Louis Bentley", + title = "Programming Pearls (reprinted with corrections)", + publisher = pub-AW, + address = pub-AW:adr, + year = "1989", + ISBN = "0-201-10331-1", + LCCN = "QA76.6.B453 1989", + pages = "viii + 195", + libnote = "Not yet in my library.", + bibdate = "Wed Dec 15 08:16:02 1993", +} + +@Book{Bentley:WEP82, + author = "Jon Louis Bentley", + title = "Writing Efficient Programs", + publisher = pub-PH, + address = pub-PH:adr, + year = "1982", + ISBN = "0-13-970251-2 (hardcover), 0-13-970244-X (paperback)", + LCCN = "QA76.6 .B455 1982", + pages = "xvi + 170", + price = "US\$22.95 (hardcover), US\$14.95 (paperback)", + bibdate = "Tue Dec 14 22:40:54 1993", +} + +@Book{Bienz:PDF93, + author = "Tim Bienz and Richard Cohn", + title = "Portable Document Format Reference Manual", + publisher = pub-AW, + year = "1993", + ISBN = "0-201-62628-4", + LCCN = "QA76.9.F5P67 1993", + address = pub-AW:adr, + pages = "xii + 214", + price = "US\$24.95", + acknowledgement = ack-nhfb, + bibdate = "Wed Feb 23 14:42:18 1994", +} + +@Article{Bigelow:digital-typography, + author = "Charles Bigelow and Donald Day", + title = "Digital Typography", + journal = j-SA, + year = "1983", + volume = "249", + number = "2", + pages = "106--119", + month = aug, +} + +@TechReport{Billawala:metamarks, + author = "Neenie Billawala", + title = "Metamarks: Preliminary studies for a {Pandora's Box} + of Shapes", + institution = pub-STAN-CS, + address = pub-STAN-CS:adr, + year = "1989", + month = may, + number = "{STAN-CS-89-1256}", +} + +@Article{Bjorstad:SR-4-11-57, + author = "Petter E. Bjorstad and Erik Boman", + title = "{SLALOM}: A Better Algorithm", + journal = j-SR, + year = "1991", + volume = "4", + number = "11", + pages = "57--62", + month = nov, +} + +@Book{Blatner:RWS93, + author = "David Blatner and Steve Roth", + title = "Real World Scanning and Halftones", + publisher = pub-PEACHPIT, + year = "1993", + ISBN = "1-56609-093-8", + address = pub-PEACHPIT:adr, + pages = "xx + 275", + price = "US\$24.95", + acknowledgement = ack-nhfb, + bibdate = "Wed Feb 23 14:45:54 1994", +} + +@Article{Boehm:flow, + author = "C. Boehm and G. Jacopini", + title = "Flow Diagrams, {Turing} Machines, and Languages With + Only Two Formation Rules", + journal = j-CACM, + year = "1966", + volume = "9", + pages = "366--371", +} + +@Book{Bohren:CGB87, + author = "Craig F. Bohren", + title = "Clouds in a Glass of Beer\emdash Simple Experiments in + Atmospheric Physics", + publisher = pub-JW, + year = "1987", + ISBN = "0-471-62482-9", + LCCN = "QC861.2.B64 1987", + address = pub-JW:adr, + pages = "xv + 195", + price = "US\$16.95", + acknowledgement = ack-nhfb, + bibdate = "Fri Apr 1 18:21:29 1994", +} + +@Book{Boole:ILT54, + author = "George Boole", + title = "An Investigation of the Laws of Thought", + publisher = pub-DOV, + address = pub-DOV:adr, + year = "1854", + LCCN = "BC135 .B7 1951", + pages= "424", +} + +@Book{Boorstin:D83, + author = "Daniel J. Boorstin", + title = "The Discoverers", + publisher = pub-VINTAGE, + address = pub-VINTAGE:adr, + year = "1983", + ISBN = "0-394-72625-1", + LCCN = "CB69 .B66 1985", + pages = "xvi + 745", + bibdate = "Tue Dec 14 22:41:00 1993", +} + +@Book{Boorstin:C92, + author = "Daniel J. Boorstin", + title = "The Creators", + publisher = pub-VINTAGE, + year = "1992", + ISBN = "0-679-74375-8", + LCCN = "CB69.B65 1993", + address = pub-VINTAGE:adr, + pages = "xiv + 811", + acknowledgement = ack-nhfb, + bibdate = "Wed Apr 6 23:40:26 1994", +} + +@Book{Borceux:LPT90, + author = "Francis Borceux", + title = "{\LaTeX}\emdash la perfection dans le traitement du + texte", + publisher = pub-CIAOCO, + address = pub-CIAOCO:adr, + year = "1990", + ISBN = "2-87085-194-4", + bibdate = "Wed Dec 15 08:46:36 1993", +} + +@Book{Borde:TE92, + author = "Arvind Borde", + title = "{\TeX} by Example", + publisher = pub-AP, + address = pub-AP:adr, + year = "1992", + ISBN = "0-12-117650-9", + LCCN = "Z253.4.T47 B67 1992", + pages = "xiv + 169", + bibdate = "Tue Dec 14 22:41:14 1993", +} + +@Book{Borde:MTE93, + author = "Arvind Borde", + title = "Mathematical {\TeX} by Example", + publisher = pub-AP, + address = pub-AP:adr, + year = "1993", + ISBN = "0-12-117645-2", + LCCN = "Z253.4.T47 B67 1993", + pages = "xii + 352", + bibdate = "Mon Jul 19 15:22:37 1993", +} + +@Book{Bourne:UVU90, + author = "Philip E. Bourne", + title = "{UNIX} for {VMS} Users", + publisher = pub-DP, + address = pub-DP:adr, + year = "1990", + ISBN = "1-55558-034-3", + LCCN = "QA76.76.O63 B67 1989", + pages = "xvi + 368", + bibdate = "Tue Dec 14 22:41:28 1993", +} + +@Book{Bowles:MPS77, + author = "Kenneth L. Bowles", + title = "Microcomputer Problem Solving Using Pascal", + publisher = pub-SV, + address = pub-SV:adr, + year = "1977", + ISBN = "0-387-90286-4, 3-540-90286-4", + LCCN = "QA76.73.P2 .B68", + pages = "563", + bibdate = "Wed Dec 15 07:57:08 1993", +} + +@Article{Boyer:string-search, + author = "R. S. Boyer and J. S. Moore", + title = "A fast string searching algorithm", + journal = j-CACM, + year = "1977", + volume = "20", + number = "10", + pages = "762--772", + month = oct, + note = "See also \cite{Knuth:string-search} and + \cite{Sunday:string-search}.", +} + +@Book{Bradley:ALP84, + author = "David J. Bradley", + title = "Assembly Language Programming for the {IBM} Personal + Computer", + publisher = pub-PH, + address = pub-PH:adr, + year = "1984", + note = "The author is one of the designers of the IBM PC. The + book covers the 8088 and 8087 instruction sets, DOS + and MASM, the IBM PC hardware, and the ROM BIOS. + Somewhat more technical than \cite{Lafore:ALP84}.", + ISBN = "0-13-049189-6", + LCCN = "QA76.8.I2594 B7 1984", + pages = "xii + 340", + bibdate = "Tue Dec 14 22:41:36 1993", +} + +@Book{Brainerd:PGF90, + author = "Walter S. Brainerd and Charles H. Goldberg and Jeanne + C. Adams", + title = "Programmer's Guide to {Fortran} 90", + publisher = pub-MH, + year = "1990", + ISBN = "0-07-000248-7", + LCCN = "QA76.73.F25 B735 1990", + address = pub-MH:adr, + pages = "vii + 410", + libnote = "Not yet in my library.", + bibdate = "Mon Jan 3 11:30:25 1994", +} + +@Book{Braswell:IP89, + author = "Frank Merritt Braswell", + title = "Inside PostScript", + publisher = pub-PEACHPIT, + year = "1989", + address = pub-PEACHPIT:adr, + price = "US\$37.50", + ISBN = "0-938151-10-X", + LCCN = "QA76.73.P67 B73 1989", + bibdate = "Tue Dec 14 23:27:05 1993", +} + +@Book{BrinchHansen:BHP85, + author = "Per {Brinch Hansen}", + title = "Brinch Hansen on Pascal Compilers", + publisher = pub-PH, + address = pub-PH:adr, + year = "1985", + price = "US\$25.00", + ISBN = "0-13-083098-4", + LCCN = "QA76.73.P2 B75 1985", + pages = "x + 310", + bibdate = "Tue Dec 14 22:42:51 1993", +} + +@Book{Brooks:PCL85, + author = "Rodney A. Brooks", + title = "Programming in Common Lisp", + publisher = pub-W, + address = pub-W:adr, + year = "1985", + price = "US\$18.95", + ISBN = "0-471-81888-7", + LCCN = "QA76.73.L23 B76 1985", + pages = "xv + 303", + bibdate = "Tue Dec 14 22:43:03 1993", +} + +@Book{Brooks:MMM82, + author = "Frederick P. {Brooks, Jr.}", + title = "The Mythical Man-Month\emdash Essays on Software + Engineering", + publisher = pub-AW, + year = "1982", + ISBN = "0-201-00650-2", + LCCN = "QA 76.6 B75 1982", + address = pub-AW:adr, + pages = "xi + 195", + libnote = "Not yet in my library.", + acknowledgement = ack-nhfb, + bibdate = "Wed Jan 12 14:30:25 1994", +} + +@Book{Brown:SPA77, + editor = "P. J. Brown", + title = "Software Portability\emdash An Advanced Course", + publisher = pub-CUP, + address = pub-CUP:adr, + year = "1977", + price = "US\$14.00", + ISBN = "0-521-21485-8", + LCCN = "QA76.6 .S6351", + pages = "xiv + 328", + bibdate = "Tue Dec 14 22:43:05 1993", +} + +@Book{Brown:UP85, + author = "Maxine Brown", + title = "Understanding {PHIGS}", + publisher = pub-MEGATEK, + address = pub-MEGATEK:adr, + year = "1985", + LCCN = "T385 .B761 1985", + bibdate = "Wed Dec 15 15:35:57 1993", +} + +@Book{Bruin:PL88, + author = "R. de Bruin and C. G. {van der Laan} and J. R. Luyten + and H. F. Vogt", + title = "Publiceren met {\LaTeX{}}", + publisher = pub-CWI, + year = "1988", + address = pub-CWI:adr, + ISBN = "90-6196-357-5", + LCCN = "Z253.4.L38 .P97 1988", + pages = "196", + bibdate = "Tue Dec 14 22:43:17 1993", +} + +@Book{Bryan:SAG88, + author = "Martin Bryan", + title = "{SGML}\emdash An Author's Guide to the Standard + Generalized Markup Language", + publisher = pub-AW, + address = pub-AW:adr, + year = "1988", + ISBN = "0-201-17535-5", + LCCN = "QA76.73.S44 B79 1988", + pages = "xvii + 364", + bibdate = "Tue Dec 14 22:43:19 1993", +} + +@Book{Buerger:LES90, + author = "David J. Buerger", + title = "{\LaTeX} for Engineers and Scientists", + publisher = pub-MH, + address = pub-MH:adr, + year = "1990", + ISBN = "0-07-008845-4", + LCCN = "Z253.4.L38 B84 1990", + pages = "xvi + 198", + bibdate = "Tue Dec 14 22:43:21 1993", +} + +@Book{Cameron:LGE91, + author = "Debra Cameron and Bill Rosenblatt", + title = "Learning {GNU} Emacs", + publisher = pub-OR, + address = pub-OR:adr, + year = "1991", + ISBN = "0-937175-84-6", + LCCN = "QA76.76.T49 C35 1991", + pages = "xxvii + 411", + bibdate = "Tue Dec 14 22:43:25 1993", +} + +@Book{Campbell:CPG87, + author = "Joe Campbell", + title = "C Programmer's Guide to Serial Communications", + publisher = pub-HWS, + address = pub-HWS:adr, + year = "1987", + price = "US\$22.95", + ISBN = "0-672-22584-0", + LCCN = "QA76.73.C15 C36 1987", + pages = "xii + 655", + bibdate = "Tue Dec 14 23:27:20 1993", +} + +@TechReport{Castaneda:pcfort, + author = "Fernando Castaneda and Frederick Chow and Peter Nye + and Dan Sleator and Gio Wiederhold", + title = "{PCFORT}\emdash A {For}\-tran-to-{Pcode} Translator", + institution = "Computer System Laboratories, Stanford University", + year = "1979", + number = "{STAN-CS-79-714}", + address = pub-STAN-CSL:adr, + month = jan, +} + +@Book{Castleman:DIP79, + author = "Kenneth R. Castleman", + title = "Digital Image Processing", + publisher = pub-PH, + address = pub-PH:adr, + year = "1979", + ISBN = "0-13-212365-7", + LCCN = "TA1632 .C3 1979", + pages = "xvi + 429", + bibdate = "Tue Dec 14 23:41:25 1993", +} + +@Book{Chambers:CSF58-1, + editor = "James Pryde", + title = "Chambers's Seven-Fig\-ure Mathematical Tables", + publisher = pub-WRC, + address = pub-WRC:adr, + year = "1958", + volume = "1", +} + +@Book{Chambers:CSF58-2, + editor = "James Pryde", + title = "Chambers's Seven-Fig\-ure Mathematical Tables", + publisher = pub-WRC, + address = pub-WRC:adr, + year = "1958", + volume = "2", +} + +@Book{Char:FLM89, + author = "Bruce W. {Char et al.}", + title = "First leaves for the Macintosh\emdash a tutorial + introduction to Maple", + publisher = pub-BC, + year = "1989", + ISBN = "0534-10222-0", + LCCN = "QA155.7.E4 F57 1989", + address = pub-BC:adr, + pages = "xv + 140", + bibdate = "Fri Apr 1 17:37:47 1994", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", +} + +@Book{Char:MLR91a, + author = "Bruce W. Char and Keith O. Geddes and Gaston H. Gonnet + and Benton Leong and Michael B. Monagan and Stephen M. + Watt", + title = "Maple {V}: Language Reference Manual", + publisher = pub-SV, + year = "1991", + ISBN = "0-387-97622-1 (New York), 3-540-97622-1 (Berlin)", + LCCN = "QA155.7.E4 M36 1991", + address = pub-SV:adr, + pages = "xv + 267", + price = "US\$24.95, FF 193,00", + acknowledgement = ack-nhfb, + bibdate = "Wed Dec 1 12:17:05 1993", +} + +@Book{Char:MLR91b, + author = "Bruce W. Char and Keith O. Geddes and Gaston H. + Gonnet and Benton Leong and Michael B. Monagan and + Stephen M. Watt", + title = "Maple Library {V} Reference Manual", + publisher = pub-SV, + year = "1991", + pages = "xxv + 698", + address = pub-SV:adr, + ISBN = "0-387-97592-6, 3-540-97592-6", + LCCN = "QA155.7.E4 M353 1991", + bibdate = "Wed Dec 15 08:49:43 1993", +} + +@Book{Char:FLT92, + author = "Bruce W. Char and Keith O. Geddes and Gaston H. + Gonnet and Benton Leong and Michael B. Monagan and + Stephen M. Watt", + title = "First leaves\emdash a tutorial introduction to Maple + {V}", + publisher = pub-SV, + year = "1992", + ISBN = "0-387-97621-3, 3-540-97621-3", + LCCN = "QA155.7.E4 F56 1992", + address = pub-SV:adr, + pages = "xvii + 253", + bibdate = "Tue Nov 2 12:30:08 1993", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", +} + +@Book{Chasen:GPP78, + author = "Sylvan H. Chasen", + title = "Geometric Principles and Procedures for Computer + Graphics Applications", + publisher = pub-PH, + address = pub-PH:adr, + year = "1978", + ISBN = "0-13-352559-7", + LCCN = "T385 .C46", + pages = "xiv + 241", + bibdate = "Tue Dec 14 23:27:35 1993", +} + +@Article{Chen:SPE-19-9-897, + author = "Pehong Chen and Michael A. Harrison", + title = "Index Preparation and Processing", + journal = j-SPE, + year = "1988", + volume = "19", + number = "9", + pages = "897--915", + month = sep, + note = "The {\LaTeX} text of this paper is included in the + {\tt makeindex} software distribution.", +} + +@TechReport{Chen:UCB-TR-87-347, + author = "Pehong Chen and Michael A. Harrison", + title = "Automating Index Preparation", + institution = "Computer Science Division, University of California", + year = "1987", + type = "Technical Report", + number = "87/347", + address = "Berkeley, CA, USA", + month = mar, + note = "This is an expanded version of + \cite{Chen:SPE-19-9-897}.", +} + +@Book{Chow:MRM89, + title = "The {MIPS-X} {RISC} Microprocessor", + publisher = pub-KLUWER, + address = pub-KLUWER:adr, + year = "1989", + editor = "Paul Chow", + ISBN = "0-7923-9045-8", + LCCN = "QA76.8.M524 M57 1989", + pages = "xxiv + 231", + bibdate = "Tue Dec 14 23:27:43 1993", +} + +@Book{Christian:GM86, + author = "Kaare Christian", + title = "A Guide to Modula-2", + publisher = pub-SV, + address = pub-SV:adr, + year = "1986", + price = "US\$28.00", + ISBN = "0-387-96242-5", + LCCN = "QA76.73.M63 C494 1986", + pages = "xix + 436", + bibdate = "Tue Dec 14 23:27:52 1993", +} + +@Book{Christian:UOS83, + author = "Kaare Christian", + title = "The {UNIX} Operating System", + publisher = pub-WI, + address = pub-WI:adr, + year = "1983", + ISBN = "0-471-87542-2 (hardcover) and 0-471-89052-9 (paperback)", + LCCN = "QA76.8.U65 C45 1983", + pages = "xviii + 318", + bibdate = "Tue Dec 14 23:28:00 1993", +} + +@Book{Christian:UOS88, + author = "Kaare Christian", + title = "The {UNIX} Operating System", + publisher = pub-WI, + address = pub-WI:adr, + year = "1988", + edition = "Second", + ISBN = "0-471-84782-8 (hardcover) and 0-471-84781-X (paperback)", + LCCN = "QA76.8.U65 C45 1988", + pages = "xxii + 455", + bibdate = "Tue Dec 14 23:28:05 1993", +} + +@Book{Churchill:CVA60, + author = "Ruel V. Churchill", + title = "Complex Variables and Applications", + publisher = pub-MH, + address = pub-MH:adr, + year = "1960", + edition = "Second", + LCCN = "QA331 .C45 1960", + pages= "297", + bibdate = "Wed Dec 15 15:35:45 1993", +} + +@Book{Churchill:OM58, + author = "Ruel V. Churchill", + title = "Operational Mathematics", + edition = "Second", + publisher = pub-MH, + address = pub-MH:adr, + year = "1958", + LCCN = "QA432 .C45 1958", + pages= "337", + bibdate = "Wed Dec 15 15:37:25 1993", +} + +@Book{Clark:MPP85, + author = "K. L. Clark and F. G. McCabe", + title = "micro-{PROLOG}: Programming in Logic", + publisher = pub-PHI, + address = pub-PHI:adr, + year = "1985", + series = "Series in Computer Science, Editor: C. A. R. Hoare", + price = "US\$17.95", + ISBN = "0-13-581264-X (paperback)", + LCCN = "QA76.73.M5 C55 1984", + pages = "xi + 401", + bibdate = "Tue Dec 14 23:28:16 1993", +} + +@Proceedings{Clark:TAU90, + title = "{\TeX{}}\emdash Ap\-pli\-ca\-tions, Uses, Methods", + booktitle = "{\TeX{}}\emdash Ap\-pli\-ca\-tions, Uses, Methods", + year = "1990", + editor = "Malcolm Clark", + publisher = pub-EH, + address = pub-EH:adr, + ISBN = "0-13-912296-6", + pages = "277", + bibdate = "Wed Dec 15 08:51:21 1993", +} + +@Book{Clark:PTP92, + author = "Malcolm Clark", + title = "A Plain {\TeX} Primer", + publisher = pub-OUP, + address = pub-OUP:adr, + year = "1992", + pages = "481", + ISBN = "0-19-853784-0 (hardback), 0-19-853724-7 (softback)", + LCCN = "Z253.4.T47 C46 1992", + bibdate = "Tue Dec 14 23:41:37 1993", +} + +@Book{Cleaveland:GPL77, + author = "J. Craig Cleaveland and Robert C. Uzgalis", + title = "Grammars for Programming Languages", + publisher = pub-ELS, + address = pub-ELS:adr, + year = "1977", + volume = "4", + series = "Programming Languages Series, Editor: Thomas E. + Cheatham", + ISBN = "0-444-00187-5 (hardcover), 0-444-00199-9 (paperback)", + LCCN = "QA76.7.C571", + pages = "xiii + 154", + bibdate = "Tue Dec 14 23:28:27 1993", +} + +@Article{Clinger:floating-point-input, + author = "William D. Clinger", + title = "How to Read Floating Point Numbers Accurately", + journal = j-SIGPLAN, + year = "1990", + volume = "25", + number = "6", + pages = "92--101", + month = jun, + note = "See also output algorithm in + \cite{Steele:floating-point-output}.", +} + +@Article{Cody:fps-analysis, + author = "William J. {Cody, Jr.}", + title = "Analysis of Proposals for the Floating-Point + Standard", + journal = j-COMPUTER, + year = "1981", + volume = "14", + number = "3", + pages = "63--69", + month = mar, +} + +@Article{Cody:IEEE-P854, + author = "William J. {Cody, Jr.} and Jerome T. Coonen and David + M. Gay and K. Hanson and David Hough and W. Kahan and + R. Karpinski and John F. Palmer and F. N. Ris and D. + Stevenson", + title = "A Proposed Radix- and Word-length-independent + Standard for Floating-Point Arithmetic", + journal = j-IEEE-MICRO, + year = "1984", + volume = "4", + number = "4", + pages = "86--100", + month = aug, +} + +@Book{Cody:SME80, + author = "William J. {Cody, Jr.} and William Waite", + title = "Software Manual for the Elementary Functions", + publisher = pub-PH, + address = pub-PH:adr, + year = "1980", + ISBN = "0-13-822064-6", + LCCN = "QA331 .C635 1980", + pages = "x + 269", + bibdate = "Tue Dec 14 23:28:38 1993", +} + +@Book{Cole:MP76, + author = "A. J. Cole", + title = "Macro Processors", + publisher = pub-CUP, + address = pub-CUP:adr, + year = "1976", + volume = "4", + series = "Cambridge Computer Science Texts, Editors: E. S. Page + and C. M. Reeves and D. E. Conway", + price = "US\$7.95", + ISBN = "0-521-29024-4", + LCCN = "QA76.C358", + pages = "viii + 230", + bibdate = "Tue Dec 14 23:28:51 1993", +} + +@Book{Coleman:HMC88, + author = "Thomas F. Coleman and Charles F. Van Loan", + title = "Handbook for Matrix Computations", + publisher = pub-SIAM, + address = pub-SIAM:adr, + year = "1988", + ISBN = "0-89871-227-0", + LCCN = "QA188 .C651 1988", + pages = "vii + 264", + libnote = "Not yet in my library.", + bibdate = "Tue Dec 14 23:41:44 1993", +} + +@Article{Collinson:awk, + author = "Peter Collinson", + title = "Awk", + journal = j-SUNEXPERT, + year = "1991", + volume = "2", + number = "1", + pages = "33--36", + month = jan, +} + +@Book{Comer:ITD91, + author = "Douglas E. Comer and David L. Stevens", + title = "Internetworking with {TCP\slash IP}. Design, + Implementation, and Internals", + publisher = pub-PH, + address = pub-PH:adr, + year = "1991", + volume = "2", + ISBN = "0-13-472242-6", + LCCN = "TK5105.5 .C59 1991-92", + bibdate = "Tue Dec 14 23:29:18 1993", +} + +@Book{Comer:ITP88, + author = "Douglas E. Comer", + title = "Internetworking with {TCP\slash IP}. Principles, + Protocols, and Architecture.", + publisher = pub-PH, + address = pub-PH:adr, + year = "1988", + price = "US\$27.00", + ISBN = "0-13-470154-2", + LCCN = "TK5105.5 .C59 1988", + bibdate = "Tue Dec 14 23:41:49 1993", +} + +@Book{Comer:OSD84, + author = "Douglas E. Comer", + title = "Operating Systems Design. The {XINU} Approach", + volume = "1", + publisher = pub-PH, + address = pub-PH:adr, + year = "1984", + ISBN = "0-13-637539-1", + LCCN = "QA76.6 .C6275 1984", + bibdate = "Tue Dec 14 23:29:35 1993", +} + +@Book{Comer:OSD87, + author = "Douglas E. Comer", + title = "Operating Systems Design. Internetworking with + {XINU}", + volume = "2", + publisher = pub-PH, + address = pub-PH:adr, + year = "1987", + ISBN = "0-13-637414-X", + LCCN = "QA76.6 .C6275 1984", + bibdate = "Tue Dec 14 23:30:03 1993", +} + +@Book{Conrac:RGH85, + author = "Conrac Division", + title = "Raster Graphics Handbook", + publisher = pub-VNR, + address = pub-VNR:adr, + ISBN = "0-442-21608-4", + LCCN = "T385 .C64 1985", + pages = "v + 345", + year = "1985", + bibdate = "Tue Dec 14 22:44:38 1993", +} + +@Article{Coonen:fps-guide, + author = "Jerome T. Coonen", + title = "An Implementation Guide to a Proposed Standard for + Floating Point Arithmetic", + journal = j-COMPUTER, + year = "1980", + volume = "13", + number = "1", + pages = "68--79", + month = jan, + note = "See errata in \cite{Coonen:fps-guide-errata}.", +} + +@Article{Coonen:fps-guide-errata, + author = "Jerome T. Coonen", + title = "Errata: An Implementation Guide to a Proposed + Standard for Floating Point Arithmetic", + journal = j-COMPUTER, + year = "1981", + volume = "14", + number = "3", + pages = "62", + month = mar, + note = "See also \cite{Coonen:fps-guide}.", +} + +@Article{Coonen:ufl-denorm, + author = "Jerome T. Coonan", + title = "Underflow and the Denormalized Numbers", + journal = j-COMPUTER, + year = "1981", + volume = "14", + number = "3", + pages = "75--87", + month = mar, +} + +@Book{Counihan:F9091, + author = "Martin Counihan", + title = "Fortran 90", + publisher = pub-PITMAN, + year = "1991", + ISBN = "0-273-03073-6", + LCCN = "QA76.73.F25 C68 1991", + address = pub-PITMAN:adr, + pages = "309", + libnote = "Not yet in my library.", + bibdate = "Mon Jan 3 11:45:59 1994", +} + +@Book{Cowell:SDM84, + editor = "Wayne R. Cowell", + title = "Sources and Development of Mathematical Software", + publisher = pub-PH, + address = pub-PH:adr, + year = "1984", + series = pub-PH # " Series in Computational Mathematics, Cleve + Moler, Advisor", + ISBN = "0-13-823501-5", + LCCN = "QA76.95 .S68 1984", + pages = "xii + 404", + bibdate = "Tue Dec 14 22:44:45 1993", +} + +@Book{Craig:DT71, + author = "James Craig", + title = "Designing with Type", + publisher = pub-WGP, + address = pub-WGP:adr, + year = "1971", + ISBN = "0-8230-1320-0", + LCCN = "70-159564", + comments = "Spiralbound. Seventh printing, 1978.", + libnote = "Not yet in my library.", +} + +@Book{Crandall:MS91, + author = "Richard E. Crandall", + title = "{Mathematica} for the Sciences", + publisher = pub-AW, + address = pub-AW:adr, + year = "1991", + ISBN = "0-201-51001-4", + LCCN = "Q172 .C73 1991", + pages = "xiii + 300", + bibdate = "Wed Dec 15 07:59:15 1993", +} + +@Article{Cybenko:perfect, + author = "George Cybenko", + title = "Supercomputer Performance Trends and the {Perfect + Benchmarks}", + journal = j-SR, + year = "1991", + volume = "4", + number = "4", + pages = "53--60", + month = apr, +} + +@Book{daCruz:KFT87, + author = "Frank da Cruz", + title = "Kermit\emdash A File Transfer Protocol", + publisher = pub-DP, + address = pub-DP:adr, + year = "1987", + ISBN = "0-932376-88-6", + LCCN = "TK5105.5 .D23 1987", + pages = "xvii + 379", + bibdate = "Tue Dec 14 22:44:57 1993", +} + +@Book{daCruz:UCK93, + author = "Frank da Cruz and Christine M. Gianone", + title = "Using {C}-{Kermit}", + publisher = pub-DP # " and " # pub-PH, + year = "1993", + ISBN = "1-55558-108-0 (DP), 0-13-037490-3 (PH)", + LCCN = "TK5105.9.D33 1993", + address = pub-DP:adr # " and " # pub-PH:adr, + pages = "xxi + 514", + bibdate = "Mon Oct 4 10:22:38 1993", +} + +@Book{Dahlquist:NM74, + author = "Germund Dalhquist and {\AA}ke Bj{\"o}rck and Ned + Anderson", + title = "Numerical Methods", + publisher = pub-PH, + address = pub-PH:adr, + year = "1974", + series = pub-PH # " Series in Automatic Computation", + ISBN = "0-13-627315-7", + LCCN = "QA297 .D131 1969", + pages = "xviii + 573", + bibdate = "Tue Dec 14 22:44:59 1993", +} + +@Book{Davie:RDC81, + author = "A. J. T. Davie and R. Morrison", + title = "Recursive Descent Compiling", + publisher = pub-EH, + address = pub-EH:adr, + year = "1981", + series = "Ellis Horwood Series in Computers and their + Applications, Editor: Brian Meek", + ISBN = "0-470-27270-8 (Halstead Press), 0-85312-386-1 (Ellis + Horwood)", + LCCN = "QA76.6 .D373", + pages = "195", + bibdate = "Tue Dec 14 22:47:07 1993", +} + +@InProceedings{deBalbine:design, + author = "Guy de Balbine", + title = "Design Criteria for the Structuring Engine", + booktitle = "Proceedings of the Second USA-Japan Computer + Conference", + year = "1975", +} + +@Book{DEC:AAH92, + author = "Digital Equipment Corporation", + title = "Alpha Architecture Handbook", + publisher = pub-DP, + year = "1992", + address = pub-DP:adr, + bibdate = "Mon Jan 18 15:08:40 1993", +} + +@Book{Dennis:NMU83, + author = "J. E. {Dennis, Jr.} and Robert B. Schnabel", + title = "Numerical Methods for Unconstrained Optimization and + Nonlinear Equations", + publisher = pub-PH, + address = pub-PH:adr, + year = "1983", + series = pub-PH # " Series in Computational Mathematics, Cleve + Moler, Advisor", + ISBN = "0-13-627216-9", + LCCN = "QA402.5 .D44 1983", + pages = "xiii + 378", + bibdate = "Tue Dec 14 22:47:13 1993", +} + +@Book{Devitt:CMV93, + author = "John S. Devitt", + title = "Calculus with {Maple} {V}", + publisher = pub-BC, + year = "1993", + address = pub-BC:adr, + ISBN = "0-534-16362-9", + LCCN = "QA303.5.D37 D48 1993", + pages = "xxii + 502", + libnote = "Not yet in my library.", + bibdate = "Tue Dec 14 22:47:21 1993", +} + +@Book{Digital:PVC82, + author = "Digital Equipment Corporation", + title = "Programming in {VAX}-11 C", + publisher = pub-DP, + address = pub-DP:adr, + year = "1982", + month = may, +} + +@Article{Dijkstra:goto-harmful, + author = "Edsger Wybe Dijkstra", + title = "Go to statement considered harmful", + journal = j-CACM, + year = "1968", + volume = "11", + number = "3", + pages = "147--148", + month = mar, + note = "This paper inspired scores of others, published + mainly in SIGPLAN Notices up to the mid-1980s. The + best-known is \cite{Knuth:goto}.", +} + +@Book{Dijkstra:SWC82, + author = "Edsger Wybe Dijkstra", + title = "Selected Writings on Computing: A Personal + Perspective", + publisher = pub-SV, + address = pub-SV:adr, + ISBN = "0-387-90652-5", + LCCN = "QA76.24 .D54 1982", + pages = "xvii + 362", + year = "1982", + bibdate = "Tue Dec 14 22:47:28 1993", +} + +@Book{Dollhoff:16B79, + author = "Terry Dollhoff", + title = "16-Bit Microprocessor Architecture", + publisher = pub-RESTON, + address = pub-RESTON:adr, + year = "1979", + ISBN = "0-8359-7001-9", + LCCN = "QA76.5 .D65 1979", + pages = "xii + 471", + bibdate = "Tue Dec 14 22:47:30 1993", +} + +@TechReport{Dongarra:ANL-23-89, + author = "J. J. Dongarra", + title = "Performance of Various Computers Using Standard + Linear Equations Software in a {Fortran} Environment", + institution = pub-ANL, + address = pub-ANL:adr, + year = "1989", + type = "Technical Memorandum", + number = "23", + month = jun # " 4", +} + +@Book{Dongarra:LUG79, + author = "J. J. Dongarra and C. B. Moler and J. R. Bunch and G. + W. Stewart", + title = "{LINPACK} Users' Guide", + publisher = pub-SIAM, + address = pub-SIAM:adr, + ISBN = "0-89871-172-X (paperback)", + LCCN = "QA76.73 .L22 L5 1979, QA214 .L56 1979", + pages = "320", + year = "1979", + bibdate = "Mon Dec 13 15:18:20 1993", +} + +@Article{Dongarra:netlib, + author = "Jack Dongarra and Eric Grosse", + title = "Distribution of Mathematical Software via Electronic + Mail", + journal = j-CACM, + year = "1987", + volume = "30", + number = "5", + pages = "403--407", + month = may, +} + +@Book{Dongarra:SLS91, + author = "Jack J. Dongarra and Iain S. Duff and Danny C. + Sorensen and Henk A. van der Vorst", + title = "Solving Linear Systems on Vector and Shared Memory + Computers", + publisher = pub-SIAM, + address = pub-SIAM:adr, + year = "1991", + ISBN = "0-89871-270-X", + LCCN = "QA184 .S65 1991", + pages = "x + 256", + bibdate = "Tue Dec 14 22:47:36 1993", +} + +@TechReport{Donnelly:bison, + author = "Charles Donnelly and Richard M. Stallman", + title = "{BISON}\emdash The {YACC}-com\-pat\-i\-ble Parser + Generator", + institution = pub-FSF, + address = pub-FSF:adr, + year = "1988", + note = "Bison was largely written by Robert Corbett, and made + yacc-com\-pat\-i\-ble by Richard Stallman. Electronic + mail: \path|rms@prep.ai.mit.edu|. Software also + available via ANONYMOUS FTP to \path|prep.ai.mit.edu|. + See also \cite{Paxson:flex}.", +} + +@Book{Doob:TS193, + author = "Michael Doob", + title = "{\TeX}: Starting from 1", + publisher = pub-SV, + year = "1993", + ISBN = "0-387-56441-1", + address = pub-SV:adr, + pages = "114", + price = "US\$25.00", + acknowledgement = ack-nhfb, + bibdate = "Mon Dec 27 12:27:26 1993", +} + +@Book{Dougherty:MSI87, + author = "Edward R. Dougherty and Charles R. Giardina", + title = "Matrix Structured Image Processing", + publisher = pub-PH, + address = pub-PH:adr, + ISBN = "0-13-565623-0", + LCCN = "TA1632.D68 1987", + pages = "x + 258", + price = "US\$44.95", + year = "1987", + bibdate = "Tue Dec 14 22:47:38 1993", +} + +@Book{Dougherty:SA91, + author = "Dale Dougherty", + title = "sed {\&} awk", + publisher = pub-OR, + address = pub-OR:adr, + year = "1991", + ISBN = "0-937175-59-5", + LCCN = "QA76.76.U84 D69 1991", + pages = "xxii + 394", +} + +@Book{Doupnik:MMK90, + author = "Joe R. Doupnik", + title = "The Making of {MS-DOS} Kermit", + publisher = pub-DP, + address = pub-DP:adr, + year = "1990", + note = "Not yet published.", +} + +@Book{Dowd:HPC93, + author = "Kevin Dowd", + title = "High Performance Computing", + publisher = pub-OR, + year = "1993", + address = pub-OR:adr, + ISBN = "1-56592-032-5", + LCCN = "QA76.88 .D6 1993", + pages = "xxv + 371", + price = "US\$25.95", + bibdate = "Mon Jan 3 18:34:37 1994", +} + +@Book{Duff:DMS86, + author = "I. S. Duff and A. M. Erisman and J. K. Reid", + title = "Direct Methods for Sparse Matrices", + publisher = pub-CP, + address = pub-CP:adr, + price = "US\$37.50", + ISBN = "0-19-853408-6 (hardcover), 0-19-853421-3 (paperback)", + LCCN = "QA188 .D841 1986", + pages = "xiii + 341", + year = "1986", + bibdate = "Tue Dec 14 22:47:43 1993", +} + +@Book{Durbeck:OHD88, + title = "Output Hardcopy Devices", + publisher = pub-AP, + address = pub-AP:adr, + year = "1988", + editor = "Robert C. Durbeck and Sol Sherr", + ISBN = "0-12-225040-0", + LCCN = "TK7887.7 .O981 1988", + pages = "xii + 526", + note = "See article by Mike Parker on printer fonts, and + undesirability of white-writ\-ing engines. I have not + bought this book.", + bibdate = "Tue Dec 14 22:47:46 1993", +} + +@Article{Dvonch:color-pdl, + author = "M. Dvonch and P. Roetling and R. Buckley", + title = "Color Descriptors in Page Description Languages", + journal = j-PROC-SID, + year = "1989", + volume = "30", + number = "2", + pages = "???--???", + month = jun, +} + +@Book{Dybvig:SPL87, + author = "R. Kent Dybvig", + title = "The {SCHEME} Programming Language", + publisher = pub-PH, + address = pub-PH:adr, + ISBN = "0-13-791864-X (paperback)", + LCCN = "QA76.73.S34 D93 1987", + pages = "xi + 242", + year = "1987", + bibdate = "Tue Dec 14 22:47:48 1993", +} + +@Book{Earnshaw:FAC85, + author = "Rae A. Earnshaw", + title = "Fundamental Algorithms for Computer Graphics", + publisher = pub-SV, + address = pub-SV:adr, + year = "1985", + ISBN = "3-540-13920-6, 0-387-13920-6", + LCCN = "QA76.6 .N379 1985", + pages = "xvi + 1042", + bibdate = "Wed Dec 15 08:55:01 1993", +} + +@Book{Earnshaw:WPS87, + editor = "Rae A. Earnshaw", + title = "Workstations and Publication Systems", + publisher = pub-SV, + address = pub-SV:adr, + year = "1987", + ISBN = "0-387-96527-0, 3-540-96527-0", + LCCN = "Z286.E43 W67 1987", + pages = "viii + 229", + bibdate = "Tue Dec 14 22:47:49 1993", +} + +@Book{Eijkhout:TTT92, + author = "Victor Eijkhout", + title = "{\TeX} by Topic, A {\TeX}nician's Reference", + publisher = pub-AW, + address = pub-AW:adr, + year = "1992", + ISBN = "0-201-56882-9", + LCCN = "Z253.4.T47 E38 1992", + pages = "vii + 307", + bibdate = "Tue Dec 14 22:47:52 1993", +} + +@Book{Ekstrom:DIP84, + author = "Michael P. Ekstrom", + title = "Digital Image Processing Techniques", + publisher = pub-AP, + address = pub-AP:adr, + year = "1984", + volume = "2", + series = "Computational Techniques, Editors: Berni J. Alder and + Sidney Fernbach", + ISBN = "0-12-236760-X", + LCCN = "TA1632 .D496 1984", + pages = "xiii + 372", + bibdate = "Tue Dec 14 22:47:54 1993", +} + +@Book{Ellis:ACR90, + author = "Margaret A. Ellis and Bjarne Stroustrup", + title = "The Annotated {C++} Reference Manual", + publisher = pub-AW, + year = "1990", + address = pub-AW:adr, + ISBN = "0-201-51459-1", + LCCN = "QA76.73.C153 E35 1990", + pages = "x + 447", + bibdate = "Tue Dec 14 22:47:56 1993", +} + +@Book{Ellis:MCS89, + author = "Wade {Ellis, Jr.} and Ed Lodi", + title = "{Maple} for the Calculus Student", + publisher = pub-BC, + year = "1989", + ISBN = "0-534-11874-7", + LCCN = "QA155.7.E4 E44 1989", + address = pub-BC:adr, + pages = "vii + 67", + libnote = "Not yet in my library.", + bibdate = "Wed Dec 15 08:56:03 1993", +} + +@Book{Ellis:F7P90, + author = "T. M. R. Ellis", + title = "Fortran 77 Programming: With an Introduction to + {Fortran} 90 {Standard}", + publisher = pub-AW, + year = "1990", + ISBN = "0-201-41638-7", + LCCN = "QA76.73.F25 E43 1990", + edition = "Second", + address = pub-AW:adr, + pages = "xxi + 641", + bibdate = "Mon Jan 3 11:48:52 1994", +} + +@Book{Enderle:CGP84, + author = "G. Enderle and K. Kansy and G. Pfaff", + title = "Computer Graphics Programming. {GKS}\emdash The + Graphics Standard", + publisher = pub-SV, + address = pub-SV:adr, + year = "1984", + series = "Symbolic Computation, Editor: J. + Encarna{\c{c}}{\~{a}}o and P. Hayes", + ISBN = "0-387-11525-0, 3-540-11525-0", + LCCN = "T385 .E531 1984", + pages = "xvi + 542", + bibdate = "Wed Dec 15 07:59:26 1993", +} + +@Book{Enderle:CGP87, + author = "G. Enderle and K. Kansy and G. Pfaff", + title = "Computer Graphics Programming. {GKS}\emdash The + Graphics Standard", + publisher = pub-SV, + address = pub-SV:adr, + edition = "Second", + year = "1987", + series = "Symbolic Computation, Editor: J. + Encarna{\c{c}}{\~{a}}o and P. Hayes", + ISBN = "0-387-11525-0, 3-540-11525-0", + LCCN = "T385 .E531 1987", + pages = "xxiii + 651", + libnote = "Not yet in my library.", + bibdate = "Wed Dec 15 07:59:26 1993", +} + +@Book{England:SUG87, + author = "D. England", + title = "A Sun User's Guide", + publisher = pub-MAC-ED, + address = pub-MAC-ED:adr, + year = "1987", + series = "Macmillan Computer Science Series, Editor: F. H. + Sumner", + ISBN = "0-333-44849-9", + LCCN = "QA76.8.S9 S85 1987", + pages = "viii + 220", + bibdate = "Tue Dec 14 22:48:00 1993", +} + +@Book{Estrada:CI93, + author = "Susan Estrada", + title = "Connecting to the Internet", + publisher = pub-OR, + year = "1993", + ISBN = "1-56592-061-9", + LCCN = "TK 5105.875 I57 E82c 1993", + price = "US\$15.95", + address = pub-OR:adr, + month = aug, + pages = "xv + 170", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Thu Dec 9 18:37:47 1993", +} + +@Book{Etter:SF793, + author = "Delores M. Etter", + title = "Structured {FORTRAN} 77 for Engineers and Scientists", + publisher = pub-BENCUM, + year = "1993", + ISBN = "0-8053-1775-9", + LCCN = "QA76.73.F25E85 1993", + address = pub-BENCUM:adr, + pages = "xxiii + 616", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Thu Feb 24 12:47:31 1994", +} + +@Book{Farin:CSC88, + author = "Gerald Farin", + title = "Curves and Surfaces for Computer-Aided Geometric + Design", + publisher = pub-AP, + address = pub-AP:adr, + year = "1988", + ISBN = "0-12-249050-9", + LCCN = "T385 .F371 1988", + pages = "xv + 334", + bibdate = "Tue Dec 14 22:48:01 1993", +} + +@Book{Farin:CSC90, + author = "Gerald Farin", + title = "Curves and Surfaces for Computer-Aided Geometric + Design", + publisher = pub-AP, + address = pub-AP:adr, + year = "1990", + edition = "Second", + ISBN = "0-12-249051-7", + LCCN = "T385 .F371 1990", + pages = "xvii + 444", + bibdate = "Tue Dec 14 22:48:03 1993", +} + +@Proceedings{Farin:NCS91, + title = "{NURBS} for Curve and Surface Design", + year = "1991", + editor = "Gerald Farin", + publisher = pub-SIAM, + address = pub-SIAM:adr, + ISBN = "0-89871-286-6", + LCCN = "QA224 .N85 1991", + pages = "ix + 161", + bibdate = "Wed Dec 15 08:57:00 1993", +} + +@Book{Fattahi:MCL92, + author = "Abi Fattahi", + title = "{Maple V} Calculus Labs", + publisher = pub-BC, + year = "1992", + ISBN = "0-534-19272-6", + address = pub-BC:adr, + libnote = "Not yet in my library.", + pages = "95", + bibdate = "Fri May 28 12:12:01 1993", +} + +@Book{Faux:CGD79, + author = "I. D. Faux and M. J. Pratt", + title = "Computational Geometry for Design and Manufacture", + publisher = pub-EH, + address = pub-EH:adr, + year = "1979", + series = "Ellis Horwood Series in Mathematics and its + Applications, Editor: G. M. Bell", + price = "UK\pounds 12.00", + ISBN = "0-470-26473-X", + LCCN = "QA447 .F33", + pages = "329", + bibdate = "Tue Dec 14 22:48:04 1993", +} + +@TechReport{Feldman:fortlex, + author = "Stuart I. Feldman", + title = "{FORTLEX}\emdash A General Purpose Lexical Analyzer + for {Fortran}", + institution = pub-ATT-BELL, + number = "51", + year = "1976", + address = pub-ATT-BELL:adr, + month = oct, +} + +@Book{Feijen:BOB90, + title = "Beauty is our business: a birthday salute to {Edsger + W. Dijkstra}", + publisher = pub-SV, + year = "1990", + ISBN = "0-387-97299-4", + LCCN = "QA76 .B326 1990", + editor = "W. H. J. Feijen and A. J. M. van Gasteren and D. Gries + and J. Misra", + address = pub-SV:adr, + pages = "xix + 453", + acknowledgement = ack-nhfb, + bibdate = "Thu Mar 24 09:27:40 1994", +} + +@Book{Ferguson:MRM93, + author = "Paula Ferguson and David Brennan", + title = "Motif Reference Manual", + publisher = pub-OR, + year = "1993", + ISBN = "1-56592-038-4", + volume = "6B", + address = pub-OR:adr, + month = jun, + pages = "920", + price = "US\$34.95", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Mon Jan 3 17:51:39 1994", +} + +@Book{Fernbach:SCS86, + author = "Sidney Fernbach", + title = "Supercomputers\emdash Class {VI} Systems, Hardware + and Software", + publisher = pub-NH, + address = pub-NH:adr, + year = "1986", + ISBN = "0-444-87981-1", + LCCN = "QA76.5.S896 1986", + pages = "vii + 251", + bibdate = "Tue Dec 14 22:48:08 1993", +} + +@Book{Ferraro:PGE88, + author = "Richard F. Ferraro", + title = "Programmer's Guide to the {EGA} and {VGA} Cards", + publisher = pub-AW, + address = pub-AW:adr, + year = "1988", + price = "US\$29.95", + ISBN = "0-201-12692-3", + LCCN = "QA 76.8 I2594 .F48 1988", + pages = "xxvii + 607", + bibdate = "Tue Dec 14 22:48:16 1993", +} + +@Book{Finseth:CTE91, + author = "Craig A. Finseth", + title = "The Craft of Text Editing\emdash Emacs for the Modern + World", + publisher = pub-SV, + address = pub-SV:adr, + year = "1991", + ISBN = "0-387-97616-7, 3-540-97616-7", + LCCN = "QA76.76.T49 F56 1991", + pages = "xii + 220", + libnote = "Not yet in my library.", + note = "Contains extensive discussion of design issues for + text editors, with examples from Emacs. Appendix B + gives sources of numerous Emacs implementations. + Appendix D summarizes the TECO command set.", + bibdate = "Tue Dec 14 22:48:42 1993", +} + +@Book{Fisher:CAG61, + author = "Robert C. Fisher and Allen D. Ziebur", + title = "Calculus and Analytic Geometry", + publisher = pub-PH, + address = pub-PH:adr, + year = "1961", + LCCN = "QA 303 F53c", + pages= "766", + bibdate = "Wed Dec 15 15:39:38 1993", +} + +@Book{Fiume:MSR89, + author = "Eugene L. Fiume", + title = "The Mathematical Structure of Raster Graphics", + publisher = pub-AP, + address = pub-AP:adr, + year = "1989", + ISBN = "0-12-257960-7", + LCCN = "T385 .F581 1989", + pages = "xvi + 221", + bibdate = "Tue Dec 14 22:48:45 1993", +} + +@Book{Flanagan:PSR91, + author = "David Flanagan", + title = "Programmer's Supplement for Release 5 of the X Window + System, Version 11", + publisher = pub-OR, + address = pub-OR:adr, + year = "1991", + ISBN = "0-937175-86-2", + LCCN = "QA76.76.W56 F5 1991", + pages = "xx + 367", + bibdate = "Tue Dec 14 22:48:47 1993", +} + +@Book{Flanagan:XTI92, + author = "David Flanagan", + title = "X Toolkit Intrinsics Reference Manual", + publisher = pub-OR, + address = pub-OR:adr, + year = "1992", + volume = "5", + ISBN = "1-56592-007-4", + LCCN = "QA76.76.W56 N94 1992", + pages = "xiii + 899", + edition = "Third", + bibdate = "Tue Dec 14 23:30:37 1993", +} + +@Book{Fletcher:PMO80, + author = "R. Fletcher", + title = "Practical Methods of Optimization. + Volume 1: Unconstrained Optimization", + publisher = pub-JW, + address = pub-JW:adr, + year = "1980", + ISBN = "0-471-27711-8", + LCCN = "QA402.5 .F43", + pages= "viii + 120", + bibdate = "Wed Dec 15 15:03:15 1993", +} + +@Book{Fletcher:PMO81, + author = "R. Fletcher", + title = "Practical Methods of Optimization. Volume 2: Constrained + Optimization", + publisher = pub-JW, + address = pub-JW:adr, + year = "1981", + ISBN = "0-471-27828-9", + LCCN = "QA402.5 .F43", + pages= "ix + 224", + bibdate = "Wed Dec 15 15:03:44 1993", +} + +@TechReport{Flynn:sf2, + author = "John A. Flynn and Gary P. Carr", + title = "User's Guide to {SFTRAN II}", + institution = pub-JPL, + year = "1976", + number = "1846-79", + address = pub-JPL:adr, + month = oct, +} + +@TechReport{Flynn:sf3, + author = "John A. Flynn", + title = "{SFTRAN} User Guide", + institution = pub-JPL, + year = "1973", + number = "Section 914, Internal Computing Memorandum 337", + address = pub-JPL:adr, + month = jul, + note = "{Also} catalogued as JPL Document No.1846-7.", +} + +@Book{Foley:FIC82, + author = "James D. Foley and Andries van Dam", + title = "Fundamentals of Interactive Computer Graphics", + publisher = pub-AW, + address = pub-AW:adr, + year = "1982", + ISBN = "0-201-14468-9", + LCCN = "T385 .F63 1982", + pages = "xx + 664", + series = "The Systems Programming Series", + bibdate = "Wed Dec 15 08:01:46 1993", +} + +@Book{Foley:FIC90, + author = "James D. Foley and Andries van Dam and Steven K. + Feiner and John F. Hughes", + title = "Fundamentals of Interactive Computer Graphics", + publisher = pub-AW, + address = pub-AW:adr, + year = "1990", + edition = "Second", + ISBN = "0-201-12110-7", + LCCN = "T385 .C568 1990", + pages = "xxiii + 1174", + series = "The Systems Programming Series", + bibdate = "Tue Dec 14 22:52:46 1993", +} + +@TechReport{Ford:sftran, + author = "William F. Ford and Theodore E. Fessler", + title = "User's Guide for {SFTRAN}\slash 1100", + institution = "NASA Lewis Research Center", + year = "1978", + number = "NASA Technical Paper 1200", + month = apr, +} + +@Article{Fox:CACM-35-1-105, + author = "Edward A. Fox and Lenwood S. Heath and Qi Fan Chen and + Amjad M. Daoud", + title = "Minimal Perfect Hash Functions for Large Databases", + journal = j-CACM, + year = "1992", + volume = "35", + number = "1", + pages = "105--121", + month = jan, + note = "This is the first published algorithm for computing + minimal perfect hash functions for lists of millions of + words; previous algorithms were computationally + infeasible for more than a few hundred words.", + bibdate = "Thu May 20 17:19:08 1993", +} + +@Article{Foxley:music, + author = "Eric Foxley", + title = "Music\emdash A Language for Typesetting Music Scores", + journal = j-SPE, + year = "1987", + volume = "17", + number = "8", + pages = "485--502", + month = aug, +} + +@Book{Frey:DEM89, + author = "Donnalyn Frey and Rick Adams", + title = "\verb|!%@|:: A Directory of Electronic Mail + Addressing and Networks", + publisher = pub-OR, + address = pub-OR:adr, + year = "1989", + ISBN = "0-937175-39-0", + LCCN = "HE6239.E54 F73 1989", + pages = "xv + 284", + bibdate = "Tue Dec 14 22:52:54 1993", +} + +@Book{Friedman:LL87, + author = "Daniel Friedman and Matthias Felleisen", + title = "The Little {LISP}er", + publisher = pub-MIT, + address = pub-MIT:adr, + year = "1987", + ISBN = "0-262-56038-0", + LCCN = "QA76.73.L23 F74 1987", + pages = "xiv + 186", + bibdate = "Tue Dec 14 22:52:59 1993", +} + +@Book{Frisch:ESA91, + author = "{\AE}leen Frisch", + title = "Essential System Administration", + publisher = pub-OR, + year = "1991", + address = pub-OR:adr, + pages = "xxiii + 440", + ISBN = "0-937175-80-3", + LCCN = "QA76.76.O63 F78 1992", + bibdate = "Tue Dec 14 22:53:05 1993", +} + +@Misc{FSF:gawk, + key = "GAWK", + title = "The {GAWK} Manual", + howpublished = pub-FSF # " " # pub-FSF:adr, + year = "1987", + note = "Also available via ANONYMOUS FTP to + \path|prep.ai.mit.edu|. See also \cite{Aho:APL87}.", +} + +@Book{Gabriel:PEL85, + author = "Richard P. Gabriel", + title = "Performance and Evaluation of Lisp Systems", + publisher = pub-MIT, + address = pub-MIT:adr, + year = "1985", + series = "MIT Press Series in Computer Systems, Editor: Herb + Schwetman", + ISBN = "0-262-07093-6", + LCCN = "QA76.73.L23 G321 1985", + pages = "xiv + 285", + bibdate = "Tue Dec 14 22:53:07 1993", +} + +@Book{Gallivan:PAM90, + author = "K. A. Gallivan and Michael T. Heath and Esmond Ng and + James M. Ortega and Barry W. Peyton and R. J. Plemmons + and Charles H. Romine and A. H. Sameh and Robert G. + Voigt", + title = "Parallel Algorithms for Matrix Computations", + publisher = pub-SIAM, + address = pub-SIAM:adr, + year = "1990", + ISBN = "0-89871-260-2", + LCCN = "QA188 .P367 1990", + pages = "ix + 197", + bibdate = "Tue Dec 14 22:53:09 1993", +} + +@Book{Garbow:MER77, + author = "B. S. Garbow and J. M. Boyle and J. J. Dongarra and + C. B. Moler", + title = "Matrix Eigensystem Routines\emdash {EISPACK} Guide + Extension", + publisher = pub-SV, + address = pub-SV:adr, + year = "1977", + volume = "51", + series = "Lecture Notes in Computer Science, Editors: G. Goos + and J. Hartmanis", + ISBN = "0-387-08254-9, 3-540-08254-9", + LCCN = "QA193 .M381, QA267.A1,L43 no. 51", + pages = "viii + 343", + bibdate = "Mon Dec 13 15:14:28 1993", +} + +@Book{Gaskins:PPM92a, + author = "Tom Gaskins", + title = "{PHIGS} Programming Manual", + publisher = pub-OR, + year = "1992", + address = pub-OR:adr, + ISBN = "0-937175-85-4 (softcover), 0-937175-92-7 (hardcover)", + LCCN = "QA76.76.W56 G37 1992", + price = "US\$42.95 (softcover), US\$52.95 (hardcover)", + acknowledgement = ack-nhfb, + bibdate = "Tue Dec 7 09:56:13 1993", +} + +@Book{Gaskins:PPM92b, + author = "Tom Gaskins", + title = "{PEX}lib Programming Manual", + publisher = pub-OR, + year = "1992", + ISBN = "1-56592-028-7", + LCCN = "QA76.76.W56 G37 1992", + address = pub-OR:adr, + pages = "xlv + 1105", + price = "US\$44.95", + acknowledgement = ack-nhfb, + bibdate = "Tue Dec 7 09:54:08 1993", +} + +@Book{Gehani:DFT87, + author = "Narain Gehani", + title = "Document Formatting and Typesetting on the {UNIX} + System", + publisher = pub-SILICON, + year = "1987", + address = pub-SILICON:adr, + edition = "Second", + libnote = "Not yet in my library.", + ISBN = "0-13-938325-5", + LCCN = "QA76.73.A35 G437 1987", + pages = "xix + 310", + bibdate = "Tue Dec 14 22:53:12 1993", +} + +@Book{George:CSL81, + author = "Alan George and Joseph W. Liu", + title = "Computer Solution of Large Sparse Positive Definite + Systems", + publisher = pub-PH, + address = pub-PH:adr, + year = "1981", + series = pub-PH # " Series in Computational Mathematics, Cleve + Moler, Advisor", + ISBN = "0-13-165274-5", + LCCN = "QA188 .G46 1980", + pages = "xii + 324", + bibdate = "Tue Dec 14 22:53:15 1993", +} + +@Proceedings{GI:86, + key = "GI86", + title = "Graphics Interface 86", + publisher = pub-CIPS, + address = pub-CIPS:adr, + year = "1986", + note = "Vancouver, B. C. 26--30 May, 1986.", +} + +@Book{Gianone:UMK90, + author = "Christine M. Gianone", + title = "Using {MS-DOS} {KERMIT}: connecting your {PC} to the + Electronic World", + publisher = pub-DP, + address = pub-DP:adr, + year = "1990", + ISBN = "1-55558-048-3", + LCCN = "TK5105.9 .G5 1990", + pages = "xxv + 244", + libnote = "Not yet in my library.", +} + +@Book{Gianone:UMK92, + author = "Christine M. Gianone", + title = "Using {MS-DOS} {KERMIT}: connecting your {PC} to the + Electronic World", + edition = "Second", + publisher = pub-DP, + address = pub-DP:adr, + year = "1992", + ISBN = "1-55558-082-3 (book + diskette)", + LCCN = "TK5105.9 .G5 1992", + pages = "xxviii + 354", + price = "US\$34.95", + libnote = "Not yet in my library.", +} + +@Book{Gill:PO81, + author = "Philip E. Gill and Walter Murray and Margaret H. + Wright", + title = "Practical Optimization", + publisher = pub-AP, + address = pub-AP:adr, + year = "1981", + ISBN = "0-12-283950-1 (hardcover), 0-12-283952-8 (paperback)", + LCCN = "QA402.5 .G5 1981", + pages = "xvi + 401", + bibdate = "Tue Dec 14 22:53:24 1993", +} + +@Book{Gilly:UN92, + author = "Daniel Gilly and {the staff of O'Reilly \& + Associates, Inc.}", + title = "{UNIX} in a Nutshell", + publisher = pub-OR, + year = "1992", + address = pub-OR:adr, + edition = "Second", + ISBN = "1-56592-001-5", + LCCN = "QA76.76.O63 G55 1992", + bibdate = "Tue Dec 14 22:53:27 1993", +} + +@Book{Gilly:XWS90, + author = "Daniel Gilly and Tim O'Reilly", + title = "The {X Window System} in a Nutshell", + publisher = pub-OR, + year = "1990", + address = pub-OR:adr, + ISBN = "0-937175-24-2", + pages = "xi + 367", + bibdate = "Wed Dec 15 19:44:49 1993", +} + +@Book{Gilly:XWS92, + author = "Daniel Gilly and Tim O'Reilly", + title = "The {X Window System} in a Nutshell", + publisher = pub-OR, + edition = "Second", + year = "1992", + address = pub-OR:adr, + libnote = "Not yet in my library.", + ISBN = "1-56592-017-1", + LCCN = "QA76.76.W56 X24 1992", + bibdate = "Wed Dec 15 08:58:54 1993", +} + +@Book{Giloi:ICG78, + author = "Wolfgang K. Giloi", + title = "Interactive Computer Graphics", + publisher = pub-PH, + address = pub-PH:adr, + year = "1978", + ISBN = "0-13-469189-X", + LCCN = "T385 .G54 1978", + pages = "xiii + 354", + price = "US\$18.50", + bibdate = "Tue Dec 14 22:53:41 1993", +} + +@Book{Gilster:IN93, + author = "Paul Gilster", + title = "The Internet Navigator\emdash The Essential Guide to + Network Exploration for the Individual Dial-up User", + publisher = pub-WI, + year = "1993", + ISBN = "0-471-59782-1", + LCCN = "TK5105.875.I57 G55 1993", + pages = "xxiv + 470", + price = "US\$24.95", + address = pub-WI:adr, + acknowledgement = ack-nhfb, + bibdate = "Mon Oct 11 08:39:42 1993", +} + +@Book{Glassner:GG90, + editor = "Andrew S. Glassner", + title = "Graphics Gems", + publisher = pub-AP, + address = pub-AP:adr, + year = "1990", + ISBN = "0-12-286165-5", + LCCN = "T385 .G75 1990", + pages = "xxix + 833", + bibdate = "Tue Dec 14 22:53:50 1993", +} + +@Book{Glassner:IRT89, + editor = "Andrew S. Glassner", + title = "An Introduction to Ray Tracing", + publisher = pub-AP, + address = pub-AP:adr, + year = "1989", + ISBN = "0-12-286160-4", + LCCN = "T385 .I58 1989", + pages = "327", + bibdate = "Tue Dec 14 22:53:55 1993", +} + +@Book{Gnosis:LL84, + author = "{Gnosis, Inc.}", + title = "Learning Lisp", + publisher = pub-PH, + year = "1984", + ISBN = "0-13-527813-9", + LCCN = "QA76.73.L23 L43 1984", + bibdate = "Thu Sep 30 15:02:58 1993", + pages = "200", + address = pub-PH:adr, +} + +@Book{Godfrey:MIO82, + author = "M. D. Godfrey and D. F. Hendry and H. J. Hermans and + R. K. Hessenberg", + title = "Machine-Independent Organic Software Tools ({MINT})", + publisher = pub-AP, + address = pub-AP:adr, + year = "1982", + edition = "Second", + ISBN = "0-12-286982-6", + LCCN = "QA76.6.M319 1982", + pages = "xv + 369", + bibdate = "Tue Dec 14 22:54:00 1993", +} + +@Book{Golub:MC83, + author = "Gene H. Golub and Charles F. Van Loan", + title = "Matrix Computations", + publisher = pub-JH, + address = pub-JH:adr, + year = "1983", + series = "Johns Hopkins Series in the Mathematical Sciences", + ISBN = "0-8018-3010-9 (hardcover), 0-8018-3011-7 (paperback)", + LCCN = "QA188 .G65 1983", + pages = "xvi + 476", + bibdate = "Tue Dec 14 22:54:02 1993", +} + +@Book{Golub:MC89, + author = "Gene H. Golub and Charles F. Van Loan", + title = "Matrix Computations", + publisher = pub-JH, + address = pub-JH:adr, + edition = "Second", + pages = "xix + 642", + year = "1989", + libnote = "Not yet in my library.", + series = "Johns Hopkins Series in the Mathematical Sciences", + ISBN = "0-8018-3772-3 (hardcover), 0-8018-3739-1 (paperback)", + LCCN = "QA188 .G65 1989", + bibdate = "Tue Dec 14 22:54:04 1993", +} + +@Book{Gonnet:HAD84, + author = "Gaston H. Gonnet", + title = "Handbook of Algorithms and Data Structures", + publisher = pub-AW, + address = pub-AW:adr, + year = "1984", + series = "International Computer Science Series. Editors: A. D. + McGettrick and J. van Leeuwen", + price = "US\$12.95", + ISBN = "0-201-14218-X", + LCCN = "QA76.6 .G636 1984", + pages = "xi + 286", + bibdate = "Tue Dec 14 22:54:11 1993", +} + +@Book{Gonzalez:DIP77, + author = "Rafael C. Gonzalez and Paul Wintz", + title = "Digital Image Processing", + publisher = pub-AW, + address = pub-AW:adr, + year = "1977", + ISBN = "0-201-02596-5 (hardcover), 0-201-02597-3 (paperback)", + LCCN = "TA1632 .G66 1977", + pages = "xvi + 431", + bibdate = "Tue Dec 14 22:54:13 1993", +} + +@Book{Goosens:LC94, + author = "Michel Goossens and Frank Mittelbach and Alexander + Samarin", + title = "The {\LaTeX} Companion", + publisher = pub-AW, + year = "1994", + ISBN = "0-201-54199-8", + LCCN = "Z253.4.L38 G66 1994", + address = pub-AW:adr, + acknowledgement = ack-nhfb, + price = "US\$34.25", + bibdate = "Thu Jan 20 12:32:57 1994", +} + +@Book{Gorin:IDA81, + author = "Ralph E. Gorin", + title = "Introduction to {DECSYSTEM}-20 Assembly Language + Programming", + publisher = pub-DP, + address = pub-DP:adr, + year = "1981", + price = "US\$40.00", + ISBN = "0-93237-612-6", + LCCN = "QA76.8.D17 .G67", + pages = "xxx + 545", + bibdate = "Tue Dec 14 22:54:14 1993", +} + +@Book{Gosling:NB89, + author = "James Gosling and David S. H. Rosenthal and Michelle + Arden", + title = "The {NeWS} Book", + publisher = pub-SV, + address = pub-SV:adr, + year = "1989", + pages = "vi + 235", + ISBN = "0-387-96915-2", + LCCN = "QA76.76.W56 A731 1989", + bibdate = "Tue Dec 14 22:54:16 1993", +} + +@Book{Gotlieb:DTS78, + author = "C. C. Gotlieb and Leo R. Gotlieb", + title = "Data Types and Structures", + publisher = pub-PH, + address = pub-PH:adr, + year = "1978", + price = "US\$18.95", + ISBN = "0-13-197095-X", + LCCN = "QA76.9.D35 .G67", + pages = "xii + 444", + bibdate = "Tue Dec 14 22:54:18 1993", +} + +@Article{Gourlay:music-printing, + author = "John S. Gourlay", + title = "A Language for Music Printing", + journal = j-CACM, + year = "1986", + volume = "29", + number = "3", + pages = "388--401", +} + +@Book{Graham:CM89, + author = "Ronald L. Graham and Donald E. Knuth and Oren + Patashnik", + title = "Concrete Mathematics", + publisher = pub-AW, + address = pub-AW:adr, + year = "1989", + ISBN = "0-201-14236-8", + LCCN = "QA39.2 .G7331 1989", + pages = "xiii + 625", + bibdate = "Wed Dec 15 08:01:55 1993", +} + +@Book{Graham:CM94, + author = "Ronald L. Graham and Donald E. Knuth and Oren + Patashnik", + title = "Concrete Mathematics", + publisher = pub-AW, + address = pub-AW:adr, + edition = "Second", + year = "1994", + ISBN = "0-201-55802-5", + LCCN = "QA39.2 .G733 1994", + libnote = "Not yet in my library.", + bibdate = "Wed Dec 15 08:01:55 1993", +} + +@Book{Grandine:NMP90, + author = "Thomas A. Grandine", + title = "The Numerical Methods Programming Projects Book", + publisher = pub-OUP, + year = "1990", + address = pub-OUP:adr, + ISBN = "0-19-853387-X", + LCCN = "QA76.6 .G718 1990", + pages = "viii + 146", + bibdate = "Tue Dec 14 22:54:20 1993", +} + +@InProceedings{Gray:lex, + author = "Robert W. Gray", + title = "$\gamma$-{GLA}\emdash A Generator for Lexical + Analyzers that Programmers Can Use", + booktitle = "Summer USENIX '88", + year = "1988", + pages = "147--160", + month = jun # " 20--24", +} + +@Book{Gray:TT83, + author = "Bill Gray", + title = "Tips on Type", + publisher = pub-VNR, + address = pub-VNR:adr, + year = "1983", + ISBN = "0-442-22888-0", + LCCN = "Z250.G78 1983", + pages = "128", + libnote = "Not yet in my library.", + note = "Little coverage of computer-based typesetting, but an + excellent coverage of principles of typography, with + lots of examples of fonts.", + bibdate = "Tue Dec 14 22:54:21 1993", +} + +@Book{Green:DIP83, + author = "William B. Green", + title = "Digital Image Processing", + publisher = pub-VNR, + address = pub-VNR:adr, + year = "1983", + series = "Computer Science and Engineering Series", + ISBN = "0-442-28801-8", + LCCN = "TA1632 .G727 1983", + pages = "xi + 192", + bibdate = "Tue Dec 14 22:54:22 1993", +} + +@Book{Greene:MAA82, + author = "Daniel H. Greene and Donald E. Knuth", + title = "Mathematics for the Analysis of Algorithms", + publisher = pub-BH, + address = pub-BH:adr, + year = "1982", + edition = "Second", + ISBN = "3-7643-3102-X", + LCCN = "QA76.6 .G7423 1982", + pages = "123", + bibdate = "Tue Dec 14 22:54:24 1993", +} + +@Book{Gregory:CMT78, + author = "Robert T. Gregory and David L. Karney", + title = "A Collection of Matrices for Testing Computational + Algorithms", + publisher = pub-REK, + address = pub-REK:adr, + year = "1978", + ISBN = "0-88275-649-4", + LCCN = "QA188 .G72 1978", + pages = "ix + 154", + bibdate = "Wed Dec 15 09:01:31 1993", +} + +@Book{Gries:PMC78, + editor = "David Gries", + title = "Programming Methodology\emdash A Collection of + Articles by Members of {IFIP} {WG}2.3", + publisher = pub-SV, + address = pub-SV:adr, + year = "1978", + ISBN = "0-387-90329-1", + LCCN = "QA76.6.P7516", + pages = "xiv + 437", + bibdate = "Tue Dec 14 22:54:27 1993", +} + +@InCollection{Gries:BDO90, + author = "David Gries", + title = "Binary to Decimal, One More Time", + booktitle = "Beauty is our business: a birthday salute to {Edsger + W. Dijkstra}", + publisher = pub-SV, + year = "1990", + ISBN = "0-387-97299-4", + LCCN = "QA76 .B326 1990", + editor = "W. H. J. Feijen and A. J. M. van Gasteren and D. Gries + and J. Misra", + address = pub-SV:adr, + chapter = "16", + pages = "141--148 (of xix + 453)", + acknowledgement = ack-nhfb, + note = "This paper presents an alternate proof of Knuth's + algorithm \cite{Knuth:SPW90} for conversion between + decimal and fixed-point binary numbers.", + bibdate = "Sun Mar 27 17:53:57 1994", +} + +@Article{Griffiths:space-fill, + author = "J. G. Griffiths", + title = "An Algorithm for Displaying a Class of Space-filling + Curves", + journal = j-SPE, + year = "1986", + volume = "16", + number = "5", + pages = "403--411", + month = may, +} + +@Book{Grimson:FIS81, + author = "William Eric Leifur Grimson", + title = "From Images to Surfaces", + publisher = pub-MIT, + address = pub-MIT:adr, + year = "1981", + ISBN = "0-262-07083-9", + LCCN = "QP487 .G74", + pages = "274", + bibdate = "Tue Dec 14 22:54:29 1993", +} + +@Book{Griswold:IIP86, + author = "Ralph E. Griswold and Madge T. Griswold", + title = "The Implementation of the {Icon} Programming + Language", + publisher = pub-PUP, + address = pub-PUP:adr, + year = "1986", + price = "US\$39.50", + ISBN = "0-69-108431-9", + LCCN = "QA76.73.I19 G76 1986", + pages = "x + 336", + bibdate = "Tue Dec 14 22:54:36 1993", +} + +@Book{Griswold:IPL83, + author = "Ralph E. Griswold and Madge T. Griswold", + title = "The {Icon} Programming Language", + publisher = pub-PH, + address = pub-PH:adr, + year = "1983", + ISBN = "0-13-449777-5", + LCCN = "QA76.73.I19 G74 1983", + pages = "xviii + 313", + bibdate = "Tue Dec 14 22:54:38 1993", +} + +@Book{Griswold:IPL90, + author = "Ralph E. Griswold and Madge T. Griswold", + title = "The {Icon} Programming Language", + publisher = pub-PH, + address = pub-PH:adr, + edition = "Second", + libnote = "Not yet in my library.", + year = "1990", + pages = "xv + 367", + ISBN = "0-13-447889-4", + LCCN = "QA76.73.I19 G74 1990", + bibdate = "Tue Dec 14 22:54:39 1993", +} + +@Book{Gurari:WT94, + author = "Eitan M. Gurari", + title = "Writing with {\TeX}", + publisher = pub-MH, + year = "1994", + ISBN = "0-07-025207-6", + LCCN = "Z253.4.T47 G87 1994", + address = pub-MH:adr, + pages = "xiv + 249", + bibdate = "Wed Sep 29 17:55:14 1993", +} + +@Book{Gurari:TLD94, + author = "Eitan M. Gurari", + title = "{\TeX} and {\LaTeX}: Drawing and Literate + Programming", + publisher = pub-MH, + ISBN = "0-07-025208-4 (book), 0-07-911616-7 (book + diskette)", + LCCN = "Z253.4.T47G87 1994", + year = "1994", + pages = "xiv + 310", + price = "US\$34.95", + address = pub-MH:adr, + bibdate = "Fri Oct 15 17:56:01 1993", + acknowledgement = ack-nhfb, +} + +@Article{Gustafson:slalom, + author = "John Gustafson and Diane Rover and Stephen Elbert and + Michael Carter", + title = "{SLALOM}\emdash The First Scalable Supercomputer + Benchmark", + journal = j-SR, + year = "1990", + volume = "3", + number = "11", + pages = "56--61", + month = nov, +} + +@Article{Gustafson:slalom-2, + author = "John Gustafson and Diane Rover and Stephen Elbert and + Michael Carter", + title = "{SLALOM} Update\emdash The Race Continues", + journal = j-SR, + year = "1991", + volume = "4", + number = "3", + pages = "56--61", + month = mar, +} + +@Article{Gustafson:slalom-3, + author = "John Gustafson and Diane Rover and Stephen Elbert and + Michael Carter", + title = "{SLALOM}\emdash Is Your Computer on the List? If not, + we'd like it to be", + journal = j-SR, + year = "1991", + volume = "4", + number = "7", + pages = "52--59", + month = jul, +} + +@Article{Gustafson:slalom-4, + author = "John Gustafson and Diane Rover and Stephen Elbert and + Michael Carter", + title = "{SLALOM}\emdash Surviving Adolescence", + journal = j-SR, + year = "1991", + volume = "4", + number = "12", + pages = "54--57", + month = dec, +} + +@Book{Hageman:AIM81, + author = "Louis A. Hageman and David M. Young", + title = "Applied Iterative Methods", + publisher = pub-AP, + address = pub-AP:adr, + year = "1981", + series = "Computer Science and Applied Mathematics, Editor: + Werner Rheinboldt", + ISBN = "0-12-313340-8", + LCCN = "QA297.8 .H34 1981", + pages = "xvii + 386", + bibdate = "Tue Dec 14 22:54:41 1993", +} + +@Book{Hahn:LE91, + author = "Jane Hahn", + title = "{\LaTeX{}} for Everyone", + publisher = pub-PTI, + year = "1991", + address = pub-PTI:adr, + ISBN = "0-9631044-0-3", + LCCN = "Z253.4.L38 H34 1991", + pages = "xi + 346", + price = "US\$19.95", + bibdate = "Tue Dec 14 22:54:48 1993", +} + +@TechReport{Hall:pfort, + author = "A. D. Hall", + title = "A Portable {Fortran} {IV} Subset", + institution = pub-ATT-BELL, + year = "1969", + address = pub-ATT-BELL:adr, +} + +@Book{Hall:SAS90, + author = "Mark Hall and John Barry", + title = "Sunburst\emdash The Ascent of Sun Microsystems", + publisher = pub-CBI, + address = pub-CBI:adr, + year = "1990", + ISBN = "0-8092-4368-7", + LCCN = "HD9696.C64 S794 1990", + pages = "xvii + 297", + bibdate = "Tue Dec 14 22:54:54 1993", +} + +@Book{Hall:SP90, + author = "Mark Hall and John Barry", + title = "The SunTechnology Papers", + publisher = pub-SV, + address = pub-SV:adr, + year = "1990", + ISBN = "0-387-97145-9", + LCCN = "HD9696.C64 S796 1990", + pages = "x + 250", + bibdate = "Wed Dec 15 08:01:59 1993", +} + +@Book{Hancock:CP82, + author = "Les Hancock and Morris Krieger", + title = "The C Primer", + publisher = pub-MH, + address = pub-MH:adr, + year = "1982", + ISBN = "0-07-025981-X", + LCCN = "QA76.73.C15 H36 1982", + pages = "ix + 235", + bibdate = "Tue Dec 14 22:54:58 1993", +} + +@Proceedings{Hansmann:eurographics89, + title = "Eurographics `89", + year = "1989", + editor = "W. Hansmann and F. R. A. Hopgood and W. Strasser", + publisher = pub-NH, + address = pub-NH:adr, + ISBN = "0-444-88013-5", + libnote = "Not yet in my library.", +} + +@Article{Hanson:parsing, + author = "David R. Hanson", + title = "Compact Recursive-descent Parsing of Expressions", + journal = j-SPE, + year = "1985", + volume = "15", + number = "12", + pages = "1205--1212", + month = dec, +} + +@Book{Harbison:CAR84, + author = "Samuel P. Harbison and Guy L. {Steele Jr.}", + title = "C\emdash A Reference Manual", + publisher = pub-PH, + address = pub-PH:adr, + year = "1984", + ISBN = "0-13-110008-4", + LCCN = "QA76.73.C15 H38 1984", + pages = "x + 352", + bibdate = "Tue Dec 14 22:55:00 1993", +} + +@Book{Harbison:CAR87, + author = "Samuel P. Harbison and Guy L. {Steele Jr.}", + title = "C\emdash A Reference Manual", + publisher = pub-PH, + address = pub-PH:adr, + year = "1987", + edition = "Second", + ISBN = "0-13-109802-0", + LCCN = "QA76.73.C15 H38 1987", + pages = "xii + 404", + bibdate = "Wed Dec 15 08:02:04 1993", +} + +@Book{Harbison:CAR91, + author = "Samuel P. Harbison and Guy L. {Steele Jr.}", + title = "C\emdash A Reference Manual", + publisher = pub-PH, + address = pub-PH:adr, + year = "1991", + edition = "Third", + ISBN = "0-13-110933-2", + LCCN = "QA76.73.C15 H38 1991", + pages = "viii + 392", + bibdate = "Tue Dec 14 22:55:01 1993", +} + +@Book{Harrington:CGP83, + author = "Steven Harrington", + title = "Computer Graphics\emdash A Programming Approach", + publisher = pub-MH, + address = pub-MH:adr, + year = "1983", + libnote = "Missing from my library.", + price = "US\$21.95", + ISBN = "0-07-026751-0", + LCCN = "T385 .H34 1983", + pages = "xv + 448", + bibdate = "Tue Dec 14 23:42:22 1993", +} + +@Book{Harrington:CGP87, + author = "Steven Harrington", + title = "Computer Graphics\emdash A Programming Approach", + publisher = pub-MH, + address = pub-MH:adr, + year = "1987", + edition = "Second", + price = "US\$38.95", + ISBN = "0-07-026753-7", + LCCN = "T385 .H34 1987", + pages = "xiv + 466", + bibdate = "Tue Dec 14 22:55:04 1993", +} + +@Book{Harris:DCM92, + author = "Kent Harris", + title = "Discovering Calculus with {Maple}", + publisher = pub-JW, + year = "1992", + ISBN = "0-471-55156-2", + LCCN = "QA303.5.D37 H37 1992", + pages = "192", + address = pub-JW:adr, + libnote = "Not yet in my library.", + bibdate = "Tue Dec 14 22:55:05 1993", +} + +@Book{Hart:CA68, + author = "John F. Hart and E. W. Cheney and Charles L. Lawson + and Hans J. Maehly and Charles K. Mesztenyi and John + R. Rice and Henry G. {Thatcher, Jr.} and Christoph + Witzgall", + title = "Computer Approximations", + publisher = pub-REK, + address = pub-REK:adr, + year = "1968", + note = "Reprinted 1978 with corrections.", + ISBN = "0-88275-642-7", + LCCN = "QA 297 C64 1978", + pages = "x + 343", + bibdate = "Tue Dec 14 22:55:11 1993", +} + +@Article{Hatton:seismic-kernel, + author = "Les Hatton and Andy Wright and Stuart Smith and Gregg + Parkes and Paddy Bennett and Robert Laws", + title = "The {Seismic} {Kernel} {System}\emdash A Large-Scale + Exercise in {Fortran} 77 Portability", + journal = j-SPE, + year = "1988", + volume = "18", + number = "4", + pages = "301--329", + month = apr, + note = "Describes portability issues in a 500,000+ line + system.", + quote = "\ldots{} a load of around $10^{14}$ floating-point + operations for a typical marine seismic survey + involving just one ship for perhaps four weeks", + quote = "Assuming that 100 Mflops\slash sec can be sustained + for an average of 600 hours per month (somewhat more + than most centers can achieve), the speed at which + data can be processed by such a computer is comparable + to the speed at which it can be acquired by a single + vessel. As might be imagined, this requires a + significant percentage of the world's supercomputer + capacity.", + quote = "\ldots{}, there are a number of algorithms waiting in + the wings which cannot be computed on any current + machine within a reasonable time, and must await the + arritve of massively parallel machines and an + appropriate software methodology \ldots{}", + quote = "Furthermore, things never improved because of the + complication and inpenetrability of most of the code, + which was negligibly commented, unindented and of a + classic fractal nature. In this sense, fractal code + (like its mathematical counterpart) never gets any + simpler no matter how closely it is scrutinized.", + quote = "SKS is expected to reach a million lines by the end + of the decade.", +} + +@Book{Heck:IM93, + author = "Andr{\'e} Heck", + title = "Introduction to Maple", + publisher = pub-SV, + address = pub-SV:adr, + year = "1993", + ISBN = "0-387-97662-0, 3-540-97662-0", + LCCN = "QA155.7.E4H43 1993", + pages = "xiii + 497", + bibdate = "Tue Dec 14 22:55:13 1993", +} + +@Book{Heindel:LIL75, + author = "Lee E. Heindel and Jerry T. Roberto", + title = "{LANG}-{PAK}\emdash An Interactive Language Design + System", + publisher = pub-ELS, + address = pub-ELS:adr, + year = "1975", + volume = "1", + series = "Programming Languages Series, Editor: Thomas E. + Cheatham", + ISBN = "0-444-00154-9 (hardcover), 0-444-00162-X (paperback)", + LCCN = "QA76.6 .H468 1975", + pages = "xi + 184", + bibdate = "Tue Dec 14 22:55:15 1993", +} + +@Article{Heising:ftn, + author = "W. P. Heising", + title = "History and Summary of {Fortran} Standardization + Development for the {ASA}", + journal = j-CACM, + year = "1966", + volume = "7", + pages = "590--625", + note = "See also final standard \cite{ANSI:ftn66}.", +} + +@Book{Heller:MPM91, + author = "Dan Heller", + title = "Motif Programming Manual for OSF/Motif Version 1.1", + publisher = pub-OR, + address = pub-OR:adr, + year = "1991", + volume = "6", + ISBN = "0-937175-70-6", + LCCN = "QA76.76.W56 H446 1991", + pages = "xl + 990", + bibdate = "Wed Dec 15 09:05:18 1993", +} + +@Book{Heller:XPM90, + author = "Dan Heller", + title = "{XV}iew Programming Manual", + publisher = pub-OR, + address = pub-OR:adr, + year = "1990", + volume = "7", + ISBN = "0-937175-38-2", + LCCN = "QA76.76.W56 D44 v.7 1990", + pages = "xxviii + 557", + bibdate = "Tue Dec 14 22:55:18 1993", +} + +@Book{Heller:XPM91, + author = "Dan Heller", + title = "{XV}iew Programming Manual", + publisher = pub-OR, + address = pub-OR:adr, + year = "1991", + edition = "Third", + month = sep, + volume = "7A", + ISBN = "0-937175-87-0", + LCCN = "QA76.76.W56 H447 1990", + pages = "779", + bibdate = "Mon Jan 3 17:55:53 1994", + libnote = "Not yet in my library.", + acknowledgement = ack-nhfb, +} + +@Book{Hennessy:CA90, + author = "John L. Hennessy and David A. Patterson", + title = "Computer Architecture\emdash A Quantitative Approach", + publisher = pub-MK, + address = pub-MK:adr, + year = "1990", + ISBN = "1-55860-069-8", + LCCN = "QA76.9.A73 P377 1990", + pages = "xxviii + 594", + bibdate = "Mon Jan 31 08:47:46 1994", +} + +@Book{Hennessy:COD94, + author = "John L. Hennessy and David A. Patterson", + title = "Computer Organization and Design\emdash The + Hardware\slash Software Interface", + publisher = pub-MK, + year = "1994", + ISBN = "1-55860-281-X", + LCCN = "QA76.9 .C643 P37 1994", + address = pub-MK:adrnew, + pages = "xxiv + 648", + price = "US\$74.75", + acknowledgement = ack-nhfb, + bibdate = "Wed Feb 2 00:08:32 1994", +} + +@TechReport{Hershey:advanced-typography, + author = "Allen V. Hershey", + title = "Advanced Computer Typography", + institution = pub-USNPS, + year = "1981", + number = "NPS012-81-005", + address = pub-USNPS:adr, + month = dec, +} + +@TechReport{Hershey:calligraphy, + author = "Allen V. Hershey", + title = "Calligraphy for Computers", + institution = pub-USNWL, + year = "1967", + number = "TR-2101", + address = pub-USNWL:adr, + month = aug, +} + +@Article{Hershey:computer-typography, + author = "Allen V. Hershey", + title = "A Computer System for Scientific Typography", + journal = j-CGIP, + year = "1972", + volume = "1", + pages = "373--385", +} + +@TechReport{Hershey:fortran-cartography, + author = "Allen V. Hershey", + title = "{FORTRAN} {IV} Programming for Cartography and + Typography", + institution = pub-USNWL, + year = "1969", + number = "TR-2339", + address = pub-USNWL:adr, + month = sep, +} + +@TechReport{Hershey:fortran-typography, + author = "Allen V. Hershey", + title = "Preparation of Reports with the {FORTRAN} Typographic + System", + institution = pub-USNWL, + year = "1970", + number = "TN-K\slash 27-70", + address = pub-USNWL:adr, + month = sep, +} + +@TechReport{Hershey:fourier, + author = "Allen V. Hershey", + title = "A Comment on the Fourier Theorem", + institution = pub-USNWL, + year = "1974", + number = "TR-3145", + address = pub-USNWL:adr, + month = jun, +} + +@TechReport{Hershey:lagally, + author = "Allen V. Hershey", + title = "A Comment on the Lagally Theorem", + institution = pub-USNWL, + year = "1974", + number = "TR-3133", + address = pub-USNWL:adr, + month = may, +} + +@TechReport{Hershey:wavetrains, + author = "Allen V. Hershey", + title = "{FORTRAN} Programming for Surface Wave Trains", + institution = pub-USNWL, + year = "1972", + number = "TR-2714", + address = pub-USNWL:adr, + month = sep, +} + +@TechReport{Hershey:wavetrains-2, + author = "Allen V. Hershey", + title = "Interpolation of Surface Wave Trains", + institution = pub-USNWL, + year = "1972", + number = "TR-3064", + address = pub-USNWL:adr, + month = sep, +} + +@Book{Higham:HWM93, + author = "Nicholas J. Higham", + title = "Handbook of Writing for the Mathematical Sciences", + publisher = pub-SIAM, + year = "1993", + ISBN = "0-89871-314-5", + LCCN = "QA42.H54 1993", + price = "US\$21.50", + address = pub-SIAM:adr, + month = jun, + pages = "xii + 241", + note-1 = "[From the publisher]: Having trouble with your + latest math paper? Giving a presentation that you + just can't pull together? Struggling with your thesis + or trying to get your first article published in a + technical journal? Handbook of Writing for the + Mathematical Sciences is the book for you! + + This handy volume provides information on virtually + every issue you will face when writing a technical + paper or talk, from choosing the right journal to + handling your references. You'll also get an overview + of the entire publication process--invaluable for + anyone hoping to publish in a technical journal.", + note-2 = "To write a truly impressive paper, you'll need to + understand the anatomy of a research paper and the + steps involved in revising a draft. This book offers + discussions of these fundamental topics, along with + illustrative and provocative examples. Also included + are chapters on standard English usage, using + computers for writing and research, and writing + technical material when English is a foreign language. + + This handbook provides much-needed advice on handling + the basic ingredients of a research paper, like + definitions, theorems, examples, and equations. In + addition, appendices provide essential reference + material, including summaries of \LaTeX{} symbols and + Emacs commands, addresses of mathematical societies, + and a list of papers that have won expository writing + prizes.", + note-3 = "This book is ideal for graduate students and + teachers. Among its special features: + + \begin{itemize} + \item Detail and extensive use of examples make it an + excellent teaching tool + + \item Discusses \TeX{} and other software tools for + preparing publications + + \item Thorough treatment, with examples, of how to + write slides (transparencies) for a mathematical + talk. + + \item Comprehensive index and extensive bibliography + make it an excellent reference + + \item Readable for everyone in the field--from + undergraduates to seasoned professionals + \end{itemize}", + note-4 = "Contents \\ + Preface; \\ + Chapter 1: General Principles; \\ + Chapter 2: Writer's Tools and Recommended Reading; \\ + Chapter 3: Mathematical Writing; \\ + Chapter 4: English Usage; \\ + Chapter 5: When English is a Foreign Language; \\ + Chapter 6: Writing a Paper; \\ + Chapter 7: Revising a Draft; \\ + Chapter 8: Publishing a Paper; \\ + Chapter 9: Writing a Talk; \\ + Chapter 10: Computer Aids for Writing and Research; \\ + Appendix A: The Greek Alphabet; \\ + Appendix B: Summary of \TeX{} and \LaTeX{} Symbols; \\ + Appendix C: GNU Emacs--The Sixty+ Most Useful Commands; \\ + Appendix D: Mathematical Organizations in the UK and USA; \\ + Appendix E: Winners of Prizes for Expository Writing; \\ + Appendix F: Glossary; \\ + Bibliography; \\ + Index.\\ + + About the Author:\\ + Nicholas J. Higham is a Reader in Mathematics at the + University of Manchester, UK. He is the author + of more than 40 publications and is a member of the + editorial board of the SIAM Journal on Matrix Analysis + and Applications.", + bibdate = "Mon Oct 4 08:48:35 1993", + acknowledgement = ack-njh, +} + +@Book{Hilburn:MMH76, + author = "John L. Hilburn and Paul M. Julich", + title = "Mi\-cro\-com\-puters\slash Mi\-cro\-pro\-ces\-sors: + Hardware, Software, and Applications", + publisher = pub-PH, + address = pub-PH:adr, + year = "1976", + series = pub-PH # " Series in Automatic Computation", + price = "US\$16.50", + ISBN = "0-13-580969-X", + LCCN = "TK7888.3 .H48", + pages = "xii + 372", + bibdate = "Wed Dec 15 09:07:00 1993", +} + +@Book{Hill:ECM88, + author = "David R. Hill and Cleve B. {Moler (consulting + editor)}", + title = "Experiments in Computational Matrix Algebra", + publisher = pub-RH, + address = pub-RH:adr, + year = "1988", + ISBN = "0-394-35678-0", + LCCN = "QA188 .H55 1987", + libnote = "Not yet in my library.", + bibdate = "Wed Dec 15 09:07:54 1993", +} + +@Book{Hillis:CM85, + author = "W. Daniel Hillis", + title = "The Connection Machine", + publisher = pub-MIT, + address = pub-MIT:adr, + year = "1985", + ISBN = "0-262-08157-1", + LCCN = "QA267 .H4871 1985", + pages = "xiii + 190", + bibdate = "Tue Dec 14 23:43:53 1993", +} + +@Book{Hockney:PC81, + author = "R. W. Hockney and C. R. Jesshope", + title = "Parallel Computers: Architecture, Programming, and + Algorithms ", + publisher = pub-AH, + address = pub-AH:adr, + year = "1981, 1983", + ISBN = "0-85274-422-6 (hardcover), 0-85274-752-7 (paperback)", + LCCN = "QA76.6 .H58 1981", + pages = "xiii + 423", + price = "UK\pounds 22.50", + bibdate = "Wed Dec 15 09:11:15 1993", +} + +@Book{Hockney:PC88, + author = "R. W. Hockney and C. R. Jesshope", + title = "Parallel Computers: Architecture, Programming, and + Algorithms ", + edition = "Second", + publisher = pub-AH, + address = pub-AH:adr, + year = "1988", + ISBN = "0-8527-4811-6 (hardcover), 0-8527-4812-4 (paperback)", + LCCN = "QA76.5 .H57 1988", + libnote = "Not yet in my library.", + bibdate = "Wed Dec 15 09:10:21 1993", +} + +@Book{Holmes:ECM93, + author = "Mark H. Holmes and Joseph G. Ecker and William E. + Boyce and WIlliam L. Siegmann", + title = "Exploring Calculus with {Maple}", + publisher = pub-AW, + address = pub-AW:adr, + year = "1993", + ISBN = "0-201-52616-6", + LCCN = "QA303.5.D37 E97 1993", + pages = "vii + 258", + libnote = "Not yet in my library.", + bibdate = "Wed Dec 15 09:12:29 1993", +} + +@Book{Holoien:FES91, + author = "Martin O. Holoien and Ali Behforooz", + title = "{FORTRAN} 77 for Engineers and Scientists", + publisher = pub-BC, + year = "1991", + edition = "Second", + ISBN = "0-534-14166-8", + LCCN = "Q183.9 .H64 1991", + address = pub-BC:adr, + pages = "x + 463", + price = "US\$28.00", + acknowledgement = ack-nhfb, + bibdate = "Thu Dec 16 08:56:27 1993", +} + +@Book{Holub:CDC90, + author = "Allen I. Holub", + title = "Compiler Design in {C}", + publisher = pub-PH, + address = pub-PH:adr, + year = "1990", + note = pub-PH # " Software Series, Editor: Brian W. + Kernighan.", + ISBN = "0-13-155045-4", + LCCN = "QA76.76.C65 H65 1990", + pages = "xviii + 924", + bibdate = "Wed Dec 15 09:13:20 1993", +} + +@Article{Holub:curses, + author = "Allen I. Holub", + title = "Curses: {UNIX}-Compatible Windowing Output Functions", + journal = j-DDJ, + year = "1987", + volume = "12", + number = "7", + pages = "94--104, 74--93", + month = jul, +} + +@Book{Holzgang:DPP90, + author = "David A. Holzgang", + title = "Display PostScript Programming", + publisher = pub-AW, + address = pub-AW:adr, + year = "1990", + ISBN = "0-201-51814-7", + LCCN = "QA76.73.P67 H63 1990", + pages = "x + 406", + bibdate = "Wed Dec 15 09:14:14 1993", +} + +@Book{Holzgang:PPR89, + author = "David A. Holzgang", + title = "PostScript Programmer's Reference Guide", + publisher = pub-SF, + address = pub-SF:adr, + year = "1989", + ISBN = "0-673-38574-4", + LCCN = "QA76.73.P67 H64 1989", + pages = "x + 486", + bibdate = "Wed Dec 15 09:15:12 1993", +} + +@Book{Holzgang:UPP87, + author = "David A. Holzgang", + title = "Understanding PostScript Programming", + publisher = pub-SYBEX, + address = pub-SYBEX:adr, + year = "1987", + ISBN = "0-89588-396-1", + LCCN = "QA76.73.P67 H65 1987", + pages = "xxxii + 459", + bibdate = "Wed Dec 15 09:15:51 1993", +} + +@Book{Hopgood:IGK83, + author = "F. Robert A. Hopgood and Julian R. Gallop and David + A. Duce and Dale C. Sutcliffe", + title = "Introduction to the Graphical Kernel System ({GKS})", + publisher = pub-AP, + address = pub-AP:adr, + year = "1983", + note = "{A. P. I. C.} Studies in Data Processing No. 19.", + ISBN = "0-12-355570-1", + LCCN = "T385 .I57 1983", + pages = "xi + 200", + bibdate = "Wed Dec 15 10:30:59 1993", +} + +@Book{Hopgood:IGK86, + author = "F. Robert A. Hopgood and Julian R. Gallop and David + A. Duce and Dale C. Sutcliffe", + title = "Introduction to the Graphical Kernel System ({GKS})", + publisher = pub-AP, + address = pub-AP:adr, + edition = "Second", + year = "1986", + note = "Revised for the International Standard. {A. P. I. C.} + Studies in Data Processing No. 28", + price = "UK\pounds 12.50", + ISBN = "0-12-355571-X (paperback)", + LCCN = "T385 .I571 1986", + pages = "xii + 250", + bibdate = "Wed Dec 15 10:31:02 1993", +} + +@Book{Hopgood:MWM86, + author = "F. Robert A. Hopgood and David A. Duce and Elizabeth + V. C. Fielding and Ken Robinson and Antony S. + Williams", + title = "Methodology of Window Management", + publisher = pub-SV, + address = pub-SV:adr, + year = "1986", + ISBN = "0-387-16116-3", + LCCN = "T385 .C671 1985", + pages = "xv + 250", + bibdate = "Wed Dec 15 10:31:05 1993", +} + +@Book{Horowitz:FCA78, + author = "Ellis Horowitz and Sartaj Sahni", + title = "Fundamentals of Computer Algorithms", + publisher = pub-CSP, + address = pub-CSP:adr, + year = "1978", + ISBN = "0-914894-22-6", + LCCN = "QA76.6 .H67 1978", + pages = "xiv + 626", + bibdate = "Wed Dec 15 10:31:07 1993", +} + +@Book{Horowitz:FDS76, + author = "Ellis Horowitz and Sartaj Sahni", + title = "Fundamentals of Data Structures", + publisher = pub-CSP, + address = pub-CSP:adr, + year = "1976, 1982, 1983", + price = "US\$15.95", + ISBN = "0-914894-20-X", + LCCN = "QA76.9.D35 H67 1977", + pages = "xii + 564", + bibdate = "Wed Dec 15 10:31:28 1993", +} + +@Book{Hoskins:IRS91, + author = "Jim Hoskins", + title = "{IBM} {RISC} {System\slash 6000}\emdash A Business + Perspective", + publisher = pub-W, + address = pub-W:adr, + year = "1991", + ISBN = "0-471-53294-0", + LCCN = "QA76.8.I25975 H67 1991", + pages= "xx + 295", + bibdate = "Thu Dec 16 08:56:00 1993", +} + +@Article{Hough:fps-applications, + author = "David Hough", + title = "Applications of the Proposed {IEEE-754} Standard for + Floating Point Arithmetic", + journal = j-COMPUTER, + year = "1981", + volume = "14", + number = "3", + pages = "70--74", + month = mar, +} + +@Book{Hubbard:CGG84, + author = "Stuart W. Hubbard", + title = "The Computer Graphics Glossary", + publisher = pub-VNR, + address = pub-VNR:adr, + year = "1984", + ISBN = "0-897-74072-6", + LCCN = "T385 .H78 1983", + pages = "vi + 94", + bibdate = "Wed Dec 15 10:34:26 1993", +} + +@Book{Hunt:CT85, + author = "William James Hunt", + title = "The C Toolbox", + publisher = pub-AW, + address = pub-AW:adr, + year = "1985", + note = "An excellent introduction to the use of C for the + writing of software tools, with particular emphasis + (but not limited to) the IBM PC. Tools developed + include a screen-based file viewing utility, sorting + programs, a B-tree module, assembly language + primitives, and a terminal emulator.", + price = "US\$19.95", + ISBN = "0-201-11111-X", + LCCN = "QA76.73.C15 H85 1985", + pages = "xviii + 413", + bibdate = "Wed Dec 15 10:34:33 1993", +} + +@Book{Hunt:TNA92, + author = "Craig Hunt", + title = "{TCP/IP} Network Administration", + publisher = pub-OR, + year = "1992", + address = pub-OR:adr, + ISBN = "0-937175-82-X", + LCCN = "TK5105.9 .H86", + pages = "xxii + 471", + libnote = "Not yet in my library.", + bibdate = "Wed Dec 15 10:34:47 1993", +} + +@Book{Hunter:DCC81, + author = "Robin Hunter", + title = "The Design and Construction of Compilers", + publisher = pub-JW, + address = pub-JW:adr, + year = "1981", + ISBN = "0-471-28054-2", + LCCN = "QA76.6.H86 1981", + pages = "xii + 272", + bibdate = "Wed Dec 15 10:34:50 1993", +} + +@Book{Hwang:TSD84, + editor = "Kai Hwang", + title = "Tutorial\emdash Su\-per\-com\-puters: Design and + Applications", + publisher = pub-IEEE, + address = pub-IEEE:adr, + year = "1984", + ISBN = "0-8186-0581-2", + LCCN = "TK 7888.3 H82 1984", + pages = "viii + 640", + bibdate = "Wed Dec 15 10:34:52 1993", +} + +@Article{Hyman:literate-c++, + author = "Marco S. Hyman", + title = "Literate {C++}", + journal = j-COMPLANG, + year = "1990", + volume = "7", + number = "7", + pages = "67--79", + month = jul, +} + +@Book{IBM:IRP86, + author = "IBM", + title = "{IBM} {RT} Personal Computer Technology, publication + {SA}23-1057", + publisher = pub-IBM, + address = pub-IBM:adr, + year = "1986", +} + +@Book{IBM:IRS90, + editor = "Mamata Misra", + title = "{IBM} {RISC} System\slash 6000 Technology, + publication {SA}23-2619-00", + publisher = pub-IBM, + address = pub-IBM:adr, + year = "1990", +} + +@Book{IBM:IRS94, + editor = "Steve White and John Reysa", + title = "{IBM} {RISC} System\slash 6000 Technology: Volume + {II}", + publisher = pub-IBM, + address = pub-IBM:adr, + year = "1994", + note = "A partial draft is available via anonymous ftp to + \path|ibminet.awdpa.ibm.com| in the PostScript file + \path|/pub/rs6kpapers/techbook.ps|.", + acknowledgement = ack-nhfb, + bibdate = "Fri Mar 18 10:25:19 1994", +} + +@Book{IBM:IPA93, + author = "{IBM Corporation}", + title = "The {IBM} {PowerPC} Architecture: {A} New Family of + {RISC} Processors", + publisher = pub-MK, + year = "1993", + ISBN = "1-55860-316-6", + address = pub-MK:adr, + price = "US\$49.95", + libnote = "Not yet in my library.", + acknowledgement = ack-nhfb, + bibdate = "Fri Mar 18 10:26:28 1994", +} + +@Book{IEEE:ITU85, + author = "IEEE", + title = "{IEEE} Trial-Use Standard Specifications for + Microprocessor Operating Systems Interfaces", + publisher = pub-WI, + address = pub-WI:adr, + year = "1985", + note = "IEEE {Std}. 855.", + ISBN = "0-471-01073-1", + LCCN = "QA76.5 .I23 1985", + pages = "173", + bibdate = "Wed Dec 15 10:35:06 1993", +} + +@Book{IEEE:ITU86, + author = "IEEE", + title = "{IEEE} Trial-Use Standard Portable Operating System + for Computer Environments", + publisher = pub-WI, + address = pub-WI:adr, + year = "1986", + edition = "{IEEE} {Std} 1003.1", + month = apr, + ISBN = "0-471-85027-6", + LCCN = "TK 275 I5 Std 1003.1", + pages = "207", + bibdate = "Wed Dec 15 10:34:55 1993", +} + +@Manual{IEEE:p754, + title = "{ANSI}\slash {IEEE} 754-1985, Standard for Binary + Floating-Point Arithmetic", + author = "IEEE Task P754", + organization = "IEEE, New York", + year = "1985", + month = aug # " 12", + note = "A preliminary draft was published in the January 1980 + issue of IEEE Computer, together with several + companion articles +\cite{Cody:fps-analysis,Coonen:ufl-denorm,Coonen:fps-guide,Coonen:fps-guide-errata,Hough:fps-applications,Stevenson:COMPUTER-14-3-51}. + Available from the IEEE Service Center, Piscataway, + NJ, USA.", +} + +@Proceedings{IEEE:workstations, + key = "IEEE", + title = "Proceedings of the 2nd {IEEE} Conference on Computer + Workstations", + year = "1988", + publisher = pub-IEEE, + address = pub-IEEE:adr, + month = mar # " 7--10", +} + +@Book{Intel:286-hrm, + author = "Intel", + title = "The {iAPX} 286 Hardware Reference Manual", + publisher = pub-INTEL, + address = pub-INTEL:adr, + year = "1983", + LCCN = "QA76.8.I264 I14 1983", + note = "The definitive statement of the 80286 and 80287 + hardware at a strongly technical level. Not an + instruction set reference, but does contain + instruction timing tables. See also + \cite{Intel:286-prm}.", + bibdate = "Wed Feb 9 09:02:53 1994", +} + +@Book{Intel:286-prm, + author = "Intel", + title = "The {iAPX} 286 Programmer's Reference Manual", + publisher = pub-INTEL, + address = pub-INTEL:adr, + year = "1985", + note = "The definitive statement of what the 80286 and 80287 + are. A valuable reference for instruction definitions. + See also \cite{Intel:286-hrm}.", +} + +@Book{Intel:386-hrm, + author = "Intel", + title = "80386 Hardware Reference Manual", + publisher = pub-INTEL, + address = pub-INTEL:adr, + year = "1987", + note = "The definitive statement of the 80386 and 80387 + hardware at a strongly technical level. Not an + instruction set reference, but does contain + instruction timing tables. See also + \cite{Intel:386-prm}.", + ISBN = "1-55512-069-5", + LCCN = "TK7895.M5 E33 1986", + bibdate = "Wed Dec 15 10:35:07 1993", +} + +@Book{Intel:386-prm, + author = "Intel", + title = "80386 Programmer's Reference Manual", + publisher = pub-INTEL, + address = pub-INTEL:adr, + year = "1986", + note = "The definitive statement of what the 80386 and 80387 + are. A valuable reference for instruction definitions. + See also \cite{Intel:386-hrm}.", + ISBN = "1-55512-022-9", + LCCN = "QA76.8.I2928 E5 1986", + bibdate = "Wed Dec 15 10:35:16 1993", +} + +@Book{Intel:860-hrm, + author = "Intel", + title = "i860 64-bit Microprocessor Hardware Reference Manual", + publisher = pub-INTEL, + address = pub-INTEL:adr, + year = "1990", + ISBN = "1-55512-106-3", + LCCN = "TK7895.M5 I57662 1990", + bibdate = "Wed Dec 15 10:35:21 1993", +} + +@Book{Intel:860-prm, + author = "Intel", + title = "i860 64-bit Microprocessor Family Programmer's + Reference Manual", + publisher = pub-INTEL, + address = pub-INTEL:adr, + year = "1991", + ISBN = "1-55512-135-7", + LCCN = "QA76.8.I57 I44 1991", + bibdate = "Wed Dec 15 10:35:26 1993", +} + +@Book{Intel:OSW83, + author = "Intel", + title = "{iAPX} 286 Operating Systems Writer's Guide", + publisher = pub-INTEL, + address = pub-INTEL:adr, + year = "1983", +} + +@Book{Intel:II85, + author = "Intel", + title = "Introduction to the {iAPX} 286", + publisher = pub-INTEL, + address = pub-INTEL:adr, + year = "1985", +} + +@Manual{ISO:pascal, + title = "Specification for Computer Programming Language + {Pascal}, {ISO} 7185-1982", + year = "1982", + organization = pub-ISO, +} + +@Book{Jaeschke:DSC91, + author = "Rex Jaeschke", + title = "The Dictionary of Standard C", + publisher = pub-PPB, + year = "1991", + address = pub-PPB:adr, + ISBN = "1-878956-07-8", + LCCN = "QA76.73.C15 J335 1991", + pages= "x + 165", + bibdate = "Wed Dec 15 17:47:50 1993", +} + +@Book{Jaeschke:PCL89, + author = "Rex Jaeschke", + title = "Portability and the {C} Language", + publisher = pub-HAYDEN, + address = pub-HAYDEN:adr, + year = "1989", + ISBN = "0-672-48428-5", + LCCN = "QA76.76.C64 J34 1988", + pages = "xvi + 382", + bibdate = "Wed Dec 15 10:35:29 1993", +} + +@Book{Jaeschke:CIE93, + author = "Rex Jaeschke", + title = "{C++}: An Introduction for Experienced {C} + Programmers", + publisher = pub-CBM, + year = "1993", + address = pub-CBM:adr, + ISBN = "1-878956-27-2", + LCCN = "QA76.73.C15J3354 1993", + pages = "xii + 236", + bibdate = "Wed Dec 15 10:35:32 1993", +} + +@Book{Jennings:MCE77, + author = "Alan Jennings", + title = "Matrix Computation for Engineers and Scientists", + publisher = pub-JW, + address = pub-JW:adr, + year = "1977", + ISBN = "0-471-99421-9 (hardcover), 0-471-27832-7 (paperback)", + LCCN = "TA347 .D4J461", + pages = "xv + 330", + bibdate = "Wed Dec 15 10:35:36 1993", +} + +@Book{Jensen:PUM74, + author = "Kathleen Jensen and Niklaus Wirth", + title = "Pascal User Manual and Report", + publisher = pub-SV, + address = pub-SV:adr, + edition = "Second", + year = "1974", + note = "See also \cite{Jensen:PUM85}.", + ISBN = "0-387-90144-2, 3-540-90144-2", + LCCN = "QA76.73.P35 J461 1975", + pages = "167", + bibdate = "Wed Dec 15 10:35:38 1993", +} + +@Book{Jensen:PUM85, + author = "Kathleen Jensen and Niklaus Wirth", + title = "Pascal User Manual and Report\emdash {ISO} Pascal + Standard", + publisher = pub-SV, + address = pub-SV:adr, + year = "1985", + edition = "Third", + note = "Revised by {Andrew} {B}. {Mickel} and {James} {F}. + {Miner}.", + ISBN = "0-387-96048-1, 3-540-96048-1", + LCCN = "QA76.73.P2 J46 1985", + pages = "xvi + 266", + bibdate = "Wed Dec 15 10:35:40 1993", +} + +@Manual{JISCII:charset, + title = "{Japanese Industrial Standard JIS C 6626-1978 Code of + the Japanese Graphics Character Set for Information + Interchange}", + organization = pub-JSA, + year = "1978", + address = pub-JSA:adr, +} + +@Manual{JISCII:dot-printers, + title = "{Japanese Industrial Standard JIS C 6234-1983 24-dots + Matrix Character Patterns for Dot Printers}", + organization = pub-JSA, + year = "1983", + address = pub-JSA:adr, +} + +@Book{Johnson:AXW90, + author = "Eric F. Johnson and Kevin Reichard", + title = "Advanced X Window Applications Programming", + publisher = pub-MIS, + year = "1990", + address = pub-MIS:adr, + ISBN = "1-55828-029-4", + LCCN = "QA76.76.W56 J63 1990", + pages= "xxii + 615", + libnote = "Not yet in my library.", + bibdate = "Wed Dec 15 17:49:00 1993", +} + +@Book{Johnson:PPM91, + author = "Eric F. Johnson and Kevin Reichard", + title = "power programming {\ldots} {MOTIF}", + publisher = pub-MIS, + address = pub-MIS:adr, + year = "1991", + ISBN = "1-55828-059-6", + pages = "xv + 464", + bibdate = "Tue Dec 14 23:53:17 1993", + price = "US\$29.95 (book), US\$59.95 (book + diskette)", + bibdate = "Wed Dec 15 17:50:16 1993", +} + +@Article{Johnson:tools78, + author = "Steven C. Johnson and Michael E. Lesk", + title = "Language Development Tools", + journal = j-BSTJ, + year = "1978", + volume = "57", + number = "6", + pages = "2155--2176", + month = jul # "\emdash " # aug, +} + +@InCollection{Johnson:tools87, + author = "Steven C. Johnson and Michael E. Lesk", + title = "Language Development Tools", + booktitle = "{UNIX} System Readings and Applications", + publisher = pub-PH, + address = pub-PH:adr, + year = "1987", + pages = "245--265", + note = "Reprinted from {The} {Bell} {System} {Technical} + {Journal}, 1978", +} + +@Book{Johnson:XWA89, + author = "Eric F. Johnson and Kevin Reichard", + title = "X Window Applications Programming", + publisher = pub-MIS, + year = "1989", + address = pub-MIS:adr, + ISBN = "1-55828-016-2", + LCCN = "QA76.76.W56 J64 1989", + pages = "xxii + 562", + bibdate = "Wed Dec 15 10:35:41 1993", +} + +@InCollection{Johnson:yacc, + author = "Steven C. Johnson", + title = "Yacc: Yet Another Compiler Compiler", + booktitle = "{UNIX} Programmer's Manual", + publisher = pub-HRW, + address = pub-HRW:adr, + year = "1979", + volume = "2", + pages = "353--387", + note = "AT\&T Bell Laboratories Technical Report July 31, + 1978.", +} + +@Book{Johnson:LAM93, + author = "Eugene W. Johnson", + title = "Linear Algebra with {Maple} {V}", + publisher = pub-BC, + year = "1993", + LCCN = "QA185.D37 J64 1993", + ISBN = "0-534-13069-0", + pages = "xii + 142", + address = pub-BC:adr, + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Tue Nov 2 12:22:39 1993", +} + +@Book{Jones:IXW89, + author = "Oliver Jones", + title = "Introduction to the {X} {Window} {System}", + publisher = pub-PH, + address = pub-PH:adr, + year = "1989", + ISBN = "0-13-499997-5", + LCCN = "QA76.76.W56 J66 1989", + pages = "xii + 511", + bibdate = "Wed Dec 15 10:35:42 1993", +} + +@Article{Kahan:SIGPLAN-27-1-61, + author = "W. Kahan", + title = "Analysis and Refutation of the {LCAS}", + journal = j-SIGPLAN, + year = "1992", + volume = "27", + number = "1", + pages = "61--74", + month = jan, +} + +@Book{Kahaner:NSM89, + author = "David Kahaner and Cleve Moler and Stephen Nash", + title = "Numerical Methods and Software", + publisher = pub-PH, + address = pub-PH:adr, + year = "1989", + ISBN = "0-13-627258-4", + LCCN = "TA345 .K341 1989", + pages = "xii + 495", + bibdate = "Wed Dec 15 10:35:43 1993", +} + +@Misc{Kahn:c, + author = "Philippe Kahn", + year = "1987", + note = "Borland International, 1800 Green Hills Road, P. O. + Box 660005, Scotts Valley, CA 95066-0005. The quote + ``C is a write-only language'' was attributed to Kahn + by a trade journal columnist", +} + +@Article{Kahrs:ditroff, + author = "Mark Kahrs and Lee Moore", + title = "Adventures with Type\-set\-ter-In\-de\-pen\-dent + {TROFF}", + journal = j-USENIX-SCP, + year = "1984", + pages = "258--269", + month = jun # " 12--15", +} + +@Article{Kajiya:grey-scale, + author = "J. Kajiya and M. Ullner", + title = "Filtering High Quality Text for Display on Raster + Scan Devices", + journal = j-SIGGRAPH, + year = "1981", + volume = "15", + number = "3", + pages = "7--15", + month = aug, + note = "See more recent work in \cite{Naiman:grey-scale}.", +} + +@Book{Kane:MRA92, + author = "Gerry Kane and Joe Heinrich", + title = "{MIPS} {RISC} Architecture", + publisher = pub-PH, + address = pub-PH:adr, + year = "1992", + ISBN = "0-13-590472-2", + LCCN = "QA76.8.M52 K37 1992", + bibdate = "Wed Dec 15 10:35:45 1993", +} + +@Book{Kane:MRR87, + author = "Gerry Kane", + title = "{MIPS} R2000 {RISC} Architecture", + publisher = pub-PH, + address = pub-PH:adr, + year = "1987", + ISBN = "0-13-584749-4", + LCCN = "QA76.8.M52 K36 1987", + bibdate = "Wed Dec 15 17:51:38 1993", +} + +@Book{Kanigel:MWK91, + author = "Robert Kanigel", + title = "The Man Who Knew Infinity\emdash {A} Life of the + Genius Ramanujan", + publisher = pub-COLLMAC, + year = "1991", + ISBN = "0684192594", + LCCN = "QA29.R3 K36 1991", + address = pub-COLLMAC:adr, + pages = "ix + 438", + price = "US\$27.95", + acknowledgement = ack-nhfb, + bibdate = "Fri Apr 1 18:24:29 1994", +} + +@Book{Karin:SE87, + author = "Sidney Karin and Norris Parker Smith", + title = "The Supercomputer Era", + publisher = pub-HBJ, + address = pub-HBJ:adr, + year = "1987", + ISBN = "0-15-186787-9", + LCCN = "QA76.5 .K356 1987", + pages = "x + 313", + bibdate = "Wed Dec 15 10:35:49 1993", +} + +@Book{Karow:DFT87, + author = "Peter Karow", + title = "Digital Formats for Typefaces", + publisher = pub-URW, + address = pub-URW:adr, + year = "1987", + ISBN = "3-926515-01-5", + LCCN = "Z253.3 .K371 1987", + pages = "400", + bibdate = "Wed Dec 15 10:35:50 1993", +} + +@TechReport{Karp:TR-31-81, + author = "R. M. Karp and M. O. Rabin", + title = "Efficient Randomized Pattern-Matching Algorithms", + institution = "Harvard University", + year = "1981", + number = "TR-31-81", + address = "Cambridge, MA, USA", + bibdate = "Sat Nov 7 11:42:35 1992", +} + +@Book{Katzan:F78, + author = "Harry {Katzan, Jr.}", + title = "Fortran 77", + publisher = pub-VNR, + address = pub-VNR:adr, + year = "1978", + series = "Computer Science Series", + ISBN = "0-442-24278-6", + LCCN = "QA76.73 .F25 K373 1978", + pages = "xvi + 207", + bibdate = "Wed Dec 15 10:35:56 1993", +} + +@Book{Kaufman:FCB78, + author = "Roger Emanuel Kaufman", + title = "A Fortran Coloring Book", + publisher = pub-MIT, + address = pub-MIT:adr, + year = "1978", + ISBN = "0-262-61026-4", + LCCN = "QA76.73 F25 K38 1978", + pages = "285", + price = "US\$6.95", + bibdate = "Mon Dec 13 17:19:24 1993", +} + +@Book{Kay:GFF92, + author = "David C. Kay and John R. Levine", + title = "Graphics File Formats", + publisher = pub-WINDCREST, + year = "1992", + ISBN = "0-8306-3060-0 (hardcover), 0-8306-3059-7 (paperback)", + LCCN = "T385 .K376 1992", + pages = "xviii + 278", + address = pub-WINDCREST:adr, + bibdate = "Wed Dec 15 10:36:02 1993", + libnote = "Not yet in my library.", +} + +@Book{Kehoe:ZAI93, + author = "Brendan P. Kehoe", + title = "Zen and the Art of the Internet: A Beginner's Guide", + publisher = pub-PH, + year = "1993", + address = pub-PH:adr, + edition = "Second", + ISBN = "0-13-010778-6", + LCCN = "TK5105.8.I57 K44 1993", + pages = "xv + 112", + bibdate = "Wed Dec 15 10:36:04 1993", +} + +@Book{Kernighan:CPL78, + author = "Brian W. Kernighan and Dennis M. Ritchie", + title = "The C Programming Language", + publisher = pub-PH, + address = pub-PH:adr, + year = "1978", + ISBN = "0-13-110163-3", + LCCN = "QA76.73 .C15 K47 1978", + pages = "x + 228", + bibdate = "Wed Dec 15 10:36:07 1993", +} + +@Book{Kernighan:CPL88, + author = "Brian W. Kernighan and Dennis M. Ritchie", + title = "The C Programming Language", + publisher = pub-PH, + address = pub-PH:adr, + year = "1988", + edition = "Second", + ISBN = "0-13-110362-8", + LCCN = "QA76.73.C15 K47 1988", + pages = "xii + 272", + bibdate = "Wed Dec 15 10:36:09 1993", +} + +@TechReport{Kernighan:ditroff, + author = "Brian W. Kernighan", + title = "A Typesetter-independent {TROFF}", + institution = pub-ATT-BELL, + year = "1981", + number = "Computer Science Report 91", + address = pub-ATT-BELL:adr, +} + +@Book{Kernighan:EPS74, + author = "Brian W. Kernighan and Peter J. Plauger", + title = "The Elements of Programming Style", + publisher = pub-MH, + address = pub-MH:adr, + year = "1974", + libnote = "Not yet in my library.", + ISBN = "0-07-034199-0", + LCCN = "QA76.6 .K47", + pages = "147", + bibdate = "Wed Dec 15 10:36:10 1993", +} + +@Book{Kernighan:EPS78, + author = "Brian W. Kernighan and Peter J. Plauger", + title = "The Elements of Programming Style", + publisher = pub-MH, + address = pub-MH:adr, + edition = "Second", + year = "1978", + libnote = "Not yet in my library.", + ISBN = "0-07-034207-5", + LCCN = "QA76.6 .K39 1978", + pages = "xii + 168", + bibdate = "Wed Dec 15 10:36:10 1993", +} + +@TechReport{Kernighan:pascal, + author = "Brian W. Kernighan", + title = "Why {Pascal} is not my favorite programming language", + institution = pub-ATT-BELL, + year = "1981", + number = "Computer Science Report 100", + month = jul, + address = pub-ATT-BELL:adr, +} + +@Article{Kernighan:pic, + author = "Brian W. Kernighan", + title = "{PIC}\emdash A language for typesetting graphics", + journal = j-SPE, + year = "1982", + volume = "12", + number = "1", + pages = "1--22", + month = jan, +} + +@Book{Kernighan:SF76, + author = "Brian W. Kernighan and Peter J. Plauger", + title = "Software Tools", + publisher = pub-AW, + address = pub-AW:adr, + year = "1976", + ISBN = "0-201-03669-X", + LCCN = "QA76.6 .K42 1976", + pages = "338", + bibdate = "Wed Dec 15 10:36:11 1993", +} + +@Book{Kernighan:STP81, + author = "Brian W. Kernighan and Peter J. Plauger", + title = "Software Tools in Pascal", + publisher = pub-AW, + address = pub-AW:adr, + year = "1981", + price = "US\$13.95", + ISBN = "0-201-10342-7", + LCCN = "QA76.6 .K493", + pages = "ix + 366", + bibdate = "Wed Dec 15 10:36:12 1993", +} + +@Book{Kernighan:UPE84, + author = "Brian W. Kernighan and Rob Pike", + title = "The {UNIX} Programming Environment", + publisher = pub-PH, + address = pub-PH:adr, + year = "1984", + ISBN = "0-13-937699-2 (hardcover), 0-13-937681-X (paperback)", + LCCN = "QA76.76.O63 K48 1984", + pages = "x + 357", + bibdate = "Wed Dec 15 10:36:12 1993", +} + +@Book{Kerrigan:MF93, + author = "James F. Kerrigan", + title = "Migrating to Fortran 90", + publisher = pub-OR, + year = "1993", + ISBN = "1-56592-049-X", + address = pub-OR:adr, + month = oct, + pages = "315", + price = "US\$24.95", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Mon Jan 3 18:29:56 1994", +} + +@Book{Kessener:DSR86, + author = "L. R. A. Kessener and F. J. Peters and M. L. P. van + Lierop", + title = "Data Structures for Raster Graphics", + publisher = pub-SV, + address = pub-SV:adr, + year = "1986", + ISBN = "0-387-16310-7", + LCCN = "QA76.9.D35 D381 1986", + pages = "vi + 201", + bibdate = "Wed Dec 15 10:36:14 1993", +} + +@Book{Kessler:LOS88, + author = "Robert R. Kessler", + title = "{LISP}, Objects, and Symbolic Programming", + publisher = pub-SF, + address = pub-SF:adr, + year = "1988", + ISBN = "0-673-39773-4", + LCCN = "QA76.73.L23 K47 1988", + pages = "xii + 644", + bibdate = "Wed Dec 15 10:36:15 1993", +} + +@Article{Keyes:IBMJRD-32-1-24, + author = "Robert W. Keyes", + title = "Miniaturization of electronics and its limits", + journal = j-IBM-JRD, + year = "1988", + volume = "32", + number = "1", + pages = "24--28", + month = jan, + bibdate = "Sun Mar 27 18:26:09 1994", +} + +@Article{Khayat:arabic-dot-matrix, + author = "M. G. Khayat", + title = "Printing {Arabic} Text on Dot Matrix Printers", + journal = j-SPE, + year = "1986", + volume = "16", + number = "2", + pages = "165--172", + month = feb, +} + +@Book{Klerer:DCU67, + editor = "Melvin Klerer and Granino A. Korn", + title = "Digital Computer User's Handbook", + publisher = pub-MH, + address = pub-MH:adr, + year = "1967", + LCCN = "QA76.5 .K524", + bibdate = "Wed Dec 15 17:52:19 1993", +} + +@Book{Knott:KFF64, + author = "L. J. Comrie", + title = "Knott's Four-Figure Mathematical Tables", + publisher = pub-WRC, + address = pub-WRC:adr, + year = "1964", +} + +@Book{Knuth:ACP68-1, + author = "Donald E. Knuth", + title = "Fundamental Algorithms", + series = "The Art of Computer Programming", + publisher = pub-AW, + address = pub-AW:adr, + year = "{\noopsort{1968a}}1968", + volume = "1", + ISBN = "0-201-03803-X", + LCCN = "QA76.5 .K74", + pages= "xxi + 634", + price = "US\$19.75", + bibdate = "Wed Dec 15 15:47:36 1993", +} + +@Book{Knuth:ACP69-2, + author = "Donald E. Knuth", + title = "Semi\-nu\-mer\-i\-cal Algorithms", + series = "The Art of Computer Programming", + publisher = pub-AW, + address = pub-AW:adr, + year = "{\noopsort{1968c}}1969", + volume = "2", + ISBN = "0-201-03802-1", + LCCN = "QA76.5 .K57", + pages= "xi + 624", + price = "US\$19.75", + bibdate = "Wed Dec 15 15:47:38 1993", +} + +@Book{Knuth:ACP73-1, + author = "Donald E. Knuth", + title = "Fundamental Algorithms", + series = "The Art of Computer Programming", + publisher = pub-AW, + address = pub-AW:adr, + year = "{\noopsort{1968b}}1973", + volume = "1", + edition = "Second", + ISBN = "0-201-03809-9", + LCCN = "QA76.6 .K641 1973", + bibdate = "Wed Dec 15 10:36:21 1993", +} + +@Book{Knuth:ACP73-3, + author = "Donald E. Knuth", + title = "Sorting and Searching", + series = "The Art of Computer Programming", + publisher = pub-AW, + address = pub-AW:adr, + year = "1973", + volume = "3", + ISBN = "0-201-03803-X", + LCCN = "QA76.5 .K74", + pages= "xi + 723", + bibdate = "Wed Dec 15 15:47:47 1993", +} + +@Book{Knuth:CSS93, + author = "Donald E. Knuth and Silvio Levy", + title = "The {CWEB} System of Structured Documentation, Version + 3.0", + publisher = pub-AW, + year = "1993", + ISBN = "0-201-57569-8", + LCCN = "QA76.9.D3 K6 1993", + address = pub-AW:adr, + acknowledgement = ack-nhfb, + bibdate = "Thu Dec 16 09:04:49 1993", +} + +@Book{Knuth:ct-a, + author = "Donald E. Knuth", + title = "The {\TeX}book", + publisher = pub-AW, + address = pub-AW:adr, + year = "1986", + volume = "{\noopsort{1986a}}A", + series = "Computers and Typesetting", + ISBN = "0-201-13447-0", + LCCN = "Z253.4.T47 K58 1986", + pages = "ix + 483", + bibdate = "Wed Dec 15 10:36:52 1993", +} + +@Book{Knuth:ct-b, + author = "Donald E. Knuth", + title = "{\TeX}: The Program", + publisher = pub-AW, + address = pub-AW:adr, + year = "{\noopsort{1986b}}1986", + volume = "B", + series = "Computers and Typesetting", + ISBN = "0-201-13437-3", + LCCN = "Z253.4.T47 K578 1986", + pages = "xv + 594", + bibdate = "Wed Dec 15 10:36:54 1993", +} + +@Book{Knuth:ct-c, + author = "Donald E. Knuth", + title = "The \MF{} book", + publisher = pub-AW, + address = pub-AW:adr, + year = "{\noopsort{1986c}}1986", + volume = "C", + series = "Computers and Typesetting", + ISBN = "0-201-13445-4", + LCCN = "Z250.8.M46 K58 1986", + pages = "xi + 361", + bibdate = "Wed Dec 15 10:37:29 1993", +} + +@Book{Knuth:ct-d, + author = "Donald E. Knuth", + title = "\MF{}: The Program", + publisher = pub-AW, + address = pub-AW:adr, + year = "{\noopsort{1986d}}1986", + volume = "D", + series = "Computers and Typesetting", + ISBN = "0-201-13438-1", + LCCN = "Z250.8.M46 K578 1986", + pages = "xv + 560", + bibdate = "Wed Dec 15 10:37:32 1993", +} + +@Book{Knuth:ct-e, + author = "Donald E. Knuth", + title = "Computer Modern Typefaces", + publisher = pub-AW, + address = pub-AW:adr, + year = "{\noopsort{1986e}}1986", + volume = "E", + series = "Computers and Typesetting", + ISBN = "0-201-13446-2", + LCCN = "Z250.8.M46 K574 1986", + pages = "xv + 588", + bibdate = "Wed Dec 15 10:37:33 1993", +} + +@Article{Knuth:goto, + author = "D. E. Knuth", + title = "Structured Programming with Go To Statements", + journal = j-CS, + volume = "6", + year = "1974", + pages = "261--301", + note = "This paper is a response to + \cite{Dijkstra:goto-harmful}.", +} + +@Article{Knuth:halftone, + author = "Donald E. Knuth", + title = "Digital Halftones by Dot Diffusion", + journal = j-TOGS, + year = "1987", + volume = "6", + number = "4", + pages = "245--273", + month = oct, +} + +@Article{Knuth:literate, + author = "Donald E. Knuth", + title = "Literate Programming", + journal = j-CJ, + year = "1984", + volume = "27", + pages = "97--111", +} + +@Manual{Knuth:math-writing, + author = "Donald E. Knuth and Tracy Larrabee and Paul M. + Roberts", + title = "Mathematical Writing", + organization = "Mathematical Association of America Notes Number 14", + year = "1989", + ISBN = "0-88385-063-X", +} + +@Article{Knuth:new-tex-mf, + author = "Donald E. Knuth and Joe Weening", + title = "New {\TeX\slash \METAFONT} sources available on + {Stanford's} master archive", + journal = j-TEXHAX, + year = "1990", + volume = "90", + number = "13", + month = jan, +} + +@InCollection{Knuth:SPW90, + author = "Donald E. Knuth", + title = "A Simple Program Whose Proof Isn't", + booktitle = "Beauty is our business: a birthday salute to {Edsger + W. Dijkstra}", + publisher = pub-SV, + year = "1990", + ISBN = "0-387-97299-4", + LCCN = "QA76 .B326 1990", + editor = "W. H. J. Feijen and A. J. M. van Gasteren and D. Gries + and J. Misra", + address = pub-SV:adr, + chapter = "27", + pages = "233--242 (of xix + 453)", + acknowledgement = ack-nhfb, + note = "This paper discusses the algorithm used in {\TeX} for + converting between decimal and scaled fixed-point + binary values, and for guaranteeing a minimum number + of digits in the decimal representation. See also + \cite{Clinger:floating-point-input} for decimal to + binary conversion, + \cite{Steele:floating-point-output} for binary to + decimal conversion, and \cite{Gries:BDO90} for an + alternate proof of Knuth's algorithm.", + bibdate = "Sun Mar 27 17:53:57 1994", +} + +@Article{Knuth:string-search, + author = "Donald E. Knuth and J. H. Morris and V. R. Pratt", + title = "Fast pattern matching in strings", + journal = j-SIAM-J-COMP, + year = "1977", + volume = "6", + number = "2", + pages = "323--350", + month = jun, + note = "See also \cite{Boyer:string-search} and + \cite{Sunday:string-search}.", +} + +@Book{Knuth:TB84, + author = "Donald E. Knuth", + title = "The {\TeX}book", + publisher = pub-AW, + address = pub-AW:adr, + year = "1984", + ISBN = "0-201-13448-9", + LCCN = "Z253.4.T47 K58 1984", + pages = "ix + 483", + bibdate = "Wed Dec 15 10:37:34 1993", +} + +@Article{Knuth:tex-3.0, + author = "Donald E. Knuth", + title = "Calling all Grand Wizards", + journal = j-TEXHAX, + year = "1989", + volume = "89", + number = "98", + month = nov, +} + +@TechReport{Knuth:tex-errors, + author = "Donald E. Knuth", + title = "The Errors of {\TeX}", + institution = pub-STAN-CS, + address = pub-STAN-CS:adr, + year = "1988", + number = "{STAN-CS-88-1223}", + month = sep, +} + +@Article{Knuth:tex-errors-2, + author = "Donald E. Knuth", + title = "The Errors of {\TeX}", + journal = j-SPE, + year = "1989", + volume = "19", + number = "7", + pages = "607--681", + month = jul, + note = "This is an updated version of + \cite{Knuth:tex-errors}.", +} + +@Book{Knuth:TMN79, + author = "Donald E. Knuth", + title = "{\TeX} and {\METAFONT}\emdash New Directions in + Typesetting", + publisher = pub-DP, + address = pub-DP:adr, + year = "1979", + ISBN = "0-932376-02-9", + LCCN = "Z253.3 .K58 1979", + pages = "xi + 201 + 105", + bibdate = "Wed Dec 15 10:37:42 1993", +} + +@Book{Knuth:LP92, + author = "Donald E. Knuth", + title = "Literate Programming", + publisher = pub-SUCSLI, + address = pub-SUCSLI:adr, + series = "CSLI Lecture Notes Number 27", + year = "1992", + ISBN = "0-937-07380-6 (paper), 0-937-07381-4 (cloth)", + LCCN = "QA76.6.K644", + pages = "xv + 368", + price = "US\$24.95", + acknowledgement = ack-nhfb, + bibdate = "Mon Jan 3 19:06:28 1994", +} + +@Article{Knuth:virtual-fonts, + author = "Donald E. Knuth", + title = "Virtual fonts: More fun for Grand Wizards", + journal = j-TEXHAX, + year = "1990", + volume = "90", + number = "11 and 12", + month = jan, +} + +@Book{Kochan:UN89, + author = "Stephen G. Kochan and Patrick H. Wood", + title = "{UNIX} Networking", + publisher = pub-HAYDEN, + address = pub-HAYDEN:adr, + year = "1989", + ISBN = "0-672-48440-4", + LCCN = "QA76.76.O63 U546 1989", + pages = "viii + 400", + bibdate = "Wed Dec 15 10:37:44 1993", +} + +@Book{Kogge:APC81, + author = "Peter M. Kogge", + title = "The Architecture of Pipelined Computers", + publisher = pub-MH, + address = pub-MH:adr, + year = "1981", + ISBN = "0-07-035237-2", + LCCN = "QA76.5 .K587", + pages = "xii + 334", + bibdate = "Wed Dec 15 10:37:46 1993", +} + +@Book{Kopka:LE90, + author = "Helmut Kopka", + title = "{\LaTeX{}}\emdash Eine Ein\-f{\"u}hr\-ung", + publisher = pub-AW, + address = pub-AW:adr, + year = "1990", + ISBN = "3-89319-199-2", +} + +@Book{Kopka:GLD93, + author = "Helmut Kopka and Patrick W. Daly", + title = "A Guide to {\LaTeX}: Document Preparation for + Beginners and Advanced Users", + ISBN = "0-201-56889-6", + publisher = pub-AW, + year = "1993", + address = pub-AW:adr, + price = "US\$34.50", + acknowledgement = ack-nhfb, + bibdate = "Thu Jan 20 12:34:31 1994", +} + +@Book{Krieger:IT90, + author = "Jost Krieger and Norbert Schwarz", + title = "Introduction to {\TeX}", + publisher = pub-AWE, + year = "1990", + address = pub-AWE:adr, + ISBN = "0-201-51141-X", +} + +@Book{Krol:WIU93, + author = "Ed Krol", + title = "The Whole Internet User's Guide and Catalog", + publisher = pub-OR, + year = "1993", + address = pub-OR:adr, + ISBN = "1-56592-025-2", + LCCN = "TK5105.875.I57 K86 1992", + pages = "xxiv + 376", + price = "US\$24.95", + bibdate = "Wed Dec 15 10:37:48 1993", +} + +@Article{Krommes:fortran-web, + author = "John Krommes", + title = "{\FWEB} ({Krommes}) vs. {\FWEB} ({Avenarius} and + {Oppermann})", + journal = j-TEXHAX, + year = "1990", + volume = "90", + number = "19", + month = feb, +} + +@Book{Kronsjo:CCS85, + author = "L. Kronsj{\"{o}}", + title = "Computational Complexity of Sequential and Parallel + Algorithms", + publisher = pub-WI, + address = pub-WI:adr, + year = "1985", + price = "US\$50.00", + ISBN = "0-471-90814-2", + LCCN = "QA76.6 .K7631 1985", + pages = "x + 224", + bibdate = "Wed Dec 15 10:37:49 1993", +} + +@Book{Kruse:DSP84, + author = "Robert L. Kruse", + title = "Data Structures and Program Design", + publisher = pub-PH, + address = pub-PH:adr, + year = "1984", + series = pub-PH # " Software Series, Editor: Brian W. + Kernighan", + price = "US\$28.95", + ISBN = "0-13-196253-1", + LCCN = "QA76.6 .K77 1984", + pages = "xxi + 486", + bibdate = "Wed Dec 15 10:37:49 1993", +} + +@Book{Kunii:ACG86, + editor = "Tosiyasu L. Kunii", + title = "Advanced Computer Graphics", + publisher = pub-SV, + address = pub-SV:adr, + year = "1986", + note = "Proceedings of Computer Graphics Tokyo '86.", + price = "US\$45.00", + ISBN = "0-387-70011-0", + LCCN = "T385 .C5931 1986", + pages = "ix + 504", + bibdate = "Wed Dec 15 10:37:50 1993", +} + +@Book{Kunii:CGT83, + editor = "Tosiyasu L. Kunii", + title = "Computer Graphics\emdash Theory and Applications", + publisher = pub-SV, + address = pub-SV:adr, + year = "1983", + note = "Proceedings of Intergraphics '83.", + ISBN = "0-387-70001-3", + LCCN = "T385 .I49 1983", + pages = "ix + 530", + bibdate = "Wed Dec 15 10:37:51 1993", +} + +@Book{Kunii:CGV85, + editor = "Tosiyasu L. Kunii", + title = "Computer Graphics\emdash Visual Technology and Art", + publisher = pub-SV, + address = pub-SV:adr, + year = "1985", + note = "Proceedings of Computer Graphics Tokyo '85.", + price = "US\$45.00", + ISBN = "0-387-70009-9, 3-540-70009-9, 4-431-70009-9", + LCCN = "T385.C5995 1985", + pages = "ix + 382", + bibdate = "Wed Dec 15 10:37:51 1993", +} + +@Book{Kunii:FCG85, + editor = "Tosiyasu L. Kunii", + title = "Frontiers in Computer Graphics", + publisher = pub-SV, + address = pub-SV:adr, + year = "1985", + note = "Proceedings of Computer Graphics Tokyo '84.", + ISBN = "0-387-70004-8, 3-540-70004-8, 4-431-70004-8", + LCCN = "T385 .C593 1984", + pages = "ix + 443", + bibdate = "Wed Dec 15 10:37:54 1993", +} + +@Book{Lafore:ALP84, + author = "Robert Lafore", + title = "Assembly Language Primer for the {IBM} {PC} and {XT}", + publisher = pub-PW, + address = pub-PW:adr, + year = "1984", + note = "A companion book for \cite{Morgan:BAR84}, written for + novice assembly-language programmers, with + considerable emphasis on the IBM PC. More elementary + than \cite{Bradley:ALP84}.", + ISBN = "0-452-25497-3", + LCCN = "QA76.8.I2594 L34 1984", + pages = "viii + 501", + bibdate = "Wed Dec 15 10:39:14 1993", +} + +@Misc{LALR:lalr, + key = "LALR", + author = "LALR Research", + title = "{LALR} 3.0", + note = "P. O. Box 50755, Knoxville, TN 37950.", + year = "1987", +} + +@Book{Lamport:LDP85, + author = "Leslie Lamport", + title = "{\LaTeX}\emdash A Document Preparation System\emdash + User's Guide and Reference Manual", + publisher = pub-AW, + address = pub-AW:adr, + year = "1985", + ISBN = "0-201-15790-X", + LCCN = "Z253.4.L38 L35 1986", + pages = "xiv + 242", + bibdate = "Wed Dec 15 10:38:04 1993", +} + +@Book{Lapin:PCU87, + author = "J. E. Lapin", + title = "Portable C and {UNIX} Programming", + publisher = pub-PH, + address = pub-PH:adr, + year = "1987", + ISBN = "0-13-686494-5", + LCCN = "QA76.73.C15 L36 1987", + pages = "xiv + 249", + bibdate = "Wed Dec 15 10:38:06 1993", +} + +@Book{Larsen:LD89, + author = "Steen Larsen", + title = "{\LaTeX} {p\aa} dansk", + publisher = pub-UNIC, + year = "1989", + address = pub-UNIC:adr, + ISBN = "87-7252-089-2", + pages= "viii + 111", + bibdate = "Wed Dec 15 17:54:21 1993", +} + +@TechReport{Lawson:sf3, + author = "C. L. Lawson and J. A. Flynn", + title = "{SFTRAN3} Programmer's Reference Manual", + institution = pub-JPL, + year = "1978", + number = "1846-98", + address = pub-JPL:adr, + month = dec, +} + +@TechReport{Lawson:sftran, + author = "C. L. Lawson", + title = "{SFTRAN} Language Constructs Supported by a Portable + Preprocessor", + institution = pub-JPL, + year = "1978", + number = "JPL Section 366 Internal Computing Memorandum 437", + address = pub-JPL:adr, + month = jan, +} + +@TechReport{Lawson:sftran-conversion, + author = "C. L. Lawson and W. V. Snyder", + title = "Conversion of {SFTRAN} Programs to {SFTRAN 3}", + institution = pub-JPL, + year = "1978", + number = "1846-99", + address = pub-JPL:adr, + month = dec, +} + +@Book{Lawson:SLS74, + author = "Charles L. Lawson and Richard J. Hanson", + title = "Solving Least Squares Problems", + publisher = pub-PH, + address = pub-PH:adr, + year = "1974", + series = pub-PH # " Series in Automatic Computation", + ISBN = "0-13-822585-0", + LCCN = "QA275 .L425 1974", + pages = "xii + 340", + bibdate = "Wed Dec 15 10:38:07 1993", +} + +@Article{Le-Ngoc:fast-hartley-transform, + author = "Tho Le-Ngoc and Minh Tue Vo", + title = "Implementation and Performance of the Fast {Hartley} + Transform", + journal = j-IEEE-MICRO, + year = "1989", + volume = "9", + number = "5", + pages = "20--27", + month = oct, +} + +@Book{Ledgard:PS79, + author = "Henry F. Ledgard and John F. Hueras and Paul A. + Nagin", + title = "Pascal with Style", + publisher = pub-HAYDEN, + address = pub-HAYDEN:adr, + year = "1979", + ISBN = "0-8104-5124-7", + LCCN = "QA76.73.P2 L4", + pages = "210", + bibdate = "Wed Dec 15 10:38:08 1993", +} + +@Book{Leffler:DIU89, + author = "Samuel J. Leffler and Marshall Kirk McKusick and + Michael J. Karels and John S. Quarterman", + title = "The Design and Implementation of the {4.3BSD UNIX} + Operating System", + publisher = pub-AW, + address = pub-AW:adr, + year = "1989", + ISBN = "0-201-06196-1", + LCCN = "QA76.76.O63 D4741 1989", + pages = "xxii + 471", + bibdate = "Wed Dec 15 10:38:09 1993", +} + +@InCollection{Lesk:lex, + author = "Michael E. Lesk and Eric Schmidt", + title = "Lex\emdash A Lexical Analyzer Generator", + booktitle = "{UNIX} Programmer's Manual", + publisher = pub-HRW, + address = pub-HRW:adr, + year = "1979", + volume = "2", + pages = "388--400", + note = "AT\&T Bell Laboratories Technical Report in 1975.", +} + +@Book{Levine:LY92, + author = "John R. Levine and Tony Mason and Doug Brown", + title = "{\tt lex} \& {\tt yacc}", + publisher = pub-OR, + year = "1992", + ISBN = "1-56592-000-7", + LCCN = "QA76.76.U84M37 1992", + pages = "xxii + 366", + address = pub-OR:adr, + edition = "Second", + price = "US\$29.95", + bibdate = "Wed Dec 15 10:38:13 1993", +} + +@Book{Levy:CPA80, + author = "Henry M. Levy and Richard H. {Eckhouse, Jr.}", + title = "Computer Programming and Architecture--the {VAX-11}", + publisher = pub-DP, + year = "1980", + address = pub-DP:adr, + ISBN = "0-932376-07-X", + LCCN = "QA76.8 .V37 L48 1980", + pages = "xxi + 407", + bibdate = "Wed Dec 15 10:38:14 1993", +} + +@Book{Lewine:PPG91, + author = "Donald A. Lewine", + title = "{POSIX} programmer's guide: writing portable {UNIX} + programs with the {POSIX.1} standard", + publisher = pub-OR, + year = "1991", + address = pub-OR:adr, + LCCN = "QA76.76.O63 L487 1991b", + ISBN = "0-937175-73-0", + libnote = "Not yet in my library.", + bibdate = "Sat Mar 12 17:42:38 1994", +} + +@Book{Libes:LU89, + author = "Don Libes and Sandy Ressler", + title = "Life with {UNIX}", + publisher = pub-PH, + address = pub-PH:adr, + year = "1989", + ISBN = "0-13-536657-7", + LCCN = "QA76.76.O63 L52 1989", + pages = "xx + 346", + bibdate = "Wed Dec 15 10:38:15 1993", +} + +@Book{Lippman:CP91, + author = "Stanley B. Lippman", + title = "{C++} Primer", + publisher = pub-AW, + year = "1991", + address = pub-AW:adr, + edition = "Second", + ISBN = "0-201-54848-8", + LCCN = "QA76.73.C15 L57 1991", + pages = "xvi + 614", + bibdate = "Wed Dec 15 10:38:15 1993", +} + +@Book{Liu:MS84, + author = "Yu-Cheng Liu and Glenn A. Gibson", + title = "Microcomputer Systems: The 8086\slash 8088 Family. + Architecture, Programming, and Design", + publisher = pub-PH, + address = pub-PH:adr, + year = "1984", + note = "A broad treatment of the Intel 8086 and 8088, with + shorter surveys of the 8087, 80186, and 80286. Nothing + specific to the IBM PC.", + ISBN = "0-13-580944-4", + LCCN = "QA76.8.I292 L58 1984", + pages = "ix + 550", + bibdate = "Wed Dec 15 10:38:16 1993", +} + +@Book{Lomuto:UP83, + author = "Ann Nicols Lomuto and Nico Lomuto", + title = "A {UNIX} Primer", + publisher = pub-PH, + address = pub-PH:adr, + year = "1983", + series = pub-PH # " Software Series, Editor: Brian W. + Kernighan", + ISBN = "0-13-938886-9", + LCCN = "QA76.8.U65 L65 1983", + pages = "xvi + 239", + bibdate = "Wed Dec 15 10:38:17 1993", +} + +@Book{Lord:MDS84, + author = "E. A. Lord and C. B. Wilson", + title = "The Mathematical Description of Shape and Form", + publisher = pub-EH, + address = pub-EH:adr, + year = "1984", + series = "Ellis Horwood Series in Mathematics and its + Applications, Editor: G. M. Bell", + ISBN = "0-853-12722-0, 0-853-12726-3, 0-470-20043-X (paperback)", + LCCN = "QA501 .L86 1984", + pages = "260", + bibdate = "Wed Dec 15 10:38:17 1993", +} + +@Book{Lorin:SSS75, + author = "Harold Lorin", + title = "Sorting and Sort Systems", + publisher = pub-AW, + address = pub-AW:adr, + year = "1975", + series = "The Systems Programming Series", + ISBN = "0-201-14453-0", + LCCN = "QA76.5 .L577 1975", + pages = "xv + 373", + bibdate = "Wed Dec 15 10:38:19 1993", +} + +@Book{Lunde:UJI93, + author = "Ken Lunde", + title = "Understanding Japanese Information Processing", + publisher = pub-OR, + year = "1993", + ISBN = "1-56592-043-0", + address = pub-OR:adr, + price = "US\$29.95", + pages = "xxxii + 435", + bibdate = "Tue Oct 5 13:27:12 1993", +} + +@Book{Luke:ACM77, + author = "Yudell L. Luke", + title = "Algorithms for the Computation of Mathematical + Functions", + publisher = pub-AP, + address = pub-AP:adr, + year = "1977", + WrongISBN = "0-12-459940-6", + ISBN = "0-12-459940-0", + LCCN = "QA351 .L7961", + pages = "xiii + 284", + bibdate = "Wed Dec 15 10:38:19 1993", +} + +@Book{Luke:SFA69-1, + author = "Yudell L. Luke", + title = "The Special Functions and Their Approximations", + publisher = pub-AP, + address = pub-AP:adr, + year = "1969", + volume = "I", + series = "Mathematics in Science and Engineering, Volume 53-I, + Editor: Richard Bellman", + ISBN = "0-12-459901-X", + LCCN = "QA351 .L94 1969", + bibdate = "Wed Dec 15 17:55:35 1993", +} + +@Book{Luke:SFA69-2, + author = "Yudell L. Luke", + title = "The Special Functions and Their Approximations", + publisher = pub-AP, + address = pub-AP:adr, + year = "1969", + volume = "II", + series = "Mathematics in Science and Engineering, Volume 53-II, + Editor: Richard Bellman", + ISBN = "0-12-459902-8", + bibdate = "Wed Dec 15 17:55:38 1993", +} + +@Book{Lyche:MMC89, + author = "Tom Lyche and Larry L. Schumaker (Eds.)", + title = "Mathematical Methods in Computer Aided Geometric + Design", + publisher = pub-AP, + address = pub-AP:adr, + year = "1989", + ISBN = "0-12-460515-X", + LCCN = "QA448.D38 M381 1989", + pages = "xv + 611", + bibdate = "Wed Dec 15 10:38:41 1993", +} + +@Book{Mackenzie:CCS80, + author = "Charles E. Mackenzie", + title = "Coded Character Sets: History and Development", + publisher = pub-AW, + address = pub-AW:adr, + year = "1980", + series = "The Systems Programming Series", + price = "US\$24.95", + ISBN = "0-201-14460-3", + LCCN = "QA268 .M27 1980", + pages = "xxi + 513", + bibdate = "Wed Dec 15 10:38:43 1993", +} + +@Article{Malcolm:j-CACM-15-11-949, + author = "Michael A. Malcolm", + title = "Algorithms to Reveal Properties of Floating-Point + Arithmetic", + journal = j-CACM, + year = "1972", + volume = "15", + number = "11", + pages = "949--951", + month = nov, +} + +@Book{Mandelbrot:FGN83, + author = "Benoit B. Mandelbrot", + title = "The Fractal Geometry of Nature", + publisher = pub-WHF, + address = pub-WHF:adr, + year = "1983", + ISBN = "0-7167-1186-9", + LCCN = "QA447 .M271 1983", + pages = "460", + bibdate = "Wed Dec 15 10:38:44 1993", +} + +@Periodical{MAPLETECH, + key = "MAPLETECH", + title = "The Maple Technical Newsletter", + editor = "Tony Scott", + organization = "Mathematical Institute, University of Oxford", + issn = "1061-5733", + publisher = pub-BH, + address = pub-BH:adr, + note = "Published twice annually.", + acknowledgement = ack-nhfb, + bibdate = "Fri Apr 1 18:55:48 1994", +} + +@Book{Margulis:IMA90, + author = "Neal Margulis", + title = "i860 Microprocessor Architecture", + publisher = pub-MH, + address = pub-MH:adr, + year = "1990", + ISBN = "0-07-881645-9", + LCCN = "QA76.5.M37 1990", + pages = "xxiii + 631", + libnote = "Not yet in my library.", + bibdate = "Wed Dec 15 10:38:45 1993", +} + +@Book{Mason:LY90, + author = "Tony Mason and Doug Brown", + title = "{\tt lex} \& {\tt yacc}", + publisher = pub-OR, + year = "1990", + address = pub-OR:adr, + ISBN = "0-937175-49-8", + LCCN = "QA76.76.O63 M37 1990", + pages= "xviii + 216", + bibdate = "Wed Dec 15 17:56:32 1993", +} + +@Book{Mathworks:SEM92, + key = "MAT92", + author = "{The MathWorks, Inc.}", + title = "The Student Edition of {Matlab}", + publisher = pub-PH, + year = "1992", + address = pub-PH:adr, + ISBN = "0-13-855974-0", + LCCN = "QA297 .S8433 1992", + pages = "xiv + 494", + bibdate = "Wed Dec 15 10:38:47 1993", +} + +@Book{Matsen:SAA86, + editor = "F. A. Matsen and T. Tajima", + title = "Supercomputers\emdash Algorithms, Architectures, and + Scientific Computation", + publisher = pub-UTP, + address = pub-UTP:adr, + year = "1986", + ISBN = "0-292-70388-0", + LCCN = "QA76.5.S8945 1986", + pages = "vi + 480", + bibdate = "Wed Dec 15 10:38:48 1993", +} + +@Book{Mayoh:PSA82, + author = "Brian Mayoh", + title = "Problem Solving with Ada", + publisher = pub-JW, + address = pub-JW:adr, + year = "1982", + price = "US\$59.00", + ISBN = "0-471-10025-0", + LCCN = "QA76.8.A15 M38 1982", + pages = "viii + 233", + bibdate = "Wed Dec 15 10:38:49 1993", +} + +@Book{MC:68000, + author = "Motorola", + title = "{MC}68000 16\slash 32-Bit Microprocessor Programmer's + Reference Manual", + edition = "Fourth", + publisher = pub-PH, + address = pub-PH:adr, + year = "1984", + ISBN = "0-13-541400-8", + pages= "xiii + 218", + bibdate = "Wed Dec 15 17:58:10 1993", +} + +@Book{MC:68020, + author = "Motorola", + title = "{MC}68020 32-Bit Microprocessor User's Manual", + edition = "Second", + publisher = pub-MOTOROLA, + address = pub-MOTOROLA:adr, + year = "1985", + ISBN = "0-13-566878-6", + bibdate = "Wed Dec 15 17:59:02 1993", +} + +@Book{MC:68881, + author = "Motorola", + title = "{MC}68881 Floating-Point Coprocessor User's Manual", + edition = "Second", + publisher = pub-MOTOROLA, + address = pub-MOTOROLA:adr, + year = "1985", + bibdate = "Wed Dec 15 17:59:06 1993", +} + +@Book{MC:88100, + author = "Motorola", + title = "{MC}88100 {RISC} Microprocessor User's Manual", + edition = "Second", + publisher = pub-MOTOROLA, + address = pub-MOTOROLA:adr, + year = "1989", + ISBN = "0-13-567090-X", +} + +@Book{McCracken:CES88, + author = "Daniel D. McCracken and William I. Salmon", + title = "Computing for Engineers and Scientists with Fortran + 77", + publisher = pub-JW, + address = pub-JW:adr, + year = "1988", + edition = "Second", + ISBN = "0-471-62552-3", + LCCN = "TA345 .M3951 1988", + pages = "xiii + 730", + bibdate = "Wed Dec 15 10:38:50 1993", +} + +@Book{McCracken:SCC87, + author = "Daniel D. McCracken and William I. Salmon", + title = "A Second Course in Computer Science with Modula-2", + publisher = pub-JW, + address = pub-JW:adr, + year = "1987", + ISBN = "0-471-63111-6", + LCCN = "QA76.73.M63 M43 1987", + pages = "xiii + 464 + 10", + bibdate = "Wed Dec 15 10:39:03 1993", +} + +@Book{McGilton:IUS83, + author = "Henry McGilton and Rachel Morgan", + title = "Introducing the {UNIX} System", + publisher = pub-MH, + address = pub-MH:adr, + year = "1983", + price = "US\$18.95", + ISBN = "0-07-045001-3", + LCCN = "QA76.8.U65 M38 1983", + pages = "xix + 556", + bibdate = "Wed Dec 15 10:39:04 1993", +} + +@Book{McGilton:TTU90, + author = "Henry McGilton and Mary McNabb", + title = "Typesetting Tables on the {UNIX} System", + publisher = pub-TRILITHON, + year = "1990", + ISBN = "0-9626289-0-5", + LCCN = "Z253.4.U53 M33 1990", + price = "US\$22.00", + address = pub-TRILITHON:adr, + pages = "xxii + 282", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Tue Oct 12 18:19:25 1993", +} + +@Book{McKeown:MC82, + author = "G. P. McKeown and V. J. Rayward-Smith", + title = "Mathematics for Computing", + publisher = pub-JW, + address = pub-JW:adr, + year = "1982", + ISBN = "0-470-27268-6 (paperback)", + LCCN = "QA39.2 .M42 1982", + pages = "428", + bibdate = "Wed Dec 15 10:39:04 1993", +} + +@InCollection{McManus:color-printing, + author = "Paul A. McMannis", + title = "Color Printing", + booktitle = "Output Hardcopy Devices", + chapter = "17", + publisher = pub-AP, + address = pub-AP:adr, + year = "1988", + editor = "Robert C. Durbeck and Sol Sherr", + pages = "441--462", +} + +@Book{Metcalf:F8E87, + author = "Michael Metcalf and John Reid", + title = "Fortran 8x Explained", + publisher = pub-CP, + address = pub-CP:adr, + year = "1987", + note = "See also \cite{ANSI:ftn8x}.", + ISBN = "0-19-853751-4 (hardcover), 0-19-853731-X (paperback)", + LCCN = "QA76.73.F26 M48 1987", + pages = "xiv + 262", + bibdate = "Wed Dec 15 10:39:06 1993", +} + +@Book{Metcalf:FO82, + author = "Michael Metcalf", + title = "Fortran Optimization", + publisher = pub-AP, + address = pub-AP:adr, + year = "1982", + volume = "17", + series = "{A. P. I. C.} Studies in Data Processing", + ISBN = "0-12-492480-8", + LCCN = "QA76.73.F25 M48 1982", + pages = "xii + 242", + bibdate = "Wed Dec 15 10:39:08 1993", +} + +@Book{Metcalf:F9E90, + author = "Michael Metcalf and John Ker Reid", + title = "Fortran 90 Explained", + publisher = pub-OUP, + year = "1990", + ISBN = "0-19-853772-7", + LCCN = "QA76.73.F28 M48 1990", + address = pub-OUP:adr, + pages = "xiv + 294", + price = "US\$22.45", + libnote = "Not in my library", + bibdate = "Mon Jan 3 11:36:13 1994", +} + +@Book{Metropolis:FS86, + author = "N. Metropolis and D. H. Sharp and W. J. Worlton and + K. R. Ames", + title = "Frontiers of Supercomputing", + publisher = pub-UCP, + address = pub-UCP:adr, + year = "1986", + ISBN = "0-520-05190-4", + LCCN = "QA76.5 .F76 1983", + pages = "xxiv + 388", + bibdate = "Wed Dec 15 10:39:09 1993", +} + +@Book{Milenkovic:OS87, + author = "Milan Milenkovi{\'{c}}", + title = "Operating Systems", + publisher = pub-MH, + address = pub-MH:adr, + year = "1987", + price = "US\$38.95", + ISBN = "0-07-041920-5", + LCCN = "QA76.76.O63 M53 1987", + pages = "xix + 568", + bibdate = "Wed Dec 15 10:39:10 1993", +} + +@Book{Miller:ENS84, + author = "Webb Miller", + title = "The Engineering of Numerical Software", + publisher = pub-PH, + address = pub-PH:adr, + year = "1984", + series = pub-PH # " Series in Computational Mathematics, Cleve + Moler, Advisor", + ISBN = "0-13-279043-2", + LCCN = "QA297.M527 1984", + pages = "viii + 167", + bibdate = "Wed Dec 15 10:39:11 1993", +} + +@Book{Miller:OLU90, + author = "John David Miller", + title = "An {OPEN LOOK} at {UNIX}", + publisher = pub-MT, + year = "1990", + address = pub-MT:adr, + ISBN = "1-55851-057-5", + LCCN = "QA76.76.U84 M55 1990", + pages = "482", + bibdate = "Wed Dec 15 10:39:11 1993", +} + +@Book{Miller:TTI92, + author = "Mark A. Miller", + title = "Troubleshooting {TCP\slash IP} \emdash{} Analyzing the + Protocols of the {Internet}", + publisher = pub-MT, + year = "1992", + ISBN = "1-55851-268-3", + LCCN = "TK5105.5 .M52 1992", + pages= "588", + address = pub-MT:adr, + price = "US\$44.95", + bibdate = "Wed Dec 15 11:07:37 1993", +} + +@Book{Mitchell:32B86, + author = "H. J. Mitchell", + title = "32-Bit Microprocessors", + publisher = pub-MH, + address = pub-MH:adr, + year = "1986", + price = "US\$39.95", + ISBN = "0-07-042585-X", + LCCN = "QA76.5 .A135 1986", + pages = "248", + bibdate = "Wed Dec 15 10:39:13 1993", +} + +@Misc{MKS:awk, + author = "{Mortice Kern Systems, Inc.}", + title = "{MKSAWK}", + year = "1987", + note = "35 King Street North, Waterloo, Ontario, Canada, Tel: + (519) 884-2251. See also \cite{Aho:APL87}.", +} + +@Misc{MKS:yacc, + author = "{Mortice Kern Systems, Inc.}", + title = "{MKS LEX \& YACC}", + year = "1987", + note = "35 King Street North, Waterloo, Ontario, Canada, Tel: + (519) 884-2251.", +} + +@TechReport{More:minpack, + author = "Jorge J. Mor{\'{e}} and Burton S. Garbow and Kenneth + E. Hillstrom", + title = "User Guide for {MINPACK-1}", + institution = pub-ANL, + year = "1980", + number = "ANL-80-74", + address = pub-ANL:adr, + month = aug, +} + +@Book{Morgan:808682, + author = "Christopher L. Morgan and Mitchell Waite", + title = "8086\slash 8088 16-Bit Microprocessor Primer", + publisher = pub-MH, + address = pub-MH:adr, + year = "1982", + note = "A general book on the 8086 and 8088 with shorter + treatments of the 8087, 8089, 80186, and 80286, and + support chips. Nothing specific to the IBM PC.", + ISBN = "0-07-043109-4", + LCCN = "QA76.8.I292 M66 1982", + pages = "ix + 355", + bibdate = "Wed Dec 15 10:39:13 1993", +} + +@Book{Morgan:BAR84, + author = "Christopher L. Morgan", + title = "Bluebook of Assembly Routines for the {IBM} {PC} and + {XT}", + publisher = pub-PW, + address = pub-PW:adr, + year = "1984", + note = "A handbook collection of many assembly language + routines for the IBM PC. The graphics algorithms, + particular line-drawing, could be substantially + speeded up.", + ISBN = "0-452-25497-3", + LCCN = "QA76.8.I2594 M64 1984", + pages= "x + 244", + bibdate = "Wed Dec 15 18:01:11 1993", +} + +@Book{Morris:CME83, + author = "John Ll. Morris", + title = "Computational Methods in Elementary Numerical + Analysis", + publisher = pub-JW, + address = pub-JW:adr, + year = "1983", + price = "US\$56.00 (hardcover), US\$30.95 (paperback)", + ISBN = "0-471-10419-1 (hardcover), 0-471-10420-5 (paperback)", + LCCN = "555 M67 1983", + pages = "xii + 410", + bibdate = "Wed Dec 15 10:39:21 1993", +} + +@Proceedings{Morris:ridt, + title = "Raster Imaging and Digital Topography {II}\emdash + Papers from the second {RIDT} meeting, held in Boston, + Oct. 14--16, 1991", + year = "1991", + editor = "Robert A. Morris and Jacques Andr{\'e}", + publisher = pub-CUP, + address = pub-CUP:adr, + ISBN = "0-521-41764-3", + LCCN = "Z253.3 .R39 1991", + pages = "x + 217", + libnote = "Not in my library", +} + +@Book{Morse:80286, + author = "Stephen P. Morse and Douglas J. Albert", + title = "The 80286 Architecture", + publisher = pub-JW, + address = pub-JW:adr, + year = "1986", + note = "Morse is the chief architect of the Intel 8086. See + also \cite{Intel:286-prm}.", + ISBN = "0-471-83185-9", + LCCN = "QA76.8.I2927 M67 1986", + pages = "xiii + 279", + bibdate = "Wed Dec 15 10:39:24 1993", +} + +@Book{Mortenson:GM85, + author = "Michael E. Mortenson", + title = "Geometric Modeling", + publisher = pub-WI, + address = pub-WI:adr, + year = "1985", + ISBN = "0-471-88279-8", + LCCN = "QA447 .M62 1985", + pages = "xvi + 763", + bibdate = "Wed Dec 15 10:39:52 1993", +} + +@Book{Mui:XWS92, + author = "Linda Mui and Eric Pearce", + title = "{X} {Window} {System} Administrator's Guide for {X11} + Release 4 and Release 5", + publisher = pub-OR, + year = "1992", + price = "US\$29.95 (without CD ROM), US\$59.95 (with CD ROM)", + ISBN = "0-937175-83-8, 1-56592-052-X (with CD ROM)", + LCCN = "QA76.76.W56 D44 v.8 1992", + address = pub-OR:adr, + pages = "xxiv + 346", + note = "Contains CD ROM with X11R4 and X11R5 source code, plus + compiled versions for Sun 3 SunOS 4.1.1, Sun 4 SunOS + 4.1.1, DECstation ULTRIX 4.2, and IBM RS/6000 AIX + 3.2.", + acknowledgement = ack-nhfb, + bibdate = "Sat Nov 13 11:49:33 1993", +} + +@Book{Muir:TTD60, + author = "Thomas Muir", + title = "A Treatise on the Theory of Determinants", + publisher = pub-DOV, + address = pub-DOV:adr, + year = "1960", + note = "Corrected printing of the 1933 edition.", +} + +@Book{Myers:8MA88, + author = "Glenford J. Myers and David L. Budde", + title = "The 80960 Microprocessor Architecture", + publisher = pub-WI, + address = pub-WI:adr, + year = "1988", + ISBN = "0-471-61857-8", + LCCN = "QA76.8.I29284 M941 1988", + pages = "xiii + 255", + bibdate = "Wed Dec 15 10:39:54 1993", +} + +@Book{Myers:AST79, + author = "Glenford J. Myers", + title = "The Art of Software Testing", + publisher = pub-JW, + address = pub-JW:adr, + year = "1979", + series = "Business Data Processing, Editors: Richard G. Canning + and J. Daniel Cougar", + ISBN = "0-471-04328-1", + LCCN = "QA76.6 .M888 1979", + pages = "xi + 177", + bibdate = "Wed Dec 15 10:39:56 1993", +} + +@Article{Naiman:grey-scale, + author = "Avi Naiman and Alain Fournier", + title = "Rectangular Convolution for Fast Filtering of + Characters", + journal = j-SIGGRAPH, + year = "1987", + volume = "21", + number = "4", + pages = "233--242", + month = jul, + personalnote = "See e-mail from Alan Broder (\path|ajb@mitre.arpa| + 14-Oct-1988) regarding TeX DVI display on grey-scale + devices.", +} + +@Book{Nash:HSC90, + editor = "Stephen G. Nash", + title = "A History of Scientific Computing", + publisher = pub-AW # " and " # pub-ACM, + address = pub-AW # " and " # pub-ACM:adr, + year = "1990", + ISBN = "0-201-50814-1", + LCCN = "QA76.17 .H59 1990", + pages = "xix + 359", + bibdate = "Wed Dec 15 10:39:57 1993", +} + +@Book{Neider:OPG93, + author = "Jackie Neider and Tom Davis and Mason Woo", + title = "{OpenGL} Programming Guide\emdash The Official Guide + to Learning {OpenGL}, Release 1", + publisher = pub-AW, + year = "1993", + ISBN = "0-201-63274-8", + LCCN = "T385.N435 1993", + address = pub-AW:adr, + pages = "xiii + 516", + price = "US\$34.95", + libnote = "Not yet in my library.", + acknowledgement = ack-nhfb, + bibdate = "Tue Mar 1 13:14:39 1994", +} + +@Book{Nelson:SPM91, + author = "Greg {Nelson, editor}", + title = "Systems Programming with Modula-3", + publisher = pub-PH, + year = "1991", + address = pub-PH:adr, + ISBN = "0-13-590464-1", + LCCN = "QA76.66 .S87 1991", + pages = "ix + 267", + libnote = "Not in my library", + note = "A description of the Modula 3 programming language by + the committee that designed it, with an entertaining + appendix on how various design decisions were made. + Section 3.4 describes three floating-point interfaces + that provide parameters of the underlying + floating-point system, access primitives, and + exception handling.", + bibdate = "Wed Dec 15 10:40:00 1993", +} + +@Book{Nemeth:USA89, + author = "Evi Nemeth and Garth Snyder and Scott Seebass", + title = "{UNIX} System Administration Handbook", + publisher = pub-PH, + address = pub-PH:adr, + year = "1989", + ISBN = "0-13-933441-6", + LCCN = "QA76.76.O63 N45 1989", + pages = "xxx + 593", + bibdate = "Wed Dec 15 10:40:01 1993", +} + +@Article{Ness:tv-guide, + author = "David Ness", + title = "The Use of {\TeX{}} in a Commercial Environment", + journal = j-TEXNIQUES, + year = "1987", + volume = "5", + pages = "115--123", + month = aug, + note = "Proceedings of the Eighth Annual Meeting of the + \TeX{} Users Group", +} + +@Book{Newman:PIC73, + author = "William M. Newman and Robert F. Sproull", + title = "Principles of Interactive Computer Graphics", + publisher = pub-MH, + address = pub-MH:adr, + year = "1973", + series = "McGraw-Hill Computer Science Series, Editors: Richard + W. Hamming and Edward A. Feigenbaum", + ISBN = "0-07-046337-9", + LCCN = "T385 .N48", + pages = "xxviii + 607", + bibdate = "Wed Dec 15 10:40:01 1993", +} + +@Book{Newman:PIC79, + author = "William M. Newman and Robert F. Sproull", + title = "Principles of Interactive Computer Graphics", + publisher = pub-MH, + address = pub-MH:adr, + year = "1979", + edition = "Second", + ISBN = "0-07-046338-7", + LCCN = "T385 .N48 1979", + pages= "xvi + 541", + bibdate = "Wed Dec 15 11:09:22 1993", +} + +@Book{Norton:IIP82, + author = "Peter Norton", + title = "Inside the {IBM} {PC}. Access to Advanced Features + and Programming", + publisher = pub-BRADY, + address = pub-BRADY:adr, + year = "1982", + note = "An excellent treatment of the IBM PC.", + ISBN = "0-89303-556-4", + LCCN = "QA76.8.I2594 N67 1983", + pages = "xi + 262", + bibdate = "Wed Dec 15 10:40:04 1993", +} + +@Book{Norton:PGI85, + author = "Peter Norton", + title = "Programmer's Guide to the {IBM} {PC}", + publisher = pub-MICROSOFT, + address = pub-MICROSOFT:adr, + year = "1985", + note = "An excellent treatment of the programming IBM PC. + Strongly recommended for all serious users of the PC.", + price = "US\$19.95", + ISBN = "0-914845-46-2", + LCCN = "QA76.8.I2594 N68 1985", +} + +@Book{Nye:XPM88, + author = "Adrian Nye", + title = "Xlib Programming Manual for Version 11", + publisher = pub-OR, + address = pub-OR:adr, + year = "1988", + volume = "1", + ISBN = "0-937175-26-9", + LCCN = "QA76.76.W56 D44 v.1 1988", + pages = "xxxiii + 615", + bibdate = "Wed Dec 15 10:40:05 1993", +} + +@Book{Nye:XPM90, + author = "Adrian Nye", + title = "{X} Protocol Reference Manual", + publisher = pub-OR, + year = "1990", + ISBN = "0-937175-50-1", + LCCN = "QA76.76.W56 X215 1990", + volume = "0", + edition = "Second", + address = pub-OR:adr, + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Fri Dec 10 13:42:12 1993", +} + +@Book{Nye:XPM92, + author = "Adrian Nye", + title = "{X} Protocol Reference Manual", + publisher = pub-OR, + year = "1992", + volume = "0", + ISBN = "1-56592-008-2", + LCCN = "QA76.76.W56 X215 1990", + edition = "Third", + address = pub-OR:adr, + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Fri Dec 10 13:42:12 1993", +} + +@Book{Nye:XRM88, + author = "Adrian Nye", + title = "Xlib Reference Manual for Version 11", + publisher = pub-OR, + address = pub-OR:adr, + year = "1988", + volume = "2", + ISBN = "0-937175-27-7", + LCCN = "QA76.76.W56 D44 v.2 1988", + pages = "xiv + 701", + bibdate = "Wed Dec 15 10:40:05 1993", +} + +@Book{Nye:XTI90, + author = "Adrian Nye and Tim O'Reilly", + title = "{X} Toolkit Intrinsics Programming Manual", + publisher = pub-OR, + address = pub-OR:adr, + year = "1990", + volume = "4", + ISBN = "0-937175-34-X", + pages = "xxxi + 543", + bibdate = "Wed Dec 15 19:46:34 1993", +} + +@Book{Nye:XTI92, + author = "Adrian Nye and Tim O'Reilly", + title = "{X} Toolkit Intrinsics Programming Manual: Motif Edition", + publisher = pub-OR, + address = pub-OR:adr, + year = "1992", + month = aug, + volume = "4M", + edition = "Second", + ISBN = "1-56592-013-9", + pages = "674", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Thu Dec 16 09:46:22 1993", +} + +@Book{Nye:XTI93, + author = "Adrian Nye and Tim O'Reilly", + title = "{X} Toolkit Intrinsics Programming Manual", + publisher = pub-OR, + address = pub-OR:adr, + year = "1993", + month = apr, + volume = "4", + edition = "Third", + ISBN = "1-56592-003-1", + pages = "567", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Thu Dec 16 09:46:22 1993", +} + +@Book{Oakley:AG49, + author = "C. O. Oakley", + title = "Analytic Geometry", + publisher = pub-BN, + address = pub-BN:adr, + year = "1949", + series = "College Outline Series", +} + +@Book{Oakley:AGP58, + author = "C. O. Oakley", + title = "Analytic Geometry Problems with Solutions", + publisher = pub-BN, + address = pub-BN:adr, + year = "1958", + series = "College Outline Series", +} + +@Book{Olver:ASF74, + author = "F. W. J. Olver", + title = "Asymptotics and Special Functions", + publisher = pub-AP, + address = pub-AP:adr, + year = "1974", + ISBN = "0-12-525850-X", + LCCN = "QA351 .O481 1974", + pages = "xvi + 572", + bibdate = "Wed Dec 15 10:40:06 1993", +} + +@Book{Omondi:CAS94, + author = "Amos R. Omondi", + title = "Computer Arithmetic Systems\emdash Algorithms, + Architecture, Implementation", + publisher = pub-PH, + year = "1994", + ISBN = "0-13-334301-4", + LCCN = "QA76.9.C62 O46 1994", + address = pub-PH:adr, + pages = "522", + price = "US\$40.00", + libnote = "Not yet in my library.", + bibdate = "Tue Feb 22 08:27:23 1994", +} + +@Misc{ONW:awk, + author = "{OpenNetwork}", + title = "{The Berkeley Utilities}", + year = "1991", + note = "215 Berkeley Place, Brooklyn, NY 11217, USA, Tel: + (718) 398-3838.", + altnote = "See ad on p. 108 of April 1991 UNIX Review.", +} + +@Book{Oram:MPM91, + author = "Andrew Oram and Steve Talbott", + title = "Managing Projects with Make", + publisher = pub-OR, + year = "1991", + edition = "Second", + ISBN = "0-937175-90-0", + LCCN = "QA76.76.O63 T35 199", + address = pub-OR:adr, + pages = "xiv + 136", + libnote = "Not yet in my library.", + bibdate = "Wed Dec 15 10:49:41 1993", +} + +@Book{Oreilly:MUU88, + author = "Tim O'Reilly and Grace Todino", + title = "Managing {UUCP} and Usenet", + publisher = pub-OR, + address = pub-OR:adr, + month = mar, + year = "1988", + ISBN = "0-937175-09-9", + LCCN = "QA76.8.U65 O64 1988", + pages = "xvi + 256", + bibdate = "Wed Dec 15 10:40:12 1993", +} + +@Book{Oreilly:XTI90, + author = "Tim O'Reilly", + title = "X Toolkit Intrinsics Reference Manual", + publisher = pub-OR, + address = pub-OR:adr, + year = "1990", + volume = "5", + ISBN = "0-937175-35-8", + pages = "xii + 543", + bibdate = "Wed Dec 15 19:47:31 1993", +} + +@Book{Oreilly:XWS88, + author = "Tim O'Reilly and Valerie Quercia and Linda Lamb", + title = "X Window System User's Guide for Version 11", + publisher = pub-OR, + address = pub-OR:adr, + volume = "3", + year = "1988", + ISBN = "0-937175-29-3", +} + +@Book{Organick:MS72, + author = "Elliott I. Organick", + title = "The Multics System: An Examination of Its Structure", + publisher = pub-MIT, + year = "1972", + ISBN = "0-262-15012-3", + LCCN = "QA76.5 O73", + address = pub-MIT:adr, + pages = "xvii + 392", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Sat Feb 5 18:29:13 1994", +} + +@Book{Organick:PVI83, + author = "Elliott I. Organick", + title = "A Programmer's View of the Intel 432 System", + publisher = pub-MH, + year = "1983", + ISBN = "0-07-047719-1", + LCCN = "QA76.8.I267 O73 1983", + address = pub-MH:adr, + pages = "xiii + 418", + price = "US\$29.95", + acknowledgement = ack-nhfb, + bibdate = "Sat Jan 29 22:36:47 1994", +} + +@Book{OSF:AES91, + author = "{Open Software Foundation}", + title = "Application Environment Specification {(AES)} User + Environment Volume, Revision B", + publisher = pub-PH, + address = pub-PH:adr, + year = "1991", + ISBN = "0-13-043530-9", + LCCN = "QA76.76.I57A665 1991", + pages = "xii + 1084 + 12", + bibdate = "Wed Dec 15 10:40:13 1993", +} + +@Book{OSF:OPG91, + author = "{Open Software Foundation}", + title = "{OSF}\slash Motif Programmer's Guide, Revision 1.1", + publisher = pub-PH, + address = pub-PH:adr, + year = "1991", + ISBN = "0-13-640673-4", + LCCN = "QA76.76.W56 O69 1991", + bibdate = "Wed Dec 15 10:40:18 1993", +} + +@Book{OSF:OPR91, + author = "{Open Software Foundation}", + title = "{OSF}\slash Motif Programmer's Reference, Revision + 1.1", + publisher = pub-PH, + address = pub-PH:adr, + year = "1991", + ISBN = "0-13-640681-5", + LCCN = "QA76.76.W56 O7 1991", + pages = "xii + 1212 + 15", + bibdate = "Wed Dec 15 10:40:19 1993", +} + +@Book{OSF:OSG91, + author = "{Open Software Foundation}", + title = "{OSF}\slash Motif Style Guide", + publisher = pub-PH, + address = pub-PH:adr, + year = "1991", + ISBN = "0-13-640616-5", + LCCN = "QA76.76.W56 O833 1991", + bibdate = "Wed Dec 15 10:40:31 1993", +} + +@Book{Ostermann:MFL52, + author = "Georg F. von Ostermann", + title = "Manual of Foreign Languages", + publisher = pub-USGPO, + address = pub-USGPO:adr, + year = "1952", + LCCN = "Z253 .V94 1952", + edition = "Fourth", + libnote = "Not yet in my library.", + bibdate = "Wed Dec 15 18:05:30 1993", +} + +@Book{Packel:AC94, + author = "Ed Packel and Stan Wagon", + title = "Animating Calculus\emdash Mathematica Notebooks for + the Laboratory", + publisher = pub-WHF, + year = "1994", + ISBN = "0-7167-2428-6", + LCCN = "QA303.5.D37P33 1994", + address = pub-WHF:adr, + pages = "xii + 289", + acknowledgement = ack-nhfb, + bibdate = "Sat Mar 5 12:29:34 1994", +} + +@Book{Pagels:DRC88, + author = "Heinz R. Pagels", + title = "The Dreams of Reason\emdash The Computer and the Rise + of the Sciences of Complexity", + publisher = pub-SS, + address = pub-SS:adr, + year = "1988", + ISBN = "0-671-62708-2", + LCCN = "QA76.9.C66 P34 1988", + pages = "352", + bibdate = "Wed Dec 15 10:40:37 1993", +} + +@Book{Palmer:8087, + author = "John F. Palmer and Stephen P. Morse", + title = "The 8087 Primer", + publisher = pub-W, + address = pub-W:adr, + year = "1984", + note = "Excellent coverage of the 8087 numeric coprocessor by + the chief architects of the Intel 8087 (Palmer) and + 8086 (Morse). Contains many candid statements about + design decisions in these processors. A must for + serious assembly language coding of the 8087 and 80287 + chips. See also \cite{Intel:286-prm}.", + ISBN = "0-471-87569-4", + LCCN = "QA76.8.I2923 P34 1984", + pages = "viii + 182", + bibdate = "Wed Dec 15 10:40:38 1993", +} + +@Article{Park:random, + author = "Stephen K. Park and Keith W. Miller", + title = "Random Number Generators: Good Ones are Hard to Find", + journal = j-CACM, + year = "1988", + volume = "31", + number = "10", + pages = "1192--1201", + month = oct, +} + +@InCollection{Parker:printer-fonts, + author = "Mike Parker", + title = "Printer Fonts", + booktitle = "Output Hardcopy Devices", + chapter = "19", + publisher = pub-AP, + address = pub-AP:adr, + year = "1988", + editor = "Robert C. Durbeck and Sol Sherr", + pages = "497--516", +} + +@Book{Parkinson:PL80, + author = "Cyril Northcote Parkinson", + title = "Parkinson, the Law", + publisher = pub-HM, + year = "1980", + ISBN = "0-395-29131-3", + LCCN = "PN6231.M2 P297 1980", + address = pub-HM:adr, + pages = "207", + price = "US\$8.95", + acknowledgement = ack-nhfb, + bibdate = "Wed Jan 12 14:59:06 1994", +} + +@Book{Parter:LSS84, + editor = "Seymour V. Parter", + title = "Large Scale Scientific Computation", + publisher = pub-AP, + address = pub-AP:adr, + year = "1984", + ISBN = "0-12-546080-5", + LCCN = "QA911 .L32 1984", + pages = "ix + 326", + bibdate = "Wed Dec 15 10:40:39 1993", +} + +@Book{Patterson:CA90, + author = "David A. Patterson and John L. Hennessy", + title = "Computer Architecture\emdash A Quantitative Approach", + publisher = pub-MK, + address = pub-MK:adr, + year = "1990", + ISBN = "1-55860-069-8", + LCCN = "QA76.9.A73 P377 1990", + pages = "xxviii + 594", + bibdate = "Mon Jan 31 08:47:46 1994", +} + +@Book{Patterson:COD94, + author = "David A. Patterson and John L. Hennessy", + title = "Computer Organization and Design\emdash The + Hardware\slash Software Interface", + publisher = pub-MK, + year = "1994", + ISBN = "1-55860-281-X", + LCCN = "QA76.9 .C643 P37 1994", + address = pub-MK:adrnew, + pages = "xxiv + 648", + price = "US\$74.75", + acknowledgement = ack-nhfb, + bibdate = "Wed Feb 2 00:08:32 1994", +} + +@Article{Patterson:raid, + author = "D. A. Patterson and P. Chen and G. Gibson and R. H. + Katz", + title = "Introduction to Redundant Arrays of Inexpensive + Disks", + journal = j-COMPCON-SPRING89, + year = "1989", + note = "IEEE Computer Society Press", +} + +@Book{Paulos:BN91, + author = "John Allen Paulos", + title = "Beyond Numeracy\emdash{}Ruminations of a Numbers Man", + publisher = pub-AAK, + year = "1991", + address = pub-AAK:adr, + ISBN = "0-394-58640-9", + LCCN = "QA5 .P38 1991", + pages = "xiii + 285", + bibdate = "Wed Dec 15 10:40:41 1993", +} + +@Book{Pavlidis:AGI82, + author = "Theo Pavlidis", + title = "Algorithms for Graphics and Image Processing", + publisher = pub-CSP, + address = pub-CSP:adr, + year = "1982", + ISBN = "0-914894-65-X", + LCCN = "T385 .P38 1982", + pages = "xv + 416", + bibdate = "Wed Dec 15 10:40:43 1993", +} + +@Misc{Paxson:flex, + author = "Vern Paxson", + title = "flex\emdash fast lexical analyzer generator", + howpublished = pub-FSF # " " # pub-FSF:adr, + year = "1988", + note = "Electronic mail: \path|vern@lbl-csam.arpa| or + \path|vern@lbl-rtsg.arpa|. Software also available via + ANONYMOUS FTP to \path|lbl-csam.arpa|, + \path|lbl-rtsg.arpa|, or \path|prep.ai.mit.edu|. See + also \cite{Donnelly:bison}.", +} + +@Misc{pc-sales88, + key = "PCS", + year = "1988", + note = "Trade journal advertisement sales volume estimates.", +} + +@Book{Peitgen:BF86, + author = "Heinz-Otto Peitgen and Peter H. Richt\-er", + title = "The Beauty of Fractals", + publisher = pub-SV, + address = pub-SV:adr, + year = "1986", + ISBN = "0-387-15851-0", + LCCN = "QA447 .P45 1986", + pages = "xii + 199", + bibdate = "Wed Dec 15 10:40:44 1993", +} + +@Book{Peitgen:SFI88, + author = "Heinz-Otto Peitgen and Dietmar Saupe", + title = "The Science of Fractal Images", + publisher = pub-SV, + address = pub-SV:adr, + year = "1988", + ISBN = "0-387-96608-0", + LCCN = "QA614.86 .S35 1988", + pages= "xiii + 312", + bibdate = "Wed Dec 15 18:08:22 1993", +} + +@Book{Penna:PGA86, + author = "Michael A. Penna and Richard R. Patterson", + title = "Projective Geometry and its Applications to Computer + Graphics", + publisher = pub-PH, + address = pub-PH:adr, + year = "1986", + price = "US\$37.50", + ISBN = "0-13-730649-0", + LCCN = "QA471 .P3951 1986", + pages = "xi + 403", + bibdate = "Wed Dec 15 10:40:45 1993", +} + +@Book{Pennington:ICM65, + author = "Ralph H. Pennington", + title = "Introductory Computer Methods and Numerical Analysis", + publisher = pub-MAC, + address = pub-MAC:adr, + year = "1965", + pages= "xi + 452", + LCCN = "QA76.5 .P38", + bibdate = "Wed Dec 15 18:09:03 1993", +} + +@Book{Phillips:NL86, + author = "Jen Phillips", + title = "The {NAG} Library", + publisher = pub-CP, + address = pub-CP:adr, + year = "1986", + price = "US\$14.50", + ISBN = "0-19-853263-6", + LCCN = "QA297.P53 1986", + pages = "viii + 245", + bibdate = "Wed Dec 15 10:40:46 1993", +} + +@Book{Pinker:LI94, + author = "Steven Pinker", + title = "The Language Instinct", + publisher = pub-MORROW, + year = "1994", + ISBN = "0-688-12141-1", + LCCN = "P106.P476 1994", + address = pub-MORROW:adr, + pages = "494", + price = "US\$23.00", + acknowledgement = ack-nhfb, + bibdate = "Wed Apr 6 23:37:04 1994", +} + +@Book{Pissanetsky:SMT84, + author = "Sergio Pissanetsky", + title = "Sparse Matrix Technology", + publisher = pub-AP, + address = pub-AP:adr, + year = "1984", + ISBN = "0-12-557580-7", + LCCN = "QA188 .P57 1984", + pages= "xiii + 321", + bibdate = "Wed Dec 15 18:10:01 1993", +} + +@Book{Plauger:SCL92, + author = "P. J. Plauger", + title = "The {Standard C} Library", + publisher = pub-PH, + address = pub-PH:adr, + year = "1992", + ISBN = "0-13-838012-0", + LCCN = "QA76.73.C15 P563 1991", + pages = "xiv + 498", + bibdate = "Wed Dec 15 10:40:47 1993", +} + +@Book{Plauger:PP93a, + author = "P. J. Plauger", + title = "Programming on Purpose: Essays on Software Design", + publisher = pub-PH, + year = "1993", + ISBN = "0-13-721374-3", + LCCN = "QA76.76.D47 P55 1993", + volume = "1", + address = pub-PH:adr, + pages = "viii + 236", + price = "US\$19.95", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Wed Jan 5 12:50:18 1994", +} + +@Book{Plauger:PP93b, + author = "P. J. Plauger", + title = "Programming on Purpose II: Essays on Software People", + publisher = pub-PH, + year = "1993", + ISBN = "0-13-328105-1", + volume = "2", + address = pub-PH:adr, + pages = "viii + 204", + price = "US\$19.95", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Wed Jan 5 12:50:18 1994", +} + +@Book{Plauger:PP93c, + author = "P. J. Plauger", + title = "Programming on Purpose: Essays on Software Design", + publisher = pub-PH, + year = "1993", + ISBN = "0-13-328113-2", + volume = "3", + address = pub-PH:adr, + price = "US\$19.95", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Wed Jan 5 12:50:18 1994", +} + +@Book{Plotnik:EEM82, + author = "Arthur Plotnik", + title = "The Elements of Editing\emdash A Modern Guide for + Editors and Journalists", + publisher = pub-COLLIER, + address = pub-COLLIER:adr, + year = "1982", + ISBN = "0-02-597700-8", + LCCN = "PN4778 .P59 1982", + pages = "xiii + 156", + bibdate = "Wed Dec 15 10:40:48 1993", +} + +@Book{Plum:NDC87, + author = "T. Plum", + title = "Notes on the Draft C Standard", + publisher = pub-PLUMHALL, + address = pub-PLUMHALL:adr, + year = "1987", + price = "US\$10.00", + ISBN = "0-911537-06-6", + LCCN = "QA76.73.C15 P585 1987", + pages = "92", + bibdate = "Wed Dec 15 10:40:49 1993", +} + +@Misc{Polytron:polyawk, + author = "Polytron Corporation", + title = "{Poly{\-}AWK}", + year = "1987", + note = "170 NW 167th Place, Beaverton, OR 97006. See also + \cite{Aho:APL87}.", +} + +@Book{Preparata:CG85, + author = "Franco P. Preparata and Michael Ian Shamos", + title = "Computational Geometry", + publisher = pub-SV, + address = pub-SV:adr, + year = "1985", + price = "US\$32.00", + ISBN = "0-387-96131-3", + LCCN = "QA447 .P735 1985", + pages = "xii + 390", + bibdate = "Wed Dec 15 10:40:51 1993", +} + +@Book{Press:NRA86, + author = "William H. Press and Brian P. Flannery and Saul A. + Teukolsky and William T. Vetterling", + title = "Numerical Recipes\emdash The Art of Scientific + Computing", + publisher = pub-CUP, + address = pub-CUP:adr, + year = "1986", + ISBN = "0-521-38330-7", + LCCN = "QA297 .N866 1989", + pages = "xx + 702", + bibdate = "Wed Dec 15 10:40:52 1993", +} + +@Article{Price:benchmark-tutorial, + author = "Walter J. Price", + title = "A Benchmark Tutorial", + journal = j-IEEE-MICRO, + year = "1989", + volume = "9", + number = "5", + pages = "28--43", + month = oct, +} + +@Book{Prior:FL55, + author = "A. N. Prior", + title = "Formal Logic", + publisher = pub-CP, + address = pub-CP:adr, + year = "1955", +} + +@Book{Prueitt:AC84, + author = "Melvin L. Prueitt", + title = "Art and the Computer", + publisher = pub-MH, + address = pub-MH:adr, + year = "1984", + price = "US\$39.95 (hardcover), US\$29.95 (paperback)", + ISBN = "0-07-050894-1 (hardcover), 0-07-050899-2 (paperback)", + LCCN = "N7433.8.P7 1984", + pages = "ix + 246", + bibdate = "Wed Dec 15 10:40:53 1993", +} + +@Book{Pyle:APL81, + author = "I. C. Pyle", + title = "The Ada Programming Language", + publisher = pub-PHI, + address = pub-PHI:adr, + year = "1981", + price = "US\$14.95", + ISBN = "0-13-003921-7", + LCCN = "QA76.73.A35 P94", + pages = "x + 293", + bibdate = "Wed Dec 15 10:40:53 1993", +} + +@Book{Pyster:CDC80, + author = "Arthur B. Pyster", + title = "Compiler Design and Construction", + publisher = pub-VNR, + address = pub-VNR:adr, + year = "1980", + ISBN = "0-442-24394-4", + LCCN = "QA76.6 .P9", + pages = "xvi + 357", + bibdate = "Wed Dec 15 10:40:54 1993", +} + +@Book{Quarterman:M89, + author = "John S. Quarterman", + title = "The Matrix", + publisher = pub-DP, + address = pub-DP:adr, + year = "1989", + ISBN = "1-55558-033-5", + LCCN = "TK5105.5 .Q37 1990", + pages = "xxvii + 719", + bibdate = "Wed Dec 15 10:40:55 1993", +} + +@Book{Quercia:XWS90, + author = "Valerie Quercia and Tim O'Reilly", + title = "{X} Window System User's Guide", + publisher = pub-OR, + year = "1990", + volume = "3", + address = pub-OR:adr, + edition = "Third", + ISBN = "0-937175-14-5", + LCCN = "QA76.76.W56 Q83 1990", + pages = "xxvi + 723", + bibdate = "Wed Dec 15 10:41:05 1993", +} + +@Book{Quercia:XWS93a, + author = "Valerie Quercia and Tim O'Reilly", + title = "{X} Window System User's Guide", + publisher = pub-OR, + year = "1993", + month = may, + volume = "3", + address = pub-OR:adr, + edition = "Fourth", + ISBN = "1-56592-014-7", + LCCN = "QA76.76.W56D43 1993", + pages = "xxx + 835", + bibdate = "Mon Jan 3 17:27:25 1994", + acknowledgement = ack-nhfb, +} + +@Book{Quercia:XWS93b, + author = "Valerie Quercia and Tim O'Reilly", + title = "{X} Window System User's Guide: OSF/Motif 1.2 Edition", + publisher = pub-OR, + year = "1993", + month = may, + volume = "3M", + address = pub-OR:adr, + edition = "Fourth", + ISBN = "1-56592-015-5", + pages = "xxx + 835", + bibdate = "Mon Jan 3 17:27:25 1994", + acknowledgement = ack-nhfb, +} + +@Book{Rabinowitz:PC90, + author = "Henry Rabinowitz and Chaim Schaap", + title = "Portable C", + publisher = pub-PH, + address = pub-PH:adr, + year = "1990", + ISBN = "0-13-685967-4", + LCCN = "QA 76.73 C15 R33 1990", + pages = "xi + 269", + bibdate = "Wed Dec 15 10:41:06 1993", +} + +@Book{Rago:USV93, + author = "Steven A. Rago", + title = "{UNIX} System {V} network programming", + publisher = pub-AW, + year = "1993", + ISBN = "0-201-56318-5", + LCCN = "92-45276, QA76.76.O63 R34 1993", + address = pub-AW:adr, + pages = "xv + 784", + price = "US\$45.50", + bibdate = "Tue Sep 21 11:32:00 1993", +} + +@Article{Ramabadran:crc-tutorial, + author = "Tenkasi V. Ramabadran and Sunil S. Gaitonde", + title = "A Tutorial on {CRC} Computations", + journal = j-IEEE-MICRO, + year = "1988", + volume = "8", + number = "4", + pages = "62--75", + month = aug, +} + +@Article{Ramsey:spiderweb, + author = "Norman Ramsey", + title = "Weaving a Language-Independent {{\WEB}}", + journal = j-CACM, + year = "1989", + volume = "32", + number = "9", + pages = "1051--1055", + month = sep, +} + +@Book{Randell:ODC82, + editor = "Brian Randell", + title = "The Origins of Digital Computers\emdash Selected + Papers", + publisher = pub-SV, + address = pub-SV:adr, + year = "1982", + ISBN = "0-387-06169-X", + LCCN = "TK7888.3.R36", + pages = "xvi + 464", + bibdate = "Wed Dec 15 10:41:08 1993", +} + +@Book{Rankin:CGS89, + author = "John R. Rankin", + title = "Computer Graphics Software Construction", + publisher = pub-PH, + address = pub-PH:adr, + year = "1989", + ISBN = "0-13-162793-7 (hardcover)", + LCCN = "T385 .R364 1988", + pages = "xvi + 544", + bibdate = "Wed Dec 15 10:41:09 1993", +} + +@Book{Rayna:RSA87, + author = "Gerhard Rayna", + title = "{REDUCE}\emdash Software for Algebraic Computation", + publisher = pub-SV, + address = pub-SV:adr, + ISBN = "0-387-96598-X (New York), 3-540-96598-X (Berlin)", + LCCN = "QA155.7.E4 R39 1987", + pages = "ix + 329", + year = "1987", + bibdate = "Wed Dec 15 10:41:10 1993", +} + +@Book{Redfern:MH93, + author = "Darren Redfern", + title = "The Maple Handbook", + publisher = pub-SV, + year = "1993", + ISBN = "0-387-94054-5 (New York), 3-540-94054-5 (Berlin)", + LCCN = "QA76.95 .R43 1993", + address = pub-SV:adr, + pages = "497", + price = "FF 181,00", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Fri Apr 1 17:21:27 1994", +} + +@TechReport{Renner:textyl, + author = "John S. Renner", + title = "{\TeX}tyl: a line-drawing interface for {\TeX}", + institution = "Department of Computer Science, Ohio State + University", + year = "1987", + number = "OSU-CISRC-4\slash 87-TR9", + month = mar, +} + +@Book{Rice:MCM81, + author = "John R. Rice", + title = "Matrix Computations and Mathematical Software", + publisher = pub-MH, + address = pub-MH:adr, + year = "1981", + series = "McGraw-Hill Computer Science Series", + ISBN = "0-07-052145-X", + LCCN = "QA188 .R52", + pages= "xii + 248", + bibdate = "Wed Dec 15 18:10:56 1993", +} + +@Book{Rice:NMS83, + author = "John R. Rice", + title = "Numerical Methods, Software, and Analysis", + publisher = pub-MH, + address = pub-MH:adr, + year = "1983", + price = "US\$19.95", + ISBN = "0-07-052208-1", + LCCN = "QA297 .R49 1983", + pages = "xii + 483", + bibdate = "Wed Dec 15 10:41:12 1993", +} + +@Book{Rimmer:BMG93, + author = "Steve Rimmer", + title = "Bit-Mapped Graphics", + publisher = pub-WINDCREST, + year = "1993", + ISBN = "0-8306-4209-9 (hardback), 0-8306-4208-0 (paperback)", + LCCN = "T385 .R55 1993", + address = pub-WINDCREST:adr, + edition = "Second", + note = "Explains the TIFF (Tagged Image File Format) and + includes sample code in C.", + pages = "ix + 484", + price = "US\$26.95 (paperback), US\$38.95 (hardback)", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Sat Feb 26 13:45:45 1994", +} + +@Article{Ritchie:time-sharing74, + author = "Dennis W. Ritchie and Ken Thompson", + title = "The {UNIX} Time-Sharing System", + journal = j-CACM, + year = "1974", + volume = "17", + number = "7", + pages = "365--375", + month = jul, +} + +@InCollection{Ritchie:time-sharing79, + author = "Dennis W. Ritchie and Ken Thompson", + title = "The {UNIX} Time-Sharing System", + booktitle = "{UNIX} Programmer's Manual", + publisher = pub-HRW, + address = pub-HRW:adr, + year = "1979", + volume = "2", + pages = "20--35", +} + +@Book{Roads:FCM87, + editor = "Curtis Roads and John Strawn", + title = "Foundations of Computer Music", + publisher = pub-MIT, + address = pub-MIT:adr, + year = "1987", + ISBN = "0-262-18114-2", + LCCN = "ML1092 .F7 1985", + pages = "xiii + 712", + bibdate = "Wed Dec 15 10:41:13 1993", +} + +@Book{Roberts:RRO89, + author = "{Major Henry} M. Robert", + title = "Robert's Rules of Order", + publisher = pub-BB, + year = "1989", + address = pub-BB:adr, + ISBN = "0-425-11690-5", +} + +@Book{Roberts:UDG92, + author = "Ralph Roberts and Mark Boyd", + title = "{UNIX} Desktop Guide to {Emacs}", + publisher = pub-HAYDEN, + address = pub-HAYDEN:adr, + year = "1992", + ISBN = "0-672-30171-7", + LCCN = "QA76.76.T49 R62 1992", + libnote = "Not in my library.", + pages = "xxiii + 504", + price = "US\$27.95", + bibdate = "Sun Mar 6 17:32:25 1994", + acknowledgement = ack-nhfb, +} + +@Book{Rochkind:AUP85, + author = "Marc J. Rochkind", + title = "Advanced {UNIX} Programming", + publisher = pub-PH, + address = pub-PH:adr, + year = "1985", + price = "US\$32.95 (hardcover), US\$24.95 (paperback)", + ISBN = "0-13-011818-4 (hardcover), 0-13-011800-1 (paperback)", + LCCN = "QA76.76.O63 R63 1985", + pages = "xv + 265", + bibdate = "Wed Dec 15 10:41:14 1993", +} + +@Book{Rodgers:UDM90, + author = "Ulka Rodgers", + title = "{UNIX} Database Management Systems", + publisher = pub-YOURDON, + address = pub-YOURDON:adr, + year = "1990", + ISBN = "0-13-945593-0", + LCCN = "QA76.9.D3 R65 1990", + pages = "xiv + 338", + bibdate = "Wed Dec 15 10:41:20 1993", +} + +@Book{Rogers:MEC76, + author = "David F. Rogers and J. Alan Adams", + title = "Mathematical Elements for Computer Graphics", + publisher = pub-MH, + address = pub-MH:adr, + year = "1976", + ISBN = "0-07-053527-2", + LCCN = "T385 .R6 1976", + pages = "xv + 239", + bibdate = "Wed Dec 15 10:41:22 1993", +} + +@Book{Rogers:PEC85, + author = "David F. Rogers", + title = "Procedural Elements for Computer Graphics", + publisher = pub-MH, + address = pub-MH:adr, + year = "1985", + price = "US\$19.95", + ISBN = "0-07-053534-5", + LCCN = "T385 .R631 1985", + pages = "xiii + 433", + bibdate = "Wed Dec 15 10:41:22 1993", +} + +@Book{Rogers:TCG87, + editor = "David F. Rogers and Rae A. Earnshaw", + title = "Techniques for Computer Graphics", + publisher = pub-SV, + address = pub-SV:adr, + year = "1987", + price = "US\$50.00", + ISBN = "0-387-96492-4, 3-540-96492-4", + LCCN = "T385 .T43 1986", + pages = "viii + 512", + bibdate = "Wed Dec 15 10:41:24 1993", +} + +@Book{Rohl:RP84, + author = "J. S. Rohl", + title = "Recursion via Pascal", + publisher = pub-CUP, + address = pub-CUP:adr, + year = "1984", + volume = "19", + series = "Cambridge Computer Science Texts, Editors: E. S. Page + and C. M. Reeves and D. E. Conway", + ISBN = "0-521-26329-8 (hardcover), 0-521-26934-2 (paperback)", + LCCN = "QA76.73.P2 R634 1984", + pages = "x + 191", + bibdate = "Wed Dec 15 10:41:25 1993", +} + +@Book{Rose:SB91, + author = "Marshall T. Rose", + title = "The Simple Book", + publisher = pub-PH, + address = pub-PH:adr, + year = "1991", + ISBN = "0-13-812611-9", + LCCN = "TK5105.5.R68 1991", + pages = "xxix + 347", + bibdate = "Wed Dec 15 10:41:26 1993", +} + +@Book{Rosenblatt:LKS93, + author = "Bill Rosenblatt", + title = "Learning the Korn Shell", + publisher = pub-OR, + year = "1993", + ISBN = "1-56592-054-6", + address = pub-OR:adr, + month = jun, + price = "US\$27.95", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Mon Jan 3 17:43:25 1994", +} + +@TechReport{Rost:pex, + author = "Randi J. Rost", + title = "{PEX} Introduction and Overview", + institution = "Digital Equipment Corporation, Workstation Systems + Engineering", + year = "1988", + number = "Version 3.20", + month = apr, + note = "This document is present in the X Window System + Version 11 Release 3 in the file + \path|X11/X11/doc/extensions/pex/doc/intro/doc.ms|.", +} + +@Book{Roth:RWP88, + editor = "Stephen E. Roth", + title = "Real World {PostScript}", + publisher = pub-AW, + address = pub-AW:adr, + year = "1988", + ISBN = "0-201-06663-7", + LCCN = "Z286.D47 R4 1988", + pages= "xiv + 383", + bibdate = "Wed Dec 15 18:12:59 1993", +} + +@Article{Rower:IEEE-MICRO-8-3-53, + author = "Chris Rowen and Mark Johnson and Paul Ries", + title = "The {MIPS} R3010 Floating-Point Coprocessor", + journal = j-IEEE-MICRO, + year = "1988", + volume = "8", + number = "3", + pages = "53--62", + month = jun, +} + +@Book{Rubinstein:DTI88, + author = "Richard Rubinstein", + title = "Digital Typography\emdash An Introduction to Type and + Composition for Computer System Design", + publisher = pub-AW, + address = pub-AW:adr, + year = "1988", + ISBN = "0-201-17633-5", + LCCN = "Z253.3 .R8 1988", + pages = "xi + 340", + bibdate = "Wed Dec 15 10:41:28 1993", +} + +@Article{Ryder:pfort, + author = "Barbara G. Ryder", + title = "The {PFORT} Verifier", + journal = j-SPE, + year = "1974", + volume = "4", + pages = "359--377", +} + +@Book{Sargent:IPC84, + author = "Murray {Sargent III} and Richard L. Schoemaker", + title = "The {IBM} Personal Computer from the Inside Out", + publisher = pub-AW, + address = pub-AW:adr, + year = "1984", + note = "A strongly hardware-oriented, but very readable, + treatment of the IBM PC. Contains three chapters on + the 8088 and assembly language programming, with the + remainder of the book devoted to descriptions of + hardware, keyboard and video display, external + devices, and data communications.", + ISBN = "0-201-06896-6", + LCCN = "QA76.8.I2594 S27 1984", + pages = "xii + 483", + bibdate = "Wed Dec 15 10:41:29 1993", +} + +@Book{Scanlon:ALP84, + author = "Leo J. Scanlon", + title = "8086\slash 88 Assembly Language Programming", + publisher = pub-BRADY, + address = pub-BRADY:adr, + year = "1984", + note = "A rather short treatment of assembly language + programming for the 8088 and 8086, with a short + chapter on the 8087. Nothing specific to the IBM PC, + and not detailed enough for a beginner. + \cite{Bradley:ALP84} and \cite{Lafore:ALP84} contain + much more detail.", + ISBN = "0-89303-424-X", + LCCN = "QA76.8.I292 S29 1984", + pages= "ix + 213", + bibdate = "Wed Dec 15 18:14:57 1993", +} + +@Book{Schachter:CIG83, + editor = "Bruce J. Schachter", + title = "Computer Image Generation", + publisher = pub-JW, + address = pub-JW:adr, + year = "1983", + price = "US\$29.95", + ISBN = "0-471-87287-3", + LCCN = "T385 .C5934 1983", + pages = "xx + 236", + bibdate = "Wed Dec 15 10:41:31 1993", +} + +@Book{Scharf:FCE90, + author = "Louis L. Scharf and Richard T. Behrens", + title = "A First Course in Electrical and Computer Engineering + with {MATLAB} Programs and Experiments", + year = "1990", + publisher = pub-AW, + address = pub-AW:adr, + ISBN = "0-201-53472-X", + LCCN = "TK168 .S34 1990", + pages= "xv + 269", + libnote = "Not yet in my library.", + bibdate = "Thu Dec 16 09:40:02 1993", +} + +@Book{Scheifler:XPM89, + author = "Robert W. Scheifler", + title = "{X} Protocol Reference Manual", + publisher = pub-OR, + address = pub-OR:adr, + year = "1989", + ISBN = "0-937175-40-4", + volume = "0", +} + +@Book{Scheifler:XWS88, + author = "Robert W. Scheifler and James Gettys and Ron Newman", + title = "{X} {Window} {System}: {C} Library and Protocol + Reference", + publisher = pub-DP, + address = pub-DP:adr, + year = "1988", + ISBN = "1-55558-012-2", + LCCN = "QA76.76.W56 S34 1988", + pages = "xxix + 701", + bibdate = "Wed Dec 15 10:41:32 1993", +} + +@Book{Schendel:INM84, + author = "U. Schendel", + title = "Introduction to Numerical Methods for Parallel + Computers", + publisher = pub-EH, + address = pub-EH:adr, + year = "1984", + series = "Ellis Horwood Series in Mathematics and its + Applications, Editor: G. M. Bell", + price = "UK\pounds 15.00", + ISBN = "0-470-20091-X, 0-85312-597-X", + LCCN = "QA297 .S3813 1984", + pages = "151", + bibdate = "Wed Dec 15 10:41:33 1993", +} + +@Book{Schildt:AAC90, + author = "Herbert Schildt", + title = "The Annotated {ANSI} {C} Standard: American National + Standard for Programming Languages \emdash {C}", + publisher = pub-OMH, + address = pub-OMH:adr, + year = "1990", + ISBN = "0-07-881952-0", + LCCN = "QA76.73.C15S356 1990", + pages = "xvi + 219", + price = "US\$39.95", + bibdate = "Mon Dec 27 09:38:20 1993", +} + +@Book{Schilpp:AEP49-1, + author = "Paul Arthur Schilpp", + title = "Albert Einstein: Philosopher-Scientist", + publisher = pub-CUP, + address = pub-CUP:adr, + year = "1949, 1951, 1969", + volume = "1", + pages= "xviii + 781", + LCCN = "QC16.E5 S3 1970", + series = "The Library of Living Philosophers", + bibdate = "Wed Dec 15 18:20:28 1993", +} + +@Book{Schilpp:AEP49-2, + author = "Paul Arthur Schilpp", + title = "Albert Einstein: Philosopher-Scientist", + publisher = pub-CUP, + address = pub-CUP:adr, + year = "1949, 1951, 1970", + volume = "2", + LCCN = "QC16.E5 S3 1970", + series = "The Library of Living Philosophers", + bibdate = "Wed Dec 15 18:20:31 1993", +} + +@Book{Schofield:OFP89, + author = "Clive F. Schofield", + title = "Optimising {Fortran} programs", + publisher = pub-EH, + address = pub-EH:adr, + year = "1989", + libnote = "Not in my library.", + bibdate = "Fri Jan 29 08:10:11 1993", + price = "US\$40.95", + ISBN = "0-7458-0654-6, 0-470-21533-X", + LCCN = "QA76.73.F25 S334 1989", + pages = "x + 309", + bibdate = "Wed Dec 15 10:41:34 1993", +} + +@Book{Schoonover:GEU92, + author = "Michael A. Schoonover and John S. Bowie and William + R. Arnold", + title = "{GNU} Emacs: {UNIX} Text Editing and Programming", + publisher = pub-AW, + year = "1992", + address = pub-AW:adr, + ISBN = "0-201-56345-2", + LCCN = "QA76.76.T49S36", + pages = "610", +} + +@Book{Schreiner:ICC85, + author = "Axel T. Schreiner and H. George {Friedman, Jr.}", + title = "Introduction to Compiler Construction Under {UNIX}", + publisher = pub-PH, + address = pub-PH:adr, + year = "1985", + ISBN = "0-13-474396-2", + LCCN = "QA76.76.C65 S37 1985", + pages = "viii + 194", + bibdate = "Wed Dec 15 18:20:18 1993", +} + +@Book{Schroeder:FCP91, + author = "Manfred Schroeder", + title = "Fractals, Chaos, Power Laws", + publisher = pub-WHF, + address = pub-WHF:adr, + year = "1991", + ISBN = "0-7167-2136-8", + LCCN = "QD921 .S3 1990", + pages = "xviii + 429", + bibdate = "Wed Dec 15 10:41:35 1993", +} + +@Book{Schwarz:ET88, + author = "Norbert Schwarz", + title = "Einf{\"u}hrung in {\TeX{}}", + edition = "Second", + publisher = pub-AW, + address = pub-AW:adr, + year = "1988", + ISBN = "3-925118-97-7", + pages = "272", + price = "DM 68", + bibdate = "Wed Dec 15 18:20:05 1993", +} + +@Book{Scott:IIC82, + author = "Joan E. Scott", + title = "Introduction to Interactive Computer Graphics", + publisher = pub-JW, + address = pub-JW:adr, + year = "1982", + ISBN = "0-471-05773-8 (hardcover), 0-471-86623-7 (paperback)", + LCCN = "T385.S36", + pages = "xi + 255", + bibdate = "Wed Dec 15 10:41:36 1993", +} + +@Book{Sedgewick:A83, + author = "Robert Sedgewick", + title = "Algorithms", + publisher = pub-AW, + address = pub-AW:adr, + year = "1983", + ISBN = "0-201-06672-6", + LCCN = "QA76.6 .S435 1983", + pages= "viii + 551", + bibdate = "Wed Dec 15 18:23:21 1993", +} + +@Book{Sedgewick:A88, + author = "Robert Sedgewick", + title = "Algorithms", + publisher = pub-AW, + address = pub-AW:adr, + edition = "Second", + year = "1988", + libnote = "Not yet in my library.", + price = "US\$34.95", + ISBN = "0-201-06673-4", + LCCN = "QA76.6 .S435 1988", + pages = "xii + 657", + bibdate = "Wed Dec 15 10:41:37 1993", +} + +@Book{Sedgewick:AC90, + author = "Robert Sedgewick", + title = "Algorithms in {C}", + publisher = pub-AW, + address = pub-AW:adr, + year = "1990", + ISBN = "0-201-51425-7", + LCCN = "QA76.73.C15 S43 1990", + pages = "xii + 657", + bibdate = "Wed Dec 15 10:41:38 1993", +} + +@Book{Sedgewick:AC92, + author = "Robert Sedgewick", + title = "Algorithms in {C++}", + publisher = pub-AW, + year = "1992", + ISBN = "0-201-51059-6", + LCCN = "QA76.73.C153 S38 1992", + address = pub-AW:adr, + pages = "xiv + 656", + libnote = "Not yet in my library.", + bibdate = "Mon Jan 3 12:10:05 1994", +} + +@Book{Sedgewick:AM93, + author = "Robert Sedgewick", + title = "Algorithms in {Modula-3}", + publisher = pub-AW, + year = "1993", + ISBN = "0-201-53351-0", + LCCN = "QA76.73.M63 S43 1993", + address = pub-AW:adr, + pages = "xiv + 656", + libnote = "Not yet in my library.", + bibdate = "Mon Jan 3 12:10:05 1994", +} + +@Book{Seroul:BBT91, + author = "Raymond Seroul and Silvio Levy", + title = "A Beginner's Book of {\TeX}", + publisher = pub-SV, + address = pub-SV:adr, + year = "1991", + ISBN = "0-387-97562-4, 3-540-97562-4", + LCCN = "Z253.4.T47 S47 1991", + pages = "xii + 282", + note = "This is a translation and adaption by Silvio Levy of + \cite{Seroul:PLT89}.", + bibdate = "Sun Mar 27 19:05:51 1994", +} + +@Book{Seroul:PLT89, + author = "Raymond Seroul", + title = "Le petit Livre de {\TeX}", + publisher = pub-IE, + year = "1989", + address = pub-IE:adr, + ISBN = "2-7296-0233-X", + acknowledgement = ack-nhfb, +} + +@Book{Sewell:WPL89, + author = "E. Wayne Sewell", + title = "Weaving a Program: Literate Programming in {\WEB}", + publisher = pub-VNR, + address = pub-VNR:adr, + year = "1989", + ISBN = "0-442-31946-0", + LCCN = "QA76.73.W24 S491 1989", + pages = "xx + 556", + bibdate = "Wed Dec 15 10:41:40 1993", +} + +@Book{Shertzer:EG86, + author = "Margaret Shertzer", + title = "The Elements of Grammar", + publisher = pub-COLLIER, + address = pub-COLLIER:adr, + year = "1986", + ISBN = "0-02-015440-2", + LCCN = "PE1112 .S54 1986", + pages= "168", + bibdate = "Wed Dec 15 18:24:52 1993", +} + +@Article{SIGGRAPH:core77, + author = "ACM\slash SIGGRAPH", + title = "Status Report of the {Graphic} {Standards} {Planning} + {Committee} of {ACM\slash SIGGRAPH}", + journal = j-SIGGRAPH, + year = "1977", + volume = "11", + number = "3", +} + +@Article{SIGGRAPH:core79, + author = "ACM\slash SIGGRAPH", + title = "Status Report of the {Graphic} {Standards} {Planning} + {Committee} of {ACM\slash SIGGRAPH}", + journal = j-SIGGRAPH, + year = "1979", + volume = "13", + month = aug, + number = "3", +} + +@Book{Skinner:IAL85, + author = "Thomas P. Skinner", + title = "An Introduction to 8086\slash 8088 Assembly Language + Programming", + publisher = pub-W, + address = pub-W:adr, + year = "1985", + price = "US\$17.95", + ISBN = "0-471-80825-3", + LCCN = "QA76.73.A8 S57 1985", + pages = "xiii + 222", + bibdate = "Wed Dec 15 10:41:41 1993", +} + +@Book{Smail:ETI23, + author = "Lloyd L. Smail", + title = "Elements of the Theory of Infinite Processes", + publisher = pub-MH, + address = pub-MH:adr, + year = "1923", +} + +@Book{Smith:LPV90, + author = "Ross Smith", + title = "Learning PostScript\emdash A Visual Approach", + publisher = pub-PEACHPIT, + year = "1990", + address = pub-PEACHPIT:adr, + ISBN = "0-938151-12-6", + LCCN = "QA76.73.P67 S55 1990", + bibdate = "Wed Dec 15 18:25:55 1993", +} + +@Book{Smith:MER76, + author = "B. T. Smith and J. M. Boyle and J. J. Dongarra and B. + S. Garbow and Y. Ikebe and V. C. Klema and C. B. + Moler", + title = "Matrix Eigensystem Routines\emdash {EISPACK} Guide", + publisher = pub-SV, + address = pub-SV:adr, + year = "1976", + volume = "6", + series = "Lecture Notes in Computer Science, Editors: G. Goos + and J. Hartmanis", + ISBN = "0-387-06710-8", + LCCN = "QA193 .M37, QA267.A1 L43 no.6", + pages = "vii + 387", + bibdate = "Mon Dec 13 15:15:20 1993", +} + +@Book{Snow:TB92, + author = "Wynter Snow", + title = "{\TeX{}} for the Beginner", + publisher = pub-AW, + address = pub-AW:adr, + year = "1992", + ISBN = "0-201-54799-6", + LCCN = "Z253.4.T47 S64 1992", + pages = "xii + 377 + 23", + bibdate = "Wed Dec 15 10:41:46 1993", +} + +@Book{Snyder:MPU82, + author = "John P. Snyder", + title = "Map Projections Used by the U. S. Geological Survey", + publisher = pub-USGPO, + address = pub-USGPO:adr, + year = "1982", + edition = "Second", + series = "Geological Survey Bulletin 1532", + LCCN = "QE75 .B9", + pages= "xiii + 313", + bibdate = "Wed Dec 15 18:27:32 1993", +} + +@Book{Sokolnikoff:MPM66, + author = "I. S. Sokolnikoff and R. M. Redheffer", + title = "Mathematics of Physics and Modern Engineering", + publisher = pub-MH, + address = pub-MH:adr, + year = "1966", + edition = "Second", + ISBN = "0-07-059625-5", + LCCN = "QA401 .S6 1966", + pages = "xi + 752", + bibdate = "Wed Dec 15 10:41:47 1993", +} + +@Book{SPARC:SAM92, + author = "{SPARC International, Inc.}", + title = "The {SPARC} Architecture Manual\emdash{}Version 8", + publisher = pub-PH, + address = pub-PH:adr, + year = "1992", + ISBN = "0-13-825001-4", + LCCN = "QA76.9.A73 S647 1992", + pages= "xxix + 316", + bibdate = "Thu Dec 16 09:12:32 1993", +} + +@Misc{Spencer:regexp, + author = "Henry Spencer", + title = "Regular expression pattern matching software", + howpublished = "Usenet \path|mod.sources| and \path|net.sources| + archives", + year = "1985", + month = nov, +} + +@Book{Spivak:JTG86, + author = "Michael D. Spivak", + title = "The Joy of {\TeX}\emdash A Gourmet Guide to + Typesetting with the {\AMSTEX} macro package", + publisher = pub-AMS, + address = pub-AMS:adr, + year = "1986", + ISBN = "0-8218-2999-8", + LCCN = "Z253.4.T47 S6731 1986", + pages = "xviii + 290", + bibdate = "Wed Dec 15 10:41:57 1993", +} + +@Book{Spivak:JTG90, + author = "Michael D. Spivak", + title = "The Joy of {\TeX}\emdash A Gourmet Guide to + Typesetting with the {\AmSTeX} macro package", + publisher = pub-AMS, + address = pub-AMS:adr, + edition = "2nd revised", + year = "1990", + price = "US\$40.00", + ISBN = "0-8218-2997-1", + bibdate = "Sat Mar 12 17:43:06 1994", +} + +@Book{Spivak:LS89, + author = "Michael D. Spivak", + title = "{L\AMSTEX}, The Synthesis", + publisher = pub-TEXPLORATORS, + address = pub-TEXPLORATORS:adr, + year = "1989", + acknowledgement = ack-nhfb, + bibdate = "Sat Mar 12 18:20:15 1994", +} + +@Book{Sproull:DIG85, + author = "Robert F. Sproull and W. R. Sutherland and Michael K. + Ullner", + title = "Device-In\-de\-pen\-dent Graphics", + publisher = pub-MH, + address = pub-MH:adr, + year = "1985", + price = "US\$29.95", + ISBN = "0-07-060504-1", + LCCN = "T385.S67 1985", + pages = "xii + 546", + bibdate = "Wed Dec 15 10:41:58 1993", +} + +@Article{Stansifer:SIGPLAN-27-12-61, + author = "Ryan Stansifer", + title = "The Calculation of Easter", + journal = j-SIGPLAN, + year = "1992", + volume = "27", + number = "12", + pages = "61--65", + month = dec, + bibdate = "Wed Dec 30 12:05:19 1992", +} + +@TechReport{Stallman:gcc, + author = "Richard M. Stallman", + title = "Using and Porting {GNU} {CC}", + institution = pub-FSF, + address = pub-FSF:adr, + year = "1988", + note = "Electronic mail: \path|rms@prep.ai.mit.edu|. Software + also available via ANONYMOUS FTP to + \path|prep.ai.mit.edu|.", +} + +@Book{Steele:CLL84, + author = "Guy L. {Steele Jr.}", + title = "Common Lisp\emdash The Language", + publisher = pub-DP, + address = pub-DP:adr, + year = "1984", + note = "See also \cite{Tatar:PGC87}.", + price = "US\$22.00", + ISBN = "0-93237-641-X", + LCCN = "QA76.73.L23 S73 1984", + pages = "xii + 465", + bibdate = "Wed Dec 15 10:42:41 1993", +} + +@Article{Steele:floating-point-output, + author = "Guy L. {Steele Jr.} and Jon L. White", + title = "How to Print Floating-Point Numbers Accurately", + journal = j-SIGPLAN, + year = "1990", + volume = "25", + number = "6", + pages = "112--126", + month = jun, + note = "See also input algorithm in + \cite{Clinger:floating-point-input}. In electronic + mail dated Wed, 27 Jun 90 11:55:36 EDT, Guy Steele + reported that an intrepid pre-SIGPLAN 90 conference + implementation of what is stated in the paper revealed + 3 mistakes: + \begin{itemize} + \item[1.] + Table~5 (page 124):\par\noindent + insert {\tt k <-- 0} after assertion, and also + delete {\tt k <-- 0} from Table~6. + \item[2.] + Table~9 (page 125):\par\noindent + \begin{tabular}{ll} + for & {\tt -1:USER!({"}{"});} \\ + substitute & {\tt -1:USER!({"}0{"});} + \end{tabular}\par\noindent + and delete the comment. + \item[3.] + Table~10 (page 125):\par\noindent + \begin{tabular}{ll} + for & {\tt fill(-k, {"}0{"})}\\ + substitute & {\tt fill(-k-1, {"}0{"})} + \end{tabular} + \end{itemize} + \def\EatBibTeXPeriod#1{\ifx#1.\else#1\fi}\EatBibTeXPeriod", +} + +@Book{Stern:MNN91, + author = "Hal Stern", + title = "Managing {NFS} and {NIS}", + publisher = pub-OR, + year = "1991", + address = pub-OR:adr, + ISBN = "0-937175-75-7", + LCCN = "TK5105.5 .S74 1991", + pages = "xxiv + 410", + bibdate = "Wed Dec 15 10:42:43 1993", +} + +@Book{Stevens:UNP90, + author = "W. Richard Stevens", + title = "{UNIX} Network Programming", + publisher = pub-PH, + address = pub-PH:adr, + year = "1990", + ISBN = "0-13-949876-1", + LCCN = "QA76.76.O63 S755 1990", + pages = "xi + 772", + bibdate = "Wed Dec 15 10:42:44 1993", +} + +@Book{Stevens:APU92, + author = "Richard Stevens", + title = "Advanced Programming in the {UNIX} Environment", + publisher = pub-AW, + year = "1992", + ISBN = "0-201-56317-7", + LCCN = "QA76.76.O63 S754 1992", + price = "US\$52.25", + address = pub-AW:adr, + note = "The source codes and errata list are obtainable by + anonymous {\tt ftp} from \path|ftp.uu.net| (in + \path|/published/books|).", + pages = "xviii + 744", + bibdate = "Tue Sep 28 14:37:02 1993", +} + +@Article{Stevenson:COMPUTER-14-3-51, + author = "David Stevenson", + title = "A Proposed Standard for Binary Floating-Point + Arithmetic", + journal = j-COMPUTER, + year = "1981", + volume = "14", + number = "3", + pages = "51--62", + month = mar, +} + +@Book{Stewart:IMC73, + author = "G. W. Stewart", + title = "Introduction to Matrix Computations", + publisher = pub-AP, + address = pub-AP:adr, + year = "1973", + series = "Computer Science and Applied Mathematics, Editor: + Werner Rheinboldt", + ISBN = "0-12-670350-7", + LCCN = "QA188 .S71 1973", + pages = "xiii + 441", + bibdate = "Wed Dec 15 10:42:45 1993", +} + +@Book{Strang:PC86, + author = "John Strang", + title = "Programming with Curses", + publisher = pub-OR, + address = pub-OR:adr, + year = "1986", + ISBN = "0-937175-02-1", + pages= "71", + bibdate = "Wed Dec 15 18:30:04 1993", +} + +@Book{Strang:RWT86, + author = "John Strang", + title = "Reading and Writing {TERMCAP} Entries", + publisher = pub-OR, + address = pub-OR:adr, + year = "1986", + pages= "73", + bibdate = "Wed Dec 15 18:30:24 1993", +} + +@Book{Strang:TT88, + author = "John Strang and Tim O'Reilly and Linda Mui", + title = "Termcap and Terminfo", + publisher = pub-OR, + address = pub-OR:adr, + month = apr, + year = "1988", + ISBN = "0-937175-22-6", + LCCN = "QA76.76.O63 S765 1990", + pages= "xv + 253", + bibdate = "Wed Dec 15 18:33:11 1993", +} + +@Book{Stroustrup:CPL86, + author = "Bjarne Stroustrup", + title = "The {C++} Programming Language", + publisher = pub-AW, + address = pub-AW:adr, + year = "1986", + ISBN = "0-201-12078-X", + LCCN = "QA76.73.C153 S77 1986", + pages= "viii + 327", + email = "\path|bs@alice.uucp|", + bibdate = "Wed Dec 15 18:34:06 1993", +} + +@Book{Stroustrup:CPL91, + author = "Bjarne Stroustrup", + title = "The {C++} Programming Language", + publisher = pub-AW, + address = pub-AW:adr, + edition = "Second", + year = "1991", + ISBN = "0-201-53992-6", + LCCN = "QA76.73.C15 S79 1991", + pages = "xi + 669", + email = "\path|bs@alice.uucp|", + bibdate = "Wed Dec 15 10:42:50 1993", +} + +@Book{Strunk:ES79, + author = "William {Strunk Jr.} and E. B. White", + title = "The Elements of Style", + publisher = pub-MAC, + address = pub-MAC:adr, + year = "1979", + edition = "Third", + ISBN = "0-02-418230-3 (hardcover), 0-02-418220-6 (paperback)", + LCCN = "PE1408 .S77 1979", + pages = "xvii + 85", + bibdate = "Wed Dec 15 10:42:54 1993", +} + +@Book{Stuart:WAE84, + author = "Ann Stuart", + title = "Writing and Analyzing Effective Computer + Documentation", + publisher = pub-HRW, + address = pub-HRW:adr, + year = "1984", + ISBN = "0-03-063892-5", + LCCN = "QA76.9.D6 S78 1984", + pages = "x + 271", + bibdate = "Wed Dec 15 10:43:02 1993", +} + +@Manual{Sun:SPARC, + key = "Sun Microsystems", + title = "The {SPARC} Architecture Manual", + organization = pub-SUN, + address = pub-SUN:adr, + edition = "Part No: 800-1399-07", + year = "1987", + month = aug # " 8", +} + +@Article{Sunday:string-search, + author = "Daniel M. Sunday", + title = "A Very Fast Substring Search Algorithm", + journal = j-CACM, + year = "1990", + volume = "33", + number = "8", + pages = "132--142", + month = aug, + note = "See also \cite{Boyer:string-search} and + \cite{Knuth:string-search}.", +} + +@Book{Swartzlander:CA90-1, + author = "Earl E. {Swartzlander, Jr.}", + title = "Computer Arithmetic", + publisher = pub-IEEE, + address = pub-IEEE:adr, + year = "1990", + volume = "1", + ISBN = "0-8186-8931-5", + LCCN = "QA76.6 .C633 1990", + pages= "xiii + 378", + bibdate = "Wed Dec 15 10:43:03 1993", +} + +@Book{Swartzlander:CA90-2, + author = "Earl E. {Swartzlander, Jr.}", + title = "Computer Arithmetic", + publisher = pub-IEEE, + address = pub-IEEE:adr, + year = "1990", + volume = "2", + ISBN = "0-8186-8945-5", + LCCN = "QA76.9 .C62C66 1990", + pages= "ix + 396", +} + +@Book{Talbott:MPM86, + author = "Steve Talbott", + title = "Managing Projects with Make", + publisher = pub-OR, + address = pub-OR:adr, + year = "1986", +} + +@Book{Talbott:MPM88, + author = "Steve Talbott", + title = "Managing Projects with Make", + edition = "Second", + publisher = pub-OR, + address = pub-OR:adr, + year = "1988", + ISBN = "0-937175-04-8", + LCCN = "QA76.8.U65 T34 1988", + pages= "77", + libnote = "Not yet in my library.", + bibdate = "Wed Dec 15 10:49:30 1993", +} + +@Book{Tanenbaum:CN88, + author = "Andrew S. Tanenbaum", + title = "Computer Networks", + publisher = pub-PH, + address = pub-PH:adr, + year = "1988", + edition = "Second", + ISBN = "0-13-162959-X", + LCCN = "TK5105.5 .T36 1988", + pages = "xv + 658", + libnote = "Not yet in my library.", + bibdate = "Wed Dec 15 10:56:26 1993", +} + +@Book{Tanenbaum:MOS92, + author = "Andrew S. Tanenbaum", + title = "Modern Operating Systems", + publisher = pub-PH, + address = pub-PH:adr, + year = "1992", + ISBN = "0-13-588187-0", + LCCN = "QA76.76.O63 T359 1992", + pages = "xx + 728", + bibdate = "Wed Dec 15 10:57:22 1993", +} + +@Book{Tanenbaum:OSD87, + author = "Andrew S. Tanenbaum", + title = "Operating Systems\emdash Design and Implementation", + publisher = pub-PH, + address = pub-PH:adr, + year = "1987", + price = "US\$34.95", + ISBN = "0-13-637406-9", + LCCN = "QA76.76.O63 T36 1987", + pages = "xvi + 719", + bibdate = "Wed Dec 15 10:57:25 1993", +} + +@Book{Tatar:PGC87, + author = "Deborah G. Tatar", + title = "A Programmer's Guide to Common {LISP}", + publisher = pub-DP, + address = pub-DP:adr, + year = "1987", + note = "See also \cite{Steele:CLL84}.", + ISBN = "0-93237-687-8", + LCCN = "QA76.73.C28 T38 1987", + pages= "x + 327", + bibdate = "Wed Dec 15 18:35:27 1993", +} + +@TechReport{Tausworthe:methods, + author = "Robert C. Tausworthe", + title = "Standardized Development of Computer Software, Part + {I}. Methods", + institution = pub-JPL, + year = "1976", + number = "SP43-29", + address = pub-JPL:adr, + month = jul, + note = "379 pages.", +} + +@Book{Tausworthe:SDC77, + author = "Robert C. Tausworthe", + title = "Standardized Development of Computer Software", + publisher = pub-PH, + address = pub-PH:adr, + year = "1977", + ISBN = "0-13-842195-1", + LCCN = "QA76.6 T39 1977", + pages = "xiii + 379", + bibdate = "Wed Dec 15 10:57:27 1993", +} + +@Book{Tausworthe:SDC79, + author = "Robert C. Tausworthe", + title = "Standardized Development of Computer Software. Part + {II}. Standards", + publisher = pub-PH, + address = pub-PH:adr, + year = "1979", + ISBN = "0-13-842203-6", + LCCN = "QA76.6.T39 1976", + pages = "x + 548", + bibdate = "Wed Dec 15 10:58:23 1993", +} + +@Book{Tenenbaum:DSP81, + author = "Aaron M. Tenenbaum and Moshe J. Augenstein", + title = "Data Structures Using Pascal", + publisher = pub-PH, + address = pub-PH:adr, + year = "1981", + series = pub-PH # " Software Series, Editor: Brian W. + Kernighan", + ISBN = "0-13-196501-8", + LCCN = "QA76.9.D35 T46", + pages = "xiv + 545", + bibdate = "Wed Dec 15 10:58:37 1993", +} + +@Book{Thomas:UGU82, + author = "Rebecca Thomas and Jean Yates", + title = "A User Guide to the {UNIX} System", + publisher = pub-OMH, + address = pub-OMH:adr, + year = "1982", + ISBN = "0-931988-71-3", + LCCN = "QA76.8.U65 T45 1982", + pages = "xi + 508", + bibdate = "Wed Dec 15 10:58:50 1993", +} + +@Book{Thompson:MA81, + author = "Morris M. Thompson", + title = "Maps for America", + publisher = pub-USGPO, + address = pub-USGPO:adr, + year = "1981", + LCCN = "GA405 .T46 1981", + pages= "xiv + 265", + price = "US\$11.00", + bibdate = "Wed Dec 15 18:36:25 1993", +} + +@Article{Thompson:trusting-trust, + author = "Ken Thompson", + title = "Reflections on Trusting Trust", + journal = j-CACM, + year = "1984", + volume = "27", + number = "8", + pages = "761--763", + month = aug, +} + +@Book{Todino:LUS93, + author = "Grace Todino and John Strang and Jerry Peek", + title = "Learning the {UNIX} Operating System", + publisher = pub-OR, + year = "1993", + ISBN = "1-56592-060-0", + address = pub-OR:adr, + month = aug, + pages = "108", + price = "US\$9.95", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Mon Jan 3 17:39:58 1994", +} + +@Book{Todino:UUU87, + author = "Grace Todino", + title = "Using {UUCP} and Usenet", + publisher = pub-OR, + address = pub-OR:adr, + month = jul, + year = "1987", + ISBN = "0-937175-10-2", + LCCN = "QA 76.76 O63 T63 1991", + pages = "xv + 194", + bibdate = "Wed Dec 15 10:58:52 1993", +} + +@Book{Tolstov:FS62, + author = "Georgi P. Tolstov", + title = "Fourier Series", + publisher = pub-PH, + address = pub-PH:adr, + year = "1962", + LCCN = "QA404 .T573", + pages= "336", + bibdate = "Wed Dec 15 18:37:08 1993", +} + +@Article{Tsuji:structured-fortran, + author = "Tatsui Tsuji and Katsumasa Watanabe", + title = "Structured {Fortran} Preprocessors Generating + Optimized Output", + journal = j-SPE, + year = "1988", + volume = "18", + number = "5", + pages = "427--442", + month = may, +} + +@Book{Tucker:PL77, + author = "Allen B. {Tucker, Jr.}", + title = "Programming Languages", + publisher = pub-MH, + address = pub-MH:adr, + year = "1977", + series = "McGraw-Hill Computer Science Series, Editor: Richard + W. Hamming and Edward A. Feigenbaum", + ISBN = "0-07-065415-8", + LCCN = "QA76.7 T8 1977", + pages = "xv + 439", + bibdate = "Wed Dec 15 10:58:52 1993", +} + +@Book{Tufte:EI90, + author = "Edward R. Tufte", + title = "Envisioning Information", + publisher = pub-GP, + year = "1990", + address = pub-GP:adr, + LCCN = "P93.5 .T84 1990", + pages= "126", + price = "US\$48.00", +} + +@Book{Tufte:VDQ83, + author = "Edward R. Tufte", + title = "The Visual Display of Quantitative Information", + publisher = pub-GP, + year = "1983", + address = pub-GP:adr, + price = "US\$34.00", + ISBN = "0-9613921-0-X", + LCCN = "K27.S8 T84", + pages = "197", + bibdate = "Wed Dec 15 10:58:53 1993", +} + +@Book{Tymms:AI87, + author = "W. R. Tymms and M. D. Wyatt", + title = "The Art of Illuminating", + publisher = pub-CHARTWELL, + year = "1987", + address = pub-CHARTWELL:adr, + ISBN = "1-55521-198-4", + LCCN = "ND3310 .T95 1987", + pages = "104", + bibdate = "Wed Dec 15 10:58:55 1993", +} + +@Book{Ulichney:DH87, + author = "Robert Ulichney", + title = "Digital Halftoning", + publisher = pub-MIT, + address = pub-MIT:adr, + year = "1987", + ISBN = "0-262-21009-6", + LCCN = "T385 .U451 1987", + pages = "xiv + 362", + bibdate = "Wed Dec 15 10:58:55 1993", +} + +@Book{Unger:FGF87, + author = "J. Marshall Unger", + title = "The Fifth Generation Fallacy\emdash Why Japan is + Betting its Future on Artificial Intelligence", + publisher = pub-OUP, + address = pub-OUP:adr, + year = "1987", + price = "US\$19.95", + ISBN = "0-19-504939-X", + LCCN = "QA76.85 .U541 1987", + pages = "x + 230", + bibdate = "Wed Dec 15 10:58:56 1993", +} + +@Book{Unicode:US91, + key = "Uni91", + author = "{The Unicode Consortium}", + title = "The Unicode Standard: Worldwide Character Encoding. + Version 1.0. Volumes 1 and 2.", + publisher = pub-AW, + year = "1991", + ISBN = "0-201-56788-1 (paperback, vol. 1), 0-201-60845-6 + (paperback, vol. 2), 0-201-56788-1", + LCCN = "QA268 .U55 1991, Z103 .U6 1991", + address = pub-AW:adr, + price = "US\$39.95 (paperback), US\$32.95 (hardback)", + libnote = "Not yet in my library.", + bibdate = "Mon Jan 3 14:38:19 1994", +} + +@Book{Upstill:RMC90, + author = "Steve Upstill", + title = "The {RenderMan} Companion", + publisher = pub-AW, + address = pub-AW:adr, + year = "1990", + ISBN = "0-201-50868-0", + LCCN = "T385 .U67 1990", + pages = "xix + 475", + bibdate = "Wed Dec 15 10:58:57 1993", +} + +@Book{vanHerwijnen:PS90, + author = "Eric van Herwijnen", + title = "Practical {SGML}", + publisher = pub-KLUWER, + address = pub-KLUWER:adr, + year = "1990", + ISBN = "0-7923-0635-X", + LCCN = "QA76.73.S44 V36 1990", + pages = "xviii + 307", + price = "UK\pounds24.90, US\$49.00", +} + +@Book{VanLoan:CFF92, + author = "Charles F. Van Loan", + title = "Computational Frameworks for the Fast Fourier + Transform", + publisher = pub-SIAM, + address = pub-SIAM:adr, + year = "1992", + ISBN = "0-89871-285-8", + LCCN = "QA403.5 .V35 1992", + pages = "xiii + 273", + bibdate = "Wed Dec 15 10:58:58 1993", +} + +@Article{VanWyk:awk, + author = "Christopher J. Van Wyk", + title = "{AWK} as Glue for Programs", + journal = j-SPE, + year = "1986", + volume = "16", + number = "4", + pages = "369--388", + month = apr, +} + +@Book{VanWyk:DSC88, + author = "Christopher J. Van Wyk", + title = "Data Structures in {C}", + publisher = pub-AW, + address = pub-AW:adr, + year = "1988", + ISBN = "0-201-16116-8", + LCCN = "QA76.73.C15 V36 1988", + pages = "x + 387", + libnote = "Not yet in my library.", + bibdate = "Wed Dec 15 10:58:58 1993", +} + +@Article{VanWyk:ideal, + author = "Christopher J. Van Wyk", + title = "A High-Level Language for Specifying Pictures", + journal = j-TOGS, + year = "1982", + volume = "1", + number = "2", + pages = "163--182", + month = apr, +} + +@Book{Vulis:MTA92, + author = "Michael Vulis", + title = "Modern {\TeX} and its Applications", + publisher = pub-CRC, + address = pub-CRC:adr, + year = "1992", + ISBN = "0-8493-4431-X", + LCCN = "Z253.4.T47V84 1993", + pages = "275", + price = "US\$32.95", + acknowledgement = ack-nhfb, + bibdate = "Wed Dec 15 19:53:27 1993", +} + +@Misc{Wall:perl, + author = "Larry Wall", + title = "perl\emdash Practical Extraction and Report Language", + howpublished = "Usenet \path|mod.sources| archives", + year = "1987", + note = "Electronic mail: + \path|lwall@jpl-devvax.jpl.nasa.gov|.", +} + +@Book{Wallis:PP82, + author = "Peter J. L. Wallis", + title = "Portable Programming", + publisher = pub-JW, + address = pub-JW:adr, + year = "1982", + ISBN = "0-470-27331-3", + LCCN = "QA76.6.W329 1982", + pages = "xiv + 141", + bibdate = "Wed Dec 15 10:58:59 1993", +} + +@Book{Walsh:MO75, + author = "G. R. Walsh", + title = "Methods of Optimization", + publisher = pub-JW, + address = pub-JW:adr, + year = "1975", + ISBN = "0-471-91922-5 (hardcover), 0-471-91924-1 (paperback)", + LCCN = "QA402.5 .W341", + pages = "x + 200", + bibdate = "Wed Dec 15 10:59:00 1993", +} + +@Book{Ward:APT85, + author = "Terry A. Ward", + title = "Applied Programming Techniques in C", + publisher = pub-SF, + address = pub-SF:adr, + year = "1985", + price = "US\$19.95", + ISBN = "0-673-18050-6", + LCCN = "QA76.73.C15 W37 1985", + pages = "xii + 349", + bibdate = "Wed Dec 15 10:59:01 1993", +} + +@Book{Watson:FSC90, + author = "Thomas J. {Watson Jr.}", + title = "Father Son \& Co.\emdash My Life at {IBM} and Beyond", + publisher = pub-BANTAM, + address = pub-BANTAM:adr, + year = "1990", + ISBN = "0-553-07011-8", + LCCN = "HD9696.C64 I4887 1990", + pages = "xi + 468", + note = "Memoirs of IBM President Watson, the son of the + founder of IBM.", + bibdate = "Wed Dec 15 10:59:01 1993", + libnote = "Not in my library.", +} + +@Book{Weaver:SAM94, + author = "David L. Weaver and Tom Germond", + title = "The {SPARC} Architecture Manual\emdash{}Version 9", + publisher = pub-PTRPH, + year = "1994", + ISBN = "0-13-099227-5", + address = pub-PTRPH:adr, + pages = "xxii + 357", + price = "US\$33.00", + acknowledgement = ack-nhfb, + bibdate = "Wed Feb 23 15:55:50 1994", +} + +@Book{Wegner:PAI80, + author = "Peter Wegner", + title = "Programming with Ada: An Introduction by Means of + Graduated Examples", + publisher = pub-PH, + address = pub-PH:adr, + year = "1980", + ISBN = "0-13-730697-0", + LCCN = "QA76.73.A35 W4 1980", + pages = "xi + 211", + bibdate = "Wed Dec 15 10:59:02 1993", +} + +@TechReport{Weitek:fp-chip, + author = "Weitek Corporation", + title = "{WTL} 1164\slash {WTL} 1165 64-bit {IEEE} + Float\-ing-Point Multiplier\slash Divider and {ALU}", + institution = pub-WEITEK, + year = "1986", + address = pub-WEITEK:adr, + month = jul, +} + +@Book{Weiss:IPP93, + author = "Shlomo Weiss and James E. Smith", + title = "{IBM} Power and {PowerPC}: Architecture and + Implementation", + publisher = pub-MK, + year = "1993", + ISBN = "1-55860-279-8", + address = pub-MK:adr, + price = "US\$54.95", + acknowledgement = ack-nhfb, + libnote = "Not yet in my library.", + bibdate = "Fri Mar 18 10:28:29 1994", +} + +@Book{Weitzman:DMM80, + author = "Cay Weitzman", + title = "Distributed Micro\slash Minicomputer Systems\emdash + Structure, Implementations, and Application", + publisher = pub-PH, + address = pub-PH:adr, + year = "1980", + price = "US\$22.50", + ISBN = "0-13-216481-7", + LCCN = "QA76.9.D5 .W44 1980", + pages = "xii + 403", + bibdate = "Wed Dec 15 10:59:03 1993", +} + +@Book{White:CEA90, + author = "Jan V. White", + title = "Color for the Electronic Age", + publisher = pub-WGP, + address = pub-WGP:adr, + year = "1990", + ISBN = "0-8230-0732-4", + LCCN = "Z 286 D47 W49 1990", + pages = "207", + bibdate = "Wed Dec 15 10:59:04 1993", +} + +@Book{White:GDE88, + author = "Jan V. White", + title = "Graphic Design for the Electronic Age", + publisher = pub-WGP, + year = "1988", + address = pub-WGP:adr, + ISBN = "0-8230-2122-X", + LCCN = "Z286.D47 W5 1988", + annote = "A very good book on typography and document design; + main topics are components of larger documents.", + keywords = "typography, layout, design", + acknowledgement = ack-nhfb # " and " # ack-fm, + pages = "xi + 211", + bibdate = "Wed Dec 15 10:59:04 1993", +} + +@Book{White:GP90, + author = "Jan V. White", + title = "Great Pages", + publisher = pub-SERIF, + address = pub-SERIF:adr, + year = "1990", + ISBN = "1-878567-01-2", + LCCN = "Z286.D47 W5 1990", + pages = "128", + bibdate = "Wed Dec 15 10:59:05 1993", +} + +@Book{White:MG83, + author = "Jan V. White", + title = "Mastering Graphics", + publisher = pub-BOWK, + year = "1983", + address = pub-BOWK:adr, + ISBN = "0-8352-1704-3", + LCCN = "Z253 .W47 1983", + pages = "xiii + 180", + libnote = "Not yet in my library.", + bibdate = "Wed Dec 15 10:59:05 1993", +} + +@Book{Wiederhold:DD77, + author = "Gio Wiederhold", + title = "Database Design", + publisher = pub-MH, + address = pub-MH:adr, + year = "1977", + series = "McGraw-Hill Computer Science Series, Editor: Richard + W. Hamming and Edward A. Feigenbaum", + ISBN = "0-07-070130-X", + LCCN = "QA76.9.D3 W531", + pages = "xiii + 658", + bibdate = "Wed Dec 15 10:59:06 1993", +} + +@Book{Wiederhold:DD83, + author = "Gio Wiederhold", + title = "Database Design", + publisher = pub-MH, + address = pub-MH:adr, + year = "1983", + series = "McGraw-Hill Computer Science Series, Editor: Richard + W. Hamming and Edward A. Feigenbaum", + edition = "Second", + price = "US\$29.95", + ISBN = "0-07-070132-6", + LCCN = "QA76.9.D3 W531 1983", + pages = "xvi + 751", + bibdate = "Wed Dec 15 10:59:06 1993", +} + +@Book{Wiederhold:FOD83, + author = "Gio Wiederhold", + title = "File Organization for Database Design", + publisher = pub-MH, + address = pub-MH:adr, + year = "1983", + series = "McGraw-Hill Computer Science Series, Editor: Richard + W. Hamming and Edward A. Feigenbaum", + bibdate = "Wed Dec 15 10:59:07 1993", +} + +@Book{Wiederhold:FOD87, + author = "Gio Wiederhold", + title = "File Organization for Database Design", + publisher = pub-MH, + address = pub-MH:adr, + year = "1987", + edition = "Second", + series = "McGraw-Hill Computer Science Series, Editor: Richard + W. Hamming and Edward A. Feigenbaum", + ISBN = "0-07-070133-4", + LCCN = "QA76.9.F5 W53 1987", + pages= "619", + price = "US\$38.95", + bibdate = "Wed Dec 15 18:40:17 1993", +} + +@Book{Wilf:AC86, + author = "Herbert S. Wilf", + title = "Algorithms and Complexity", + publisher = pub-PH, + address = pub-PH:adr, + year = "1986", + ISBN = "0-13-021973-8 (hardcover), 0-13-022054-X (paperback)", + LCCN = "QA63 .W55 1986", + pages = "vi + 231", + bibdate = "Wed Dec 15 10:59:08 1993", +} + +@Book{Wilkinson:AEP65, + author = "James H. Wilkinson", + title = "The Algebraic Eigenvalue Problem", + publisher = pub-CP, + address = pub-CP:adr, + year = "1965", + ISBN = "0-19-853403-5", + LCCN = "QA218 .W686 1965", + pages = "xviii + 662", + bibdate = "Wed Dec 15 10:59:09 1993", +} + +@Book{Wilkinson:LA71, + author = "James H. Wilkinson and Christian Reinsch", + title = "Linear Algebra", + publisher = pub-SV, + address = pub-SV:adr, + year = "1971", + volume = "II", + series = "Handbook for Automatic Computation, Editors: F. L. + Bauer, A. S. Householder, F. W. J. Olver, H. + Rutishauser, K. Samelson and E. Stiefel", + ISBN = "0-387-05414-6, 3-540-05414-6", + LCCN = "QA251 .W67", + pages= "viii + 439", + bibdate = "Wed Dec 15 18:44:50 1993", +} + +@Book{Wirth:ADS76, + author = "Niklaus Wirth", + title = "Algorithms $+$ Data Structures $=$ Programs", + publisher = pub-PH, + address = pub-PH:adr, + year = "1976", + series = pub-PH # " Series in Automatic Computation", + ISBN = "0-13-022418-9", + LCCN = "QA76.6 .W561", + pages = "xvii + 366", + bibdate = "Wed Dec 15 10:59:10 1993", +} + +@Book{Wirth:ADS86, + author = "Niklaus Wirth", + title = "Algorithms and Data Structures", + publisher = pub-PH, + address = pub-PH:adr, + year = "1986", + ISBN = "0-13-022005-1", + LCCN = "QA76.9.D35 W58 1986", + pages = "288", + bibdate = "Wed Dec 15 10:59:10 1993", +} + +@Book{Wirth:PM83, + author = "Niklaus Wirth", + title = "Programming in Modula-2", + publisher = pub-SV, + address = pub-SV:adr, + year = "1983", + edition = "Second", + ISBN = "0-387-12206-0", + LCCN = "QA76.73.M63 W5713 1983", + pages = "176", + bibdate = "Wed Dec 15 10:59:11 1993", +} + +@InCollection{Wirth:DLC90, + author = "Niklaus Wirth", + title = "Drawing Lines, Circles, and Ellipses in a Raster", + booktitle = "Beauty is our business: a birthday salute to {Edsger + W. Dijkstra}", + publisher = pub-SV, + year = "1990", + ISBN = "0-387-97299-4", + LCCN = "QA76 .B326 1990", + editor = "W. H. J. Feijen and A. J. M. van Gasteren and D. Gries + and J. Misra", + address = pub-SV:adr, + chapter = "51", + pages = "428--434 (of xix + 453)", + acknowledgement = ack-nhfb, + note = "This paper rederives the Bresenham line and circle + drawing algorithms, and then extends the latter to + handle ellipses.", + bibdate = "Sun Mar 27 17:53:57 1994", +} + +@Book{Wirth:PO92, + author = "Niklaus Wirth", + title = "Project Oberon\emdash The Design of an Operating + System and Compiler", + publisher = pub-AW, + year = "1992", + ISBN = "0-201-54428-8", + LCCN = "QA76.76.O63 W58 1992", + address = pub-AW:adr, + pages = "xi + 548", + bibdate = "Wed Sep 29 18:54:37 1993", +} + +@TechReport{Wolcott:hershey-fonts, + author = "Norman M. Wolcott and Joseph Hilsenrath", + title = "A Contribution to Computer Typesetting Techniques. + {Tables} of Coordinates for {Hershey}'s Repertoire of + Occidental Type Fonts and Graphics Symbols", + institution = "U. S. National Bureau of Standards", + year = "1976", + number = "PB-251 845", + month = apr, + note = "NBS Special Publication 424", +} + +@Book{Wolfram:MSD91, + author = "Stephen Wolfram", + title = "Mathematica\emdash{}A System for Doing Mathematics by + Computer", + publisher = pub-AW, + address = pub-AW:adr, + year = "1991", + edition = "Second", + ISBN = "0-201-51507-5", + LCCN = "QA76.95 .W65 1991", + pages = "xxii + 961", + bibdate = "Wed Dec 15 10:59:12 1993", +} + +@Book{Wolfram:MRG92, + author = "Stephen Wolfram", + title = "Mathematica Reference Guide", + publisher = pub-AW, + year = "1992", + ISBN = "0-201-51502-4, 0-201-51507-5 (paperback), + 0-201-19330-2", + LCCN = "QA76.95 .W66 1992", + address = pub-AW:adr, + pages = "305", + bibdate = "Mon Jan 3 12:25:34 1994", +} + +@Book{Wonneberger:L88, + author = "Reinhard Wonneberger", + title = "{\LaTeX{}}", + edition = "Second", + publisher = pub-AW, + address = pub-AW:adr, + year = "1988", + ISBN = "3-89319-152-6", +} + +@Misc{Wood:plj, + author = "Patrick {Wood, editor}", + title = "{\POSTSCRIPT} {Language} {Journal}", + howpublished = "Pipeline Associates, Inc., P. O. Box 5763, + Parsippany, NJ 07054", +} + +@Article{Wu:j-CACM-35-10-83, + author = "Sun Wu and Udi Manber", + title = "Fast Text Searching Allowing Errors", + journal = j-CACM, + year = "1992", + volume = "35", + number = "10", + pages = "83--91", + month = oct, + note = "This algorithm in this paper is implemented in the + \path|agrep| program, publicly available via ANONYMOUS + FTP to \path|cs.arizona.edu| in the \path|agrep| + subdirectory. See also + \cite{Baeza-Yates:j-CACM-35-10-74}.", + bibdate = "Sat Nov 7 11:31:19 1992", +} + +@TechReport{Xerox:color, + author = "Xerox Corporation", + title = "The {Xerox} {Color} {Encoding} {Standard}", + institution = "Xerox Systems Institute", + number = "XNSS 288811", + year = "1989", + month = mar, +} + +@Book{xopen:XPG88-4, + author = "{X/Open Company, Ltd.}", + title = "X\slash Open Portability Guide, Programming + Languages", + publisher = pub-PH, + address = pub-PH:adr, + year = "1988", + volume = "4", + ISBN = "0-13-685868-6", + pages= "xiii + 198", + bibdate = "Thu Dec 16 08:02:25 1993", +} + +@Book{xopen:XPG88-5, + author = "{X/Open Company, Ltd.}", + title = "X\slash Open Portability Guide, Data Management", + publisher = pub-PH, + address = pub-PH:adr, + year = "1988", + volume = "5", + ISBN = "0-13-685876-7", + pages= "xiii + 204", + bibdate = "Thu Dec 16 08:02:52 1993", +} + +@Book{xopen:XPG88-6, + author = "{X/Open Company, Ltd.}", + title = "X\slash Open Portability Guide, Window Management", + publisher = pub-PH, + address = pub-PH:adr, + year = "1988", + volume = "6", + ISBN = "0-13-685884-8", + pages= "xiv + 338", + bibdate = "Thu Dec 16 08:03:33 1993", +} + +@Book{xopen:XPG88-7, + author = "{X/Open Company, Ltd.}", + title = "X\slash Open Portability Guide, Networking Services", + publisher = pub-PH, + address = pub-PH:adr, + year = "1988", + volume = "7", + ISBN = "0-13-685892-9", + pages= "xiii + 144", + bibdate = "Thu Dec 16 08:04:12 1993", +} + +@Book{xopen:XPG89-1, + author = "{X/Open Company, Ltd.}", + title = "X\slash Open Portability Guide, {XSI} Commands and + Utilities", + publisher = pub-PH, + address = pub-PH:adr, + year = "1989", + volume = "1", + ISBN = "0-13-685835-X", + pages = "xii + 340", + bibdate = "Wed Dec 15 19:50:06 1993", +} + +@Book{xopen:XPG89-2, + author = "{X/Open Company, Ltd.}", + title = "X\slash Open Portability Guide, {XSI} System + Interface and Headers", + publisher = pub-PH, + address = pub-PH:adr, + year = "1989", + volume = "2", + ISBN = "0-13-685843-0", + pages = "xx + 666", + bibdate = "Thu Dec 16 08:05:00 1993", +} + +@Book{xopen:XPG89-3, + author = "{X/Open Company, Ltd.}", + title = "X\slash Open Portability Guide, Supplementary + Definitions", + publisher = pub-PH, + address = pub-PH:adr, + year = "1989", + volume = "3", + ISBN = "0-13-685850-3", + pages= "xiv + 172", + bibdate = "Thu Dec 16 08:01:40 1993", +} + +@Book{Yeung:ALG84, + author = "Bik Chung Yeung", + title = "8086\slash 8088 Assembly Language Programming", + publisher = pub-W, + address = pub-W:adr, + year = "1984", + price = "US\$23.88", + ISBN = "0-471-90463-5", + LCCN = "QA 76.8 I292 Y48 1984", + pages = "xi + 265", + bibdate = "Wed Dec 15 10:59:12 1993", +} + +@Book{Young:IA83, + author = "Stephen J. Young", + title = "An Introduction to Ada", + publisher = pub-EH, + address = pub-EH:adr, + year = "1983", + series = "Ellis Horwood Series in Computers and their + Applications, Editor: Brian Meek", + price = "UK\pounds 25.00", + ISBN = "0-85312-535-X", + LCCN = "QA76.73.A35 Y68 1983", + pages = "400", + bibdate = "Wed Dec 15 10:59:13 1993", +} + +@Book{Young:ISL71, + author = "David M. Young", + title = "Iterative Solution of Large Linear Systems", + publisher = pub-AP, + address = pub-AP:adr, + year = "1971", + series = "Computer Science and Applied Mathematics, Editor: + Werner Rheinboldt", + ISBN = "0-12-773050-8", + LCCN = "QA195 .Y681 1971", + pages = "xxiv + 570", + bibdate = "Wed Dec 15 10:59:14 1993", +} + +@Book{Young:XWS89, + author = "Douglas A. Young", + title = "X Window Systems\emdash Programming and Applications + with Xt", + publisher = pub-PH, + address = pub-PH:adr, + year = "1989", + ISBN = "0-13-972167-3", + LCCN = "QA76.76 .W56 Y68 1989", + pages = "x + 468", + bibdate = "Tue Dec 14 23:50:39 1993", +} + +@Book{Young:XWS90, + author = "Douglas A. Young", + title = "X Window Systems\emdash Pro\-gram\-ming and + Applications with Xt\emdash {OSF}\slash Mo\-tif + Edition", + publisher = pub-PH, + address = pub-PH:adr, + year = "1990", + ISBN = "0-13-497074-8", + LCCN = "QA76.76 .W56 Y67 1990", + pages = "x + 533", + bibdate = "Tue Dec 14 23:50:15 1993", +} + +@Book{Young:XWS92, + author = "Douglas A. Young and John A. Pew", + title = "The X Window System\emdash Pro\-gram\-ming and + Applications with Xt\emdash {OPEN} {LOOK} Edition", + publisher = pub-PH, + address = pub-PH:adr, + year = "1992", + ISBN = "0-13-982992-X", + LCCN = "QA76.76 .W56Y67 1992", + pages = "vii + 589", + bibdate = "Tue Dec 14 23:48:23 1993", +} + +@Book{Zlotnick:PSP91, + author = "Fred Zlotnick", + title = "The {POSIX.1} standard: a programmer's guide", + publisher = pub-BENCUM, + year = "1991", + address = pub-BENCUM:adr, + bibdate = "Wed May 12 21:33:56 1993", + ISBN = "0-8053-9605-5", + LCCN = "QA76.76.063 Z57 1991", + pages = "xi + 379", + bibdate = "Tue Dec 14 23:46:44 1993", +} diff --git a/misc.bib b/misc.bib new file mode 100644 index 0000000..0d23ae7 --- /dev/null +++ b/misc.bib @@ -0,0 +1,31 @@ + +@ARTICLE{aho:75, + author = {A[lfred] V. Aho and M[argaret] J. Corasick}, + title = {Efficient String Matching: An Aid to Bibliographic Search.}, + journal = {CACM}, + year = 1975, + volume = 18, + number = 6, + pages = "333-340", + month = "June", +} + +@ARTICLE{hanson:90, + author = {C[hris] Hanson}, + title = {Efficient Stack Allocation for Tail-Recursive Languages.}, + series = {Proceedings of the Conference on LISP and Functional Programming}, + year = 1990, + address = "Nice, France", + publisher = "ACM Press", + organization = ACM, +} + +@ARTICLE{drakos:94, + author = {Nikos Drakos}, + title = {From Text to Hypertext: A Post-Hoc Rationalisation of LaTeX2HTML}, + journal = {Computer Networks and ISDN Systems}, + volume = 27, + pages = "215-224", + year = 1994, + publisher = "Elsevier", +} diff --git a/names.c b/names.c new file mode 100644 index 0000000..aeccbbd --- /dev/null +++ b/names.c @@ -0,0 +1,628 @@ +#include "global.h" +enum { LESS, GREATER, EQUAL, PREFIX, EXTENSION }; + +static int compare(x, y) + char *x; + char *y; +{ + int len, result; + int xl = strlen(x); + int yl = strlen(y); + int xp = x[xl - 1] == ' '; + int yp = y[yl - 1] == ' '; + if (xp) xl--; + if (yp) yl--; + len = xl < yl ? xl : yl; + result = strncmp(x, y, len); + if (result < 0) return GREATER; + else if (result > 0) return LESS; + else if (xl < yl) { + if (xp) return EXTENSION; + else return LESS; + } + else if (xl > yl) { + if (yp) return PREFIX; + else return GREATER; + } + else return EQUAL; +} +char *save_string(s) + char *s; +{ + char *new = (char *) arena_getmem((strlen(s) + 1) * sizeof(char)); + strcpy(new, s); + return new; +} +static int ambiguous_prefix(); + +static char * found_name = NULL; + +Name *prefix_add(rt, spelling, sector) + Name **rt; + char *spelling; + unsigned char sector; +{ + Name *node = *rt; + int cmp; + + while (node) { + switch ((cmp = compare(node->spelling, spelling))) { + case GREATER: rt = &node->rlink; + break; + case LESS: rt = &node->llink; + break; + case EQUAL: + found_name = node->spelling; + case EXTENSION: if (node->sector > sector) { + rt = &node->rlink; + break; + } + else if (node->sector < sector) { + rt = &node->llink; + break; + } + if (cmp == EXTENSION) + node->spelling = save_string(spelling); + return node; + case PREFIX: { + if (ambiguous_prefix(node->llink, spelling, sector) || + ambiguous_prefix(node->rlink, spelling, sector)) + fprintf(stderr, + "%s: ambiguous prefix %c<%s...%c> (%s, line %d)\n", + command_name, nw_char, spelling, nw_char, source_name, source_line); + } + return node; + } + node = *rt; + } + /* Create new name entry */ + { + node = (Name *) arena_getmem(sizeof(Name)); + if (found_name && robs_strcmp(found_name, spelling) == 0) + node->spelling = found_name; + else + node->spelling = save_string(spelling); + node->mark = FALSE; + node->llink = NULL; + node->rlink = NULL; + node->uses = NULL; + node->defs = NULL; + node->arg[0] = + node->arg[1] = + node->arg[2] = + node->arg[3] = + node->arg[4] = + node->arg[5] = + node->arg[6] = + node->arg[7] = + node->arg[8] = NULL; + node->tab_flag = TRUE; + node->indent_flag = TRUE; + node->debug_flag = FALSE; + node->comment_flag = 0; + node->sector = sector; + *rt = node; + return node; + } +} +static int ambiguous_prefix(node, spelling, sector) + Name *node; + char *spelling; + unsigned char sector; +{ + while (node) { + switch (compare(node->spelling, spelling)) { + case GREATER: node = node->rlink; + break; + case LESS: node = node->llink; + break; + case EXTENSION: + case PREFIX: + case EQUAL: if (node->sector > sector) { + node = node->rlink; + break; + } + else if (node->sector < sector) { + node = node->llink; + break; + } + return TRUE; + } + } + return FALSE; +} +int robs_strcmp(char* x, char* y) +{ + int cmp = 0; + + for (; *x && *y; x++, y++) + { + /* Skip invisibles on 'x' */ + if (*x == '|') + x++; + + /* Skip invisibles on 'y' */ + if (*y == '|') + y++; + + if (*x == *y) + continue; + if (islower(*x) && toupper(*x) == *y) + { + if (!cmp) cmp = 1; + continue; + } + if (islower(*y) && *x == toupper(*y)) + { + if (!cmp) cmp = -1; + continue; + } + return 2*(toupper(*x) - toupper(*y)); + } + if (*x) + return 2; + if (*y) + return -2; + return cmp; +} +Name *name_add(rt, spelling, sector) + Name **rt; + char *spelling; + unsigned char sector; +{ + Name *node = *rt; + while (node) { + int result = robs_strcmp(node->spelling, spelling); + if (result > 0) + rt = &node->llink; + else if (result < 0) + rt = &node->rlink; + else + { + found_name = node->spelling; + if (node->sector > sector) + rt = &node->llink; + else if (node->sector < sector) + rt = &node->rlink; + else + return node; + } + node = *rt; + } + /* Create new name entry */ + { + node = (Name *) arena_getmem(sizeof(Name)); + if (found_name && robs_strcmp(found_name, spelling) == 0) + node->spelling = found_name; + else + node->spelling = save_string(spelling); + node->mark = FALSE; + node->llink = NULL; + node->rlink = NULL; + node->uses = NULL; + node->defs = NULL; + node->arg[0] = + node->arg[1] = + node->arg[2] = + node->arg[3] = + node->arg[4] = + node->arg[5] = + node->arg[6] = + node->arg[7] = + node->arg[8] = NULL; + node->tab_flag = TRUE; + node->indent_flag = TRUE; + node->debug_flag = FALSE; + node->comment_flag = 0; + node->sector = sector; + *rt = node; + return node; + } +} +Name *collect_file_name() +{ + Name *new_name; + char name[MAX_NAME_LEN]; + char *p = name; + int start_line = source_line; + int c = source_get(), c2; + while (isspace(c)) + c = source_get(); + while (isgraph(c)) { + *p++ = c; + c = source_get(); + } + if (p == name) { + fprintf(stderr, "%s: expected file name (%s, %d)\n", + command_name, source_name, start_line); + exit(-1); + } + *p = '\0'; + /* File names are always global. */ + new_name = name_add(&file_names, name, 0); + /* Handle optional per-file flags */ + { + while (1) { + while (isspace(c)) + c = source_get(); + if (c == '-') { + c = source_get(); + do { + switch (c) { + case 't': new_name->tab_flag = FALSE; + break; + case 'd': new_name->debug_flag = TRUE; + break; + case 'i': new_name->indent_flag = FALSE; + break; + case 'c': c = source_get(); + if (c == 'c') + new_name->comment_flag = 1; + else if (c == '+') + new_name->comment_flag = 2; + else if (c == 'p') + new_name->comment_flag = 3; + else + fprintf(stderr, "%s: Unrecognised comment flag (%s, %d)\n", + command_name, source_name, source_line); + + break; + default : fprintf(stderr, "%s: unexpected per-file flag (%s, %d)\n", + command_name, source_name, source_line); + break; + } + c = source_get(); + } while (!isspace(c)); + } + else break; + } + } + c2 = source_get(); + if (c != nw_char || (c2 != '{' && c2 != '(' && c2 != '[')) { + fprintf(stderr, "%s: expected %c{, %c[, or %c( after file name (%s, %d)\n", + command_name, nw_char, nw_char, nw_char, source_name, start_line); + exit(-1); + } + return new_name; +} +Name *collect_macro_name() +{ + char name[MAX_NAME_LEN]; + char args[1000]; + char * arg[9]; + char * argp = args; + int argc = 0; + char *p = name; + int start_line = source_line; + int c = source_get(), c2; + unsigned char sector = current_sector; + + if (c == '+') { + sector = 0; + c = source_get(); + } + while (isspace(c)) + c = source_get(); + while (c != EOF) { + Name * node; + switch (c) { + case '\t': + case ' ': *p++ = ' '; + do + c = source_get(); + while (c == ' ' || c == '\t'); + break; + case '\n': { + do + c = source_get(); + while (isspace(c)); + c2 = source_get(); + if (c != nw_char || (c2 != '{' && c2 != '(' && c2 != '[')) { + fprintf(stderr, "%s: expected %c{ after fragment name (%s, %d)\n", + command_name, nw_char, source_name, start_line); + exit(-1); + } + /* Cleanup and install name */ + { + if (p > name && p[-1] == ' ') + p--; + if (p - name > 3 && p[-1] == '.' && p[-2] == '.' && p[-3] == '.') { + p[-3] = ' '; + p -= 2; + } + if (p == name || name[0] == ' ') { + fprintf(stderr, "%s: empty name (%s, %d)\n", + command_name, source_name, source_line); + exit(-1); + } + *p = '\0'; + node = prefix_add(¯o_names, name, sector); + } + return install_args(node, argc, arg); + } + default: + if (c==nw_char) + { + /* Check for terminating at-sequence and return name */ + { + c = source_get(); + switch (c) { + case '(': + case '[': + case '{': { + if (p > name && p[-1] == ' ') + p--; + if (p - name > 3 && p[-1] == '.' && p[-2] == '.' && p[-3] == '.') { + p[-3] = ' '; + p -= 2; + } + if (p == name || name[0] == ' ') { + fprintf(stderr, "%s: empty name (%s, %d)\n", + command_name, source_name, source_line); + exit(-1); + } + *p = '\0'; + node = prefix_add(¯o_names, name, sector); + } + return install_args(node, argc, arg); + case '\'': arg[argc] = argp; + while ((c = source_get()) != EOF) { + if (c==nw_char) { + c2 = source_get(); + if (c2=='\'') { + /* Make this argument */ + if (argc < 9) { + *argp++ = '\000'; + argc += 1; + } + + c = source_get(); + break; + } + else + *argp++ = c2; + } + else + *argp++ = c; + } + *p++ = ARG_CHR; + + break; + default: + if (c==nw_char) + { + *p++ = c; + break; + } + fprintf(stderr, + "%s: unexpected %c%c in fragment definition name (%s, %d)\n", + command_name, nw_char, c, source_name, start_line); + exit(-1); + } + } + break; + } + *p++ = c; + c = source_get(); + break; + } + } + fprintf(stderr, "%s: expected fragment name (%s, %d)\n", + command_name, source_name, start_line); + exit(-1); + return NULL; /* unreachable return to avoid warnings on some compilers */ +} +Name *install_args(Name * name, int argc, char *arg[9]) +{ + int i; + + for (i = 0; i < argc; i++) { + if (name->arg[i] == NULL) + name->arg[i] = save_string(arg[i]); + } + return name; +} +Arglist * buildArglist(Name * name, Arglist * a) +{ + Arglist * args = (Arglist *)arena_getmem(sizeof(Arglist)); + + args->args = a; + args->next = NULL; + args->name = name; + return args; +} +Arglist * collect_scrap_name(int current_scrap) +{ + char name[MAX_NAME_LEN]; + char *p = name; + int c = source_get(); + unsigned char sector = current_sector; + Arglist * head = NULL; + Arglist ** tail = &head; + + if (c == '+') + { + sector = 0; + c = source_get(); + } + while (c == ' ' || c == '\t') + c = source_get(); + while (c != EOF) { + switch (c) { + case '\t': + case ' ': *p++ = ' '; + do + c = source_get(); + while (c == ' ' || c == '\t'); + break; + default: + if (c==nw_char) + { + /* Look for end of scrap name and return */ + { + Name * node; + + c = source_get(); + switch (c) { + + case '\'': { + /* Add plain string argument */ + char buff[MAX_NAME_LEN]; + char * s = buff; + int c, c2; + + while ((c = source_get()) != EOF) { + if (c==nw_char) { + c2 = source_get(); + if (c2=='\'') + break; + *s++ = c2; + } + else + *s++ = c; + } + *s = '\000'; + /* Add buff to current arg list */ + *tail = buildArglist(NULL, (Arglist *)save_string(buff)); + tail = &(*tail)->next; + + } + *p++ = ARG_CHR; + c = source_get(); + break; + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': { + /* Add a propagated argument */ + char buff[3]; + buff[0] = ARG_CHR; + buff[1] = c; + buff[2] = '\000'; + /* Add buff to current arg list */ + *tail = buildArglist(NULL, (Arglist *)save_string(buff)); + tail = &(*tail)->next; + + } + *p++ = ARG_CHR; + c = source_get(); + break; + case '{': { + /* Add an inline scrap argument */ + int s = collect_scrap(); + Scrap_Node * d = (Scrap_Node *)arena_getmem(sizeof(Scrap_Node)); + d->scrap = s; + d->quoted = 0; + d->next = NULL; + *tail = buildArglist((Name *)1, (Arglist *)d); + tail = &(*tail)->next; + } + *p++ = ARG_CHR; + c = source_get(); + break; + case '<': + /* Add macro call argument */ + *tail = collect_scrap_name(current_scrap); + if (current_scrap >= 0) + add_to_use((*tail)->name, current_scrap); + tail = &(*tail)->next; + + *p++ = ARG_CHR; + c = source_get(); + break; + case '(': + scrap_name_has_parameters = 1; + /* Cleanup and install name */ + { + if (p > name && p[-1] == ' ') + p--; + if (p - name > 3 && p[-1] == '.' && p[-2] == '.' && p[-3] == '.') { + p[-3] = ' '; + p -= 2; + } + if (p == name || name[0] == ' ') { + fprintf(stderr, "%s: empty name (%s, %d)\n", + command_name, source_name, source_line); + exit(-1); + } + *p = '\0'; + node = prefix_add(¯o_names, name, sector); + } + return buildArglist(node, head); + case '>': + scrap_name_has_parameters = 0; + /* Cleanup and install name */ + { + if (p > name && p[-1] == ' ') + p--; + if (p - name > 3 && p[-1] == '.' && p[-2] == '.' && p[-3] == '.') { + p[-3] = ' '; + p -= 2; + } + if (p == name || name[0] == ' ') { + fprintf(stderr, "%s: empty name (%s, %d)\n", + command_name, source_name, source_line); + exit(-1); + } + *p = '\0'; + node = prefix_add(¯o_names, name, sector); + } + return buildArglist(node, head); + + default: + if (c==nw_char) + { + *p++ = c; + c = source_get(); + break; + } + fprintf(stderr, + "%s: unexpected %c%c in fragment invocation name (%s, %d)\n", + command_name, nw_char, c, source_name, source_line); + exit(-1); + } + } + break; + } + if (!isgraph(c)) { + fprintf(stderr, + "%s: unexpected character in fragment name (%s, %d)\n", + command_name, source_name, source_line); + exit(-1); + } + *p++ = c; + c = source_get(); + break; + } + } + fprintf(stderr, "%s: unexpected end of file (%s, %d)\n", + command_name, source_name, source_line); + exit(-1); + return NULL; /* unreachable return to avoid warnings on some compilers */ +} +static Scrap_Node *reverse(); /* a forward declaration */ + +void reverse_lists(names) + Name *names; +{ + while (names) { + reverse_lists(names->llink); + names->defs = reverse(names->defs); + names->uses = reverse(names->uses); + names = names->rlink; + } +} +static Scrap_Node *reverse(a) + Scrap_Node *a; +{ + if (a) { + Scrap_Node *b = a->next; + a->next = NULL; + while (b) { + Scrap_Node *c = b->next; + b->next = a; + a = b; + b = c; + } + } + return a; +} diff --git a/nuweb.el b/nuweb.el new file mode 100644 index 0000000..ce02c73 --- /dev/null +++ b/nuweb.el @@ -0,0 +1,809 @@ +;;; nuweb.el --- major mode to edit nuweb files with AucTex or TeX. +;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Original header +;;; +;;; $ Id: nuweb.el 184 2010-04-12 18:42:08Z ddw $ +;;; +;;; +;; Author: Dominique de Waleffe <ddewaleffe@gmail.com> +;; Maintainer: Dominique de Waleffe <ddewaleffe@gmail.com> +;; Version: $ Revision: 184 $ +;; Keywords: nuweb programming tex tools languages +;; +;; +;; DISCLAIMER: I do not guarantee anything about this +;; package, nor does my employer. You get it as is and not much else. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This nuweb support package is free software, just as GNU Emacs; you +;; can redistribute it and/or modify it under the terms of the GNU +;; General Public License as published by ;the Free Software Foundation; +;; either version 2, or (at your option) any later version. +;; GNU Emacs is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;; + +;;; +;;; Bug reports , suggestions are welcome at http:// + +;;; DOCUMENTATION (short) there is no long version yet:-) +;;; To install: +;;; ; if your version of nuweb does not know about @% comments +;;; (setq nuweb-comment-leader "") +;;; ; if you want to activate the mode for .w files +;;; (push '( "\\.w" . nuweb-mode) auto-mode-alist) +;;; ; To load it +;;; (require 'nuweb) +;;; +;;; When called, nuweb-mode calls latex-mode and adds the following +;;; bindings: +;;; +;;; A) Help for editing scraps in language dependent mode +;;; +;;; C-c C-z nuweb-edit-this scrap +;;; Edit the scrap point is on in its own buffer *Source* +;;; put into the mode specified as follows: +;;; a) if the first line contains -*-mode-name-*- that is +;;; used, +;;; b) otherwise, for @o <filename> scraps, the mode is +;;; derived from the value of auto-mode-alist +;;; c) otherwise it is taken from the (buffer local) variable +;;; nuweb-source-mode (which defaults to "emacs-lisp") +;;; +;;; The *Source* buffer is then put into Nuweb minor mode +;;; which adds two bindings: +;;; C-c C-z nuweb-install-this-scrap +;;; Which takes the *Source* buffer contents and puts +;;; it back into the web buffer in place of the old +;;; version of the scrap. +;;; C-c M-k nuweb-kill-this-scrap +;;; Which restores the old scrap, ignoring changes +;;; made. +;;; The original buffer is put in read-only mode until you +;;; call one of the two above functions or kill the +;;; *Source* buffer. +;;; C-c @ nuweb-insert-scrap +;;; With no argument: inserts an empty scrap template at +;;; point. +;;; With an argument: prompt for scrap type (oDdD), scrap +;;; name and language mode. A new scrap is inserted and +;;; edited as if nuweb-edit-this-scrap had been called. +;;; +;;; B) Help for navigation on definitions and uses +;;; (not normally allowed by the guidelones for elisp modes, I +;;; could not think of any other other than C-c C-d [rpsn] but +;;; auctex now uses C-c C-d....) +;;; +;;; C-c d r nuweb-compute-d-u +;;; Recompute all defs and uses in current buffer. +;;; C-c d p +;;; Pop back to previous def/use +;;; C-c d s +;;; Find first definition for scrap name at point +;;; C-c d n +;;; Find next definition of same scrap name +;;; C-c u s +;;; Find first use of scrap name at point +;;; C-c u n +;;; Find next use of smae scrap name +;;; M-mouse3 +;;; Find first def or first use (if on a def -> use, if on a +;;; use -> def) +;;; C-M-S-mouse1 +;;; Make an imenu for symbols (@|) , scrap names (@d) and +;;; files (@o). (imenu.el comes with 19.25, and should be on archive +;;; sites). +;;; +;;; C) The commands to run nuweb and latex on the file are known as +;;; Tangle: generate output files only +;;; Weave: generate tex file then run latex on it +;;; Web: does it all. +;;; Provided your version of nuweb does output !name(f.w) and +;;; !offset(<num>) in the generated tex file Auctex will take you +;;; right back to Tex errors but at the correct stop in the web file. +;;; +;;; CUSTOMISATION: +;;; +;;; Change language mode for scraps +;;; (setq-default nuweb-source-mode "mode-name-function(without -mode)") +;;; (setq-default nuweb-source-mode "prolog") ;default for all buffers +;;; or (setq nuweb-source-mode "emacs-lisp") ; current one only +;;; +;;; Support for nuweb comments @% (I have patches to nuweb for that) +;;; (setq nuweb-comment-leader "@%") +;;; +;;; +;;; +;;; PROBLEMS: SOLUTION: +;;; +;;; -) Relies on FSF Emacs 19 Upgrade or make the package +;;; back-compatible +;;; -) Functions are not well I should have used nuweb for this +;;; documented +;;; -) Bindings may not suit Change as you like +;;; every one +;;; -) Does not yet support the +;;; standard TeX mode of Emacs + +;;; WISH LIST: +;;; -) Menus active on scrap def/use point providing navigation +;;; functions (I'm thinking of looking at imenu.el for this +;;; (Experimental support for this at the end) Bound to C-M-mouse-1. +;;; -) Better support for standard tex mode (or that GNU adopts AucTeX..) +;;; +;;; CONTRIBUTIONS: +;;; Thorbj{\o}rn Andersen <ravn@imada.ou.dk> suggested the use of C-c C-z +;;; I used it to get into the *source* and as normal exit key. +;;; Also suggested the simple (no prompts) insertion of a scrap +;;; template, and other things. +;;; +;;; AVAILABILITY: +;;; +;;; elisp-archive directory: elisp-archive/modes/nuweb.el.Z +;;; from main site and mirrors +;;; or from by email from me +;;; +(require 'cl) + +(if (locate-library "auctex") + (progn + (require 'tex-site) + (require 'latex)) + (require 'tex-mode) + (setq TeX-command-list nil) + (setq LaTeX-mode-map tex-mode-map) +) + +;;; Extend the list of commands +;;; Web generates both tex and sources +(push + (list "Web" + "sh -c \"nuweb %s && pdflatex '\\nonstopmode\\input{%s}'\"" + 'TeX-run-LaTeX nil + t) + TeX-command-list) +;;; Weave generates Tex output then runs LaTeX +(push + (list "Weave" + "sh -c \"nuweb -o %s && pdflatex '\\nonstopmode\\input{%s}'\"" + 'TeX-run-LaTeX nil + t) + TeX-command-list) +;;; Tangle generates only the source file compile not done. +(push + (list "Tangle" + "sh -c \"nuweb -t %s && echo 'Sources updated'\"" + 'TeX-run-LaTeX nil + t) + TeX-command-list) + +;;; allow .w as extension +(if (boundp 'TeX-file-extensions) + (push "w" TeX-file-extensions) + (setq TeX-file-extensions '("tex" "sty" "w"))) + +(defvar nuweb-mode-map nil) +(defvar nuweb-source-mode "emacs-lisp") + +(defvar nuweb-defs nil + "List of defs found and where") +(defvar nuweb-uses nil + "List of uses found and where") +(defvar nuweb-names nil + "List of canonical names of scraps") +(defvar *def-list* nil) +(defvar *use-list* nil) +(defvar nuweb-def-use-stack nil + "Record locations we have visited so far") + +; only one of those in effect.... +(defvar *nuweb-last-scrap-pos* nil) +(defvar *nuweb-last-scrap-begin* nil) +(defvar *nuweb-last-scrap-end* nil) + +(defun ins-@()(interactive)(insert "@@") ) +(defun ins-@<()(interactive)(insert "@< @>\n")(forward-char -4) ) +(defun ins-@d()(interactive)(insert "@d @{@%\n@|@}\n") (forward-char -11)) +(defun ins-@D()(interactive)(insert "@D @{@%\n@|@}\n")(forward-char -11) ) +(defun ins-@o()(interactive)(insert "@o @{@%\n@|@}\n") (forward-char -11)) +(defun ins-@O()(interactive)(insert "@O @{@%\n@|@}\n") (forward-char -11)) +(defun ins-@|()(interactive)(insert "@|") ) +(defun ins-@{()(interactive)(insert "@{") ) +(defun ins-@}()(interactive)(insert "@}") ) +(defun ins-@m()(interactive)(insert "@m") ) +(defun ins-@u()(interactive)(insert "@u") ) +(defun ins-@f()(interactive)(insert "@f") ) +(defun ins-@%()(interactive)(insert "@%") ) + + +(defun nuweb-mode () + "Major mode to edit nuweb source files. +Adds the following bindings to the normal LaTeX ones. +Commands: +\{nuweb-mode-map}" + (interactive) + (latex-mode) + (setq mode-name "nuweb") + ;; Make sure the nuweb map exist + (cond ((or (not (boundp 'nuweb-mode-map)) + (null nuweb-mode-map)) + ;; this keymap inherit the current local bindings + (setq nuweb-mode-map (cons 'keymap LaTeX-mode-map)) + (define-key nuweb-mode-map + "\C-c\C-z" 'nuweb-edit-this-scrap) + (define-key nuweb-mode-map + "\C-c@" 'nuweb-insert-scrap) + (define-key nuweb-mode-map "@@" 'ins-@) + (define-key nuweb-mode-map "@<" 'ins-@<) + (define-key nuweb-mode-map "@|" 'ins-@|) + (define-key nuweb-mode-map "@}" 'ins-@}) + (define-key nuweb-mode-map "@{" 'ins-@{) + (define-key nuweb-mode-map "@d" 'ins-@d) + (define-key nuweb-mode-map "@D" 'ins-@D) + (define-key nuweb-mode-map "@o" 'ins-@o) + (define-key nuweb-mode-map "@O" 'ins-@O) + (define-key nuweb-mode-map "@%" 'ins-@%) + (define-key nuweb-mode-map "@m" 'ins-@m) + (define-key nuweb-mode-map "@u" 'ins-@u) + (define-key nuweb-mode-map "@f" 'ins-@f) + (define-key nuweb-mode-map "\C-cds" 'nuweb-find-def) + (define-key nuweb-mode-map "\C-cus" 'nuweb-find-use) + (define-key nuweb-mode-map "\C-cdn" 'nuweb-find-next-def) + (define-key nuweb-mode-map "\C-cun" 'nuweb-find-next-use) + (define-key nuweb-mode-map "\C-cdr" 'nuweb-compute-d-u) + (define-key nuweb-mode-map "\C-cdp" 'nuweb-pop-d-u) + (define-key nuweb-mode-map [M-mouse-3] 'nuweb-find-def-or-use))) + ;; make sure we have our own keymap + ;; we use a copy for in buffer so that outline mode is + ;; properly initialized + (use-local-map (copy-keymap nuweb-mode-map)) + (make-local-variable 'nuweb-source-mode) + (make-local-variable 'nuweb-defs) + (make-local-variable 'nuweb-uses) + (make-local-variable 'nuweb-names) + (make-local-variable '*def-list*) + (make-local-variable '*use-list*) + (make-local-variable 'nuweb-def-use-stack) + (make-local-variable '*nuweb-last-scrap-pos*) + (make-local-variable '*nuweb-last-scrap-begin*) + (make-local-variable '*nuweb-last-scrap-end*) + (setq TeX-default-extension "w") + (setq TeX-auto-untabify nil) + (setq TeX-command-default "Web") + (run-hooks 'nuweb-mode-hook)) + +;; set this to "" if you dont have comments in nuweb +;; (I have patches to support @%) +(defvar nuweb-comment-leader "") + +(defvar nuweb-scrap-name-hist nil + "History list for scrap names used") + +(defun nuweb-insert-scrap(arg) + "Insert a scrap at current cursor location. With an argument, +prompts for the type, name and editing mode then directly enter +the *Source* buffer. If no argument given, simply inserts a template +for a scrap" + (interactive "P") + (if arg + (apply 'nuweb-insert-scrap-intern + (list + (concat (read-from-minibuffer "Type of scrap: " "d")" ") + (concat (read-from-minibuffer + "Scrap title:" + (car nuweb-scrap-name-hist) + nil ;no keymap + nil ;dont use read + (cons 'nuweb-scrap-name-hist 0)) + " ") + (read-from-minibuffer "Mode name:" nuweb-source-mode) + ;; edit if interactive + t)) + (save-excursion + (nuweb-insert-scrap-intern "" "\n" nuweb-source-mode nil)) + (forward-char 1))) + +(defun nuweb-insert-scrap-intern(type title modename editp) + (save-excursion + (insert (format "@%s%s@\{%s%s\n@| @\}\n" + type title + nuweb-comment-leader + (if (or (equal modename "") + (equal modename nuweb-source-mode)) + "" + (concat " -*-" modename "-*-"))))) + (cond ( editp + (forward-line 1) + (nuweb-edit-this-scrap)))) + +;;; +;;; !!! The file re does not check for nuweb options that may follow +(defun nuweb-edit-this-scrap() + (interactive) + (barf-if-buffer-read-only) + (cond ((or (null *nuweb-last-scrap-pos*) + (y-or-n-p + "You did not finish editing the previous scrap. Continue")) + (setq *nuweb-last-scrap-pos* (point-marker)) + (let* ((s-begin (and (re-search-backward "@[dDoO]" nil t) + ;; (search-forward "@\{" nil t) + (point))) + (file (if (looking-at "@[oO][ \t]*\\([^ \t]+\\)[ \t]*") + (buffer-substring (match-beginning 1) + (match-end 1)) + nil)) + (b-begin + (and (re-search-forward + (concat "@\{[ \t]*\\(" + nuweb-comment-leader + "\\)?[ \t]*\\(-\\*-[ \t]*\\([^ \t]+\\)[ \t]*-\\*-\\)?") nil t) + (prog2 (if (and (match-beginning 1)(match-end 1)) + (skip-chars-forward "[^\n]")) + (point)))) + (mode-spec (if (and b-begin (match-beginning 3) (match-end 3)) + (buffer-substring (match-beginning 3) + (match-end 3)) + nil)) + (offset (- (marker-position *nuweb-last-scrap-pos*) + b-begin)) + ;; fool nuweb-mode using concat + (b-end (and (re-search-forward "@[|}]" nil t) + (prog1 t (forward-char -2)) + (>= (point) (marker-position *nuweb-last-scrap-pos*)) + (point))) + (text "") + (nuweb-source-mode-orig nuweb-source-mode) + (saved-return-location *nuweb-last-scrap-pos*) + source-mode) + (cond ( (and b-begin b-end) + (setq *nuweb-last-scrap-begin* b-begin) + (setq *nuweb-last-scrap-end* b-end) + (setq text (buffer-substring b-begin b-end)) + (setq buffer-read-only t) + (setq *nuweb-win-config* + (current-window-configuration)) + (pop-to-buffer "*Source*") + (erase-buffer) + (insert text) + (setq source-mode nil) + (if (and (not source-mode) + mode-spec) + (setq source-mode + (intern (concat (downcase mode-spec) "-mode")))) + + (if file + (let* ((case-fold-search nil) + (mode (cdr (find file auto-mode-alist + :key 'car + :test (function + (lambda(a b) + (string-match b a))))))) + (if mode (setq source-mode mode)))) + + (if (not source-mode) + (setq source-mode + (if (stringp nuweb-source-mode-orig) + (intern (concat + (downcase nuweb-source-mode-orig) + "-mode")) + source-mode))) + + (funcall source-mode) + + ;; go to same relative position + (goto-char (+ (point-min) (max offset 0))) + ;; clean up when killing the *source* buffer + (make-local-variable 'kill-buffer-hook) + + (make-local-variable 'nuweb-minor-mode) + (make-local-variable 'nuweb-return-location) + (setq nuweb-return-location saved-return-location) + (add-hook 'kill-buffer-hook + (function (lambda() + (save-excursion + (nuweb-kill-this-scrap))))) + (nuweb-minor-mode 1) + (message "C-c C-z to use source, C-c M-k to abort")) + (t (goto-char (marker-position *nuweb-last-scrap-pos*)) + (setq *nuweb-last-scrap-pos* nil) + (error "Could not identify scrap"))) + ) + ) + (t (message "Use C-x b and select buffer *Source* to finish")))) + +(defvar nuweb-minor-mode-map nil) +(cond ((or (not (boundp 'nuweb-minor-mode-map)) + (null nuweb-minor-mode-map)) + (setq nuweb-minor-mode-map (make-sparse-keymap)) + (define-key nuweb-minor-mode-map "\C-c\C-z" 'nuweb-install-this-scrap) + (define-key nuweb-minor-mode-map "\C-c\M-k" 'nuweb-kill-this-scrap) + )) + +(defvar nuweb-minor-mode nil) + +(make-variable-buffer-local 'nuweb-minor-mode) + +(or (assq 'nuweb-minor-mode minor-mode-alist) + (setq minor-mode-alist (cons '(nuweb-minor-mode " Nuweb") + minor-mode-alist))) +(or (assq 'nuweb-minor-mode minor-mode-map-alist) + (setq minor-mode-map-alist (cons (cons 'nuweb-minor-mode + nuweb-minor-mode-map) + minor-mode-map-alist))) + +;;; The function is there but has nothing to do (thanks to Emacs 19 +;;; function for minor mode bindings +;;; It is here if anyone cares to make it Emacs 18 compatible. +(defun nuweb-minor-mode (arg) + "This minor mode provides two additional bindings to the current +language mode. The bindings allow to install the contents of the +*Source* buffer as current scrap body or to kill the buffer and +re-install the old scrap body. + +The bindings installed by this minor mode are +\\{nuweb-minor-mode-map}" + (interactive "P") + (setq nuweb-minor-mode + (if (null arg) (not nuweb-minor-mode) + (> (prefix-numeric-value arg) 0))) + (cond (nuweb-minor-mode + ;; turn it on + ;; Nothin to do yet... + t + ) + (t + ;; turn it off + ;; Nothin to do yet... + nil + ))) + +(defun nuweb-install-this-scrap() + (interactive) + (let ((offset (point))) + (setq kill-buffer-hook nil) + ;; use *Source* local variable to return to correct buffer + (switch-to-buffer (marker-buffer nuweb-return-location)) + (setq buffer-read-only nil) ;it was writable + (set-window-configuration *nuweb-win-config*) + ;; now we can use the last-scrap-pos variable + (goto-char (marker-position *nuweb-last-scrap-pos* )) + (set-marker *nuweb-last-scrap-pos* nil) + (recenter) + (goto-char *nuweb-last-scrap-begin*) + (delete-region *nuweb-last-scrap-begin* *nuweb-last-scrap-end*) + (insert-buffer "*Source*") + (forward-char (- offset 1)) + (setq *nuweb-last-scrap-pos* nil))) + +(defun nuweb-kill-this-scrap() + (interactive) + (nuweb-back-to-pos) + (setq *nuweb-last-scrap-pos* nil)) + +(defun nuweb-back-to-pos() + (setq kill-buffer-hook nil) + (switch-to-buffer (marker-buffer nuweb-return-location)) + (setq buffer-read-only nil) + (delete-other-windows) + (goto-char (marker-position *nuweb-last-scrap-pos*)) + (recenter)) + + +;;; Below is code to support movements based on scrap uses and +;;; definitions. +;;; +;; structure to hold the scrap def descriptors +;; The name field +;; contains the name as found in buffer, then will hold the cononical +;; name (after second pass). While text will contain the whole text +;; matched when the def or use is found. + +(defstruct scrap-def name text type loc) +;; structure to hold the scrap def descriptors (see above) + +(defstruct scrap-use name text loc) + +(defvar nuweb-scrap-def-re "@\\([oOdD]\\)[ \t]*\\(.*[^ \t\n]\\)[ \t]*\n?@{" + "Way to match a scrap definition") + +(defun nuweb-make-scrap-def-list() + "Collect a list of all the scrap definitions" + (save-excursion + (goto-char (point-min)) + (loop + while (re-search-forward nuweb-scrap-def-re nil t) + collect (make-scrap-def :name (buffer-substring (match-beginning 2) + (match-end 2)) + :type (buffer-substring (match-beginning 1) + (match-end 1)) + :text (buffer-substring (match-beginning 0) + (match-end 0)) + :loc (match-beginning 0))))) + +(defvar nuweb-scrap-use-re "@<[ \t]*\\(.*[^ \t\n]\\)[ \t]*@>" + "How to recognize a usage") + +(defun nuweb-make-scrap-use-list() + "Collect list of scrap usages" + (save-excursion + (goto-char (point-min)) + (loop + while (re-search-forward nuweb-scrap-use-re nil t) + collect (make-scrap-use :name (buffer-substring (match-beginning 1) + (match-end 1)) + :text (buffer-substring (match-beginning 0) + (match-end 0)) + :loc (match-beginning 0))))) + + +(defun nuweb-merge-names ( defs uses) + "Builds a list of full names use as scrap names" + (remove-duplicates + (sort* + (append + (loop for x in defs + when (not (string-match ".*\\.\\.\\." (scrap-def-name x))) + collect (scrap-def-name x)) + (loop for x in uses + when (not (string-match ".*\\.\\.\\." (scrap-use-name x))) + collect (scrap-use-name x))) + 'string-lessp) + :test 'equal)) + + + +(defun nuweb-canonic-name(name) + "Returns the full name corresponding to the one given" + (if (string-match "\\(.*\\)\\.\\.\\." name) + (let ((prefix (substring name 0 -3))) + ;; then finds it in name list + (find (regexp-quote prefix) nuweb-names :test 'string-match)) + name)) + +(defun nuweb-compute-d-u() + "Recompute all the defs and uses point in the current file" + (interactive) + (message "Looking for defs") + ; gets defs, + (setq nuweb-defs (nuweb-make-scrap-def-list)) + (message "Looking for uses") + ; gets uses + (setq nuweb-uses (nuweb-make-scrap-use-list)) + ;; compute list of names + (message "Fixing names") + (setq nuweb-names (nuweb-merge-names nuweb-defs nuweb-uses)) + ;; Now change all name fields back to their canonical names + ;; in both lists + (loop for def in nuweb-defs + when (string-match "\\(.*\\)\\.\\.\\." (scrap-def-name def)) + do (setf (scrap-def-name def) + (nuweb-canonic-name (scrap-def-name def)))) + (loop for use in nuweb-uses + when (string-match "\\(.*\\)\\.\\.\\." (scrap-use-name use)) + do (setf (scrap-use-name use) + (nuweb-canonic-name (scrap-use-name use)))) + (setq nuweb-def-use-stack nil) + (message "Done.")) + +(defun nuweb-scrap-name-at-point() + "Gathers the scrap name under the cursor. Returns a pair whose car +is the scrap name found and whose cdr is either 'def or 'use" + (interactive) + (save-excursion + ;; God this code is not the nicest I've written... + ;; Comprenne qui pourras + (let* ((here (point)) + (beg (if (re-search-backward "@[oOdD<]" nil t) + (match-end 0) + nil)) + (to-match (if beg + (if (equal (char-after (+ (match-beginning 0) 1)) + ?<) + "@>" + "@{") + nil)) + (context (if (equal to-match "@{") 'def 'use)) + (end (if (search-forward to-match nil t) + (match-beginning 0) + nil))) + (cond ((and beg end + (<= beg here) + (>= end here)) + (cons (buffer-substring + (progn + (goto-char beg) + (skip-chars-forward " \t\n") + (point)) + (progn + (goto-char end) + (skip-chars-backward" \t\n") + (point))) + context)) + (t (error "Not on a possible scrap name")))))) + +(defun nuweb-find-next-use() + (interactive) + (nuweb-find-use t)) + +(defun nuweb-find-use(arg) + "Find use of scrap name at point. With argument, find next use" + (interactive "P") + (if (not arg) + (nuweb-find-use-internal + (nuweb-canonic-name (car(nuweb-scrap-name-at-point))) + t) + (nuweb-find-use-internal *nuweb-prev-use* nil))) + +(defun nuweb-find-use-internal (name first) + (if first + (setq *use-list* + (remove* name nuweb-uses :test-not 'equal :key 'scrap-use-name) + ;; list of use points for scrap name at point + *nuweb-prev-use* name)) + (if (not *use-list*) + (error "Nor more uses for of <%s>" name) + (push (point) nuweb-def-use-stack) + (nuweb-position-search (scrap-use-loc (car *use-list*)) + (scrap-use-text (pop *use-list*))))) + + +(defun nuweb-find-next-def() + (interactive) + (nuweb-find-def t)) + +(defun nuweb-find-def(arg) + "Find def of scrap name at point. With argument, find next def" + (interactive "P") + (if (not arg) + (nuweb-find-def-internal + (nuweb-canonic-name (car (nuweb-scrap-name-at-point))) + t) + (nuweb-find-def-internal *nuweb-prev-def* nil))) + +(defun nuweb-find-def-internal (name first) + (if first + (setq *def-list* + (remove* name nuweb-defs :test-not 'equal :key 'scrap-def-name) + ;; list of def points for scrap name at point + *nuweb-prev-def* name)) + (if (not *def-list*) + (error "Nor more defs for <%s>" name) + (push (point) nuweb-def-use-stack) + (nuweb-position-search (scrap-def-loc (car *def-list*)) + (scrap-def-text (pop *def-list*))))) + + +(defun nuweb-position-search( loc expected-text) + (goto-char loc) + + (let ((offset 250) + (found (looking-at expected-text)) + up down) + (while (and (not found) + (not (equal up (point-min))) + (not (equal down (point-max)))) + (setq up (max (- loc offset) (point-min))) + (setq down (min (+ loc offset) (point-max))) + (setq offset (* 2 offset)) + (goto-char up) + (setq found (search-forward expected-text down t))) + (if (not found) + (error "Time to resynchronize defs and uses") + (goto-char (+ 2 (match-beginning 0))) + (recenter)))) + + +(defun nuweb-find-def-or-use(arg) + (interactive "e") + (mouse-set-point arg) + (let ((scrap (nuweb-scrap-name-at-point))) + (message "Looking for: %S" scrap) + (cond ((eq (cdr scrap) 'def) + (nuweb-find-use-internal (nuweb-canonic-name (car scrap)) t)) + ((eq (cdr scrap) 'use) + (nuweb-find-def-internal (nuweb-canonic-name (car scrap)) t)) + (t (error "nuweb mode: should never get here"))))) + + +(defun nuweb-pop-d-u() + (interactive) + (goto-char (pop nuweb-def-use-stack))) + +;;; +;;; Some support for use of imenu. Experimental. +;;; Provides a menu of scrap definitions (one for files, one for +;;; macros). + + +(eval-when (compile ) + (require 'imenu)) + +(defvar imenu-wanted t + "Specifies whether imenu functions are useable in nuweb mode") + +(if imenu-wanted + (progn + (require 'imenu) + (add-hook 'nuweb-mode-hook 'nuweb-imenu-setup))) + +(defun nuweb-imenu-setup () + (make-local-variable 'imenu-create-index-function) + (setq imenu-create-index-function 'nuweb-create-imenu-index) + (local-set-key [C-M-S-mouse-1] 'imenu) + (imenu-add-menubar-index)) + +(defvar imenu-nuweb-scrap-regexp + "\\(@|[ \t]*\\([^@]*\\)@}\\)\\|\\(@[dDoO][ \t]*\\(.*[^ \t\n]\\)[ \t\n]*@{\\)" + "How do we match a scrap def point or a index defining entry") + +(defun imenu-nuweb-name-and-position-scrap() + (if (and (match-beginning 4) (match-end 4)) + (cons (buffer-substring (match-beginning 4) (match-end 4)) + (match-beginning 0)) + nil)) + +;;; The symbol information is not used as is... +(defun imenu-nuweb-name-and-position-symbol() + (if (and (match-beginning 2) (match-end 2)) + (cons (buffer-substring (match-beginning 2) (match-end 2)) + (match-beginning 0)) + nil)) +(defmacro imenu-create-submenu-name(name) name) +(defun nuweb-create-imenu-index(&optional regexp) + (let ((index-macros-alist '()) + (index-files-alist '()) + (index-symbols-alist '()) + (char)) + (goto-char (point-min)) +;; (imenu-progress-message 0) + ;; Search for the function + (save-match-data + (while (re-search-forward + (or regexp imenu-nuweb-scrap-regexp) + nil t) +;; (imenu-progress-message) + (let ((scrap-name-pos (imenu-nuweb-name-and-position-scrap)) + (symbol-name-pos (imenu-nuweb-name-and-position-symbol))) + (save-excursion + (goto-char (match-beginning 0)) + (cond ((looking-at "@[oO]") + (push scrap-name-pos index-files-alist)) + ( (looking-at "@|") + (if (looking-at "@|[ \t]*@}") + t ; do nothing + (forward-char 2) + (let ((pos (point)) + (ref-pos (cdr symbol-name-pos))) + (while (not (looking-at "[\t\n ]*@}")) + (if (re-search-forward "[\t\n ]*\\([^@ \t\n]+\\)" + nil t) + (push (cons (buffer-substring + (match-beginning 1) + (match-end 1)) + ref-pos) + index-symbols-alist)))))) + (t (push scrap-name-pos index-macros-alist))))))) +;; (imenu-progress-message 100) + (list + ;; the list of symbols is sorted as it is easier to search in an + ;; alpha sorted list + (cons (imenu-create-submenu-name "Symbols") + (sort (nreverse index-symbols-alist) + (function(lambda(pair1 pair2) + (string< (car pair1) (car pair2)))))) + ;; the scrap and file def point are left in their order of + ;; appearance in the file. + (cons (imenu-create-submenu-name "Macros") + (nreverse index-macros-alist)) + (cons (imenu-create-submenu-name "Files") + (nreverse index-files-alist))))) + +(provide 'nuweb) +;;; nuweb.el ends here diff --git a/nuweb.w b/nuweb.w new file mode 100644 index 0000000..db1841e --- /dev/null +++ b/nuweb.w @@ -0,0 +1,6868 @@ +% +% Copyright (c) 1996, Preston Briggs +% All rights reserved. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions +% are met: +% +% Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% Neither name of the product nor the names of its contributors may +% be used to endorse or promote products derived from this software without +% specific prior written permission. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +% ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +% LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +% FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS +% OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +% PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +% OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +% + +% Notes: +% Update on 2011-12-16 from Keith Harwood. +% -- @@s in scrap supresses indent of following fragment expansion +% -- @@<Name@@> in text is expanded +% Update on 2011-04-20 from Keith Harwood. +% -- @@t provide fragment title in output +% Changes from 2010-03-11 in the Sourceforge revision history. -- sjw +% Updates on 2004-02-23 from Gregor Goldbach +% <glauschwuffel@@users.sourceforge.net> +% -- new command line option -r which will make nuweb typeset each +% NWtarget and NWlink instance with \LaTeX-commands from the hyperref +% package. This gives clickable scrap numbers which is very useful +% when viewing the document on-line. + +% Updates on 2004-02-13 from Gregor Goldbach +% <glauschwuffel@@users.sourceforge.net> +% -- new command line option -l which will make nuweb typeset scraps +% with the help of LaTeX's listings packages instead or pure +% verbatim. +% -- man page corrections and additions. + +% Updates on 2003-04-24 from Keith Harwood <Keith.Harwood@@vitalmis.com> +% -- sectioning commands (@@s and global-plus-sign in scrap names) +% -- @@x..@@x labelling +% -- @@f current file +% -- @@\# suppress indent + +% This file has been changed by Javier Goizueta <jgoizueta@@jazzfree.es> +% on 2001-02-15. +% These are the changes: +% LANG -- Introduction of \NW macros to substitue language dependent text +% DIAM -- Introduction of \NWsep instead of the \diamond separator +% HYPER -- Introduction of hyper-references +% NAME -- LaTeX formatting of macro names in HTML output +% ADJ -- Adjust of the spacing between < and a fragment name +% TEMPN -- Fix of the use of tempnam +% LINE -- Synchronizing #lines when @@% is used +% MAC -- definition of the macros used by LANG,DIAM,HYPER +% CHAR -- Introduce @@r to change the nuweb meta character (@@) +% TIE -- Replacement of ~ by "\nobreak\ " +% SCRAPs-- Elimination of s +% DNGL -- Correction: option -d was not working and was misdocumented +% --after the CHAR modifications, to be able to specify non-ascii characters +% for the scape character, the program must be compiled with the -K +% option in Borland compilers or the -funsigned-char in GNU's gcc +% to treat char as an unsigned value when converted to int. +% To make the program independent of those options, either char +% should be changed to unsigned char (bad solution, since unsigned +% char should be used for numerical purposes) or attention should +% be payed to all char-int conversions. (including comparisons) + +% --2002-01-15: the TILDE modificiation is necessary because some ties +% have been introduced in version 0.93 in troublesome places when +% the babel package is used with the spanish.ldf option (which makes +% ~ an active character). + +% --2002-01-15: an ``s'' was being added to the NWtxtDefBy and +% NWtxtDefBy messages when followed by more than one reference. + +\documentclass[a4paper]{report} +\newif\ifshowcode +\showcodetrue + +\usepackage{latexsym} +%\usepackage{html} + +\usepackage{listings} + +\usepackage{color} +\definecolor{linkcolor}{rgb}{0, 0, 0.7} + +\usepackage[% +backref,% +raiselinks,% +pdfhighlight=/O,% +pagebackref,% +hyperfigures,% +breaklinks,% +colorlinks,% +pdfpagemode=None,% +pdfstartview=FitBH,% +linkcolor={linkcolor},% +anchorcolor={linkcolor},% +citecolor={linkcolor},% +filecolor={linkcolor},% +menucolor={linkcolor},% +pagecolor={linkcolor},% +urlcolor={linkcolor}% +]{hyperref} + +\setlength{\oddsidemargin}{0in} +\setlength{\evensidemargin}{0in} +\setlength{\topmargin}{0in} +\addtolength{\topmargin}{-\headheight} +\addtolength{\topmargin}{-\headsep} +\setlength{\textheight}{8.9in} +\setlength{\textwidth}{6.5in} +\setlength{\marginparwidth}{0.5in} + +\title{Nuweb Version 1.62 \\ A Simple Literate Programming Tool} +\date{} +\author{Preston Briggs\thanks{This work has been supported by ARPA, +through ONR grant N00014-91-J-1989.} +\\ {\sl preston@@tera.com} +\\ HTML scrap generator by John D. Ramsdell +\\ {\sl ramsdell@@mitre.org} +\\ Scrap formatting by Marc W. Mengel +\\ {\sl mengel@@fnal.gov} +\\ Continuing maintenance by Simon Wright +\\ {\sl simon@@pushface.org} +\\ and Keith Harwood +\\ {\sl Keith.Harwood@@vitalmis.com}} + +\begin{document} +\pagenumbering{roman} +\maketitle +\tableofcontents + +\chapter{Introduction} +\pagenumbering{arabic} + +In 1984, Knuth introduced the idea of {\em literate programming\/} and +described a pair of tools to support the practise~\cite{Knuth:CJ-27-2-97}. +His approach was to combine Pascal code with \TeX\ documentation to +produce a new language, \verb|WEB|, that offered programmers a superior +approach to programming. He wrote several programs in \verb|WEB|, +including \verb|weave| and \verb|tangle|, the programs used to support +literate programming. +The idea was that a programmer wrote one document, the web file, that +combined documentation (written in \TeX~\cite{Knuth:ct-a}) with code +(written in Pascal). + +Running \verb|tangle| on the web file would produce a complete +Pascal program, ready for compilation by an ordinary Pascal compiler. +The primary function of \verb|tangle| is to allow the programmer to +present elements of the program in any desired order, regardless of +the restrictions imposed by the programming language. Thus, the +programmer is free to present his program in a top-down fashion, +bottom-up fashion, or whatever seems best in terms of promoting +understanding and maintenance. + +Running \verb|weave| on the web file would produce a \TeX\ file, ready +to be processed by \TeX\@@. The resulting document included a variety of +automatically generated indices and cross-references that made it much +easier to navigate the code. Additionally, all of the code sections +were automatically prettyprinted, resulting in a quite impressive +document. + +Knuth also wrote the programs for \TeX\ and {\small\sf METAFONT} +entirely in \verb|WEB|, eventually publishing them in book +form~\cite{Knuth:ct-b,Knuth:ct-d}. These are probably the +largest programs ever published in a readable form. + +Inspired by Knuth's example, many people have experimented with +\verb|WEB|\@@. Some people have even built web-like tools for their +own favorite combinations of programming language and typesetting +language. For example, \verb|CWEB|, Knuth's current system of choice, +works with a combination of C (or C++) and \TeX~\cite{Levy:TB8-1-12}. +Another system, FunnelWeb, is independent of any programming language +and only mildly dependent on \TeX~\cite{Williams:FUM92}. Inspired by the +versatility of FunnelWeb and by the daunting size of its +documentation, I decided to write my own, very simple, tool for +literate programming.% +\footnote{There is another system similar to +mine, written by Norman Ramsey, called {\em noweb}~\cite{Ramsey:LPT92}. It +perhaps suffers from being overly Unix-dependent and requiring several +programs to use. On the other hand, its command syntax is very nice. +In any case, nuweb certainly owes its name and a number of features to +his inspiration.} + + +\section{Nuweb} + +Nuweb works with any programming language and \LaTeX~\cite{Lamport:LDP85}. I +wanted to use \LaTeX\ because it supports a multi-level sectioning +scheme and has facilities for drawing figures. I wanted to be able to +work with arbitrary programming languages because my friends and I +write programs in many languages (and sometimes combinations of +several languages), {\em e.g.,} C, Fortran, C++, yacc, lex, Scheme, +assembly, Postscript, and so forth. The need to support arbitrary +programming languages has many consequences: +\begin{description} +\item[No prettyprinting] Both \verb|WEB| and \verb|CWEB| are able to + prettyprint the code sections of their documents because they + understand the language well enough to parse it. Since we want to use + {\em any\/} language, we've got to abandon this feature. + However, we do allow particular individual formulas or fragments + of \LaTeX\ code to be formatted and still be parts of output files. + Also, keywords in scraps can be surrounded by \verb|@@_| to + have them be bold in the output. +\item[No index of identifiers] Because \verb|WEB| knows about Pascal, + it is able to construct an index of all the identifiers occurring in + the code sections (filtering out keywords and the standard type + identifiers). Unfortunately, this isn't as easy in our case. We don't + know what an identifier looks like in each language and we certainly + don't know all the keywords. (On the other hand, see the end of + Section~\ref{minorcommands}) +\end{description} +Of course, we've got to have some compensation for our losses or the +whole idea would be a waste. Here are the advantages I can see: +\begin{description} +\item[Simplicity] The majority of the commands in \verb|WEB| are + concerned with control of the automatic prettyprinting. Since we + don't prettyprint, many commands are eliminated. A further set of + commands is subsumed by \LaTeX\ and may also be eliminated. As a + result, our set of commands is reduced to only four members (explained + in the next section). This simplicity is also reflected in + the size of this tool, which is quite a bit smaller than the tools + used with other approaches. +\item[No prettyprinting] Everyone disagrees about how their code + should look, so automatic formatting annoys many people. One approach + is to provide ways to control the formatting. Our approach is + simpler---we perform no automatic formatting and therefore allow the + programmer complete control of code layout. + We do allow individual scraps to be presented in either verbatim, + math, or paragraph mode in the \TeX\ output. +\item[Control] We also offer the programmer complete control of the + layout of his output files (the files generated during tangling). Of + course, this is essential for languages that are sensitive to layout; + but it is also important in many practical situations, {\em e.g.,} + debugging. +\item[Speed] Since nuweb doesn't do too much, the nuweb tool runs + quickly. I combine the functions of \verb|tangle| and \verb|weave| into + a single program that performs both functions at once. +\item[Page numbers] Inspired by the example of noweb, nuweb refers to + all scraps by page number to simplify navigation. If there are + multiple scraps on a page (say, page~17), they are distinguished by + lower-case letters ({\em e.g.,} 17a, 17b, and so forth). +\item[Multiple file output] The programmer may specify more than one + output file in a single nuweb file. This is required when constructing + programs in a combination of languages (say, Fortran and C)\@@. It's also + an advantage when constructing very large programs that would require + a lot of compile time. +\end{description} +This last point is very important. By allowing the creation of +multiple output files, we avoid the need for monolithic programs. +Thus we support the creation of very large programs by groups of +people. + +A further reduction in compilation time is achieved by first +writing each output file to a temporary location, then comparing the +temporary file with the old version of the file. If there is no +difference, the temporary file can be deleted. If the files differ, +the old version is deleted and the temporary file renamed. This +approach works well in combination with \verb|make| (or similar tools), +since \verb|make| will avoid recompiling untouched output files. + +\subsection{Nuweb and HTML} + +In addition to producing {\LaTeX} source, nuweb can be used to +generate HyperText Markup Language (HTML), the markup language used by +the World Wide Web. HTML provides hypertext links. When an HTML +document is viewed online, a user can navigate within the document by +activating the links. The tools which generate HTML automatically +produce hypertext links from a nuweb source. + +(Note that hyperlinks can be included in \LaTeX\ using the +\verb|hyperref| package. This is now the preferred way of doing +this and the HTML processing is not up to date.) + +\section{Writing Nuweb} + +The bulk of a nuweb file will be ordinary \LaTeX\@@. In fact, any +{\LaTeX} file can serve as input to nuweb and will be simply copied +through, unchanged, to the documentation file---unless a nuweb command +is discovered. All nuweb commands begin with an ``at-sign'' +(\verb|@@|). Therefore, a file without at-signs will be copied +unchanged. Nuweb commands are used to specify {\em output files,} +define {\em fragments,} and delimit {\em scraps}. These are the basic +features of interest to the nuweb tool---all else is simply text to be +copied to the documentation file. + +\subsection{The Major Commands} + +Files and fragments are defined with the following commands: +\begin{description} +\item[{\tt @@o} {\em file-name flags scrap\/}] Output a file. The file + name is terminated by whitespace. +\item[{\tt @@d} {\em fragment-name scrap\/}] Define a fragment. The + fragment name is terminated by a return or the beginning of a scrap. +\item[{\tt @@q} {\em fragment-name scrap\/}] Define a fragment. The + fragment name is terminated by a return or the beginning of a scrap. + This a quoted fragment. +\end{description} +A specific file may be specified several times, with each definition +being written out, one after the other, in the order they appear. +The definitions of fragments may be similarly specified piecemeal. + +A fragment name may have embedded parameters. The parameters are +denoted by the sequence \texttt{@@'value@@'} where \texttt{value} is +an uninterpreted string of characters (although the sequence +\texttt{@@@@} denotes a single \texttt{@@} character). When a fragment +name is used inside a scrap the parameters may be replaced by an +argument which may be a different literal string, a fragment use, an +embedded fragment or by a parameter use. + +The difference between a quoted fragment (\texttt{@@q}) and an +ordinary one (\texttt{@@d}) is that inside a quoted fragment fragments +are not expanded on output. Rather, they are formatted as uses of +fragments so that the output file can itself be \texttt{nuweb} +source. This allows you to create files containing fragments which can +undergo further processing before the fragments are expanded, while +also describing and documenting them in one place. + +You can have both quoted and unquoted fragments with the same +name. They are written out in order as usual, with those introduced by +\texttt{@@q} being quoted and those with \texttt{@@d} expanded as +normal. + +In quoted fragments, the \texttt{@@f} filename is quoted as well, so that +when it is expanded it refers to the finally produced file, not +any of the intermediate ones. + +\subsubsection{Scraps} + +Scraps have specific begin markers and end markers to allow precise +control over the contents and layout. Note that any amount of +whitespace (including carriage returns) may appear between a name and +the beginning of a scrap. Scraps may also appear in the running text +where they are formatted (almost) identically to their use in definitions, +but don't appear in any code output. +\begin{description} +\item[\tt @@\{{\em anything\/}@@\}] where the scrap body includes every + character in {\em anything\/}---all the blanks, all the tabs, all the + carriage returns. This scrap will be typeset in verbatim mode. Using + the \texttt{-l} option will cause the program to typeset the scrap with + the help of \LaTeX's \texttt{listings} package. +\item[\tt @@[{\em anything\/}@@]] where the scrap body includes every + character in {\em anything\/}---all the blanks, all the tabs, all the + carriage returns. This scrap will be typeset in paragraph mode, allowing + sections of \TeX\ documents to be scraps, but still be prettyprinted + in the document. +\item[\tt @@({\em anything\/}@@)] where the scrap body includes every + character in {\em anything\/}---all the blanks, all the tabs, all the + carriage returns. This scrap will be typeset in math mode. This allows + this scrap to contain a formula which will be typeset nicely. +\end{description} +Inside a scrap, we may invoke a fragment. +\begin{description} +\item[\tt @@<{\em fragment-name\/}@@>] + This is a fragment use. It causes the fragment + {\em fragment-name\/} to be expanded inline as the code is written out + to a file. It is an error to specify recursive fragment invocations. +\item[\tt @@<{\em fragment-name\/}@@( {\em a1} @@, {\em a2} @@) @@>] This + is the old form of parameterising a fragment. It causes the fragment + {\em fragment-name\/} to be expanded inline with the arguments {\em a1}, + {\em a2}, etc. Up to 9 arguments may be given. +\item[\tt @@1, @@2, ..., @@9] In a fragment causes the n'th fragment + argument to be substituted into the scrap. If the argument + is not passed, a null string is substituted. + Arguments can be passed in two ways, either embedded in the + fragment + name or as the old form given above. + + An embedded argument may specified in four ways. + \begin{description} + \item[\tt @@'string@@'] + The string will be copied literally into the called fragment. + It will not be interpreted (except for \texttt{@@@@} converted + to \texttt{@@}). + \item[\tt @@<{\em fragment-name\/}@@>] + The fragment will be expanded in the usual fashion and the results + passed to the called fragment. + \item[\tt @@\{text@@\}] + The text will be expanded as normal and the results passed to + the called fragment. This behaves like an anonymous fragment which has + the same arguments as the calling fragment. Its principle use is + to combine text and arguments into one argument. + \item[\tt @@1, @@2, ..., @@9] + The argument of the calling fragment will be passed to the called + fragment and expanded in there. + \end{description} + + If an argument is used but there is no corresponding parameter + in the fragment name, the null string is substituted. But what + happens if there is a parameter in the full name of a fragment, + but a particular application of the fragment is abbreviated + (using the \verb|. . .| notation) and the argument is missed? In + that case the argument is replaced by the string given in the + definition of the fragment. + + In the old form the parameter may contain any text and will be + expanded as a normal scrap. The two forms of parameter passing + don't play nicely together. If a scrap passes both embedded and + old form arguments the old form arguments are ignored. +\item[\tt @@x{\em label}@@x] Marks a place inside a scrap and +associates it to the label (which can be any text not containing +a @@). Expands to the reference number of the scrap followed by a +numeric value. Outside scraps it expands to the same value. It is +used so that text outside scraps can refer to particular places +within scraps. +\item[\tt @@f] Inside a scrap this is replaced by the name of the +current output file. +\item[\tt @@t] Inside a scrap this is replaced by the title of the +fragment as it is at the point it is used, with all parameters +replaced by actual arguments. +\item[\tt @@\#] At the beginning of a line in a scrap this will +suppress the normal indentation for that line. Use this, for +example, when you have a \verb|#ifdef| inside a nested scrap. +Writing \verb|@@##ifdef| will cause it to be lined up on the left +rather than indented with the rest of its code. +\item[\tt @@s] Inside a scrap supresses indentation for the following +fragment expansion. +\end{description} +Note that fragment names may be abbreviated, either during invocation or +definition. For example, it would be very tedious to have to +type, repeatedly, the fragment name +\begin{quote} +\verb|@@d Check for terminating at-sequence and return name if found| +\end{quote} +Therefore, we provide a mechanism (stolen from Knuth) of indicating +abbreviated names. +\begin{quote} +\verb|@@d Check for terminating...| +\end{quote} +Basically, the programmer need only type enough characters to +identify the fragment name uniquely, followed by three periods. An abbreviation +may even occur before the full version; nuweb simply preserves the +longest version of a fragment name. Note also that blanks and tabs are +insignificant within a fragment name; each string of them is replaced by a +single blank. + +Sometimes, for instance during program testing, it is convenient to comment +out a few lines of code. In C or Fortran placing \verb|/* ... */| around the relevant +code is not a robust solution, as the code itself may contain +comments. Nuweb provides the command +\begin{quote} +\verb|@@%| +\end{quote}only to be used inside scraps. It behaves exactly the same +as \verb|%| in the normal {\LaTeX} text body. + +When scraps are written to a program file or a documentation file, tabs are +expanded into spaces by default. Currently, I assume tab stops are set +every eight characters. Furthermore, when a fragment is expanded in a scrap, +the body of the fragment is indented to match the indentation of the +fragment invocation. Therefore, care must be taken with languages +({\em e.g.,} Fortran) that are sensitive to indentation. +These default behaviors may be changed for each output file (see +below). + +\subsubsection{Flags} + +When defining an output file, the programmer has the option of using +flags to control output of a particular file. The flags are intended +to make life a little easier for programmers using certain languages. +They introduce little language dependences; however, they do so only +for a particular file. Thus it is still easy to mix languages within a +single document. There are four ``per-file'' flags: +\begin{description} +\item[\tt -d] Forces the creation of \verb|#line| directives in the + output file. These are useful with C (and sometimes C++ and Fortran) on + many Unix systems since they cause the compiler's error messages to + refer to the web file rather than to the output file. Similarly, they + allow source debugging in terms of the web file. +\item[\tt -i] Suppresses the indentation of fragments. That is, when a + fragment is expanded within a scrap, it will {\em not\/} be indented to + match the indentation of the fragment invocation. This flag would seem + most useful for Fortran programmers. +\item[\tt -t] Suppresses expansion of tabs in the output file. This + feature seems important when generating \verb|make| files. +\item[\tt -c{\it x}] Puts comments in generated code documenting the +fragment that generated that code. The {\it x} selects the comment style +for the language in use. So far the only valid values are \verb|c| to get +\verb|C| comment style, \verb|+| for \verb|C++| and \verb|p| for +\verb|Perl|. (\verb|Perl| commenting can be used for several languages +including \verb|sh| and, mostly, \verb|tcl|.) +If the global \verb|-x| cross-reference flag is +set the comment includes the page reference for the first scrap that +generated the code. +\end{description} + + +\subsection{The Minor Commands\label{minorcommands}} + +We have some very low-level utility commands that may appear anywhere +in the web file. +\begin{description} +\item[\tt @@@@] Causes a single ``at sign'' to be copied into the output. +\item[\tt @@\_] Causes the text between it and the next {\tt @@\_} + to be made bold (for keywords, etc.) +\item[\tt @@i {\em file-name\/}] Includes a file. Includes may be + nested, though there is currently a limit of 10~levels. The file name + should be complete (no extension will be appended) and should be + terminated by a carriage return. Normally the current directory is + searched for the file to be included, but this can be varied using + the \verb|-I| flag on the command line. Each such flag adds one + directory tothe search path and they are searched in the order + given. +\item[{\tt @@r}$x$] Changes the escape character `@@' to `$x$'. + This must appear before any scrap definitions. +\item[\tt @@v] Always replaced by the string established by +the \texttt{-V} flag, or a default string if the flag isn't +given. This is intended to mark versions of the generated +files. +\end{description} + +In the text of the document, that is outside scraps, you may include +scrap-like material. + +\begin{description} +\item[\tt @@\{\textit{Anything}@@\}] +The included material, the \textit{Anything}, +is typeset as if it appeared inside a scrap. This is useful for +referring to fragments in the text and for +describing the literate programming process itself. +\item[\tt @@<\textit{Fragment name}@@>] +The fragment named is expanded in place in the text. +The expansion is presented verbatim, it is not interpretted for +typesetting, so any special environment must be set up before and +after this is used. +\end{description} + +Finally, there are three commands used to create indices to the +fragment +names, file definitions, and user-specified identifiers. +\begin{description} +\item[\tt @@f] Create an index of file names. +\item[\tt @@m] Create an index of fragment names. +\item[\tt @@u] Create an index of user-specified identifiers. +\end{description} +I usually put these in their own section +in the \LaTeX\ document; for example, see Chapter~\ref{indices}. + +Identifiers must be explicitly specified for inclusion in the +\verb|@@u| index. By convention, each identifier is marked at the +point of its definition; all references to each identifier (inside +scraps) will be discovered automatically. To ``mark'' an identifier +for inclusion in the index, we must mention it at the end of a scrap. +For example, +\begin{quote} +\begin{verbatim} +@@d a scrap @@{ +Let's pretend we're declaring the variables FOO and BAR +inside this scrap. +@@| FOO BAR @@} +\end{verbatim} +\end{quote} +I've used alphabetic identifiers in this example, but any string of +characters (not including whitespace or \verb|@@| characters) will do. +Therefore, it's possible to add index entries for things like +\verb|<<=| if desired. An identifier may be declared in more than one +scrap. + +In the generated index, each identifier appears with a list of all the +scraps using and defining it, where the defining scraps are +distinguished by underlining. Note that the identifier doesn't +actually have to appear in the defining scrap; it just has to be in +the list of definitions at the end of a scrap. + +\section{Sectioning commands} +For larger documents the indexes and usage lists get rather +unwieldy and problems arise in naming things so that different +things in different parts of the document don't get confused. We +have a sectioning command which keeps the fragment names and user +identifiers separate. Thus, you can give a fragment in one section +the same name as a fragment in another and the two won't be confused +or connected in any way. Nor will user identifiers +defined in one section be referenced in another. Except for the +fact that scraps in successive sections can go into the same +output file, this is the same as if the sections came from +separate input files. + +However, occasionally you may really want fragments from one section +to be used in another. More often, you will want to identify a +user identifier in one section with the same identifier in +another (as, for example, a header file defined in one section is +included in code in another). Extra commands allow a fragment +defined in one section to be accessible from all other sections. +Similarly, you can have scraps which define user identifiers and +export them so that they can be used in other sections. + +\begin{description} +\item[{\tt @@s}] Start a new section. +\item[{\tt @@S}] Close the current section and don't start another. +\item[{\tt @@d+} fragment-name scrap] Define a fragment which is +accessible in all sections, a global fragment. +\item[{\tt @@D+}] Likewise +\item[{\tt @@q+}] Likewise +\item[{\tt @@Q+}] Likewise +\item[{\tt @@m+}] Create an index of all such fragments. +\item[{\tt @@u+}] Create an index of globally accessible +user identifiers. +\end{description} + +There are two kinds of section, the base section which is where +normally everything goes, and local sections which are introduced with +the {\tt @@s} command. A local section comprises everything from the +command which starts it to the one which ends it. A {\tt @@s} command +will start a new local section. A {\tt @@S} command closes the current +local section, but doesn't open another, so what follows goes into the +base section. Note that fragments defined in the base section aren't +global; they are accessible only in the base section, but they are +accessible regardless of any local sections between their definition +and their use. + +Within a scrap: +\begin{description} +\item[\tt @@<+{\em fragment-name\/}@@>] +Expand the globally accessible fragment with that name, rather than +any local fragment. +\item[{\tt @@+}] Like \verb"@@|" except that the identifiers +defined are exported to the global realm and are not directly +referenced in any scrap in any section (not even the one where +they are defined). +\item[{\tt @@-}] Like \verb"@@|" except that the identifiers +are imported to the local realm. The cross-references show where +the global variables are defined and defines the same names as +locally accesible. Uses of the names within the section will +point to this scrap. +\end{description} + +Note that the \verb"+" signs above are part of the commands. They +are not part of the fragment names. If you want a fragment whose name +begins with a plus sign, leave a space between the command and the +name. + +\section{Running Nuweb} + +Nuweb is invoked using the following command: +\begin{quote} +{\tt nuweb} {\em flags file-name}\ldots +\end{quote} +One or more files may be processed at a time. If a file name has no +extension, \verb|.w| will be appended. {\LaTeX} suitable for +translation into HTML by {\LaTeX}2HTML will be produced from +files whose name ends with \verb|.hw|, otherwise, ordinary {\LaTeX} will be +produced. While a file name may specify a file in another directory, +the resulting documentation file will always be created in the current +directory. For example, +\begin{quote} +{\tt nuweb /foo/bar/quux} +\end{quote} +will take as input the file \verb|/foo/bar/quux.w| and will create the +file \verb|quux.tex| in the current directory. + +By default, nuweb performs both tangling and weaving at the same time. +Normally, this is not a bottleneck in the compilation process; +however, it's possible to achieve slightly faster throughput by +avoiding one or another of the default functions using command-line +flags. There are currently three possible flags: +\begin{description} +\item[\tt -t] Suppress generation of the documentation file. +\item[\tt -o] Suppress generation of the output files. +\item[\tt -c] Avoid testing output files for change before updating them. +\end{description} +Thus, the command +\begin{quote} +\verb|nuweb -to /foo/bar/quux| +\end{quote} +would simply scan the input and produce no output at all. + +There are several additional command-line flags: +\begin{description} +\item[\tt -v] For ``verbose'', causes nuweb to write information about + its progress to \verb|stderr|. +\item[\tt -n] Forces scraps to be numbered sequentially from~1 + (instead of using page numbers). This form is perhaps more desirable + for small webs. +\item[\tt -s] Doesn't print list of scraps making up each file + following each scrap. +\item[\tt -d] Print ``dangling'' identifiers -- user identifiers which + are never referenced, in indices, etc. +\item[\tt -p {\it path}] Prepend \textit{path} to the filenames for +all the output files. +\item[\tt -l] \label{sec:pretty-print} Use the \texttt{listings} +package for formatting scraps. Use this if you want to have a +pretty-printer for your scraps. In order to e.g. have pretty Perl +scraps, include the following \LaTeX\ commands in your document: +\lstset{language=[LaTeX]TeX} + +\begin{lstlisting}{language={[LaTeX]TeX}} +\usepackage{listings} +... +\lstset{extendedchars=true,keepspaces=true,language=perl} +\end{lstlisting} + +See the \texttt{listings} documentation for a list of formatting +options. Be sure to include a \texttt{\char92 +usepackage\{listings\}} +in your document. + +\item[\tt -V \it string] Provide \textit{string} as the +replacement for the @@v operation. +\end{description} + +\section{Generating HTML} + +Nikos Drakos' {\LaTeX}2HTML Version 0.5.3~\cite{drakos:94} can be used +to translate {\LaTeX} with embedded HTML scraps into HTML\@@. Be sure +to include the document-style option \verb|html| so that {\LaTeX} will +understand the hypertext commands. When translating into HTML, do not +allow a document to be split by specifying ``\verb|-split 0|''. +You need not generate navigation links, so also specify +``\verb|-no_navigation|''. + +While preparing a web, you may want to view the program's scraps without +taking the time to run {\LaTeX}2HTML\@@. Simply rename the generated +{\LaTeX} source so that its file name ends with \verb|.html|, and view +that file. The documentations section will be jumbled, but the +scraps will be clear. + +(Note that the HTML generation is not currently maintained. If the +only reason you want HTML is ti get hyperlinks, use the {\LaTeX} +\verb|hyperref| package and produce your document as PDF via +\verb|pdflatex|.) + +\section{Restrictions} + +Because nuweb is intended to be a simple tool, I've established a few +restrictions. Over time, some of these may be eliminated; others seem +fundamental. +\begin{itemize} +\item The handling of errors is not completely ideal. In some cases, I + simply warn of a problem and continue; in other cases I halt + immediately. This behavior should be regularized. +\item I warn about references to fragments that haven't been defined, but + don't halt. The name of the fragment is included in the output file + surrounded by \verb|<>| signs. + This seems most convenient for development, but may change + in the future. +\item File names and index entries should not contain any \verb|@@| + signs. +\item Fragment names may be (almost) any well-formed \TeX\ string. + It makes sense to change fonts or use math mode; however, care should + be taken to ensure matching braces, brackets, and dollar signs. + When producing HTML, fragments are displayed in a preformatted element + (PRE), so fragments may contain one or more A, B, I, U, or P elements + or data characters. +\item Anything is allowed in the body of a scrap; however, very + long scraps (horizontally or vertically) may not typeset well. +\item Temporary files (created for comparison to the eventual + output files) are placed in the current directory. Since they may be + renamed to an output file name, all the output files should be on the + same file system as the current directory. Alternatively, you can + use the \verb|-p| flag to specify where the files go. +\item Because page numbers cannot be determined until the document has + been typeset, we have to rerun nuweb after \LaTeX\ to obtain a clean + version of the document (very similar to the way we sometimes have + to rerun \LaTeX\ to obtain an up-to-date table of contents after + significant edits). Nuweb will warn (in most cases) when this needs + to be done; in the remaining cases, \LaTeX\ will warn that labels + may have changed. +\end{itemize} +Very long scraps may be allowed to break across a page if declared +with \verb|@@O| or \verb|@@D| (instead of \verb|@@o| and \verb|@@d|). +This doesn't work very well as a default, since far too many short +scraps will be broken across pages; however, as a user-controlled +option, it seems very useful. No distinction is made between the +upper case and lower case forms of these commands when generating +HTML\@@. + +\section{Acknowledgements} + +Several people have contributed their times, ideas, and debugging +skills. In particular, I'd like to acknowledge the contributions of +Osman Buyukisik, Manuel Carriba, Adrian Clarke, Tim Harvey, Michael +Lewis, Walter Ravenek, Rob Shillingsburg, Kayvan Sylvan, Dominique +de~Waleffe, and Scott Warren. Of course, most of these people would +never have heard or nuweb (or many other tools) without the efforts of +George Greenwade. + +Since maintenance has been taken over by Marc Mengel, Simon Wright and +Keith Harwood online contributions have been made by: +\begin{itemize} +\item Walter Brown \verb|<wb@@fnal.gov>| +\item Nicky van Foreest \verb|<n.d.vanforeest@@math.utwente.nl>| +\item Javier Goizueta \verb|<jgoizueta@@jazzfree.com>| +\item Alan Karp \verb|<karp@@hp.com>| +\end{itemize} + +\ifshowcode +\chapter{The Overall Structure} + +Processing a web requires three major steps: +\begin{enumerate} + \item Read the source, accumulating file names, fragment names, scraps, + and lists of cross-references. + \item Reread the source, copying out to the documentation file, with + protection and cross-reference information for all the scraps. + \item Traverse the list of files names. For each file name: + \begin{enumerate} + \item Dump all the defining scraps into a temporary file. + \item If the file already exists and is unchanged, delete the + temporary file; otherwise, rename the temporary file. + \end{enumerate} +\end{enumerate} + + +\section{Files} + +I have divided the program into several files for quicker +recompilation during development. +@o global.h -cc +@{@<Include files@> +@<Type declarations@> +@<Limits@> +@<Global variable declarations@> +@<Function prototypes@> +@<Operating System Dependencies@>@} + +We'll need at least five of the standard system include files. +@d Include files +@{ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <signal.h> +#include <locale.h> +@| FILE stderr exit fprintf fputs fopen fclose getc putc strlen +toupper isupper islower isgraph isspace remove malloc size_t +setlocale getenv @} + + +\newpage +\noindent +I like to use \verb|TRUE| and \verb|FALSE| in my code. +I'd use an \verb|enum| here, except that some systems seem to provide +definitions of \verb|TRUE| and \verb|FALSE| by default. The following +code seems to work on all the local systems. +@d Type dec... +@{#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif +@| FALSE TRUE @} + +Here we define the maximum length for names (of fragments etc). + +@d Limits @{@% +#ifndef MAX_NAME_LEN +#define MAX_NAME_LEN 1024 +#endif +@| MAX_NAME_LEN @} + + +\subsection{The Main Files} + +The code is divided into four main files (introduced here) and five +support files (introduced in the next section). +The file \verb|main.c| will contain the driver for the whole program +(see Section~\ref{main-routine}). +@o main.c -cc +@{#include "global.h" +@} + +The first pass over the source file is contained in \verb|pass1.c|. +It handles collection of all the file names, fragments names, and scraps +(see Section~\ref{pass-one}). +@o pass1.c -cc +@{#include "global.h" +@} + +The \verb|.tex| file is created during a second pass over the source +file. The file \verb|latex.c| contains the code controlling the +construction of the \verb|.tex| file +(see Section~\ref{latex-file}). +@o latex.c -cc +@{#include "global.h" +static int scraps = 1; +@} + +The file \verb|html.c| contains the code controlling the +construction of the \verb|.tex| file appropriate for use with {\LaTeX}2HTML +(see Section~\ref{html-file}). +@o html.c +@{#include "global.h" +static int scraps = 1; +@} + +The code controlling the creation of the output files is in \verb|output.c| +(see Section~\ref{output-files}). +@o output.c -cc +@{#include "global.h" +@} + +\newpage +\subsection{Support Files} + +The support files contain a variety of support routines used to define +and manipulate the major data abstractions. +The file \verb|input.c| holds all the routines used for referring to +source files (see Section~\ref{source-files}). +@o input.c -cc +@{#include "global.h" +@} + +Creation and lookup of scraps is handled by routines in \verb|scraps.c| +(see Section~\ref{scraps}). +@o scraps.c -cc +@{#include "global.h" +@} + + +The handling of file names and fragment names is detailed in \verb|names.c| +(see Section~\ref{names}). +@o names.c -cc +@{#include "global.h" +@} + +Memory allocation and deallocation is handled by routines in \verb|arena.c| +(see Section~\ref{memory-management}). +@o arena.c -cc +@{#include "global.h" +@} + +Finally, for best portability, I seem to need a file containing +(useless!) definitions of all the global variables. +@o global.c -cc +@{#include "global.h" +@<Operating System Dependencies@> +@<Global variable definitions@> +@} + +\section{The Main Routine} \label{main-routine} + +The main routine is quite simple in structure. +It wades through the optional command-line arguments, +then handles any files listed on the command line. +@o main.c -cc +@{ +#include <stdlib.h> +int main(argc, argv) + int argc; + char **argv; +{ + int arg = 1; + @<Interpret command-line arguments@> + @<Set locale information@> + initialise_delimit_scrap_array(); + @<Process the remaining arguments (file names)@> + exit(0); +} +@| main @} + +We only have two major operating system dependencies; the separators for +file names, and how to set environment variables. +For now we assume the latter can be accomplished +via \verb|putenv()| in \verb|stdlib.h|. +@d Operating System Dependencies @{ +#if defined(VMS) +#define PATH_SEP(c) (c==']'||c==':') +#define PATH_SEP_CHAR "" +#define DEFAULT_PATH "" +#elif defined(MSDOS) +#define PATH_SEP(c) (c=='\\') +#define PATH_SEP_CHAR "\\" +#define DEFAULT_PATH "." +#else +#define PATH_SEP(c) (c=='/') +#define PATH_SEP_CHAR "/" +#define DEFAULT_PATH "." +#endif +@} +\subsection{Command-Line Arguments} + +There are numerous possible command-line arguments: +\begin{description} +\item[\tt -t] Suppresses generation of the {\tt .tex} file. +\item[\tt -o] Suppresses generation of the output files. +\item[\tt -d] list dangling identifier references in indexes. +\item[\tt -c] Forces output files to overwrite old files of the same + name without comparing for equality first. +\item[\tt -v] The verbose flag. Forces output of progress reports. +\item[\tt -n] Forces sequential numbering of scraps (instead of page + numbers). +\item[\tt -s] Doesn't print list of scraps making up file at end of + each scrap. +\item[\tt -x] Include cross-reference numbers in scrap comments. +\item[\tt -p \it path] Prepend \textit{path} to the filenames for +all the output files. +\item[\tt -h \it options] Provide options for the hyperref +package. +\item[\tt -r] Turn on hyperlinks. You must include the |usepackage| +options in the text. +\end{description} + +There are two ways to get hyper-links into your documentation. With +one, the \texttt{-r} flag simply arranges for fragment +cross-references to be hyperlinks. You have to provide all the rest of +the \texttt{hyperref} material yourself. The \texttt{-h} flag does +more work, but requires you provide the \texttt{hyperref} options on +the command line. You would use the first if you know you will use the +same tools all the time. You would use the second if you have to +distribute the nuweb file and use the build system to provide the +\texttt{hyperref} options. + +The \texttt{-h}\ option is used as follows. If you want +hyperlinks in your document give a string to this option which is +a valid option for the \texttt{hyperref} package. For example, +\verb|"dvips,colorlinks=true"| sets it to use the +\texttt{dvips} driver and mark the links in colour. For more +information about these options, see the \texttt{hyperref}\ +documentation. + +Then in your document you put the command \verb|\NWuseHyperlinks| +immadiately after your \verb|usepackage| commands. If you do both +of these you will get hyperlinks. If you miss out either then +nothing interesting happens. + +\noindent +Global flags are declared for each of the arguments. +@d Global variable dec... +@{extern int tex_flag; /* if FALSE, don't emit the documentation file */ +extern int html_flag; /* if TRUE, emit HTML instead of LaTeX scraps. */ +extern int output_flag; /* if FALSE, don't emit the output files */ +extern int compare_flag; /* if FALSE, overwrite without comparison */ +extern int verbose_flag; /* if TRUE, write progress information */ +extern int number_flag; /* if TRUE, use a sequential numbering scheme */ +extern int scrap_flag; /* if FALSE, don't print list of scraps */ +extern int dangling_flag; /* if FALSE, don't print dangling identifiers */ +extern int xref_flag; /* If TRUE, print cross-references in scrap comments */ +extern int prepend_flag; /* If TRUE, prepend a path to the output file names */ +extern char * dirpath; /* The prepended directory path */ +extern char * path_sep; /* How to join path to filename */ +extern int listings_flag; /* if TRUE, use listings package for scrap formatting */ +extern int version_info_flag; /* If TRUE, set up version string */ +extern char * version_string; /* What to print for @@v */ +extern int hyperref_flag; /* Are we preparing for hyperref + package. */ +extern int hyperopt_flag; /* Are we preparing for hyperref options */ +extern char * hyperoptions; /* The options to pass to the + hyperref package */ +extern int includepath_flag; /* Do we have an include path? */ +extern struct incl{char * name; struct incl * next;} * include_list; + /* The list of include paths */ +@| tex_flag html_flag output_flag compare_flag verbose_flag number_flag +scrap_flag dangling_flag xref_flag version_info_flag +version_string hyperref_flag hyperopt_flag hyperoptions includepath_flag +incl @} + +The flags are all initialized for correct default behavior. + +@d Global variable def... +@{int tex_flag = TRUE; +int html_flag = FALSE; +int output_flag = TRUE; +int compare_flag = TRUE; +int verbose_flag = FALSE; +int number_flag = FALSE; +int scrap_flag = TRUE; +int dangling_flag = FALSE; +int xref_flag = FALSE; +int prepend_flag = FALSE; +char * dirpath = DEFAULT_PATH; /* Default directory path */ +char * path_sep = PATH_SEP_CHAR; +int listings_flag = FALSE; +int version_info_flag = FALSE; +char default_version_string[] = "no version"; +char * version_string = default_version_string; +int hyperref_flag = FALSE; +int hyperopt_flag = FALSE; +char * hyperoptions = ""; +int includepath_flag = FALSE; /* Do we have an include path? */ +struct incl * include_list = NULL; + /* The list of include paths */ +@} + +A global variable \verb|nw_char| will be used for the nuweb +meta-character, which by default will be @@. +@d Global variable dec... +@{extern int nw_char; +@| nw_char @} +@d Global variable def... +@{int nw_char='@@'; +@| nw_char @} + + +We save the invocation name of the command in a global variable +\verb|command_name| for use in error messages. +@d Global variable dec... +@{extern char *command_name; +@| command_name @} + +@d Global variable def... +@{char *command_name = NULL; +@} + +The invocation name is conventionally passed in \verb|argv[0]|. +@d Interpret com... +@{command_name = argv[0]; +@} + +We need to examine the remaining entries in \verb|argv|, looking for +command-line arguments. +@d Interpret com... +@{while (arg < argc) { + char *s = argv[arg]; + if (*s++ == '-') { + @<Interpret the argument string \verb|s|@> + arg++; + @<Perhaps get the prepend path@> + @<Perhaps get the version info string@> + @<Perhaps get the hyperref options@> + @<Perhaps add an include path@> + } + else break; +}@} + +Several flags can be stacked behind a single minus sign; therefore, +we've got to loop through the string, handling them all. +If this flag requires an argument we skip to getting its argument +straight away. This allows arguments to butt up to their flags +and also avoids ambiguity about which value goes with which flag. + +@d Interpret the... +@{{ + char c = *s++; + while (c) { + switch (c) { + case 'c': compare_flag = FALSE; + break; + case 'd': dangling_flag = TRUE; + break; + case 'h': hyperopt_flag = TRUE; + goto HasValue; + case 'I': includepath_flag = TRUE; + goto HasValue; + case 'l': listings_flag = TRUE; + break; + case 'n': number_flag = TRUE; + break; + case 'o': output_flag = FALSE; + break; + case 'p': prepend_flag = TRUE; + goto HasValue; + case 'r': hyperref_flag = TRUE; + break; + case 's': scrap_flag = FALSE; + break; + case 't': tex_flag = FALSE; + break; + case 'v': verbose_flag = TRUE; + break; + case 'V': version_info_flag = TRUE; + goto HasValue; + case 'x': xref_flag = TRUE; + break; + default: fprintf(stderr, "%s: unexpected argument ignored. ", + command_name); + fprintf(stderr, "Usage is: %s [-cdnostvx] " + "[-I path] [-V version] " + "[-h options] [-p path] file...\n", + command_name); + break; + } + c = *s++; + } +@#HasValue:; +}@} + + +@d Perhaps get the prepend path +@{if (prepend_flag) +{ + if (*s == '\0') + s = argv[arg++]; + dirpath = s; + prepend_flag = FALSE; +} +@} + +@d Perhaps add an include path +@{if (includepath_flag) +{ + struct incl * le + = (struct incl *)arena_getmem(sizeof(struct incl)); + struct incl ** p = &include_list; + + if (*s == '\0') + s = argv[arg++]; + le->name = save_string(s); + le->next = NULL; + while (*p != NULL) + p = &((*p)->next); + *p = le; + includepath_flag = FALSE; +} +@} + +@d Perhaps get the version info string +@{if (version_info_flag) +{ + if (*s == '\0') + s = argv[arg++]; + version_string = s; + version_info_flag = FALSE; +} +@} + +@d Perhaps get the hyperref options +@{if (hyperopt_flag) +{ + if (*s == '\0') + s = argv[arg++]; + hyperoptions = s; + hyperopt_flag = FALSE; + hyperref_flag = TRUE; +} +@} + +In order to be able to process files in foreign languages we +set the locale information. \texttt{isgraph()} and friends need +this (see Section~\ref{names}). +Try to read \texttt{LC\_CTYPE} from the environment. Use \texttt{LC\_ALL} +if that fails. Don't set the locale if reading \texttt{LC\_ALL} fails, too. +Print a warning if setting the program's locale fails. +@d Set locale information @{ +{ + /* try to get locale information */ + char *s=getenv("LC_CTYPE"); + if (s==NULL) s=getenv("LC_ALL"); + + /* set it */ + if (s!=NULL) + if(setlocale(LC_CTYPE, s)==NULL) + fprintf(stderr, "Setting locale failed\n"); +} +@} + +\subsection{File Names} + +We expect at least one file name. While a missing file name might be +ignored without causing any problems, we take the opportunity to report +the usage convention. +@d Process the remaining... +@{{ + if (arg >= argc) { + fprintf(stderr, "%s: expected a file name. ", command_name); + fprintf(stderr, "Usage is: %s [-cnotv] [-p path] file-name...\n", command_name); + exit(-1); + } + do { + @<Handle the file name in \verb|argv[arg]|@> + arg++; + } while (arg < argc); +}@} + +\newpage +\noindent +The code to handle a particular file name is rather more tedious than +the actual processing of the file. A file name may be an arbitrarily +complicated path name, with an optional extension. If no extension is +present, we add \verb|.w| as a default. The extended path name will be +kept in a local variable \verb|source_name|. The resulting documentation +file will be written in the current directory; its name will be kept +in the variable \verb|tex_name|. +@d Handle the file... +@{{ + char source_name[FILENAME_MAX]; + char tex_name[FILENAME_MAX]; + char aux_name[FILENAME_MAX]; + @<Build \verb|source_name| and \verb|tex_name|@> + @<Process a file@> +}@} + + +I bump the pointer \verb|p| through all the characters in \verb|argv[arg]|, +copying all the characters into \verb|source_name| (via the pointer +\verb|q|). + +At each slash, I update \verb|trim| to point just past the +slash in \verb|source_name|. The effect is that \verb|trim| will point +at the file name without any leading directory specifications. + +The pointer \verb|dot| is made to point at the file name extension, if +present. If there is no extension, we add \verb|.w| to the source name. +In any case, we create the \verb|tex_name| from \verb|trim|, taking +care to get the correct extension. The \verb|html_flag| is set in +this scrap. +@d Build \verb|sou... +@{{ + char *p = argv[arg]; + char *q = source_name; + char *trim = q; + char *dot = NULL; + char c = *p++; + while (c) { + *q++ = c; + if (PATH_SEP(c)) { + trim = q; + dot = NULL; + } + else if (c == '.') + dot = q - 1; + c = *p++; + } + @<Add the source path to the include path list@> + *q = '\0'; + if (dot) { + *dot = '\0'; /* produce HTML when the file extension is ".hw" */ + html_flag = dot[1] == 'h' && dot[2] == 'w' && dot[3] == '\0'; + sprintf(tex_name, "%s%s%s.tex", dirpath, path_sep, trim); + sprintf(aux_name, "%s%s%s.aux", dirpath, path_sep, trim); + *dot = '.'; + } + else { + sprintf(tex_name, "%s%s%s.tex", dirpath, path_sep, trim); + sprintf(aux_name, "%s%s%s.aux", dirpath, path_sep, trim); + *q++ = '.'; + *q++ = 'w'; + *q = '\0'; + } +}@} + +If the source file has a directory part we add that directory to the +end of the search path so that the path of last resort is the same as +the source path, not, as one person put it, something irrelevant like +the directory nuweb was invoked from. + +@d Add the source path to the include path list +@{if (trim != source_name) { + struct incl * le + = (struct incl *)arena_getmem(sizeof(struct incl)); + struct incl ** p = &include_list; + char sv = *trim; + + *trim = '\0'; + le->name = save_string(source_name); + le->next = NULL; + while (*p != NULL) + p = &((*p)->next); + *p = le; + *trim = sv; +} +@} + +Now that we're finally ready to process a file, it's not really too +complex. We bundle most of the work into four routines \verb|pass1| +(see Section~\ref{pass-one}), \verb|write_tex| (see +Section~\ref{latex-file}), \verb|write_html| (see +Section~\ref{html-file}), and \verb|write_files| (see +Section~\ref{output-files}). After we're finished with a +particular file, we must remember to release its storage (see +Section~\ref{memory-management}). The sequential numbering of scraps +is forced when generating HTML. +@d Process a file +@{{ + pass1(source_name); + current_sector = 1; + prev_sector = 1; + if (tex_flag) { + if (html_flag) { + int saved_number_flag = number_flag; + number_flag = TRUE; + collect_numbers(aux_name); + write_html(source_name, tex_name, 0/*Dummy */); + number_flag = saved_number_flag; + } + else { + collect_numbers(aux_name); + write_tex(source_name, tex_name); + } + } + if (output_flag) + write_files(file_names); + arena_free(); +}@} + + +\newpage +\section{Pass One} \label{pass-one} + +During the first pass, we scan the file, recording the definitions of +each fragment and file and accumulating all the scraps. + +@d Function pro... +@{extern void pass1(); +@} + + +The routine \verb|pass1| takes a single argument, the name of the +source file. It opens the file, then initializes the scrap structures +(see Section~\ref{scraps}) and the roots of the file-name tree, the +fragment-name tree, and the tree of user-specified index entries (see +Section~\ref{names}). After completing all the +necessary preparation, we make a pass over the file, filling in all +our data structures. Next, we seach all the scraps for references to +the user-specified index entries. Finally, we must reverse all the +cross-reference lists accumulated while scanning the scraps. +@o pass1.c -cc +@{void pass1(file_name) + char *file_name; +{ + if (verbose_flag) + fprintf(stderr, "reading %s\n", file_name); + source_open(file_name); + init_scraps(); + macro_names = NULL; + file_names = NULL; + user_names = NULL; + @<Scan the source file, looking for at-sequences@> + if (tex_flag) + search(); + @<Reverse cross-reference lists@> +} +@| pass1 @} + +The only thing we look for in the first pass are the command +sequences. All ordinary text is skipped entirely. +@d Scan the source file, look... +@{{ + int c = source_get(); + while (c != EOF) { + if (c == nw_char) + @<Scan at-sequence@> + c = source_get(); + } +}@} + +Only four of the at-sequences are interesting during the first pass. +We skip past others immediately; warning if unexpected sequences are +discovered. +@d Scan at-sequence +@{{ + char quoted = 0; + + c = source_get(); + switch (c) { + case 'r': + c = source_get(); + nw_char = c; + update_delimit_scrap(); + break; + case 'O': + case 'o': @<Build output file definition@> + break; + case 'Q': + case 'q': quoted = 1; + case 'D': + case 'd': @<Build fragment definition@> + break; + case 's': + @<Step to next sector@> + break; + case 'S': + @<Close the current sector@> + break; + case '<': + case '(': + case '[': + case '{': @<Skip over an in-text scrap@> + break; + case 'c': @<Collect a block comment@> + break; + case 'x': + case 'v': + case 'u': + case 'm': + case 'f': /* ignore during this pass */ + break; + default: if (c==nw_char) /* ignore during this pass */ + break; + fprintf(stderr, + "%s: unexpected %c sequence ignored (%s, line %d)\n", + command_name, nw_char, source_name, source_line); + break; + } +}@} + +@d Step to next sector +@{ +prev_sector += 1; +current_sector = prev_sector; +c = source_get(); +@} + +@d Close the current sector +@{current_sector = 1; +c = source_get(); +@} + +@d Global variable declar... +@{extern unsigned char current_sector; +extern unsigned char prev_sector; +@| current_sector prev_sector @} + +@d Global variable def... +@{unsigned char current_sector = 1; +unsigned char prev_sector = 1; +@} + +\subsection{Accumulating Definitions} + +There are three steps required to handle a definition: +\begin{enumerate} + \item Build an entry for the name so we can look it up later. + \item Collect the scrap and save it in the table of scraps. + \item Attach the scrap to the name. +\end{enumerate} +We go through the same steps for both file names and fragment names. +@d Build output file definition +@{{ + Name *name = collect_file_name(); /* returns a pointer to the name entry */ + int scrap = collect_scrap(); /* returns an index to the scrap */ + @<Add \verb|scrap| to...@> +}@} + + +@d Build fragment definition +@{{ + Name *name = collect_macro_name(); + int scrap = collect_scrap(); + @<Add \verb|scrap| to...@> +}@} + + +Since a file or fragment may be defined by many scraps, we maintain them +in a simple linked list. The list is actually built in reverse order, +with each new definition being added to the head of the list. +@d Add \verb|scrap| to \verb|name|'s definition list +@{{ + Scrap_Node *def = (Scrap_Node *) arena_getmem(sizeof(Scrap_Node)); + def->scrap = scrap; + def->quoted = quoted; + def->next = name->defs; + name->defs = def; +}@} + +@d Skip over an in-text scrap +@{ +{ + int c; + int depth = 1; + while ((c = source_get()) != EOF) { + if (c == nw_char) + @<Skip over at-sign or go to skipped@> + } + fprintf(stderr, "%s: unexpected EOF in text at (%s, %d)\n", + command_name, source_name, source_line); + exit(-1); + +skipped: ; +} +@} + +@d Skip over at-sign or go to skipped +@{ +{ + c = source_get(); + switch (c) { + case '{': case '[': case '(': case '<': + depth += 1; + break; + case '}': case ']': case ')': case '>': + if (--depth == 0) + goto skipped; + case 'x': case '|': case ',': + case '%': case '1': case '2': + case '3': case '4': case '5': case '6': + case '7': case '8': case '9': case '_': + case 'f': case '#': case '+': case '-': + case 'v': case '*': case 'c': case '\'': + case 's': + break; + default: + if (c != nw_char) { + fprintf(stderr, "%s: unexpected %c%c in text at (%s, %d)\n", + command_name, nw_char, c, source_name, source_line); + exit(-1); + } + break; + } +} +@} +\subsection{Block Comments} + +@d Collect a block comment +@{{ + char * p = blockBuff; + char * e = blockBuff + (sizeof(blockBuff)/sizeof(blockBuff[0])) - 1; + + @<Skip whitespace@> + while (p < e) + { + @<Add one char to the block buffer@> + } + if (p == e) + { + @<Skip to the next nw-char@> + } + *p = '\000'; +} +@} + +@d Skip whitespace +@{while (source_peek == ' ' + || source_peek == '\t' + || source_peek == '\n') + (void)source_get(); +@} + +@d Add one char to the block buffer +@{int c = source_get(); + +if (c == nw_char) +{ + @<Add an at character to the block or break@> +} +else if (c == EOF) +{ + source_ungetc(&c); + break; +} +else +{ + @<Add any other character to the block@> +} +@} + +@d Add an at character to the block or break +@{int cc = source_peek; + +if (cc == 'c') +{ + do + c = source_get(); + while (c <= ' '); + + break; +} +else if (cc == 'd' + || cc == 'D' + || cc == 'q' + || cc == 'Q' + || cc == 'o' + || cc == 'O' + || cc == EOF) +{ + source_ungetc(&c); + break; +} +else +{ + *p++ = c; + *p++ = source_get(); +} +@} + +@d Add any other character to the block +@{ + @<Perhaps skip white-space@> + *p++ = c; +@} + +@d Perhaps skip white-space +@{if (c == ' ') +{ + while (source_peek == ' ') + c = source_get(); +} +if (c == '\n') +{ + if (source_peek == '\n') + { + do + c = source_get(); + while (source_peek == '\n'); + } + else + c = ' '; +} +@} + +@d Skip to the next nw-char +@{int c; + +while ((c = source_get()), c != nw_char && c != EOF)/* Skip */ +source_ungetc(&c);@} + +@d Global variable declar... +@{extern char blockBuff[6400]; +@| blockBuff @} + +@d Global variable def... +@{char blockBuff[6400]; +@} + +We don't show block comments inside scraps in the \TeX\ file, +but we do show where they go. + +@d Show presence of a block comment +@{{ + fputs(delimit_scrap[scrap_type][1],file); + fprintf(file, "\\hbox{\\sffamily\\slshape (Comment)}"); + fputs(delimit_scrap[scrap_type][0], file); +} +@} + +The block comment is presently in the block buffer. Here we +copy it into the scrap whence we shall copy it into the output +file. + +@d Include block comment in a scrap +@{{ + char * p = blockBuff; + + push(nw_char, &writer); + do + { + push(c, &writer); + c = *p++; + } while (c != '\0'); +}@} + +@d Copy block comment from scrap +@{{ + int bgn = indent + global_indent; + int posn = bgn + strlen(comment_begin[comment_flag]); + int i; + + @<Perhaps put a delayed indent@> + c = pop(&reader); + fputs(comment_begin[comment_flag], file); + while (c != '\0') + { + @<Move a word to the file@> + @<If we break the line at this word@> + { + putc('\n', file); + for (i = 0; i < bgn ; i++) + putc(' ', file); + c = pop(&reader); + if (c != '\0') + { + posn = bgn + strlen(comment_mid[comment_flag]); + fputs(comment_mid[comment_flag], file); + } + } + } + fputs(comment_end[comment_flag], file); +} +@} + +@d Move a word to the file +@{do +{ + putc(c, file); + posn += 1; + c = pop(&reader); +} while (c > ' '); +@} + +@d If we break the line at this word +@{if (c == '\n' || (c == ' ' && posn > 60))@} + +@d Skip over a block comment +@{if (last == nw_char && c == 'c') + while ((c = pop(reader.m)) != '\0') + /* Skip */; +@} + +@d Begin or end a block comment +@{if (inBlock) +{ + @<End block@> +} +else +{ + @<Start block@> +}@} + + +\subsection{Fixing the Cross References} + +Since the definition and reference lists for each name are accumulated +in reverse order, we take the time at the end of \verb|pass1| to +reverse them all so they'll be simpler to print out prettily. +The code for \verb|reverse_lists| appears in Section~\ref{names}. +@d Reverse cross-reference lists +@{{ + reverse_lists(file_names); + reverse_lists(macro_names); + reverse_lists(user_names); +}@} + +\subsection{Dealing with fragment parameters} + +Fragment parameters were added on later in nuweb's development. +There still is not, for example, an index of fragment parameters. +We need a data type to keep track of fragment parameters. + +@o global.h -cc +@{typedef int *Parameters; +@| Parameters @} + + +When we are copying a scrap to the output, we check for an embedded +parameter. If we find it we copy it. Otherwise it's an old-style +parameter and we can then pull +the $n$th string from the \verb|Parameters| list when we +see an \verb|@@1| \verb|@@2|, etc. + +@D Handle macro parameter substitution @{ +case '1': case '2': case '3': +case '4': case '5': case '6': +case '7': case '8': case '9': + { + Arglist * args; + Name * name; + + lookup(c - '1', inArgs, inParams, &name, &args); + + if (name == (Name *)1) { + Embed_Node * q = (Embed_Node *)args; + indent = write_scraps(file, spelling, q->defs, + global_indent + indent, + indent_chars, debug_flag, + tab_flag, indent_flag, + 0, + q->args, inParams, + local_parameters, ""); + } + else if (name != NULL) { + int i, narg; + char * p = name->spelling; + Arglist *q = args; + + @<Perhaps comment...@> + indent = write_scraps(file, spelling, name->defs, + global_indent + indent, + indent_chars, debug_flag, + tab_flag, indent_flag, + comment_flag, args, name->arg, + local_parameters, p); + } + else if (args != NULL) { + if (delayed_indent) { + @<Put out the indent@> + } + fputs((char *)args, file); + } + else if ( parameters && parameters[c - '1'] ) { + Scrap_Node param_defs; + param_defs.scrap = parameters[c - '1']; + param_defs.next = 0; + write_scraps(file, spelling, ¶m_defs, + global_indent + indent, + indent_chars, debug_flag, + tab_flag, indent_flag, + comment_flag, NULL, NULL, 0, ""); + } else if (delayed_indent) { + @<Put out the indent@> + } + } +@} +Now onto actually parsing fragment parameters from a call. +We start off checking for fragment parameters, an \verb|@@(| sequence +followed by parameters separated by \verb|@@,| sequences, and +terminated by a \verb|@@)| sequence. + +We collect separate scraps for each parameter, and write the +scrap numbers down in the text. For example, if the file has: +\begin{verbatim} + @@<foo @@( param1 @@, param2 @@)@@> +\end{verbatim} +we actually make new scraps, say 10 and 11, for param1 and param2, +and write in the collected scrap: +\begin{verbatim} + @@<foo @@(10@@,11@@)@@> +\end{verbatim} + +@d Save macro parameters +@{{ + int param_scrap; + char param_buf[10]; + + push(nw_char, &writer); + push('(', &writer); + do { + param_scrap = collect_scrap(); + sprintf(param_buf, "%d", param_scrap); + pushs(param_buf, &writer); + push(nw_char, &writer); + push(scrap_ended_with, &writer); + add_to_use(name, current_scrap); + } while( scrap_ended_with == ',' ); + do + c = source_get(); + while( ' ' == c ); + if (c == nw_char) { + c = source_get(); + } + if (c != '>') { + /* ZZZ print error */; + } +}@} + +If we get inside, we have at least one parameter, which will be at +the beginning of the parms buffer, and we prime the pump with the +first character. + +@d Check for macro parameters +@{ + if (c == '(') { + Parameters res = arena_getmem(10 * sizeof(int)); + int *p2 = res; + int count = 0; + int scrapnum; + + while( c && c != ')' ) { + scrapnum = 0; + c = pop(manager); + while( '0' <= c && c <= '9' ) { + scrapnum = scrapnum * 10 + c - '0'; + c = pop(manager); + } + if ( c == nw_char ) { + c = pop(manager); + } + *p2++ = scrapnum; + } + while (count < 10) { + *p2++ = 0; + count++; + } + while( c && c != nw_char ) { + c = pop(manager); + } + if ( c == nw_char ) { + c = pop(manager); + } + *parameters = res; + } +@} + +These are used in \verb|write_tex| and \verb|write_html| to output the +argument list for a fragment. + +@d Format macro parameters +@{ + char sep; + + sep = '('; + do { + fputc(sep,file); + + fputs("{\\footnotesize ", file); + write_single_scrap_ref(file, scraps + 1); + fprintf(file, "\\label{scrap%d}\n", scraps + 1); + fputs(" }", file); + + source_last = '{'; + copy_scrap(file, TRUE, NULL); + + ++scraps; + + sep = ','; + } while ( source_last != ')' && source_last != EOF ); + fputs(" ) ",file); + do + c = source_get(); + while(c != nw_char && c != EOF); + if (c == nw_char) { + c = source_get(); + } +@} + +@d Format HTML macro parameters +@{ + char sep; + + sep = '('; + fputs("\\begin{rawhtml}", file); + do { + + fputc(sep,file); + + fprintf(file, "%d <A NAME=\"#nuweb%d\"></A>", scraps, scraps); + + source_last = '{'; + copy_scrap(file, TRUE); + + ++scraps; + sep = ','; + + } while ( source_last != ')' && source_last != EOF ); + fputs(" ) ",file); + do + c = source_get(); + while(c != nw_char && c != EOF); + if (c == nw_char) { + c = source_get(); + } + fputs("\\end{rawhtml}", file); +@} + + +\section{Writing the Latex File} \label{latex-file} + +The second pass (invoked via a call to \verb|write_tex|) copies most of +the text from the source file straight into a \verb|.tex| file. +Definitions are formatted slightly and cross-reference information is +printed out. + +Note that all the formatting is handled in this section. +If you don't like the format of definitions or indices or whatever, +it'll be in this section somewhere. Similarly, if someone wanted to +modify nuweb to work with a different typesetting system, this would +be the place to look. + +@d Function... +@{extern void write_tex(); +@} + +We need a few local function declarations before we get into the body +of \verb|write_tex|. + +@o latex.c -cc +@{static void copy_scrap(); /* formats the body of a scrap */ +static void print_scrap_numbers(); /* formats a list of scrap numbers */ +static void format_entry(); /* formats an index entry */ +static void format_file_entry(); /* formats a file index entry */ +static void format_user_entry(); +static void write_arg(); +static void write_literal(); +static void write_ArglistElement(); +@} + + +The routine \verb|write_tex| takes two file names as parameters: the +name of the web source file and the name of the \verb|.tex| output file. +@o latex.c -cc +@{void write_tex(file_name, tex_name, sector) + char *file_name; + char *tex_name; + unsigned char sector; +{ + FILE *tex_file = fopen(tex_name, "w"); + if (tex_file) { + if (verbose_flag) + fprintf(stderr, "writing %s\n", tex_name); + source_open(file_name); + @<Write LaTeX limbo definitions@> + @<Copy \verb|source_file| into \verb|tex_file|@> + fclose(tex_file); + } + else + fprintf(stderr, "%s: can't open %s\n", command_name, tex_name); +} +@| write_tex @} + + +Now that the \verb|\NW...| macros are used, it seems convenient +to write default definitions for those macros so that source files +need not define anything new. If a user wants to change any of +the macros (to use hyperref or to write in some language other than +english) he or she can redefine the commands. + +@d Write LaTeX limbo definitions +@{if (hyperref_flag) { + fputs("\\newcommand{\\NWtarget}[2]{\\hypertarget{#1}{#2}}\n", tex_file); + fputs("\\newcommand{\\NWlink}[2]{\\hyperlink{#1}{#2}}\n", tex_file); +} else { + fputs("\\newcommand{\\NWtarget}[2]{#2}\n", tex_file); + fputs("\\newcommand{\\NWlink}[2]{#2}\n", tex_file); +} +fputs("\\newcommand{\\NWtxtMacroDefBy}{Fragment defined by}\n", tex_file); +fputs("\\newcommand{\\NWtxtMacroRefIn}{Fragment referenced in}\n", tex_file); +fputs("\\newcommand{\\NWtxtMacroNoRef}{Fragment never referenced}\n", tex_file); +fputs("\\newcommand{\\NWtxtDefBy}{Defined by}\n", tex_file); +fputs("\\newcommand{\\NWtxtRefIn}{Referenced in}\n", tex_file); +fputs("\\newcommand{\\NWtxtNoRef}{Not referenced}\n", tex_file); +fputs("\\newcommand{\\NWtxtFileDefBy}{File defined by}\n", tex_file); +fputs("\\newcommand{\\NWtxtIdentsUsed}{Uses:}\n", tex_file); +fputs("\\newcommand{\\NWtxtIdentsNotUsed}{Never used}\n", tex_file); +fputs("\\newcommand{\\NWtxtIdentsDefed}{Defines:}\n", tex_file); +fputs("\\newcommand{\\NWsep}{${\\diamond}$}\n", tex_file); +fputs("\\newcommand{\\NWnotglobal}{(not defined globally)}\n", tex_file); +fputs("\\newcommand{\\NWuseHyperlinks}{", tex_file); +if (hyperoptions[0] != '\0') +{ + @<Write the hyperlink usage macro@> +} +fputs("}\n", tex_file); +@} + +@d Write the hyperlink usage macro +@{fprintf(tex_file, "\\usepackage[%s]{hyperref}", hyperoptions);@} + +We make our second (and final) pass through the source web, this time +copying characters straight into the \verb|.tex| file. However, we keep +an eye peeled for \verb|@@|~characters, which signal a command sequence. + +@d Copy \verb|source_file| into \verb|tex_file| +@{{ + int inBlock = FALSE; + int c = source_get(); + while (c != EOF) { + if (c == nw_char) + { + @<Interpret at-sequence@> + } + else { + putc(c, tex_file); + c = source_get(); + } + } +}@} + +@d Interpret at-sequence +@{{ + int big_definition = FALSE; + c = source_get(); + switch (c) { + case 'r': + c = source_get(); + nw_char = c; + update_delimit_scrap(); + break; + case 'O': big_definition = TRUE; + case 'o': @<Write output file definition@> + break; + case 'Q': + case 'D': big_definition = TRUE; + case 'q': + case 'd': @<Write macro definition@> + break; + case 's': + @<Step to next sector@> + break; + case 'S': + @<Close the current sector@> + break; + case '{': + case '[': + case '(': @<Write in-text scrap@> + break; + case '<': @<Expand macro into @'tex_file@'@> + break; + case 'x': @<Copy label from source into@(tex_file@)@> + c = source_get(); + break; + case 'c': @<Begin or end a block comment@> + c = source_get(); + break; + case 'f': @<Write index of file names@> + break; + case 'm': @<Write index of macro names@> + break; + case 'u': @<Write index of user-specified names@> + break; + case 'v': @<Copy version info into tex file@> + break; + default: + if (c==nw_char) + putc(c, tex_file); + c = source_get(); + break; + } +}@} + +@d Copy version info into tex file +@{fputs(version_string, tex_file); +c = source_get(); +@} + +@d Expand macro into @'file@' +@{{ + Parameters local_parameters = 0; + int changed; + char indent_chars[MAX_INDENT]; + Arglist *a; + Name *name; + Arglist * args; + a = collect_scrap_name(0); + name = a->name; + args = instance(a->args, NULL, NULL, &changed); + name->mark = TRUE; + write_scraps(@1, tex_name, name->defs, 0, indent_chars, 0, 0, 1, 0, + args, name->arg, local_parameters, tex_name); + name->mark = FALSE; + c = source_get(); +} +@} + +\subsection{Formatting Definitions} + +We go through a fair amount of effort to format a file definition. +I've derived most of the \LaTeX\ commands experimentally; it's quite +likely that an expert could do a better job. The \LaTeX\ for +the previous fragment definition should look like this (perhaps modulo +the scrap references): +{\small +\begin{verbatim} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap70}\raggedright\small +$\langle$Interpret at-sequence {\footnotesize 18}$\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@@{@@\\ +\mbox{}\verb@@ int big_definition = FALSE;@@\\ +\mbox{}\verb@@ c = source_get();@@\\ +\mbox{}\verb@@ switch (c) {@@\\ +\mbox{}\verb@@ case 'O': big_definition = TRUE;@@\\ +\mbox{}\verb@@ case 'o': @@$\langle$Write output file definition {\footnotesize 19a}$\rangle$\verb@@@@\\ +\end{verbatim} +\vdots +\begin{verbatim} +\mbox{}\verb@@ case '@@{\tt @@}\verb@@': putc(c, tex_file);@@\\ +\mbox{}\verb@@ default: c = source_get();@@\\ +\mbox{}\verb@@ break;@@\\ +\mbox{}\verb@@ }@@\\ +\mbox{}\verb@@}@@$\diamond$ +\end{list} +\vspace{-1ex} +\footnotesize\addtolength{\baselineskip}{-1ex} +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item Fragment referenced in scrap 17b. +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{verbatim}} + +\noindent +The {\em flushleft\/} environment is used to avoid \LaTeX\ warnings +about underful lines. The {\em minipage\/} environment is used to +avoid page breaks in the middle of scraps. The {\em verb\/} command +allows arbitrary characters to be printed (however, note the special +handling of the \verb|@@| case in the switch statement). + +Fragment and file definitions are formatted nearly identically. +I've factored the common parts out into separate scraps. + +@d Write output file definition +@{{ + Name *name = collect_file_name(); + @<Begin the scrap environment@> + fputs("\\NWtarget{nuweb", tex_file); + write_single_scrap_ref(tex_file, scraps); + fputs("}{} ", tex_file); + fprintf(tex_file, "\\verb%c\"%s\"%c\\nobreak\\ {\\footnotesize {", nw_char, name->spelling, nw_char); + write_single_scrap_ref(tex_file, scraps); + fputs("}}$\\equiv$\n", tex_file); + @<Fill in the middle of the scrap environment@> + @<Begin the cross-reference environment@> + if ( scrap_flag ) { + @<Write file defs@> + } + format_defs_refs(tex_file, scraps); + format_uses_refs(tex_file, scraps++); + @<Finish the cross-reference environment@> + @<Finish the scrap environment@> +}@} + + +I don't format a fragment name at all specially, figuring the programmer +might want to use italics or bold face in the midst of the name. + +@d Write macro definition +@{{ + Name *name = collect_macro_name(); + + @<Begin the scrap environment@> + fputs("\\NWtarget{nuweb", tex_file); + write_single_scrap_ref(tex_file, scraps); + fputs("}{} $\\langle\\,${\\itshape ", tex_file); + @<Write the macro's name@> + fputs("}\\nobreak\\ {\\footnotesize {", tex_file); + write_single_scrap_ref(tex_file, scraps); + fputs("}}$\\,\\rangle\\equiv$\n", tex_file); + @<Fill in the middle of the scrap environment@> + @<Begin the cross-reference environment@> + @<Write macro defs@> + @<Write macro refs@> + format_defs_refs(tex_file, scraps); + format_uses_refs(tex_file, scraps++); + @<Finish the cross-reference environment@> + @<Finish the scrap environment@> +}@} + +@d Write the macro's name +@{{ + char * p = name->spelling; + int i = 0; + + while (*p != '\000') { + if (*p == ARG_CHR) { + write_arg(tex_file, name->arg[i++]); + p++; + } + else + fputc(*p++, tex_file); + } +}@} + +@o latex.c -cc +@{static void write_arg(FILE * tex_file, char * p) +{ + fputs("\\hbox{\\slshape\\sffamily ", tex_file); + while (*p) + { + switch (*p) + { + case '$': + case '_': + case '^': + case '#': + fputc('\\', tex_file); + break; + default: + break; + } + fputc(*p, tex_file); + p++; + } + + fputs("\\/}", tex_file); +} +@| write_arg @} + +@d Begin the scrap environment +@{{ + if (big_definition) + { + if (inBlock) + { + @<End block@> + } + fputs("\\begin{flushleft} \\small", tex_file); + } + else + { + if (inBlock) + { + @<Switch block@> + } + else + { + @<Start block@> + } + } + fprintf(tex_file, "\\label{scrap%d}\\raggedright\\small\n", scraps); +}@} + +@d Start block +@{fputs("\\begin{flushleft} \\small\n\\begin{minipage}{\\linewidth}", tex_file); +inBlock = TRUE;@} + +@d Switch block +@{fputs("\\par\\vspace{\\baselineskip}\n", tex_file);@} + +@d End block +@{fputs("\\end{minipage}\\vspace{4ex}\n", tex_file); +fputs("\\end{flushleft}\n", tex_file); +inBlock = FALSE;@} + +The interesting things here are the $\diamond$ inserted at the end of +each scrap and the various spacing commands. The diamond helps to +clearly indicate the end of a scrap. The spacing commands were derived +empirically; they may be adjusted to taste. + +@d Fill in the middle of the scrap environment +@{{ + fputs("\\vspace{-1ex}\n\\begin{list}{}{} \\item\n", tex_file); + extra_scraps = 0; + copy_scrap(tex_file, TRUE, name); + fputs("{\\NWsep}\n\\end{list}\n", tex_file); +}@} + +\newpage +\noindent +We've got one last spacing command, controlling the amount of white +space after a scrap. + +Note also the whitespace eater. I use it to remove any blank lines +that appear after a scrap in the source file. This way, text following +a scrap will not be indented. Again, this is a matter of personal taste. + +@d Finish the scrap environment +@{{ + scraps += extra_scraps; + if (big_definition) + fputs("\\vspace{4ex}\n\\end{flushleft}\n", tex_file); + else + { + @<End block@> + } + do + c = source_get(); + while (isspace(c)); +}@} + +@d Global variable declar... +@{extern int extra_scraps; +@| extra_scraps @} + +@d Global variable def... +@{int extra_scraps = 0; + @} + +@d Write in-text scrap +@{copy_scrap(tex_file, FALSE, NULL); +c = source_get(); +@} + +\subsubsection{Formatting Cross References} + +@d Begin the cross-reference environment +@{{ + fputs("\\vspace{-1.5ex}\n", tex_file); + fputs("\\footnotesize\n", tex_file); + fputs("\\begin{list}{}{\\setlength{\\itemsep}{-\\parsep}", + tex_file); + fputs("\\setlength{\\itemindent}{-\\leftmargin}}\n", tex_file);} +@} + +There may (unusually) be nothing to output in the cross-reference +section, so output an empty list item anyway to avoid having an empty +list. + +@d Finish the cross-reference environment +@{{ + fputs("\n\\item{}", tex_file); + fputs("\n\\end{list}\n", tex_file); +}@} + +@d Write file defs +@{{ + if (name->defs) { + if (name->defs->next) { + fputs("\\item \\NWtxtFileDefBy\\ ", tex_file); + print_scrap_numbers(tex_file, name->defs); + } + } else { + fprintf(stderr, + "would have crashed in 'Write file defs' for '%s'\n", + name->spelling); + } +}@} + +@d Write macro defs +@{{ + if (name->defs->next) { + fputs("\\item \\NWtxtMacroDefBy\\ ", tex_file); + print_scrap_numbers(tex_file, name->defs); + } +}@} + +@d Write macro refs +@{{ + if (name->uses) { + if (name->uses->next) { + fputs("\\item \\NWtxtMacroRefIn\\ ", tex_file); + print_scrap_numbers(tex_file, name->uses); + } + else { + fputs("\\item \\NWtxtMacroRefIn\\ ", tex_file); + fputs("\\NWlink{nuweb", tex_file); + write_single_scrap_ref(tex_file, name->uses->scrap); + fputs("}{", tex_file); + write_single_scrap_ref(tex_file, name->uses->scrap); + fputs("}", tex_file); + fputs(".\n", tex_file); + } + } + else { + fputs("\\item {\\NWtxtMacroNoRef}.\n", tex_file); + fprintf(stderr, "%s: <%s> never referenced.\n", + command_name, name->spelling); + } +}@} + +@o latex.c -cc +@{static void print_scrap_numbers(tex_file, scraps) + FILE *tex_file; + Scrap_Node *scraps; +{ + int page; + fputs("\\NWlink{nuweb", tex_file); + write_scrap_ref(tex_file, scraps->scrap, -1, &page); + fputs("}{", tex_file); + write_scrap_ref(tex_file, scraps->scrap, TRUE, &page); + fputs("}", tex_file); + scraps = scraps->next; + while (scraps) { + fputs("\\NWlink{nuweb", tex_file); + write_scrap_ref(tex_file, scraps->scrap, -1, &page); + fputs("}{", tex_file); + write_scrap_ref(tex_file, scraps->scrap, FALSE, &page); + scraps = scraps->next; + fputs("}", tex_file); + } + fputs(".\n", tex_file); +} +@| print_scrap_numbers @} + +\subsubsection{Formatting a Scrap} + +We add a \verb|\mbox{}| at the beginning of each line to avoid +problems with older versions of \TeX. +This is the only place we really care whether a scrap is +delimited with \verb|@@{...@@}|, \verb|@@[...@@]|, or \verb|@@(...@@)|, +and we base our output sequences on that. + +We have an array \texttt{delimit\_scrap} where we store our strings +that perform the formatting for one line of a scrap. Upon +initialisation we copy our strings from the source +\texttt{orig\_delimit\_scrap} to it to have the strings writeable. We +might change the strings later when we encounter the command to change +the `nuweb character'. + +@o latex.c +@{static char *orig_delimit_scrap[3][5] = { + /* {} mode: begin, end, insert nw_char, prefix, suffix */ + { "\\verb@@", "@@", "@@{\\tt @@}\\verb@@", "\\mbox{}", "\\\\" }, + /* [] mode: begin, end, insert nw_char, prefix, suffix */ + { "", "", "@@", "", "" }, + /* () mode: begin, end, insert nw_char, prefix, suffix */ + { "$", "$", "@@", "", "" }, +}; + +static char *delimit_scrap[3][5]; +@} + +The function \texttt{initialise\_delimit\_scrap\_array} does the +copying. If we want to have the listings package \index{listings package} +do the formatting we have to replace only two of those strings: the +\texttt{verb} command has to be replaced by the package's \texttt{lstinline} +command. + +@o latex.c +@{void initialise_delimit_scrap_array() { + int i,j; + for(i = 0; i < 3; i++) { + for(j = 0; j < 5; j++) { + if((delimit_scrap[i][j] = strdup(orig_delimit_scrap[i][j])) == NULL) { + fprintf(stderr, "Not enough memory for string allocation\n"); + exit(EXIT_FAILURE); + } + } + } + + /* replace verb by lstinline */ + if (listings_flag) { + free(delimit_scrap[0][0]); + if((delimit_scrap[0][0]=strdup("\\lstinline@@")) == NULL) { + fprintf(stderr, "Not enough memory for string allocation\n"); + exit(EXIT_FAILURE); + } + free(delimit_scrap[0][2]); + if((delimit_scrap[0][2]=strdup("@@{\\tt @@}\\lstinline@@")) == NULL) { + fprintf(stderr, "Not enough memory for string allocation\n"); + exit(EXIT_FAILURE); + } + } +} +@} + +@d Function prototypes +@{void initialise_delimit_scrap_array(void); +@} + +@o latex.c +@{int scrap_type = 0; +@| scrap_type @} + +@o latex.c -cc +@{static void write_literal(FILE * tex_file, char * p, int mode) +{ + fputs(delimit_scrap[mode][0], tex_file); + while (*p!= '\000') { + if (*p == nw_char) + fputs(delimit_scrap[mode][2], tex_file); + else + fputc(*p, tex_file); + p++; + } + fputs(delimit_scrap[mode][1], tex_file); +} +@| write_literal @} + +@o latex.c -cc +@{static void copy_scrap(file, prefix, name) + FILE *file; + int prefix; + Name * name; +{ + int indent = 0; + int c; + char ** params = name->arg; + if (source_last == '{') scrap_type = 0; + if (source_last == '[') scrap_type = 1; + if (source_last == '(') scrap_type = 2; + c = source_get(); + if (prefix) fputs(delimit_scrap[scrap_type][3], file); + fputs(delimit_scrap[scrap_type][0], file); + while (1) { + switch (c) { + case '\n': fputs(delimit_scrap[scrap_type][1], file); + if (prefix) fputs(delimit_scrap[scrap_type][4], file); + fputs("\n", file); + if (prefix) fputs(delimit_scrap[scrap_type][3], file); + fputs(delimit_scrap[scrap_type][0], file); + indent = 0; + break; + case '\t': @<Expand tab into spaces@> + break; + default: + if (c==nw_char) + { + @<Check at-sequence for end-of-scrap@> + break; + } + putc(c, file); + indent++; + break; + } + c = source_get(); + } +} +@| copy_scrap scrap_type @} + +When we encounter the command to change the `nuweb character' we call +this function. It updates the scrap formatting directives accordingly. + +@o latex.c +@{void update_delimit_scrap() +{ + /* {}-mode begin */ + if (listings_flag) { + delimit_scrap[0][0][10] = nw_char; + } else { + delimit_scrap[0][0][5] = nw_char; + } + /* {}-mode end */ + delimit_scrap[0][1][0] = nw_char; + /* {}-mode insert nw_char */ + + delimit_scrap[0][2][0] = nw_char; + delimit_scrap[0][2][6] = nw_char; + + if (listings_flag) { + delimit_scrap[0][2][18] = nw_char; + } else { + delimit_scrap[0][2][13] = nw_char; + } + + /* []-mode insert nw_char */ + delimit_scrap[1][2][0] = nw_char; + + /* ()-mode insert nw_char */ + delimit_scrap[2][2][0] = nw_char; +} +@| update_delimit_scrap @} + +@d Function prototypes +@{void update_delimit_scrap(); +@} + +@d Expand tab into spaces +@{{ + int delta = 8 - (indent % 8); + indent += delta; + while (delta > 0) { + putc(' ', file); + delta--; + } +}@} + +@d Check at-sequence... +@{{ + c = source_get(); + switch (c) { + case 'c': @<Show presence of a block comment@> + break; + case 'x': @<Copy label from source into@(file@)@> + break; + case 'v': @<Copy version info into file@> + case 's': + break; + case '+': + case '-': + case '*': + case '|': @<Skip over index entries@> + case ',': + case ')': + case ']': + case '}': fputs(delimit_scrap[scrap_type][1], file); + return; + case '<': @<Format macro name@> + break; + case '%': @<Skip commented-out code@> + break; + case '_': @<Bold Keyword@> + break; + case 't': @<Italic "@'fragment title@'"@> + break; + case 'f': @<Italic "@'file name@'"@> + break; + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + if (name == NULL + || name->arg[c - '1'] == NULL) { + fputs(delimit_scrap[scrap_type][2], file); + fputc(c, file); + } + else { + fputs(delimit_scrap[scrap_type][1], file); + write_arg(file, name->arg[c - '1']); + fputs(delimit_scrap[scrap_type][0], file); + } + break; + default: + if (c==nw_char) + { + fputs(delimit_scrap[scrap_type][2], file); + break; + } + /* ignore these since pass1 will have warned about them */ + break; + } +}@} + +@d Copy version info into file +@{fputs(version_string, file); +@} + +@d Copy label from source into +@{{ + @<Get label from@(source_get()@)@> + write_label(label_name, @1); +}@} + + +There's no need to check for errors here, since we will have already +pointed out any during the first pass. +@d Skip over index entries +@{{ + do { + do + c = source_get(); + while (c != nw_char); + c = source_get(); + } while (c != '}' && c != ']' && c != ')' ); +}@} + +@d Skip commented-out code... +@{{ + do + c = source_get(); + while (c != '\n'); +}@} + +This scrap helps deal with bold keywords: + +@d Bold Keyword +@{{ + fputs(delimit_scrap[scrap_type][1],file); + fprintf(file, "\\hbox{\\sffamily\\bfseries "); + c = source_get(); + do { + fputc(c, file); + c = source_get(); + } while (c != nw_char); + c = source_get(); + fprintf(file, "}"); + fputs(delimit_scrap[scrap_type][0], file); +}@} + +@d Italic "@'whatever@'" +@{{ + fputs(delimit_scrap[scrap_type][1],file); + fprintf(file, "\\hbox{\\sffamily\\slshape @1}"); + fputs(delimit_scrap[scrap_type][0], file); +}@} + +@d Format macro name +@{{ + Arglist *args = collect_scrap_name(-1); + Name *name = args->name; + char * p = name->spelling; + Arglist *q = args->args; + int narg = 0; + + fputs(delimit_scrap[scrap_type][1],file); + if (prefix) + fputs("\\hbox{", file); + fputs("$\\langle\\,${\\itshape ", file); + while (*p != '\000') { + if (*p == ARG_CHR) { + if (q == NULL) { + write_literal(file, name->arg[narg], scrap_type); + } + else { + write_ArglistElement(file, q, params); + q = q->next; + } + p++; + narg++; + } + else + fputc(*p++, file); + } + fputs("}\\nobreak\\ ", file); + if (scrap_name_has_parameters) { + @<Format macro parameters@> + } + fprintf(file, "{\\footnotesize "); + if (name->defs) + @<Write abbreviated definition list@> + else { + putc('?', file); + fprintf(stderr, "%s: never defined <%s>\n", + command_name, name->spelling); + } + fputs("}$\\,\\rangle$", file); + if (prefix) + fputs("}", file); + fputs(delimit_scrap[scrap_type][0], file); +}@} + + +@d Write abbreviated definition list +@{{ + Scrap_Node *p = name->defs; + fputs("\\NWlink{nuweb", file); + write_single_scrap_ref(file, p->scrap); + fputs("}{", file); + write_single_scrap_ref(file, p->scrap); + fputs("}", file); + p = p->next; + if (p) + fputs(", \\ldots\\ ", file); +}@} + +@o latex.c -cc +@{static void +write_ArglistElement(FILE * file, Arglist * args, char ** params) +{ + Name *name = args->name; + Arglist *q = args->args; + + if (name == NULL) { + char * p = (char*)q; + + if (p[0] == ARG_CHR) { + write_arg(file, params[p[1] - '1']); + } else { + write_literal(file, (char *)q, 0); + } + } else if (name == (Name *)1) { + Scrap_Node * qq = (Scrap_Node *)q; + qq->quoted = TRUE; + fputs(delimit_scrap[scrap_type][0], file); + write_scraps(file, "", qq, + -1, "", 0, 0, 0, 0, + NULL, params, 0, ""); + fputs(delimit_scrap[scrap_type][1], file); + extra_scraps++; + qq->quoted = FALSE; + } else { + char * p = name->spelling; + fputs("$\\langle\\,${\\itshape ", file); + while (*p != '\000') { + if (*p == ARG_CHR) { + write_ArglistElement(file, q, params); + q = q->next; + p++; + } + else + fputc(*p++, file); + } + fputs("}\\nobreak\\ ", file); + if (scrap_name_has_parameters) { + int c; + + @<Format macro parameters@> + } + fprintf(file, "{\\footnotesize "); + if (name->defs) + @<Write abbreviated definition list@> + else { + putc('?', file); + fprintf(stderr, "%s: never defined <%s>\n", + command_name, name->spelling); + } + fputs("}$\\,\\rangle$", file); + } +} +@| write_ArglistElement @} + +\subsection{Generating the Indices} + +@d Write index of file names +@{{ + if (file_names) { + fputs("\n{\\small\\begin{list}{}{\\setlength{\\itemsep}{-\\parsep}", + tex_file); + fputs("\\setlength{\\itemindent}{-\\leftmargin}}\n", tex_file); + format_file_entry(file_names, tex_file); + fputs("\\end{list}}", tex_file); + } + c = source_get(); +}@} + +@o latex.c -cc +@{static void format_file_entry(name, tex_file) + Name *name; + FILE *tex_file; +{ + while (name) { + format_file_entry(name->llink, tex_file); + @<Format a file index entry@> + name = name->rlink; + } +} +@| format_file_entry @} + +@d Format a file index entry +@{fputs("\\item ", tex_file); +fprintf(tex_file, "\\verb%c\"%s\"%c ", nw_char, name->spelling, nw_char); +@<Write file's defining scrap numbers@> +putc('\n', tex_file);@} + +@d Write file's defining scrap numbers +@{{ + Scrap_Node *p = name->defs; + fputs("{\\footnotesize {\\NWtxtDefBy}", tex_file); + if (p->next) { + /* fputs("s ", tex_file); */ + putc(' ', tex_file); + print_scrap_numbers(tex_file, p); + } + else { + putc(' ', tex_file); + fputs("\\NWlink{nuweb", tex_file); + write_single_scrap_ref(tex_file, p->scrap); + fputs("}{", tex_file); + write_single_scrap_ref(tex_file, p->scrap); + fputs("}", tex_file); + putc('.', tex_file); + } + putc('}', tex_file); +}@} + +@d Write index of macro names +@{{ + unsigned char sector = current_sector; + int c = source_get(); + if (c == '+') + sector = 0; + else + source_ungetc(&c); + if (has_sector(macro_names, sector)) { + fputs("\n{\\small\\begin{list}{}{\\setlength{\\itemsep}{-\\parsep}", + tex_file); + fputs("\\setlength{\\itemindent}{-\\leftmargin}}\n", tex_file); + format_entry(macro_names, tex_file, sector); + fputs("\\end{list}}", tex_file); + } else { + fputs("None.\n", tex_file); + } +} +c = source_get(); +@} + +@o latex.c -cc +@{static int load_entry(Name * name, Name ** nms, int n) +{ + while (name) { + n = load_entry(name->llink, nms, n); + nms[n++] = name; + name = name->rlink; + } + return n; +} +@| load_entry @} + +@o latex.c -cc +@{static void format_entry(name, tex_file, sector) + Name *name; + FILE *tex_file; + unsigned char sector; +{ + Name ** nms = malloc(num_scraps()*sizeof(Name *)); + int n = load_entry(name, nms, 0); + int i; + + @<Sort @'nms@' of size @'n@' for @<Rob's ordering@>@> + for (i = 0; i < n; i++) + { + Name * name = nms[i]; + + @<Format an index entry@> + } +} +@| format_entry @} + +@d Rob's... +@{robs_strcmp(ki->spelling, kj->spelling) < 0@} + +@d Sort @'key@' of size @'n@' for @'ordering@' +@{int j; +for (j = 1; j < @2; j++) +{ + int i = j - 1; + Name * kj = @1[j]; + + do + { + Name * ki = @1[i]; + + if (@3) + break; + @1[i + 1] = ki; + i -= 1; + } while (i >= 0); + @1[i + 1] = kj; +} +@} + +@d Format an index entry +@{if (name->sector == sector){ + fputs("\\item ", tex_file); + fputs("$\\langle\\,$", tex_file); + @<Write the macro's name@> + fputs("\\nobreak\\ {\\footnotesize ", tex_file); + @<Write defining scrap numbers@> + fputs("}$\\,\\rangle$ ", tex_file); + @<Write referencing scrap numbers@> + putc('\n', tex_file); +}@} + +@d Write defining scrap numbers +@{{ + Scrap_Node *p = name->defs; + if (p) { + int page; + fputs("\\NWlink{nuweb", tex_file); + write_scrap_ref(tex_file, p->scrap, -1, &page); + fputs("}{", tex_file); + write_scrap_ref(tex_file, p->scrap, TRUE, &page); + fputs("}", tex_file); + p = p->next; + while (p) { + fputs("\\NWlink{nuweb", tex_file); + write_scrap_ref(tex_file, p->scrap, -1, &page); + fputs("}{", tex_file); + write_scrap_ref(tex_file, p->scrap, FALSE, &page); + fputs("}", tex_file); + p = p->next; + } + } + else + putc('?', tex_file); +}@} + +@d Write referencing scrap numbers +@{{ + Scrap_Node *p = name->uses; + fputs("{\\footnotesize ", tex_file); + if (p) { + fputs("{\\NWtxtRefIn}", tex_file); + if (p->next) { + /* fputs("s ", tex_file); */ + putc(' ', tex_file); + print_scrap_numbers(tex_file, p); + } + else { + putc(' ', tex_file); + fputs("\\NWlink{nuweb", tex_file); + write_single_scrap_ref(tex_file, p->scrap); + fputs("}{", tex_file); + write_single_scrap_ref(tex_file, p->scrap); + fputs("}", tex_file); + putc('.', tex_file); + } + } + else + fputs("{\\NWtxtNoRef}.", tex_file); + putc('}', tex_file); +}@} + +@d Function prototypes +@{extern int has_sector(Name *, unsigned char); +@} + +@o latex.c -cc +@{int has_sector(Name * name, unsigned char sector) +{ + while(name) { + if (name->sector == sector) + return TRUE; + if (has_sector(name->llink, sector)) + return TRUE; + name = name->rlink; + } + return FALSE; +} +@| has_sector @} + +@d Write index of user-specified names +@{{ + unsigned char sector = current_sector; + c = source_get(); + if (c == '+') { + sector = 0; + c = source_get(); + } + if (has_sector(user_names, sector)) { + fputs("\n{\\small\\begin{list}{}{\\setlength{\\itemsep}{-\\parsep}", + tex_file); + fputs("\\setlength{\\itemindent}{-\\leftmargin}}\n", tex_file); + format_user_entry(user_names, tex_file, sector); + fputs("\\end{list}}", tex_file); + } +}@} + + +@o latex.c -cc +@{static void format_user_entry(name, tex_file, sector) + Name *name; + FILE *tex_file; + unsigned char sector; +{ + while (name) { + format_user_entry(name->llink, tex_file, sector); + @<Format a user index entry@> + name = name->rlink; + } +} +@| format_user_entry @} + + +@D Format a user index entry +@{if (name->sector == sector){ + Scrap_Node *uses = name->uses; + if ( uses || dangling_flag ) { + int page; + Scrap_Node *defs = name->defs; + fprintf(tex_file, "\\item \\verb%c%s%c: ", nw_char,name->spelling,nw_char); + if (!uses) { + fputs("(\\underline{", tex_file); + fputs("\\NWlink{nuweb", tex_file); + write_single_scrap_ref(tex_file, defs->scrap); + fputs("}{", tex_file); + write_single_scrap_ref(tex_file, defs->scrap); + fputs("})}", tex_file); + page = -2; + defs = defs->next; + } + else + if (!defs || uses->scrap < defs->scrap) { + fputs("\\NWlink{nuweb", tex_file); + write_scrap_ref(tex_file, uses->scrap, -1, &page); + fputs("}{", tex_file); + write_scrap_ref(tex_file, uses->scrap, TRUE, &page); + fputs("}", tex_file); + uses = uses->next; + } + else { + if (defs->scrap == uses->scrap) + uses = uses->next; + fputs("\\underline{", tex_file); + + fputs("\\NWlink{nuweb", tex_file); + write_single_scrap_ref(tex_file, defs->scrap); + fputs("}{", tex_file); + write_single_scrap_ref(tex_file, defs->scrap); + fputs("}}", tex_file); + page = -2; + defs = defs->next; + } + while (uses || defs) { + if (uses && (!defs || uses->scrap < defs->scrap)) { + fputs("\\NWlink{nuweb", tex_file); + write_scrap_ref(tex_file, uses->scrap, -1, &page); + fputs("}{", tex_file); + write_scrap_ref(tex_file, uses->scrap, FALSE, &page); + fputs("}", tex_file); + uses = uses->next; + } + else { + if (uses && defs->scrap == uses->scrap) + uses = uses->next; + fputs(", \\underline{", tex_file); + + fputs("\\NWlink{nuweb", tex_file); + write_single_scrap_ref(tex_file, defs->scrap); + fputs("}{", tex_file); + write_single_scrap_ref(tex_file, defs->scrap); + fputs("}", tex_file); + + putc('}', tex_file); + page = -2; + defs = defs->next; + } + } + fputs(".\n", tex_file); + } +}@} + +\section{Writing the LaTeX File with HTML Scraps} \label{html-file} + +The HTML generated is patterned closely upon the {\LaTeX} generated in +the previous section.\footnote{\relax While writing this section, I +tried to follow Preston's style as displayed in +Section~\ref{latex-file}---J. D. R.} When a file name ends in +\verb|.hw|, the second pass (invoked via a call to \verb|write_html|) +copies most of the text from the source file straight into a +\verb|.tex| file. Definitions are formatted slightly and +cross-reference information is printed out. + +@d Function... +@{extern void write_html(); +@} + +We need a few local function declarations before we get into the body +of \verb|write_html|. + +@o html.c +@{static void copy_scrap(); /* formats the body of a scrap */ +static void display_scrap_ref(); /* formats a scrap reference */ +static void display_scrap_numbers(); /* formats a list of scrap numbers */ +static void print_scrap_numbers(); /* pluralizes scrap formats list */ +static void format_entry(); /* formats an index entry */ +static void format_user_entry(); +@} + + +The routine \verb|write_html| takes two file names as parameters: the +name of the web source file and the name of the \verb|.tex| output file. +@o html.c +@{void write_html(file_name, html_name) + char *file_name; + char *html_name; +{ + FILE *html_file = fopen(html_name, "w"); + FILE *tex_file = html_file; + @<Write LaTeX limbo definitions@> + if (html_file) { + if (verbose_flag) + fprintf(stderr, "writing %s\n", html_name); + source_open(file_name); + @<Copy \verb|source_file| into \verb|html_file|@> + fclose(html_file); + } + else + fprintf(stderr, "%s: can't open %s\n", command_name, html_name); +} +@| write_html @} + + +We make our second (and final) pass through the source web, this time +copying characters straight into the \verb|.tex| file. However, we keep +an eye peeled for \verb|@@|~characters, which signal a command sequence. + +@d Copy \verb|source_file| into \verb|html_file| +@{{ + int c = source_get(); + while (c != EOF) { + if (c == nw_char) + @<Interpret HTML at-sequence@> + else { + putc(c, html_file); + c = source_get(); + } + } +}@} + +@d Interpret HTML at-sequence +@{{ + c = source_get(); + switch (c) { + case 'r': + c = source_get(); + nw_char = c; + update_delimit_scrap(); + break; + case 'O': + case 'o': @<Write HTML output file definition@> + break; + case 'Q': + case 'q': + case 'D': + case 'd': @<Write HTML macro definition@> + break; + case 'f': @<Write HTML index of file names@> + break; + case 'm': @<Write HTML index of macro names@> + break; + case 'u': @<Write HTML index of user-specified names@> + break; + default: + if (c==nw_char) + putc(c, html_file); + c = source_get(); + break; + } +}@} + + +\subsection{Formatting Definitions} + +We go through only a little amount of effort to format a definition. +The HTML for the previous fragment definition should look like this +(perhaps modulo the scrap references): + +\begin{verbatim} +<pre> +<a name="nuweb68"><Interpret HTML at-sequence 68></a> = +{ + c = source_get(); + switch (c) { + case 'O': + case 'o': <Write HTML output file definition <a href="#nuweb69">69</a>> + break; + case 'D': + case 'd': <Write HTML macro definition <a href="#nuweb71">71</a>> + break; + case 'f': <Write HTML index of file names <a href="#nuweb86">86</a>> + break; + case 'm': <Write HTML index of macro names <a href="#nuweb87">87</a>> + break; + case 'u': <Write HTML index of user-specified names <a href="#nuweb93">93</a>> + break; + default: + if (c==nw_char) + putc(c, html_file); + c = source_get(); + break; + } +}<></pre> +Fragment referenced in scrap <a href="#nuweb67">67</a>. +<br> +\end{verbatim} + +Fragment and file definitions are formatted nearly identically. +I've factored the common parts out into separate scraps. + +@d Write HTML output file definition +@{{ + Name *name = collect_file_name(); + @<Begin HTML scrap environment@> + @<Write HTML output file declaration@> + scraps++; + @<Fill in the middle of HTML scrap environment@> + @<Write HTML file defs@> + @<Finish HTML scrap environment@> +}@} + +@d Write HTML output file declaration +@{ fputs("<a name=\"nuweb", html_file); + write_single_scrap_ref(html_file, scraps); + fprintf(html_file, "\"><code>\"%s\"</code> ", name->spelling); + write_single_scrap_ref(html_file, scraps); + fputs("</a> =\n", html_file); +@} + +@d Write HTML macro definition +@{{ + Name *name = collect_macro_name(); + @<Begin HTML scrap environment@> + @<Write HTML macro declaration@> + scraps++; + @<Fill in the middle of HTML scrap environment@> + @<Write HTML macro defs@> + @<Write HTML macro refs@> + @<Finish HTML scrap environment@> +}@} + +I don't format a fragment name at all specially, figuring the programmer +might want to use italics or bold face in the midst of the name. Note +that in this implementation, programmers may only use directives in +fragment names that are recognized in preformatted text elements (PRE). + +Modification 2001--02--15.: I'm interpreting the fragment name +as regular LaTex, so that any formatting can be used in it. To use +HTML formatting, the \verb|rawhtml| environment should be used. + +@d Write HTML macro declaration +@{ fputs("<a name=\"nuweb", html_file); + write_single_scrap_ref(html_file, scraps); + fputs("\"><\\end{rawhtml}", html_file); + fputs(name->spelling, html_file); + fputs("\\begin{rawhtml} ", html_file); + write_single_scrap_ref(html_file, scraps); + fputs("></a> =\n", html_file); +@} + +@d Begin HTML scrap environment +@{{ + fputs("\\begin{rawhtml}\n", html_file); + fputs("<pre>\n", html_file); +}@} + +The end of a scrap is marked with the characters \verb|<>|. +@d Fill in the middle of HTML scrap environment +@{{ + copy_scrap(html_file, TRUE); + fputs("<></pre>\n", html_file); +}@} + +The only task remaining is to get rid of the current at command and +end the paragraph. + +@d Finish HTML scrap environment +@{{ + fputs("\\end{rawhtml}\n", html_file); + c = source_get(); /* Get rid of current at command. */ +}@} + + +\subsubsection{Formatting Cross References} + +@d Write HTML file defs +@{{ + if (name->defs->next) { + fputs("\\end{rawhtml}\\NWtxtFileDefBy\\begin{rawhtml} ", html_file); + print_scrap_numbers(html_file, name->defs); + fputs("<br>\n", html_file); + } +}@} + +@d Write HTML macro defs +@{{ + if (name->defs->next) { + fputs("\\end{rawhtml}\\NWtxtMacroDefBy\\begin{rawhtml} ", html_file); + print_scrap_numbers(html_file, name->defs); + fputs("<br>\n", html_file); + } +}@} + +@d Write HTML macro refs +@{{ + if (name->uses) { + fputs("\\end{rawhtml}\\NWtxtMacroRefIn\\begin{rawhtml} ", html_file); + print_scrap_numbers(html_file, name->uses); + } + else { + fputs("\\end{rawhtml}{\\NWtxtMacroNoRef}.\\begin{rawhtml}", html_file); + fprintf(stderr, "%s: <%s> never referenced.\n", + command_name, name->spelling); + } + fputs("<br>\n", html_file); +}@} + +@o html.c +@{static void display_scrap_ref(html_file, num) + FILE *html_file; + int num; +{ + fputs("<a href=\"#nuweb", html_file); + write_single_scrap_ref(html_file, num); + fputs("\">", html_file); + write_single_scrap_ref(html_file, num); + fputs("</a>", html_file); +} +@| display_scrap_ref @} + +@o html.c +@{static void display_scrap_numbers(html_file, scraps) + FILE *html_file; + Scrap_Node *scraps; +{ + display_scrap_ref(html_file, scraps->scrap); + scraps = scraps->next; + while (scraps) { + fputs(", ", html_file); + display_scrap_ref(html_file, scraps->scrap); + scraps = scraps->next; + } +} +@| display_scrap_numbers @} + +@o html.c +@{static void print_scrap_numbers(html_file, scraps) + FILE *html_file; + Scrap_Node *scraps; +{ + display_scrap_numbers(html_file, scraps); + fputs(".\n", html_file); +} +@| print_scrap_numbers @} + + +\subsubsection{Formatting a Scrap} + +We must translate HTML special keywords into entities in scraps. + +@o html.c +@{static void copy_scrap(file, prefix) + FILE *file; + int prefix; +{ + int indent = 0; + int c = source_get(); + while (1) { + switch (c) { + case '<' : fputs("<", file); + indent++; + break; + case '>' : fputs(">", file); + indent++; + break; + case '&' : fputs("&", file); + indent++; + break; + case '\n': fputc(c, file); + indent = 0; + break; + case '\t': @<Expand tab into spaces@> + break; + default: + if (c==nw_char) + { + @<Check HTML at-sequence for end-of-scrap@> + break; + } + putc(c, file); + indent++; + break; + } + c = source_get(); + } +} +@| copy_scrap @} + +@d Check HTML at-sequence... +@{{ + c = source_get(); + switch (c) { + case '+': + case '-': + case '*': + case '|': @<Skip over index entries@> + case ',': + case '}': + case ']': + case ')': return; + case '_': @<Write HTML bold tag or end@> + break; + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + fputc(nw_char, file); + fputc(c, file); + break; + case '<': @<Format HTML macro name@> + break; + case '%': @<Skip commented-out code@> + break; + default: + if (c==nw_char) + { + fputc(c, file); + break; + } + /* ignore these since pass1 will have warned about them */ + break; + } +}@} + +There's no need to check for errors here, since we will have already +pointed out any during the first pass. + +@d Format HTML macro name +@{{ + Arglist * args = collect_scrap_name(-1); + Name *name = args->name; + fputs("<\\end{rawhtml}", file); + fputs(name->spelling, file); + if (scrap_name_has_parameters) { + @<Format HTML macro parameters@> + } + fputs("\\begin{rawhtml} ", file); + if (name->defs) + @<Write HTML abbreviated definition list@> + else { + putc('?', file); + fprintf(stderr, "%s: never defined <%s>\n", + command_name, name->spelling); + } + fputs(">", file); +}@} + + +@d Write HTML abbreviated definition list +@{{ + Scrap_Node *p = name->defs; + display_scrap_ref(file, p->scrap); + if (p->next) + fputs(", ... ", file); +}@} + + +\subsection{Generating the Indices} + +@d Write HTML index of file names +@{{ + if (file_names) { + fputs("\\begin{rawhtml}\n", html_file); + fputs("<dl compact>\n", html_file); + format_entry(file_names, html_file, TRUE); + fputs("</dl>\n", html_file); + fputs("\\end{rawhtml}\n", html_file); + } + c = source_get(); +}@} + + +@d Write HTML index of macro names +@{{ + if (macro_names) { + fputs("\\begin{rawhtml}\n", html_file); + fputs("<dl compact>\n", html_file); + format_entry(macro_names, html_file, FALSE); + fputs("</dl>\n", html_file); + fputs("\\end{rawhtml}\n", html_file); + } + c = source_get(); +}@} + + +@d Write HTML bold tag or end +@{{ + static int toggle; + toggle = ~toggle; + if( toggle ) { + fputs( "<b>", file ); + } else { + fputs( "</b>", file ); + } +}@} + +@o html.c +@{static void format_entry(name, html_file, file_flag) + Name *name; + FILE *html_file; + int file_flag; +{ + while (name) { + format_entry(name->llink, html_file, file_flag); + @<Format an HTML index entry@> + name = name->rlink; + } +} +@| format_entry @} + +@d Format an HTML index entry +@{{ + fputs("<dt> ", html_file); + if (file_flag) { + fprintf(html_file, "<code>\"%s\"</code>\n<dd> ", name->spelling); + @<Write HTML file's defining scrap numbers@> + } + else { + fputs("<\\end{rawhtml}", html_file); + fputs(name->spelling, html_file); + fputs("\\begin{rawhtml} ", html_file); + @<Write HTML defining scrap numbers@> + fputs(">\n<dd> ", html_file); + @<Write HTML referencing scrap numbers@> + } + putc('\n', html_file); +}@} + + +@d Write HTML file's defining scrap numbers +@{{ + fputs("\\end{rawhtml}\\NWtxtDefBy\\begin{rawhtml} ", html_file); + print_scrap_numbers(html_file, name->defs); +}@} + +@d Write HTML defining scrap numbers +@{{ + if (name->defs) + display_scrap_numbers(html_file, name->defs); + else + putc('?', html_file); +}@} + +@d Write HTML referencing scrap numbers +@{{ + Scrap_Node *p = name->uses; + if (p) { + fputs("\\end{rawhtml}\\NWtxtRefIn\\begin{rawhtml} ", html_file); + print_scrap_numbers(html_file, p); + } + else + fputs("\\end{rawhtml}{\\NWtxtNoRef}.\\begin{rawhtml}", html_file); +}@} + + +@d Write HTML index of user-specified names +@{{ + if (user_names) { + fputs("\\begin{rawhtml}\n", html_file); + fputs("<dl compact>\n", html_file); + format_user_entry(user_names, html_file, 0/* Dummy */); + fputs("</dl>\n", html_file); + fputs("\\end{rawhtml}\n", html_file); + } + c = source_get(); +}@} + + +@o html.c +@{static void format_user_entry(name, html_file, sector) + Name *name; + FILE *html_file; + int sector; +{ + while (name) { + format_user_entry(name->llink, html_file, sector); + @<Format a user HTML index entry@> + name = name->rlink; + } +} +@| format_user_entry @} + + +@d Format a user HTML index entry +@{{ + Scrap_Node *uses = name->uses; + if (uses) { + Scrap_Node *defs = name->defs; + fprintf(html_file, "<dt><code>%s</code>:\n<dd> ", name->spelling); + if (uses->scrap < defs->scrap) { + display_scrap_ref(html_file, uses->scrap); + uses = uses->next; + } + else { + if (defs->scrap == uses->scrap) + uses = uses->next; + fputs("<strong>", html_file); + display_scrap_ref(html_file, defs->scrap); + fputs("</strong>", html_file); + defs = defs->next; + } + while (uses || defs) { + fputs(", ", html_file); + if (uses && (!defs || uses->scrap < defs->scrap)) { + display_scrap_ref(html_file, uses->scrap); + uses = uses->next; + } + else { + if (uses && defs->scrap == uses->scrap) + uses = uses->next; + fputs("<strong>", html_file); + display_scrap_ref(html_file, defs->scrap); + fputs("</strong>", html_file); + defs = defs->next; + } + } + fputs(".\n", html_file); + } +}@} + +\section{Writing the Output Files} \label{output-files} + +@d Function pro... +@{extern void write_files(); +@} + +@o output.c -cc +@{void write_files(files) + Name *files; +{ + while (files) { + write_files(files->llink); + @<Write out \verb|files->spelling|@> + files = files->rlink; + } +} +@| write_files @} + +\verb|MAX_INDENT| defines the maximum number of leading whitespace + characters. This is only a problem when outputting very long lines, + possibly by multiple definitions of the same fragment (as in a list + of elements which is added to every time a new element is defined). + +@d Type dec... +@{ +#define MAX_INDENT 500 +@| MAX_INDENT @} + +@d Write out \verb|files->spelling| +@{{ + static char temp_name[FILENAME_MAX]; + static char real_name[FILENAME_MAX]; + static int temp_name_count = 0; + char indent_chars[MAX_INDENT]; + FILE *temp_file; + + @< Find a free temporary file @> + + sprintf(real_name, "%s%s%s", dirpath, path_sep, files->spelling); + if (verbose_flag) + fprintf(stderr, "writing %s [%s]\n", files->spelling, temp_name); + write_scraps(temp_file, files->spelling, files->defs, 0, indent_chars, + files->debug_flag, files->tab_flag, files->indent_flag, + files->comment_flag, NULL, NULL, 0, files->spelling); + fclose(temp_file); + + @< Move the temporary file to the target, if required @> +}@} + +@d Find a free temporary file @{@% +for( temp_name_count = 0; temp_name_count < 10000; temp_name_count++) { + sprintf(temp_name,"%s%snw%06d", dirpath, path_sep, temp_name_count); +#ifdef O_EXCL + if (-1 != (temp_file_fd = open(temp_name, O_CREAT|O_WRONLY|O_EXCL))) { + temp_file = fdopen(temp_file_fd, "w"); + break; + } +#else + if (0 != (temp_file = fopen(temp_name, "a"))) { + if ( 0L == ftell(temp_file)) { + break; + } else { + fclose(temp_file); + temp_file = 0; + } + } +#endif +} +if (!temp_file) { + fprintf(stderr, "%s: can't create %s for a temporary file\n", + command_name, temp_name); + exit(-1); +} +@} + +Note the call to \verb|remove| before \verb|rename| -- the ANSI/ISO C +standard does {\em not} guarantee that renaming a file to an existing +filename will overwrite the file. + +@d Move the temporary file to the target, if required @{@% +if (compare_flag) + @<Compare the temp file and the old file@> +else { + remove(real_name); + @< Rename the temporary file to the target @> +} +@} + +Again, we use a call to \verb|remove| before \verb|rename|. +@d Compare the temp file... +@{{ + FILE *old_file = fopen(real_name, "r"); + if (old_file) { + int x, y; + temp_file = fopen(temp_name, "r"); + do { + x = getc(old_file); + y = getc(temp_file); + } while (x == y && x != EOF); + fclose(old_file); + fclose(temp_file); + if (x == y) + remove(temp_name); + else { + remove(real_name); + @< Rename the temporary file to the target @> + } + } + else + @< Rename the temporary file to the target @> +}@} + +@d Rename the temporary file to the target @{@% +if (0 != rename(temp_name, real_name)) { + fprintf(stderr, "%s: can't rename output file to %s\n", + command_name, real_name); +} +@|@} + + + +\chapter{The Support Routines} + +\section{Source Files} \label{source-files} + +\subsection{Global Declarations} + +We need two routines to handle reading the source files. +@d Function pro... +@{extern void source_open(); /* pass in the name of the source file */ +extern int source_get(); /* no args; returns the next char or EOF */ +extern int source_last; /* what last source_get() returned. */ +extern int source_peek; /* The next character to get */ +@} + + +There are also two global variables maintained for use in error +messages and such. +@d Global variable dec... +@{extern char *source_name; /* name of the current file */ +extern int source_line; /* current line in the source file */ +@| source_name source_line @} + +@d Global variable def... +@{char *source_name = NULL; +int source_line = 0; +@} + +\subsection{Local Declarations} + + +@o input.c -cc +@{static FILE *source_file; /* the current input file */ +static int double_at; +static int include_depth; +@| source_file double_at include_depth @} + + +@o input.c -cc +@{static struct { + FILE *file; + char *name; + int line; +} stack[10]; +@| stack @} + + +\subsection{Reading a File} + +The routine \verb|source_get| returns the next character from the +current source file. It notices newlines and keeps the line counter +\verb|source_line| up to date. It also catches \verb|EOF| and watches +for \verb|@@|~characters. All other characters are immediately returned. +We define \verb|source_last| to let us tell which type of scrap we +are defining. +@o input.c -cc +@{ +int source_peek; +int source_last; +int source_get() +{ + int c; + source_last = c = source_peek; + switch (c) { + case EOF: @<Handle \verb|EOF|@> + return c; + case '\n': source_line++; + default: + if (c==nw_char) + { + @<Handle an ``at'' character@> + return c; + } + source_peek = getc(source_file); + return c; + } +} +@| source_peek source_get source_last @} + +\verb|source_ungetc| pushes a read character back to the \verb|source_file|. + +@d Function prototypes +@{extern void source_ungetc(int*); +@} + + +@o input.c -cc +@{void source_ungetc(int *c) +{ + ungetc(source_peek, source_file); + if(*c == '\n') + source_line--; + source_peek=*c; +} +@|source_ungetc @} + +This whole \verb|@@|~character handling mess is pretty annoying. +I want to recognize \verb|@@i| so I can handle include files correctly. +At the same time, it makes sense to recognize illegal \verb|@@|~sequences +and complain; this avoids ever having to check anywhere else. +Unfortunately, I need to avoid tripping over the \verb|@@@@|~sequence; +hence this whole unsatisfactory \verb|double_at| business. +@d Handle an ``at''... +@{{ + c = getc(source_file); + if (double_at) { + source_peek = c; + double_at = FALSE; + c = nw_char; + } + else + switch (c) { + case 'i': @<Open an include file@> + break; + case '#': case 'f': case 'm': case 'u': case 'v': + case 'd': case 'o': case 'D': case 'O': case 's': + case 'q': case 'Q': case 'S': case 't': + case '+': + case '-': + case '*': + case '\'': + case '{': case '}': case '<': case '>': case '|': + case '(': case ')': case '[': case ']': + case '%': case '_': + case ':': case ',': case 'x': case 'c': + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + case 'r': + source_peek = c; + c = nw_char; + break; + default: + if (c==nw_char) + { + source_peek = c; + double_at = TRUE; + break; + } + fprintf(stderr, "%s: bad %c sequence %c[%d] (%s, line %d)\n", + command_name, nw_char, c, c, source_name, source_line); + exit(-1); + } +}@} + +@d Open an include file +@{{ + char name[FILENAME_MAX]; + char fullname[FILENAME_MAX]; + struct incl * p = include_list; + + if (include_depth >= 10) { + fprintf(stderr, "%s: include nesting too deep (%s, %d)\n", + command_name, source_name, source_line); + exit(-1); + } + @<Collect include-file name@> + stack[include_depth].file = source_file; + fullname[0] = '\0'; + for (;;) { + strcat(fullname, name); + source_file = fopen(fullname, "r"); + if (source_file || !p) + break; + strcpy(fullname, p->name); + strcat(fullname, "/"); + p = p->next; + } + if (!source_file) { + fprintf(stderr, "%s: can't open include file %s\n", + command_name, name); + source_file = stack[include_depth].file; + } + else + { + stack[include_depth].name = source_name; + stack[include_depth].line = source_line + 1; + include_depth++; + source_line = 1; + source_name = save_string(fullname); + } + source_peek = getc(source_file); + c = source_get(); +}@} + +@d Collect include-file name +@{{ + char *p = name; + do + c = getc(source_file); + while (c == ' ' || c == '\t'); + while (isgraph(c)) { + *p++ = c; + c = getc(source_file); + } + *p = '\0'; + if (c != '\n') { + fprintf(stderr, "%s: unexpected characters after file name (%s, %d)\n", + command_name, source_name, source_line); + exit(-1); + } +}@} + +If an \verb|EOF| is discovered, the current file must be closed and +input from the next stacked file must be resumed. If no more files are +on the stack, the \verb|EOF| is returned. +@d Handle \verb|EOF| +@{{ + fclose(source_file); + if (include_depth) { + include_depth--; + source_file = stack[include_depth].file; + source_line = stack[include_depth].line; + source_name = stack[include_depth].name; + source_peek = getc(source_file); + c = source_get(); + } +}@} + + +\subsection{Opening a File} + +The routine \verb|source_open| takes a file name and tries to open the +file. If unsuccessful, it complains and halts. Otherwise, it sets +\verb|source_name|, \verb|source_line|, and \verb|double_at|. +@o input.c -cc +@{void source_open(name) + char *name; +{ + source_file = fopen(name, "r"); + if (!source_file) { + fprintf(stderr, "%s: couldn't open %s\n", command_name, name); + exit(-1); + } + nw_char = '@@'; + source_name = name; + source_line = 1; + source_peek = getc(source_file); + double_at = FALSE; + include_depth = 0; +} +@| source_open @} + + + + +\section{Scraps} \label{scraps} + + +@o scraps.c -cc +@{#define SLAB_SIZE 1024 + +typedef struct slab { + struct slab *next; + char chars[SLAB_SIZE]; +} Slab; +@| Slab next SLAB_SIZE @} + +@o scraps.c -cc +@{typedef struct { + char *file_name; + Slab *slab; + struct uses *uses; + struct uses *defs; + int file_line; + int page; + char letter; + unsigned char sector; +} ScrapEntry; +@| file_name slab uses defs file_line page letter sector ScrapEntry @} + +There's some issue with reading the auxiliary file if it has more than 255 lines, so (as a workround only) increase the size of the array of \verb|ScrapEntry|s held in \verb|SCRAP[n]|. + +@o scraps.c -cc +@{ +#define SCRAP_BITS 10 +#define SCRAP_SIZE (1<<SCRAP_BITS) +#define SCRAP_MASK (SCRAP_SIZE - 1) +#define SCRAP_SHIFT SCRAP_BITS +static ScrapEntry *SCRAP[SCRAP_SIZE]; + +#define scrap_array(i) SCRAP[(i) >> SCRAP_SHIFT][(i) & SCRAP_MASK] + +static int scraps; +int num_scraps() +{ + return scraps; +}; +@<Forward declarations for scraps.c@> +@| num_scraps scraps scrap_array SCRAP_BITS SCRAP_SIZE SCRAP_MASK SCRAP_SHIFT SCRAP @} + + +@d Function pro... +@{extern void init_scraps(); +extern int collect_scrap(); +extern int write_scraps(); +extern void write_scrap_ref(); +extern void write_single_scrap_ref(); +extern int num_scraps(); +@} + + +@o scraps.c -cc +@{void init_scraps() +{ + scraps = 1; + SCRAP[0] = (ScrapEntry *) arena_getmem(SCRAP_SIZE * sizeof(ScrapEntry)); +} +@| init_scraps @} + +@o scraps.c -cc +@{void write_scrap_ref(file, num, first, page) + FILE *file; + int num; + int first; + int *page; +{ + if (scrap_array(num).page >= 0) { + if (first!=0) + fprintf(file, "%d", scrap_array(num).page); + else if (scrap_array(num).page != *page) + fprintf(file, ", %d", scrap_array(num).page); + if (scrap_array(num).letter > 0) + fputc(scrap_array(num).letter, file); + } + else { + if (first!=0) + putc('?', file); + else + fputs(", ?", file); + @<Warn (only once) about needing to rerun after Latex@> + } + if (first>=0) + *page = scrap_array(num).page; +} +@| write_scrap_ref @} + +@o scraps.c -cc +@{void write_single_scrap_ref(file, num) + FILE *file; + int num; +{ + int page; + write_scrap_ref(file, num, TRUE, &page); +} +@| write_single_scrap_ref @} + + +@d Warn (only once) about needing to... +@{{ + if (!already_warned) { + fprintf(stderr, "%s: you'll need to rerun nuweb after running latex\n", + command_name); + already_warned = TRUE; + } +}@} + +@d Global variable dec... +@{extern int already_warned; +@| already_warned @} + +@d Global variable def... +@{int already_warned = 0; +@} + +@o scraps.c -cc +@{typedef struct { + Slab *scrap; + Slab *prev; + int index; +} Manager; +@| Manager @} + + + +@o scraps.c -cc +@{static void push(c, manager) + char c; + Manager *manager; +{ + Slab *scrap = manager->scrap; + int index = manager->index; + scrap->chars[index++] = c; + if (index == SLAB_SIZE) { + Slab *new = (Slab *) arena_getmem(sizeof(Slab)); + scrap->next = new; + manager->scrap = new; + index = 0; + } + manager->index = index; +} +@| push @} + +@o scraps.c -cc +@{static void pushs(s, manager) + char *s; + Manager *manager; +{ + while (*s) + push(*s++, manager); +} +@| pushs @} + +@o scraps.c -cc +@{int collect_scrap() +{ + int current_scrap, lblseq = 0; + int depth = 1; + Manager writer; + @<Create new scrap...@> + @<Accumulate scrap and return \verb|scraps++|@> +} +@| collect_scrap @} + +@d Create new scrap, managed by \verb|writer| +@{{ + Slab *scrap = (Slab *) arena_getmem(sizeof(Slab)); + if ((scraps & SCRAP_MASK) == 0) + SCRAP[scraps >> SCRAP_SHIFT] = (ScrapEntry *) arena_getmem(SCRAP_SIZE * sizeof(ScrapEntry)); + scrap_array(scraps).slab = scrap; + scrap_array(scraps).file_name = save_string(source_name); + scrap_array(scraps).file_line = source_line; + scrap_array(scraps).page = -1; + scrap_array(scraps).letter = 0; + scrap_array(scraps).uses = NULL; + scrap_array(scraps).defs = NULL; + scrap_array(scraps).sector = current_sector; + writer.scrap = scrap; + writer.index = 0; + current_scrap = scraps++; +}@} + + +@d Accumulate scrap... +@{{ + int c = source_get(); + while (1) { + switch (c) { + case EOF: fprintf(stderr, "%s: unexpect EOF in (%s, %d)\n", + command_name, scrap_array(current_scrap).file_name, + scrap_array(current_scrap).file_line); + exit(-1); + default: + if (c==nw_char) + { + @<Handle at-sign during scrap accumulation@> + break; + } + push(c, &writer); + c = source_get(); + break; + } + } +}@} + +@d Handle at-sign during scrap accumulation +@{{ + c = source_get(); + switch (c) { + case '(': + case '[': + case '{': depth++; + break; + case '+': + case '-': + case '*': + case '|': @<Collect user-specified index entries@> + /* Fall through */ + case ')': + case ']': + case '}': if (--depth > 0) + break; + /* else fall through */ + case ',': + push('\0', &writer); + scrap_ended_with = c; + return current_scrap; + case '<': @<Handle macro invocation in scrap@> + break; + case '%': @<Skip commented-out code@> + /* emit line break to the output file to keep #line in sync. */ + push('\n', &writer); + c = source_get(); + break; + case 'x': @<Get label while collecting scrap@> + break; + case 'c': @<Include block comment in a scrap@> + break; + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + case 'f': case '#': case 'v': + case 't': case 's': + push(nw_char, &writer); + break; + case '_': c = source_get(); + break; + default : + if (c==nw_char) + { + push(nw_char, &writer); + push(nw_char, &writer); + c = source_get(); + break; + } + fprintf(stderr, "%s: unexpected %c%c in scrap (%s, %d)\n", + command_name, nw_char, c, source_name, source_line); + exit(-1); + } +}@} + +@d Get label while collecting scrap +@{{ + @<Get label from@(source_get()@)@> + @<Save label to label store@> + push(nw_char, &writer); + push('x', &writer); + pushs(label_name, &writer); + push(nw_char, &writer); +}@} + + +@d Collect user-specified index entries +@{{ + do { + int type = c; + do { + char new_name[MAX_NAME_LEN]; + char *p = new_name; + unsigned int sector = 0; + do + c = source_get(); + while (isspace(c)); + if (c != nw_char) { + Name *name; + do { + *p++ = c; + c = source_get(); + } while (c != nw_char && !isspace(c)); + *p = '\0'; + switch (type) { + case '*': + sector = current_sector; + @<Add user identifier use@> + break; + case '-': + @<Add user identifier use@> + /* Fall through */ + case '|': + sector = current_sector; + /* Fall through */ + case '+': + @<Add user identifier definition@> + break; + } + } + } while (c != nw_char); + c = source_get(); + }while (c == '|' || c == '*' || c == '-' || c == '+'); + if (c != '}' && c != ']' && c != ')') { + fprintf(stderr, "%s: unexpected %c%c in index entry (%s, %d)\n", + command_name, nw_char, c, source_name, source_line); + exit(-1); + } +}@} + +@d Add user identifier use +@{name = name_add(&user_names, new_name, sector); +if (!name->uses || name->uses->scrap != current_scrap) { + Scrap_Node *use = (Scrap_Node *) arena_getmem(sizeof(Scrap_Node)); + use->scrap = current_scrap; + use->next = name->uses; + name->uses = use; + add_uses(&(scrap_array(current_scrap).uses), name); +}@} + +@d Add user identifier definition +@{name = name_add(&user_names, new_name, sector); +if (!name->defs || name->defs->scrap != current_scrap) { + Scrap_Node *def = (Scrap_Node *) arena_getmem(sizeof(Scrap_Node)); + def->scrap = current_scrap; + def->next = name->defs; + name->defs = def; + add_uses(&(scrap_array(current_scrap).defs), name); +}@} + +@d Handle macro invocation in scrap +@{{ + Arglist * args = collect_scrap_name(current_scrap); + Name *name = args->name; + @<Save macro name@> + add_to_use(name, current_scrap); + if (scrap_name_has_parameters) { + @<Save macro parameters @> + } + push(nw_char, &writer); + push('>', &writer); + c = source_get(); +}@} + + +@d Save macro name +@{{ + char buff[24]; + + push(nw_char, &writer); + push('<', &writer); + push(name->sector, &writer); + sprintf(buff, "%p", args); + pushs(buff, &writer); +}@} + +@o scraps.c -cc +@{void +add_to_use(Name * name, int current_scrap) +{ + if (!name->uses || name->uses->scrap != current_scrap) { + Scrap_Node *use = (Scrap_Node *) arena_getmem(sizeof(Scrap_Node)); + use->scrap = current_scrap; + use->next = name->uses; + name->uses = use; + } +} +@| add_to_use @} + +@d Function... +@{extern void add_to_use(Name * name, int current_scrap); +@} +@o scraps.c -cc +@{static char pop(manager) + Manager *manager; +{ + Slab *scrap = manager->scrap; + int index = manager->index; + char c = scrap->chars[index++]; + if (index == SLAB_SIZE) { + manager->prev = scrap; + manager->scrap = scrap->next; + index = 0; + } + manager->index = index; + return c; +} +@| pop @} + +@o scraps.c -cc +@{static void backup(n, manager) + int n; + Manager *manager; +{ + int index = manager->index; + if (n > index + && manager->prev != NULL) + { + manager->scrap = manager->prev; + manager->prev = NULL; + index += SLAB_SIZE; + } + manager->index = (n <= index ? index - n : 0); +} +@| backup @} + +@o scraps.c -cc +@{void +lookup(int n, Arglist * par, char * arg[9], Name **name, Arglist ** args) +{ + int i; + Arglist * p = par; + + for (i = 0; i < n && p != NULL; i++) + p = p->next; + if (p == NULL) { + char * a = arg[n]; + + *name = NULL; + *args = (Arglist *)a; + } + else { + *name = p->name; + *args = p->args; + } +} +@| lookup @} + +@o scraps.c -cc +@{Arglist * instance(Arglist * a, Arglist * par, char * arg[9], int * ch) +{ + if (a != NULL) { + int changed = 0; + Arglist *args, *next; + Name* name; + @<Set up name, args and next@> + if (changed){ + @<Build a new arglist@> + *ch = 1; + } + } + + return a; +} +@| instance @} + +@d Function prototypes +@{Arglist * instance(); +@} + +@d Set up name, args and next +@{next = instance(a->next, par, arg, &changed); +name = a->name; +if (name == (Name *)1) { + Embed_Node * q = (Embed_Node *)arena_getmem(sizeof(Embed_Node)); + q->defs = (Scrap_Node *)a->args; + q->args = par; + args = (Arglist *)q; + changed = 1; +} else if (name != NULL) + args = instance(a->args, par, arg, &changed); +else { + char * p = (char *)a->args; + if (p[0] == ARG_CHR) { + lookup(p[1] - '1', par, arg, &name, &args); + changed = 1; + } + else { + args = a->args; + } +}@} + +@d Build a new arglist +@{a = (Arglist *)arena_getmem(sizeof(Arglist)); +a->name = name; +a->args = args; +a->next = next;@} + +@o scraps.c -cc +@{static Arglist *pop_scrap_name(manager, parameters) + Manager *manager; + Parameters *parameters; +{ + char name[MAX_NAME_LEN]; + char *p = name; + Arglist * args; + int c; + + (void)pop(manager); /* not sure why we have to pop twice */ + c = pop(manager); + + while (c != nw_char) { + *p++ = c; + c = pop(manager); + } + *p = '\000'; + if (sscanf(name, "%p", &args) != 1) + { + fprintf(stderr, "%s: found an internal problem (2)\n", command_name); + exit(-1); + } + @<Check for end of scrap name@> + return args; +} +@| pop_scrap_name @} + + +@d Check for end of scrap name +@{{ + c = pop(manager); + @<Check for macro parameters@> +}@} + +@o scraps.c -cc +@{int write_scraps(file, spelling, defs, global_indent, indent_chars, + debug_flag, tab_flag, indent_flag, + comment_flag, inArgs, inParams, parameters, title) + FILE *file; + char * spelling; + Scrap_Node *defs; + int global_indent; + char *indent_chars; + char debug_flag; + char tab_flag; + char indent_flag; + unsigned char comment_flag; + Arglist * inArgs; + char * inParams[9]; + Parameters parameters; + char * title; +{ + /* This is in file @f */ + int indent = 0; + int newline = 1; + while (defs) { + @<Copy \verb|defs->scrap| to \verb|file|@> + defs = defs->next; + } + return indent + global_indent; +} +@| write_scraps @} + +@d Forward declarations for scraps.c +@{int delayed_indent = 0; +@| delayed_indent @} + +@d Copy \verb|defs->scrap... +@{{ + char c; + Manager reader; + Parameters local_parameters = 0; + int line_number = scrap_array(defs->scrap).file_line; + reader.scrap = scrap_array(defs->scrap).slab; + reader.index = 0; + @<Insert debugging information if required@> + if (delayed_indent) + { + @<Insert appropriate indentation@> + } + c = pop(&reader); + while (c) { + switch (c) { + case '\n': + if (global_indent >= 0) { + putc(c, file); + line_number++; + newline = 1; + delayed_indent = 0; + @<Insert appropriate indentation@> + break; + } else { + /* Don't show newlines in embedded fragmants */ + fputs(". . .", file); + return 0; + } + case '\t': @<Handle tab...@> + delayed_indent = 0; + break; + default: + if (c==nw_char) + { + @<Check for macro invocation in scrap@> + break; + } + putc(c, file); + if (global_indent >= 0) { + @<Add more indentation @'' '@'@> + } + indent++; + if (c > ' ') newline = 0; + delayed_indent = 0; + break; + } + c = pop(&reader); + } +}@} + +We need to make sure that we don't overflow \verb|indent_chars[]|. +@d Add more indentation @'char@' +@{{ + if (global_indent + indent >= MAX_INDENT) { + fprintf(stderr, + "Error! maximum indentation exceeded in \"%s\".\n", + spelling); + exit(1); + } + indent_chars[global_indent + indent] = @1; +}@} + + +@d Insert debugging information if required +@{if (debug_flag) { + fprintf(file, "\n#line %d \"%s\"\n", + line_number, scrap_array(defs->scrap).file_name); + @<Insert appropr...@> +}@} + + +@d Insert approp... +@{{ + char c1 = pop(&reader); + char c2 = pop(&reader); + + if (indent_flag && !(@<Indent suppressed@>)) { + @<Put out the indent@> + } + indent = 0; + backup(2, &reader); +}@} + +@d Put out the indent +@{if (tab_flag) + for (indent=0; indent<global_indent; indent++) + putc(' ', file); + else + for (indent=0; indent<global_indent; indent++) + putc(indent_chars[indent], file); +@} + +Indent will be suppressed if the next character is a newline or +if the next two characters are \verb|@@#|. If the next two characters +are \verb|@@<|, we suppress the indent for now but mark that it +may be needed when the next fragment is started. + +@d Indent suppressed +@{c1 == '\n' +|| (c1 == nw_char && (c2 == '#' || (delayed_indent |= (c2 == '<'))))@} + +@d Handle tab characters on output +@{{ + if (tab_flag) + @<Expand tab...@> + else { + putc('\t', file); + if (global_indent >= 0) { + @<Add more indentation @''\t'@'@> + } + indent++; + } +}@} + + +@d Check for macro invocation... +@{{ + int oldin = indent; + char oldcf = comment_flag; + c = pop(&reader); + switch (c) { + case 't': @<Copy fragment title into file@> + break; + case 'c': @<Copy block comment from scrap@> + break; + case 'f': @<Copy file name into file@> + break; + case 'x': @<Copy label from scrap into file@> + case '_': break; + case 'v': @<Copy version info into file@> + break; + case 's': indent = -global_indent; + comment_flag = 0; + break; + case '<': @<Copy macro into \verb|file|@> + @<Insert debugging information if required@> + indent = oldin; + comment_flag = oldcf; + break; + @<Handle macro parameter substitution@> + indent = oldin; + break; + default: + if(c==nw_char) + { + putc(c, file); + if (global_indent >= 0) { + @<Add more indentation @'' '@'@> + } + indent++; + break; + } + /* ignore, since we should already have a warning */ + break; + } +}@} + +@d Copy label from scrap into file +@{{ + @<Get label from@(pop(&reader)@)@> + write_label(label_name, file); +}@} + +@d Copy file name into file +@{if (defs->quoted) + fprintf(file, "%cf", nw_char); +else + fputs(spelling, file); +@} + +@d Copy macro into... +@{{ + Arglist *a = pop_scrap_name(&reader, &local_parameters); + Name *name = a->name; + int changed; + Arglist * args = instance(a->args, inArgs, inParams, &changed); + int i, narg; + char * p = name->spelling; + char * * inParams = name->arg; + Arglist *q = args; + + if (name->mark) { + fprintf(stderr, "%s: recursive macro discovered involving <%s>\n", + command_name, name->spelling); + exit(-1); + } + if (name->defs && !defs->quoted) { + @<Perhaps comment this macro@> + name->mark = TRUE; + indent = write_scraps(file, spelling, name->defs, global_indent + indent, + indent_chars, debug_flag, tab_flag, indent_flag, + comment_flag, args, name->arg, + local_parameters, name->spelling); + indent -= global_indent; + name->mark = FALSE; + } + else + { + if (delayed_indent) + { + for (i = indent + global_indent; --i >= 0; ) + putc(' ', file); + } + + fprintf(file, "%c<", nw_char); + if (name->sector == 0) + fputc('+', file); + @<Comment this macro use@> + fprintf(file, "%c>", nw_char); + if (!defs->quoted && !tex_flag) + fprintf(stderr, "%s: macro never defined <%s>\n", + command_name, name->spelling); + } +}@} + +@d Perhaps comment this macro +@{if (comment_flag && newline) { + @<Perhaps put a delayed indent@> + fputs(comment_begin[comment_flag], file); + @<Comment this macro use@> + if (xref_flag) { + putc(' ', file); + write_single_scrap_ref(file, name->defs->scrap); + } + fputs(comment_end[comment_flag], file); + putc('\n', file); + if (!delayed_indent) + for (i = indent + global_indent; --i >= 0; ) + putc(' ', file); +} +@} + +@d Perhaps put a delayed indent +@{if (delayed_indent) + for (i = indent + global_indent; --i >= 0; ) + putc(' ', file); +@} + +@d Copy fragment title into file +@{{ + char * p = title; + Arglist *q = inArgs; + int narg; + + @<Comment this macro use@> + if (xref_flag) { + putc(' ', file); + write_single_scrap_ref(file, defs->scrap); + } +}@} + +@d Comment this macro use +@{narg = 0; +while (*p != '\000') { + if (*p == ARG_CHR) { + if (q == NULL) { + if (defs->quoted) + fprintf(file, "%c'%s%c'", nw_char, inParams[narg], nw_char); + else + fprintf(file, "'%s'", inParams[narg]); + } + else { + comment_ArglistElement(file, q, defs->quoted); + q = q->next; + } + p++; + narg++; + } + else + fputc(*p++, file); +}@} + +@d Forward declarations for scraps.c +@{static void +comment_ArglistElement(FILE * file, Arglist * args, int quote) +{ + Name *name = args->name; + Arglist *q = args->args; + + if (name == NULL) { + if (quote) + fprintf(file, "%c'%s%c'", nw_char, (char *)q, nw_char); + else + fprintf(file, "'%s'", (char *)q); + } else if (name == (Name *)1) { + @<Include an embedded scrap in comment@> + } else { + @<Include a fragment use in comment@> + } +} +@| comment_ArglistElement @} + +@d Include an embedded scrap in comment +@{Embed_Node * e = (Embed_Node *)q; +fputc('{', file); +write_scraps(file, "", e->defs, -1, "", 0, 0, 0, 0, e->args, 0, 1, ""); +fputc('}', file);@} + +@d Include a fragment use in comment +@{char * p = name->spelling; +if (quote) + fputc(nw_char, file); +fputc('<', file); +if (quote && name->sector == 0) + fputc('+', file); +while (*p != '\000') { + if (*p == ARG_CHR) { + comment_ArglistElement(file, q, quote); + q = q->next; + p++; + } + else + fputc(*p++, file); +} +if (quote) + fputc(nw_char, file); +fputc('>', file);@} + +\subsection{Collecting Page Numbers} + +@d Function... +@{extern void collect_numbers(); +@} + +@o scraps.c -cc +@{void collect_numbers(aux_name) + char *aux_name; +{ + if (number_flag) { + int i; + for (i=1; i<scraps; i++) + scrap_array(i).page = i; + } + else { + FILE *aux_file = fopen(aux_name, "r"); + already_warned = FALSE; + if (aux_file) { + char aux_line[500]; + while (fgets(aux_line, 500, aux_file)) { + @< Read line in \verb|.aux| file @> + } + fclose(aux_file); + @<Add letters to scraps with duplicate page numbers@> + } + } +} +@| collect_numbers @} + +The \textit{memoir} document class creates references in the +\verb|.aux| file with nested braces, so after each open brace we have +to wait for the matching closing brace. + +@d Read line in \verb|.aux| file @{@% +int scrap_number; +int page_number; +int i; +int dummy_idx; +int bracket_depth = 1; +if (1 == sscanf(aux_line, + "\\newlabel{scrap%d}{{%n", + &scrap_number, + &dummy_idx)) { + for (i = dummy_idx; i < strlen(aux_line) && bracket_depth > 0; i++) { + if (aux_line[i] == '{') bracket_depth++; + else if (aux_line[i] == '}') bracket_depth--; + } + if (i > dummy_idx + && i < strlen(aux_line) + && 1 == sscanf(aux_line+i, "{%d}" ,&page_number)) { + if (scrap_number < scraps) + scrap_array(scrap_number).page = page_number; + else + @<Warn...@> + } +} +@|@} + + +@d Add letters to scraps with... +@{{ + int i = 0; + + @<Step @'i@' to the next valid scrap@> + @<For all remaining scraps@> { + int j = i; + @<Step @'j@' to the next valid scrap@> + @<Perhaps add letters to the page numbers@> + i = j; + } +} +@} + +@d Step @'i@' to the next valid scrap +@{do + @1++; +while (@1 < scraps && scrap_array(@1).page == -1); +@} + +@d For all remaining scraps +@{while (i < scraps)@} + +@d Perhaps add letters to the page numbers +@{if (scrap_array(i).page == scrap_array(j).page) { + if (scrap_array(i).letter == 0) + scrap_array(i).letter = 'a'; + scrap_array(j).letter = scrap_array(i).letter + 1; +} +@} + +\section{Names} \label{names} + +@d Type de... +@{typedef struct scrap_node { + struct scrap_node *next; + int scrap; + char quoted; +} Scrap_Node; +@| Scrap_Node @} + + +@d Type de... +@{typedef struct name { + char *spelling; + struct name *llink; + struct name *rlink; + Scrap_Node *defs; + Scrap_Node *uses; + char * arg[9]; + int mark; + char tab_flag; + char indent_flag; + char debug_flag; + unsigned char comment_flag; + unsigned char sector; +} Name; +@| Name @} + +@d Global variable dec... +@{extern Name *file_names; +extern Name *macro_names; +extern Name *user_names; +extern int scrap_name_has_parameters; +extern int scrap_ended_with; +@| file_names macro_names user_names @} + +@d Global variable def... +@{Name *file_names = NULL; +Name *macro_names = NULL; +Name *user_names = NULL; +int scrap_name_has_parameters; +int scrap_ended_with; +@} + +@d Function pro... +@{extern Name *collect_file_name(); +extern Name *collect_macro_name(); +extern Arglist *collect_scrap_name(); +extern Name *name_add(); +extern Name *prefix_add(); +extern char *save_string(); +extern void reverse_lists(); +@} + +@o names.c -cc +@{enum { LESS, GREATER, EQUAL, PREFIX, EXTENSION }; + +static int compare(x, y) + char *x; + char *y; +{ + int len, result; + int xl = strlen(x); + int yl = strlen(y); + int xp = x[xl - 1] == ' '; + int yp = y[yl - 1] == ' '; + if (xp) xl--; + if (yp) yl--; + len = xl < yl ? xl : yl; + result = strncmp(x, y, len); + if (result < 0) return GREATER; + else if (result > 0) return LESS; + else if (xl < yl) { + if (xp) return EXTENSION; + else return LESS; + } + else if (xl > yl) { + if (yp) return PREFIX; + else return GREATER; + } + else return EQUAL; +} +@| compare LESS GREATER EQUAL PREFIX EXTENSION @} + + +@o names.c -cc +@{char *save_string(s) + char *s; +{ + char *new = (char *) arena_getmem((strlen(s) + 1) * sizeof(char)); + strcpy(new, s); + return new; +} +@| save_string @} + +@o names.c -cc +@{static int ambiguous_prefix(); + +static char * found_name = NULL; + +Name *prefix_add(rt, spelling, sector) + Name **rt; + char *spelling; + unsigned char sector; +{ + Name *node = *rt; + int cmp; + + while (node) { + switch ((cmp = compare(node->spelling, spelling))) { + case GREATER: rt = &node->rlink; + break; + case LESS: rt = &node->llink; + break; + case EQUAL: + found_name = node->spelling; + case EXTENSION: if (node->sector > sector) { + rt = &node->rlink; + break; + } + else if (node->sector < sector) { + rt = &node->llink; + break; + } + if (cmp == EXTENSION) + node->spelling = save_string(spelling); + return node; + case PREFIX: @<Check for ambiguous prefix@> + return node; + } + node = *rt; + } + @<Create new name entry@> +} +@| prefix_add @} + +Since a very short prefix might match more than one fragment name, I need +to check for other matches to avoid mistakes. Basically, I simply +continue the search down {\em both\/} branches of the tree. + +@d Check for ambiguous prefix +@{{ + if (ambiguous_prefix(node->llink, spelling, sector) || + ambiguous_prefix(node->rlink, spelling, sector)) + fprintf(stderr, + "%s: ambiguous prefix %c<%s...%c> (%s, line %d)\n", + command_name, nw_char, spelling, nw_char, source_name, source_line); +}@} + +@o names.c -cc +@{static int ambiguous_prefix(node, spelling, sector) + Name *node; + char *spelling; + unsigned char sector; +{ + while (node) { + switch (compare(node->spelling, spelling)) { + case GREATER: node = node->rlink; + break; + case LESS: node = node->llink; + break; + case EXTENSION: + case PREFIX: + case EQUAL: if (node->sector > sector) { + node = node->rlink; + break; + } + else if (node->sector < sector) { + node = node->llink; + break; + } + return TRUE; + } + } + return FALSE; +} +@} + +Rob Shillingsburg suggested that I organize the index of +user-specified identifiers more traditionally; that is, not relying on +strict {\small ASCII} comparisons via \verb|strcmp|. Ideally, we'd like +to see the index ordered like this: +\begin{quote} +\begin{flushleft} +aardvark \\ +Adam \\ +atom \\ +Atomic \\ +atoms +\end{flushleft} +\end{quote} +The function \verb|robs_strcmp| implements the desired predicate. +It returns -2 for alphabetically less-than, -1 for less-than but only +differing in case, zero for equal, 1 for greater-than but only in case +and 2 for alphabetically greater-than. + +@d Function prototypes +@{extern int robs_strcmp(char*, char*); +@} + +@o names.c -cc +@{int robs_strcmp(char* x, char* y) +{ + int cmp = 0; + + for (; *x && *y; x++, y++) + { + @<Skip invisibles on @'x@'@> + @<Skip invisibles on @'y@'@> + if (*x == *y) + continue; + if (islower(*x) && toupper(*x) == *y) + { + if (!cmp) cmp = 1; + continue; + } + if (islower(*y) && *x == toupper(*y)) + { + if (!cmp) cmp = -1; + continue; + } + return 2*(toupper(*x) - toupper(*y)); + } + if (*x) + return 2; + if (*y) + return -2; + return cmp; +} +@| robs_strcmp @} + +Certain character sequences are invisible when printed. We don't want +them to be considered for the alphabetical ordering. + +@d Skip invisibles on @'p@' +@{if (*@1 == '|') + @1++; +@} + +@o names.c -cc +@{Name *name_add(rt, spelling, sector) + Name **rt; + char *spelling; + unsigned char sector; +{ + Name *node = *rt; + while (node) { + int result = robs_strcmp(node->spelling, spelling); + if (result > 0) + rt = &node->llink; + else if (result < 0) + rt = &node->rlink; + else + { + found_name = node->spelling; + if (node->sector > sector) + rt = &node->llink; + else if (node->sector < sector) + rt = &node->rlink; + else + return node; + } + node = *rt; + } + @<Create new name entry@> +} +@| name_add @} + + +@d Create new name... +@{{ + node = (Name *) arena_getmem(sizeof(Name)); + if (found_name && robs_strcmp(found_name, spelling) == 0) + node->spelling = found_name; + else + node->spelling = save_string(spelling); + node->mark = FALSE; + node->llink = NULL; + node->rlink = NULL; + node->uses = NULL; + node->defs = NULL; + node->arg[0] = + node->arg[1] = + node->arg[2] = + node->arg[3] = + node->arg[4] = + node->arg[5] = + node->arg[6] = + node->arg[7] = + node->arg[8] = NULL; + node->tab_flag = TRUE; + node->indent_flag = TRUE; + node->debug_flag = FALSE; + node->comment_flag = 0; + node->sector = sector; + *rt = node; + return node; +}@} + + +Name terminated by whitespace. Also check for ``per-file'' flags. Keep +skipping white space until we reach scrap. +@o names.c -cc +@{Name *collect_file_name() +{ + Name *new_name; + char name[MAX_NAME_LEN]; + char *p = name; + int start_line = source_line; + int c = source_get(), c2; + while (isspace(c)) + c = source_get(); + while (isgraph(c)) { + *p++ = c; + c = source_get(); + } + if (p == name) { + fprintf(stderr, "%s: expected file name (%s, %d)\n", + command_name, source_name, start_line); + exit(-1); + } + *p = '\0'; + /* File names are always global. */ + new_name = name_add(&file_names, name, 0); + @<Handle optional per-file flags@> + c2 = source_get(); + if (c != nw_char || (c2 != '{' && c2 != '(' && c2 != '[')) { + fprintf(stderr, "%s: expected %c{, %c[, or %c( after file name (%s, %d)\n", + command_name, nw_char, nw_char, nw_char, source_name, start_line); + exit(-1); + } + return new_name; +} +@| collect_file_name @} + +@d Handle optional per-file flags +@{{ + while (1) { + while (isspace(c)) + c = source_get(); + if (c == '-') { + c = source_get(); + do { + switch (c) { + case 't': new_name->tab_flag = FALSE; + break; + case 'd': new_name->debug_flag = TRUE; + break; + case 'i': new_name->indent_flag = FALSE; + break; + case 'c': @<Get comment delimiters@> + break; + default : fprintf(stderr, "%s: unexpected per-file flag (%s, %d)\n", + command_name, source_name, source_line); + break; + } + c = source_get(); + } while (!isspace(c)); + } + else break; + } +}@} + +So far we only deal with C comments. +@d Get comment delimiters +@{c = source_get(); +if (c == 'c') + new_name->comment_flag = 1; +else if (c == '+') + new_name->comment_flag = 2; +else if (c == 'p') + new_name->comment_flag = 3; +else + fprintf(stderr, "%s: Unrecognised comment flag (%s, %d)\n", + command_name, source_name, source_line); +@} + + +@d Forward declarations for scraps.c +@{char * comment_begin[4] = { "", "/* ", "// ", "# "}; +char * comment_mid[4] = { "", " * ", "// ", "# "}; +char * comment_end[4] = { "", " */", "", ""}; +@| comment_begin comment_end comment_mid @} + +Name terminated by \verb+\n+ or \verb+@@{+; but keep skipping until \verb+@@{+ +@o names.c -cc +@{Name *collect_macro_name() +{ + char name[MAX_NAME_LEN]; + char args[1000]; + char * arg[9]; + char * argp = args; + int argc = 0; + char *p = name; + int start_line = source_line; + int c = source_get(), c2; + unsigned char sector = current_sector; + + if (c == '+') { + sector = 0; + c = source_get(); + } + while (isspace(c)) + c = source_get(); + while (c != EOF) { + Name * node; + switch (c) { + case '\t': + case ' ': *p++ = ' '; + do + c = source_get(); + while (c == ' ' || c == '\t'); + break; + case '\n': @<Skip until scrap begins, then return name@> + default: + if (c==nw_char) + { + @<Check for terminating at-sequence and return name@> + break; + } + *p++ = c; + c = source_get(); + break; + } + } + fprintf(stderr, "%s: expected fragment name (%s, %d)\n", + command_name, source_name, start_line); + exit(-1); + return NULL; /* unreachable return to avoid warnings on some compilers */ +} +@| collect_macro_name @} + + +@d Check for termina... +@{{ + c = source_get(); + switch (c) { + case '(': + case '[': + case '{': @<Cleanup and install name@> + return install_args(node, argc, arg); + case '\'': @<Enter the next argument@> + break; + default: + if (c==nw_char) + { + *p++ = c; + break; + } + fprintf(stderr, + "%s: unexpected %c%c in fragment definition name (%s, %d)\n", + command_name, nw_char, c, source_name, start_line); + exit(-1); + } +}@} + +@d Enter the next argument +@{arg[argc] = argp; +while ((c = source_get()) != EOF) { + if (c==nw_char) { + c2 = source_get(); + if (c2=='\'') { + @<Make this argument@> + c = source_get(); + break; + } + else + *argp++ = c2; + } + else + *argp++ = c; +} +*p++ = ARG_CHR; +@} + +@d Type dec... +@{#define ARG_CHR '\001' +@| ARG_CHR@} + +@d Make this argument +@{if (argc < 9) { + *argp++ = '\000'; + argc += 1; +} +@} + +@d Cleanup and install name +@{{ + if (p > name && p[-1] == ' ') + p--; + if (p - name > 3 && p[-1] == '.' && p[-2] == '.' && p[-3] == '.') { + p[-3] = ' '; + p -= 2; + } + if (p == name || name[0] == ' ') { + fprintf(stderr, "%s: empty name (%s, %d)\n", + command_name, source_name, source_line); + exit(-1); + } + *p = '\0'; + node = prefix_add(¯o_names, name, sector); +}@} + +@d Skip until scrap... +@{{ + do + c = source_get(); + while (isspace(c)); + c2 = source_get(); + if (c != nw_char || (c2 != '{' && c2 != '(' && c2 != '[')) { + fprintf(stderr, "%s: expected %c{ after fragment name (%s, %d)\n", + command_name, nw_char, source_name, start_line); + exit(-1); + } + @<Cleanup and install name@> + return install_args(node, argc, arg); +}@} + +@d Function prototypes +@{extern Name *install_args(); +@} + +@o names.c -cc +@{Name *install_args(Name * name, int argc, char *arg[9]) +{ + int i; + + for (i = 0; i < argc; i++) { + if (name->arg[i] == NULL) + name->arg[i] = save_string(arg[i]); + } + return name; +} +@} + +@d Type declarations +@{typedef struct arglist +{Name * name; +struct arglist * args; +struct arglist * next; +} Arglist; +@| Arglist @} + +@o names.c -cc +@{Arglist * buildArglist(Name * name, Arglist * a) +{ + Arglist * args = (Arglist *)arena_getmem(sizeof(Arglist)); + + args->args = a; + args->next = NULL; + args->name = name; + return args; +} +@| buildArglist @} + +Terminated by \verb+@@>+ +@o names.c -cc +@{Arglist * collect_scrap_name(int current_scrap) +{ + char name[MAX_NAME_LEN]; + char *p = name; + int c = source_get(); + unsigned char sector = current_sector; + Arglist * head = NULL; + Arglist ** tail = &head; + + if (c == '+') + { + sector = 0; + c = source_get(); + } + while (c == ' ' || c == '\t') + c = source_get(); + while (c != EOF) { + switch (c) { + case '\t': + case ' ': *p++ = ' '; + do + c = source_get(); + while (c == ' ' || c == '\t'); + break; + default: + if (c==nw_char) + { + @<Look for end of scrap name and return@> + break; + } + if (!isgraph(c)) { + fprintf(stderr, + "%s: unexpected character in fragment name (%s, %d)\n", + command_name, source_name, source_line); + exit(-1); + } + *p++ = c; + c = source_get(); + break; + } + } + fprintf(stderr, "%s: unexpected end of file (%s, %d)\n", + command_name, source_name, source_line); + exit(-1); + return NULL; /* unreachable return to avoid warnings on some compilers */ +} +@| collect_scrap_name @} + +@d Look for end of scrap name... +@{{ + Name * node; + + c = source_get(); + switch (c) { + + case '\'': { + @< Add plain string argument@> + } + *p++ = ARG_CHR; + c = source_get(); + break; + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': { + @<Add a propagated argument@> + } + *p++ = ARG_CHR; + c = source_get(); + break; + case '{': { + @<Add an inline scrap argument@> + } + *p++ = ARG_CHR; + c = source_get(); + break; + case '<': + @<Add macro call argument@> + *p++ = ARG_CHR; + c = source_get(); + break; + case '(': + scrap_name_has_parameters = 1; + @<Cleanup and install name@> + return buildArglist(node, head); + case '>': + scrap_name_has_parameters = 0; + @<Cleanup and install name@> + return buildArglist(node, head); + + default: + if (c==nw_char) + { + *p++ = c; + c = source_get(); + break; + } + fprintf(stderr, + "%s: unexpected %c%c in fragment invocation name (%s, %d)\n", + command_name, nw_char, c, source_name, source_line); + exit(-1); + } +}@} + +A plain string argument has no name and a string as a value. + +@d Add plain string argument +@{char buff[MAX_NAME_LEN]; +char * s = buff; +int c, c2; + +while ((c = source_get()) != EOF) { + if (c==nw_char) { + c2 = source_get(); + if (c2=='\'') + break; + *s++ = c2; + } + else + *s++ = c; +} +*s = '\000'; +@<Add buff to current arg list@>@} + +A parameter argument propagated into an interior fragment has no name +and and a string of \verb|ARG_CHAR| followed by a digit as value. + +@d Add a propagated argument +@{char buff[3]; +buff[0] = ARG_CHR; +buff[1] = c; +buff[2] = '\000'; +@<Add buff to current arg list@>@} + +@d Add an inline scrap argument +@{int s = collect_scrap(); +Scrap_Node * d = (Scrap_Node *)arena_getmem(sizeof(Scrap_Node)); +d->scrap = s; +d->quoted = 0; +d->next = NULL; +*tail = buildArglist((Name *)1, (Arglist *)d); +tail = &(*tail)->next;@} + +@d Type declarations +@{typedef struct embed { + Scrap_Node * defs; + Arglist * args; +} Embed_Node; +@| Embed_Node@} + +@d Add macro call argument +@{*tail = collect_scrap_name(current_scrap); +if (current_scrap >= 0) + add_to_use((*tail)->name, current_scrap); +tail = &(*tail)->next; +@} + +@d Add buff... +@{*tail = buildArglist(NULL, (Arglist *)save_string(buff)); +tail = &(*tail)->next; +@} + +@o names.c -cc +@{static Scrap_Node *reverse(); /* a forward declaration */ + +void reverse_lists(names) + Name *names; +{ + while (names) { + reverse_lists(names->llink); + names->defs = reverse(names->defs); + names->uses = reverse(names->uses); + names = names->rlink; + } +} +@| reverse_lists @} + +Just for fun, here's a non-recursive version of the traditional list +reversal code. Note that it reverses the list in place; that is, it +does no new allocations. +@o names.c -cc +@{static Scrap_Node *reverse(a) + Scrap_Node *a; +{ + if (a) { + Scrap_Node *b = a->next; + a->next = NULL; + while (b) { + Scrap_Node *c = b->next; + b->next = a; + a = b; + b = c; + } + } + return a; +} +@| reverse @} + + +\section{Searching for Index Entries} \label{search} + +Given the array of scraps and a set of index entries, we need to +search all the scraps for occurrences of each entry. The obvious +approach to this problem would be quite expensive for large documents; +however, there is an interesting paper describing an efficient +solution~\cite{aho:75}. + + +@o scraps.c -cc +@{typedef struct name_node { + struct name_node *next; + Name *name; +} Name_Node; +@| Name_Node @} + +@o scraps.c -cc +@{typedef struct goto_node { + Name_Node *output; /* list of words ending in this state */ + struct move_node *moves; /* list of possible moves */ + struct goto_node *fail; /* and where to go when no move fits */ + struct goto_node *next; /* next goto node with same depth */ +} Goto_Node; +@| Goto_Node @} + +@o scraps.c -cc +@{typedef struct move_node { + struct move_node *next; + Goto_Node *state; + char c; +} Move_Node; +@| Move_Node @} + +@o scraps.c -cc +@{static Goto_Node *root[256]; +static int max_depth; +static Goto_Node **depths; +@| root max_depth depths @} + + +@o scraps.c -cc +@{static Goto_Node *goto_lookup(c, g) + char c; + Goto_Node *g; +{ + Move_Node *m = g->moves; + while (m && m->c != c) + m = m->next; + if (m) + return m->state; + else + return NULL; +} +@| goto_lookup @} + +\subsection{Retrieving scrap uses} + +@o scraps.c -cc +@{typedef struct ArgMgr_s +{ + char * pv; + char * bgn; + Arglist * arg; + struct ArgMgr_s * old; +} ArgMgr; +@| ArgMgr @} + +@o scraps.c -cc +@{typedef struct ArgManager_s +{ + Manager * m; + ArgMgr * a; +} ArgManager; +@| ArgManager @} + +@o scraps.c -cc +@{static void +pushArglist(ArgManager * mgr, Arglist * a) +{ + ArgMgr * b = malloc(sizeof(ArgMgr)); + + if (b == NULL) + { + fprintf(stderr, "Can't allocate space for an argument manager\n"); + exit(EXIT_FAILURE); + } + b->pv = b->bgn = NULL; + b->arg = a; + b->old = mgr->a; + mgr->a = b; +} +@| pushArglist @} + +@o scraps.c -cc +@{static char argpop(ArgManager * mgr) +{ + while (mgr->a != NULL) + { + ArgMgr * a = mgr->a; + + @<Perhaps |return| a character from the current arg@> + @<Perhaps start a new arg@> + @<Otherwise pop the current arg@> + } + + return (pop(mgr->m)); +} +@| argpop @} + +We separate individual arguments using spaces. + +@d Perhaps |return| a character from the current arg +@{if (a->pv != NULL) +{ + char c = *a->pv++; + + if (c != '\0') + return c; + a->pv = NULL; + return ' '; +} +@} + +I'm pretty sure that only the first case is ever used. I don't think +the others can occur in this context, which makes the whole +|ArgManager| thing doubtful. + +@d Perhaps start a new arg +@{if (a->arg) { + Arglist * b = a->arg; + + a->arg = b->next; + if (b->name == NULL) { + a->bgn = a->pv = (char *)b->args; + } else if (b->name == (Name *)1) { + a->bgn = a->pv = "{Embedded Scrap}"; + } else { + pushArglist(mgr, b->args); + }@} + +@d Otherwise pop the current arg +@{} else { + mgr->a = a->old; + free(a); +}@} + +@o scraps.c -cc +@{static char +prev_char(ArgManager * mgr, int n) +{ + char c = '\0'; + ArgMgr * a = mgr->a; + Manager * m = mgr->m; + + if (a != NULL) { + @<Get the nth previous character from an argument@> + } else { + @<Get the nth previous character from a scrap@> + } + + return c; +} +@| prev_char @} + +@d Get the nth previous character from an argument +@{if (a->pv && a->pv - n >= a->bgn) + c = *a->pv; +else if (a->bgn) { + int j = strlen(a->bgn) + 1; + + if (n >= j) + c = a->bgn[j - n]; + else + c = ' '; +} +@} + +@d Get the nth previous character from a scrap +@{int k = m->index - n - 2; + +if (k >= 0) + c = m->scrap->chars[k]; +else if (m->prev) + c = m->prev->chars[SLAB_SIZE - k]; +@} + +\subsection{Building the Automata} + +@d Function pro... +@{extern void search(); +@} + +@o scraps.c -cc +@{static void build_gotos(); +static int reject_match(); + +void search() +{ + int i; + for (i=0; i<128; i++) + root[i] = NULL; + max_depth = 10; + depths = (Goto_Node **) arena_getmem(max_depth * sizeof(Goto_Node *)); + for (i=0; i<max_depth; i++) + depths[i] = NULL; + build_gotos(user_names); + @<Build failure functions@> + @<Search scraps@> +} +@| search @} + + + +@o scraps.c -cc +@{static void build_gotos(tree) + Name *tree; +{ + while (tree) { + @<Extend goto graph with \verb|tree->spelling|@> + build_gotos(tree->rlink); + tree = tree->llink; + } +} +@| build_gotos @} + +@d Extend goto... +@{{ + int depth = 2; + char *p = tree->spelling; + char c = *p++; + Goto_Node *q = root[(unsigned char)c]; + Name_Node * last; + if (!q) { + q = (Goto_Node *) arena_getmem(sizeof(Goto_Node)); + root[(unsigned char)c] = q; + q->moves = NULL; + q->fail = NULL; + q->moves = NULL; + q->output = NULL; + q->next = depths[1]; + depths[1] = q; + } + while ((c = *p++)) { + Goto_Node *new = goto_lookup(c, q); + if (!new) { + Move_Node *new_move = (Move_Node *) arena_getmem(sizeof(Move_Node)); + new = (Goto_Node *) arena_getmem(sizeof(Goto_Node)); + new->moves = NULL; + new->fail = NULL; + new->moves = NULL; + new->output = NULL; + new_move->state = new; + new_move->c = c; + new_move->next = q->moves; + q->moves = new_move; + if (depth == max_depth) { + int i; + Goto_Node **new_depths = + (Goto_Node **) arena_getmem(2*depth*sizeof(Goto_Node *)); + max_depth = 2 * depth; + for (i=0; i<depth; i++) + new_depths[i] = depths[i]; + depths = new_depths; + for (i=depth; i<max_depth; i++) + depths[i] = NULL; + } + new->next = depths[depth]; + depths[depth] = new; + } + q = new; + depth++; + } + last = q->output; + q->output = (Name_Node *) arena_getmem(sizeof(Name_Node)); + q->output->next = last; + q->output->name = tree; +}@} + + +@d Build failure functions +@{{ + int depth; + for (depth=1; depth<max_depth; depth++) { + Goto_Node *r = depths[depth]; + while (r) { + Move_Node *m = r->moves; + while (m) { + char a = m->c; + Goto_Node *s = m->state; + Goto_Node *state = r->fail; + while (state && !goto_lookup(a, state)) + state = state->fail; + if (state) + s->fail = goto_lookup(a, state); + else + s->fail = root[(unsigned char)a]; + if (s->fail) { + Name_Node *p = s->fail->output; + while (p) { + Name_Node *q = (Name_Node *) arena_getmem(sizeof(Name_Node)); + q->name = p->name; + q->next = s->output; + s->output = q; + p = p->next; + } + } + m = m->next; + } + r = r->next; + } + } +}@} + + +\subsection{Searching the Scraps} + +@d Search scraps +@{{ + for (i=1; i<scraps; i++) { + char c, last = '\0'; + Manager rd; + ArgManager reader; + Goto_Node *state = NULL; + rd.prev = NULL; + rd.scrap = scrap_array(i).slab; + rd.index = 0; + reader.m = &rd; + reader.a = NULL; + c = argpop(&reader); + while (c) { + while (state && !goto_lookup(c, state)) + state = state->fail; + if (state) + state = goto_lookup(c, state); + else + state = root[(unsigned char)c]; + @<Skip over at at@> + @<Skip over a scrap use@> + @<Skip over a block comment@> + last = c; + c = argpop(&reader); + if (state && state->output) { + Name_Node *p = state->output; + do { + Name *name = p->name; + if (!reject_match(name, c, &reader) && + scrap_array(i).sector == name->sector && + (!name->uses || name->uses->scrap != i)) { + Scrap_Node *new_use = + (Scrap_Node *) arena_getmem(sizeof(Scrap_Node)); + new_use->scrap = i; + new_use->next = name->uses; + name->uses = new_use; + if (!scrap_is_in(name->defs, i)) + add_uses(&(scrap_array(i).uses), name); + } + p = p->next; + } while (p); + } + } + } +}@} + +@d Skip over at at +@{if (last == nw_char && c == nw_char) +{ + last = '\0'; + c = argpop(&reader); +} +@} + +@d Skip over a scrap use +@{if (last == nw_char && c == '<') +{ + char buf[MAX_NAME_LEN]; + char * p = buf; + Arglist * args; + + c = argpop(&reader); + while ((c = argpop(&reader)) != nw_char) + *p++ = c; + c = argpop(&reader); + *p = '\0'; + if (sscanf(buf, "%p", &args) != 1) { + fprintf(stderr, "%s: found an internal problem (3)\n", command_name); + exit(-1); + } + pushArglist(&reader, args); +}@} + +@d Forward declarations for scraps.c +@{ +static void add_uses(); +static int scrap_is_in(); +@} + +@o scraps.c -cc +@{ +static int scrap_is_in(Scrap_Node * list, int i) +{ + while (list != NULL) { + if (list->scrap == i) + return TRUE; + list = list->next; + } + return FALSE; +} +@| scrap_is_in@} + +@o scraps.c -cc +@{ +static void add_uses(Uses * * root, Name *name) +{ + int cmp; + Uses *p, **q = root; + + while ((p = *q, p != NULL) + && (cmp = robs_strcmp(p->defn->spelling, name->spelling)) < 0) + q = &(p->next); + if (p == NULL || cmp > 0) + { + Uses *new = arena_getmem(sizeof(Uses)); + new->next = p; + new->defn = name; + *q = new; + } +} +@| add_uses @} + +@d Type dec... +@{typedef struct uses { + struct uses *next; + Name *defn; +} Uses; +@| Uses @} + +@d Function prototypes +@{extern void format_uses_refs(FILE *, int); +@} + +@o scraps.c -cc +@{ +void +format_uses_refs(FILE * tex_file, int scrap) +{ + Uses * p = scrap_array(scrap).uses; + if (p != NULL) + @<Write uses references@> +} +@| format_uses_refs @} + +@d Write uses ... +@{{ + char join = ' '; + fputs("\\item \\NWtxtIdentsUsed\\nobreak\\", tex_file); + do { + @<Write one use reference@> + join = ','; + p = p->next; + }while (p != NULL); + fputs(".", tex_file); +}@} + +@d Write one use reference +@{Name * name = p->defn; +Scrap_Node *defs = name->defs; +int first = TRUE, page = -1; +fprintf(tex_file, + "%c \\verb%c%s%c\\nobreak\\ ", + join, nw_char, name->spelling, nw_char); +if (defs) +{ + do { + @<Write one referenced scrap@> + first = FALSE; + defs = defs->next; + }while (defs!= NULL); +} +else +{ + fputs("\\NWnotglobal", tex_file); +} +@} + +@d Write one referenced scrap +@{fputs("\\NWlink{nuweb", tex_file); +write_scrap_ref(tex_file, defs->scrap, -1, &page); +fputs("}{", tex_file); +write_scrap_ref(tex_file, defs->scrap, first, &page); +fputs("}", tex_file);@} + +@d Function prototypes +@{extern void format_defs_refs(FILE *, int); +@} + +@o scraps.c -cc +@{ +void +format_defs_refs(FILE * tex_file, int scrap) +{ + Uses * p = scrap_array(scrap).defs; + if (p != NULL) + @<Write defs references@> +} +@| format_defs_refs @} + +@d Write defs ... +@{{ + char join = ' '; + fputs("\\item \\NWtxtIdentsDefed\\nobreak\\", tex_file); + do { + @<Write one def reference@> + join = ','; + p = p->next; + }while (p != NULL); + fputs(".", tex_file); +}@} + +@d Write one def reference +@{Name * name = p->defn; +Scrap_Node *defs = name->uses; +int first = TRUE, page = -1; +fprintf(tex_file, + "%c \\verb%c%s%c\\nobreak\\ ", + join, nw_char, name->spelling, nw_char); +if (defs == NULL + || (defs->scrap == scrap && defs->next == NULL)) { + fputs("\\NWtxtIdentsNotUsed", tex_file); +} +else { + do { + if (defs->scrap != scrap) { + @<Write one referenced scrap@> + first = FALSE; + } + defs = defs->next; + }while (defs!= NULL); +} +@} + +\subsubsection{Rejecting Matches} + +A problem with simple substring matching is that the string ``he'' +would match longer strings like ``she'' and ``her.'' Norman Ramsey +suggested examining the characters occurring immediately before and +after a match and rejecting the match if it appears to be part of a +longer token. Of course, the concept of {\sl token\/} is +language-dependent, so we may be occasionally mistaken. +For the present, we'll consider the mechanism an experiment. + +@o scraps.c -cc +@{#define sym_char(c) (isalnum(c) || (c) == '_') + +static int op_char(c) + char c; +{ + switch (c) { + case '!': case '#': case '%': case '$': case '^': + case '&': case '*': case '-': case '+': case '=': case '/': + case '|': case '~': case '<': case '>': + return TRUE; + default: + return c==nw_char ? TRUE : FALSE; + } +} +@| sym_char op_char @} + +@o scraps.c -cc +@{static int reject_match(name, post, reader) + Name *name; + char post; + ArgManager *reader; +{ + int len = strlen(name->spelling); + char first = name->spelling[0]; + char last = name->spelling[len - 1]; + char prev = prev_char(reader, len); + if (sym_char(last) && sym_char(post)) return TRUE; + if (sym_char(first) && sym_char(prev)) return TRUE; + if (op_char(last) && op_char(post)) return TRUE; + if (op_char(first) && op_char(prev)) return TRUE; + return FALSE; /* Here is @xother@x */ +} +@| reject_match @} + + +\section{Labels} + +Refer to @xlabel@x. +And another one @xother@x. + +@d Get label from +@{char label_name[MAX_NAME_LEN]; +char * p = label_name; +while (c = @1, c != nw_char) /* Here is @xlabel@x */ + *p++ = c; +*p = '\0'; +c = @1; +@} + +@o scraps.c -cc +@{void +write_label(char label_name[], FILE * file) +@<Search for label(@<Write the label to file@>,@<Complain about missing label@>)@> +@| write_label@} + +@d Function prototypes +@{void write_label(char label_name[], FILE * file); +@} + +@d Write the label to file +@{write_single_scrap_ref(file, lbl->scrap); +fprintf(file, "-%02d", lbl->seq);@} + +@d Complain about missing label +@{fprintf(stderr, "Can't find label %s.\n", label_name);@} + +@d Save label to label store +@{if (label_name[0]) +@<Search for label(@<Complain about duplicate labels@>,@<Create a new label entry@>)@> +else +{ + @<Complain about empty label@> +}@} + +@d Create a new label en... +@{lbl = (label_node *)arena_getmem(sizeof(label_node) + (p - label_name)); +lbl->left = lbl->right = NULL; +strcpy(lbl->name, label_name); +lbl->scrap = current_scrap; +lbl->seq = ++lblseq; +*plbl = lbl;@} + +@d Complain about duplicate labels +@{fprintf(stderr, "Duplicate label %s.\n", label_name);@} + +@d Complain about empty label +@{fprintf(stderr, "Empty label.\n");@} + +@d Search for label(@'Found@',@'Notfound@') +@{{ + label_node * * plbl = &label_tab; + for (;;) + { + label_node * lbl = *plbl; + + if (lbl) + { + int cmp = label_name[0] - lbl->name[0]; + + if (cmp == 0) + cmp = strcmp(label_name + 1, lbl->name + 1); + if (cmp < 0) + plbl = &lbl->left; + else if (cmp > 0) + plbl = &lbl->right; + else + { + @1 + break; + } + } + else + { + @2 + break; + } + } +} +@} + +@o global.c -cc +@{label_node * label_tab = NULL; +@| label_tab@} + +@d Type declarations +@{typedef struct l_node +{ + struct l_node * left, * right; + int scrap, seq; + char name[1]; +} label_node; +@| label_node@} + +@d Global variable declarations +@{extern label_node * label_tab; +@} + + +\section{Memory Management} \label{memory-management} + +I manage memory using a simple scheme inspired by Hanson's idea of +{\em arenas\/}~\cite{hanson:90}. +Basically, I allocate all the storage required when processing a +source file (primarily for names and scraps) using calls to +\verb|arena_getmem(n)|, where \verb|n| specifies the number of bytes to +be allocated. When the storage is no longer required, the entire arena +is freed with a single call to \verb|arena_free()|. Both operations +are quite fast. +@d Function p... +@{extern void *arena_getmem(); +extern void arena_free(); +@} + + +@o arena.c -cc +@{typedef struct chunk { + struct chunk *next; + char *limit; + char *avail; +} Chunk; +@| Chunk @} + + +We define an empty chunk called \verb|first|. The variable \verb|arena| points +at the current chunk of memory; it's initially pointed at \verb|first|. +As soon as some storage is required, a ``real'' chunk of memory will +be allocated and attached to \verb|first->next|; storage will be +allocated from the new chunk (and later chunks if necessary). +@o arena.c -cc +@{static Chunk first = { NULL, NULL, NULL }; +static Chunk *arena = &first; +@| first arena @} + + +\subsection{Allocating Memory} + +The routine \verb|arena_getmem(n)| returns a pointer to (at least) +\verb|n| bytes of memory. Note that \verb|n| is rounded up to ensure +that returned pointers are always aligned. We align to the nearest +8-byte segment, since that'll satisfy the more common 2-byte and +4-byte alignment restrictions too. + +@o arena.c -cc +@{void *arena_getmem(n) + size_t n; +{ + char *q; + char *p = arena->avail; + n = (n + 7) & ~7; /* ensuring alignment to 8 bytes */ + q = p + n; + if (q <= arena->limit) { + arena->avail = q; + return p; + } + @<Find a new chunk of memory@> +} +@| arena_getmem @} + + +If the current chunk doesn't have adequate space (at least \verb|n| +bytes) we examine the rest of the list of chunks (starting at +\verb|arena->next|) looking for a chunk with adequate space. If \verb|n| +is very large, we may not find it right away or we may not find a +suitable chunk at all. +@d Find a new chunk... +@{{ + Chunk *ap = arena; + Chunk *np = ap->next; + while (np) { + char *v = sizeof(Chunk) + (char *) np; + if (v + n <= np->limit) { + np->avail = v + n; + arena = np; + return v; + } + ap = np; + np = ap->next; + } + @<Allocate a new chunk of memory@> +}@} + + +If there isn't a suitable chunk of memory on the free list, then we +need to allocate a new one. +@d Allocate a new ch... +@{{ + size_t m = n + 10000; + np = (Chunk *) malloc(m); + np->limit = m + (char *) np; + np->avail = n + sizeof(Chunk) + (char *) np; + np->next = NULL; + ap->next = np; + arena = np; + return sizeof(Chunk) + (char *) np; +}@} + + +\subsection{Freeing Memory} + +To free all the memory in the arena, we need only point \verb|arena| +back to the first empty chunk. +@o arena.c -cc +@{void arena_free() +{ + arena = &first; +} +@| arena_free @} + +\chapter{Man page} + +Here is the UNIX man page for nuweb: + +@O nuweb.1 @{.TH NUWEB 1 "local 3/22/95" +.SH NAME +Nuweb, a literate programming tool +.SH SYNOPSIS +.B nuweb +.br +\fBnuweb\fP [options] [file] ... +.SH DESCRIPTION +.I Nuweb +is a literate programming tool like Knuth's +.I WEB, +only simpler. +A +.I nuweb +file contains program source code interleaved with documentation. +When +.I nuweb +is given a +.I nuweb +file, it writes the program file(s), +and also +produces, +.I LaTeX +source for typeset documentation. +.SH COMMAND LINE OPTIONS +.br +\fB-t\fP Suppresses generation of the {\tt .tex} file. +.br +\fB-o\fP Suppresses generation of the output files. +.br +\fB-d\fP List dangling identifier references in indexes. +.br +\fB-c\fP Forces output files to overwrite old files of the same + name without comparing for equality first. +.br +\fB-v\fP The verbose flag. Forces output of progress reports. +.br +\fB-n\fP Forces sequential numbering of scraps (instead of page + numbers). +.br +\fB-s\fP Doesn't print list of scraps making up file at end of + each scrap. +\fB-p path\fP Prepend path to the filenames for all the output files. +\fB-V string\fP Provide the string for replacement of the @@v +operation. This is intended as a means for including version +information in generated output. +\fB-x\fP Include cross-references in comments in output files. +\fB-h options\fP Turn on hyperlinks using the hyperref package of +LaTeX and provide the options to the package. +\fB-r\fP Turn on hyperlinks using the hyperref package of +LaTeX, with the package options being in the text. +\fB-I path\fP Provide a directory to search for included files. This +may appear several times. + +.SH FORMAT OF NUWEB FILES +A +.I nuweb +file contains mostly ordinary +.I LaTeX. +The file is read and copied to output (.tex file) unless a +.I nuweb +command is encountered. All +.I nuweb +commands start with an ``at-sign'' (@@). +Files and fragments are defined with the following commands: +.PP +@@o \fIfile-name flags scrap\fP where scrap is smaller than one page. +.br +@@O \fIfile-name flags scrap\fP where scrap is bigger than one page. +.br +@@d \fIfragment-name scrap\fP. Where scrap is smallar than one page. +.br +@@D \fIfragment-name scrap\fP. Where scrap is bigger than one page. +.PP +@@q \fIfragment-name scrap\fP. Where scrap is smallar than one page. +The scrap is not expanded in the output, allowing you to construct +output files which can, perhaps after further processing, be input to +.I nuweb. +.br +@@Q \fIfragment-name scrap\fP. Where scrap is bigger than one page. +Likewise. +.PP +Scraps have specific begin and end +markers; +which begin and end marker you use determines how the scrap will be +typeset in the .tex file: +.br +\fB@@{\fP...\fB@@}\fP for verbatim "terminal style" formatting or, +with the -l flag, LaTeX listing package. +.br +\fB@@[\fP...\fB@@]\fP for LaTeX paragraph mode formatting, and +.br +\fB@@(\fP...\fB@@)\fP for LaTeX math mode formmating. +.br +Any amount of whitespace +(including carriage returns) may appear between a name and the +begining of a scrap. +.PP +Several code/file scraps may have the same name; +.I nuweb +concatenates their definitions to produce a single scrap. +Code scrap definitions are like macro definitions; +.I nuweb +extracts a program by expanding one scrap. +The definition of that scrap contains references to other scraps, which are +themselves expanded, and so on. +\fINuweb\fP's output is readable; it preserves the indentation of expanded +scraps with respect to the scraps in which they appear. +.PP +.SH PER FILE OPTIONS +When defining an output file, the programmer has the option of using flags +to control the output. +.PP +\fB-d\fR option, +.I Nuweb +will emit line number indications at scrap boundaries. +.br +\fB-i\fR option, +.I Nuweb +supresses the indentation of fragments (useful for \fBFortran\fR). +.br +\fB-t\fP option makes \fInuweb\fP +copy tabs untouched from input to output. +.br +\fB-c\fIx\fP Include comments in the output file. +\fIx\fP may be \fBc\fP for C-style comments, \fB+\fP for C++ and +\fBp\fP for perl and similar. +.PP +.SH MINOR COMMANDS +.br +@@@@ Causes a single ``at-sign'' to be copied into the output. +.br +@@\_ Causes the text between it and the next {\tt @@\_} to be made bold + (for keywords, etc.) in the formatted document +.br +@@% Comments out a line so that it doesn't appear in the output. +.br +@@i \fBfilename\fR causes the file named to be included. +.br +@@f Creates an index of output files. +.br +@@m Creates an index of fragments. +.br +@@u Creates an index of user-specified identifiers. +.PP +To mark an identifier for inclusion in the index, it must be mentioned +at the end of the scrap it was defined in. The line starts +with @@| and ends with the \fBend of scrap\fP mark \fB@@}\fP. +.PP +.SH ERROR MESSAGES +.PP +.SH BUGS +.PP +.SH AUTHOR +Preston Briggs. +Internet address \fBpreston@@cs.rice.edu\fP. +.SH MAINTAINER +Simon Wright +Internet address \fBsimon@@pushface.org\fP +.br +Keith Harwood +Internet address \fBKeith.Harwood@@vitalmis.com\fP +@} + +\chapter{Indices} \label{indices} + +Three sets of indices can be created automatically: an index of file +names, an index of fragment names, and an index of user-specified +identifiers. An index entry includes the name of the entry, where it +was defined, and where it was referenced. + +\section{Files} + +@f + +\section{Fragments} + +@m + +\section{Identifiers} + +Knuth prints his index of identifiers in a two-column format. +I could force this automatically by emitting the \verb|\twocolumn| +command; but this has the side effect of forcing a new page. +Therefore, it seems better to leave it this up to the user. + +@u + +\fi + +\bibliographystyle{amsplain} +\bibliography{litprog,master,misc} + +\end{document} diff --git a/nuwebdoc.tex b/nuwebdoc.tex new file mode 100644 index 0000000..556bcec --- /dev/null +++ b/nuwebdoc.tex @@ -0,0 +1,822 @@ +\newcommand{\NWtarget}[2]{\hypertarget{#1}{#2}} +\newcommand{\NWlink}[2]{\hyperlink{#1}{#2}} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +% +% Copyright (c) 1996, Preston Briggs +% All rights reserved. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions +% are met: +% +% Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% Neither name of the product nor the names of its contributors may +% be used to endorse or promote products derived from this software without +% specific prior written permission. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +% ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +% LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +% FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS +% OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +% PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +% OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +% + +% Notes: +% Update on 2011-12-16 from Keith Harwood. +% -- @s in scrap supresses indent of following fragment expansion +% -- @<Name@> in text is expanded +% Update on 2011-04-20 from Keith Harwood. +% -- @t provide fragment title in output +% Changes from 2010-03-11 in the Sourceforge revision history. -- sjw +% Updates on 2004-02-23 from Gregor Goldbach +% <glauschwuffel@users.sourceforge.net> +% -- new command line option -r which will make nuweb typeset each +% NWtarget and NWlink instance with \LaTeX-commands from the hyperref +% package. This gives clickable scrap numbers which is very useful +% when viewing the document on-line. + +% Updates on 2004-02-13 from Gregor Goldbach +% <glauschwuffel@users.sourceforge.net> +% -- new command line option -l which will make nuweb typeset scraps +% with the help of LaTeX's listings packages instead or pure +% verbatim. +% -- man page corrections and additions. + +% Updates on 2003-04-24 from Keith Harwood <Keith.Harwood@vitalmis.com> +% -- sectioning commands (@s and global-plus-sign in scrap names) +% -- @x..@x labelling +% -- @f current file +% -- @\# suppress indent + +% This file has been changed by Javier Goizueta <jgoizueta@jazzfree.es> +% on 2001-02-15. +% These are the changes: +% LANG -- Introduction of \NW macros to substitue language dependent text +% DIAM -- Introduction of \NWsep instead of the \diamond separator +% HYPER -- Introduction of hyper-references +% NAME -- LaTeX formatting of macro names in HTML output +% ADJ -- Adjust of the spacing between < and a fragment name +% TEMPN -- Fix of the use of tempnam +% LINE -- Synchronizing #lines when @% is used +% MAC -- definition of the macros used by LANG,DIAM,HYPER +% CHAR -- Introduce @r to change the nuweb meta character (@) +% TIE -- Replacement of ~ by "\nobreak\ " +% SCRAPs-- Elimination of s +% DNGL -- Correction: option -d was not working and was misdocumented +% --after the CHAR modifications, to be able to specify non-ascii characters +% for the scape character, the program must be compiled with the -K +% option in Borland compilers or the -funsigned-char in GNU's gcc +% to treat char as an unsigned value when converted to int. +% To make the program independent of those options, either char +% should be changed to unsigned char (bad solution, since unsigned +% char should be used for numerical purposes) or attention should +% be payed to all char-int conversions. (including comparisons) + +% --2002-01-15: the TILDE modificiation is necessary because some ties +% have been introduced in version 0.93 in troublesome places when +% the babel package is used with the spanish.ldf option (which makes +% ~ an active character). + +% --2002-01-15: an ``s'' was being added to the NWtxtDefBy and +% NWtxtDefBy messages when followed by more than one reference. + +\documentclass[a4paper]{report} +\newif\ifshowcode +\showcodetrue + +\usepackage{latexsym} +%\usepackage{html} + +\usepackage{listings} + +\usepackage{color} +\definecolor{linkcolor}{rgb}{0, 0, 0.7} + +\usepackage[% +backref,% +raiselinks,% +pdfhighlight=/O,% +pagebackref,% +hyperfigures,% +breaklinks,% +colorlinks,% +pdfpagemode=None,% +pdfstartview=FitBH,% +linkcolor={linkcolor},% +anchorcolor={linkcolor},% +citecolor={linkcolor},% +filecolor={linkcolor},% +menucolor={linkcolor},% +pagecolor={linkcolor},% +urlcolor={linkcolor}% +]{hyperref} + +\setlength{\oddsidemargin}{0in} +\setlength{\evensidemargin}{0in} +\setlength{\topmargin}{0in} +\addtolength{\topmargin}{-\headheight} +\addtolength{\topmargin}{-\headsep} +\setlength{\textheight}{8.9in} +\setlength{\textwidth}{6.5in} +\setlength{\marginparwidth}{0.5in} + +\title{Nuweb Version 1.62 \\ A Simple Literate Programming Tool} +\date{} +\author{Preston Briggs\thanks{This work has been supported by ARPA, +through ONR grant N00014-91-J-1989.} +\\ {\sl preston@tera.com} +\\ HTML scrap generator by John D. Ramsdell +\\ {\sl ramsdell@mitre.org} +\\ Scrap formatting by Marc W. Mengel +\\ {\sl mengel@fnal.gov} +\\ Continuing maintenance by Simon Wright +\\ {\sl simon@pushface.org} +\\ and Keith Harwood +\\ {\sl Keith.Harwood@vitalmis.com}} + +\begin{document} +\pagenumbering{roman} +\maketitle +\tableofcontents + +\chapter{Introduction} +\pagenumbering{arabic} + +In 1984, Knuth introduced the idea of {\em literate programming\/} and +described a pair of tools to support the practise~\cite{Knuth:CJ-27-2-97}. +His approach was to combine Pascal code with \TeX\ documentation to +produce a new language, \verb|WEB|, that offered programmers a superior +approach to programming. He wrote several programs in \verb|WEB|, +including \verb|weave| and \verb|tangle|, the programs used to support +literate programming. +The idea was that a programmer wrote one document, the web file, that +combined documentation (written in \TeX~\cite{Knuth:ct-a}) with code +(written in Pascal). + +Running \verb|tangle| on the web file would produce a complete +Pascal program, ready for compilation by an ordinary Pascal compiler. +The primary function of \verb|tangle| is to allow the programmer to +present elements of the program in any desired order, regardless of +the restrictions imposed by the programming language. Thus, the +programmer is free to present his program in a top-down fashion, +bottom-up fashion, or whatever seems best in terms of promoting +understanding and maintenance. + +Running \verb|weave| on the web file would produce a \TeX\ file, ready +to be processed by \TeX\@. The resulting document included a variety of +automatically generated indices and cross-references that made it much +easier to navigate the code. Additionally, all of the code sections +were automatically prettyprinted, resulting in a quite impressive +document. + +Knuth also wrote the programs for \TeX\ and {\small\sf METAFONT} +entirely in \verb|WEB|, eventually publishing them in book +form~\cite{Knuth:ct-b,Knuth:ct-d}. These are probably the +largest programs ever published in a readable form. + +Inspired by Knuth's example, many people have experimented with +\verb|WEB|\@. Some people have even built web-like tools for their +own favorite combinations of programming language and typesetting +language. For example, \verb|CWEB|, Knuth's current system of choice, +works with a combination of C (or C++) and \TeX~\cite{Levy:TB8-1-12}. +Another system, FunnelWeb, is independent of any programming language +and only mildly dependent on \TeX~\cite{Williams:FUM92}. Inspired by the +versatility of FunnelWeb and by the daunting size of its +documentation, I decided to write my own, very simple, tool for +literate programming.% +\footnote{There is another system similar to +mine, written by Norman Ramsey, called {\em noweb}~\cite{Ramsey:LPT92}. It +perhaps suffers from being overly Unix-dependent and requiring several +programs to use. On the other hand, its command syntax is very nice. +In any case, nuweb certainly owes its name and a number of features to +his inspiration.} + + +\section{Nuweb} + +Nuweb works with any programming language and \LaTeX~\cite{Lamport:LDP85}. I +wanted to use \LaTeX\ because it supports a multi-level sectioning +scheme and has facilities for drawing figures. I wanted to be able to +work with arbitrary programming languages because my friends and I +write programs in many languages (and sometimes combinations of +several languages), {\em e.g.,} C, Fortran, C++, yacc, lex, Scheme, +assembly, Postscript, and so forth. The need to support arbitrary +programming languages has many consequences: +\begin{description} +\item[No prettyprinting] Both \verb|WEB| and \verb|CWEB| are able to + prettyprint the code sections of their documents because they + understand the language well enough to parse it. Since we want to use + {\em any\/} language, we've got to abandon this feature. + However, we do allow particular individual formulas or fragments + of \LaTeX\ code to be formatted and still be parts of output files. + Also, keywords in scraps can be surrounded by \verb|@_| to + have them be bold in the output. +\item[No index of identifiers] Because \verb|WEB| knows about Pascal, + it is able to construct an index of all the identifiers occurring in + the code sections (filtering out keywords and the standard type + identifiers). Unfortunately, this isn't as easy in our case. We don't + know what an identifier looks like in each language and we certainly + don't know all the keywords. (On the other hand, see the end of + Section~\ref{minorcommands}) +\end{description} +Of course, we've got to have some compensation for our losses or the +whole idea would be a waste. Here are the advantages I can see: +\begin{description} +\item[Simplicity] The majority of the commands in \verb|WEB| are + concerned with control of the automatic prettyprinting. Since we + don't prettyprint, many commands are eliminated. A further set of + commands is subsumed by \LaTeX\ and may also be eliminated. As a + result, our set of commands is reduced to only four members (explained + in the next section). This simplicity is also reflected in + the size of this tool, which is quite a bit smaller than the tools + used with other approaches. +\item[No prettyprinting] Everyone disagrees about how their code + should look, so automatic formatting annoys many people. One approach + is to provide ways to control the formatting. Our approach is + simpler---we perform no automatic formatting and therefore allow the + programmer complete control of code layout. + We do allow individual scraps to be presented in either verbatim, + math, or paragraph mode in the \TeX\ output. +\item[Control] We also offer the programmer complete control of the + layout of his output files (the files generated during tangling). Of + course, this is essential for languages that are sensitive to layout; + but it is also important in many practical situations, {\em e.g.,} + debugging. +\item[Speed] Since nuweb doesn't do too much, the nuweb tool runs + quickly. I combine the functions of \verb|tangle| and \verb|weave| into + a single program that performs both functions at once. +\item[Page numbers] Inspired by the example of noweb, nuweb refers to + all scraps by page number to simplify navigation. If there are + multiple scraps on a page (say, page~17), they are distinguished by + lower-case letters ({\em e.g.,} 17a, 17b, and so forth). +\item[Multiple file output] The programmer may specify more than one + output file in a single nuweb file. This is required when constructing + programs in a combination of languages (say, Fortran and C)\@. It's also + an advantage when constructing very large programs that would require + a lot of compile time. +\end{description} +This last point is very important. By allowing the creation of +multiple output files, we avoid the need for monolithic programs. +Thus we support the creation of very large programs by groups of +people. + +A further reduction in compilation time is achieved by first +writing each output file to a temporary location, then comparing the +temporary file with the old version of the file. If there is no +difference, the temporary file can be deleted. If the files differ, +the old version is deleted and the temporary file renamed. This +approach works well in combination with \verb|make| (or similar tools), +since \verb|make| will avoid recompiling untouched output files. + +\subsection{Nuweb and HTML} + +In addition to producing {\LaTeX} source, nuweb can be used to +generate HyperText Markup Language (HTML), the markup language used by +the World Wide Web. HTML provides hypertext links. When an HTML +document is viewed online, a user can navigate within the document by +activating the links. The tools which generate HTML automatically +produce hypertext links from a nuweb source. + +(Note that hyperlinks can be included in \LaTeX\ using the +\verb|hyperref| package. This is now the preferred way of doing +this and the HTML processing is not up to date.) + +\section{Writing Nuweb} + +The bulk of a nuweb file will be ordinary \LaTeX\@. In fact, any +{\LaTeX} file can serve as input to nuweb and will be simply copied +through, unchanged, to the documentation file---unless a nuweb command +is discovered. All nuweb commands begin with an ``at-sign'' +(\verb|@|). Therefore, a file without at-signs will be copied +unchanged. Nuweb commands are used to specify {\em output files,} +define {\em fragments,} and delimit {\em scraps}. These are the basic +features of interest to the nuweb tool---all else is simply text to be +copied to the documentation file. + +\subsection{The Major Commands} + +Files and fragments are defined with the following commands: +\begin{description} +\item[{\tt @o} {\em file-name flags scrap\/}] Output a file. The file + name is terminated by whitespace. +\item[{\tt @d} {\em fragment-name scrap\/}] Define a fragment. The + fragment name is terminated by a return or the beginning of a scrap. +\item[{\tt @q} {\em fragment-name scrap\/}] Define a fragment. The + fragment name is terminated by a return or the beginning of a scrap. + This a quoted fragment. +\end{description} +A specific file may be specified several times, with each definition +being written out, one after the other, in the order they appear. +The definitions of fragments may be similarly specified piecemeal. + +A fragment name may have embedded parameters. The parameters are +denoted by the sequence \texttt{@'value@'} where \texttt{value} is +an uninterpreted string of characters (although the sequence +\texttt{@@} denotes a single \texttt{@} character). When a fragment +name is used inside a scrap the parameters may be replaced by an +argument which may be a different literal string, a fragment use, an +embedded fragment or by a parameter use. + +The difference between a quoted fragment (\texttt{@q}) and an +ordinary one (\texttt{@d}) is that inside a quoted fragment fragments +are not expanded on output. Rather, they are formatted as uses of +fragments so that the output file can itself be \texttt{nuweb} +source. This allows you to create files containing fragments which can +undergo further processing before the fragments are expanded, while +also describing and documenting them in one place. + +You can have both quoted and unquoted fragments with the same +name. They are written out in order as usual, with those introduced by +\texttt{@q} being quoted and those with \texttt{@d} expanded as +normal. + +In quoted fragments, the \texttt{@f} filename is quoted as well, so that +when it is expanded it refers to the finally produced file, not +any of the intermediate ones. + +\subsubsection{Scraps} + +Scraps have specific begin markers and end markers to allow precise +control over the contents and layout. Note that any amount of +whitespace (including carriage returns) may appear between a name and +the beginning of a scrap. Scraps may also appear in the running text +where they are formatted (almost) identically to their use in definitions, +but don't appear in any code output. +\begin{description} +\item[\tt @\{{\em anything\/}@\}] where the scrap body includes every + character in {\em anything\/}---all the blanks, all the tabs, all the + carriage returns. This scrap will be typeset in verbatim mode. Using + the \texttt{-l} option will cause the program to typeset the scrap with + the help of \LaTeX's \texttt{listings} package. +\item[\tt @[{\em anything\/}@]] where the scrap body includes every + character in {\em anything\/}---all the blanks, all the tabs, all the + carriage returns. This scrap will be typeset in paragraph mode, allowing + sections of \TeX\ documents to be scraps, but still be prettyprinted + in the document. +\item[\tt @({\em anything\/}@)] where the scrap body includes every + character in {\em anything\/}---all the blanks, all the tabs, all the + carriage returns. This scrap will be typeset in math mode. This allows + this scrap to contain a formula which will be typeset nicely. +\end{description} +Inside a scrap, we may invoke a fragment. +\begin{description} +\item[\tt @<{\em fragment-name\/}@>] + This is a fragment use. It causes the fragment + {\em fragment-name\/} to be expanded inline as the code is written out + to a file. It is an error to specify recursive fragment invocations. +\item[\tt @<{\em fragment-name\/}@( {\em a1} @, {\em a2} @) @>] This + is the old form of parameterising a fragment. It causes the fragment + {\em fragment-name\/} to be expanded inline with the arguments {\em a1}, + {\em a2}, etc. Up to 9 arguments may be given. +\item[\tt @1, @2, ..., @9] In a fragment causes the n'th fragment + argument to be substituted into the scrap. If the argument + is not passed, a null string is substituted. + Arguments can be passed in two ways, either embedded in the + fragment + name or as the old form given above. + + An embedded argument may specified in four ways. + \begin{description} + \item[\tt @'string@'] + The string will be copied literally into the called fragment. + It will not be interpreted (except for \texttt{@@} converted + to \texttt{@}). + \item[\tt @<{\em fragment-name\/}@>] + The fragment will be expanded in the usual fashion and the results + passed to the called fragment. + \item[\tt @\{text@\}] + The text will be expanded as normal and the results passed to + the called fragment. This behaves like an anonymous fragment which has + the same arguments as the calling fragment. Its principle use is + to combine text and arguments into one argument. + \item[\tt @1, @2, ..., @9] + The argument of the calling fragment will be passed to the called + fragment and expanded in there. + \end{description} + + If an argument is used but there is no corresponding parameter + in the fragment name, the null string is substituted. But what + happens if there is a parameter in the full name of a fragment, + but a particular application of the fragment is abbreviated + (using the \verb|. . .| notation) and the argument is missed? In + that case the argument is replaced by the string given in the + definition of the fragment. + + In the old form the parameter may contain any text and will be + expanded as a normal scrap. The two forms of parameter passing + don't play nicely together. If a scrap passes both embedded and + old form arguments the old form arguments are ignored. +\item[\tt @x{\em label}@x] Marks a place inside a scrap and +associates it to the label (which can be any text not containing +a @). Expands to the reference number of the scrap followed by a +numeric value. Outside scraps it expands to the same value. It is +used so that text outside scraps can refer to particular places +within scraps. +\item[\tt @f] Inside a scrap this is replaced by the name of the +current output file. +\item[\tt @t] Inside a scrap this is replaced by the title of the +fragment as it is at the point it is used, with all parameters +replaced by actual arguments. +\item[\tt @\#] At the beginning of a line in a scrap this will +suppress the normal indentation for that line. Use this, for +example, when you have a \verb|#ifdef| inside a nested scrap. +Writing \verb|@##ifdef| will cause it to be lined up on the left +rather than indented with the rest of its code. +\item[\tt @s] Inside a scrap supresses indentation for the following +fragment expansion. +\end{description} +Note that fragment names may be abbreviated, either during invocation or +definition. For example, it would be very tedious to have to +type, repeatedly, the fragment name +\begin{quote} +\verb|@d Check for terminating at-sequence and return name if found| +\end{quote} +Therefore, we provide a mechanism (stolen from Knuth) of indicating +abbreviated names. +\begin{quote} +\verb|@d Check for terminating...| +\end{quote} +Basically, the programmer need only type enough characters to +identify the fragment name uniquely, followed by three periods. An abbreviation +may even occur before the full version; nuweb simply preserves the +longest version of a fragment name. Note also that blanks and tabs are +insignificant within a fragment name; each string of them is replaced by a +single blank. + +Sometimes, for instance during program testing, it is convenient to comment +out a few lines of code. In C or Fortran placing \verb|/* ... */| around the relevant +code is not a robust solution, as the code itself may contain +comments. Nuweb provides the command +\begin{quote} +\verb|@%| +\end{quote}only to be used inside scraps. It behaves exactly the same +as \verb|%| in the normal {\LaTeX} text body. + +When scraps are written to a program file or a documentation file, tabs are +expanded into spaces by default. Currently, I assume tab stops are set +every eight characters. Furthermore, when a fragment is expanded in a scrap, +the body of the fragment is indented to match the indentation of the +fragment invocation. Therefore, care must be taken with languages +({\em e.g.,} Fortran) that are sensitive to indentation. +These default behaviors may be changed for each output file (see +below). + +\subsubsection{Flags} + +When defining an output file, the programmer has the option of using +flags to control output of a particular file. The flags are intended +to make life a little easier for programmers using certain languages. +They introduce little language dependences; however, they do so only +for a particular file. Thus it is still easy to mix languages within a +single document. There are four ``per-file'' flags: +\begin{description} +\item[\tt -d] Forces the creation of \verb|#line| directives in the + output file. These are useful with C (and sometimes C++ and Fortran) on + many Unix systems since they cause the compiler's error messages to + refer to the web file rather than to the output file. Similarly, they + allow source debugging in terms of the web file. +\item[\tt -i] Suppresses the indentation of fragments. That is, when a + fragment is expanded within a scrap, it will {\em not\/} be indented to + match the indentation of the fragment invocation. This flag would seem + most useful for Fortran programmers. +\item[\tt -t] Suppresses expansion of tabs in the output file. This + feature seems important when generating \verb|make| files. +\item[\tt -c{\it x}] Puts comments in generated code documenting the +fragment that generated that code. The {\it x} selects the comment style +for the language in use. So far the only valid values are \verb|c| to get +\verb|C| comment style, \verb|+| for \verb|C++| and \verb|p| for +\verb|Perl|. (\verb|Perl| commenting can be used for several languages +including \verb|sh| and, mostly, \verb|tcl|.) +If the global \verb|-x| cross-reference flag is +set the comment includes the page reference for the first scrap that +generated the code. +\end{description} + + +\subsection{The Minor Commands\label{minorcommands}} + +We have some very low-level utility commands that may appear anywhere +in the web file. +\begin{description} +\item[\tt @@] Causes a single ``at sign'' to be copied into the output. +\item[\tt @\_] Causes the text between it and the next {\tt @\_} + to be made bold (for keywords, etc.) +\item[\tt @i {\em file-name\/}] Includes a file. Includes may be + nested, though there is currently a limit of 10~levels. The file name + should be complete (no extension will be appended) and should be + terminated by a carriage return. Normally the current directory is + searched for the file to be included, but this can be varied using + the \verb|-I| flag on the command line. Each such flag adds one + directory tothe search path and they are searched in the order + given. +\item[{\tt @r}$x$] Changes the escape character `@' to `$x$'. + This must appear before any scrap definitions. +\item[\tt @v] Always replaced by the string established by +the \texttt{-V} flag, or a default string if the flag isn't +given. This is intended to mark versions of the generated +files. +\end{description} + +In the text of the document, that is outside scraps, you may include +scrap-like material. + +\begin{description} +\item[\tt @\{\textit{Anything}@\}] +The included material, the \textit{Anything}, +is typeset as if it appeared inside a scrap. This is useful for +referring to fragments in the text and for +describing the literate programming process itself. +\item[\tt @<\textit{Fragment name}@>] +The fragment named is expanded in place in the text. +The expansion is presented verbatim, it is not interpretted for +typesetting, so any special environment must be set up before and +after this is used. +\end{description} + +Finally, there are three commands used to create indices to the +fragment +names, file definitions, and user-specified identifiers. +\begin{description} +\item[\tt @f] Create an index of file names. +\item[\tt @m] Create an index of fragment names. +\item[\tt @u] Create an index of user-specified identifiers. +\end{description} +I usually put these in their own section +in the \LaTeX\ document; for example, see Chapter~\ref{indices}. + +Identifiers must be explicitly specified for inclusion in the +\verb|@u| index. By convention, each identifier is marked at the +point of its definition; all references to each identifier (inside +scraps) will be discovered automatically. To ``mark'' an identifier +for inclusion in the index, we must mention it at the end of a scrap. +For example, +\begin{quote} +\begin{verbatim} +@d a scrap @{ +Let's pretend we're declaring the variables FOO and BAR +inside this scrap. +@| FOO BAR @} +\end{verbatim} +\end{quote} +I've used alphabetic identifiers in this example, but any string of +characters (not including whitespace or \verb|@| characters) will do. +Therefore, it's possible to add index entries for things like +\verb|<<=| if desired. An identifier may be declared in more than one +scrap. + +In the generated index, each identifier appears with a list of all the +scraps using and defining it, where the defining scraps are +distinguished by underlining. Note that the identifier doesn't +actually have to appear in the defining scrap; it just has to be in +the list of definitions at the end of a scrap. + +\section{Sectioning commands} +For larger documents the indexes and usage lists get rather +unwieldy and problems arise in naming things so that different +things in different parts of the document don't get confused. We +have a sectioning command which keeps the fragment names and user +identifiers separate. Thus, you can give a fragment in one section +the same name as a fragment in another and the two won't be confused +or connected in any way. Nor will user identifiers +defined in one section be referenced in another. Except for the +fact that scraps in successive sections can go into the same +output file, this is the same as if the sections came from +separate input files. + +However, occasionally you may really want fragments from one section +to be used in another. More often, you will want to identify a +user identifier in one section with the same identifier in +another (as, for example, a header file defined in one section is +included in code in another). Extra commands allow a fragment +defined in one section to be accessible from all other sections. +Similarly, you can have scraps which define user identifiers and +export them so that they can be used in other sections. + +\begin{description} +\item[{\tt @s}] Start a new section. +\item[{\tt @S}] Close the current section and don't start another. +\item[{\tt @d+} fragment-name scrap] Define a fragment which is +accessible in all sections, a global fragment. +\item[{\tt @D+}] Likewise +\item[{\tt @q+}] Likewise +\item[{\tt @Q+}] Likewise +\item[{\tt @m+}] Create an index of all such fragments. +\item[{\tt @u+}] Create an index of globally accessible +user identifiers. +\end{description} + +There are two kinds of section, the base section which is where +normally everything goes, and local sections which are introduced with +the {\tt @s} command. A local section comprises everything from the +command which starts it to the one which ends it. A {\tt @s} command +will start a new local section. A {\tt @S} command closes the current +local section, but doesn't open another, so what follows goes into the +base section. Note that fragments defined in the base section aren't +global; they are accessible only in the base section, but they are +accessible regardless of any local sections between their definition +and their use. + +Within a scrap: +\begin{description} +\item[\tt @<+{\em fragment-name\/}@>] +Expand the globally accessible fragment with that name, rather than +any local fragment. +\item[{\tt @+}] Like \verb"@|" except that the identifiers +defined are exported to the global realm and are not directly +referenced in any scrap in any section (not even the one where +they are defined). +\item[{\tt @-}] Like \verb"@|" except that the identifiers +are imported to the local realm. The cross-references show where +the global variables are defined and defines the same names as +locally accesible. Uses of the names within the section will +point to this scrap. +\end{description} + +Note that the \verb"+" signs above are part of the commands. They +are not part of the fragment names. If you want a fragment whose name +begins with a plus sign, leave a space between the command and the +name. + +\section{Running Nuweb} + +Nuweb is invoked using the following command: +\begin{quote} +{\tt nuweb} {\em flags file-name}\ldots +\end{quote} +One or more files may be processed at a time. If a file name has no +extension, \verb|.w| will be appended. {\LaTeX} suitable for +translation into HTML by {\LaTeX}2HTML will be produced from +files whose name ends with \verb|.hw|, otherwise, ordinary {\LaTeX} will be +produced. While a file name may specify a file in another directory, +the resulting documentation file will always be created in the current +directory. For example, +\begin{quote} +{\tt nuweb /foo/bar/quux} +\end{quote} +will take as input the file \verb|/foo/bar/quux.w| and will create the +file \verb|quux.tex| in the current directory. + +By default, nuweb performs both tangling and weaving at the same time. +Normally, this is not a bottleneck in the compilation process; +however, it's possible to achieve slightly faster throughput by +avoiding one or another of the default functions using command-line +flags. There are currently three possible flags: +\begin{description} +\item[\tt -t] Suppress generation of the documentation file. +\item[\tt -o] Suppress generation of the output files. +\item[\tt -c] Avoid testing output files for change before updating them. +\end{description} +Thus, the command +\begin{quote} +\verb|nuweb -to /foo/bar/quux| +\end{quote} +would simply scan the input and produce no output at all. + +There are several additional command-line flags: +\begin{description} +\item[\tt -v] For ``verbose'', causes nuweb to write information about + its progress to \verb|stderr|. +\item[\tt -n] Forces scraps to be numbered sequentially from~1 + (instead of using page numbers). This form is perhaps more desirable + for small webs. +\item[\tt -s] Doesn't print list of scraps making up each file + following each scrap. +\item[\tt -d] Print ``dangling'' identifiers -- user identifiers which + are never referenced, in indices, etc. +\item[\tt -p {\it path}] Prepend \textit{path} to the filenames for +all the output files. +\item[\tt -l] \label{sec:pretty-print} Use the \texttt{listings} +package for formatting scraps. Use this if you want to have a +pretty-printer for your scraps. In order to e.g. have pretty Perl +scraps, include the following \LaTeX\ commands in your document: +\lstset{language=[LaTeX]TeX} + +\begin{lstlisting}{language={[LaTeX]TeX}} +\usepackage{listings} +... +\lstset{extendedchars=true,keepspaces=true,language=perl} +\end{lstlisting} + +See the \texttt{listings} documentation for a list of formatting +options. Be sure to include a \texttt{\char92 +usepackage\{listings\}} +in your document. + +\item[\tt -V \it string] Provide \textit{string} as the +replacement for the @v operation. +\end{description} + +\section{Generating HTML} + +Nikos Drakos' {\LaTeX}2HTML Version 0.5.3~\cite{drakos:94} can be used +to translate {\LaTeX} with embedded HTML scraps into HTML\@. Be sure +to include the document-style option \verb|html| so that {\LaTeX} will +understand the hypertext commands. When translating into HTML, do not +allow a document to be split by specifying ``\verb|-split 0|''. +You need not generate navigation links, so also specify +``\verb|-no_navigation|''. + +While preparing a web, you may want to view the program's scraps without +taking the time to run {\LaTeX}2HTML\@. Simply rename the generated +{\LaTeX} source so that its file name ends with \verb|.html|, and view +that file. The documentations section will be jumbled, but the +scraps will be clear. + +(Note that the HTML generation is not currently maintained. If the +only reason you want HTML is ti get hyperlinks, use the {\LaTeX} +\verb|hyperref| package and produce your document as PDF via +\verb|pdflatex|.) + +\section{Restrictions} + +Because nuweb is intended to be a simple tool, I've established a few +restrictions. Over time, some of these may be eliminated; others seem +fundamental. +\begin{itemize} +\item The handling of errors is not completely ideal. In some cases, I + simply warn of a problem and continue; in other cases I halt + immediately. This behavior should be regularized. +\item I warn about references to fragments that haven't been defined, but + don't halt. The name of the fragment is included in the output file + surrounded by \verb|<>| signs. + This seems most convenient for development, but may change + in the future. +\item File names and index entries should not contain any \verb|@| + signs. +\item Fragment names may be (almost) any well-formed \TeX\ string. + It makes sense to change fonts or use math mode; however, care should + be taken to ensure matching braces, brackets, and dollar signs. + When producing HTML, fragments are displayed in a preformatted element + (PRE), so fragments may contain one or more A, B, I, U, or P elements + or data characters. +\item Anything is allowed in the body of a scrap; however, very + long scraps (horizontally or vertically) may not typeset well. +\item Temporary files (created for comparison to the eventual + output files) are placed in the current directory. Since they may be + renamed to an output file name, all the output files should be on the + same file system as the current directory. Alternatively, you can + use the \verb|-p| flag to specify where the files go. +\item Because page numbers cannot be determined until the document has + been typeset, we have to rerun nuweb after \LaTeX\ to obtain a clean + version of the document (very similar to the way we sometimes have + to rerun \LaTeX\ to obtain an up-to-date table of contents after + significant edits). Nuweb will warn (in most cases) when this needs + to be done; in the remaining cases, \LaTeX\ will warn that labels + may have changed. +\end{itemize} +Very long scraps may be allowed to break across a page if declared +with \verb|@O| or \verb|@D| (instead of \verb|@o| and \verb|@d|). +This doesn't work very well as a default, since far too many short +scraps will be broken across pages; however, as a user-controlled +option, it seems very useful. No distinction is made between the +upper case and lower case forms of these commands when generating +HTML\@. + +\section{Acknowledgements} + +Several people have contributed their times, ideas, and debugging +skills. In particular, I'd like to acknowledge the contributions of +Osman Buyukisik, Manuel Carriba, Adrian Clarke, Tim Harvey, Michael +Lewis, Walter Ravenek, Rob Shillingsburg, Kayvan Sylvan, Dominique +de~Waleffe, and Scott Warren. Of course, most of these people would +never have heard or nuweb (or many other tools) without the efforts of +George Greenwade. + +Since maintenance has been taken over by Marc Mengel, Simon Wright and +Keith Harwood online contributions have been made by: +\begin{itemize} +\item Walter Brown \verb|<wb@fnal.gov>| +\item Nicky van Foreest \verb|<n.d.vanforeest@math.utwente.nl>| +\item Javier Goizueta \verb|<jgoizueta@jazzfree.com>| +\item Alan Karp \verb|<karp@hp.com>| +\end{itemize} + + +\bibliographystyle{amsplain} +\bibliography{litprog,master,misc} + +\end{document} diff --git a/nuwebsty.w b/nuwebsty.w new file mode 100644 index 0000000..668d7e4 --- /dev/null +++ b/nuwebsty.w @@ -0,0 +1,92 @@ +% nuwebsty.w -- styles for use with nuweb +% (c) 2001 Javier Goizueta + +\documentclass{report} + +%\usepackage{html} + +\title{Nuweb Redefinitions} +\date{} +\author{Javier Goizueta} + +\begin{document} + +I've changed \verb|nuweb| to use macros instead of +some fixed strings. The modified \verb|nuweb| inserts +default values of those macros at the beginning of +the produced \LaTeX\ file. +The macros I've introduced and their default values are as follows. +\begin{itemize} +\item +\verb|\NWtarget| has two arguments just like \verb|hyperref|'s +\verb|\hypertarget| and by default simply places the second argument +in the output. It's used as a placeholder to introduce hyperlinks. +\item +\verb|\NWlink| has two arguments just like \verb|hyperref|'s +\verb|\hyperlink| and by default simply places the second argument in +the output. It's used as a placeholder to introduce hyper links. +\item +\verb|\NWtxtMacroDefBy| its default value is the string ``Macro defined by'' +and it's used to replace that string in other languages. +\item +\verb|\NWtxtMacroRefIn| its default value is the string ``Macro referenced in'' +and it's used to replace that string in other languages. +\item +\verb|\NWtxtMacroNoRef| its default value is the string ``Macro never referenced'' +and it's used to replace that string in other languages. +\item +\verb|\NWtxtDefBy| its default value is the string ``Defined by'' +and it's used to replace that string in other languages. +\item +\verb|\NWtxtRefIn| its default value is the string ``Referenced in'' +and it's used to replace that string in other languages. +\item +\verb|\NWtxtNoRef| its default value is the string ``Not referenced'' +and it's used to replace that string in other languages. +\item +\verb|\NWtxtFileDefBy| its default value is the string ``File defined by'' +and it's used to replace that string in other languages. +\item +\verb|\NWsep| is used as an end marker for scraps; its default value is +\verb|$\Diamond $|. +\end{itemize} + +These macros can be redefined in the \LaTeX\ file to adapt +the output to the taste of the user. I define here two files +to redefine the macros to include hyper-links from the +\verb|hyper-ref| package in the documentation (which works for +example in pdf output) in english and spanish. +These files can be included with \verb|\usepackage| in the +documentation part. + +Here's the english hyper-ref version: + +@o nwhren.sty +@{% nwhren.sty -- nuweb macros for hyperref in english +@<Hyper-ref macros@> +@} + +@d Hyper-ref macros +@{@% +\renewcommand{\NWtarget}[2]{\hypertarget{#1}{#2}} +\renewcommand{\NWlink}[2]{\hyperlink{#1}{#2}} +@} + +For the spanish version I'm using the spanish \emph{fragmento} ---whose meaning +is close to ``scrap''--- for the term ``macro''. +I like this but many spanish people involved with computer science use \emph{macro} +itself in spanish. + +@o nwhres.sty +@{% nwhres.sty -- nuweb macros for hyperref in spanish +@<Hyper-ref macros@> +\renewcommand{\NWtxtMacroDefBy}{Fragmento definido en} % Macro defined by +\renewcommand{\NWtxtMacroRefIn}{Fragmento usado en} % Macro referenced in +\renewcommand{\NWtxtMacroNoRef}{Fragmento no usado} % Macro never referenced +\renewcommand{\NWtxtDefBy}{Definido en} % Defined by +\renewcommand{\NWtxtRefIn}{Usado en} % Referenced in +\renewcommand{\NWtxtNoRef}{No usado} % Not referenced +\renewcommand{\NWtxtFileDefBy}{Archivo definido en} % File defined by +@} + +\end{document} diff --git a/output.c b/output.c new file mode 100644 index 0000000..cb8ef44 --- /dev/null +++ b/output.c @@ -0,0 +1,101 @@ +#include "global.h" +void write_files(files) + Name *files; +{ + while (files) { + write_files(files->llink); + /* Write out \verb|files->spelling| */ + { + static char temp_name[FILENAME_MAX]; + static char real_name[FILENAME_MAX]; + static int temp_name_count = 0; + char indent_chars[MAX_INDENT]; + FILE *temp_file; + + /* Find a free temporary file */ + + for( temp_name_count = 0; temp_name_count < 10000; temp_name_count++) { + sprintf(temp_name,"%s%snw%06d", dirpath, path_sep, temp_name_count); + #ifdef O_EXCL + if (-1 != (temp_file_fd = open(temp_name, O_CREAT|O_WRONLY|O_EXCL))) { + temp_file = fdopen(temp_file_fd, "w"); + break; + } + #else + if (0 != (temp_file = fopen(temp_name, "a"))) { + if ( 0L == ftell(temp_file)) { + break; + } else { + fclose(temp_file); + temp_file = 0; + } + } + #endif + } + if (!temp_file) { + fprintf(stderr, "%s: can't create %s for a temporary file\n", + command_name, temp_name); + exit(-1); + } + + + sprintf(real_name, "%s%s%s", dirpath, path_sep, files->spelling); + if (verbose_flag) + fprintf(stderr, "writing %s [%s]\n", files->spelling, temp_name); + write_scraps(temp_file, files->spelling, files->defs, 0, indent_chars, + files->debug_flag, files->tab_flag, files->indent_flag, + files->comment_flag, NULL, NULL, 0, files->spelling); + fclose(temp_file); + + /* Move the temporary file to the target, if required */ + + if (compare_flag) + /* Compare the temp file and the old file */ + { + FILE *old_file = fopen(real_name, "r"); + if (old_file) { + int x, y; + temp_file = fopen(temp_name, "r"); + do { + x = getc(old_file); + y = getc(temp_file); + } while (x == y && x != EOF); + fclose(old_file); + fclose(temp_file); + if (x == y) + remove(temp_name); + else { + remove(real_name); + /* Rename the temporary file to the target */ + + if (0 != rename(temp_name, real_name)) { + fprintf(stderr, "%s: can't rename output file to %s\n", + command_name, real_name); + } + + } + } + else + /* Rename the temporary file to the target */ + + if (0 != rename(temp_name, real_name)) { + fprintf(stderr, "%s: can't rename output file to %s\n", + command_name, real_name); + } + + } + else { + remove(real_name); + /* Rename the temporary file to the target */ + + if (0 != rename(temp_name, real_name)) { + fprintf(stderr, "%s: can't rename output file to %s\n", + command_name, real_name); + } + + } + + } + files = files->rlink; + } +} diff --git a/pass1.c b/pass1.c new file mode 100644 index 0000000..09733c5 --- /dev/null +++ b/pass1.c @@ -0,0 +1,234 @@ +#include "global.h" +void pass1(file_name) + char *file_name; +{ + if (verbose_flag) + fprintf(stderr, "reading %s\n", file_name); + source_open(file_name); + init_scraps(); + macro_names = NULL; + file_names = NULL; + user_names = NULL; + /* Scan the source file, looking for at-sequences */ + { + int c = source_get(); + while (c != EOF) { + if (c == nw_char) + /* Scan at-sequence */ + { + char quoted = 0; + + c = source_get(); + switch (c) { + case 'r': + c = source_get(); + nw_char = c; + update_delimit_scrap(); + break; + case 'O': + case 'o': { + Name *name = collect_file_name(); /* returns a pointer to the name entry */ + int scrap = collect_scrap(); /* returns an index to the scrap */ + /* Add \verb|scrap| to \verb|name|'s definition list */ + { + Scrap_Node *def = (Scrap_Node *) arena_getmem(sizeof(Scrap_Node)); + def->scrap = scrap; + def->quoted = quoted; + def->next = name->defs; + name->defs = def; + } + } + break; + case 'Q': + case 'q': quoted = 1; + case 'D': + case 'd': { + Name *name = collect_macro_name(); + int scrap = collect_scrap(); + /* Add \verb|scrap| to \verb|name|'s definition list */ + { + Scrap_Node *def = (Scrap_Node *) arena_getmem(sizeof(Scrap_Node)); + def->scrap = scrap; + def->quoted = quoted; + def->next = name->defs; + name->defs = def; + } + } + break; + case 's': + /* Step to next sector */ + + prev_sector += 1; + current_sector = prev_sector; + c = source_get(); + + break; + case 'S': + /* Close the current sector */ + current_sector = 1; + c = source_get(); + + break; + case '<': + case '(': + case '[': + case '{': + { + int c; + int depth = 1; + while ((c = source_get()) != EOF) { + if (c == nw_char) + /* Skip over at-sign or go to skipped */ + + { + c = source_get(); + switch (c) { + case '{': case '[': case '(': case '<': + depth += 1; + break; + case '}': case ']': case ')': case '>': + if (--depth == 0) + goto skipped; + case 'x': case '|': case ',': + case '%': case '1': case '2': + case '3': case '4': case '5': case '6': + case '7': case '8': case '9': case '_': + case 'f': case '#': case '+': case '-': + case 'v': case '*': case 'c': case '\'': + case 's': + break; + default: + if (c != nw_char) { + fprintf(stderr, "%s: unexpected %c%c in text at (%s, %d)\n", + command_name, nw_char, c, source_name, source_line); + exit(-1); + } + break; + } + } + + } + fprintf(stderr, "%s: unexpected EOF in text at (%s, %d)\n", + command_name, source_name, source_line); + exit(-1); + + skipped: ; + } + + break; + case 'c': { + char * p = blockBuff; + char * e = blockBuff + (sizeof(blockBuff)/sizeof(blockBuff[0])) - 1; + + /* Skip whitespace */ + while (source_peek == ' ' + || source_peek == '\t' + || source_peek == '\n') + (void)source_get(); + + while (p < e) + { + /* Add one char to the block buffer */ + int c = source_get(); + + if (c == nw_char) + { + /* Add an at character to the block or break */ + int cc = source_peek; + + if (cc == 'c') + { + do + c = source_get(); + while (c <= ' '); + + break; + } + else if (cc == 'd' + || cc == 'D' + || cc == 'q' + || cc == 'Q' + || cc == 'o' + || cc == 'O' + || cc == EOF) + { + source_ungetc(&c); + break; + } + else + { + *p++ = c; + *p++ = source_get(); + } + + } + else if (c == EOF) + { + source_ungetc(&c); + break; + } + else + { + /* Add any other character to the block */ + + /* Perhaps skip white-space */ + if (c == ' ') + { + while (source_peek == ' ') + c = source_get(); + } + if (c == '\n') + { + if (source_peek == '\n') + { + do + c = source_get(); + while (source_peek == '\n'); + } + else + c = ' '; + } + + *p++ = c; + + } + + } + if (p == e) + { + /* Skip to the next nw-char */ + int c; + + while ((c = source_get()), c != nw_char && c != EOF)/* Skip */ + source_ungetc(&c); + } + *p = '\000'; + } + + break; + case 'x': + case 'v': + case 'u': + case 'm': + case 'f': /* ignore during this pass */ + break; + default: if (c==nw_char) /* ignore during this pass */ + break; + fprintf(stderr, + "%s: unexpected %c sequence ignored (%s, line %d)\n", + command_name, nw_char, source_name, source_line); + break; + } + } + c = source_get(); + } + } + if (tex_flag) + search(); + /* Reverse cross-reference lists */ + { + reverse_lists(file_names); + reverse_lists(macro_names); + reverse_lists(user_names); + } +} diff --git a/scraps.c b/scraps.c new file mode 100644 index 0000000..7a6d845 --- /dev/null +++ b/scraps.c @@ -0,0 +1,1676 @@ +#include "global.h" +#define SLAB_SIZE 1024 + +typedef struct slab { + struct slab *next; + char chars[SLAB_SIZE]; +} Slab; +typedef struct { + char *file_name; + Slab *slab; + struct uses *uses; + struct uses *defs; + int file_line; + int page; + char letter; + unsigned char sector; +} ScrapEntry; + +#define SCRAP_BITS 10 +#define SCRAP_SIZE (1<<SCRAP_BITS) +#define SCRAP_MASK (SCRAP_SIZE - 1) +#define SCRAP_SHIFT SCRAP_BITS +static ScrapEntry *SCRAP[SCRAP_SIZE]; + +#define scrap_array(i) SCRAP[(i) >> SCRAP_SHIFT][(i) & SCRAP_MASK] + +static int scraps; +int num_scraps() +{ + return scraps; +}; +/* Forward declarations for scraps.c */ +int delayed_indent = 0; +static void +comment_ArglistElement(FILE * file, Arglist * args, int quote) +{ + Name *name = args->name; + Arglist *q = args->args; + + if (name == NULL) { + if (quote) + fprintf(file, "%c'%s%c'", nw_char, (char *)q, nw_char); + else + fprintf(file, "'%s'", (char *)q); + } else if (name == (Name *)1) { + /* Include an embedded scrap in comment */ + Embed_Node * e = (Embed_Node *)q; + fputc('{', file); + write_scraps(file, "", e->defs, -1, "", 0, 0, 0, 0, e->args, 0, 1, ""); + fputc('}', file); + } else { + /* Include a fragment use in comment */ + char * p = name->spelling; + if (quote) + fputc(nw_char, file); + fputc('<', file); + if (quote && name->sector == 0) + fputc('+', file); + while (*p != '\000') { + if (*p == ARG_CHR) { + comment_ArglistElement(file, q, quote); + q = q->next; + p++; + } + else + fputc(*p++, file); + } + if (quote) + fputc(nw_char, file); + fputc('>', file); + } +} +char * comment_begin[4] = { "", "/* ", "// ", "# "}; +char * comment_mid[4] = { "", " * ", "// ", "# "}; +char * comment_end[4] = { "", " */", "", ""}; + +static void add_uses(); +static int scrap_is_in(); + +void init_scraps() +{ + scraps = 1; + SCRAP[0] = (ScrapEntry *) arena_getmem(SCRAP_SIZE * sizeof(ScrapEntry)); +} +void write_scrap_ref(file, num, first, page) + FILE *file; + int num; + int first; + int *page; +{ + if (scrap_array(num).page >= 0) { + if (first!=0) + fprintf(file, "%d", scrap_array(num).page); + else if (scrap_array(num).page != *page) + fprintf(file, ", %d", scrap_array(num).page); + if (scrap_array(num).letter > 0) + fputc(scrap_array(num).letter, file); + } + else { + if (first!=0) + putc('?', file); + else + fputs(", ?", file); + /* Warn (only once) about needing to rerun after Latex */ + { + if (!already_warned) { + fprintf(stderr, "%s: you'll need to rerun nuweb after running latex\n", + command_name); + already_warned = TRUE; + } + } + } + if (first>=0) + *page = scrap_array(num).page; +} +void write_single_scrap_ref(file, num) + FILE *file; + int num; +{ + int page; + write_scrap_ref(file, num, TRUE, &page); +} +typedef struct { + Slab *scrap; + Slab *prev; + int index; +} Manager; +static void push(c, manager) + char c; + Manager *manager; +{ + Slab *scrap = manager->scrap; + int index = manager->index; + scrap->chars[index++] = c; + if (index == SLAB_SIZE) { + Slab *new = (Slab *) arena_getmem(sizeof(Slab)); + scrap->next = new; + manager->scrap = new; + index = 0; + } + manager->index = index; +} +static void pushs(s, manager) + char *s; + Manager *manager; +{ + while (*s) + push(*s++, manager); +} +int collect_scrap() +{ + int current_scrap, lblseq = 0; + int depth = 1; + Manager writer; + /* Create new scrap, managed by \verb|writer| */ + { + Slab *scrap = (Slab *) arena_getmem(sizeof(Slab)); + if ((scraps & SCRAP_MASK) == 0) + SCRAP[scraps >> SCRAP_SHIFT] = (ScrapEntry *) arena_getmem(SCRAP_SIZE * sizeof(ScrapEntry)); + scrap_array(scraps).slab = scrap; + scrap_array(scraps).file_name = save_string(source_name); + scrap_array(scraps).file_line = source_line; + scrap_array(scraps).page = -1; + scrap_array(scraps).letter = 0; + scrap_array(scraps).uses = NULL; + scrap_array(scraps).defs = NULL; + scrap_array(scraps).sector = current_sector; + writer.scrap = scrap; + writer.index = 0; + current_scrap = scraps++; + } + /* Accumulate scrap and return \verb|scraps++| */ + { + int c = source_get(); + while (1) { + switch (c) { + case EOF: fprintf(stderr, "%s: unexpect EOF in (%s, %d)\n", + command_name, scrap_array(current_scrap).file_name, + scrap_array(current_scrap).file_line); + exit(-1); + default: + if (c==nw_char) + { + /* Handle at-sign during scrap accumulation */ + { + c = source_get(); + switch (c) { + case '(': + case '[': + case '{': depth++; + break; + case '+': + case '-': + case '*': + case '|': { + do { + int type = c; + do { + char new_name[MAX_NAME_LEN]; + char *p = new_name; + unsigned int sector = 0; + do + c = source_get(); + while (isspace(c)); + if (c != nw_char) { + Name *name; + do { + *p++ = c; + c = source_get(); + } while (c != nw_char && !isspace(c)); + *p = '\0'; + switch (type) { + case '*': + sector = current_sector; + /* Add user identifier use */ + name = name_add(&user_names, new_name, sector); + if (!name->uses || name->uses->scrap != current_scrap) { + Scrap_Node *use = (Scrap_Node *) arena_getmem(sizeof(Scrap_Node)); + use->scrap = current_scrap; + use->next = name->uses; + name->uses = use; + add_uses(&(scrap_array(current_scrap).uses), name); + } + break; + case '-': + /* Add user identifier use */ + name = name_add(&user_names, new_name, sector); + if (!name->uses || name->uses->scrap != current_scrap) { + Scrap_Node *use = (Scrap_Node *) arena_getmem(sizeof(Scrap_Node)); + use->scrap = current_scrap; + use->next = name->uses; + name->uses = use; + add_uses(&(scrap_array(current_scrap).uses), name); + } + /* Fall through */ + case '|': + sector = current_sector; + /* Fall through */ + case '+': + /* Add user identifier definition */ + name = name_add(&user_names, new_name, sector); + if (!name->defs || name->defs->scrap != current_scrap) { + Scrap_Node *def = (Scrap_Node *) arena_getmem(sizeof(Scrap_Node)); + def->scrap = current_scrap; + def->next = name->defs; + name->defs = def; + add_uses(&(scrap_array(current_scrap).defs), name); + } + break; + } + } + } while (c != nw_char); + c = source_get(); + }while (c == '|' || c == '*' || c == '-' || c == '+'); + if (c != '}' && c != ']' && c != ')') { + fprintf(stderr, "%s: unexpected %c%c in index entry (%s, %d)\n", + command_name, nw_char, c, source_name, source_line); + exit(-1); + } + } + /* Fall through */ + case ')': + case ']': + case '}': if (--depth > 0) + break; + /* else fall through */ + case ',': + push('\0', &writer); + scrap_ended_with = c; + return current_scrap; + case '<': { + Arglist * args = collect_scrap_name(current_scrap); + Name *name = args->name; + /* Save macro name */ + { + char buff[24]; + + push(nw_char, &writer); + push('<', &writer); + push(name->sector, &writer); + sprintf(buff, "%p", args); + pushs(buff, &writer); + } + add_to_use(name, current_scrap); + if (scrap_name_has_parameters) { + /* Save macro parameters */ + { + int param_scrap; + char param_buf[10]; + + push(nw_char, &writer); + push('(', &writer); + do { + param_scrap = collect_scrap(); + sprintf(param_buf, "%d", param_scrap); + pushs(param_buf, &writer); + push(nw_char, &writer); + push(scrap_ended_with, &writer); + add_to_use(name, current_scrap); + } while( scrap_ended_with == ',' ); + do + c = source_get(); + while( ' ' == c ); + if (c == nw_char) { + c = source_get(); + } + if (c != '>') { + /* ZZZ print error */; + } + } + } + push(nw_char, &writer); + push('>', &writer); + c = source_get(); + } + break; + case '%': { + do + c = source_get(); + while (c != '\n'); + } + /* emit line break to the output file to keep #line in sync. */ + push('\n', &writer); + c = source_get(); + break; + case 'x': { + /* Get label from */ + char label_name[MAX_NAME_LEN]; + char * p = label_name; + while (c = source_get(), c != nw_char) /* Here is 150a-01 */ + *p++ = c; + *p = '\0'; + c = source_get(); + + /* Save label to label store */ + if (label_name[0]) + /* Search for label(<Complain about duplicate labels>,<Create a new label entry>) */ + { + label_node * * plbl = &label_tab; + for (;;) + { + label_node * lbl = *plbl; + + if (lbl) + { + int cmp = label_name[0] - lbl->name[0]; + + if (cmp == 0) + cmp = strcmp(label_name + 1, lbl->name + 1); + if (cmp < 0) + plbl = &lbl->left; + else if (cmp > 0) + plbl = &lbl->right; + else + { + /* Complain about duplicate labels */ + fprintf(stderr, "Duplicate label %s.\n", label_name); + break; + } + } + else + { + /* Create a new label entry */ + lbl = (label_node *)arena_getmem(sizeof(label_node) + (p - label_name)); + lbl->left = lbl->right = NULL; + strcpy(lbl->name, label_name); + lbl->scrap = current_scrap; + lbl->seq = ++lblseq; + *plbl = lbl; + break; + } + } + } + + else + { + /* Complain about empty label */ + fprintf(stderr, "Empty label.\n"); + } + push(nw_char, &writer); + push('x', &writer); + pushs(label_name, &writer); + push(nw_char, &writer); + } + break; + case 'c': { + char * p = blockBuff; + + push(nw_char, &writer); + do + { + push(c, &writer); + c = *p++; + } while (c != '\0'); + } + break; + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + case 'f': case '#': case 'v': + case 't': case 's': + push(nw_char, &writer); + break; + case '_': c = source_get(); + break; + default : + if (c==nw_char) + { + push(nw_char, &writer); + push(nw_char, &writer); + c = source_get(); + break; + } + fprintf(stderr, "%s: unexpected %c%c in scrap (%s, %d)\n", + command_name, nw_char, c, source_name, source_line); + exit(-1); + } + } + break; + } + push(c, &writer); + c = source_get(); + break; + } + } + } +} +void +add_to_use(Name * name, int current_scrap) +{ + if (!name->uses || name->uses->scrap != current_scrap) { + Scrap_Node *use = (Scrap_Node *) arena_getmem(sizeof(Scrap_Node)); + use->scrap = current_scrap; + use->next = name->uses; + name->uses = use; + } +} +static char pop(manager) + Manager *manager; +{ + Slab *scrap = manager->scrap; + int index = manager->index; + char c = scrap->chars[index++]; + if (index == SLAB_SIZE) { + manager->prev = scrap; + manager->scrap = scrap->next; + index = 0; + } + manager->index = index; + return c; +} +static void backup(n, manager) + int n; + Manager *manager; +{ + int index = manager->index; + if (n > index + && manager->prev != NULL) + { + manager->scrap = manager->prev; + manager->prev = NULL; + index += SLAB_SIZE; + } + manager->index = (n <= index ? index - n : 0); +} +void +lookup(int n, Arglist * par, char * arg[9], Name **name, Arglist ** args) +{ + int i; + Arglist * p = par; + + for (i = 0; i < n && p != NULL; i++) + p = p->next; + if (p == NULL) { + char * a = arg[n]; + + *name = NULL; + *args = (Arglist *)a; + } + else { + *name = p->name; + *args = p->args; + } +} +Arglist * instance(Arglist * a, Arglist * par, char * arg[9], int * ch) +{ + if (a != NULL) { + int changed = 0; + Arglist *args, *next; + Name* name; + /* Set up name, args and next */ + next = instance(a->next, par, arg, &changed); + name = a->name; + if (name == (Name *)1) { + Embed_Node * q = (Embed_Node *)arena_getmem(sizeof(Embed_Node)); + q->defs = (Scrap_Node *)a->args; + q->args = par; + args = (Arglist *)q; + changed = 1; + } else if (name != NULL) + args = instance(a->args, par, arg, &changed); + else { + char * p = (char *)a->args; + if (p[0] == ARG_CHR) { + lookup(p[1] - '1', par, arg, &name, &args); + changed = 1; + } + else { + args = a->args; + } + } + if (changed){ + /* Build a new arglist */ + a = (Arglist *)arena_getmem(sizeof(Arglist)); + a->name = name; + a->args = args; + a->next = next; + *ch = 1; + } + } + + return a; +} +static Arglist *pop_scrap_name(manager, parameters) + Manager *manager; + Parameters *parameters; +{ + char name[MAX_NAME_LEN]; + char *p = name; + Arglist * args; + int c; + + (void)pop(manager); /* not sure why we have to pop twice */ + c = pop(manager); + + while (c != nw_char) { + *p++ = c; + c = pop(manager); + } + *p = '\000'; + if (sscanf(name, "%p", &args) != 1) + { + fprintf(stderr, "%s: found an internal problem (2)\n", command_name); + exit(-1); + } + /* Check for end of scrap name */ + { + c = pop(manager); + /* Check for macro parameters */ + + if (c == '(') { + Parameters res = arena_getmem(10 * sizeof(int)); + int *p2 = res; + int count = 0; + int scrapnum; + + while( c && c != ')' ) { + scrapnum = 0; + c = pop(manager); + while( '0' <= c && c <= '9' ) { + scrapnum = scrapnum * 10 + c - '0'; + c = pop(manager); + } + if ( c == nw_char ) { + c = pop(manager); + } + *p2++ = scrapnum; + } + while (count < 10) { + *p2++ = 0; + count++; + } + while( c && c != nw_char ) { + c = pop(manager); + } + if ( c == nw_char ) { + c = pop(manager); + } + *parameters = res; + } + + } + return args; +} +int write_scraps(file, spelling, defs, global_indent, indent_chars, + debug_flag, tab_flag, indent_flag, + comment_flag, inArgs, inParams, parameters, title) + FILE *file; + char * spelling; + Scrap_Node *defs; + int global_indent; + char *indent_chars; + char debug_flag; + char tab_flag; + char indent_flag; + unsigned char comment_flag; + Arglist * inArgs; + char * inParams[9]; + Parameters parameters; + char * title; +{ + /* This is in file scraps.c */ + int indent = 0; + int newline = 1; + while (defs) { + /* Copy \verb|defs->scrap| to \verb|file| */ + { + char c; + Manager reader; + Parameters local_parameters = 0; + int line_number = scrap_array(defs->scrap).file_line; + reader.scrap = scrap_array(defs->scrap).slab; + reader.index = 0; + /* Insert debugging information if required */ + if (debug_flag) { + fprintf(file, "\n#line %d \"%s\"\n", + line_number, scrap_array(defs->scrap).file_name); + /* Insert appropriate indentation */ + { + char c1 = pop(&reader); + char c2 = pop(&reader); + + if (indent_flag && !(c1 == '\n' + || (c1 == nw_char && (c2 == '#' || (delayed_indent |= (c2 == '<')))))) { + /* Put out the indent */ + if (tab_flag) + for (indent=0; indent<global_indent; indent++) + putc(' ', file); + else + for (indent=0; indent<global_indent; indent++) + putc(indent_chars[indent], file); + + } + indent = 0; + backup(2, &reader); + } + } + if (delayed_indent) + { + /* Insert appropriate indentation */ + { + char c1 = pop(&reader); + char c2 = pop(&reader); + + if (indent_flag && !(c1 == '\n' + || (c1 == nw_char && (c2 == '#' || (delayed_indent |= (c2 == '<')))))) { + /* Put out the indent */ + if (tab_flag) + for (indent=0; indent<global_indent; indent++) + putc(' ', file); + else + for (indent=0; indent<global_indent; indent++) + putc(indent_chars[indent], file); + + } + indent = 0; + backup(2, &reader); + } + } + c = pop(&reader); + while (c) { + switch (c) { + case '\n': + if (global_indent >= 0) { + putc(c, file); + line_number++; + newline = 1; + delayed_indent = 0; + /* Insert appropriate indentation */ + { + char c1 = pop(&reader); + char c2 = pop(&reader); + + if (indent_flag && !(c1 == '\n' + || (c1 == nw_char && (c2 == '#' || (delayed_indent |= (c2 == '<')))))) { + /* Put out the indent */ + if (tab_flag) + for (indent=0; indent<global_indent; indent++) + putc(' ', file); + else + for (indent=0; indent<global_indent; indent++) + putc(indent_chars[indent], file); + + } + indent = 0; + backup(2, &reader); + } + break; + } else { + /* Don't show newlines in embedded fragmants */ + fputs(". . .", file); + return 0; + } + case '\t': { + if (tab_flag) + /* Expand tab into spaces */ + { + int delta = 8 - (indent % 8); + indent += delta; + while (delta > 0) { + putc(' ', file); + delta--; + } + } + else { + putc('\t', file); + if (global_indent >= 0) { + /* Add more indentation ''\t'' */ + { + if (global_indent + indent >= MAX_INDENT) { + fprintf(stderr, + "Error! maximum indentation exceeded in \"%s\".\n", + spelling); + exit(1); + } + indent_chars[global_indent + indent] = '\t'; + } + } + indent++; + } + } + delayed_indent = 0; + break; + default: + if (c==nw_char) + { + /* Check for macro invocation in scrap */ + { + int oldin = indent; + char oldcf = comment_flag; + c = pop(&reader); + switch (c) { + case 't': { + char * p = title; + Arglist *q = inArgs; + int narg; + + /* Comment this macro use */ + narg = 0; + while (*p != '\000') { + if (*p == ARG_CHR) { + if (q == NULL) { + if (defs->quoted) + fprintf(file, "%c'%s%c'", nw_char, inParams[narg], nw_char); + else + fprintf(file, "'%s'", inParams[narg]); + } + else { + comment_ArglistElement(file, q, defs->quoted); + q = q->next; + } + p++; + narg++; + } + else + fputc(*p++, file); + } + if (xref_flag) { + putc(' ', file); + write_single_scrap_ref(file, defs->scrap); + } + } + break; + case 'c': { + int bgn = indent + global_indent; + int posn = bgn + strlen(comment_begin[comment_flag]); + int i; + + /* Perhaps put a delayed indent */ + if (delayed_indent) + for (i = indent + global_indent; --i >= 0; ) + putc(' ', file); + + c = pop(&reader); + fputs(comment_begin[comment_flag], file); + while (c != '\0') + { + /* Move a word to the file */ + do + { + putc(c, file); + posn += 1; + c = pop(&reader); + } while (c > ' '); + + /* If we break the line at this word */ + if (c == '\n' || (c == ' ' && posn > 60)) + { + putc('\n', file); + for (i = 0; i < bgn ; i++) + putc(' ', file); + c = pop(&reader); + if (c != '\0') + { + posn = bgn + strlen(comment_mid[comment_flag]); + fputs(comment_mid[comment_flag], file); + } + } + } + fputs(comment_end[comment_flag], file); + } + + break; + case 'f': if (defs->quoted) + fprintf(file, "%cf", nw_char); + else + fputs(spelling, file); + + break; + case 'x': { + /* Get label from */ + char label_name[MAX_NAME_LEN]; + char * p = label_name; + while (c = pop(&reader), c != nw_char) /* Here is 150a-01 */ + *p++ = c; + *p = '\0'; + c = pop(&reader); + + write_label(label_name, file); + } + case '_': break; + case 'v': fputs(version_string, file); + + break; + case 's': indent = -global_indent; + comment_flag = 0; + break; + case '<': { + Arglist *a = pop_scrap_name(&reader, &local_parameters); + Name *name = a->name; + int changed; + Arglist * args = instance(a->args, inArgs, inParams, &changed); + int i, narg; + char * p = name->spelling; + char * * inParams = name->arg; + Arglist *q = args; + + if (name->mark) { + fprintf(stderr, "%s: recursive macro discovered involving <%s>\n", + command_name, name->spelling); + exit(-1); + } + if (name->defs && !defs->quoted) { + /* Perhaps comment this macro */ + if (comment_flag && newline) { + /* Perhaps put a delayed indent */ + if (delayed_indent) + for (i = indent + global_indent; --i >= 0; ) + putc(' ', file); + + fputs(comment_begin[comment_flag], file); + /* Comment this macro use */ + narg = 0; + while (*p != '\000') { + if (*p == ARG_CHR) { + if (q == NULL) { + if (defs->quoted) + fprintf(file, "%c'%s%c'", nw_char, inParams[narg], nw_char); + else + fprintf(file, "'%s'", inParams[narg]); + } + else { + comment_ArglistElement(file, q, defs->quoted); + q = q->next; + } + p++; + narg++; + } + else + fputc(*p++, file); + } + if (xref_flag) { + putc(' ', file); + write_single_scrap_ref(file, name->defs->scrap); + } + fputs(comment_end[comment_flag], file); + putc('\n', file); + if (!delayed_indent) + for (i = indent + global_indent; --i >= 0; ) + putc(' ', file); + } + + name->mark = TRUE; + indent = write_scraps(file, spelling, name->defs, global_indent + indent, + indent_chars, debug_flag, tab_flag, indent_flag, + comment_flag, args, name->arg, + local_parameters, name->spelling); + indent -= global_indent; + name->mark = FALSE; + } + else + { + if (delayed_indent) + { + for (i = indent + global_indent; --i >= 0; ) + putc(' ', file); + } + + fprintf(file, "%c<", nw_char); + if (name->sector == 0) + fputc('+', file); + /* Comment this macro use */ + narg = 0; + while (*p != '\000') { + if (*p == ARG_CHR) { + if (q == NULL) { + if (defs->quoted) + fprintf(file, "%c'%s%c'", nw_char, inParams[narg], nw_char); + else + fprintf(file, "'%s'", inParams[narg]); + } + else { + comment_ArglistElement(file, q, defs->quoted); + q = q->next; + } + p++; + narg++; + } + else + fputc(*p++, file); + } + fprintf(file, "%c>", nw_char); + if (!defs->quoted && !tex_flag) + fprintf(stderr, "%s: macro never defined <%s>\n", + command_name, name->spelling); + } + } + /* Insert debugging information if required */ + if (debug_flag) { + fprintf(file, "\n#line %d \"%s\"\n", + line_number, scrap_array(defs->scrap).file_name); + /* Insert appropriate indentation */ + { + char c1 = pop(&reader); + char c2 = pop(&reader); + + if (indent_flag && !(c1 == '\n' + || (c1 == nw_char && (c2 == '#' || (delayed_indent |= (c2 == '<')))))) { + /* Put out the indent */ + if (tab_flag) + for (indent=0; indent<global_indent; indent++) + putc(' ', file); + else + for (indent=0; indent<global_indent; indent++) + putc(indent_chars[indent], file); + + } + indent = 0; + backup(2, &reader); + } + } + indent = oldin; + comment_flag = oldcf; + break; + /* Handle macro parameter substitution */ + + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + { + Arglist * args; + Name * name; + + lookup(c - '1', inArgs, inParams, &name, &args); + + if (name == (Name *)1) { + Embed_Node * q = (Embed_Node *)args; + indent = write_scraps(file, spelling, q->defs, + global_indent + indent, + indent_chars, debug_flag, + tab_flag, indent_flag, + 0, + q->args, inParams, + local_parameters, ""); + } + else if (name != NULL) { + int i, narg; + char * p = name->spelling; + Arglist *q = args; + + /* Perhaps comment this macro */ + if (comment_flag && newline) { + /* Perhaps put a delayed indent */ + if (delayed_indent) + for (i = indent + global_indent; --i >= 0; ) + putc(' ', file); + + fputs(comment_begin[comment_flag], file); + /* Comment this macro use */ + narg = 0; + while (*p != '\000') { + if (*p == ARG_CHR) { + if (q == NULL) { + if (defs->quoted) + fprintf(file, "%c'%s%c'", nw_char, inParams[narg], nw_char); + else + fprintf(file, "'%s'", inParams[narg]); + } + else { + comment_ArglistElement(file, q, defs->quoted); + q = q->next; + } + p++; + narg++; + } + else + fputc(*p++, file); + } + if (xref_flag) { + putc(' ', file); + write_single_scrap_ref(file, name->defs->scrap); + } + fputs(comment_end[comment_flag], file); + putc('\n', file); + if (!delayed_indent) + for (i = indent + global_indent; --i >= 0; ) + putc(' ', file); + } + + indent = write_scraps(file, spelling, name->defs, + global_indent + indent, + indent_chars, debug_flag, + tab_flag, indent_flag, + comment_flag, args, name->arg, + local_parameters, p); + } + else if (args != NULL) { + if (delayed_indent) { + /* Put out the indent */ + if (tab_flag) + for (indent=0; indent<global_indent; indent++) + putc(' ', file); + else + for (indent=0; indent<global_indent; indent++) + putc(indent_chars[indent], file); + + } + fputs((char *)args, file); + } + else if ( parameters && parameters[c - '1'] ) { + Scrap_Node param_defs; + param_defs.scrap = parameters[c - '1']; + param_defs.next = 0; + write_scraps(file, spelling, ¶m_defs, + global_indent + indent, + indent_chars, debug_flag, + tab_flag, indent_flag, + comment_flag, NULL, NULL, 0, ""); + } else if (delayed_indent) { + /* Put out the indent */ + if (tab_flag) + for (indent=0; indent<global_indent; indent++) + putc(' ', file); + else + for (indent=0; indent<global_indent; indent++) + putc(indent_chars[indent], file); + + } + } + + indent = oldin; + break; + default: + if(c==nw_char) + { + putc(c, file); + if (global_indent >= 0) { + /* Add more indentation '' '' */ + { + if (global_indent + indent >= MAX_INDENT) { + fprintf(stderr, + "Error! maximum indentation exceeded in \"%s\".\n", + spelling); + exit(1); + } + indent_chars[global_indent + indent] = ' '; + } + } + indent++; + break; + } + /* ignore, since we should already have a warning */ + break; + } + } + break; + } + putc(c, file); + if (global_indent >= 0) { + /* Add more indentation '' '' */ + { + if (global_indent + indent >= MAX_INDENT) { + fprintf(stderr, + "Error! maximum indentation exceeded in \"%s\".\n", + spelling); + exit(1); + } + indent_chars[global_indent + indent] = ' '; + } + } + indent++; + if (c > ' ') newline = 0; + delayed_indent = 0; + break; + } + c = pop(&reader); + } + } + defs = defs->next; + } + return indent + global_indent; +} +void collect_numbers(aux_name) + char *aux_name; +{ + if (number_flag) { + int i; + for (i=1; i<scraps; i++) + scrap_array(i).page = i; + } + else { + FILE *aux_file = fopen(aux_name, "r"); + already_warned = FALSE; + if (aux_file) { + char aux_line[500]; + while (fgets(aux_line, 500, aux_file)) { + /* Read line in \verb|.aux| file */ + + int scrap_number; + int page_number; + int i; + int dummy_idx; + int bracket_depth = 1; + if (1 == sscanf(aux_line, + "\\newlabel{scrap%d}{{%n", + &scrap_number, + &dummy_idx)) { + for (i = dummy_idx; i < strlen(aux_line) && bracket_depth > 0; i++) { + if (aux_line[i] == '{') bracket_depth++; + else if (aux_line[i] == '}') bracket_depth--; + } + if (i > dummy_idx + && i < strlen(aux_line) + && 1 == sscanf(aux_line+i, "{%d}" ,&page_number)) { + if (scrap_number < scraps) + scrap_array(scrap_number).page = page_number; + else + /* Warn (only once) about needing to rerun after Latex */ + { + if (!already_warned) { + fprintf(stderr, "%s: you'll need to rerun nuweb after running latex\n", + command_name); + already_warned = TRUE; + } + } + } + } + + } + fclose(aux_file); + /* Add letters to scraps with duplicate page numbers */ + { + int i = 0; + + /* Step 'i' to the next valid scrap */ + do + i++; + while (i < scraps && scrap_array(i).page == -1); + + /* For all remaining scraps */ + while (i < scraps) { + int j = i; + /* Step 'j' to the next valid scrap */ + do + j++; + while (j < scraps && scrap_array(j).page == -1); + + /* Perhaps add letters to the page numbers */ + if (scrap_array(i).page == scrap_array(j).page) { + if (scrap_array(i).letter == 0) + scrap_array(i).letter = 'a'; + scrap_array(j).letter = scrap_array(i).letter + 1; + } + + i = j; + } + } + + } + } +} +typedef struct name_node { + struct name_node *next; + Name *name; +} Name_Node; +typedef struct goto_node { + Name_Node *output; /* list of words ending in this state */ + struct move_node *moves; /* list of possible moves */ + struct goto_node *fail; /* and where to go when no move fits */ + struct goto_node *next; /* next goto node with same depth */ +} Goto_Node; +typedef struct move_node { + struct move_node *next; + Goto_Node *state; + char c; +} Move_Node; +static Goto_Node *root[256]; +static int max_depth; +static Goto_Node **depths; +static Goto_Node *goto_lookup(c, g) + char c; + Goto_Node *g; +{ + Move_Node *m = g->moves; + while (m && m->c != c) + m = m->next; + if (m) + return m->state; + else + return NULL; +} +typedef struct ArgMgr_s +{ + char * pv; + char * bgn; + Arglist * arg; + struct ArgMgr_s * old; +} ArgMgr; +typedef struct ArgManager_s +{ + Manager * m; + ArgMgr * a; +} ArgManager; +static void +pushArglist(ArgManager * mgr, Arglist * a) +{ + ArgMgr * b = malloc(sizeof(ArgMgr)); + + if (b == NULL) + { + fprintf(stderr, "Can't allocate space for an argument manager\n"); + exit(EXIT_FAILURE); + } + b->pv = b->bgn = NULL; + b->arg = a; + b->old = mgr->a; + mgr->a = b; +} +static char argpop(ArgManager * mgr) +{ + while (mgr->a != NULL) + { + ArgMgr * a = mgr->a; + + /* Perhaps |return| a character from the current arg */ + if (a->pv != NULL) + { + char c = *a->pv++; + + if (c != '\0') + return c; + a->pv = NULL; + return ' '; + } + + /* Perhaps start a new arg */ + if (a->arg) { + Arglist * b = a->arg; + + a->arg = b->next; + if (b->name == NULL) { + a->bgn = a->pv = (char *)b->args; + } else if (b->name == (Name *)1) { + a->bgn = a->pv = "{Embedded Scrap}"; + } else { + pushArglist(mgr, b->args); + } + /* Otherwise pop the current arg */ + } else { + mgr->a = a->old; + free(a); + } + } + + return (pop(mgr->m)); +} +static char +prev_char(ArgManager * mgr, int n) +{ + char c = '\0'; + ArgMgr * a = mgr->a; + Manager * m = mgr->m; + + if (a != NULL) { + /* Get the nth previous character from an argument */ + if (a->pv && a->pv - n >= a->bgn) + c = *a->pv; + else if (a->bgn) { + int j = strlen(a->bgn) + 1; + + if (n >= j) + c = a->bgn[j - n]; + else + c = ' '; + } + + } else { + /* Get the nth previous character from a scrap */ + int k = m->index - n - 2; + + if (k >= 0) + c = m->scrap->chars[k]; + else if (m->prev) + c = m->prev->chars[SLAB_SIZE - k]; + + } + + return c; +} +static void build_gotos(); +static int reject_match(); + +void search() +{ + int i; + for (i=0; i<128; i++) + root[i] = NULL; + max_depth = 10; + depths = (Goto_Node **) arena_getmem(max_depth * sizeof(Goto_Node *)); + for (i=0; i<max_depth; i++) + depths[i] = NULL; + build_gotos(user_names); + /* Build failure functions */ + { + int depth; + for (depth=1; depth<max_depth; depth++) { + Goto_Node *r = depths[depth]; + while (r) { + Move_Node *m = r->moves; + while (m) { + char a = m->c; + Goto_Node *s = m->state; + Goto_Node *state = r->fail; + while (state && !goto_lookup(a, state)) + state = state->fail; + if (state) + s->fail = goto_lookup(a, state); + else + s->fail = root[(unsigned char)a]; + if (s->fail) { + Name_Node *p = s->fail->output; + while (p) { + Name_Node *q = (Name_Node *) arena_getmem(sizeof(Name_Node)); + q->name = p->name; + q->next = s->output; + s->output = q; + p = p->next; + } + } + m = m->next; + } + r = r->next; + } + } + } + /* Search scraps */ + { + for (i=1; i<scraps; i++) { + char c, last = '\0'; + Manager rd; + ArgManager reader; + Goto_Node *state = NULL; + rd.prev = NULL; + rd.scrap = scrap_array(i).slab; + rd.index = 0; + reader.m = &rd; + reader.a = NULL; + c = argpop(&reader); + while (c) { + while (state && !goto_lookup(c, state)) + state = state->fail; + if (state) + state = goto_lookup(c, state); + else + state = root[(unsigned char)c]; + /* Skip over at at */ + if (last == nw_char && c == nw_char) + { + last = '\0'; + c = argpop(&reader); + } + + /* Skip over a scrap use */ + if (last == nw_char && c == '<') + { + char buf[MAX_NAME_LEN]; + char * p = buf; + Arglist * args; + + c = argpop(&reader); + while ((c = argpop(&reader)) != nw_char) + *p++ = c; + c = argpop(&reader); + *p = '\0'; + if (sscanf(buf, "%p", &args) != 1) { + fprintf(stderr, "%s: found an internal problem (3)\n", command_name); + exit(-1); + } + pushArglist(&reader, args); + } + /* Skip over a block comment */ + if (last == nw_char && c == 'c') + while ((c = pop(reader.m)) != '\0') + /* Skip */; + + last = c; + c = argpop(&reader); + if (state && state->output) { + Name_Node *p = state->output; + do { + Name *name = p->name; + if (!reject_match(name, c, &reader) && + scrap_array(i).sector == name->sector && + (!name->uses || name->uses->scrap != i)) { + Scrap_Node *new_use = + (Scrap_Node *) arena_getmem(sizeof(Scrap_Node)); + new_use->scrap = i; + new_use->next = name->uses; + name->uses = new_use; + if (!scrap_is_in(name->defs, i)) + add_uses(&(scrap_array(i).uses), name); + } + p = p->next; + } while (p); + } + } + } + } +} +static void build_gotos(tree) + Name *tree; +{ + while (tree) { + /* Extend goto graph with \verb|tree->spelling| */ + { + int depth = 2; + char *p = tree->spelling; + char c = *p++; + Goto_Node *q = root[(unsigned char)c]; + Name_Node * last; + if (!q) { + q = (Goto_Node *) arena_getmem(sizeof(Goto_Node)); + root[(unsigned char)c] = q; + q->moves = NULL; + q->fail = NULL; + q->moves = NULL; + q->output = NULL; + q->next = depths[1]; + depths[1] = q; + } + while ((c = *p++)) { + Goto_Node *new = goto_lookup(c, q); + if (!new) { + Move_Node *new_move = (Move_Node *) arena_getmem(sizeof(Move_Node)); + new = (Goto_Node *) arena_getmem(sizeof(Goto_Node)); + new->moves = NULL; + new->fail = NULL; + new->moves = NULL; + new->output = NULL; + new_move->state = new; + new_move->c = c; + new_move->next = q->moves; + q->moves = new_move; + if (depth == max_depth) { + int i; + Goto_Node **new_depths = + (Goto_Node **) arena_getmem(2*depth*sizeof(Goto_Node *)); + max_depth = 2 * depth; + for (i=0; i<depth; i++) + new_depths[i] = depths[i]; + depths = new_depths; + for (i=depth; i<max_depth; i++) + depths[i] = NULL; + } + new->next = depths[depth]; + depths[depth] = new; + } + q = new; + depth++; + } + last = q->output; + q->output = (Name_Node *) arena_getmem(sizeof(Name_Node)); + q->output->next = last; + q->output->name = tree; + } + build_gotos(tree->rlink); + tree = tree->llink; + } +} + +static int scrap_is_in(Scrap_Node * list, int i) +{ + while (list != NULL) { + if (list->scrap == i) + return TRUE; + list = list->next; + } + return FALSE; +} + +static void add_uses(Uses * * root, Name *name) +{ + int cmp; + Uses *p, **q = root; + + while ((p = *q, p != NULL) + && (cmp = robs_strcmp(p->defn->spelling, name->spelling)) < 0) + q = &(p->next); + if (p == NULL || cmp > 0) + { + Uses *new = arena_getmem(sizeof(Uses)); + new->next = p; + new->defn = name; + *q = new; + } +} + +void +format_uses_refs(FILE * tex_file, int scrap) +{ + Uses * p = scrap_array(scrap).uses; + if (p != NULL) + /* Write uses references */ + { + char join = ' '; + fputs("\\item \\NWtxtIdentsUsed\\nobreak\\", tex_file); + do { + /* Write one use reference */ + Name * name = p->defn; + Scrap_Node *defs = name->defs; + int first = TRUE, page = -1; + fprintf(tex_file, + "%c \\verb%c%s%c\\nobreak\\ ", + join, nw_char, name->spelling, nw_char); + if (defs) + { + do { + /* Write one referenced scrap */ + fputs("\\NWlink{nuweb", tex_file); + write_scrap_ref(tex_file, defs->scrap, -1, &page); + fputs("}{", tex_file); + write_scrap_ref(tex_file, defs->scrap, first, &page); + fputs("}", tex_file); + first = FALSE; + defs = defs->next; + }while (defs!= NULL); + } + else + { + fputs("\\NWnotglobal", tex_file); + } + + join = ','; + p = p->next; + }while (p != NULL); + fputs(".", tex_file); + } +} + +void +format_defs_refs(FILE * tex_file, int scrap) +{ + Uses * p = scrap_array(scrap).defs; + if (p != NULL) + /* Write defs references */ + { + char join = ' '; + fputs("\\item \\NWtxtIdentsDefed\\nobreak\\", tex_file); + do { + /* Write one def reference */ + Name * name = p->defn; + Scrap_Node *defs = name->uses; + int first = TRUE, page = -1; + fprintf(tex_file, + "%c \\verb%c%s%c\\nobreak\\ ", + join, nw_char, name->spelling, nw_char); + if (defs == NULL + || (defs->scrap == scrap && defs->next == NULL)) { + fputs("\\NWtxtIdentsNotUsed", tex_file); + } + else { + do { + if (defs->scrap != scrap) { + /* Write one referenced scrap */ + fputs("\\NWlink{nuweb", tex_file); + write_scrap_ref(tex_file, defs->scrap, -1, &page); + fputs("}{", tex_file); + write_scrap_ref(tex_file, defs->scrap, first, &page); + fputs("}", tex_file); + first = FALSE; + } + defs = defs->next; + }while (defs!= NULL); + } + + join = ','; + p = p->next; + }while (p != NULL); + fputs(".", tex_file); + } +} +#define sym_char(c) (isalnum(c) || (c) == '_') + +static int op_char(c) + char c; +{ + switch (c) { + case '!': case '#': case '%': case '$': case '^': + case '&': case '*': case '-': case '+': case '=': case '/': + case '|': case '~': case '<': case '>': + return TRUE; + default: + return c==nw_char ? TRUE : FALSE; + } +} +static int reject_match(name, post, reader) + Name *name; + char post; + ArgManager *reader; +{ + int len = strlen(name->spelling); + char first = name->spelling[0]; + char last = name->spelling[len - 1]; + char prev = prev_char(reader, len); + if (sym_char(last) && sym_char(post)) return TRUE; + if (sym_char(first) && sym_char(prev)) return TRUE; + if (op_char(last) && op_char(post)) return TRUE; + if (op_char(first) && op_char(prev)) return TRUE; + return FALSE; /* Here is 149b-01 */ +} +void +write_label(char label_name[], FILE * file) +/* Search for label(<Write the label to file>,<Complain about missing label>) */ +{ + label_node * * plbl = &label_tab; + for (;;) + { + label_node * lbl = *plbl; + + if (lbl) + { + int cmp = label_name[0] - lbl->name[0]; + + if (cmp == 0) + cmp = strcmp(label_name + 1, lbl->name + 1); + if (cmp < 0) + plbl = &lbl->left; + else if (cmp > 0) + plbl = &lbl->right; + else + { + /* Write the label to file */ + write_single_scrap_ref(file, lbl->scrap); + fprintf(file, "-%02d", lbl->seq); + break; + } + } + else + { + /* Complain about missing label */ + fprintf(stderr, "Can't find label %s.\n", label_name); + break; + } + } +} + diff --git a/test/00/t0001a.sh b/test/00/t0001a.sh new file mode 100644 index 0000000..c71cdbe --- /dev/null +++ b/test/00/t0001a.sh @@ -0,0 +1,113 @@ +#!/bin/sh +# +# $RCSfile: t0001a.sh,v $ -- Test test/00/t0001a.sh +# +# +# Test of formating bare parameter uses +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of formating bare parameter uses" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of formating bare parameter uses" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test formating bare parameter uses +# + +cat > test.w <<"EOF" +@d Test with parameter +@{Try @1 parameter. +@} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Test with parameter}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Try @{\tt @}\verb@1 parameter.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item {\NWtxtMacroNoRef}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0002a.sh b/test/00/t0002a.sh new file mode 100644 index 0000000..e2fd567 --- /dev/null +++ b/test/00/t0002a.sh @@ -0,0 +1,119 @@ +#!/bin/sh +# +# $RCSfile: t0002a.sh,v $-- Test test/00/t0002a.sh +# +# +# Test of formatting parameters in index +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of formatting parameters in index" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of formatting parameters in index" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test formatting parameters in index +# + +cat > test.w <<"EOF" +@d Test @'param@' in index +@{Param @1 here +@} + +@m +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Test \hbox{\slshape\sffamily param\/} in index}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Param @\hbox{\slshape\sffamily param\/}\verb@ here@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item {\NWtxtMacroNoRef}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} + +{\small\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item $\langle\,$Test \hbox{\slshape\sffamily param\/} in index\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$ {\footnotesize {\NWtxtNoRef}.} +\end{list}} +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0003a.sh b/test/00/t0003a.sh new file mode 100644 index 0000000..00947f5 --- /dev/null +++ b/test/00/t0003a.sh @@ -0,0 +1,122 @@ +#!/bin/sh +# +# $RCSfile: t0003a.sh,v $-- Test test/00/t0003a.sh +# +# +# Test of more vspace in file entry +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of more vspace in file entry" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of more vspace in file entry" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test more vspace in file entry +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@o test.c +@{File defining fred and jim. + +See? +@| fred jim @} +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb?}{} \verb@"test.c"@\nobreak\ {\footnotesize {?}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@File defining fred and jim.@\\ +\mbox{}\verb@@\\ +\mbox{}\verb@See? @\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtIdentsDefed\nobreak\ \verb@fred@\nobreak\ \NWtxtIdentsNotUsed, \verb@jim@\nobreak\ \NWtxtIdentsNotUsed. +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{document} +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0004a.sh b/test/00/t0004a.sh new file mode 100644 index 0000000..9ce18ce --- /dev/null +++ b/test/00/t0004a.sh @@ -0,0 +1,179 @@ +#!/bin/sh +# +# $RCSfile: t0004a.sh,v $-- Test test/00/t0004a.sh +# +# +# Test of indent before parameter +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of indent before parameter" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of indent before parameter" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test indent before parameter +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@o test.c +@{Start + @<Here is the first call@> +End +@} + +@d Here is the first call +@{@<Use @'xxx@' as parameter@> +@<Use @'ZZZ@' as parameter@> +@} + +@d Use @'yyy@' as... +@{@1 is here. +@} +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb?}{} \verb@"test.c"@\nobreak\ {\footnotesize {?}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Start@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Here is the first call}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@End@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap2}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Here is the first call}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@@\hbox{$\langle\,${\itshape Use \verb@xxx@ as parameter}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Use \verb@ZZZ@ as parameter}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap3}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Use \hbox{\slshape\sffamily yyy\/} as parameter}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@@\hbox{\slshape\sffamily yyy\/}\verb@ is here.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{document} +EOF + +cat > test.expected.c <<"EOF" +Start + xxx is here. + + ZZZ is here. + + +End +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.c test.c +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0005a.sh b/test/00/t0005a.sh new file mode 100644 index 0000000..9a50895 --- /dev/null +++ b/test/00/t0005a.sh @@ -0,0 +1,224 @@ +#!/bin/sh +# +# $RCSfile: t0005a.sh,v $-- Test test/00/t0005a.sh +# +# +# Test of Commenting macroes as argument uses +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of Commenting macroes as argument uses" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of Commenting macroes as argument uses" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test Commenting macroes as argument uses +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@o test.c -cc +@{Call the macro + @<Fragment with @<A macro argument@> as parameter@> + @<Second frag with @<A macro argument@> as parameter@> + @<Third frag with @<A macro argument@> as parameter@> +@} + +@d Fragment with @'Begin macro@'... +@{@1<<<Here 'tis. +That argument was at the beginning of the fragment@} + +@d Second frag with @'Begin line@'... +@{Here is the beginning of the second macro +@1<<<That is the argument +And this is the end of the second frag@} + +@d Third frag with @'Embedded@'... +@{Here is the argument>>>@1<<<That was it.@} + +@d A macro argument +@{Hello folks@} +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb?}{} \verb@"test.c"@\nobreak\ {\footnotesize {?}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Call the macro@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Fragment with $\langle\,${\itshape A macro argument}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$ as parameter}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Second frag with $\langle\,${\itshape A macro argument}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$ as parameter}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Third frag with $\langle\,${\itshape A macro argument}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$ as parameter}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap2}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Fragment with \hbox{\slshape\sffamily Begin macro\/} as parameter}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@@\hbox{\slshape\sffamily Begin macro\/}\verb@<<<Here 'tis.@\\ +\mbox{}\verb@That argument was at the beginning of the fragment@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap3}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Second frag with \hbox{\slshape\sffamily Begin line\/} as parameter}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Here is the beginning of the second macro@\\ +\mbox{}\verb@@\hbox{\slshape\sffamily Begin line\/}\verb@<<<That is the argument@\\ +\mbox{}\verb@And this is the end of the second frag@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap4}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Third frag with \hbox{\slshape\sffamily Embedded\/} as parameter}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Here is the argument>>>@\hbox{\slshape\sffamily Embedded\/}\verb@<<<That was it.@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap5}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape A macro argument}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Hello folks@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{document} +EOF + +cat > test.expected.c <<"EOF" +Call the macro + /* Fragment with <A macro argument> as parameter */ + /* A macro argument */ + Hello folks<<<Here 'tis. + That argument was at the beginning of the fragment + /* Second frag with <A macro argument> as parameter */ + Here is the beginning of the second macro + /* A macro argument */ + Hello folks<<<That is the argument + And this is the end of the second frag + /* Third frag with <A macro argument> as parameter */ + Here is the argument>>>Hello folks<<<That was it. +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.c test.c +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0006a.sh b/test/00/t0006a.sh new file mode 100644 index 0000000..3df6804 --- /dev/null +++ b/test/00/t0006a.sh @@ -0,0 +1,119 @@ +#!/bin/sh +# +# $RCSfile: t0006a.sh,v $-- Test test/00/t0006a.sh +# +# +# Test of cross-reference flag +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of cross-reference flag" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of cross-reference flag" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test cross-reference flag +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@o test.c -cc +@{Call the macro + @<Fragment with @<A macro argument@> as parameter@> + @<Second frag with @<A macro argument@> as parameter@> + @<Third frag with @<A macro argument@> as parameter@> +@} + +@d Fragment with @'Begin macro@'... +@{@1<<<Here 'tis. +That argument was at the beginning of the fragment@} + +@d Second frag with @'Begin line@'... +@{Here is the beginning of the second macro +@1<<<That is the argument +And this is the end of the second frag@} + +@d Third frag with @'Embedded@'... +@{Here is the argument>>>@1<<<That was it.@} + +@d A macro argument +@{Hello folks@} +\end{document} +EOF + +cat > test.expected.c <<"EOF" +Call the macro + /* Fragment with <A macro argument> as parameter 1b */ + /* A macro argument 1e */ + Hello folks<<<Here 'tis. + That argument was at the beginning of the fragment + /* Second frag with <A macro argument> as parameter 1c */ + Here is the beginning of the second macro + /* A macro argument 1e */ + Hello folks<<<That is the argument + And this is the end of the second frag + /* Third frag with <A macro argument> as parameter 1d */ + Here is the argument>>>Hello folks<<<That was it. +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb -x test.w +if test $? -ne 0 ; then fail; fi + +latex test + +$bin/nuweb -x test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.c test.c +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0007a.sh b/test/00/t0007a.sh new file mode 100644 index 0000000..e10c980 --- /dev/null +++ b/test/00/t0007a.sh @@ -0,0 +1,192 @@ +#!/bin/sh +# +# $RCSfile: t0007a.sh,v $-- Test test/00/t0007a.sh +# +# +# Test of ??? +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of ???" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of ???" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test ??? +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +Here is a macro that defines something. +@d Define something +@{something anything +@| something anything @} + +Here is a macro that uses an argument +@d Use the @'thing@' +@{Use @1 +Use anything +@} + +Now use the something in an argument +@o test.c -cc +@{ +@<Define something@> +@<Use the @'something@'@> +@} +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +Here is a macro that defines something. +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb1a}{} $\langle\,${\itshape Define something}\nobreak\ {\footnotesize {1a}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@something anything@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1c}{1c}. +\item \NWtxtIdentsDefed\nobreak\ \verb@anything@\nobreak\ \NWlink{nuweb1b}{1b}, \verb@something@\nobreak\ \NWlink{nuweb1c}{1c}. +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +Here is a macro that uses an argument +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap2}\raggedright\small +\NWtarget{nuweb1b}{} $\langle\,${\itshape Use the \hbox{\slshape\sffamily thing\/}}\nobreak\ {\footnotesize {1b}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Use @\hbox{\slshape\sffamily thing\/}\verb@@\\ +\mbox{}\verb@Use anything@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1c}{1c}. +\item \NWtxtIdentsUsed\nobreak\ \verb@anything@\nobreak\ \NWlink{nuweb1a}{1a}. +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +Now use the something in an argument +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap3}\raggedright\small +\NWtarget{nuweb1c}{} \verb@"test.c"@\nobreak\ {\footnotesize {1c}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Define something}\nobreak\ {\footnotesize \NWlink{nuweb1a}{1a}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Use the \verb@something@}\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtIdentsUsed\nobreak\ \verb@something@\nobreak\ \NWlink{nuweb1a}{1a}. +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{document} +EOF + +cat > test.expected.c <<"EOF" + +/* Define something */ +something anything + +/* Use the 'something' */ +Use something +Use anything + +EOF + + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +latex test + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.c test.c +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0008a.sh b/test/00/t0008a.sh new file mode 100644 index 0000000..35a2fbb --- /dev/null +++ b/test/00/t0008a.sh @@ -0,0 +1,179 @@ +#!/bin/sh +# +# $RCSfile: t0008a.sh,v $-- Test test/00/t0008a.sh +# +# +# Test of Version flag +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of Version flag" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of Version flag" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test Version flag +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +Here >>@v<< is the version information. +@o test.c -cc +@{Here >>@v<< is the version information in code. +@} + +\end{document} +EOF + +cat > test.expected.with.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +Here >>3.14159<< is the version information. +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb?}{} \verb@"test.c"@\nobreak\ {\footnotesize {?}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Here >>3.14159<< is the version information in code.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{document} +EOF + +cat > test.expected.with.c <<"EOF" +Here >>3.14159<< is the version information in code. +EOF + +cat > test.expected.without.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +Here >>no version<< is the version information. +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb?}{} \verb@"test.c"@\nobreak\ {\footnotesize {?}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Here >>no version<< is the version information in code.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{document} +EOF + +cat > test.expected.without.c <<"EOF" +Here >>no version<< is the version information in code. +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb -V 3.14159 test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.with.tex test.tex +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.with.c test.c +if test $? -ne 0 ; then fail; fi + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.without.tex test.tex +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.without.c test.c +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0009a.sh b/test/00/t0009a.sh new file mode 100644 index 0000000..1a070a1 --- /dev/null +++ b/test/00/t0009a.sh @@ -0,0 +1,145 @@ +#!/bin/sh +# +# $RCSfile: t0009a.sh,v $-- Test test/00/t0009a.sh +# +# +# Test of user specified use of identifiers +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of user specified use of identifiers" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of user specified use of identifiers" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test user specified use of identifiers +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +Define a thing. +@o test.c -cc +@{This defines ident. +@<Use the thing defined@> +@| ident @} + +Now use it without it actually appearing in the text. + +@d Use the thing defined +@{Pretend that we use it here. +@* ident @} +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +Define a thing. +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb1a}{} \verb@"test.c"@\nobreak\ {\footnotesize {1a}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@This defines ident.@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Use the thing defined}\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtIdentsDefed\nobreak\ \verb@ident@\nobreak\ \NWlink{nuweb1b}{1b}. +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +Now use it without it actually appearing in the text. + +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap2}\raggedright\small +\NWtarget{nuweb1b}{} $\langle\,${\itshape Use the thing defined}\nobreak\ {\footnotesize {1b}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Pretend that we use it here.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1a}{1a}. +\item \NWtxtIdentsUsed\nobreak\ \verb@ident@\nobreak\ \NWlink{nuweb1a}{1a}. +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{document} +EOF + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +latex test +latex test + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0010a.sh b/test/00/t0010a.sh new file mode 100644 index 0000000..aedb4d9 --- /dev/null +++ b/test/00/t0010a.sh @@ -0,0 +1,135 @@ +#!/bin/sh +# +# $RCSfile: t0010a.sh,v $-- Test test/00/t0010a.sh +# +# +# Test cross-reference isn't followed by 'x' +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test cross-reference isn't followed by 'x'" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test cross-reference isn't followed by 'x'" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test ??? +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +Here is a cross-reference: @xref@x + +@o test.c +@{This (@xref@x) is where it is referencing. +@} +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +Here is a cross-reference: 1-01 + +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb1}{} \verb@"test.c"@\nobreak\ {\footnotesize {1}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@This (1-01) is where it is referencing.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{document} +EOF + +cat > test.expected.c <<"EOF" +This (1-01) is where it is referencing. +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +latex test +if test $? -ne 0 ; then fail; fi + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.c test.c +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0011a.sh b/test/00/t0011a.sh new file mode 100644 index 0000000..1c248ae --- /dev/null +++ b/test/00/t0011a.sh @@ -0,0 +1,97 @@ +#!/bin/sh +# +# $RCSfile: t0011a.sh,v $-- Test test/00/t0011a.sh +# +# +# Test that unimpemented fragments are indented +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test that unimpemented fragments are indented" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test that unimpemented fragments are indented" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test ??? +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@o test.c +@{Begin + @<Implemented fragment@> +End +@} + +@d Impl... +@{@<Unimplemented fragment A@> +@<Unimplemented fragment B@> +@<Unimplemented fragment C@>@} + +\end{document} +EOF + +cat > test.expected.c <<"EOF" +Begin + @<Unimplemented fragment A@> + @<Unimplemented fragment B@> + @<Unimplemented fragment C@> +End +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.c test.c +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0012a.sh b/test/00/t0012a.sh new file mode 100644 index 0000000..f1169f7 --- /dev/null +++ b/test/00/t0012a.sh @@ -0,0 +1,204 @@ +#!/bin/sh +# +# $RCSfile: t0012a.sh,v $-- Test test/00/t0012a.sh +# +# +# Test of block comments +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of block comments" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of block comments" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test block comments +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@c Here is a block comment which is long enough to need line +breaking. (And a bit extra.) +Here is a block comment which is long enough to need line +breaking. +Here is a block comment which is long enough to need line +breaking. (Some more extra.) +Here is a block comment which is long enough to need line +breaking. + +Here is more of the block comment. It is also long enough to +need line-breaking. + +@o test.c -cc +@{Here is some stuff. + @c +Here is the end of the stuff. +Here (@c) is a block comment in code. +@} + +@c This is another block comment that shouldn't end in a +newline. (So long as its length is right. +@o test.c -cc +@{This --@c-- is where it is used. +@} +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +\begin{flushleft} \small +\begin{minipage}{\linewidth} Here is a block comment which is long enough to need line +breaking. (And a bit extra.) +Here is a block comment which is long enough to need line +breaking. +Here is a block comment which is long enough to need line +breaking. (Some more extra.) +Here is a block comment which is long enough to need line +breaking. + +Here is more of the block comment. It is also long enough to +need line-breaking. + +\par\vspace{\baselineskip} +\label{scrap1}\raggedright\small +\NWtarget{nuweb?}{} \verb@"test.c"@\nobreak\ {\footnotesize {?}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Here is some stuff.@\\ +\mbox{}\verb@ @\hbox{\sffamily\slshape (Comment)}\verb@@\\ +\mbox{}\verb@Here is the end of the stuff.@\\ +\mbox{}\verb@Here (@\hbox{\sffamily\slshape (Comment)}\verb@) is a block comment in code.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtFileDefBy\ \NWlink{nuweb?}{?}\NWlink{nuweb?}{, ?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth} This is another block comment that shouldn't end in a +newline. (So long as its length is right. +\par\vspace{\baselineskip} +\label{scrap2}\raggedright\small +\NWtarget{nuweb?}{} \verb@"test.c"@\nobreak\ {\footnotesize {?}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@This --@\hbox{\sffamily\slshape (Comment)}\verb@-- is where it is used.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtFileDefBy\ \NWlink{nuweb?}{?}\NWlink{nuweb?}{, ?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{document} +EOF + +cat > test.expected.c <<"EOF" +Here is some stuff. + /* Here is a block comment which is long enough to need line + * breaking. (And a bit extra.) Here is a block comment which + * is long enough to need line breaking. Here is a block comment + * which is long enough to need line breaking. (Some more extra.) + * Here is a block comment which is long enough to need line + * breaking. + * Here is more of the block comment. It is also long enough + * to need line-breaking. + */ +Here is the end of the stuff. +Here (/* Here is a block comment which is long enough to need + * line breaking. (And a bit extra.) Here is a block comment + * which is long enough to need line breaking. Here is a + * block comment which is long enough to need line breaking. + * (Some more extra.) Here is a block comment which is long + * enough to need line breaking. + * Here is more of the block comment. It is also long enough + * to need line-breaking. + */) is a block comment in code. +This --/* This is another block comment that shouldn't end in + * a newline. (So long as its length is right. */-- is where it is used. +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.c test.c +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0013a.sh b/test/00/t0013a.sh new file mode 100644 index 0000000..09712c3 --- /dev/null +++ b/test/00/t0013a.sh @@ -0,0 +1,158 @@ +#!/bin/sh +# +# $RCSfile: t0013a.sh,v $-- Test test/00/t0013a.sh +# +# +# Test block comments aren't indexed +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test block comments aren't indexed" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test block comments aren't indexed" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test ??? +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@c +Here is a block comment which contains the word 'target'. +@o test.c -cc +@{Here is a fragment which contains the block comment +@c +That was the block comment. +Here we use another fragment. +@<Define...@> +@} + +@d Define our target +@{This fragment defines 'target'. +@| target @} + +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +\begin{flushleft} \small +\begin{minipage}{\linewidth} +Here is a block comment which contains the word 'target'. +\par\vspace{\baselineskip} +\label{scrap1}\raggedright\small +\NWtarget{nuweb1a}{} \verb@"test.c"@\nobreak\ {\footnotesize {1a}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Here is a fragment which contains the block comment@\\ +\mbox{}\verb@@\hbox{\sffamily\slshape (Comment)}\verb@@\\ +\mbox{}\verb@That was the block comment.@\\ +\mbox{}\verb@Here we use another fragment.@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Define our target}\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap2}\raggedright\small +\NWtarget{nuweb1b}{} $\langle\,${\itshape Define our target}\nobreak\ {\footnotesize {1b}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@This fragment defines 'target'.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1a}{1a}. +\item \NWtxtIdentsDefed\nobreak\ \verb@target@\nobreak\ \NWtxtIdentsNotUsed. +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{document} +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +latex test + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0014a.sh b/test/00/t0014a.sh new file mode 100644 index 0000000..e119ba6 --- /dev/null +++ b/test/00/t0014a.sh @@ -0,0 +1,125 @@ +#!/bin/sh +# +# $RCSfile: t0014a.sh,v $-- Test test/00/t0014a.sh +# +# +# Test of @@ in scraps +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of @@ in scraps" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of @@ in scraps" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test @@ in scraps +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@o test.c -cc +@{This scrap contains @@<. +@} +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb?}{} \verb@"test.c"@\nobreak\ {\footnotesize {?}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@This scrap contains @{\tt @}\verb@<.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{document} +EOF + +cat > test.expected.c <<"EOF" +This scrap contains @<. +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.c test.c +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0015a.sh b/test/00/t0015a.sh new file mode 100644 index 0000000..3b7bf0d --- /dev/null +++ b/test/00/t0015a.sh @@ -0,0 +1,152 @@ +#!/bin/sh +# +# $RCSfile: t0015a.sh,v $-- Test test/00/t0015a.sh +# +# +# Test of ??? +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of ???" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of ???" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test ??? +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@d Sort @'key@' of size @'n@' for @'ordering@' +@{for (int j = 1; j < @2; j++) +{ + int i = j - 1; + int kj = @1[j]; + + do + { + int ki = @1[i]; + + if (@3) + break; + @1[i + 1] = ki; + i -= 1; + } while (i >= 0); + @1[i + 1] = kj; +} +@} + +Test in-text @{@<Sort @'key@'...@>@} usage. +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Sort \hbox{\slshape\sffamily key\/} of size \hbox{\slshape\sffamily n\/} for \hbox{\slshape\sffamily ordering\/}}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@for (int j = 1; j < @\hbox{\slshape\sffamily n\/}\verb@; j++)@\\ +\mbox{}\verb@{@\\ +\mbox{}\verb@ int i = j - 1;@\\ +\mbox{}\verb@ int kj = @\hbox{\slshape\sffamily key\/}\verb@[j];@\\ +\mbox{}\verb@@\\ +\mbox{}\verb@ do@\\ +\mbox{}\verb@ {@\\ +\mbox{}\verb@ int ki = @\hbox{\slshape\sffamily key\/}\verb@[i];@\\ +\mbox{}\verb@@\\ +\mbox{}\verb@ if (@\hbox{\slshape\sffamily ordering\/}\verb@)@\\ +\mbox{}\verb@ break;@\\ +\mbox{}\verb@ @\hbox{\slshape\sffamily key\/}\verb@[i + 1] = ki;@\\ +\mbox{}\verb@ i -= 1;@\\ +\mbox{}\verb@ } while (i >= 0);@\\ +\mbox{}\verb@ @\hbox{\slshape\sffamily key\/}\verb@[i + 1] = kj;@\\ +\mbox{}\verb@}@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item {\NWtxtMacroNoRef}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +Test in-text \verb@@$\langle\,${\itshape Sort \verb@key@ of size \verb@n@ for \verb@ordering@}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$\verb@@ usage. +\end{document} +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0016a.sh b/test/00/t0016a.sh new file mode 100644 index 0000000..eb23991 --- /dev/null +++ b/test/00/t0016a.sh @@ -0,0 +1,259 @@ +#!/bin/sh +# +# $RCSfile: t0016a.sh,v $-- Test test/00/t0016a.sh +# +# +# Test no pagebreak before scraps +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test no pagebreak before scraps" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test no pagebreak before scraps" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test ??? +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +@c Here comes a block comment just before a scrap and we don't +want this separated from it. (Thinks: +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because:) + +@d Here is a scrap. +@{This is the contents of the scrap. + +More stuff, not related to songs without ends. + +"This is a song that will get on your nerves, + Get on your nerves, + Get on your nerves," + +Ad infinitum. +@} + +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: + +\begin{flushleft} \small +\begin{minipage}{\linewidth} Here comes a block comment just before a scrap and we don't +want this separated from it. (Thinks: +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because: +This is a song without and end. It goes on and on my friend. Some +people started singing it, not knowing what it was, and they'll +go on forever just because:) + +\par\vspace{\baselineskip} +\label{scrap1}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Here is a scrap.}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@This is the contents of the scrap.@\\ +\mbox{}\verb@@\\ +\mbox{}\verb@More stuff, not related to songs without ends.@\\ +\mbox{}\verb@@\\ +\mbox{}\verb@"This is a song that will get on your nerves,@\\ +\mbox{}\verb@ Get on your nerves,@\\ +\mbox{}\verb@ Get on your nerves,"@\\ +\mbox{}\verb@@\\ +\mbox{}\verb@Ad infinitum.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item {\NWtxtMacroNoRef}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{document} +EOF + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0017a.sh b/test/00/t0017a.sh new file mode 100644 index 0000000..1128871 --- /dev/null +++ b/test/00/t0017a.sh @@ -0,0 +1,318 @@ +#!/bin/sh +# +# $RCSfile: t0017a.sh,v $-- Test test/00/t0017a.sh +# +# +# Test of quoted scraps +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of quoted scraps" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of quoted scraps" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test quoted scraps +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@o test.c -cc +@{Test of quoted fragments. + @<Insert first fragment@> + @<Insert second fragment@> + @<Insert third fragment@> + @<Insert parameter @'whatsit@'...@> +End of test. +@} + +@d Insert first fragment +@{This fragment is not quoted. + @<Insert unquoted fragment@> + @<Insert quoted fragment@> + @<Insert parameter @'1@'...@> + @<Insert param...@> +End of first fragment.@} + +@q Insert second fragment +@{This fragment is quoted. + @<Insert unquoted fragment@> + @<Insert quoted fragment@> + @<Insert parameter @'2@'...@> + @<Insert param...@> +End of second fragment.@} + +@d Insert third fragment +@{This fragment is not quoted. + @<Insert unquoted fragment@> + @<Insert quoted fragment@> + @<Insert parameter @'3@'...@> + @<Insert param...@> +End of third fragment.@} + +@d Insert unquoted fragment +@{This fragment in file @f is not quoted@} + +@q Insert quoted fragment +@{This fragment in file @f is quoted@} + +@d Insert parameter @'thing@' fragment +@{Here >>@1<< is the parameter@} + +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb1a}{} \verb@"test.c"@\nobreak\ {\footnotesize {1a}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Test of quoted fragments.@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Insert first fragment}\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Insert second fragment}\nobreak\ {\footnotesize \NWlink{nuweb1c}{1c}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Insert third fragment}\nobreak\ {\footnotesize \NWlink{nuweb1d}{1d}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Insert parameter \verb@whatsit@ fragment}\nobreak\ {\footnotesize \NWlink{nuweb2b}{2b}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@End of test.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap2}\raggedright\small +\NWtarget{nuweb1b}{} $\langle\,${\itshape Insert first fragment}\nobreak\ {\footnotesize {1b}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@This fragment is not quoted.@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Insert unquoted fragment}\nobreak\ {\footnotesize \NWlink{nuweb1e}{1e}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Insert quoted fragment}\nobreak\ {\footnotesize \NWlink{nuweb2a}{2a}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Insert parameter \verb@1@ fragment}\nobreak\ {\footnotesize \NWlink{nuweb2b}{2b}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Insert parameter \verb@thing@ fragment}\nobreak\ {\footnotesize \NWlink{nuweb2b}{2b}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@End of first fragment.@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1a}{1a}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap3}\raggedright\small +\NWtarget{nuweb1c}{} $\langle\,${\itshape Insert second fragment}\nobreak\ {\footnotesize {1c}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@This fragment is quoted.@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Insert unquoted fragment}\nobreak\ {\footnotesize \NWlink{nuweb1e}{1e}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Insert quoted fragment}\nobreak\ {\footnotesize \NWlink{nuweb2a}{2a}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Insert parameter \verb@2@ fragment}\nobreak\ {\footnotesize \NWlink{nuweb2b}{2b}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Insert parameter \verb@thing@ fragment}\nobreak\ {\footnotesize \NWlink{nuweb2b}{2b}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@End of second fragment.@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1a}{1a}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap4}\raggedright\small +\NWtarget{nuweb1d}{} $\langle\,${\itshape Insert third fragment}\nobreak\ {\footnotesize {1d}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@This fragment is not quoted.@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Insert unquoted fragment}\nobreak\ {\footnotesize \NWlink{nuweb1e}{1e}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Insert quoted fragment}\nobreak\ {\footnotesize \NWlink{nuweb2a}{2a}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Insert parameter \verb@3@ fragment}\nobreak\ {\footnotesize \NWlink{nuweb2b}{2b}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@ @\hbox{$\langle\,${\itshape Insert parameter \verb@thing@ fragment}\nobreak\ {\footnotesize \NWlink{nuweb2b}{2b}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@End of third fragment.@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1a}{1a}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap5}\raggedright\small +\NWtarget{nuweb1e}{} $\langle\,${\itshape Insert unquoted fragment}\nobreak\ {\footnotesize {1e}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@This fragment in file @\hbox{\sffamily\slshape file name}\verb@ is not quoted@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1b}{1b}\NWlink{nuweb1c}{c}\NWlink{nuweb1d}{d}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap6}\raggedright\small +\NWtarget{nuweb2a}{} $\langle\,${\itshape Insert quoted fragment}\nobreak\ {\footnotesize {2a}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@This fragment in file @\hbox{\sffamily\slshape file name}\verb@ is quoted@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1b}{1b}\NWlink{nuweb1c}{c}\NWlink{nuweb1d}{d}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap7}\raggedright\small +\NWtarget{nuweb2b}{} $\langle\,${\itshape Insert parameter \hbox{\slshape\sffamily thing\/} fragment}\nobreak\ {\footnotesize {2b}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Here >>@\hbox{\slshape\sffamily thing\/}\verb@<< is the parameter@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1a}{1a}\NWlink{nuweb1b}{b}\NWlink{nuweb1c}{c}\NWlink{nuweb1d}{d}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{document} +EOF + +cat > test.expected.c <<"EOF" +Test of quoted fragments. + /* Insert first fragment */ + This fragment is not quoted. + /* Insert unquoted fragment */ + This fragment in file test.c is not quoted + /* Insert quoted fragment */ + This fragment in file @f is quoted + /* Insert parameter '1' fragment */ + Here >>1<< is the parameter + /* Insert parameter 'thing' fragment */ + Here >>thing<< is the parameter + End of first fragment. + /* Insert second fragment */ + This fragment is quoted. + @<Insert unquoted fragment@> + @<Insert quoted fragment@> + @<Insert parameter @'2@' fragment@> + @<Insert parameter @'thing@' fragment@> + End of second fragment. + /* Insert third fragment */ + This fragment is not quoted. + /* Insert unquoted fragment */ + This fragment in file test.c is not quoted + /* Insert quoted fragment */ + This fragment in file @f is quoted + /* Insert parameter '3' fragment */ + Here >>3<< is the parameter + /* Insert parameter 'thing' fragment */ + Here >>thing<< is the parameter + End of third fragment. + /* Insert parameter 'whatsit' fragment */ + Here >>whatsit<< is the parameter +End of test. +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +latex test +if test $? -ne 0 ; then fail; fi + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.c test.c +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0018a.sh b/test/00/t0018a.sh new file mode 100644 index 0000000..d2e8097 --- /dev/null +++ b/test/00/t0018a.sh @@ -0,0 +1,150 @@ +#!/bin/sh +# +# $RCSfile: t0018a.sh,v $-- Test test/00/t0018a.sh +# +# +# Test of using hyperlinks +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of using hyperlinks" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of using hyperlinks" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test using hyperlinks +# + +cat > test.w <<"EOF" +\documentclass{article} +\NWuseHyperlinks +\begin{document} +@o test.c -cc +@{@<Use a fragment@> +@} +@d Use... +@{Here is a fragment. + Make sure it is referenced properly.@} +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{\hypertarget{#1}{#2}} +\newcommand{\NWlink}[2]{\hyperlink{#1}{#2}} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{\usepackage[pdftex,colorlinks=true]{hyperref}} +\documentclass{article} +\NWuseHyperlinks +\begin{document} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb1a}{} \verb@"test.c"@\nobreak\ {\footnotesize {1a}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@@\hbox{$\langle\,${\itshape Use a fragment}\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap2}\raggedright\small +\NWtarget{nuweb1b}{} $\langle\,${\itshape Use a fragment}\nobreak\ {\footnotesize {1b}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Here is a fragment.@\\ +\mbox{}\verb@ Make sure it is referenced properly.@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1a}{1a}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{document} +EOF + + +# [Add other files here. Avoid any extra processing such as +# decompression until after nuweb has run. If nuweb fails this script +# can save time by not decompressing. ] + +$bin/nuweb -h "pdftex,colorlinks=true" test.w +if test $? -ne 0 ; then fail; fi + +pdflatex test +if test $? -ne 0 ; then fail; fi + +$bin/nuweb -h "pdftex,colorlinks=true" test.w +if test $? -ne 0 ; then fail; fi + +pdflatex test +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0019a.sh b/test/00/t0019a.sh new file mode 100644 index 0000000..e462e39 --- /dev/null +++ b/test/00/t0019a.sh @@ -0,0 +1,158 @@ +#!/bin/sh +# +# $RCSfile: t0019a.sh,v $-- Test test/00/t0019a.sh +# +# +# Test of C++ comments +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of C++ comments" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of C++ comments" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test C++ comments +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +This tests C++ style comments. +@o test.cpp -c+ +@{@<File header@> +@<More stuff@> +@<A little more stuff@> +@} + +@d File header +@{// The comments here are explicit. +// @f +@} + +@c +Here we have a lot of stuff that is going to go into a block +comment which we make long enough to spread over several lines. +Here we have a lot of stuff that is going to go into a block +comment which we make long enough to spread over several lines. +Here we have a lot of stuff that is going to go into a block +comment which we make long enough to spread over several lines. +Here we have a lot of stuff that is going to go into a block +comment which we make long enough to spread over several lines. +Here we have a lot of stuff that is going to go into a block +comment which we make long enough to spread over several lines. +Here we have a lot of stuff that is going to go into a block +comment which we make long enough to spread over several lines. +@d More stuff +@{@c +This is the body of more stuff. +@} + +@d A little more stuff +@{Another check on a single-line comment. + And another check on block comments. + @<More stuff@> +That is the end of a little more stuff. +@} +\end{document} +EOF + +cat > test.expected.cpp <<"EOF" +// File header +// The comments here are explicit. +// test.cpp + +// More stuff +// Here we have a lot of stuff that is going to go into a block +// comment which we make long enough to spread over several lines. +// Here we have a lot of stuff that is going to go into a block +// comment which we make long enough to spread over several lines. +// Here we have a lot of stuff that is going to go into a block +// comment which we make long enough to spread over several lines. +// Here we have a lot of stuff that is going to go into a block +// comment which we make long enough to spread over several lines. +// Here we have a lot of stuff that is going to go into a block +// comment which we make long enough to spread over several lines. +// Here we have a lot of stuff that is going to go into a block +// comment which we make long enough to spread over several lines. + +This is the body of more stuff. + +// A little more stuff +Another check on a single-line comment. + And another check on block comments. + // More stuff + // Here we have a lot of stuff that is going to go into a block + // comment which we make long enough to spread over several + // lines. Here we have a lot of stuff that is going to go into + // a block comment which we make long enough to spread over + // several lines. Here we have a lot of stuff that is going + // to go into a block comment which we make long enough to + // spread over several lines. Here we have a lot of stuff that + // is going to go into a block comment which we make long enough + // to spread over several lines. Here we have a lot of stuff + // that is going to go into a block comment which we make long + // enough to spread over several lines. Here we have a lot + // of stuff that is going to go into a block comment which + // we make long enough to spread over several lines. + This is the body of more stuff. + +That is the end of a little more stuff. + +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.cpp test.cpp +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0020a.sh b/test/00/t0020a.sh new file mode 100644 index 0000000..61df69f --- /dev/null +++ b/test/00/t0020a.sh @@ -0,0 +1,126 @@ +#!/bin/sh +# +# $RCSfile: t0020a.sh,v $-- Test test/00/t0020a.sh +# +# +# Test of include paths +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of include paths" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of include paths" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test include paths +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +Here is the main. +@i testincl.w +Still in main +@i incltest.w +End in main. +\end{document} +EOF + +cat >testincl.w <<"EOF" +Here is top level include file. +EOF + +cat >incltest.w <<"EOF" +Here is include file that must be searched for. +EOF + +mkdir lvl1 +if test $? -ne 0 ; then no_result; fi + +mkdir lvl1/lvl2 +if test $? -ne 0 ; then no_result; fi + +mv incltest.w lvl1/lvl2 +if test $? -ne 0 ; then no_result; fi + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +Here is the main. +Here is top level include file. +Still in main +Here is include file that must be searched for. +End in main. +\end{document} +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb -I lvl1 -I lvl1/lvl2 test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0021a.sh b/test/00/t0021a.sh new file mode 100644 index 0000000..7bd5b4d --- /dev/null +++ b/test/00/t0021a.sh @@ -0,0 +1,126 @@ +#!/bin/sh +# +# $RCSfile: t0021a.sh,v $-- Test test/00/t0020a.sh +# +# +# Test of include paths +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of include paths" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of include paths" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test include paths +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +Here is the main. +@i testincl.w +Still in main +@i incltest.w +End in main. +\end{document} +EOF + +cat >testincl.w <<"EOF" +Here is top level include file. +EOF + +cat >incltest.w <<"EOF" +Here is include file that must be searched for. +EOF + +mkdir lvl1 +if test $? -ne 0 ; then no_result; fi + +mkdir lvl1/lvl2 +if test $? -ne 0 ; then no_result; fi + +mv incltest.w lvl1/lvl2 +if test $? -ne 0 ; then no_result; fi + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +Here is the main. +Here is top level include file. +Still in main +Here is include file that must be searched for. +End in main. +\end{document} +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb -Ilvl1 -Ilvl1/lvl2 test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0022a.sh b/test/00/t0022a.sh new file mode 100644 index 0000000..1e13f1b --- /dev/null +++ b/test/00/t0022a.sh @@ -0,0 +1,111 @@ +#!/bin/sh +# +# $RCSfile: t0022a.sh,v $-- Test test/00/t0022a.sh +# +# +# Test that missing includes don't bomb +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test that missing includes don't bomb" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test that missing includes don't bomb" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test ??? +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +Here follows a file that exists. +@i exist.w +Here follows a file that doesn't exist. +@i non-exist.w +No more files. +\end{document} +EOF + +cat >exist.w <<"EOF" +Here is the existing file. +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +Here follows a file that exists. +Here is the existing file. +Here follows a file that doesn't exist. +No more files. +\end{document} +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0023a.sh b/test/00/t0023a.sh new file mode 100644 index 0000000..8888456 --- /dev/null +++ b/test/00/t0023a.sh @@ -0,0 +1,110 @@ +#!/bin/sh +# +# $RCSfile: t0023a.sh,v $-- Test test/00/t0023a.sh +# +# +# Test Perl comments +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test Perl comments" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test Perl comments" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@c +Here is a block comment that takes many lines. +Here is a block comment that takes many lines. +Here is a block comment that takes many lines. +Here is a block comment that takes many lines. +@o test -cp +@{@<First stuff@> +Now a block comment. +@c +@<Second stuff@> +End +@} + +@d First... +@{This is the body of first stuff. +@} + +@d Second... +@{Yes, it's the second stuff. +@} +\end{document} +EOF + +cat > test.expected <<"EOF" +# First stuff +This is the body of first stuff. + +Now a block comment. +# Here is a block comment that takes many lines. Here is a block +# comment that takes many lines. Here is a block comment that +# takes many lines. Here is a block comment that takes many lines. + +# Second stuff +Yes, it's the second stuff. + +End +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected test +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0024a.sh b/test/00/t0024a.sh new file mode 100644 index 0000000..cd972ca --- /dev/null +++ b/test/00/t0024a.sh @@ -0,0 +1,397 @@ +#!/bin/sh +# +# $RCSfile: t0024a.sh,v $-- Test test/00/t0024a.sh +# +# +# Test of Local and global sectors +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of Local and global sectors" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of Local and global sectors" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test Local and global sectors +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@o test.actual.c +@{ First use in global +@<Frag 1@> +@} +@d Frag 1 +@{Global sector line one. +@} +@s +@d Frag 1 +@{First sector line one. +@} +@o test.actual.c +@{Use first local +@<Frag 1@> +@} +@m +@s +@o test.actual.c +@{Use second local +@<Frag 1@> +@} +@d Frag 1 +@{Second sector line one. +@} +@m +@S +@d Frag 1 +@{Global sector line two. +@} +@s +@d Frag 1 +@{Third sector line one. +@} +@o test.actual.c +@{Use second local +@<Frag 1@> +@} +@m +@S +@d Frag 1 +@{Global sector line three. +@} +@o test.actual.c +@{ Last use in global +@<Frag 1@> +@} +@m +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb1a}{} \verb@"test.actual.c"@\nobreak\ {\footnotesize {1a}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@ First use in global@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}, \ldots\ }$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtFileDefBy\ \NWlink{nuweb1a}{1a}\NWlink{nuweb1d}{d}\NWlink{nuweb1e}{e}\NWlink{nuweb2c}{, 2c}\NWlink{nuweb2e}{e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap2}\raggedright\small +\NWtarget{nuweb1b}{} $\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize {1b}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Global sector line one.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroDefBy\ \NWlink{nuweb1b}{1b}\NWlink{nuweb2a}{, 2a}\NWlink{nuweb2d}{d}. +\item \NWtxtMacroRefIn\ \NWlink{nuweb1a}{1a}\NWlink{nuweb2e}{, 2e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} + +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap3}\raggedright\small +\NWtarget{nuweb1c}{} $\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize {1c}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@First sector line one.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1d}{1d}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap4}\raggedright\small +\NWtarget{nuweb1d}{} \verb@"test.actual.c"@\nobreak\ {\footnotesize {1d}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Use first local@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize \NWlink{nuweb1c}{1c}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtFileDefBy\ \NWlink{nuweb1a}{1a}\NWlink{nuweb1d}{d}\NWlink{nuweb1e}{e}\NWlink{nuweb2c}{, 2c}\NWlink{nuweb2e}{e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} + +{\small\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item $\langle\,$Frag 1\nobreak\ {\footnotesize \NWlink{nuweb1c}{1c}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb1d}{1d}.} +\end{list}} + +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap5}\raggedright\small +\NWtarget{nuweb1e}{} \verb@"test.actual.c"@\nobreak\ {\footnotesize {1e}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Use second local@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize \NWlink{nuweb1f}{1f}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtFileDefBy\ \NWlink{nuweb1a}{1a}\NWlink{nuweb1d}{d}\NWlink{nuweb1e}{e}\NWlink{nuweb2c}{, 2c}\NWlink{nuweb2e}{e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap6}\raggedright\small +\NWtarget{nuweb1f}{} $\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize {1f}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Second sector line one.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1e}{1e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} + +{\small\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item $\langle\,$Frag 1\nobreak\ {\footnotesize \NWlink{nuweb1f}{1f}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb1e}{1e}.} +\end{list}} + +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap7}\raggedright\small +\NWtarget{nuweb2a}{} $\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize {2a}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Global sector line two.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroDefBy\ \NWlink{nuweb1b}{1b}\NWlink{nuweb2a}{, 2a}\NWlink{nuweb2d}{d}. +\item \NWtxtMacroRefIn\ \NWlink{nuweb1a}{1a}\NWlink{nuweb2e}{, 2e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} + +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap8}\raggedright\small +\NWtarget{nuweb2b}{} $\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize {2b}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Third sector line one.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb2c}{2c}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap9}\raggedright\small +\NWtarget{nuweb2c}{} \verb@"test.actual.c"@\nobreak\ {\footnotesize {2c}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Use second local@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize \NWlink{nuweb2b}{2b}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtFileDefBy\ \NWlink{nuweb1a}{1a}\NWlink{nuweb1d}{d}\NWlink{nuweb1e}{e}\NWlink{nuweb2c}{, 2c}\NWlink{nuweb2e}{e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} + +{\small\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item $\langle\,$Frag 1\nobreak\ {\footnotesize \NWlink{nuweb2b}{2b}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb2c}{2c}.} +\end{list}} + +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap10}\raggedright\small +\NWtarget{nuweb2d}{} $\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize {2d}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Global sector line three.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroDefBy\ \NWlink{nuweb1b}{1b}\NWlink{nuweb2a}{, 2a}\NWlink{nuweb2d}{d}. +\item \NWtxtMacroRefIn\ \NWlink{nuweb1a}{1a}\NWlink{nuweb2e}{, 2e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap11}\raggedright\small +\NWtarget{nuweb2e}{} \verb@"test.actual.c"@\nobreak\ {\footnotesize {2e}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@ Last use in global@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}, \ldots\ }$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtFileDefBy\ \NWlink{nuweb1a}{1a}\NWlink{nuweb1d}{d}\NWlink{nuweb1e}{e}\NWlink{nuweb2c}{, 2c}\NWlink{nuweb2e}{e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} + +{\small\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item $\langle\,$Frag 1\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}\NWlink{nuweb2a}{, 2a}\NWlink{nuweb2d}{d}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb1a}{1a}\NWlink{nuweb2e}{, 2e}. +} +\end{list}} +\end{document} +EOF + +cat > test.expected.c <<"EOF" + First use in global +Global sector line one. +Global sector line two. +Global sector line three. + +Use first local +First sector line one. + +Use second local +Second sector line one. + +Use second local +Third sector line one. + + Last use in global +Global sector line one. +Global sector line two. +Global sector line three. + +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +latex test +if test $? -ne 0 ; then fail; fi + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +latex test +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.c test.actual.c +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0025a.sh b/test/00/t0025a.sh new file mode 100644 index 0000000..5114542 --- /dev/null +++ b/test/00/t0025a.sh @@ -0,0 +1,426 @@ +#!/bin/sh +# +# $RCSfile: t0025a.sh,v $-- Test test/00/t0024a.sh +# +# +# Test of Local and global sectors +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of Local and global sectors" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of Local and global sectors" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test Local and global sectors +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@o test.actual.c +@{ First use in global +@<Frag 1@> +@} +@d Frag 1 +@{Base sector line one. +@} +@s +@d Frag 1 +@{First sector line one. +@} +@o test.actual.c +@{Use first local +@<Frag 1@> +@<+ Frag 2@> +@} +@m +@s +@o test.actual.c +@{Use second local +@<Frag 1@> +@} +@d Frag 1 +@{Second sector line one. +@} +@m +@S +@d Frag 1 +@{Base sector line two. +@} +@s +@d Frag 1 +@{Third sector line one. +@} +@o test.actual.c +@{Use second local +@<Frag 1@> +@} +@m +@S +@d Frag 1 +@{Base sector line three. +@} +@o test.actual.c +@{ Last use in global +@<Frag 1@> +@} +@d+ Frag 2 +@{Here is frag 2 +@} +@m +@m+ +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb1a}{} \verb@"test.actual.c"@\nobreak\ {\footnotesize {1a}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@ First use in global@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}, \ldots\ }$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtFileDefBy\ \NWlink{nuweb1a}{1a}\NWlink{nuweb1d}{d}\NWlink{nuweb1e}{e}\NWlink{nuweb2c}{, 2c}\NWlink{nuweb2e}{e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap2}\raggedright\small +\NWtarget{nuweb1b}{} $\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize {1b}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Base sector line one.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroDefBy\ \NWlink{nuweb1b}{1b}\NWlink{nuweb2a}{, 2a}\NWlink{nuweb2d}{d}. +\item \NWtxtMacroRefIn\ \NWlink{nuweb1a}{1a}\NWlink{nuweb2e}{, 2e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} + +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap3}\raggedright\small +\NWtarget{nuweb1c}{} $\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize {1c}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@First sector line one.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1d}{1d}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap4}\raggedright\small +\NWtarget{nuweb1d}{} \verb@"test.actual.c"@\nobreak\ {\footnotesize {1d}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Use first local@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize \NWlink{nuweb1c}{1c}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Frag 2}\nobreak\ {\footnotesize \NWlink{nuweb2f}{2f}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtFileDefBy\ \NWlink{nuweb1a}{1a}\NWlink{nuweb1d}{d}\NWlink{nuweb1e}{e}\NWlink{nuweb2c}{, 2c}\NWlink{nuweb2e}{e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} + +{\small\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item $\langle\,$Frag 1\nobreak\ {\footnotesize \NWlink{nuweb1c}{1c}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb1d}{1d}.} +\end{list}} + +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap5}\raggedright\small +\NWtarget{nuweb1e}{} \verb@"test.actual.c"@\nobreak\ {\footnotesize {1e}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Use second local@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize \NWlink{nuweb1f}{1f}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtFileDefBy\ \NWlink{nuweb1a}{1a}\NWlink{nuweb1d}{d}\NWlink{nuweb1e}{e}\NWlink{nuweb2c}{, 2c}\NWlink{nuweb2e}{e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap6}\raggedright\small +\NWtarget{nuweb1f}{} $\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize {1f}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Second sector line one.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1e}{1e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} + +{\small\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item $\langle\,$Frag 1\nobreak\ {\footnotesize \NWlink{nuweb1f}{1f}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb1e}{1e}.} +\end{list}} + +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap7}\raggedright\small +\NWtarget{nuweb2a}{} $\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize {2a}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Base sector line two.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroDefBy\ \NWlink{nuweb1b}{1b}\NWlink{nuweb2a}{, 2a}\NWlink{nuweb2d}{d}. +\item \NWtxtMacroRefIn\ \NWlink{nuweb1a}{1a}\NWlink{nuweb2e}{, 2e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} + +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap8}\raggedright\small +\NWtarget{nuweb2b}{} $\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize {2b}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Third sector line one.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb2c}{2c}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap9}\raggedright\small +\NWtarget{nuweb2c}{} \verb@"test.actual.c"@\nobreak\ {\footnotesize {2c}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Use second local@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize \NWlink{nuweb2b}{2b}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtFileDefBy\ \NWlink{nuweb1a}{1a}\NWlink{nuweb1d}{d}\NWlink{nuweb1e}{e}\NWlink{nuweb2c}{, 2c}\NWlink{nuweb2e}{e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} + +{\small\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item $\langle\,$Frag 1\nobreak\ {\footnotesize \NWlink{nuweb2b}{2b}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb2c}{2c}.} +\end{list}} + +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap10}\raggedright\small +\NWtarget{nuweb2d}{} $\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize {2d}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Base sector line three.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroDefBy\ \NWlink{nuweb1b}{1b}\NWlink{nuweb2a}{, 2a}\NWlink{nuweb2d}{d}. +\item \NWtxtMacroRefIn\ \NWlink{nuweb1a}{1a}\NWlink{nuweb2e}{, 2e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap11}\raggedright\small +\NWtarget{nuweb2e}{} \verb@"test.actual.c"@\nobreak\ {\footnotesize {2e}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@ Last use in global@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Frag 1}\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}, \ldots\ }$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtFileDefBy\ \NWlink{nuweb1a}{1a}\NWlink{nuweb1d}{d}\NWlink{nuweb1e}{e}\NWlink{nuweb2c}{, 2c}\NWlink{nuweb2e}{e}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap12}\raggedright\small +\NWtarget{nuweb2f}{} $\langle\,${\itshape Frag 2}\nobreak\ {\footnotesize {2f}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Here is frag 2@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1d}{1d}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} + +{\small\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item $\langle\,$Frag 1\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}\NWlink{nuweb2a}{, 2a}\NWlink{nuweb2d}{d}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb1a}{1a}\NWlink{nuweb2e}{, 2e}. +} +\end{list}} + +{\small\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item $\langle\,$Frag 2\nobreak\ {\footnotesize \NWlink{nuweb2f}{2f}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb1d}{1d}.} +\end{list}} +\end{document} +EOF + +cat > test.expected.c <<"EOF" + First use in global +Base sector line one. +Base sector line two. +Base sector line three. + +Use first local +First sector line one. + +Here is frag 2 + +Use second local +Second sector line one. + +Use second local +Third sector line one. + + Last use in global +Base sector line one. +Base sector line two. +Base sector line three. + +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +latex test +if test $? -ne 0 ; then fail; fi + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +latex test +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.c test.actual.c +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0026a.sh b/test/00/t0026a.sh new file mode 100644 index 0000000..c2daa43 --- /dev/null +++ b/test/00/t0026a.sh @@ -0,0 +1,118 @@ +#!/bin/sh +# +# $RCSfile: t0026a.sh,v $-- Test test/00/t0026a.sh +# +# +# Test of ??? +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of ???" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of ???" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test ??? +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@o test.actual.c +@{ First use in global +@<Frag 1@> +@} +@d Frag 1 +@{Base sector line one. +@} +@s +@d Frag 1 +@{First sector line one. +@} +@o test.actual.c +@{@<Frag 3@> +@} +@q Frag 3 +@{Use first local +@<Frag 1@> +@<+ Frag 2@> +@} +@m +@S +@d Frag 1 +@{Base sector line two. +@} +@d+ Frag 2 +@{Here is frag 2 +@} +@m +@m+ +\end{document} +EOF + +cat > test.expected.c <<"EOF" + First use in global +Base sector line one. +Base sector line two. + +Use first local +@<Frag 1@> +@<+Frag 2@> + +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.c test.actual.c +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0027a.sh b/test/00/t0027a.sh new file mode 100644 index 0000000..f14b243 --- /dev/null +++ b/test/00/t0027a.sh @@ -0,0 +1,127 @@ +#!/bin/sh +# +# $RCSfile: t0027a.sh,v $-- Test test/00/t0027a.sh +# +# +# Test of nested global macros +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of nested global macros" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of nested global macros" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test nested global macros +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@o test.actual.c +@{ First use in global +@<Frag 1@> +@} +@d Frag 1 +@{Base sector line one. +@} +@d Frag 4 uses @'thing@' +@{Access @1 +@} +@q Frag 5 +@{@<Frag 4 uses @<+Frag 2@>@> +@} +@s +@d Frag 1 +@{First sector line one. +@} +@o test.actual.c +@{@<Frag 3@> +@} +@q Frag 3 +@{Use first local +@<Frag 1@> +@<+ Frag 2@> +@} +@m +@S +@d Frag 1 +@{Base sector line two. +@<Frag 5@> +@} +@d+ Frag 2 +@{Here is frag 2 +@} +@m +@m+ +\end{document} +EOF + +cat > test.expected.c <<"EOF" + First use in global +Base sector line one. +Base sector line two. +@<Frag 4 uses @<+Frag 2@>@> + + +Use first local +@<Frag 1@> +@<+Frag 2@> + +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.c test.actual.c +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0028a.sh b/test/00/t0028a.sh new file mode 100644 index 0000000..9da2328 --- /dev/null +++ b/test/00/t0028a.sh @@ -0,0 +1,157 @@ +#!/bin/sh +# +# $RCSfile: t0028a.sh,v $-- Test test/00/t0028a.sh +# +# +# Test of Maths in arguments +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of Maths in arguments" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of Maths in arguments" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test Maths in arguments +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@d Frag with @'arg1@' and @'$arg2@' +@{Here is the first arg:@1. +Here is the second arg:@2. +@} + +@o test.c -cc +@{Front +@<Frag with @'$tuff@' and @'Non_sense@'@> +Back +@} +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Frag with \hbox{\slshape\sffamily arg1\/} and \hbox{\slshape\sffamily \$arg2\/}}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Here is the first arg:@\hbox{\slshape\sffamily arg1\/}\verb@.@\\ +\mbox{}\verb@Here is the second arg:@\hbox{\slshape\sffamily \$arg2\/}\verb@.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap2}\raggedright\small +\NWtarget{nuweb?}{} \verb@"test.c"@\nobreak\ {\footnotesize {?}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Front@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Frag with \verb@$tuff@ and \verb@Non_sense@}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@Back@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{document} +EOF + +cat > test.expected.c <<"EOF" +Front +/* Frag with '$tuff' and 'Non_sense' */ +Here is the first arg:$tuff. +Here is the second arg:Non_sense. + +Back +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.c test.c +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0029a.sh b/test/00/t0029a.sh new file mode 100644 index 0000000..0f6058b --- /dev/null +++ b/test/00/t0029a.sh @@ -0,0 +1,301 @@ +#!/bin/sh +# +# $RCSfile: t0029a.sh,v $-- Test test/00/t0029a.sh +# +# +# Test of Bar in fragment names is invisible +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of Bar in fragment names is invisible" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of Bar in fragment names is invisible" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test Bar in fragment names is invisible +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@d Atom +@{@} + +@d atom +@{@} + +@d Atomic +@{@} + +@d atomi... +@{ +@} + +@d Save |file| abc +@{@} + +@d Save file uvw +@{@} + +@d Adam +@{@} + +@d atoms +@{@} + +@o test.c +@{@<Atom@> +@<atom@> +@<Save |file| abc@> +@<Save file uvw@> +@<Adam@> +@<atomic@> +@<atoms@> +@<Atomic@> +@} + +@m + +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Atom}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap2}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape atom}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap3}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Atomic}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap4}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape atomic}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap5}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Save |file| abc}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap6}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Save file uvw}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap7}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Adam}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap8}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape atoms}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap9}\raggedright\small +\NWtarget{nuweb?}{} \verb@"test.c"@\nobreak\ {\footnotesize {?}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@@\hbox{$\langle\,${\itshape Atom}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape atom}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Save |file| abc}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Save file uvw}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Adam}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape atomic}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape atoms}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Atomic}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} + +{\small\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item $\langle\,$Adam\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb?}{?}.} +\item $\langle\,$Atom\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb?}{?}.} +\item $\langle\,$atom\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb?}{?}.} +\item $\langle\,$Atomic\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb?}{?}.} +\item $\langle\,$atomic\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb?}{?}.} +\item $\langle\,$atoms\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb?}{?}.} +\item $\langle\,$Save |file| abc\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb?}{?}.} +\item $\langle\,$Save file uvw\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb?}{?}.} +\end{list}} + +\end{document} +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0032a.sh b/test/00/t0032a.sh new file mode 100644 index 0000000..12ddf43 --- /dev/null +++ b/test/00/t0032a.sh @@ -0,0 +1,194 @@ +#!/bin/sh +# +# $RCSfile: t0032a.sh,v $-- Test test/00/t0032a.sh +# +# +# Test of Embedded fragments as arguments +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of Embedded fragments as arguments" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of Embedded fragments as arguments" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test Embedded fragments as arguments +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@o test.c -cc +@{Begin +@<Outer @'abc@' and @'def@' retuO@> +@<Outer @'cba@' and @'fed@' retuO@> +End +@} + +@d Outer @'Arg1@' and @'Arg2@' retuO +@{Start +@<Inner @{x@1y@2z@} rennI@> +Finish +@} + +@d Inner @'Stuff@' rennI +@{XX>>@1<<YY@} + +@m + +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb1a}{} \verb@"test.c"@\nobreak\ {\footnotesize {1a}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Begin@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Outer \verb@abc@ and \verb@def@ retuO}\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Outer \verb@cba@ and \verb@fed@ retuO}\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@End@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap2}\raggedright\small +\NWtarget{nuweb1b}{} $\langle\,${\itshape Outer \hbox{\slshape\sffamily Arg1\/} and \hbox{\slshape\sffamily Arg2\/} retuO}\nobreak\ {\footnotesize {1b}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Start@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Inner \verb@xArg1yArg2z@ rennI}\nobreak\ {\footnotesize \NWlink{nuweb1c}{1c}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@Finish@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1a}{1a}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap4}\raggedright\small +\NWtarget{nuweb1c}{} $\langle\,${\itshape Inner \hbox{\slshape\sffamily Stuff\/} rennI}\nobreak\ {\footnotesize {1c}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@XX>>@\hbox{\slshape\sffamily Stuff\/}\verb@<<YY@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1b}{1b}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} + +{\small\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item $\langle\,$Inner \hbox{\slshape\sffamily Stuff\/} rennI\nobreak\ {\footnotesize \NWlink{nuweb1c}{1c}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb1b}{1b}.} +\item $\langle\,$Outer \hbox{\slshape\sffamily Arg1\/} and \hbox{\slshape\sffamily Arg2\/} retuO\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb1a}{1a}.} +\end{list}} + +\end{document} +EOF + +cat > test.expected.c <<"EOF" +Begin +/* Outer 'abc' and 'def' retuO */ +Start +/* Inner {xabcydefz} rennI */ +XX>>xabcydefz<<YY +Finish + +/* Outer 'cba' and 'fed' retuO */ +Start +/* Inner {xcbayfedz} rennI */ +XX>>xcbayfedz<<YY +Finish + +End +EOF + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +latex test + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.c test.c +if test $? -ne 0 ; then fail; fi + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0033a.sh b/test/00/t0033a.sh new file mode 100644 index 0000000..369c593 --- /dev/null +++ b/test/00/t0033a.sh @@ -0,0 +1,257 @@ +#!/bin/sh +# +# $RCSfile: t0033a.sh,v $-- Test test/00/t0032a.sh +# +# +# Test of Cross-reference environment +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of Cross-reference environment" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of Cross-reference environment" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test Cross-reference environment +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@o test.c -cc +@{Begin +Define abc cba +@<Outer @'abc@' and @'def@' retuO@> +@<Outer @'cba@' and @'fed@' retuO@> +End +@| abc cba @} + +@d Outer @'Arg1@' and @'Arg2@' retuO +@{Start +Define def fed +Use abc cba +@<Inner @{x@1y@2z@} rennI@> +Finish +@| def fed@} + +@d Inner @'Stuff@' rennI +@{XX>>@1<<YY@} + +@o test.c -cc +@{More stuff +@} + +@d Outer... +@{Added stuff to force fragment defined +cross-reference entry. +@} + +@m + +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb1a}{} \verb@"test.c"@\nobreak\ {\footnotesize {1a}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Begin@\\ +\mbox{}\verb@Define abc cba@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Outer \verb@abc@ and \verb@def@ retuO}\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}, \ldots\ }$\,\rangle$}\verb@@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Outer \verb@cba@ and \verb@fed@ retuO}\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}, \ldots\ }$\,\rangle$}\verb@@\\ +\mbox{}\verb@End@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtFileDefBy\ \NWlink{nuweb1a}{1a}\NWlink{nuweb1d}{d}. +\item \NWtxtIdentsDefed\nobreak\ \verb@abc@\nobreak\ \NWlink{nuweb1b}{1b}, \verb@cba@\nobreak\ \NWlink{nuweb1b}{1b}.\item \NWtxtIdentsUsed\nobreak\ \verb@def@\nobreak\ \NWlink{nuweb1b}{1b}, \verb@fed@\nobreak\ \NWlink{nuweb1b}{1b}. +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap2}\raggedright\small +\NWtarget{nuweb1b}{} $\langle\,${\itshape Outer \hbox{\slshape\sffamily Arg1\/} and \hbox{\slshape\sffamily Arg2\/} retuO}\nobreak\ {\footnotesize {1b}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Start@\\ +\mbox{}\verb@Define def fed@\\ +\mbox{}\verb@Use abc cba@\\ +\mbox{}\verb@@\hbox{$\langle\,${\itshape Inner \verb@xArg1yArg2z@ rennI}\nobreak\ {\footnotesize \NWlink{nuweb1c}{1c}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@Finish@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroDefBy\ \NWlink{nuweb1b}{1b}\NWlink{nuweb1e}{e}. +\item \NWtxtMacroRefIn\ \NWlink{nuweb1a}{1a}. +\item \NWtxtIdentsDefed\nobreak\ \verb@def@\nobreak\ \NWlink{nuweb1a}{1a}, \verb@fed@\nobreak\ \NWlink{nuweb1a}{1a}.\item \NWtxtIdentsUsed\nobreak\ \verb@abc@\nobreak\ \NWlink{nuweb1a}{1a}, \verb@cba@\nobreak\ \NWlink{nuweb1a}{1a}. +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap4}\raggedright\small +\NWtarget{nuweb1c}{} $\langle\,${\itshape Inner \hbox{\slshape\sffamily Stuff\/} rennI}\nobreak\ {\footnotesize {1c}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@XX>>@\hbox{\slshape\sffamily Stuff\/}\verb@<<YY@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1b}{1b}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap5}\raggedright\small +\NWtarget{nuweb1d}{} \verb@"test.c"@\nobreak\ {\footnotesize {1d}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@More stuff@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtFileDefBy\ \NWlink{nuweb1a}{1a}\NWlink{nuweb1d}{d}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap6}\raggedright\small +\NWtarget{nuweb1e}{} $\langle\,${\itshape Outer \hbox{\slshape\sffamily Arg1\/} and \hbox{\slshape\sffamily Arg2\/} retuO}\nobreak\ {\footnotesize {1e}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Added stuff to force fragment defined@\\ +\mbox{}\verb@cross-reference entry.@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroDefBy\ \NWlink{nuweb1b}{1b}\NWlink{nuweb1e}{e}. +\item \NWtxtMacroRefIn\ \NWlink{nuweb1a}{1a}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} + +{\small\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item $\langle\,$Inner \hbox{\slshape\sffamily Stuff\/} rennI\nobreak\ {\footnotesize \NWlink{nuweb1c}{1c}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb1b}{1b}.} +\item $\langle\,$Outer \hbox{\slshape\sffamily Arg1\/} and \hbox{\slshape\sffamily Arg2\/} retuO\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}\NWlink{nuweb1e}{e}}$\,\rangle$ {\footnotesize {\NWtxtRefIn} \NWlink{nuweb1a}{1a}.} +\end{list}} + +\end{document} +EOF + +cat > test.expected.c <<"EOF" +Begin +Define abc cba +/* Outer 'abc' and 'def' retuO 1b */ +Start +Define def fed +Use abc cba +/* Inner {xabcydefz} rennI 1c */ +XX>>xabcydefz<<YY +Finish +Added stuff to force fragment defined +cross-reference entry. + +/* Outer 'cba' and 'fed' retuO 1b */ +Start +Define def fed +Use abc cba +/* Inner {xcbayfedz} rennI 1c */ +XX>>xcbayfedz<<YY +Finish +Added stuff to force fragment defined +cross-reference entry. + +End +More stuff +EOF + +$bin/nuweb -x test.w +if test $? -ne 0 ; then fail; fi + +latex test + +$bin/nuweb -x test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.c test.c +if test $? -ne 0 ; then fail; fi + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0034a.sh b/test/00/t0034a.sh new file mode 100644 index 0000000..a35c8e8 --- /dev/null +++ b/test/00/t0034a.sh @@ -0,0 +1,195 @@ +#!/bin/sh +# +# $RCSfile: t0034a.sh,v $-- Test test/00/t0034a.sh +# +# +# Test of Listing package +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of Listing package" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of Listing package" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test Listing package +# + +cat > test.w <<"EOF" +\documentclass{article} +\usepackage{listings} +\begin{document} + +\lstset{extendedchars=true,keepspaces=true,language=C} + +@o test.c -cc +@{int +main(int argc, char ** argv) +{ + @<Body of main@> +} +@} + +@d Body... +@{int in; +unsigned char out[20]; + +while (scanf("%x", &in) == 1) +{ + @<Do one item@> +} +return 0;@} + +@d Do... +@{int n = mangle(in, out); + +for (int i = 0; i < n; i++) + printf("%02x", out[i]); +printf("\n");@} + +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\usepackage{listings} +\begin{document} + +\lstset{extendedchars=true,keepspaces=true,language=C} + +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb?}{} \verb@"test.c"@\nobreak\ {\footnotesize {?}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\lstinline@int@\\ +\mbox{}\lstinline@main(int argc, char ** argv)@\\ +\mbox{}\lstinline@{@\\ +\mbox{}\lstinline@ @\hbox{$\langle\,${\itshape Body of main}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\lstinline@@\\ +\mbox{}\lstinline@}@\\ +\mbox{}\lstinline@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap2}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Body of main}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\lstinline@int in;@\\ +\mbox{}\lstinline@unsigned char out[20];@\\ +\mbox{}\lstinline@@\\ +\mbox{}\lstinline@while (scanf("%x", &in) == 1)@\\ +\mbox{}\lstinline@{@\\ +\mbox{}\lstinline@ @\hbox{$\langle\,${\itshape Do one item}\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\lstinline@@\\ +\mbox{}\lstinline@}@\\ +\mbox{}\lstinline@return 0;@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap3}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Do one item}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\lstinline@int n = mangle(in, out);@\\ +\mbox{}\lstinline@@\\ +\mbox{}\lstinline@for (int i = 0; i < n; i++)@\\ +\mbox{}\lstinline@ printf("%02x", out[i]);@\\ +\mbox{}\lstinline@printf("\n");@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{document} +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb -l test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0035a.sh b/test/00/t0035a.sh new file mode 100644 index 0000000..5f550e4 --- /dev/null +++ b/test/00/t0035a.sh @@ -0,0 +1,150 @@ +#!/bin/sh +# +# $RCSfile: t0035a.sh,v $-- Test test/00/t0018a.sh +# +# +# Test of hyperlinks using -r +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of hyperlinks using -r" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of hyperlinks using -r" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test hyperlinks using -r +# + +cat > test.w <<"EOF" +\documentclass{article} +\usepackage[pdftex,colorlinks=true]{hyperref} +\begin{document} +@o test.c -cc +@{@<Use a fragment@> +@} +@d Use... +@{Here is a fragment. + Make sure it is referenced properly.@} +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{\hypertarget{#1}{#2}} +\newcommand{\NWlink}[2]{\hyperlink{#1}{#2}} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\usepackage[pdftex,colorlinks=true]{hyperref} +\begin{document} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb1a}{} \verb@"test.c"@\nobreak\ {\footnotesize {1a}}$\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@@\hbox{$\langle\,${\itshape Use a fragment}\nobreak\ {\footnotesize \NWlink{nuweb1b}{1b}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap2}\raggedright\small +\NWtarget{nuweb1b}{} $\langle\,${\itshape Use a fragment}\nobreak\ {\footnotesize {1b}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Here is a fragment.@\\ +\mbox{}\verb@ Make sure it is referenced properly.@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item \NWtxtMacroRefIn\ \NWlink{nuweb1a}{1a}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} +\end{document} +EOF + + +# [Add other files here. Avoid any extra processing such as +# decompression until after nuweb has run. If nuweb fails this script +# can save time by not decompressing. ] + +$bin/nuweb -r test.w +if test $? -ne 0 ; then fail; fi + +pdflatex test +if test $? -ne 0 ; then fail; fi + +$bin/nuweb -r test.w +if test $? -ne 0 ; then fail; fi + +pdflatex test +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0036a.sh b/test/00/t0036a.sh new file mode 100644 index 0000000..be10467 --- /dev/null +++ b/test/00/t0036a.sh @@ -0,0 +1,129 @@ +#!/bin/sh +# +# $RCSfile: t0036a.sh,v $-- Test test/00/t0036a.sh +# +# +# Test of Empty macro index +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of Empty macro index" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of Empty macro index" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test Empty macro index +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +Test text. +@d Fragment one +@{Stuff 1@} + +@s +No fragments here. +@m +@S +@m +\end{document} +EOF + +cat > test.expected.tex <<"EOF" +\newcommand{\NWtarget}[2]{#2} +\newcommand{\NWlink}[2]{#2} +\newcommand{\NWtxtMacroDefBy}{Fragment defined by} +\newcommand{\NWtxtMacroRefIn}{Fragment referenced in} +\newcommand{\NWtxtMacroNoRef}{Fragment never referenced} +\newcommand{\NWtxtDefBy}{Defined by} +\newcommand{\NWtxtRefIn}{Referenced in} +\newcommand{\NWtxtNoRef}{Not referenced} +\newcommand{\NWtxtFileDefBy}{File defined by} +\newcommand{\NWtxtIdentsUsed}{Uses:} +\newcommand{\NWtxtIdentsNotUsed}{Never used} +\newcommand{\NWtxtIdentsDefed}{Defines:} +\newcommand{\NWsep}{${\diamond}$} +\newcommand{\NWnotglobal}{(not defined globally)} +\newcommand{\NWuseHyperlinks}{} +\documentclass{article} +\begin{document} +Test text. +\begin{flushleft} \small +\begin{minipage}{\linewidth}\label{scrap1}\raggedright\small +\NWtarget{nuweb?}{} $\langle\,${\itshape Fragment one}\nobreak\ {\footnotesize {?}}$\,\rangle\equiv$ +\vspace{-1ex} +\begin{list}{}{} \item +\mbox{}\verb@Stuff 1@{\NWsep} +\end{list} +\vspace{-1.5ex} +\footnotesize +\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item {\NWtxtMacroNoRef}. + +\item{} +\end{list} +\end{minipage}\vspace{4ex} +\end{flushleft} + +No fragments here. +None. + + + +{\small\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} +\item $\langle\,$Fragment one\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$ {\footnotesize {\NWtxtNoRef}.} +\end{list}} +\end{document} +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.tex test.tex +if test $? -ne 0 ; then fail; fi + +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass diff --git a/test/00/t0037a.sh b/test/00/t0037a.sh new file mode 100644 index 0000000..0839128 --- /dev/null +++ b/test/00/t0037a.sh @@ -0,0 +1,119 @@ +#!/bin/sh +# +# $RCSfile: t0037a.sh,v $-- Test test/00/t0006a.sh +# +# +# Test of big definitions +# +work=${TMPDIR:-/tmp}/$$ +PAGER=cat +export PAGER +umask 022 +here=`pwd` +if test $? -ne 0 ; then exit 2; fi +SHELL=/bin/sh +export SHELL + +bin="$here/${1-.}" + +pass() +{ + set +x + cd $here + rm -rf $work + exit 0 +} +fail() +{ + set +x + echo "FAILED test of big definitions" 1>&2 + cd $here + rm -rf $work + exit 1 +} +no_result() +{ + set +x + echo "NO RESULT for test of big definitions" 1>&2 + cd $here + rm -rf $work + exit 2 +} +trap \"no_result\" 1 2 3 15 + +mkdir $work +if test $? -ne 0 ; then no_result; fi +cd $work +if test $? -ne 0 ; then no_result; fi + +# +# test big definitions +# + +cat > test.w <<"EOF" +\documentclass{article} +\begin{document} +@O test.c -cc +@{Call the macro + @<Fragment with @<A macro argument@> as parameter@> + @<Second frag with @<A macro argument@> as parameter@> + @<Third frag with @<A macro argument@> as parameter@> +@} + +@D Fragment with @'Begin macro@'... +@{@1<<<Here 'tis. +That argument was at the beginning of the fragment@} + +@D Second frag with @'Begin line@'... +@{Here is the beginning of the second macro +@1<<<That is the argument +And this is the end of the second frag@} + +@D Third frag with @'Embedded@'... +@{Here is the argument>>>@1<<<That was it.@} + +@D A macro argument +@{Hello folks@} +\end{document} +EOF + +cat > test.expected.c <<"EOF" +Call the macro + /* Fragment with <A macro argument> as parameter 1b */ + /* A macro argument 1e */ + Hello folks<<<Here 'tis. + That argument was at the beginning of the fragment + /* Second frag with <A macro argument> as parameter 1c */ + Here is the beginning of the second macro + /* A macro argument 1e */ + Hello folks<<<That is the argument + And this is the end of the second frag + /* Third frag with <A macro argument> as parameter 1d */ + Here is the argument>>>Hello folks<<<That was it. +EOF + +# [Add other files here. Avoid any extra processing such as +# decompression until after demo has run. If demo fails this script +# can save time by not decompressing. ] + +$bin/nuweb -x test.w +if test $? -ne 0 ; then fail; fi + +latex test + +$bin/nuweb -x test.w +if test $? -ne 0 ; then fail; fi + +diff -a --context test.expected.c test.c +if test $? -ne 0 ; then fail; fi + +# [Add other sub-tests that might be failed here. If they need files +# created above to be decompressed, decompress them here ; this saves +# time if demo fails or the text-based sub-test fails.] + +# +# Only definite negatives are possible. +# The functionality exercised by this test appears to work, +# no other guarantees are made. +# +pass