#!/usr/bin/perl
binmode STDOUT;
#=============================================================================
# UNGEEK -- Parser for Geek Code, Version 3.1  
# Pete Williams <petew@lexis-nexis.com>
#
# Usage: ungeek [-h] [-m] [-n] [-r] [-t] [-x] [filenames]
# Use "ungeek -h" for a quick help summary or RTFMpage for details
#
#=============================================================================

#=============================================================================
# Global Variables

$Debug = 0;
$NULL = '';
$Varystring = "But that varies...";
$Paidstring = "Getting paid for it!";
$Stupidstring = "?  I don't even know what that is...";
$Wannabestring = "  But someday I'd like to say:  \"";
$Rangefrom = "My tendencies on this issue range from:  \"";
$Rangeto = "\", to:  \"";
$ExtraNegate = "But if I did participate in this category, I would characterize myself as follows:";
$TokensToMatch = $DefTokensToMatch = 5;
$Linelth = 78;
$Cols = 74;
$PrintedFrom = 0;
$GCBegin = "-----BEGIN GEEK CODE BLOCK-----";
$GCVersion = "Version: 3.1";
$GCEnd = "------END GEEK CODE BLOCK------";
$Validsuffixes = '$?@';   # Special suffix codes

#=============================================================================
# MAIN

&ParseArgs;

if ($TestPatt) {
	&ParsePatt($TestPatt);
} else {
	if (@infiles) {
		foreach $infile (@infiles) {
			open(IF,$infile) || die "Can't open $infile: $!";
			open(STDIN,"<&IF") || die "Can't dup STDIN: $!";
			$RelaxFlag ? &TestForAll : &TestForGeek;
			close IF;
		}
	} else {
		$RelaxFlag ? &TestForAll : &TestForGeek;
	}
}

#=============================================================================
# ParseArgs

sub ParseArgs {
	local($_,$infile);

	while ($_ = shift(@ARGV)) {
		/^-h/ && &DisplayHelp;
		/^-t/ && ($TestPatt = shift(@ARGV)) && next;
		/^-x/ && ++$ExtractFlag && next;
		/^-m/ && ++$FromFlag && next;
		/^-r/ && ++$RelaxFlag && next;
		/^-n/ && ($TokensToMatch = shift(@ARGV)) && next;
		(-f $_) ? push(@infiles,$_) : &DisplayHelp;
	}
}

#=============================================================================
# ParsePatt

sub ParsePatt {
	local($_) = shift;

	@line = split(/\s+/);
	foreach $Token (@line) {
		if ($Token =~ /^G/) {
			if (&ExtractGeekTypes || &TestToken) {
				$printtoken = $Token;	
				write;
			} else {
				print "Unparseable token: [$Token]\n";
			}
		} elsif (&TestToken) {
			$printtoken = $Token;
			write;
		} else {
			print "Unparseable token: [$Token]\n";
		}
	}
}

#=============================================================================
# TestForAll

sub TestForAll {
	local($ingeek,@tokens,@headers,@outstrings,$header,$token,$outstring);
	while (<STDIN>) {
		s/^\s+//;
		@line = split(/\s+/);
		if (/^From:\s+(.*)$/) { push(@from,$1); }
		while ($Token = shift @line) { 
			if ($Token =~ /^G/) {
				if (&ExtractGeekTypes) {
					&SuccessCode;
				} elsif (&TestToken) {
					&SuccessCode;
				} else {
					&FailCode;
				}	
			} elsif (&TestToken) {
				&SuccessCode;
			} else {
				&FailCode;
			}
		}
	}
}

#=============================================================================
# TestForGeek

sub TestForGeek {
	local($ingeek,@tokens,@headers,@outstrings,$header,$token,$outstring);
	local($success);

	while (<STDIN>) {
		s/^\s+//;
		@line = split(/\s+/);
		if (/^From:\s+(.*)$/) { push(@from,$1); }
		if ($ingeek) {
			while ($Token = shift @line) {
				&TestToken ? &SuccessCode : do {&FailCode; last};
			}
		} else {
			while ($Token = shift @line) { 
				if ($Token =~ /^G/) { # Might be the start of the geek code (type)
					if ($success = &ExtractGeekTypes) {
						&SuccessCode;
						CHANCE: { while ($success && @line) {
							while ($Token = shift(@line)) {
								$success = &TestToken;
								$success ? &SuccessCode 
								: do { &FailCode; last CHANCE };
							}
						} } # CHANCE
					}
				}
			}
		}
	}
	&FailCode if @tokens;
}

#=============================================================================
# TestToken

sub TestToken {
	local($valid_ids) = "PGP|PE|PS|DI|tv|[C-EGK-PRUV-Yabdehor-tw-z5]";
	local($valid_pre) = "!";

	if ($Token =~ /^([$valid_pre])?($valid_ids)(.*)$/) {
		($Negate,$CodeId,$RestToken) = ($1,$2,$3);
		&ProcessGeekToken($RestToken);
	} else {
		$NULL;
	}
}

#=============================================================================
# SuccessCode

sub SuccessCode {
	$ingeek++;
	push(@tokens,$Token);
	push(@headers,$header);
	push(@outstrings,$outstring);
	$outstring = $header = $Token = '';
}

#=============================================================================
# FailCode

sub FailCode {
	if ($TestPatt) {
		&PrintOutGeek;
	} elsif ($ingeek > $TokensToMatch) {
		if ($ExtractFlag) {
			&PrintOutCode;
		} else {
			&PrintOutAll;
		}
	} elsif ($RelaxFlag) {
		if ($TokensToMatch != $DefTokensToMatch) {
			if ($ingeek >= $TokensToMatch) {
				if ($ExtractFlag) {
					&PrintOutCode;
				} else {
					&PrintOutAll;
				}
			}
		} else {
				if ($ExtractFlag) {
					&PrintOutCode;
				} else {
					&PrintOutAll;
				}
		}
	} else {
		; # Do nothing
	}
	$ingeek = $PrintedFrom = $success = $outstring = '';
	@tokens = @headers = @outstrings = @from = ();
}

#=============================================================================
# ProcessGeekCode

sub ProcessGeekToken {
	local($RestToken) = @_;
	$_ = $CodeId;
	/^PGP$/ && &ExtractPGP;
	/^DI$/  && &ExtractDilbert;
	/^PE$/  && &ExtractPolEcon;
	/^PS$/  && &ExtractPolSoc;
	/^tv$/  && &ExtractTV;
	/^5$/   && &ExtractBabylon5;
	/^a$/   && &ExtractAge;
	/^b$/   && &ExtractBooks;
	/^C$/   && &ExtractComputer;
	/^Y$/   && &ExtractCypher;
	/^D$/   && &ExtractDoom;
	/^d$/   && &ExtractDress;
	/^o$/   && &ExtractUsenetOracle;
	/^e$/   && &ExtractEducation;
	/^E$/   && &ExtractEmacs;
	/^G$/   && &ExtractGeek;
	/^h$/   && &ExtractHouse;
	/^K$/   && &ExtractKibo;
	/^L$/   && &ExtractLinux;
	/^M$/   && &ExtractMac;
	/^w$/   && &ExtractMicroSloth;
	/^O$/   && &ExtractOS2;
	/^P$/   && &ExtractPerl;
	/^r$/   && &ExtractRelationships;
	/^R$/   && &ExtractRoleplay;
	/^x$/   && &ExtractSexFemale;
	/^y$/   && &ExtractSexMale;
	/^z$/   && &ExtractSexNeuter;
	/^s$/   && &ExtractShape;
	/^t$/   && &ExtractStarTrek;
	/^U$/   && return(&ExtractUnix);
	/^N$/   && &ExtractUsenet;
	/^V$/   && &ExtractVMS;
	/^W$/   && &ExtractWWW;
	/^X$/   && &ExtractXfiles;

	&ProcessWholeToken;
}

