[net.sources] VMS version of ncode

talmage@excalibur.UUCP (Talmage) (01/20/87)

Here's a VMS version of good@pixar's ncode toy.  I bundled it with
Marvin Minow's (minow@decvax) archc program.  Cut along the dashed line
and use either MM's archx or your fave editor to unbundle it.

Enclosed is a bug report, source code, some sample input files (blame me for
abuse.ncode), the original man page and news headers.

I didn't change the man page to reflect the changes I've made and bugs I've
introduced.

David Talmage
UUCP:   seismo!cmbvax \                                                         
        ihnp4!--<      >!vu-vlsi!excalibur!talmage                              
        cbosgd!psuvax1/                                                         
                                                                                
Bitnet: TALMAGE@VILLVM, TALMAGE@VUVAXCOM
Arpa:   TALMAGE%villvm.bitnet@wiscvm.wisc.edu                                   

-------------------- Cut here ----------------------------------------------

-h- bugs	Tue Jan 20 11:02:55 1987	bugs

In <401.pixar.UUCP>, good@pixar gives us a nifty toy called "ncode".  I've 
recently hacked at it so it runs on VAXen under VMS 4.2.  We have version 2.2 
of the VAX/VMS C compiler.  I don't know if ncode.c will compile with any 
earlier versions.


There are some differences between the VMS version and the UNIX version.

As you may know, VMS is uses a record-oriented file system, rather than a 
stream-oriented one like UNIX.  If you look in init(), you'll see that
the UNIX code eats input files in one big gulp, while the VMS code takes
smaller bites.

Good@pixar sent me a change to allow you to put \'s in your output.  Just
preceed them with a |.  E.g.  printf("foo|\n"); in your input should come
out as printf("foo\n");

When I was testing this puppy, I wasn't sure it was reading the groups 
correctly, so I introduced another command-line option to help confirm or deny
my suspicions.  ncode -d codefile prints the groups and their contents before 
giving you the usual ncode output.

There are some bugs in my version.  I don't know if they exist in the original
version or not.

	1. It doesn't ignore blank lines.  They become part of a group.

	2. It treats multiple %'s as names of groups.  E.g.
			:
			:
		%
		#include ncode.sample2
		%
		CODE
			:
			:
		%
	   introduces a  group called "%" if the file ncode.sample2 ends in a %.

	3. The VAX/VMS linker spewls forth the following complaint.  I quote:
	  %LINK-W-MULPSC, conflicting attributes for psect DATA
		  in module SHELL$FIX_TIME file SYS$COMMON:[SYSLIB]VAXCRTL.OLB;1
	  %LINK-W-OVRALI, conflicting alignment on overlayed psect DATA
		  in module SHELL$FIX_TIME file SYS$COMMON:[SYSLIB]VAXCRTL.OLB;1

	   My system manager says it's DEC's fault, not mine.

-h- ncode.txt	Tue Jan 20 11:02:55 1987	ncode.txt
From good@pixar.UUCP (Pixar -- Out of our minds, into your hands.) Mon Dec 22 21:58:41 1986
Relay-Version: version B 2.10.2 9/5/84; site excalibur.UUCP
Path: excalibur!vu-vlsi!cbmvax!bpa!burdvax!sdcrdcf!hplabs!ucbvax!ucsfcgl!pixar!good
From: good@pixar.UUCP (Pixar -- Out of our minds, into your hands.)
Newsgroups: net.sources
Subject: ncode -- source, man page and sample input files
Message-ID: <401@pixar.UUCP>
Date: 23 Dec 86 02:58:41 GMT
Article-I.D.: pixar.401
Posted: Mon Dec 22 21:58:41 1986
Date-Received: 24 Dec 86 23:04:03 GMT
Reply-To: good@pixar.UUCP (Pixar -- Out of our minds, into your hands.)
Organization: Pixar -- Marin County, California
Lines: 900
Distribution: net
Xref: excalibur net.sources:16

Here it is: the new, improved ncode.c along with new, improved sample
files which help you appreciate all the wonderful features of the program.
To unwrap your kit, save it in a file called "ncode.shar".

