commit 6ba17b6389bbe60d3bb74654a6889117abc83236 Author: Matthew Gretton-Dann Date: Fri Mar 15 08:04:56 2024 +0000 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 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