#=============================================================================
# SplitWannabes

sub SplitWannabes {
	local($maintoken,@wannabes,$newstring,$suffices,$suffstring,$wannaflag,
		$butif);

	if ($Negate) {
		$outstring = &BuildNegateString;
		unless ($RestToken) {
			return $outstring;
		} elsif ($RestToken =~ /^([$Validsuffixes]+)$/) {
			$suffices = $1;
			if ($suffices) {
				$suffstring = &ExtractSuffices;
				return $NULL unless $suffstring;
				$outstring .= "  ${butif}$suffstring";
			}
			return $outstring; 
		}
	}
        
    ($maintoken,@wannabes) = split(/\>/,$RestToken);
	$newstring = &SplitToken($maintoken);
	return $NULL unless $newstring;
    $outstring .= $outstring ? join('  ','',"${butif}$newstring") : $newstring;

	if ($RestToken =~ /\>/) {
		if (@wannabes) {
			foreach $wannabe (@wannabes) {
				$wannaflag++;
				$newstring = &SplitToken($wannabe);
				return $NULL unless $newstring;
				$outstring .= join('',$Wannabestring,$newstring,"\"");
			}
		} else {
			$wannaflag++;
			$newstring = &SplitToken($wannabe);
			return $NULL unless $newstring;
			$outstring .= join('',$Wannabestring,$newstring,"\"");
		}
	}
	if ($Negate && $butif) { $outstring .= "\""; }
    $outstring;
}

#=============================================================================
# SplitToken

sub SplitToken {
	local($token) = shift;
	local($fromstring,$tostring,$parenstring,$outstring,$suffices,$suffstring,
		$valstring);

	# String like "()++", "(+)++", "(+)++$?"
	if ($token =~ s/^\(([^)]*)\)($validvals)([$Validsuffixes]*)//) {
		($parenstring,$valstring,$suffices) = ($1,$2,$3);
		$fromstring = &SplitVals($parenstring);
		$tostring = &SplitVals($valstring);
		if ($suffices) {
			$suffstring = &ExtractSuffices;
			return $NULL unless $suffstring;
			$outstring = join('',$Rangefrom,$fromstring,$Rangeto,$tostring,"\"",'  ',$suffstring);
		} else {
			$outstring = join('',$Rangefrom,$fromstring,$Rangeto,$tostring,"\"");
		}

	# String like "()", "(+)", "()$?", "(+)$?"
	} elsif ($token =~ s/^\(([^)]*)\)([$Validsuffixes]*)$//) {
		($parenstring,$suffices) = ($1,$2);
		return $NULL unless ($fromstring = $IDS{''});
		$tostring = &SplitVals($parenstring);
		if ($suffices) {
			$suffstring = &ExtractSuffices;
			return $NULL unless $suffstring;
			$outstring = join('',$Rangefrom,$fromstring,$Rangeto,$tostring,"\"",'  ',$suffstring);
		} else {
			$outstring = join('',$Rangefrom,$fromstring,$Rangeto,$tostring,"\"");
		}

	# String like "+()", "+(++)", "+()$?", "+()"
	} elsif ($token =~ s/^([^(]+)\(([^)]*)\)([$Validsuffixes]*)//) {
		($valstring,$parenstring,$suffices) = ($1,$2,$3);
		$fromstring = &SplitVals($valstring);
		$tostring = &SplitVals($parenstring);
		if ($suffices) {
			$suffstring = &ExtractSuffices;
			return $NULL unless $suffstring;
			$outstring = join('',$Rangefrom,$fromstring,$Rangeto,$tostring,"\"",'  ',$suffstring);
		} else {
			$outstring = join('',$Rangefrom,$fromstring,$Rangeto,$tostring,"\"");
		}

	# String like "$?", "?" -- only suffices
	} elsif ($token =~ s/^([$Validsuffixes]+)$//) {
		$suffices = $1;
		$suffstring = &ExtractSuffices;
		if ($suffices =~ /\$/) {
			$outstring = $suffstring;
		} elsif ($suffices =~ /\?/) {
			$outstring = $suffstring;
		} else {
			$outstring = join('  ',$IDS{''},$suffstring);
		}	

	# String like "+", "--", etc. -- only values
	} elsif ($token =~ s/^([^(]+)$//) {
		$tostring = $1;
		$outstring = &SplitVals($tostring);

	# No value -- null implied
	} elsif (!$token) {
		if ($wannaflag) {
			$outstring = $IDS{''};
		} else {
			$outstring = $IDS{''} unless $outstring;
		}

	# Some invalid string
	} else {
		return $NULL;
	}
	$outstring;
}

#=============================================================================
# SplitVals

sub SplitVals {
	local($token) = shift;
	local($outstring,$tmpstring,$suffices,$suffstring,$seentoken);

	unless ($token) {
		$outstring = $IDS{''};
		return $outstring;
	}
	while ($token) {
		if ($token =~ s/^($validvals)//) {
			$outstring .= $outstring ? "  $IDS{$1}": $IDS{$1};
			$seentoken++;

		} elsif ($token =~ s/^([$Validsuffixes]+)//) {
			$suffices = $1;
			$suffstring = &ExtractSuffices;
			unless ($seentoken) {
				$tmpstring = $IDS{''} || return $NULL;
				$outstring .= $outstring ? join('  ',$tmpstring,'',$suffstring) : join('  ',$tmpstring,$suffstring);
			} else {
				$outstring .= $outstring ? join('  ','',$suffstring) : $suffstring;
			}

		} else {
			return $NULL;
		}
	}
	$outstring;
}

#=============================================================================
# ExtractSuffices

sub ExtractSuffices {
	local(@suffices,%suff,@suffstrings,$suffix);

	foreach $suffix (split('',$suffices)) {
		if ($suffix eq '@') {
			if ($IDS{'@'}) {
				push(@suffstrings,$IDS{'@'});
			} else {
				push(@suffstrings,$Varystring);
			}
		} elsif ($suffix eq '?') {
			if ($IDS{'?'}) {
				push(@suffstrings,$IDS{'?'});
			} else {
				push(@suffstrings,join('',$Category,$Stupidstring));
			}
		} elsif ($suffix eq '$') {
			if ($IDS{'$'}) {
				push(@suffstrings,$IDS{'$'});
			} else {
				push(@suffstrings,$Paidstring);
			}
		}
	}
	join('  ',@suffstrings);
}

#=============================================================================
# BuildNegateString