To assemble your kit, delete everything in the file above (and including)
this "cut here" line, and delete everything below (and including) the
other "cut here" line near the bottom of the file.  Then give the command

	sh ncode.shar

and start by reading the README file.  Cheers.
------------------------------- cut here --------------------------------

------------------------------- cut here --------------------------------
(delete from here down)
---- 
		--Craig
		...{ucbvax,sun}!pixar!good

-h- ncode.c	Tue Jan 20 11:02:55 1987	ncode.c
/*
 *	ncode.c --  a random text constructor
 *	pixar!good
 *	based on a program by pixar!mark
 */

#include <stdio.h>
#include <sys/file.h>

#ifndef VMS		/* DWT 9 January, 1987 */
#include <sys/time.h>
#define OK_FINE	0	/* DWT */
#define UNWELL	1	/* DWT */
#endif

#include <sys/types.h>
#include <sys/stat.h>

#ifdef VMS
#define random	rand	/* DWT 9 January, 1987.  Won't run under VMS	*/
#define srandom	srand	/* without these changes.  The author says these*/
			/* are also needed under SYSV.			*/
#define rindex	strrchr	/* Also need this.				*/

#define OK_FINE	1	/* Termination with bit 1 set is normal for	*/
#define UNWELL	1	/* VMS.						*/

#include <timeb.h>
#endif

#define DATALUMP	8192	/* increment size of data[] by this as needed */
#define BIGBUF		4096	/* nice, roomy buffer for group name checks */

char **data;	/* array of pointers to elements in bucket */
int dindex;	/* number of elements in data */
int datasize;	/* how many elements would fit in data[] is right now */

char *malloc();
char *realloc();
char *rindex();
char *fgets();
long random();

struct gstruct {
	char *name;	/* points to name of a group in data[] */
	int count;	/* how many elements of data belong to this group */
	int index;	/* index of element of data where group starts */
};
struct gstruct *groups; /* where the group structs live, or is that obvious? */
int ngroups;		/* number of elements in groups */

main (ac,av)
int ac;
char *av[];
{
	char *prog;		/* name of this program */
	char *fname = 0;
	int loopcnt = 1;	/* times through main loop */
 	char *groupname = "CODE";
	int	debug = 0;	/* DWT- Defaults to			*/
				/* "Don't print the group tables."	*/

	prog = rindex(*av,'/');
	prog = ( prog == NULL ) ? *av : ++prog ;
	ac--;av++;
	while(ac && **av == '-'){
		if (strcmp(*av,"-n") == 0){
			ac--;av++;
			loopcnt = atoi(*av);
			if (loopcnt <= 0){
				fprintf(stderr,
					"%s: -n: need positive integer\n",prog);
				exit(UNWELL);
			}
			ac--;av++;
		} else if (strcmp(*av,"-g") == 0){
			ac--;av++;
			groupname = *av;	/* use instead of "CODE" */
			if (! groupname ){
				fprintf(stderr,
					"%s: -g: need group name\n",prog);
				exit(UNWELL);
			}
			ac--;av++;
		} else if (strcmp(*av,"-d") == 0){
			debug = 1;
			ac--;av++;
		} else {
			printf(
			"Usage %s [-n n ] [-g groupname] [-d] codefile\n",prog);
			exit(OK_FINE);
		}
	}
	if (!ac){
		fprintf(stderr,
			"Usage %s [-n n ] [-g groupname] [-d] codefile\n",prog);
		exit(UNWELL);
	}
	fname = *av;

	/*
	 *	Make some room to start, and increment by DATALUMP as needed
	 */
	datasize = DATALUMP;
	if ((data = (char **) malloc(datasize * sizeof(char *))) == NULL ){
		perror("main: could not malloc for data[]");
		exit(UNWELL);
	}
	dindex = 0;
	if( init(fname) != 0 ){	
		fprintf(stderr,"%s: init error\n",prog);
		exit(UNWELL);
	}
	/*
	 * This should be more than enough room for worst-case
	 */
	groups = (struct gstruct *) malloc(dindex * sizeof(struct gstruct));
	if (groups == NULL){
		perror("main: could not malloc for groups[]");
		exit(UNWELL);
	}
	if ( scan() != 0 ){
		fprintf(stderr,"%s: scan error\n",prog);
		exit(UNWELL);
	}

	if (debug)		/* DWT 9 January, 1987 */
	printgroups();

	srandom(a_random_number());	/* seed the number generator */
	while ( loopcnt ){
		expand(groupname,strlen(groupname));
		loopcnt--;
	}
	exit(OK_FINE);
}

init(fname)
char *fname;
{
	char *bucket;	/* big array where data lives */
	char *bptr;	/* points into bucket */
	int fd;
	struct stat sbuf;
	char *s, *t;
	int	n_read;	/* DWT How many bytes have we read from fname?	*/

#ifdef VMS
	int bytecount;	/* DWT Number of bytes read so far		*/
#endif

	fd = open(fname,O_RDONLY,0);
	if ( fd < 0 ) {
		perror(fname);
		return 1;
	}
	if ( fstat(fd,&sbuf) != 0 ){
		perror(fname);
		return 1;
	}
	if ((bucket = (char *) malloc( sbuf.st_size + 1)) == NULL ){
		perror("init(): malloc() trouble");
		return 1;
	}
	/*
	 *	Read entire file into bucket[]
	 */
#ifndef VMS
	if ((read(fd,bucket,sbuf.st_size)) != sbuf.st_size){
		perror("init: read error");
		return 1;
	}
	n_read = sbuf.st_size;
#else
	/* DWT- gots to do this for VMS.  Most files under VMS aren't stream */
	/* as read and its relatives expect, so for each call to read we get */
	/* however many characters up to the next end of record marker.  This*/
	/* little loop lets us read the entire file into the buffer in some  */
	/* number of passes.						     */

	n_read = 0;
	bytecount = 0;
	while ( (n_read = read(fd, bucket+bytecount, sbuf.st_size ) ) != 0 )
		bytecount = bytecount + n_read;
	n_read = bytecount;
#endif
	close(fd);
	/*
	 * Make first pass through memory, pointing data[] the right way
	 * and recursing as needed on #include files.
	 */
	bptr = bucket;
/*	while ( *bptr && (bptr <= bucket + sbuf.st_size) ){ */

/* DWT */
	while ( *bptr && (bptr <= bucket + n_read) ){
		s = bptr; 
		while ( *s != '\0' ){
			if(*s == '\n' )
				*s = '\0';	/* nuke newline */
			else
				s++;
		}
		if( strncmp(bptr, "#include", 8) == 0 ){
			for(t = bptr + 8; *t!='\0' && (*t==' '||*t=='\t');t++)
				;	/* skipping white space */
			if (init(t) != 0){	/* RECURSES HERE */
				return 1;
			}
			bptr = t +strlen(t) + 1; /* skip the #include line */
			continue;	/* back to the top of the while loop */
		}
		/*
		 *	Make sure data[] is still big enough
		 */
		if ( dindex >= datasize){
			datasize += DATALUMP;
			if((data=(char **) realloc(data,
					datasize*sizeof(char *)))==NULL){
				perror("init: could not realloc for data[]");
				return(1);
			}
		}
		data[dindex] = bptr;	/* point it at the data */
		bptr = s + 1;	/* move bptr to the next location to fill */
		dindex++;
	}
	return 0;
}

/*
 *	Scan data[] marking and counting groups
 */
scan()
{
	register i, gcnt, gindex;

	/*
	 * special case: first line always a group name 
	 */
	groups[0].name = data[0];
	groups[0].index = 0;
	ngroups = 1;
	i = 1;
	gindex = 0;
	gcnt = 0;
	while ( i < dindex ){
		if ( data[i][0] == '%' ){
			groups[gindex].count = gcnt;
			gcnt = 0;		/* close out prev group */
			ngroups++;
			i++;			/* start next group */
			/*
			 *	If a #included file has any blank lines after
			 *	the last '%' then the group name would wind
			 *	up being '\0'.  So the first group name after
			 *	the #include won't be marked as a group name
			 *	and will thus never be expanded.  We could
			 *	cluck our tongues at the user and say he has
			 *	a bogus file and thus deserves what he gets.
			 *	But hopefully this check will just make the
			 *	program more robust.
			 */
			while ((i < dindex) && (data[i][0] == '\0')){
					i++;
			}
			gindex++;
			groups[gindex].name = data[i];
			groups[gindex].index = i;
		}else{
			gcnt++;
		}
		i++;
	}
	ngroups--;	/* The last % in the file doesn't start a new group */
	return 0;
}