sub BuildNegateString {
	local($outstring);

	unless ($IDS{$Negate}) {
		$outstring = "I refuse to categorize myself on $Category.";
		if ($RestToken && ($RestToken !~ /^[$Validsuffixes]+$/)) {
			$outstring = join('  ',$outstring,$ExtraNegate);
			$butif = "\"";
		}
	} else {
		$outstring = $IDS{$Negate};
		if ($RestToken && ($RestToken !~ /^[$Validsuffixes]+$/)) {
			$outstring = join('  ',$outstring,$ExtraNegate);
			$butif = "\"";
		}
	}
	$outstring;
}

#=============================================================================
# BuildHeader

sub BuildHeader {
	local($token) = shift;
    local($headchar,$hdrlen,$border,$header,$string);
   
	$token = join('','[',$token,']'); 
    $headchar = '-';
    $string = $Category ? join(' ','','GEEK',$Category,'CODE') : ' THE GEEK CODE';
    $string =~ tr/a-z/A-Z/;
	$string .= " $token ";
    $hdrlen = length($string);
    $border = $headchar x int(($Linelth - $hdrlen)/2);
    $header = join('',$border,$string,$border,"\n\n");
    $header;
}

#=============================================================================
# ProcessWholeToken

sub ProcessWholeToken {
	local($validvals,$hold);

	# Write out the category header
	$header = &BuildHeader($Token);

	if ($Category eq "Sex") { $outstring = "$Sex."; }

	if ($IDS{$Token}) {
		$outstring = $outstring ? "  $IDS{$Token}" : $IDS{$Token};
	} else {
		$hold = $IDS{''}; delete $IDS{''};
		$validvals = join('|',reverse sort {length($a) <=> length($b)} (keys(%IDS)));
		$validvals =~ s/([+?*])/\\$1/g;
		$IDS{''} = $hold if $hold;
		$outstring = &SplitWannabes;
	}
	$outstring;
}

#=============================================================================
# DisplayHelp

sub DisplayHelp {
	print <<"EndOfHelp";
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
                   UNGEEK --- GEEK CODE 3.1 EXTRACTOR
                  Pete Williams <petew\@lexis-nexis.com>
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=

  VALID OPTIONS ARE:

  -h          -- Help (display this screen)
  -m          -- Mail format.  Ungeek will attempt to guess who this geek
                 code belongs to and print it on standard output.
  -n number   -- Attempt "number" matches to determine whether the geek
                 code has been found.
  -r          -- Relax restrictions on code length; normally the program
                 looks for at least 5 valid geek code tokens to help 
                 ensure that it has actually found the geek code.
  -t code     -- Test "code" code fragment thru the ungeeker.  Note that
                 this option can only be used once on the command line.
  -x          -- Xtract code (or attempt to) only, do not print 
                 translation.
  filenames   -- Use given files rather than standard input (the 
                 program does its best to find filenames anywhere on 
                 the command line, namely those arguments not preceded 
                 by one of the valid options).

+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
EndOfHelp
	exit;
}

#=============================================================================
# PrintOutFrom

sub PrintOutFrom {
	if ($FromFlag) {
		$~ = 'MAIL_FROM'; foreach $from (@from) { write; } $~ = 'STDOUT';
	}
}

#=============================================================================
# PrintEnd

sub PrintEnd {
	$~ = 'GEEK_END'; write; $~ = 'STDOUT';
}

#=============================================================================
# PrintOutAll

sub PrintOutAll {
	&PrintOutGeek; &PrintEnd; &PrintOutCode;
}

#=============================================================================
# PrintOutCode

sub PrintOutCode {
	local($tokenstring,$curtoken,$curline,$linelen);
	local(@printtokens) = @tokens;

	&PrintOutFrom if ($FromFlag && !$PrintedFrom);
	return unless @tokens;
	$~ = 'STDOUT_ONLY_TOP'; write; $~ = 'STDOUT_CODE_ONLY';

	while ($curtoken = shift @printtokens) {
		if (($linelen + length($curtoken)) <= $Cols) {
			$curline = join('',$curline,$curtoken,' ');
			$linelen += length($curtoken) + 1;
		} else {
			write;
			$curline = "$curtoken ";
			$linelen = length($curtoken) + 1;
		}
	}
	write if $curline;
	$~ = 'STDOUT_ONLY_BOTTOM'; write; $~ = 'STDOUT';
}

#=============================================================================
# PrintOutGeek

sub PrintOutGeek {
	local($header,$token,$outstring,$printtoken);
	local(@tmpheaders) = @headers;
	local(@tmptokens) = @tokens;
	local(@tmpoutstrings) = @outstrings;

	$~ = 'GEEK_BEGIN'; write; $~ = 'STDOUT';
	if ($FromFlag) { &PrintOutFrom; $PrintedFrom++; }

	while ($header = shift @tmpheaders) {
		$printtoken = shift @tmptokens;
		$outstring = shift @tmpoutstrings;
		write;
	}
}

#=============================================================================
# FORMATS

format STDOUT =
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$header

    ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    $outstring
~~  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    $outstring

.

format STDOUT_ONLY_TOP = 
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$GCBegin
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$GCVersion
.

format STDOUT_ONLY_BOTTOM = 
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$GCEnd

.

format STDOUT_CODE_ONLY =
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$curline 
.

format GEEK_BEGIN =
============================================================================
================  UNGEEK 3.1 -- Geek Code v3.1 Interpreter  ================
============================================================================

.
#================   @||||||||||||||||||||||||||||||||||||    ================
#                  "Pete Williams <petew@lexis-nexis.com>"

format GEEK_END =
============================================================================

.

format MAIL_FROM =
****************************************************************************
* @<<<<<<<<<<<<<<<<<<<<<<<  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< *
 "Geek Code Signature ID:", $from
*                         ~~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< *
                            $from
****************************************************************************

.

#=============================================================================
# ExtractGeekTypes