/*
 *	This is where we finally do the deed.  If a string is a group name
 *	then expand() will randomly select a member of that group to
 *	replace it.  Through the miracle of recursion, a whole sentence
 *	may be passed to expand() and each word (anything bounded by what
 *	we call "white space" gets expanded.  Anything that cannot be
 *	expanded gets printed out.
 */
expand(s,lim)
char s[];
int lim;
{
	register i, j, k, done, n, r;

	i = j = 0;
	while ( s[i] != 0 && i < lim ){
		done = 0;
		while ( ! done && j <= lim ){
			if ( isawhite(s[j]) ){
				/* chase down remaining white space */
				for (k=j; k<=lim && s[k] && isawhite(s[k]);k++){
					;
				}
				n = isagroup(&s[i], j-i);
				if ( n >= 0 ){
					r = (groups[n].index + 1
						+ rnd(groups[n].count));
					expand( data[r], strlen(data[r]));
					outstring(&s[j], k-j);
				} else {
					outstring(&s[i], k-i);
				}
				done++;
				i = j = k; /* should be on next word, if any */
			}
			j++;
		}
	}


}

/*
 *	Return index into groups[] array if a group name, -1 if just a word.
 *	We have to use gbuf, a seperate place, so that we can null-terminate
 *	the string where we want.  Otherwise it wouldn't know santa from
 *	santana.
 */
isagroup(s,lim)
char s[];
int lim;
{
	register i;
	static char gbuf[BIGBUF];

	strncpy(gbuf,s,lim);
	gbuf[lim] = '\0';	/* strncpy might not do this */
	for(i=0; i<ngroups; i++ ){
		if (groups[i].name && strcmp(gbuf,groups[i].name) == 0){
			return i;	/* hit */
		}
	}
	return -1;	/* fail */
}

/*
 * 	Output string, handling splices
 */
outstring(s,lim)
char s[];
int lim;
{
	register i = 0;

	while ( s[i] != '\0' && i < lim ){
		switch (s[i]){
/*		case '|':
				break;	/* splice: no output */

/*
   DWT-
   pixar!good told me about this little change.  If you preceed a \ with
   a |, you can make legal C statements part of your output.  E.g.

	printf("foo|\n");

   in an input file should translate to

	printf("foo\n");

   in the output.

*/

		case '|':
				if ( s[i+1] == '\\' ){
					putchar('\\');	/* special case:     */
					i++;		/* |\ outputs a \    */
					break;	
				}
				break;	/* splice: no output */

		case '\\':
				putchar('\n');
				break;
		default:
				putchar(s[i]);
				break;
		}
		i++;
	}
}

/*
 *     Return random number 0 to limit
 */
rnd(limit)
int limit;
{
	if (limit > 0){
		return (random() % limit);
	}
	return 0;	/* better than a floating exception if lim == 0 */
}

a_random_number()
{
#ifndef VMS
	struct timeval tp;
	struct timezone tzp;

	gettimeofday (&tp, &tzp);

	return((getpid() ^ tp.tv_usec) % 123456);
#else
	/* DWT- VMS is not quite but almost entirely different... */
	struct	timeb	tp;
	ftime( &tp );
	return((getpid() ^ tp.millitm) % 123456);
#endif
}

/*
 *	Return 1 if one of our "white" characters.  A white character is
 *	any character which can bound a group name, so punctuation marks
 *	are included.
 */