sub ExtractGeekTypes {
	local(@wannabes,$maintype,$newtoken,$wannaflag);
	$Category = 'type';
	%IDS = (
	"B", "Geek of Business",
	"C", "Geek of Classics",
	"CA","Geek of Commercial Arts",
	"CM","Geek of Computer Management",
	"CS","Geek of Computer Science",
	"CC","Geek of Communications",
	"E", "Geek of Engineering",
	"ED","Geek of Education",
	"FA","Geek of Fine Arts",
	"G", "Geek of Government",
	"H", "Geek of Humanities",
	"IT","Geek of Information Technology",
	"J", "Geek of Jurisprudence (Law)",
	"LS","Geek of Library Science",
	"L", "Geek of Literature",
	"MC","Geek of Mass Communications",
	"M", "Geek of Math",
	"MD","Geek of Medicine",
	"MU","Geek of Music",
	"PA","Geek of Performing Arts",
	"P", "Geek of Philosophy",
	"S", "Geek of Science (Physics, Chemistry, Biology, etc.)",
	"SS","Geek of Social Science (Psychology, Sociology, etc.)",
	"TW","Geek of Technical Writing",
	"O", "Geek of Other",
	"U", "Geek of Undecided",
	"AT","Geek of All Trades",
	"!", "Geek of no qualifications",
	);

	$newtoken = substr($Token,1);
	($maintype,@wannabes) = split(/\>/,$newtoken);
	if ($maintype) {
		foreach $geektype (split(/\//,$maintype)) {
			return 0 unless &ProcessGeekType;
		}
		$outstring .= ".";
	} else {
		return 0;
	}
	foreach $wannabe (@wannabes) {
		$wannaflag++;
		local($wannastring);
		foreach $geektype (split(/\//,$wannabe)) {
			return 0 unless &ProcessGeekType;
		}
		$outstring .= join('',$wannastring,".\"");
	}
	$header = &BuildHeader($Token);
	1;
}

#=============================================================================
# ProcessGeekType
#
# Will need to do separate processing for this one, as many of the options
# normally used for other categories really make no sense here.
# Valid Options: @, >, $

sub ProcessGeekType {
	local($valid_syms,$sufflag,$gtpatts,$suffices,$type);

	$gt_patts = "CA|CM|CS|CC|ED|FA|IT|LS|MC|MD|MU|PA|SS|TW|AT|[!BCEGHJLMOPSU]";
	$valid_syms = '[$@]';

	if ($geektype =~ /^($gt_patts)(${valid_syms}*)$/) {
		($type,$suffices) = ($1,$2);
		if ($wannaflag) {
			if ($wannastring) {
				$wannastring .= ", $IDS{$type}" if $type;
			} else {
				$wannastring .= join('',$Wannabestring,$IDS{$type}) if $type;
			}
		} else {
			$outstring .= $outstring ? ", $IDS{$type}" : $IDS{$type};
		}

		if ($suffices =~ /\$/) {
			if ($wannaflag) {
				$wannastring .= "  $Paidstring";
			} else {
				$outstring .= "  $Paidstring";
			}
			$sufflag++;
		}
		if ($suffices =~ /@/) {
			if ($wannaflag) {
				$wannastring .= "  $Varystring";
			} else {
				$outstring .= "  $Varystring";
			}
			$sufflag++;
		}
		1;
	} else {
		0;
	}
}

#=============================================================================
# ExtractAge

sub ExtractAge {
	local($tmptoken) = $Token;
	$Category = 'Age';
	%IDS = (
		"+++",  "My age is 60 and up.",
		"++",   "My age is 50-59.",
		"+",    "My age is 40-49.",
		"",     "My age is 30-39.",
		"-",    "My age is 25-29.",
		"--",   "My age is 20-24.",
		"---",  "My age is 15-19.",
		"----", "My age is 10-14.",
		"-----","My age is 9 and under (Geek in training?).",
		"?",    "I am immortal.",
		"!",    "It's none of your business how old I am.",
	);
	while ($tmptoken =~ s/(\d+)//) { $IDS{$1} = "I am $1 years old."; }
}

#=============================================================================
# ExtractDress

sub ExtractDress {
	$Category = 'Dress';
	%IDS= (
	"++", "I tend to wear conservative dress such as a business suit or worse, a tie.",
	"+",  "Good leisure-wear.  Slacks, button-shirt, etc.  No jeans, tennis shoes, or t-shirts.",
	"",   "I dress a lot like those found in catalog ads.  Bland, boring, without life or meaning.",
	"-",  "I'm usually in jeans and a t-shirt.",
	"--", "My t-shirts go a step further and have a trendy political message on them.",
	"---","Punk dresser, including, but not limited to, torn jeans and shirts, body piercings, and prominent tattoos.",
	"x",  "Cross Dresser",
	"?",  "I have no idea what I am wearing right now, let alone what I wore yesterday.",
	"!",  "No clothing.  Quite a fashion statement, don't you think?",
	"pu", "I wear the same clothes all the time, no matter the occasion, forgetting to do laundry between wearings.",
	);

}

#=============================================================================
# ExtractEducation

sub ExtractEducation {
	$Category = 'Education';
	%IDS = (
	"+++++", "I am Stephen Hawking.",
	"++++",  "Managed to get my Ph.D.",
	"+++",   "Got a Masters degree.",
	"++",    "Got a Baccalaureate degree.",
	"+",     "Got an Associate degree.",
	"",      "Finished High School.",
	"-",     "Haven't finished High School.",
	"--",    "Haven't even entered High School.",
	"*",     "I learned everything there is to know about life from the \"Hitchhiker's Trilogy\".",
	);
}

#=============================================================================
# ExtractHouse

sub ExtractHouse {
	$Category = 'Housing';
	%IDS = (
	"++",   "Living in a cave with 47 computers and an Internet feed, located near a Dominoes pizza.  See !d.",
	"+",    "Living alone, get out once a week to buy food, no more than once a month to do laundry.  All surfaces covered.",
	"",     "Friends come over to visit every once in a while to talk about Geek things.  There is a place for them to sit.",
	"-",    "Living with one or more registered Geeks.",
	"--",   "Living with one or more people who know nothing about being a Geek and refuse to watch Babylon 5.",
	"---",  "Married, (persons living romantically with someone might as well label themselves h---, you're as good as there already.)",
	"----", "Married with children - Al Bundy can sympathize.",
	"!",    "I am stuck living with my parents!",
	"*",    "I'm not sure where I live anymore.  This lab/workplace seems like home to me.",
	);
}

#=============================================================================
# ExtractRelationships

sub ExtractRelationships {
	$Category = 'Relationships';
	%IDS = (
	"+++", "Found someone, dated, and am now married.",
	"++",  "I've dated my current S.O. for a long time.",
	"+",   "I date frequently, bouncing from one relationship to another. ",
	"",    "I date periodically.",
	"-",   "I have difficulty maintaining a relationship.",
	"--",  "People just aren't interested in dating me.",
	"---", "I'm beginning to think that I'm a leper or something, the way people avoid me like the plague.",
	"!",   "I've never had a relationship.",
	"*",   "signifying membership in the SBCA (Sour Bachelor(ette)'s Club of America).  The motto is 'Bitter, but not Desperate'.  First founded at Caltech.",
	"%",   "I was going out with someone, but the asshole dumped me.",
	);
}

#=============================================================================
# ExtractShape

sub ExtractShape {
	$Category = 'Shape';
	%IDS = (
	"+++:",  "I usually have to duck through doors.",
	"++:",   "I'm a basketball candidate.",
	"+:",    "I'm a little taller than most.",
	"-:",    "I look up to most people.",
	"--:",   "I look up to damn near everybody.",
	"---:",  "I take a phone book with me when I go out so I can see to eat dinner.",
	":+++", "I take up three movie seats.",
	"+++", "I take up three movie seats.",
	":++",  "I'm a linebacker candidate.",
	"++",  "I'm a linebacker candidate.",
	":+",   "I'm a little rounder than most.",
	"+",   "I'm a little rounder than most.",
	":-",   "Everyone tells me to gain a few pounds.",
	"-",   "Everyone tells me to gain a few pounds.",
	":--",  "I tend to have to fight against a strong breeze.",
	"--",  "I tend to have to fight against a strong breeze.",
	":---", "My bones are poking through my skin.",
	"---", "My bones are poking through my skin.",
	":",     "I'm an average geek.",
	);
}

#=============================================================================
# ExtractStarTrek

sub ExtractStarTrek {
	$Category = 'Star Trek';
	%IDS = (
	"+++", "It's not just a TV show, it's a religion.  I know all about warp field dynamics and the principles behind the transporter.  I have memorized the TECH manual.  I speak Klingon.  I go to cons with Vulcan ears on.  I have no life.",
	"++",  "It's the best show around.  I have all the episodes and the movies on tape and can quote entire scenes verbatim.  I've built a few of the model kits too.  But you'll never catch me at one of those conventions.  Those people are kooks.",
	"+",   "It's a damn fine TV show and is one of the only things good on television any more.",
	"",    "It's just another TV show.",
	"-",   "Maybe it is just me, but I have no idea what the big deal with Star Trek is.  Perhaps I'm missing something but I just think it is bad drama.",
	"--",  "Star Trek is just another Space Opera.  William Shatner isn't an actor, he's a poser!  And what's with this Jean-Luc Picard?  A Frenchman with a British accent?  Come on.  I'd only watch this show if my remote control broke.  Isn't Voyager just a rehash of Lost in Space?  Has Sisko even breathed in the last two seasons?",
	"---", "Star Trek SUCKS!  It is the worst crap I have ever seen! Hey, all you trekkies out there, GET A LIFE!  (William Shatner is a t---).",
	"*",   "I identify with Barclay, the greatest of the Trek Geeks." 
	);
}

#=============================================================================
# ExtractTV

sub ExtractTV {
	$Category = 'Television';
	%IDS = (
	"+++", "There's nothing I can experience \"out there\" that I can't see coming over my satellite dish.  I wish there were MORE channels.  I live for the O.J. Trial.",
	"++",  "I just leave the tv on, to make sure I don't miss anything.",
	"+",   "I watch some tv every day.",
	"",    "I watch only the shows that are actually worthwhile, such as those found on PBS.",
	"-",   "I watch tv for the news and 'special programming.'",
	"--",  "I turn my tv on during natural disasters.",
	"!",   "I do not own a television.",
	);
}

#=============================================================================
# ExtractBooks

sub ExtractBooks {
	$Category = 'Books';
	%IDS = (
	"++++","I read a book a day.  I have library cards in three states.  I have discount cards from every major bookstore.  I've ordered books from another country to get my Favorite Author Fix.",
	"+++", "I consume a few books a week as part of a staple diet.", 
	"++",  "I find the time to get through at least one new book a month.", 
	"+",   "I enjoy reading, but don't get the time very often.",
	"",    "I read the newspaper and the occasional book.",
	"-",   "I read when there is no other way to get the information.",
	"--",  "I did not actually READ the geek code, I just had someone tell me.",
	);
}

#=============================================================================
# ExtractMicroSloth

sub ExtractMicroSloth {
	$Category = 'MicroSoft Windows';
	%IDS = (
	"+++++", "I am Bill Gates",
	"++++",  "I have Windows, Windows 95, Windows NT, and Windows NT Advanced Server all running on my SMP RISC machine.  I haven't seen daylight in six months.",
	"+++",   "I am a MS Windows programming god.  I wrote a VxD driver to allow MS Windows and DOS to share the use of my waffle iron.  P.S.  Unix sux.",
	"++",    "I write MS Windows programs in C and think about using C++ someday.  I've written at least one DLL.",
	"+",     "I have installed my own custom sounds, wallpaper, and screen savers so my PC walks and talks like a fun house.  Oh yeah, I have a hundred TrueType(tm) fonts that I've installed but never used.  I never lose Minesweeper and Solitaire",
	"",      "Ok, so I use MS Windows, I don't have to like it.",
	"-",     "I'm still trying to install MS Windows and have at least one peripheral that never works right",
	"--",    "MS Windows is a joke operating system.  Hell, it's not even an operating system.  NT is Not Tough enough for me either.  95 is how may times it will crash an hour.",
	"---",   "Windows has set back the computing industry by at least 10 years.  Bill Gates should be drawn, quartered, hung, shot, poisoned, disembowelled, and then REALLY hurt.",
	);
}

#=============================================================================
# ExtractSexNeuter

sub ExtractSexNeuter {
	$Category = 'Sex';
	$Sex = "Gender undisclosed";

	%IDS = (
	"++++", "I have a few little rug rats to prove I've been there.  Besides, with kids around, who has time for sex?",
	"+++",  "I'm married, so I can get it (theoretically) whenever I want.", 
	"++",   "I was once referred to as 'easy'.  I have no idea where that might have come from though.",
	"+",    "I've had real, live sex.",
	"",     "I've had sex.  Oh!  You mean with someone else?  Then no.",
	"-",    "Not having sex by choice.",
	"--",   "Not having sex because I just can't get any...",
	"---",  "Not having sex because I'm a nun or a priest.",
	"*",    "I'm a pervert.",
	"**",   "I've been known to make perverts look like angels.",
	"!",    "Sex?  What's that?  I've had no sexual experiences.",
	"?",    "It's none of your business what my sex life is like.",
	"!z+",  "Sex? What's that? No experience, willing to learn!",
	);
}

#=============================================================================
# ExtractSexFemale

sub ExtractSexFemale {
	$Category = 'Sex';
	$Sex = "Female";

	%IDS = (
	"+++++","I am Madonna",
	"++++", "I have a few little rug rats to prove I've been there.  Besides, with kids around, who has time for sex?",
	"+++",  "I'm married, so I can get it (theoretically) whenever I want.", 
	"++",   "I was once referred to as 'easy'.  I have no idea where that might have come from though.",
	"+",    "I've had real, live sex.",
	"",     "I've had sex.  Oh!  You mean with someone else?  Then no.",
	"-",    "Not having sex by choice.",
	"--",   "Not having sex because I just can't get any...",
	"---",  "Not having sex because I'm a nun or a priest.",
	"*",    "I'm a pervert.",
	"**",   "I've been known to make perverts look like angels.",
	"!",    "Sex?  What's that?  I've had no sexual experiences.",
	"?",    "It's none of your business what my sex life is like.",
	"!x+",  "Sex? What's that? No experience, willing to learn!",
	);
}

#=============================================================================
# ExtractSexMale

sub ExtractSexMale {
	$Category = 'Sex';
	$Sex = "Male";

	%IDS = (
	"++++", "I have a few little rug rats to prove I've been there.  Besides, with kids around, who has time for sex?",
	"+++",  "I'm married, so I can get it (theoretically) whenever I want.", 
	"++",   "I was once referred to as 'easy'.  I have no idea where that might have come from though.",
	"+",    "I've had real, live sex.",
	"",     "I've had sex.  Oh!  You mean with someone else?  Then no.",
	"-",    "Not having sex by choice.",
	"--",   "Not having sex because I just can't get any...",
	"---",  "Not having sex because I'm a nun or a priest.",
	"*",    "I'm a pervert.",
	"**",   "I've been known to make perverts look like angels.",
	"!",    "Sex?  What's that?  I've had no sexual experiences.",
	"?",    "It's none of your business what my sex life is like.",
	"!y+",  "Sex? What's that? No experience, willing to learn!",
	);
}

#=============================================================================
# ExtractComputer

sub ExtractComputer {
	$Category = 'Computers';
	%IDS = (
	"++++", "I'll be first in line to get the new cybernetic interface installed into my skull.",
	"+++",  "You mean there is life outside of Internet?  You're shittin' me!  I haven't dragged myself to class in weeks.",
	"++",   "Computers are a large part of my existence.  When I get up in the morning, the first thing I do is log myself in.  I play games or mud on weekends, but still manage to stay off of academic probation.",
	"+",    "Computers are fun and I enjoy using them.  I play a mean game of DOOM! and can use a word processor without resorting to the manual too often.  I know that a 3.5\" disk is not a hard disk.  I also know that when it says 'press any key to continue', I don't have to look for a key labeled 'ANY'.",
	"",     "Computers are a tool, nothing more.  I use it when it serves my purpose.",
	"-",    "Anything more complicated than my calculator and I'm screwed.",
	"--",   "Where's the on switch?",
	"---",  "If you even mention computers, I will rip your head off!",
	);
}

#=============================================================================
# ExtractDoom

sub ExtractDoom {
	$Category = 'Doom';
	%IDS = (
	"++++","I work for iD Software.",
	"+++", "I crank out PWAD files daily, complete with new monsters, weaponry, sounds and maps.  I'm a DOOM God.  I can solve the original maps in nightmare mode with my eyes closed.",
	"++",  "I've played the shareware version and bought the real one and I'm actually pretty good at the game.  I occasionally download PWAD files and play them too.",
	"+",   "It's a fun, action game that is a nice diversion on a lazy afternoon.",
	"",    "I've played the game and I'm pretty indifferent.",
	"-",   "I've played the game and really didn't think it was all that impressive.",
	"--",  "It's an overly-violent game and pure crap.",
	"---", "To hell with Doom, I miss Zork.",
	"----","I've seen better on my Atari 2600.",
	);
}

#=============================================================================
# ExtractDilbert

sub ExtractDilbert {
	$Category = 'Dilbert';
	%IDS = (
	"+++++", "I am Scott Adams.",
	"++++",  "I've received mail from Scott Adams.  I'm in the DNRC (Dogbert's New Ruling Class).",
	"+++",   "I am a Dilbert prototype.",
	"++",    "I work with people that act a lot like Dilbert and his boss.",
	"+",     "I read Dilbert daily, often understanding it.",
	"",      "I read Dilbert infrequently, rarely understanding it.",
	"-",     "Is that the comic about the engineers?",
	"--",    "Don't read it, but I think the dog is kinda cute.",
	"---",   "I don't think it's funny to make fun of managers trying their best to run their organizational units.",
	);
}

#=============================================================================
# ExtractEmacs

sub ExtractEmacs {
	$Category = 'Emacs';
	%IDS = (
	"+++", "Emacs is my login shell!!  M-x doctor is my psychologist! I use emacs to control my TV and toaster oven!  All you vi people don't know what you're missing!  I read alt.relgion.emacs, alt.sex.emacs, and comp.os.emacs.",
	"++",  "I know and use elisp regularly!",
	"+",   "Emacs is great!  I read my mail and news with it!",
	"",    "Yeah, I know what emacs is, and use it as my regular editor.",
	"-",   "Emacs is too big and bloated for my tastes",
	"--",  "Emacs is just a fancy word processor",
	"---", "Emacs sucks!  vi forever!!!",
	"----","Emacs sucks!  pico forever!!!",
	);
}

#=============================================================================
# ExtractGeek

sub ExtractGeek {
	$Category = '';
	%IDS = (
	"+++++","I am Robert Hayden.",
	"++++", "I have made a suggestion for future versions of the code.", 
	"+++",  "I have memorized the entire geek code, and can decode others' codes in my head.  I know by heart where to find the current version of the code on the net.",
	"++",   "I know what each letter means, but sometimes have to look up the specifics.",
	"+",    "I was once G++ (or higher), but the new versions are getting too long and too complicated.",
	"",     "I know what the geek code is and even did up this code.",
	"-",    "What a tremendous waste of time this Geek Code is.",
	"--",   "Not only a waste of time, but it obviously shows that this Hayden guy needs a life.",
	);
}

#=============================================================================
# ExtractKibo

sub ExtractKibo {
	$Category = 'Kibo';
	%IDS = ( #
	"++++++", "I am Kibo.",
	"+++++",  "I've had sex with Kibo.",
	"++++",   "I've met Kibo.",
	"+++",    "I've gotten mail from Kibo.",
	"++",     "I've read Kibo.",
	"+",      "I like Kibo.",
	"",       "I know who Kibo is.",
	"-",      "I don't know who Kibo is.",
	"--",     "I dislike Kibo.",
	"---",    "I am currently hunting Kibo down with the intent of ripping his still-beating heart out of his chest and showing it to him as he dies.",
	"----",   "I am Xibo.",
	);
}

#=============================================================================
# ExtractLinux

sub ExtractLinux {
	$Category = 'Linux';
	%IDS = ( #
	"+++++", "I am Linus, grovel before me.",
	"++++",  "I am a Linux wizard.  I munch C code for breakfast and have enough room left over for a kernel debugging.  I have so many patches installed that I lost track about ten versions ago.  Linux newbies consider me a net.god.",
	"+++",   "I use Linux exclusively on my system.  I monitor comp.os.linux.* and even answer questions sometimes.",
	"++",    "I use Linux ALMOST exclusively on my system.  I've given up trying to achieve Linux.God status, but welcome the OS as a replacement for DOS.  I only boot to DOS to play games.",
	"+",     "I've managed to get Linux installed and even used it a few times.  It seems like it is just another OS.",
	"",      "I know what Linux is, but that's about all.",
	"-",     "I have no desire to use Linux and frankly don't give a rats patootie about it.  There are other, better, operating systems out there.  Like Mac, DOS, or Amiga-OS.  Or, better yet even, would be another free Unix OS like FreeBSD.",
	"--",    "Unix sucks.  Because Linux = Unix.  Linux Sucks.  I worship Bill Gates.",
	"---",   "I am Bill Gates.",
	"!",     "I don't even know what Linux is!",
	);
}

#=============================================================================
# ExtractMac

sub ExtractMac {
	$Category = 'Macintosh';
	%IDS = (
	"++", "I am a Mac guru.  Anything those DOS putzes and unix nerds can do, I can do better, and if not, I'll write the damn software to do it.",
	"+",  "A Mac has it's uses and I use it quite often.",
	"",   "I use a Mac, but I'm pretty indifferent about it.",
	"-",  "Macs suck.  All real geeks have a character prompt.",
	"--", "Macs do more than suck.  They make a user stupid by allowing them to use the system without knowing what they are doing.  Mac weenies have lower IQs than the fuzz in my navel.",
	);
}

#=============================================================================
# ExtractUsenet

sub ExtractUsenet {
	$Category = 'Usenet';

	%IDS = (
	"++++", "I am Tim Pierce.",
	"+++",  "I read so many news groups that the next batch of news comes in before I finish reading the last batch, and I have to read for about 2 hours straight before I'm caught up on the morning's news.  Then there's the afternoon...",
	"++",   "I read all the news in a select handful of groups.",
	"+",    "I read news recreationally when I have some time to kill.",
	"",     "Usenet News?  Sure, I read that once.",
	"-",    "News is a waste of my time and I avoid it completely.",
	"--",   "News sucks!  'Nuff said.",
	"---",  "I work for Time Magazine.",
	"----", "I am a Scientologist.",
	"*",    "All I do is read news.",
	);
}

#=============================================================================
# ExtractUsenetOracle

sub ExtractUsenetOracle {
	$Category = 'Usenet Oracle';
	%IDS = (
	"+++++", "I am Steve Kinzler",
	"++++",  "I am an active Priest",
	"+++",   "I was a Priest, but have retired.",
	"++",    "I have made the Best Of Oracularities.",
	"+",     "I have been incarnated at least once.",
	"",	     "I've submitted a question, but it has never been incarnated.", 
	"-",     "I sent my question to the wrong group and got flamed.",
	"--",    "Who needs answers from a bunch of geeks anyhow?",
	);
}

#=============================================================================
# ExtractOS2

sub ExtractOS2 {
	$Category = 'OS/2';
	%IDS = (
	"+++", "I live, eat and breathe OS/2.  All of my hard drives are HPFS.  I am the Anti-Gates.",
	"++",  "I use OS/2 for all my computing needs.  I use some DOS and Windows programs, but rune them under OS/2.  If the program won't run under OS/2, then obviously I don't need it.",
	"+",   "I keep a DOS partition on my hard drive \"just in case\".  I'm afraid to try HPFS.",
	"",    "I finally managed to get OS/2 installed but wasn't too terribly impressed.",
	"-",   "Tried it, didn't like it.",
	"--",  "I can't even get the thing to install!",
	"---", "Windows RULES!!!  Long live Bill Gates.  (See w++++).",
	"----","I am Bill Gates of Borg.  OS/2 is irrelevant.",
	);
}

#=============================================================================
# ExtractPerl

sub ExtractPerl {
	$Category = 'Perl';
	%IDS = (
	"+++++","I am Larry Wall, Tom Christiansen, or Randal Schwartz.",
	"++++", "I don't write Perl, I speak it.  Perl has superseded all other programming languages.  I firmly believe that all programs can be reduced to a Perl one-liner.  I use Perl to achieve U+++ status.",
	"+++",  "Perl is a very powerful programming tool. Not only do I no longer write shell scripts,  I also no longer use awk or sed.  I use Perl for all programs of less than a thousand lines.",
	"++",   "Perl is a powerful programming tool.  I don't write shell scripts anymore because I write them in Perl.",
	"+",    "I know of perl.  I like perl.  I just haven't learned much perl, but it is on my agenda.",
	"",     "I know Perl exists, but that's all.",
	"-",    "What's Perl got that awk and sed don't have?",
	"--",   "Perl users are sick, twisted programmers who are just showing off.",
	"---",  "Perl combines the power of sh, the clarity of sed, and the performance of awk with the simplicity of C.  It should be banned.",
	"?",    "What's Pearl?",
	"!",    "Our paranoid admin won't let us install perl!  Says it's a \"hacking tool\".",
	);
}

#=============================================================================
# ExtractPolEcon

sub ExtractPolEcon {
	$Category = 'Politics & Economic Issues';
	%IDS = (
	"+++", "Abolish antitrust legislation.  Raise taxes on everyone but the rich so that the money can trickle-down to the masses.",
	"++",  "Keep the government off the backs of businesses.  Deregulate as much as possible.",
	"+",   "Balance the budget with spending cuts and an amendment.",
	"",    "Distrust both government and business.",
	"-",   "It's ok to increase government spending, so we can help more poor people.  Tax the rich!  Cut the defense budget!",
	"--",  "Capitalism is evil!  Government should provide the services we really need.  Nobody should be rich.",
	);
}

#=============================================================================
# ExtractPGP

sub ExtractPGP {
	$Category = 'PGP';
	%IDS = (
	"++++", "I am Philip Zimmerman.",
	"+++",  "I don't send or answer mail that is not encrypted, or at the very least signed.  If you are reading this without decrypting it first, something is wrong.  IT DIDN'T COME FROM ME!",
	"++",   "I have the most recent version and use it regularly.",
	"+",    "\"Finger me for my public key\".",
	"",	    "I've used it, but stopped long ago.",
	"-",    "I don't have anything to hide.",
	"--",   "I feel that the glory of the Internet is in the anarchic, trusting environment that so nurtures the exchange of information.  Encryption just bogs that down.",
	"---",  "If you support encryption on the Internet, you must be a drug dealer or terrorist or something like that.",
	"----", "Oh, here's is something you all can use that is better (insert Clipper here).",
	);
}

#=============================================================================
# ExtractPolSoc

sub ExtractPolSoc {
	$Category = 'Politics & Social Issues';
	%IDS = (
	"+++", "Legalize drugs!  Abolish the government.  Fuck the draft!",
	"++",  "I give to liberal causes.  I march for gay rights.  I'm a card carrying member of the ACLU.  Keep abortion safe and legal.",
	"+",   "My whole concept of liberalism is that nobody has the right to tell anybody else what to do, on either side of the political fence.  If you don't like it, turn the bloody channel.",
	"",    "I really don't have an opinion; nobody's messing with my freedoms right now.",
	"-",   "Label records!  Keep dirty stuff off the TV and the Internet.",
	"--",  "Oppose sex education, abortion rights, gay rights.  Rush Limbaugh is my spokesman.",
	"---", "Repent left-wing sinners and change your wicked evil ways. Buchanan/Robertson in '96.",
	);
}

#=============================================================================
# ExtractRoleplay

sub ExtractRoleplay {
	$Category = 'Role-Playing';
	%IDS = (
	"+++", "I've written and published my own gaming materials.",
	"++",  "There is no life outside the role of the die.  I know all of the piddly rules of (chosen game).  _MY_ own warped rules scare the rest of the players.",
	"+",   "I've got my weekly sessions set up and a character that I know better than I know myself.",
	"",    "Role-Playing?  That's just something to do to kill a Saturday afternoon.",
	"-",   "Gosh, what an utter waste of time!",
	"--",  "Role-Players are instruments of pure evil.",
	"---", "I work for T$R.",
	"*",   "I thought life WAS role-playing?",
	);
}

#=============================================================================
# ExtractUnix

sub ExtractUnix {
	local($seenunix,%unices,$unixtype,$extraunices,$onlyunix,$extrahold);
	$Category = 'UNIX';
	$unixvals = "ABCHILOSUVX*";
	$extraunices = '*';
	%unices = (
	"B",    "BSD",
	"L",    "Linux",
	"U",    "Ultrix",
	"A",    "AIX",
	"V",    "SysV",
	"H",    "HPUX",
	"I",    "IRIX ",
	"O",    "OSF/1 (aka Digital Unix)",
	"S",    "SunOS/Solaris",
	"C",    "SCO Unix",
	"X",    "NeXT",
	"*",    "some other(s) not listed",
	);
	%IDS = ( #
	"++++", "I am the sysadmin.  If you try and crack my machine don't be surprised if the municipal works department gets an \"accidental\" computer-generated order to put start a new landfill on your front lawn or your quota is reduced to 4K.",
	"+++",  "I don't need to crack /etc/passwd because I just modified su so that it doesn't prompt me.  The admin staff doesn't even know I'm here.  If you don't understand what I just said, this category does NOT apply to you!",
	"++",   "I've get the entire admin ticked off at me because I am always using all of the CPU time and trying to run programs that I don't have access to.  I'm going to try cracking /etc/passwd next week, just don't tell anyone.",
	"+",    "I not only have a unix account, but I slam VMS any chance I get.",
	"",     "I have a unix account to do my stuff in.",
	"-",    "I have a VMS account.",
	"--",   "I've seen unix and didn't like it.  DEC rules!",
	"---",  "Unix geeks are actually nerds in disguise.",
	);

	if ($RestToken =~ /([$unixvals])[^$unixvals]*([$unixvals]*)/) {
		if ($1 && $2) {
			$outstring = "I use ";
			while ($RestToken =~ s/([$unixvals])//) { # Go thru all the values
				$unixtype = $1;
				if ($RestToken =~ /([$unixvals])/) { # There's another unixval in there somewhere
					if ($unixtype eq $extraunices) {
							$extrahold++;
					} elsif ($seenunix) {
							$outstring .= ", $unices{$unixtype}";
					} else {
						$outstring .= $unices{$unixtype};
						$seenunix++;
					}
				} else { # This seems to be the last unixval in the string
					if ($seenunix) {
						if (($unixtype eq $extraunices) || !$extrahold) {
							$outstring .= " and $unices{$unixtype}.";
						} else {
							$outstring .= ", $unices{$unixtype} and $unices{'*'}.";
						}
					} else {
						if (($unixtype eq $extraunices) || !$extrahold) {
							$outstring .= "$unices{$unixtype}.";
						} else {
							$outstring .= "$unices{$unixtype} and $unices{'*'}.";
						}
					}
				}
			}
		} else {
			$onlyunix = $1;
			if ($onlyunix eq $extraunices) {
				$outstring .= "I use $unices{'*'}";
			} else {
				$outstring .= "I use $unices{$onlyunix} exclusively.";
			}
		}
	}
	$RestToken =~ s/[$unixvals]//g;
	&ProcessWholeToken;
}

#=============================================================================
# ExtractVMS

sub ExtractVMS {
	$Category = 'VMS';
	%IDS = (
	"+++", "I am a VMS sysadmin.  I wield far more power than those UNIX admins, because UNIX can be found on any dweeb's desktop.  Power through obscurity is my motto.",
	"++",  "Unix is a passing fad compared to the real power in the universe, my VMS system.",
	"+",   "I tend to like VMS better than Unix",
	"",    "I've used VMS.",
	"-",   "Unix is much better than VMS for my computing needs.",
	"--",  "I would rather smash my head repeatedly into a brick wall than suffer the agony of working with VMS.  It's reminiscent of a dead and decaying pile of moose droppings.  Unix rules the universe.",
	);
}

#=============================================================================
# ExtractWWW

sub ExtractWWW {
	$Category = 'World Wide Web';
	%IDS = (
	"+++", "I am a WebMaster.  Don't even think about trying to view my homepage without the latest version of Netscape.  When I'm not on my normal net connection, I surf the web using my Newton and a cellular modem.",
	"++",  "I have a homepage.  I surf daily.  My homepage is advertised in my .signature.",
	"+",   "I have the latest version of Netscape, and wander the web only when there's something specific I'm looking for.",
	"",    "I have a browser and a connection.  Occasionally I'll use them. ",
	"-",   "The web is really a pain.  Life was so much easier when you could transfer information by simple ASCII.  Now everyone won't even consider your ideas unless you spiff them up with bandwidth-consuming pictures and pointless information links.",
	"--",  "A pox on the Web!  It wastes time and bandwidth and just gives the uneducated morons a reason to clutter the Internet.",
	);
}

#=============================================================================
# ExtractXfiles

sub ExtractXfiles {
	$Category = 'X Files';
	%IDS = (
	"++++","I am Chris Carter",
	"+++", "This is the BEST show on TV, and it's about time.  I've seen everything David Duchovny and Gillian Anderson have ever done that been recorded and I'm a loyal Duchovny/ Gillian Anderson fan.  I've Converted at least 10 people.  I have every episode at SP, debate the fine details on-line, and have a credit for at least 2 YAXAs. ",
	"++",  "This is one of the better shows I've seen.  I wish I'd taped everything from the start at SP, because I'm wearing out my EP tapes.  I'll periodically debate online.  I've Converted at least 5 people.  I've gotten a YAXA.",
	"+",   "I've Converted my family and watch the show when I remember.  It's really kinda fun.",
	"",    "Ho hum.  Just another Fox show.",
	"-",   "It's ok if you like paranoia and conspiracy stories, but, let's face it, it's crap.",
	"--",  "If I wanted to watch this kind of stuff, I'd talk to Oliver Stone",
	);
}

#=============================================================================
# ExtractCypher

sub ExtractCypher {
	$Category = 'Cypherpunks';
	%IDS = (
	"+++", "I am T.C. May",
	"++",  "I am on the cypherpunks mailing list and active around Usenet.  I never miss an opportunity to talk about the evils of Clipper and ITAR and the NSA.  Orwell's 1984 is more than a story, it is a warning to our's and future generations.  I'm a member of the EFF.",
	"+",   "I have an interest and concern in privacy issues, but in reality I am not really all that active or vocal.",
	"",    "I'm pretty indifferent on the whole issue.",
	"-",   "It seems to me that all of these concerns are a little extreme.  I mean, the government must be able to protect itself from criminals and the populace from indecent speech. ",
	"--",  "Get a life.  The only people that need this kind of protection are people with something to hide.  I think cypherpunks are just a little paranoid.",
	"---", "I am L. Detweiler.",
	);
}

#=============================================================================
# ExtractBabylon5

sub ExtractBabylon5 {
	$Category = 'Babylon 5';
	%IDS = (
	"++++","I am J. Michael Straczynski",
	"+++", "I am a True Worshipper of the Church of Joe who lives eats breathes and thinks Babylon 5, and has Evil thoughts about stealing Joe's videotape archives just to see episodes earlier.  I am planning to break into the bank and steal the triple-encoded synopsis of the 5-year arc.",
	"++",  "Finally a show that shows what a real future would look like.  None of this Picardian \"Let's talk about it and be friends\" crap.  And what's this?  We finally get to see a bathroom!  Over on that Enterprise, they've been holding it for over seven years!",
	"+",   "Babylon 5 certainly presents a fresh perspective in the Sci-Fi universe.  I watch it weekly.",
	"",    "I've seen it, I am pretty indifferent to it.",
	"-",   "This show is sub-par.  The acting is wooden, the special effects are obviously poor quality.  In general, it seems like a very cheap Star Trek ripoff.",
	"--",  "You call this Sci-Fi?  That is such a load of crap!  This show is just a soap with bad actors, piss-poor effects, and lame storylines.  Puh-leese.  ",
	);
}