isawhite(c)
char c;
{
	if (	c == '\0' ||		/* traditional white space */
		c == ' '  ||
		c == '\t' ||
		c == '|'  ||		/* "splice" character */
		c == '\\' ||		/* becomes a newline */
		c == '.'  ||		/* common punctuation */
		c == '-'  ||
		c == ':'  ||
		c == ';'  ||
		c == ','  ||
		c == '!'  ||
		c == '?'  ||
		c == '['  ||
		c == ']'  ||
		c == '{'  ||
		c == '}'  ||
		c == '('  ||
		c == ')'  ||
		c == '\'' ||
		c == '\"' ||
		c == '`'
	)
		return 1;
	return 0;
}

printgroups()
{
/* DWT- Use the "-d" command line option to make ncode print out a list of */
/* the groups and their elements					   */

	int gindex, thing;

	for ( gindex = 0; gindex < ngroups; gindex++ )
	{
		printf( "Group %s has %d elements\n",
			groups[gindex].name, groups[gindex].count );

		for ( thing = groups[gindex].index;
		      thing<= groups[gindex].index + groups[gindex].count;
		      thing++ )
			printf( "%d\t%s\n", thing, data[thing] );

		printf( "\n\n" );
	}
}
-h- ncode.man	Tue Jan 20 11:02:55 1987	ncode.man



NCODE(1)            UNIX Programmer's Manual             NCODE(1)



NAME
     ncode  - stochastic text construction

SYNOPSIS
     ncode [-n number] [-g groupname] [-d] codefile

DESCRIPTION
     _N_c_o_d_e reads in a file of a certain format and randomly con-
     structs text based on the organization of the file.  Other
     files may be recursively included by putting

     #include pathname

     on any line of the file.  This is useful when you want to
     use a file of basic definitions, or groups, in different
     configurations.

     The -n flag is used to run the program through the main loop
     multiple times.

     A "group" name is defined as the word on the first line of
     the file and, more commonly, the word on each line following
     a line starting with "%".  The members of a group are all
     lines between the group name and the next "%".  When a group
     name is encountered, surrounded by any of a set of charac-
     ters called "white space" in this context, it is randomly
     expanded into one of its members.  Group names are not
     allowed to contain any white space, to prevent terminal con-
     fusion on the part of the program.

     The -g flag allows you to start the expanding process on a
     group name other than the default, which is "CODE".  The
     argument may be a group name, or an entire string including
     group names, just as if it were a line in the file.  It is
     legal to start on any group in the file, and groups may be
     referenced before or after the place in the file where they
     are defined.  In the case of duplicate group definitions,
     the first one occurring is the only one used.

     For example, here is a sample group definition:

          NOUN
          lamp
          house
          car
          %

     The line "See the NOUN." could be randomly expanded to say
     "See the lamp."

     The characters considered "white" for the purpose of bound-
     ing a group name, besides what is normally considered white



Printed 12/29/86              Pixar                             1






NCODE(1)            UNIX Programmer's Manual             NCODE(1)



     space, are currently:

          | \ .  - : ; , ! ? [ ] { } () ' " `

     Two of those characters have special meanings to _n_c_o_d_e. The
     "|" symbol allows you to "splice" things to a group name.
     When it is encountered, no character is printed on output.
     The "\" causes a newline to be printed on output.

     The simplest application would be for a "fortune" program,
     but _n_c_o_d_e could also be used for more complex things such as
     a rumor generating file.  The group definitions will be left
     as an exercise for the reader, but the following example
     should prove illuminating:

     CODE
     It was rumored today that COMPANY will be bought by COMPANY for PRICE\.
     PERSON, POSITION of COMPANY, said that PRODUCT will be announced DATE\.

     Note that every string to be expanded must be on only one
     line of the file.  The program now dynamically allocates
     memory in a very general way, so the total size of your
     input files and the length of the lines in the files is lim-
     ited only by how much memory you can get.  The only hard
     limit is that a group name can't be over 4096 characters
     long.  If you can't come up with a unique group name in
     fewer characters then don't blame me.

BUGS
     No bugs.  Only features that you haven't figured out how to
     use yet.  A recent improvement makes it tolerant of blank
     lines following the last % in a #include file.

DIAGNOSTICS
     Standard perror() stuff.  Pretty self explanatory.  A bogus
     input file might benignly yield cryptic results.

AUTHOR
     Craig Good
















Printed 12/29/86              Pixar                             2



-h- ncode.sample1	Tue Jan 20 11:02:55 1987	ncode.sample1
NOUN
North
South
East
West
Truth
grass
desk
wall
window
ceiling
floor
car
sign
%
NUMBER
one
two
two
3.1415927
three
eleven
a googol
%
VERB
meet
knock
kiss
hug
trot
miss
nod
wink
hit
walk
fly
zip
smash
sniff
%
FLOWERS
Roses
Violets
Chrysanthemums
Daisies
Gardenias
Stinkweeds
Petunias
%
COLOR
puce
invisible
red
tan
white
blue
green
muave
purple
chartreuse
black
yellow
%
SOMETHING
I am
Sugar is
Radiation is
Computing is
Nitrous Oxide is
ANIMALS are
AUTHOR_ANY is
You are
%
PROPERTY
fearful
liberal
conservative
sexy
schizophrenic
sweet
bitter
stupid
ugly
hilarious
slow
miserable
%
ISYOU
are you.
is this.
am I.
is Maple Surple.
is it.
it is.
are they.
-...who cares?
%
HAND
mouth
hand
hand
eye
eye
nose
ear
tooth
foot
%
AUTHOR_A
Craig Good
Michael Jackson
Wally
Beaver
Spock
Gidget
Bambi
Dracula
Superman
Kahn
Bullwinkle
Bo Derek
Koo Stark
Lady Diana
Steve Jobs
Roy Rogers
Bugs Bunny
James Bond
Godzilla
Kilroy
The Emperor
Sweeny Todd
Kate Bush
%
AUTHOR_AN
Anonymous
Andre
Oliver North
Ed Catmull
%
AUTHOR_ANY
AUTHOR_AN
AUTHOR_A
AUTHOR_A
FOX
FOX
FOX
%
ANIMAL_A
Bird
Snail
Panda
Fishy
Doggy
Puppy
Tiger
Kitty
Worm
Kangaroo
Wart Hog
Penguin
Polar Bear
Parakeet
Cat
Mountain Goat
Moose
Mouse
%
ANIMAL_AN
Egret
Aardvark
Emu
Elephant
%
ANIMAL_ANY
ANIMAL_AN
ANIMAL_A
ANIMAL_A
ANIMAL_A
%
ANIMALS
Birds
Snails
Pandas
Fish
Dogs
Puppies
Tigers
Kittens
Aardvarks
Worms
Kangaroos
Wart Hogs
Penguins
Polar Bears
Parakeets
Cats
Mountain Goats
Mooses
Mice
%
ROYALTY
Prince
King
Boss
Programmer
Hacker
Salesman
Head Hunter
%
MITS
knickers
arm bands
mittens
sunglasses
cowboy boots
galoshes
%
HURT
hurt
hurt
kill
slap
deoderize
break
zap
vaporize
irradiate
bother
%
STICKS
Sticks
Stones
Bullets
Bombs
Croissants
Keyboards
%
FOREST
ball park
forest
swamp land
jungle
ghetto
drug store
office
%
PLACE
garage
oven
bush
bush
FOREST
%
TREE
a tree
FOX's knee
FOX's knee
FOX's knee
FOX's knee
%
PROVERB
NOUN is NOUN, and NOUN is NOUN,\and never the twain shall meet.\
NOUN is NOUN, and NOUN is NOUN,\and never the twain shall VERB.\
NOUN is NOUN, and NOUN is NOUN,\and never the twain shall VERB.\
NOUN is NOUN, and NOUN is NOUN,\and never the ANIMAL_ANY shall VERB.\
NOUN is NOUN, and NOUN is NOUN,\and never the ANIMAL_ANY shall VERB.\
NOUN is NOUN, and NOUN is NOUN,\and never the ANIMAL_ANY shall VERB.\
A ANIMAL_A is as good as a FOREST to AUTHOR_ANY.\
A ANIMAL_A is as good as a FOREST to AUTHOR_ANY.\
An ANIMAL_AN is as good as a FOREST to AUTHOR_ANY.\
A HURT is as good as a VERB to a ANIMAL_A.\
A HURT is as good as a VERB to an ANIMAL_AN.\
A HURT is as good as a VERB to a ANIMAL_A.\
A HURT is as good as a VERB to an ANIMAL_AN.\
A VERB is as good as a HURT to AUTHOR_ANY.\
A VERB is as good as a HURT to AUTHOR_ANY.\
FLOWERS and MITS\May HURT my bones,\But AUTHOR_ANY will never VERB me.\
STICKS and ANIMALS\May HURT my bones,\But FLOWERS will never HURT me.\
FLOWERS and STICKS\May HURT my bones,\But MITS will never HURT me.\
STICKS and STICKS\May HURT my bones,\But ANIMALS will never VERB me.\
Never VERB today what you can HURT tomorrow.
Never VERB today what you can HURT tomorrow.
Never HURT today what you can VERB tomorrow.
A ANIMAL_A in the HAND is worth NUMBER in the PLACE.
An ANIMAL_AN in the HAND is worth NUMBER in the PLACE.
A ANIMAL_A in the HAND is worth NUMBER in the PLACE.
An ANIMAL_AN in the HAND is worth NUMBER in the PLACE.
A AUTHOR_A in the HAND is worth NUMBER in the PLACE.
An AUTHOR_AN in the HAND is worth NUMBER in the PLACE.
Never look a gift ANIMAL_ANY in the mouth.
Dead ANIMALS aren't much fun.
%
VERSE
ANIMAL_ANY, ANIMAL_ANY, burning bright\In the FOREST of the night\What immortal HAND or HAND\Dare frame thy PROPERTY symmetry?\
FLOWERS are COLOR,\FLOWERS are COLOR,\SOMETHING PROPERTY,\And so ISYOU\
Hark!  Hark!\The ANIMALS do bark!\The ROYALTY is fond of ANIMALS\He likes to take their insides out\And wear them as his MITS.\
I think that I shall never see\A thing as lovely\As TREE.\
%
TITLE
		"Why AUTHOR_ANY tried to HURT the ANIMAL_ANY"
		"The day AUTHOR_ANY wanted to HURT the ANIMAL_ANY"
			"ANIMALS"
			"FLOWERS"
		"The PROPERTY ANIMAL_ANY"
		"The PROPERTY FLOWERS"
		"Ode to AUTHOR_ANY"
		"I'm so COLOR without my ANIMAL_ANY"
		"Ode to the ANIMAL_ANY"
		"I'm dreaming of a COLOR Christmas"
		"I Love The FLOWERS"
			"Dead ANIMALS"
%
CODE
\PROVERB\\			--AUTHOR_ANY\
\PROVERB\\			--AUTHOR_ANY\
\VERSE\\			--AUTHOR_ANY\
\VERSE\\			--AUTHOR_ANY\
\TITLE\\VERSE\\			--AUTHOR_ANY\
%
#include ncode.sample2

-h- ncode.sample2	Tue Jan 20 11:02:55 1987	ncode.sample2
FOX
Appollonia
April Wayne
Barbara Hershey
Bo Derek
Brooke Adams
Carly Simon
Carol Alt
Catherine Mary Stewart
Cheryl Tiegs
Christie Brinkley
Coco Mitchell
Cybill Shepherd
Darryl Hannah
Erin Grey
Farrah Fawcett Majors
Heather Thomas
Jaclyn Smith
Jamie Lee Curtis
Jane Seymour
Janet Jones
Jennifer Beales
Jenny Seagrove
Johann Carlo
Kate Capshaw
Kate Jackson
Kathy Ireland
Kelly Emberg
Kelly LeBrock
Kim Basinger
Lauren Hutton
Lea Thompson
Lisa Bonet
Lisa Hartman
Markie Post
Marlee Matlin
Melanie Griffith
Michelle Pfieffer
Nastasia Kinski
Ola Ray
Olivia Newton John
Pamela Sue Martin
Paulina Porizkova
Rachel Ward
Rosanna Arquette
Sheila E
Shelly Hack
Signey Coleman
Stevie Nicks
Tahnee Welch
Tanya Roberts
Victoria Principal
Vivian Ruiz
Whitney Houston
%
-h- abuse.ncode	Tue Jan 20 11:02:55 1987	abuse.ncode
NOUN
house coat
badger
piece of lizt wire
calliope
patch of crab grass
desktop copier
troglodyte
sot
puff of lint
gasbag
cartoon
love doll
clump of okapi dung
trash bag
buffoon
dingo's kidney
ANIMAL_ANY
%
ADJECTIVE
COLOR
PROPERTY
%
PROPERTY
infectious
soft shelled
overbearing
festering
balloon-eared
smug
fetid
watery
fearful
inflatable
slimy
silly
liberal
conservative
thick headed
androgynous
ambiguous
sexy
schizophrenic
sweet
vacuous
bitter
stupid
insufferable
ugly
hilarious
slow
intimidated
sticky
miserable
%
ADVERB
bloody
disgustingly
lecherously
mind-bogglingly
incredibly
festeringly
insufferably
%
NUMBER
one
two
two
3.1415927
three
eleven
a googol
%
VERB
meet
knock
kiss
hug
trot
miss
nod
wink
hit
walk
fly
zip
smash
sniff
%
FLOWERS
roses
violets
chrysanthemums
daisies
gardenias
stinkweeds
petunias
%
COLOR
puce
invisible
red
tan
white
blue
green
muave
purple
chartreuse
black
yellow
%
HAND
mouth
hand
hand
eye
eye
nose
ear
tooth
foot
%
AUTHOR_A
Craig Good
Michael Jackson
Wally
Beaver
Spock
Gidget
Bambi
Dracula
Superman
Kahn
Bullwinkle
Bo Derek
Koo Stark
Lady Diana
Steve Jobs
Roy Rogers
Bugs Bunny
James Bond
Godzilla
Kilroy
The Emperor
Sweeny Todd
Kate Bush
%
ANIMAL_A
bird
snail
panda
fishy
doggy
puppy
tiger
kitty
worm
kangaroo
wart hog
penguin
polar bear
parakeet
cat
mountain goat
moose
mouse
%
ANIMAL_AN
egret
aardvark
emu
elephant
%
ANIMAL_ANY
ANIMAL_AN
ANIMAL_A
ANIMAL_A
ANIMAL_A
%
ANIMALS
birds
snails
pandas
fish
dogs
puppies
tigers
kittens
aardvarks
worms
snuggle bunnies
kangaroos
wart hogs
penguins
polar bears
parakeets
cats
mountain goats
mooses
mice
%
ROYALTY
prince
king
boss
programmer
hacker
salesman
head hunter
%
MITS
knickers
arm bands
mittens
sunglasses
cowboy boots
galoshes
%
HURT
hurt
hurt
kill
slap
deoderize
break
zap
vaporize
irradiate
bother
%
GERUND
hurting
hurting
killing
beating
slapping
deoderizing
breaking
zapping
vaporizing
irradiating
bothering
%
STICKS
sticks
stones
bullets
bombs
croissants
keyboards
%
FOREST
ball park
forest
swamp land
jungle
ghetto
drug store
office
%
PLACE
garage
oven
bush
bush
FOREST
%
WIFE
wife
ROYALTY
daughter
aged aunty
MITS
grandmother
mother
ANIMAL_ANY
father
son
uncle
%
BODILY_PARTS
ANIMALS
MITS
arm pits
bottoms
ear lobes
toe nails
shoulder blades
medulla oblongata
%
ACTION_DOER
biter
wiper
eater
painter
butcher
baker
purloiner
purveyer
sniffer
ogler
%
TIME_THING
lately
today
all the time
whenever you're on the computer
in small groups
in a crowd
when you're alone
in the sack
in the clutch
when we're together
%
ABUSE
How come you're so ADVERB PROPERTY TIME_THING?\\
You ADJECTIVE NOUN\\
You ACTION_DOER of other people's BODILY_PARTS\\
You ADJECTIVE, ADJECTIVE NOUN\\
When did you stop GERUND your WIFE?\\
You NOUN\\
%
CODE
ABUSE
%