shithub: werc

Download patch

ref: 58060d803edc8696b20919a5bcb6451703965542
author: uriel <uriel@engel.se.cat-v.org>
date: Sun May 27 09:25:55 EDT 2007

Initial commit

diff: cannot open b/bin//null: file does not exist: 'b/bin//null' diff: cannot open b/etc//null: file does not exist: 'b/etc//null' diff: cannot open b/pub/cat-v//null: file does not exist: 'b/pub/cat-v//null' diff: cannot open b/pub/style//null: file does not exist: 'b/pub/style//null' diff: cannot open b/pub//null: file does not exist: 'b/pub//null' diff: cannot open b/tpl/_inc//null: file does not exist: 'b/tpl/_inc//null' diff: cannot open b/tpl/cat-v//null: file does not exist: 'b/tpl/cat-v//null' diff: cannot open b/tpl/children//null: file does not exist: 'b/tpl/children//null' diff: cannot open b/tpl/economics//null: file does not exist: 'b/tpl/economics//null' diff: cannot open b/tpl/software//null: file does not exist: 'b/tpl/software//null' diff: cannot open b/tpl//null: file does not exist: 'b/tpl//null'
--- /dev/null
+++ b/bin/controller.rc
@@ -1,0 +1,44 @@
+#!/usr/local/plan9/bin/rc
+
+path=(. ./bin $PLAN9/bin /bin/ /usr/bin)
+ifs='/' { args = `{ echo -n $REQUEST_URI | sed -e 's/[^a-zA-Z_\-\/]//g' -e 's/\?.*//' } } 
+args=`{echo $args | tr -d '
+'} 
+cd ..
+
+
+# config
+body=index
+title=Title
+template=default
+sidebar=sidebar
+
+. etc/initrc
+
+if (! ~ $#args 0 && ! ~ $args '') {
+    title=$args($#args)
+    body=`{ echo -n $"args |sed 's, ,/,g' }
+}
+
+l=tpl
+for ( i in $args ) {
+    l = $l'/'$i
+    if ( test -f $l/_config ) {
+        . $l/_config
+    }
+} 
+
+template=tpl/$template.tpl
+if (! ~ $sidebar 0) { sidebar=tpl/_inc/$sidebar.tpl }
+if (test -d tpl/$body) {
+    body=$body/index
+}
+body=`{echo tpl/^$"body^.md | sed 's, ,/,' }
+
+
+template.awk $template | rc 
+
+echo '<pre>'
+#echo $"args
+#env
+
--- /dev/null
+++ b/bin/gensitemaptxt.sh
@@ -1,0 +1,4 @@
+#!/bin/sh
+
+find . -name '*.md'|sed -e 's/\.md$//' -e 's,/index$,/,' -e 's,^\.,http://harmful.cat-v.org,'
+
--- /dev/null
+++ b/bin/markdown.pl
@@ -1,0 +1,1447 @@
+#!/usr/bin/perl
+#
+# Markdown -- A text-to-HTML conversion tool for web writers
+#
+# Copyright (c) 2004 John Gruber
+# <http://daringfireball.net/projects/markdown/>
+#
+package Markdown;
+require 5.006_000;
+use strict;
+use warnings;
+
+use Digest::MD5 qw(md5_hex);
+use vars qw($VERSION);
+$VERSION = '1.0.1';
+# Tue 14 Dec 2004
+
+## Disabled; causes problems under Perl 5.6.1:
+# use utf8;
+# binmode( STDOUT, ":utf8" );  # c.f.: http://acis.openlib.org/dev/perl-unicode-struggle.html
+
+
+#
+# Global default settings:
+#
+my $g_empty_element_suffix = " />";     # Change to ">" for HTML output
+my $g_tab_width = 4;
+
+
+#
+# Globals:
+#
+
+# Regex to match balanced [brackets]. See Friedl's
+# "Mastering Regular Expressions", 2nd Ed., pp. 328-331.
+my $g_nested_brackets;
+$g_nested_brackets = qr{
+	(?> 								# Atomic matching
+	   [^\[\]]+							# Anything other than brackets
+	 | 
+	   \[
+		 (??{ $g_nested_brackets })		# Recursive set of nested brackets
+	   \]
+	)*
+}x;
+
+
+# Table of hash values for escaped characters:
+my %g_escape_table;
+foreach my $char (split //, '\\`*_{}[]()>#+-.!') {
+	$g_escape_table{$char} = md5_hex($char);
+}
+
+
+# Global hashes, used by various utility routines
+my %g_urls;
+my %g_titles;
+my %g_html_blocks;
+
+# Used to track when we're inside an ordered or unordered list
+# (see _ProcessListItems() for details):
+my $g_list_level = 0;
+
+
+#### Blosxom plug-in interface ##########################################
+
+# Set $g_blosxom_use_meta to 1 to use Blosxom's meta plug-in to determine
+# which posts Markdown should process, using a "meta-markup: markdown"
+# header. If it's set to 0 (the default), Markdown will process all
+# entries.
+my $g_blosxom_use_meta = 0;
+
+sub start { 1; }
+sub story {
+	my($pkg, $path, $filename, $story_ref, $title_ref, $body_ref) = @_;
+
+	if ( (! $g_blosxom_use_meta) or
+	     (defined($meta::markup) and ($meta::markup =~ /^\s*markdown\s*$/i))
+	     ){
+			$$body_ref  = Markdown($$body_ref);
+     }
+     1;
+}
+
+
+#### Movable Type plug-in interface #####################################
+eval {require MT};  # Test to see if we're running in MT.
+unless ($@) {
+    require MT;
+    import  MT;
+    require MT::Template::Context;
+    import  MT::Template::Context;
+
+	eval {require MT::Plugin};  # Test to see if we're running >= MT 3.0.
+	unless ($@) {
+		require MT::Plugin;
+		import  MT::Plugin;
+		my $plugin = new MT::Plugin({
+			name => "Markdown",
+			description => "A plain-text-to-HTML formatting plugin. (Version: $VERSION)",
+			doc_link => 'http://daringfireball.net/projects/markdown/'
+		});
+		MT->add_plugin( $plugin );
+	}
+
+	MT::Template::Context->add_container_tag(MarkdownOptions => sub {
+		my $ctx	 = shift;
+		my $args = shift;
+		my $builder = $ctx->stash('builder');
+		my $tokens = $ctx->stash('tokens');
+
+		if (defined ($args->{'output'}) ) {
+			$ctx->stash('markdown_output', lc $args->{'output'});
+		}
+
+		defined (my $str = $builder->build($ctx, $tokens) )
+			or return $ctx->error($builder->errstr);
+		$str;		# return value
+	});
+
+	MT->add_text_filter('markdown' => {
+		label     => 'Markdown',
+		docs      => 'http://daringfireball.net/projects/markdown/',
+		on_format => sub {
+			my $text = shift;
+			my $ctx  = shift;
+			my $raw  = 0;
+		    if (defined $ctx) {
+		    	my $output = $ctx->stash('markdown_output'); 
+				if (defined $output  &&  $output =~ m/^html/i) {
+					$g_empty_element_suffix = ">";
+					$ctx->stash('markdown_output', '');
+				}
+				elsif (defined $output  &&  $output eq 'raw') {
+					$raw = 1;
+					$ctx->stash('markdown_output', '');
+				}
+				else {
+					$raw = 0;
+					$g_empty_element_suffix = " />";
+				}
+			}
+			$text = $raw ? $text : Markdown($text);
+			$text;
+		},
+	});
+
+	# If SmartyPants is loaded, add a combo Markdown/SmartyPants text filter:
+	my $smartypants;
+
+	{
+		no warnings "once";
+		$smartypants = $MT::Template::Context::Global_filters{'smarty_pants'};
+	}
+
+	if ($smartypants) {
+		MT->add_text_filter('markdown_with_smartypants' => {
+			label     => 'Markdown With SmartyPants',
+			docs      => 'http://daringfireball.net/projects/markdown/',
+			on_format => sub {
+				my $text = shift;
+				my $ctx  = shift;
+				if (defined $ctx) {
+					my $output = $ctx->stash('markdown_output'); 
+					if (defined $output  &&  $output eq 'html') {
+						$g_empty_element_suffix = ">";
+					}
+					else {
+						$g_empty_element_suffix = " />";
+					}
+				}
+				$text = Markdown($text);
+				$text = $smartypants->($text, '1');
+			},
+		});
+	}
+}
+else {
+#### BBEdit/command-line text filter interface ##########################
+# Needs to be hidden from MT (and Blosxom when running in static mode).
+
+    # We're only using $blosxom::version once; tell Perl not to warn us:
+	no warnings 'once';
+    unless ( defined($blosxom::version) ) {
+		use warnings;
+
+		#### Check for command-line switches: #################
+		my %cli_opts;
+		use Getopt::Long;
+		Getopt::Long::Configure('pass_through');
+		GetOptions(\%cli_opts,
+			'version',
+			'shortversion',
+			'html4tags',
+		);
+		if ($cli_opts{'version'}) {		# Version info
+			print "\nThis is Markdown, version $VERSION.\n";
+			print "Copyright 2004 John Gruber\n";
+			print "http://daringfireball.net/projects/markdown/\n\n";
+			exit 0;
+		}
+		if ($cli_opts{'shortversion'}) {		# Just the version number string.
+			print $VERSION;
+			exit 0;
+		}
+		if ($cli_opts{'html4tags'}) {			# Use HTML tag style instead of XHTML
+			$g_empty_element_suffix = ">";
+		}
+
+
+		#### Process incoming text: ###########################
+		my $text;
+		{
+			local $/;               # Slurp the whole file
+			$text = <>;
+		}
+        print Markdown($text);
+    }
+}
+
+
+
+sub Markdown {
+#
+# Main function. The order in which other subs are called here is
+# essential. Link and image substitutions need to happen before
+# _EscapeSpecialChars(), so that any *'s or _'s in the <a>
+# and <img> tags get encoded.
+#
+	my $text = shift;
+
+	# Clear the global hashes. If we don't clear these, you get conflicts
+	# from other articles when generating a page which contains more than
+	# one article (e.g. an index page that shows the N most recent
+	# articles):
+	%g_urls = ();
+	%g_titles = ();
+	%g_html_blocks = ();
+
+
+	# Standardize line endings:
+	$text =~ s{\r\n}{\n}g; 	# DOS to Unix
+	$text =~ s{\r}{\n}g; 	# Mac to Unix
+
+	# Make sure $text ends with a couple of newlines:
+	$text .= "\n\n";
+
+	# Convert all tabs to spaces.
+	$text = _Detab($text);
+
+	# Strip any lines consisting only of spaces and tabs.
+	# This makes subsequent regexen easier to write, because we can
+	# match consecutive blank lines with /\n+/ instead of something
+	# contorted like /[ \t]*\n+/ .
+	$text =~ s/^[ \t]+$//mg;
+
+	# Turn block-level HTML blocks into hash entries
+	$text = _HashHTMLBlocks($text);
+
+	# Strip link definitions, store in hashes.
+	$text = _StripLinkDefinitions($text);
+
+	$text = _RunBlockGamut($text);
+
+	$text = _UnescapeSpecialChars($text);
+
+	return $text . "\n";
+}
+
+
+sub _StripLinkDefinitions {
+#
+# Strips link definitions from text, stores the URLs and titles in
+# hash references.
+#
+	my $text = shift;
+	my $less_than_tab = $g_tab_width - 1;
+
+	# Link defs are in the form: ^[id]: url "optional title"
+	while ($text =~ s{
+						^[ ]{0,$less_than_tab}\[(.+)\]:	# id = $1
+						  [ \t]*
+						  \n?				# maybe *one* newline
+						  [ \t]*
+						<?(\S+?)>?			# url = $2
+						  [ \t]*
+						  \n?				# maybe one newline
+						  [ \t]*
+						(?:
+							(?<=\s)			# lookbehind for whitespace
+							["(]
+							(.+?)			# title = $3
+							[")]
+							[ \t]*
+						)?	# title is optional
+						(?:\n+|\Z)
+					}
+					{}mx) {
+		$g_urls{lc $1} = _EncodeAmpsAndAngles( $2 );	# Link IDs are case-insensitive
+		if ($3) {
+			$g_titles{lc $1} = $3;
+			$g_titles{lc $1} =~ s/"/&quot;/g;
+		}
+	}
+
+	return $text;
+}
+
+
+sub _HashHTMLBlocks {
+	my $text = shift;
+	my $less_than_tab = $g_tab_width - 1;
+
+	# Hashify HTML blocks:
+	# We only want to do this for block-level HTML tags, such as headers,
+	# lists, and tables. That's because we still want to wrap <p>s around
+	# "paragraphs" that are wrapped in non-block-level tags, such as anchors,
+	# phrase emphasis, and spans. The list of tags we're looking for is
+	# hard-coded:
+	my $block_tags_a = qr/p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del/;
+	my $block_tags_b = qr/p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math/;
+
+	# First, look for nested blocks, e.g.:
+	# 	<div>
+	# 		<div>
+	# 		tags for inner block must be indented.
+	# 		</div>
+	# 	</div>
+	#
+	# The outermost tags must start at the left margin for this to match, and
+	# the inner nested divs must be indented.
+	# We need to do this before the next, more liberal match, because the next
+	# match will start at the first `<div>` and stop at the first `</div>`.
+	$text =~ s{
+				(						# save in $1
+					^					# start of line  (with /m)
+					<($block_tags_a)	# start tag = $2
+					\b					# word break
+					(.*\n)*?			# any number of lines, minimally matching
+					</\2>				# the matching end tag
+					[ \t]*				# trailing spaces/tabs
+					(?=\n+|\Z)	# followed by a newline or end of document
+				)
+			}{
+				my $key = md5_hex($1);
+				$g_html_blocks{$key} = $1;
+				"\n\n" . $key . "\n\n";
+			}egmx;
+
+
+	#
+	# Now match more liberally, simply from `\n<tag>` to `</tag>\n`
+	#
+	$text =~ s{
+				(						# save in $1
+					^					# start of line  (with /m)
+					<($block_tags_b)	# start tag = $2
+					\b					# word break
+					(.*\n)*?			# any number of lines, minimally matching
+					.*</\2>				# the matching end tag
+					[ \t]*				# trailing spaces/tabs
+					(?=\n+|\Z)	# followed by a newline or end of document
+				)
+			}{
+				my $key = md5_hex($1);
+				$g_html_blocks{$key} = $1;
+				"\n\n" . $key . "\n\n";
+			}egmx;
+	# Special case just for <hr />. It was easier to make a special case than
+	# to make the other regex more complicated.	
+	$text =~ s{
+				(?:
+					(?<=\n\n)		# Starting after a blank line
+					|				# or
+					\A\n?			# the beginning of the doc
+				)
+				(						# save in $1
+					[ ]{0,$less_than_tab}
+					<(hr)				# start tag = $2
+					\b					# word break
+					([^<>])*?			# 
+					/?>					# the matching end tag
+					[ \t]*
+					(?=\n{2,}|\Z)		# followed by a blank line or end of document
+				)
+			}{
+				my $key = md5_hex($1);
+				$g_html_blocks{$key} = $1;
+				"\n\n" . $key . "\n\n";
+			}egx;
+
+	# Special case for standalone HTML comments:
+	$text =~ s{
+				(?:
+					(?<=\n\n)		# Starting after a blank line
+					|				# or
+					\A\n?			# the beginning of the doc
+				)
+				(						# save in $1
+					[ ]{0,$less_than_tab}
+					(?s:
+						<!
+						(--.*?--\s*)+
+						>
+					)
+					[ \t]*
+					(?=\n{2,}|\Z)		# followed by a blank line or end of document
+				)
+			}{
+				my $key = md5_hex($1);
+				$g_html_blocks{$key} = $1;
+				"\n\n" . $key . "\n\n";
+			}egx;
+
+
+	return $text;
+}
+
+
+sub _RunBlockGamut {
+#
+# These are all the transformations that form block-level
+# tags like paragraphs, headers, and list items.
+#
+	my $text = shift;
+
+	$text = _DoHeaders($text);
+
+	# Do Horizontal Rules:
+	$text =~ s{^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$}{\n<hr$g_empty_element_suffix\n}gmx;
+	$text =~ s{^[ ]{0,2}([ ]? -[ ]?){3,}[ \t]*$}{\n<hr$g_empty_element_suffix\n}gmx;
+	$text =~ s{^[ ]{0,2}([ ]? _[ ]?){3,}[ \t]*$}{\n<hr$g_empty_element_suffix\n}gmx;
+
+	$text = _DoLists($text);
+
+	$text = _DoCodeBlocks($text);
+
+	$text = _DoBlockQuotes($text);
+
+	# We already ran _HashHTMLBlocks() before, in Markdown(), but that
+	# was to escape raw HTML in the original Markdown source. This time,
+	# we're escaping the markup we've just created, so that we don't wrap
+	# <p> tags around block-level tags.
+	$text = _HashHTMLBlocks($text);
+
+	$text = _FormParagraphs($text);
+
+	return $text;
+}
+
+
+sub _RunSpanGamut {
+#
+# These are all the transformations that occur *within* block-level
+# tags like paragraphs, headers, and list items.
+#
+	my $text = shift;
+
+	$text = _DoCodeSpans($text);
+
+	$text = _EscapeSpecialChars($text);
+
+	# Process anchor and image tags. Images must come first,
+	# because ![foo][f] looks like an anchor.
+	$text = _DoImages($text);
+	$text = _DoAnchors($text);
+
+	# Make links out of things like `<http://example.com/>`
+	# Must come after _DoAnchors(), because you can use < and >
+	# delimiters in inline links like [this](<url>).
+	$text = _DoAutoLinks($text);
+
+	$text = _EncodeAmpsAndAngles($text);
+
+	$text = _DoItalicsAndBold($text);
+
+	# Do hard breaks:
+	$text =~ s/ {2,}\n/ <br$g_empty_element_suffix\n/g;
+
+	return $text;
+}
+
+
+sub _EscapeSpecialChars {
+	my $text = shift;
+	my $tokens ||= _TokenizeHTML($text);
+
+	$text = '';   # rebuild $text from the tokens
+# 	my $in_pre = 0;	 # Keep track of when we're inside <pre> or <code> tags.
+# 	my $tags_to_skip = qr!<(/?)(?:pre|code|kbd|script|math)[\s>]!;
+
+	foreach my $cur_token (@$tokens) {
+		if ($cur_token->[0] eq "tag") {
+			# Within tags, encode * and _ so they don't conflict
+			# with their use in Markdown for italics and strong.
+			# We're replacing each such character with its
+			# corresponding MD5 checksum value; this is likely
+			# overkill, but it should prevent us from colliding
+			# with the escape values by accident.
+			$cur_token->[1] =~  s! \* !$g_escape_table{'*'}!gx;
+			$cur_token->[1] =~  s! _  !$g_escape_table{'_'}!gx;
+			$text .= $cur_token->[1];
+		} else {
+			my $t = $cur_token->[1];
+			$t = _EncodeBackslashEscapes($t);
+			$text .= $t;
+		}
+	}
+	return $text;
+}
+
+
+sub _DoAnchors {
+#
+# Turn Markdown link shortcuts into XHTML <a> tags.
+#
+	my $text = shift;
+
+	#
+	# First, handle reference-style links: [link text] [id]
+	#
+	$text =~ s{
+		(					# wrap whole match in $1
+		  \[
+		    ($g_nested_brackets)	# link text = $2
+		  \]
+
+		  [ ]?				# one optional space
+		  (?:\n[ ]*)?		# one optional newline followed by spaces
+
+		  \[
+		    (.*?)		# id = $3
+		  \]
+		)
+	}{
+		my $result;
+		my $whole_match = $1;
+		my $link_text   = $2;
+		my $link_id     = lc $3;
+
+		if ($link_id eq "") {
+			$link_id = lc $link_text;     # for shortcut links like [this][].
+		}
+
+		if (defined $g_urls{$link_id}) {
+			my $url = $g_urls{$link_id};
+			$url =~ s! \* !$g_escape_table{'*'}!gx;		# We've got to encode these to avoid
+			$url =~ s!  _ !$g_escape_table{'_'}!gx;		# conflicting with italics/bold.
+			$result = "<a href=\"$url\"";
+			if ( defined $g_titles{$link_id} ) {
+				my $title = $g_titles{$link_id};
+				$title =~ s! \* !$g_escape_table{'*'}!gx;
+				$title =~ s!  _ !$g_escape_table{'_'}!gx;
+				$result .=  " title=\"$title\"";
+			}
+			$result .= ">$link_text</a>";
+		}
+		else {
+			$result = $whole_match;
+		}
+		$result;
+	}xsge;
+
+	#
+	# Next, inline-style links: [link text](url "optional title")
+	#
+	$text =~ s{
+		(				# wrap whole match in $1
+		  \[
+		    ($g_nested_brackets)	# link text = $2
+		  \]
+		  \(			# literal paren
+		  	[ \t]*
+			<?(.*?)>?	# href = $3
+		  	[ \t]*
+			(			# $4
+			  (['"])	# quote char = $5
+			  (.*?)		# Title = $6
+			  \5		# matching quote
+			)?			# title is optional
+		  \)
+		)
+	}{
+		my $result;
+		my $whole_match = $1;
+		my $link_text   = $2;
+		my $url	  		= $3;
+		my $title		= $6;
+
+		$url =~ s! \* !$g_escape_table{'*'}!gx;		# We've got to encode these to avoid
+		$url =~ s!  _ !$g_escape_table{'_'}!gx;		# conflicting with italics/bold.
+		$result = "<a href=\"$url\"";
+
+		if (defined $title) {
+			$title =~ s/"/&quot;/g;
+			$title =~ s! \* !$g_escape_table{'*'}!gx;
+			$title =~ s!  _ !$g_escape_table{'_'}!gx;
+			$result .=  " title=\"$title\"";
+		}
+
+		$result .= ">$link_text</a>";
+
+		$result;
+	}xsge;
+
+	return $text;
+}
+
+
+sub _DoImages {
+#
+# Turn Markdown image shortcuts into <img> tags.
+#
+	my $text = shift;
+
+	#
+	# First, handle reference-style labeled images: ![alt text][id]
+	#
+	$text =~ s{
+		(				# wrap whole match in $1
+		  !\[
+		    (.*?)		# alt text = $2
+		  \]
+
+		  [ ]?				# one optional space
+		  (?:\n[ ]*)?		# one optional newline followed by spaces
+
+		  \[
+		    (.*?)		# id = $3
+		  \]
+
+		)
+	}{
+		my $result;
+		my $whole_match = $1;
+		my $alt_text    = $2;
+		my $link_id     = lc $3;
+
+		if ($link_id eq "") {
+			$link_id = lc $alt_text;     # for shortcut links like ![this][].
+		}
+
+		$alt_text =~ s/"/&quot;/g;
+		if (defined $g_urls{$link_id}) {
+			my $url = $g_urls{$link_id};
+			$url =~ s! \* !$g_escape_table{'*'}!gx;		# We've got to encode these to avoid
+			$url =~ s!  _ !$g_escape_table{'_'}!gx;		# conflicting with italics/bold.
+			$result = "<img src=\"$url\" alt=\"$alt_text\"";
+			if (defined $g_titles{$link_id}) {
+				my $title = $g_titles{$link_id};
+				$title =~ s! \* !$g_escape_table{'*'}!gx;
+				$title =~ s!  _ !$g_escape_table{'_'}!gx;
+				$result .=  " title=\"$title\"";
+			}
+			$result .= $g_empty_element_suffix;
+		}
+		else {
+			# If there's no such link ID, leave intact:
+			$result = $whole_match;
+		}
+
+		$result;
+	}xsge;
+
+	#
+	# Next, handle inline images:  ![alt text](url "optional title")
+	# Don't forget: encode * and _
+
+	$text =~ s{
+		(				# wrap whole match in $1
+		  !\[
+		    (.*?)		# alt text = $2
+		  \]
+		  \(			# literal paren
+		  	[ \t]*
+			<?(\S+?)>?	# src url = $3
+		  	[ \t]*
+			(			# $4
+			  (['"])	# quote char = $5
+			  (.*?)		# title = $6
+			  \5		# matching quote
+			  [ \t]*
+			)?			# title is optional
+		  \)
+		)
+	}{
+		my $result;
+		my $whole_match = $1;
+		my $alt_text    = $2;
+		my $url	  		= $3;
+		my $title		= '';
+		if (defined($6)) {
+			$title		= $6;
+		}
+
+		$alt_text =~ s/"/&quot;/g;
+		$title    =~ s/"/&quot;/g;
+		$url =~ s! \* !$g_escape_table{'*'}!gx;		# We've got to encode these to avoid
+		$url =~ s!  _ !$g_escape_table{'_'}!gx;		# conflicting with italics/bold.
+		$result = "<img src=\"$url\" alt=\"$alt_text\"";
+		if (defined $title) {
+			$title =~ s! \* !$g_escape_table{'*'}!gx;
+			$title =~ s!  _ !$g_escape_table{'_'}!gx;
+			$result .=  " title=\"$title\"";
+		}
+		$result .= $g_empty_element_suffix;
+
+		$result;
+	}xsge;
+
+	return $text;
+}
+
+
+sub _DoHeaders {
+	my $text = shift;
+
+	# Setext-style headers:
+	#	  Header 1
+	#	  ========
+	#  
+	#	  Header 2
+	#	  --------
+	#
+	$text =~ s{ ^(.+)[ \t]*\n=+[ \t]*\n+ }{
+		"<h1>"  .  _RunSpanGamut($1)  .  "</h1>\n\n";
+	}egmx;
+
+	$text =~ s{ ^(.+)[ \t]*\n-+[ \t]*\n+ }{
+		"<h2>"  .  _RunSpanGamut($1)  .  "</h2>\n\n";
+	}egmx;
+
+
+	# atx-style headers:
+	#	# Header 1
+	#	## Header 2
+	#	## Header 2 with closing hashes ##
+	#	...
+	#	###### Header 6
+	#
+	$text =~ s{
+			^(\#{1,6})	# $1 = string of #'s
+			[ \t]*
+			(.+?)		# $2 = Header text
+			[ \t]*
+			\#*			# optional closing #'s (not counted)
+			\n+
+		}{
+			my $h_level = length($1);
+			"<h$h_level>"  .  _RunSpanGamut($2)  .  "</h$h_level>\n\n";
+		}egmx;
+
+	return $text;
+}
+
+
+sub _DoLists {
+#
+# Form HTML ordered (numbered) and unordered (bulleted) lists.
+#
+	my $text = shift;
+	my $less_than_tab = $g_tab_width - 1;
+
+	# Re-usable patterns to match list item bullets and number markers:
+	my $marker_ul  = qr/[*+-]/;
+	my $marker_ol  = qr/\d+[.]/;
+	my $marker_any = qr/(?:$marker_ul|$marker_ol)/;
+
+	# Re-usable pattern to match any entirel ul or ol list:
+	my $whole_list = qr{
+		(								# $1 = whole list
+		  (								# $2
+			[ ]{0,$less_than_tab}
+			(${marker_any})				# $3 = first list item marker
+			[ \t]+
+		  )
+		  (?s:.+?)
+		  (								# $4
+			  \z
+			|
+			  \n{2,}
+			  (?=\S)
+			  (?!						# Negative lookahead for another list item marker
+				[ \t]*
+				${marker_any}[ \t]+
+			  )
+		  )
+		)
+	}mx;
+
+	# We use a different prefix before nested lists than top-level lists.
+	# See extended comment in _ProcessListItems().
+	#
+	# Note: There's a bit of duplication here. My original implementation
+	# created a scalar regex pattern as the conditional result of the test on
+	# $g_list_level, and then only ran the $text =~ s{...}{...}egmx
+	# substitution once, using the scalar as the pattern. This worked,
+	# everywhere except when running under MT on my hosting account at Pair
+	# Networks. There, this caused all rebuilds to be killed by the reaper (or
+	# perhaps they crashed, but that seems incredibly unlikely given that the
+	# same script on the same server ran fine *except* under MT. I've spent
+	# more time trying to figure out why this is happening than I'd like to
+	# admit. My only guess, backed up by the fact that this workaround works,
+	# is that Perl optimizes the substition when it can figure out that the
+	# pattern will never change, and when this optimization isn't on, we run
+	# afoul of the reaper. Thus, the slightly redundant code to that uses two
+	# static s/// patterns rather than one conditional pattern.
+
+	if ($g_list_level) {
+		$text =~ s{
+				^
+				$whole_list
+			}{
+				my $list = $1;
+				my $list_type = ($3 =~ m/$marker_ul/) ? "ul" : "ol";
+				# Turn double returns into triple returns, so that we can make a
+				# paragraph for the last item in a list, if necessary:
+				$list =~ s/\n{2,}/\n\n\n/g;
+				my $result = _ProcessListItems($list, $marker_any);
+				$result = "<$list_type>\n" . $result . "</$list_type>\n";
+				$result;
+			}egmx;
+	}
+	else {
+		$text =~ s{
+				(?:(?<=\n\n)|\A\n?)
+				$whole_list
+			}{
+				my $list = $1;
+				my $list_type = ($3 =~ m/$marker_ul/) ? "ul" : "ol";
+				# Turn double returns into triple returns, so that we can make a
+				# paragraph for the last item in a list, if necessary:
+				$list =~ s/\n{2,}/\n\n\n/g;
+				my $result = _ProcessListItems($list, $marker_any);
+				$result = "<$list_type>\n" . $result . "</$list_type>\n";
+				$result;
+			}egmx;
+	}
+
+
+	return $text;
+}
+
+
+sub _ProcessListItems {
+#
+#	Process the contents of a single ordered or unordered list, splitting it
+#	into individual list items.
+#
+
+	my $list_str = shift;
+	my $marker_any = shift;
+
+
+	# The $g_list_level global keeps track of when we're inside a list.
+	# Each time we enter a list, we increment it; when we leave a list,
+	# we decrement. If it's zero, we're not in a list anymore.
+	#
+	# We do this because when we're not inside a list, we want to treat
+	# something like this:
+	#
+	#		I recommend upgrading to version
+	#		8. Oops, now this line is treated
+	#		as a sub-list.
+	#
+	# As a single paragraph, despite the fact that the second line starts
+	# with a digit-period-space sequence.
+	#
+	# Whereas when we're inside a list (or sub-list), that line will be
+	# treated as the start of a sub-list. What a kludge, huh? This is
+	# an aspect of Markdown's syntax that's hard to parse perfectly
+	# without resorting to mind-reading. Perhaps the solution is to
+	# change the syntax rules such that sub-lists must start with a
+	# starting cardinal number; e.g. "1." or "a.".
+
+	$g_list_level++;
+
+	# trim trailing blank lines:
+	$list_str =~ s/\n{2,}\z/\n/;
+
+
+	$list_str =~ s{
+		(\n)?							# leading line = $1
+		(^[ \t]*)						# leading whitespace = $2
+		($marker_any) [ \t]+			# list marker = $3
+		((?s:.+?)						# list item text   = $4
+		(\n{1,2}))
+		(?= \n* (\z | \2 ($marker_any) [ \t]+))
+	}{
+		my $item = $4;
+		my $leading_line = $1;
+		my $leading_space = $2;
+
+		if ($leading_line or ($item =~ m/\n{2,}/)) {
+			$item = _RunBlockGamut(_Outdent($item));
+		}
+		else {
+			# Recursion for sub-lists:
+			$item = _DoLists(_Outdent($item));
+			chomp $item;
+			$item = _RunSpanGamut($item);
+		}
+
+		"<li>" . $item . "</li>\n";
+	}egmx;
+
+	$g_list_level--;
+	return $list_str;
+}
+
+
+
+sub _DoCodeBlocks {
+#
+#	Process Markdown `<pre><code>` blocks.
+#	
+
+	my $text = shift;
+
+	$text =~ s{
+			(?:\n\n|\A)
+			(	            # $1 = the code block -- one or more lines, starting with a space/tab
+			  (?:
+			    (?:[ ]{$g_tab_width} | \t)  # Lines must start with a tab or a tab-width of spaces
+			    .*\n+
+			  )+
+			)
+			((?=^[ ]{0,$g_tab_width}\S)|\Z)	# Lookahead for non-space at line-start, or end of doc
+		}{
+			my $codeblock = $1;
+			my $result; # return value
+
+			$codeblock = _EncodeCode(_Outdent($codeblock));
+			$codeblock = _Detab($codeblock);
+			$codeblock =~ s/\A\n+//; # trim leading newlines
+			$codeblock =~ s/\s+\z//; # trim trailing whitespace
+
+			$result = "\n\n<pre><code>" . $codeblock . "\n</code></pre>\n\n";
+
+			$result;
+		}egmx;
+
+	return $text;
+}
+
+
+sub _DoCodeSpans {
+#
+# 	*	Backtick quotes are used for <code></code> spans.
+# 
+# 	*	You can use multiple backticks as the delimiters if you want to
+# 		include literal backticks in the code span. So, this input:
+#     
+#         Just type ``foo `bar` baz`` at the prompt.
+#     
+#     	Will translate to:
+#     
+#         <p>Just type <code>foo `bar` baz</code> at the prompt.</p>
+#     
+#		There's no arbitrary limit to the number of backticks you
+#		can use as delimters. If you need three consecutive backticks
+#		in your code, use four for delimiters, etc.
+#
+#	*	You can use spaces to get literal backticks at the edges:
+#     
+#         ... type `` `bar` `` ...
+#     
+#     	Turns to:
+#     
+#         ... type <code>`bar`</code> ...
+#
+
+	my $text = shift;
+
+	$text =~ s@
+			(`+)		# $1 = Opening run of `
+			(.+?)		# $2 = The code block
+			(?<!`)
+			\1			# Matching closer
+			(?!`)
+		@
+ 			my $c = "$2";
+ 			$c =~ s/^[ \t]*//g; # leading whitespace
+ 			$c =~ s/[ \t]*$//g; # trailing whitespace
+ 			$c = _EncodeCode($c);
+			"<code>$c</code>";
+		@egsx;
+
+	return $text;
+}
+
+
+sub _EncodeCode {
+#
+# Encode/escape certain characters inside Markdown code runs.
+# The point is that in code, these characters are literals,
+# and lose their special Markdown meanings.
+#
+    local $_ = shift;
+
+	# Encode all ampersands; HTML entities are not
+	# entities within a Markdown code span.
+	s/&/&amp;/g;
+
+	# Encode $'s, but only if we're running under Blosxom.
+	# (Blosxom interpolates Perl variables in article bodies.)
+	{
+		no warnings 'once';
+    	if (defined($blosxom::version)) {
+    		s/\$/&#036;/g;	
+    	}
+    }
+
+
+	# Do the angle bracket song and dance:
+	s! <  !&lt;!gx;
+	s! >  !&gt;!gx;
+
+	# Now, escape characters that are magic in Markdown:
+	s! \* !$g_escape_table{'*'}!gx;
+	s! _  !$g_escape_table{'_'}!gx;
+	s! {  !$g_escape_table{'{'}!gx;
+	s! }  !$g_escape_table{'}'}!gx;
+	s! \[ !$g_escape_table{'['}!gx;
+	s! \] !$g_escape_table{']'}!gx;
+	s! \\ !$g_escape_table{'\\'}!gx;
+
+	return $_;
+}
+
+
+sub _DoItalicsAndBold {
+	my $text = shift;
+
+	# <strong> must go first:
+	$text =~ s{ (\*\*|__) (?=\S) (.+?[*_]*) (?<=\S) \1 }
+		{<strong>$2</strong>}gsx;
+
+	$text =~ s{ (\*|_) (?=\S) (.+?) (?<=\S) \1 }
+		{<em>$2</em>}gsx;
+
+	return $text;
+}
+
+
+sub _DoBlockQuotes {
+	my $text = shift;
+
+	$text =~ s{
+		  (								# Wrap whole match in $1
+			(
+			  ^[ \t]*>[ \t]?			# '>' at the start of a line
+			    .+\n					# rest of the first line
+			  (.+\n)*					# subsequent consecutive lines
+			  \n*						# blanks
+			)+
+		  )
+		}{
+			my $bq = $1;
+			$bq =~ s/^[ \t]*>[ \t]?//gm;	# trim one level of quoting
+			$bq =~ s/^[ \t]+$//mg;			# trim whitespace-only lines
+			$bq = _RunBlockGamut($bq);		# recurse
+
+			$bq =~ s/^/  /g;
+			# These leading spaces screw with <pre> content, so we need to fix that:
+			$bq =~ s{
+					(\s*<pre>.+?</pre>)
+				}{
+					my $pre = $1;
+					$pre =~ s/^  //mg;
+					$pre;
+				}egsx;
+
+			"<blockquote>\n$bq\n</blockquote>\n\n";
+		}egmx;
+
+
+	return $text;
+}
+
+
+sub _FormParagraphs {
+#
+#	Params:
+#		$text - string to process with html <p> tags
+#
+	my $text = shift;
+
+	# Strip leading and trailing lines:
+	$text =~ s/\A\n+//;
+	$text =~ s/\n+\z//;
+
+	my @grafs = split(/\n{2,}/, $text);
+
+	#
+	# Wrap <p> tags.
+	#
+	foreach (@grafs) {
+		unless (defined( $g_html_blocks{$_} )) {
+			$_ = _RunSpanGamut($_);
+			s/^([ \t]*)/<p>/;
+			$_ .= "</p>";
+		}
+	}
+
+	#
+	# Unhashify HTML blocks
+	#
+	foreach (@grafs) {
+		if (defined( $g_html_blocks{$_} )) {
+			$_ = $g_html_blocks{$_};
+		}
+	}
+
+	return join "\n\n", @grafs;
+}
+
+
+sub _EncodeAmpsAndAngles {
+# Smart processing for ampersands and angle brackets that need to be encoded.
+
+	my $text = shift;
+
+	# Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin:
+	#   http://bumppo.net/projects/amputator/
+ 	$text =~ s/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/&amp;/g;
+
+	# Encode naked <'s
+ 	$text =~ s{<(?![a-z/?\$!])}{&lt;}gi;
+
+	return $text;
+}
+
+
+sub _EncodeBackslashEscapes {
+#
+#   Parameter:  String.
+#   Returns:    The string, with after processing the following backslash
+#               escape sequences.
+#
+    local $_ = shift;
+
+    s! \\\\  !$g_escape_table{'\\'}!gx;		# Must process escaped backslashes first.
+    s! \\`   !$g_escape_table{'`'}!gx;
+    s! \\\*  !$g_escape_table{'*'}!gx;
+    s! \\_   !$g_escape_table{'_'}!gx;
+    s! \\\{  !$g_escape_table{'{'}!gx;
+    s! \\\}  !$g_escape_table{'}'}!gx;
+    s! \\\[  !$g_escape_table{'['}!gx;
+    s! \\\]  !$g_escape_table{']'}!gx;
+    s! \\\(  !$g_escape_table{'('}!gx;
+    s! \\\)  !$g_escape_table{')'}!gx;
+    s! \\>   !$g_escape_table{'>'}!gx;
+    s! \\\#  !$g_escape_table{'#'}!gx;
+    s! \\\+  !$g_escape_table{'+'}!gx;
+    s! \\\-  !$g_escape_table{'-'}!gx;
+    s! \\\.  !$g_escape_table{'.'}!gx;
+    s{ \\!  }{$g_escape_table{'!'}}gx;
+
+    return $_;
+}
+
+
+sub _DoAutoLinks {
+	my $text = shift;
+
+	$text =~ s{<((https?|ftp):[^'">\s]+)>}{<a href="$1">$1</a>}gi;
+
+	# Email addresses: <address@domain.foo>
+	$text =~ s{
+		<
+        (?:mailto:)?
+		(
+			[-.\w]+
+			\@
+			[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+
+		)
+		>
+	}{
+		_EncodeEmailAddress( _UnescapeSpecialChars($1) );
+	}egix;
+
+	return $text;
+}
+
+
+sub _EncodeEmailAddress {
+#
+#	Input: an email address, e.g. "foo@example.com"
+#
+#	Output: the email address as a mailto link, with each character
+#		of the address encoded as either a decimal or hex entity, in
+#		the hopes of foiling most address harvesting spam bots. E.g.:
+#
+#	  <a href="&#x6D;&#97;&#105;&#108;&#x74;&#111;:&#102;&#111;&#111;&#64;&#101;
+#       x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;">&#102;&#111;&#111;
+#       &#64;&#101;x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;</a>
+#
+#	Based on a filter by Matthew Wickline, posted to the BBEdit-Talk
+#	mailing list: <http://tinyurl.com/yu7ue>
+#
+
+	my $addr = shift;
+
+	srand;
+	my @encode = (
+		sub { '&#' .                 ord(shift)   . ';' },
+		sub { '&#x' . sprintf( "%X", ord(shift) ) . ';' },
+		sub {                            shift          },
+	);
+
+	$addr = "mailto:" . $addr;
+
+	$addr =~ s{(.)}{
+		my $char = $1;
+		if ( $char eq '@' ) {
+			# this *must* be encoded. I insist.
+			$char = $encode[int rand 1]->($char);
+		} elsif ( $char ne ':' ) {
+			# leave ':' alone (to spot mailto: later)
+			my $r = rand;
+			# roughly 10% raw, 45% hex, 45% dec
+			$char = (
+				$r > .9   ?  $encode[2]->($char)  :
+				$r < .45  ?  $encode[1]->($char)  :
+							 $encode[0]->($char)
+			);
+		}
+		$char;
+	}gex;
+
+	$addr = qq{<a href="$addr">$addr</a>};
+	$addr =~ s{">.+?:}{">}; # strip the mailto: from the visible part
+
+	return $addr;
+}
+
+
+sub _UnescapeSpecialChars {
+#
+# Swap back in all the special characters we've hidden.
+#
+	my $text = shift;
+
+	while( my($char, $hash) = each(%g_escape_table) ) {
+		$text =~ s/$hash/$char/g;
+	}
+    return $text;
+}
+
+
+sub _TokenizeHTML {
+#
+#   Parameter:  String containing HTML markup.
+#   Returns:    Reference to an array of the tokens comprising the input
+#               string. Each token is either a tag (possibly with nested,
+#               tags contained therein, such as <a href="<MTFoo>">, or a
+#               run of text between tags. Each element of the array is a
+#               two-element array; the first is either 'tag' or 'text';
+#               the second is the actual value.
+#
+#
+#   Derived from the _tokenize() subroutine from Brad Choate's MTRegex plugin.
+#       <http://www.bradchoate.com/past/mtregex.php>
+#
+
+    my $str = shift;
+    my $pos = 0;
+    my $len = length $str;
+    my @tokens;
+
+    my $depth = 6;
+    my $nested_tags = join('|', ('(?:<[a-z/!$](?:[^<>]') x $depth) . (')*>)' x  $depth);
+    my $match = qr/(?s: <! ( -- .*? -- \s* )+ > ) |  # comment
+                   (?s: <\? .*? \?> ) |              # processing instruction
+                   $nested_tags/ix;                   # nested tags
+
+    while ($str =~ m/($match)/g) {
+        my $whole_tag = $1;
+        my $sec_start = pos $str;
+        my $tag_start = $sec_start - length $whole_tag;
+        if ($pos < $tag_start) {
+            push @tokens, ['text', substr($str, $pos, $tag_start - $pos)];
+        }
+        push @tokens, ['tag', $whole_tag];
+        $pos = pos $str;
+    }
+    push @tokens, ['text', substr($str, $pos, $len - $pos)] if $pos < $len;
+    \@tokens;
+}
+
+
+sub _Outdent {
+#
+# Remove one level of line-leading tabs or spaces
+#
+	my $text = shift;
+
+	$text =~ s/^(\t|[ ]{1,$g_tab_width})//gm;
+	return $text;
+}
+
+
+sub _Detab {
+#
+# Cribbed from a post by Bart Lateur:
+# <http://www.nntp.perl.org/group/perl.macperl.anyperl/154>
+#
+	my $text = shift;
+
+	$text =~ s{(.*?)\t}{$1.(' ' x ($g_tab_width - length($1) % $g_tab_width))}ge;
+	return $text;
+}
+
+
+1;
+
+__END__
+
+
+=pod
+
+=head1 NAME
+
+B<Markdown>
+
+
+=head1 SYNOPSIS
+
+B<Markdown.pl> [ B<--html4tags> ] [ B<--version> ] [ B<-shortversion> ]
+    [ I<file> ... ]
+
+
+=head1 DESCRIPTION
+
+Markdown is a text-to-HTML filter; it translates an easy-to-read /
+easy-to-write structured text format into HTML. Markdown's text format
+is most similar to that of plain text email, and supports features such
+as headers, *emphasis*, code blocks, blockquotes, and links.
+
+Markdown's syntax is designed not as a generic markup language, but
+specifically to serve as a front-end to (X)HTML. You can  use span-level
+HTML tags anywhere in a Markdown document, and you can use block level
+HTML tags (like <div> and <table> as well).
+
+For more information about Markdown's syntax, see:
+
+    http://daringfireball.net/projects/markdown/
+
+
+=head1 OPTIONS
+
+Use "--" to end switch parsing. For example, to open a file named "-z", use:
+
+	Markdown.pl -- -z
+
+=over 4
+
+
+=item B<--html4tags>
+
+Use HTML 4 style for empty element tags, e.g.:
+
+    <br>
+
+instead of Markdown's default XHTML style tags, e.g.:
+
+    <br />
+
+
+=item B<-v>, B<--version>
+
+Display Markdown's version number and copyright information.
+
+
+=item B<-s>, B<--shortversion>
+
+Display the short-form version number.
+
+
+=back
+
+
+
+=head1 BUGS
+
+To file bug reports or feature requests (other than topics listed in the
+Caveats section above) please send email to:
+
+    support@daringfireball.net
+
+Please include with your report: (1) the example input; (2) the output
+you expected; (3) the output Markdown actually produced.
+
+
+=head1 VERSION HISTORY
+
+See the readme file for detailed release notes for this version.
+
+1.0.1 - 14 Dec 2004
+
+1.0 - 28 Aug 2004
+
+
+=head1 AUTHOR
+
+    John Gruber
+    http://daringfireball.net
+
+    PHP port and other contributions by Michel Fortin
+    http://michelf.com
+
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (c) 2003-2004 John Gruber   
+<http://daringfireball.net/>   
+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 the name "Markdown" 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 copyright owner
+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.
+
+=cut
--- /dev/null
+++ b/bin/template.awk
@@ -1,0 +1,55 @@
+#!/usr/bin/awk -f
+function pr(str) {
+	if(lastc !~ "[{(]")
+		gsub(/'/, "''", str)
+	printf "%s", str
+}
+function trans(c) {
+	printf "%s", end
+
+	lastc = c
+	end = "\n"
+	if(c == "%")
+		end = ""
+	else if(c == "(")
+		printf "echo -n "
+	else if(c ~ "[})]") {
+		end = "'\n"
+		printf "echo -n '"
+	}
+}
+
+BEGIN {
+	lastc = "{"
+	trans("}")
+}
+END {
+	print end
+}
+
+/^%/ && $0 !~ /^%[{()}%]/ && lastc !~ /[({]/ {
+	trans("%")
+	print substr($0, 2)
+	next
+}
+{
+	if(lastc == "%")
+		trans("}")
+	n = split($0, a, "%")
+	pr(a[1])
+	for(i=2; i<=n; i++) {
+		c = substr(a[i], 1, 1)
+		rest = substr(a[i], 2)
+
+		if((lastc !~ "[({]" && c ~ "[({]") ||
+		   (lastc == "{" && c == "}") ||
+		   (lastc == "(" && c == ")"))
+			trans(c)
+		else if(c == "%")
+			pr("%")
+		else
+			pr("%" c)
+		pr(rest)
+	}
+	pr("\n")
+}
--- /dev/null
+++ b/bin/urldecode.awk
@@ -1,0 +1,39 @@
+#!/usr/bin/awk -f
+BEGIN {
+	hextab ["0"] = 0; hextab ["8"] = 8;
+	hextab ["1"] = 1; hextab ["9"] = 9;
+	hextab ["2"] = 2; hextab ["A"] = hextab ["a"] = 10
+	hextab ["3"] = 3; hextab ["B"] = hextab ["b"] = 11;
+	hextab ["4"] = 4; hextab ["C"] = hextab ["c"] = 12;
+	hextab ["5"] = 5; hextab ["D"] = hextab ["d"] = 13;
+	hextab ["6"] = 6; hextab ["E"] = hextab ["e"] = 14;
+	hextab ["7"] = 7; hextab ["F"] = hextab ["f"] = 15;
+}
+{
+	decoded = ""
+	i   = 1
+	len = length ($0)
+	while ( i <= len ) {
+		c = substr ($0, i, 1)
+		if ( c == "%" ) {
+			if ( i+2 <= len ) {
+				c1 = substr ($0, i+1, 1)
+				c2 = substr ($0, i+2, 1)
+				if ( hextab [c1] == "" || hextab [c2] == "" ) {
+					print "WARNING: invalid hex encoding: %" c1 c2 | "cat >&2"
+				} else {
+					code = 0 + hextab [c1] * 16 + hextab [c2] + 0
+					c = sprintf ("%c", code)
+					i = i + 2
+				}
+			} else {
+				print "WARNING: invalid % encoding: " substr ($0, i, len - i)
+			}
+		} else if ( c == "+" ) {
+			c = " "
+		}
+		decoded = decoded c
+		++i
+	}
+	print decoded
+}
--- /dev/null
+++ b/etc/initrc
@@ -1,0 +1,1 @@
+title=cat-v.org
binary files /dev/null b/pub/cat-v/unix_prog_design.pdf differ
--- /dev/null
+++ b/pub/cat-v/unix_prog_design.ps
@@ -1,0 +1,1055 @@
+%!PS-Adobe-2.0
+%%Copyright: Copyright (c) 1993 AT&T, All Rights Reserved
+%%Version: 3.4
+%%DocumentFonts: (atend)
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+/DpostDict 200 dict def
+DpostDict begin
+%
+% Copyright (c) 1993 AT&T, All Rights Reserved
+%
+% Version 3.4 prologue for troff files.
+%
+
+/#copies 1 store
+/Prologue (dpost.ps) def
+/aspectratio 1 def
+/formsperpage 1 def
+/landscape false def
+/linewidth .3 def
+/magnification 1 def
+/margin 0 def
+/orientation 0 def
+/resolution 720 def
+/rotation 1 def
+/xoffset 0 def
+/yoffset 0 def
+
+/roundpage true def
+/useclippath true def
+/pagebbox [0 0 612 792] def
+
+/R  /Times-Roman def
+/I  /Times-Italic def
+/B  /Times-Bold def
+/BI /Times-BoldItalic def
+/H  /Helvetica def
+/HI /Helvetica-Oblique def
+/HB /Helvetica-Bold def
+/HX /Helvetica-BoldOblique def
+/CW /Courier def
+/CO /Courier def
+/CI /Courier-Oblique def
+/CB /Courier-Bold def
+/CX /Courier-BoldOblique def
+/PA /Palatino-Roman def
+/PI /Palatino-Italic def
+/PB /Palatino-Bold def
+/PX /Palatino-BoldItalic def
+/Hr /Helvetica-Narrow def
+/Hi /Helvetica-Narrow-Oblique def
+/Hb /Helvetica-Narrow-Bold def
+/Hx /Helvetica-Narrow-BoldOblique def
+/KR /Bookman-Light def
+/KI /Bookman-LightItalic def
+/KB /Bookman-Demi def
+/KX /Bookman-DemiItalic def
+/AR /AvantGarde-Book def
+/AI /AvantGarde-BookOblique def
+/AB /AvantGarde-Demi def
+/AX /AvantGarde-DemiOblique def
+/NR /NewCenturySchlbk-Roman def
+/NI /NewCenturySchlbk-Italic def
+/NB /NewCenturySchlbk-Bold def
+/NX /NewCenturySchlbk-BoldItalic def
+/ZD /ZapfDingbats def
+/ZI /ZapfChancery-MediumItalic def
+/S  /S def
+/S1 /S1 def
+/GR /Symbol def
+
+/inch {72 mul} bind def
+/min {2 copy gt {exch} if pop} bind def
+
+/setup {
+	counttomark 2 idiv {def} repeat pop
+
+	landscape {/orientation 90 orientation add def} if
+	/scaling 72 resolution div def
+	linewidth setlinewidth
+	1 setlinecap
+
+	pagedimensions
+	xcenter ycenter translate
+	orientation rotation mul rotate
+	width 2 div neg height 2 div translate
+	xoffset inch yoffset inch neg translate
+	margin 2 div dup neg translate
+	magnification dup aspectratio mul scale
+	scaling scaling scale
+
+	addmetrics
+	0 0 moveto
+} def
+
+/pagedimensions {
+	useclippath userdict /gotpagebbox known not and {
+		/pagebbox [clippath pathbbox newpath] def
+		roundpage currentdict /roundpagebbox known and {roundpagebbox} if
+	} if
+	pagebbox aload pop
+	4 -1 roll exch 4 1 roll 4 copy
+	landscape {4 2 roll} if
+	sub /width exch def
+	sub /height exch def
+	add 2 div /xcenter exch def
+	add 2 div /ycenter exch def
+	userdict /gotpagebbox true put
+} def
+
+/landscapepage {
+	landscape not {
+		0 height scaling div neg translate	% not quite
+		90 rotate
+	} if
+} bind def
+
+/portraitpage {
+	landscape {
+		width scaling div 0 translate	% not quite
+		-90 rotate
+	} if
+} bind def
+
+/addmetrics {
+	/Symbol /S null Sdefs cf
+	/Times-Roman /S1 StandardEncoding dup length array copy S1defs cf
+} def
+
+/pagesetup {
+	/page exch def
+	currentdict /pagedict known currentdict page known and {
+		page load pagedict exch get cvx exec
+	} if
+} def
+
+/decodingdefs [
+	{counttomark 2 idiv {y moveto show} repeat}
+	{neg /y exch def counttomark 2 idiv {y moveto show} repeat}
+	{neg moveto {2 index stringwidth pop sub exch div 0 32 4 -1 roll widthshow} repeat}
+	{neg moveto {spacewidth sub 0.0 32 4 -1 roll widthshow} repeat}
+	{counttomark 2 idiv {y moveto show} repeat}
+	{neg setfunnytext}
+] def
+
+/setdecoding {/t decodingdefs 3 -1 roll get bind def} bind def
+
+/w {neg moveto show} bind def
+/m {neg dup /y exch def moveto} bind def
+/done {/lastpage where {pop lastpage} if} def
+
+/f {
+	dup /font exch def findfont exch
+	dup /ptsize exch def scaling div dup /size exch def scalefont setfont
+	linewidth ptsize mul scaling 10 mul div setlinewidth
+	/spacewidth ( ) stringwidth pop def
+} bind def
+
+/changefont {
+	/fontheight exch def
+	/fontslant exch def
+	currentfont [
+		1 0
+		fontheight ptsize div fontslant sin mul fontslant cos div
+		fontheight ptsize div
+		0 0
+	] makefont setfont
+} bind def
+
+/sf {f} bind def
+
+/cf {
+	dup length 2 idiv
+	/entries exch def
+	/chtab exch def
+	/newencoding exch def
+	/newfont exch def
+
+	findfont dup length 1 add dict
+	/newdict exch def
+	{1 index /FID ne {newdict 3 1 roll put}{pop pop} ifelse} forall
+
+	newencoding type /arraytype eq {newdict /Encoding newencoding put} if
+
+	newdict /Metrics entries dict put
+	newdict /Metrics get
+	begin
+		chtab aload pop
+		1 1 entries {pop def} for
+		newfont newdict definefont pop
+	end
+} bind def
+
+%
+% A few arrays used to adjust reference points and character widths in some
+% of the printer resident fonts. If square roots are too high try changing
+% the lines describing /radical and /radicalex to,
+%
+%	/radical	[0 -75 550 0]
+%	/radicalex	[-50 -75 500 0]
+%
+% Move braceleftbt a bit - default PostScript character is off a bit.
+%
+
+/Sdefs [
+	/bracketlefttp		[201 500]
+	/bracketleftbt		[201 500]
+	/bracketrighttp		[-81 380]
+	/bracketrightbt		[-83 380]
+	/braceleftbt		[203 490]
+	/bracketrightex		[220 -125 500 0]
+	/radical		[0 0 550 0]
+	/radicalex		[-50 0 500 0]
+	/parenleftex		[-20 -170 0 0]
+	/integral		[100 -50 500 0]
+	/infinity		[10 -75 730 0]
+] def
+
+/S1defs [
+	/underscore		[0 80 500 0]
+	/endash			[7 90 650 0]
+] def
+end
+%%EndProlog
+%%BeginSetup
+DpostDict begin
+mark
+/rotation 1 def
+/gotpagebbox true def
+/linewidth 0.5 def
+/xoffset 0 def
+/yoffset 0 def
+/#copies 1 store
+/magnification 1 def
+%%FormsPerPage: 1
+/formsperpage 1 def
+%%Patch from lp
+%%EndPatch from lp
+/landscape false def
+/resolution 720 def
+setup
+2 setdecoding
+end
+%%EndSetup
+%%Page: 1 1
+%%PageBoundingBox: (atend)
+DpostDict begin
+/saveobj save def
+mark
+1 pagesetup
+12 B f
+(Program design in the UNIX\262 environment)5 2217 1 1771 1230 t
+10 I f
+(Rob Pike)1 363 1 2698 1470 t
+(Brian W. Kernighan)2 814 1 2473 1650 t
+(ABSTRACT)2643 2090 w
+10 R f
+( style of program)3 709(Much of the power of the UNIX operating system comes from a)11 2641 2 1330 2386 t
+( more important, easy to combine with other)7 1797(design that makes programs easy to use and,)7 1803 2 1080 2506 t
+( style has been called the use of)7 1268(programs. This)1 631 2 1080 2626 t
+10 I f
+(software tools)1 567 1 3005 2626 t
+10 R f
+(, and depends more on how)5 1108 1 3572 2626 t
+( can be used with other)5 953(the programs fit into the programming environment \320 how they)9 2647 2 1080 2746 t
+( as the system has become)5 1116( But)1 208( are designed internally.)3 998(programs \320 than on how they)5 1278 4 1080 2866 t
+(commercially successful and has spread widely, this style has often been compromised, to)12 3600 1 1080 2986 t
+( programs have become encrusted with dubious features.)7 2337( Old)1 209(the detriment of all users.)4 1054 3 1080 3106 t
+( are not always written with attention to proper separation of function)11 2919(Newer programs)1 681 2 1080 3226 t
+( program design,)2 708( paper discusses the elements of)5 1358( This)1 244(and design for interconnection.)3 1290 4 1080 3346 t
+( possible trends for the)4 970(showing by example good and bad design, and indicates some)9 2630 2 1080 3466 t
+(future.)1080 3586 w
+( a great commercial success, and is likely to be the standard)11 2428(The UNIX operating system has become)5 1642 2 970 3862 t
+(operating system for microcomputers and some mainframes in the coming years.)10 3231 1 720 3982 t
+( the)1 158( is portability: the operating system kernel and)7 1927( One)1 226(There are good reasons for this popularity.)6 1759 4 970 4138 t
+( can be moved from one type of)7 1279(applications programs are written in the programming language C, and thus)10 3041 2 720 4258 t
+( another with much less effort than would be involved in recreating them in the assembly lan-)16 3835(computer to)1 485 2 720 4378 t
+( of comput-)2 470( the same operating system therefore runs on a wide variety)10 2408( Essentially)1 492(guage of each machine.)3 950 4 720 4498 t
+( more important, ven-)3 883( Perhaps)1 370( along.)1 276(ers, and users needn't learn a new system when new hardware comes)11 2791 4 720 4618 t
+( sell the UNIX system needn't provide new software for each new machine; instead, their software)15 3970(dors that)1 350 2 720 4738 t
+(can be compiled and run without change on any hardware, which makes the system commercially attrac-)15 4320 1 720 4858 t
+( element of zealotry: users of the system tend to be enthusiastic and to expect it wher-)16 3454( is also an)3 406(tive. There)1 460 3 720 4978 t
+( the UNIX system in university a few years ago are now in the job mar-)15 2888(ever they go; the students who used)6 1432 2 720 5098 t
+(ket and often demand it as a condition of employment.)9 2181 1 720 5218 t
+( system was popular long before it was even portable, let alone a commercial success.)14 3496(But the UNIX)2 574 2 970 5374 t
+(The reasons for that are more interesting.)6 1643 1 720 5494 t
+( the UNIX system was written for the a machine that was \(deservedly\))12 2882(Except for the initial version,)4 1188 2 970 5650 t
+( powerful enough to do real computing, but small enough to be affordable by small)14 3517( were)1 257(very popular.)1 546 3 720 5770 t
+(organizations such as academic departments in universities.)6 2382 1 720 5890 t
+( compet-)1 353(The early UNIX system was smaller but more effective and technically more interesting than)13 3717 2 970 6046 t
+( provided a number of innovative applications of computer science,)9 2767( It)1 119( the same hardware.)3 821(ing systems on)2 613 4 720 6166 t
+( include the)2 496( Examples)1 459( be obtained by a judicious blend of theory and practice.)10 2393(showing the benefits to)3 972 4 720 6286 t
+10 CW f
+(yacc)720 6406 w
+10 R f
+(parser-generator, the)1 827 1 988 6406 t
+10 CW f
+(diff)1843 6406 w
+10 R f
+( regular expressions to)3 907(file comparison program, and the pervasive use of)7 2022 2 2111 6406 t
+( turn to new programming languages and interesting software for)9 2751( led in)2 282( These)1 304(describe string patterns.)2 983 4 720 6526 t
+(applications like program development, document preparation and circuit design.)8 3245 1 720 6646 t
+( size, and since essentially everything was written in C, the software)11 2781(Since the system was modest in)5 1289 2 970 6802 t
+( customize for particular applications or merely to support a view of the world)13 3346(was easy to modify, to)4 974 2 720 6922 t
+8 S1 f
+(__________________)720 7022 w
+8 R f
+(\262 UNIX is a trademark of Bell Laboratories.)7 1409 1 720 7122 t
+cleartomark
+showpage
+saveobj restore
+end
+%%%PageBoundingBox: 61 65 514 691
+%%EndPage: 1 1
+%%Page: 2 2
+%%PageBoundingBox: (atend)
+DpostDict begin
+/saveobj save def
+mark
+2 pagesetup
+10 R f
+(- 2 -)2 166 1 2797 480 t
+( the plethora)2 503( ease of change is also a weakness, of course, as evidenced by)12 2482( \(This)1 262(different from the original.)3 1073 4 720 840 t
+(of different versions of the system.\))5 1425 1 720 960 t
+( new way of thinking of how to attack)8 1528(Finally, the UNIX system provided a new style of computing, a)10 2542 2 970 1116 t
+( programs separately or in combina-)5 1474( style was based on the use of using)8 1482( This)1 235(a problem with a computer.)4 1129 4 720 1236 t
+(tion to get a job done, rather than doing it by hand, by monolithic self-sufficient subsystems, or by special-)18 4320 1 720 1356 t
+( has been much discussed in the literature, so we don't need to repeat it)14 2926( This)1 234(purpose, one-time programs.)2 1160 3 720 1476 t
+(here; see [1], for example.)4 1046 1 720 1596 t
+( style is still evolving,)4 898( The)1 209( on the system are closely related.)6 1374(The style of use and design of the tools)8 1589 4 970 1752 t
+( program fit together, how the)5 1248(and is the subject of this essay: in particular, how the design and use of a)15 3072 2 720 1872 t
+( focus of the)3 526( The)1 215( influences solutions to new problems.)5 1588(tools fit into the environment, and how the style)8 1991 4 720 1992 t
+(discussion is a single example, the program)6 1758 1 720 2112 t
+10 CW f
+(cat)2506 2112 w
+10 R f
+( of files onto its standard output.)6 1309(, which concatenates a set)4 1045 2 2686 2112 t
+10 CW f
+(cat)720 2232 w
+10 R f
+( it is essential to the UNIX system; and it is a)11 1852(is a simple program, both in implementation and in use;)9 2260 2 928 2232 t
+( a)1 77( \(Often)1 318( of the kinds of decisions that delight both supporters and critics of the system.)14 3257(good illustration)1 668 4 720 2352 t
+( an asset or as a fault by different audiences; our audience is)12 2471(single property of the system will be taken as)8 1849 2 720 2472 t
+( the)1 167( Even)1 275( programming.\))1 647(programmers, because the UNIX environment is designed fundamentally for)8 3231 4 720 2592 t
+(name)720 2712 w
+10 CW f
+(cat)965 2712 w
+10 R f
+(is typical of UNIX program names: it is short, pronounceable, but not conventional English for)14 3866 1 1174 2712 t
+( though,)1 329( important,)1 441( Most)1 258( an opposing viewpoint, see [2].\))5 1322( \(For)1 224(the job it does.)3 595 6 720 2832 t
+10 CW f
+(cat)3915 2832 w
+10 R f
+(in its usages and varia-)4 919 1 4121 2832 t
+(tions exemplifies UNIX program design style and how it has been interpreted by different communities.)14 4158 1 720 2952 t
+9 CW f
+( \(I\))1 216(11/3/71 CAT)1 3888 2 900 3218 t
+( -- concatenate and print)4 1350( _a _t _)3 108(NAME c)1 774 3 900 3438 t
+( ...)1 216( _i _l _e _1 _)5 216( f)1 108( _a _t _)3 108(SYNOPSIS c)1 774 5 900 3658 t
+( reads each file in sequence and writes it on)9 2430( _a _t _)3 108(DESCRIPTION c)1 774 3 900 3878 t
+( Thus:)1 378(the standard output stream.)3 1458 2 1620 3988 t
+( _i _l _e _)4 162( f)1 108(c _a _t _)3 162 3 1782 4208 t
+( Also:)1 378(is about the easiest way to print a file.)8 2214 2 1620 4428 t
+( _i _l _e _3 _)5 216( >f)1 162( _i _l _e _2 _)5 216( f)1 108( _i _l _e _1 _)5 216( f)1 108(c _a _t _)3 162 7 1782 4648 t
+(is about the easiest way to concatenate files.)7 2484 1 1620 4868 t
+( reads from the)3 810( _a _t _)3 108(If no input file is given c)6 1458 3 1620 5088 t
+(standard input file.)2 1080 1 1620 5198 t
+(FILES --)1 828 1 900 5418 t
+( cp)1 162( pr,)1 450(SEE ALSO)1 432 3 900 5638 t
+( if a file cannot be found it is ignored.)9 2214(DIAGNOSTICS none;)1 990 2 900 5858 t
+(BUGS --)1 828 1 900 6078 t
+( dmr)1 216(OWNER ken,)1 936 2 900 6298 t
+10 R f
+( page for)2 354( Manual)1 355(Figure 1:)1 364 3 1517 6538 t
+10 HB f
+(cat)2615 6538 w
+10 R f
+(, UNIX 1st Edition, November, 1971)5 1482 1 2760 6538 t
+( is the manual page for)5 917(Figure 1)1 336 2 720 6898 t
+10 CW f
+(cat)1999 6898 w
+10 R f
+( Evidently,)1 465(from the UNIX 1st Edition manual.)5 1426 2 2205 6898 t
+10 CW f
+(cat)4122 6898 w
+10 R f
+(copies its input to)3 712 1 4328 6898 t
+( taken from a sequence of one or more files, but it can come from the stan-)16 2995( input is normally)3 715( The)1 207(its output.)1 403 4 720 7018 t
+( manual suggests two uses, the general file copy:)8 1950( The)1 205( output is the standard output.)5 1189( The)1 205(dard input.)1 433 5 720 7138 t
+cleartomark
+showpage
+saveobj restore
+end
+%%PageBoundingBox: 61 62 514 764
+%%EndPage: 2 2
+%%Page: 3 3
+%%PageBoundingBox: (atend)
+DpostDict begin
+/saveobj save def
+mark
+3 pagesetup
+10 R f
+(- 3 -)2 166 1 2797 480 t
+9 CW f
+(cat file1 file2 >file3)3 1188 1 1008 830 t
+10 R f
+(and printing a file on the terminal:)6 1371 1 720 1010 t
+9 CW f
+(cat file)1 432 1 1008 1180 t
+10 R f
+( redirection \(provided)2 876( Output)1 331( the design of the program.)5 1091(The general case is certainly what was intended in)8 2022 4 720 1360 t
+(by the)1 248 1 720 1480 t
+10 CW f
+(>)994 1480 w
+10 R f
+( by the UNIX shell\) makes)5 1073(operator, implemented)1 905 2 1080 1480 t
+10 CW f
+(cat)3083 1480 w
+10 R f
+(a fine general-purpose file concatenator and)5 1752 1 3288 1480 t
+(a valuable adjunct for other programs, which can use)8 2114 1 720 1600 t
+10 CW f
+(cat)2859 1600 w
+10 R f
+(to process filenames, as in:)4 1079 1 3064 1600 t
+9 CW f
+(cat file file2 ... | other-program)5 1836 1 1008 1770 t
+10 R f
+(The fact that)2 510 1 720 1950 t
+10 CW f
+(cat)1258 1950 w
+10 R f
+( surprisingly, in practice it turns)5 1297( Perhaps)1 370(will also print on the terminal is a special case.)9 1906 3 1467 1950 t
+(out that the special case is the main use of the program.\262)11 2263 1 720 2070 t
+(The design of)2 553 1 970 2226 t
+10 CW f
+(cat)1550 2226 w
+10 R f
+(is typical of most UNIX programs: it implements one simple but general function)12 3283 1 1757 2226 t
+( many different applications \(including many not envisioned by the original author\).)11 3517(that can be used in)4 803 2 720 2346 t
+( example, there are separate commands for file system)8 2241( For)1 198( functions.)1 431(Other commands are used for other)5 1450 4 720 2466 t
+( systems instead lump these into a)6 1361( Other)1 277( them or telling how big they are.)7 1332(tasks like renaming files, deleting)4 1350 4 720 2586 t
+( file copy)2 379( \(The)1 239( its own.)2 344(single ``file system'' command with an internal structure and command language of)11 3358 4 720 2706 t
+( approach is not necessarily worse or bet-)7 1675( That)1 236( operating systems like or is an example.\))7 1680(program found on)2 729 4 720 2826 t
+( are not completely alien)4 999( such programs)2 614( Unfortunately,)1 637(ter, but it is certainly against the UNIX philosophy.)8 2070 4 720 2946 t
+( mail-reading programs and text editors, for example, are large self-contained)10 3132(to the UNIX system \320 some)5 1188 2 720 3066 t
+( and mesh poorly with the rest of the system.)9 1838(``subsystems'' that provide their own complete environments)6 2482 2 720 3186 t
+( however, are usually imported from or inspired by programs on other operating sys-)13 3396(Most such subsystems,)2 924 2 720 3306 t
+(tems with markedly different programming environments.)5 2325 1 720 3426 t
+( most important)2 638( The)1 207( significant advantages to the traditional UNIX system approach.)8 2609(There are some)2 616 4 970 3582 t
+(is that the surrounding environment \320 the shell and the programs it can invoke \320 provides a uniform)17 4320 1 720 3702 t
+( expanded by the shell for all programs, without)8 1941( argument patterns are)3 895( Filename)1 424(access to system facilities.)3 1060 4 720 3822 t
+( are a natural)3 550( Pipes)1 278( same is true of input and output redirection.)8 1861( The)1 216(prearrangement in each command.)3 1415 5 720 3942 t
+( than decorate each command with options for all relevant pre- and post-)12 2983( Rather)1 323( redirection.)1 489(outgrowth of)1 525 4 720 4062 t
+( concise and header-free textual data that)6 1633(processing, each program expects as input, and produces as output,)9 2687 2 720 4182 t
+( takes some programming discipline)4 1461( It)1 114( with other programs to do the rest of the task at hand.)12 2197(connects well)1 548 4 720 4302 t
+( environment \320 primarily, to avoid the temptation to add features)10 2649(to build a program that works well in this)8 1671 2 720 4422 t
+(that conflict with or duplicate services provided by other commands \320 but it's well worthwhile.)14 3854 1 720 4542 t
+( example, the 7th Edition shell was aug-)7 1660( For)1 197( functions are well separated.)4 1198(Growth is easy when the)4 1015 4 970 4698 t
+( program into the arguments to another, as)7 1699(mented with a backquote operator that converts the output of one)10 2621 2 720 4818 t
+(in)720 4938 w
+9 CW f
+(cat `cat filelist`)2 972 1 1008 5108 t
+10 R f
+( when this operator was invented; because the backquote is)9 2458(No changes were made in any other program)7 1862 2 720 5288 t
+( If)1 119( by the shell acquire the feature transparently and uniformly.)9 2444(interpreted by the shell, all programs called)6 1757 3 720 5408 t
+( subroutine, by each)3 825(special characters like backquotes were instead interpreted, even by calling a standard)11 3495 2 720 5528 t
+( appropriate, every program would require \(at least\) recompilation whenever)9 3085(program that found the feature)4 1235 2 720 5648 t
+( but experimentation would be)4 1273( only would uniformity be hard to enforce,)7 1787( Not)1 212(someone had a new idea.)4 1048 4 720 5768 t
+(harder because of the effort of installing any changes.)8 2141 1 720 5888 t
+( introduced two changes in)4 1124(The UNIX 7th Edition system)4 1249 2 970 6044 t
+10 CW f
+(cat)3380 6044 w
+10 R f
+( files that could not be read,)6 1184(. First,)1 296 2 3560 6044 t
+( Second,)1 376( permissions or simple non-existence, were reported rather than ignored.)9 2954(either because of denied)3 990 3 720 6164 t
+( the addition of a single optional argument)7 1703(and less desirable, was)3 909 2 720 6284 t
+10 CW f
+(-u)3358 6284 w
+10 R f
+(, which forced)2 575 1 3478 6284 t
+10 CW f
+(cat)4079 6284 w
+10 R f
+(to unbuffer its out-)3 755 1 4285 6284 t
+( 8th Edition of the system, are technical)7 1608(put \(the reasons for this option, which has disappeared again in the)11 2712 2 720 6404 t
+(and irrelevant here.\))2 805 1 720 6524 t
+( of one argument was enough to suggest more, and other versions of the system)14 3358(But the existence)2 712 2 970 6680 t
+8 S1 f
+(__________________)720 6780 w
+8 R f
+(\262 The use of)3 402 1 720 6880 t
+8 CW f
+(cat)1144 6880 w
+8 R f
+(to feed a single input file to a program has to some degree superseded the shell's)15 2592 1 1310 6880 t
+8 CW f
+(<)3924 6880 w
+8 R f
+(operator, which illus-)2 686 1 3994 6880 t
+(trates that general-purpose constructs \320 like)5 1482 1 720 6980 t
+8 CW f
+(cat)2234 6980 w
+8 R f
+( are often more natural than convenient special-purpose)7 1843(and pipes \320)2 427 2 2410 6980 t
+(ones.)720 7080 w
+cleartomark
+showpage
+saveobj restore
+end
+%%PageBoundingBox: 61 69 514 764
+%%EndPage: 3 3
+%%Page: 4 4
+%%PageBoundingBox: (atend)
+DpostDict begin
+/saveobj save def
+mark
+4 pagesetup
+10 R f
+(- 4 -)2 166 1 2797 480 t
+(soon embellished)1 703 1 720 840 t
+10 CW f
+(cat)1454 840 w
+10 R f
+( list comes from)3 665( This)1 234(with features.)1 549 3 1665 840 t
+10 CW f
+(cat)3144 840 w
+10 R f
+( UNIX)1 281(on the Berkeley distribution of the)5 1404 2 3355 840 t
+(system:)720 960 w
+9 CW f
+(-s)1008 1130 w
+9 R f
+(strip multiple blank lines to a single instance)7 1611 1 1391 1130 t
+9 CW f
+(-n)1008 1240 w
+9 R f
+(number the output lines)3 854 1 1391 1240 t
+9 CW f
+(-b)1008 1350 w
+9 R f
+(number only the non-blank lines)4 1172 1 1391 1350 t
+9 CW f
+(-v)1008 1460 w
+9 R f
+(make non-printing characters visible)3 1319 1 1391 1460 t
+9 CW f
+(-ve)1368 1570 w
+9 R f
+(mark ends of lines)3 664 1 1751 1570 t
+9 CW f
+(-vt)1368 1680 w
+9 R f
+(change representation of tab)3 1019 1 1751 1680 t
+10 R f
+( there are similar options and even a clash of naming:)10 2265(In System V,)2 549 2 970 1896 t
+10 CW f
+(-s)3822 1896 w
+10 R f
+(instructs)3980 1896 w
+10 CW f
+(cat)4357 1896 w
+10 R f
+(to be silent)2 465 1 4575 1896 t
+( none of these options are appropriate additions to)8 2029( But)1 199(about non-existent files.)2 971 3 720 2016 t
+10 CW f
+(cat)3948 2016 w
+10 R f
+( reasons get to the)4 733(; the)1 179 2 4128 2016 t
+(heart of how UNIX programs are designed and why they work well together.)12 3073 1 720 2136 t
+(It's easy to dispose of \(Berkeley\))5 1322 1 970 2292 t
+10 CW f
+(-s)2317 2292 w
+10 R f
+(,)2437 2292 w
+10 CW f
+(-n)2487 2292 w
+10 R f
+(and)2632 2292 w
+10 CW f
+(-b)2801 2292 w
+10 R f
+( done with existing tools)4 988(: all of these jobs are readily)6 1131 2 2921 2292 t
+(like)720 2412 w
+10 CW f
+(sed)895 2412 w
+10 R f
+(and)1100 2412 w
+10 CW f
+(awk)1269 2412 w
+10 R f
+( example, to number lines, this)5 1230(. For)1 214 2 1449 2412 t
+10 CW f
+(awk)2918 2412 w
+10 R f
+(invocation suffices:)1 785 1 3123 2412 t
+9 CW f
+(awk '{ print NR "\\t" $0 }')6 1404 1 1008 2582 t
+9 I f
+(filenames)2466 2582 w
+10 R f
+(If line-numbering is needed often, this command can be packaged under a name like)13 3370 1 720 2762 t
+10 CW f
+(linenumber)4116 2762 w
+10 R f
+(and put)1 298 1 4742 2762 t
+( possibility is to modify the)5 1104( Another)1 378(in a convenient public place.)4 1149 3 720 2882 t
+10 CW f
+(pr)3377 2882 w
+10 R f
+( format text)2 466(command, whose job is to)4 1051 2 3523 2882 t
+( lines is an appropriate feature in)6 1314( Numbering)1 506( printer.)1 317(such as program source for output on a line)8 1730 4 720 3002 t
+10 CW f
+(pr)4613 3002 w
+10 R f
+(; in fact)2 307 1 4733 3002 t
+(UNIX System V)2 682 1 720 3122 t
+10 CW f
+(pr)1435 3122 w
+10 R f
+(has a)1 210 1 1588 3122 t
+10 CW f
+(-n)1831 3122 w
+10 R f
+( never was a need to modify)6 1167( There)1 289(option to do so.)3 644 3 1983 3122 t
+10 CW f
+(cat)4115 3122 w
+10 R f
+(; these options are)3 745 1 4295 3122 t
+(gratuitous tinkering.)1 811 1 720 3242 t
+(But what about)2 623 1 970 3398 t
+10 CW f
+(-v)1624 3398 w
+10 R f
+( strange)1 319( Making)1 367( prints non-printing characters in a visible representation.)7 2327(? That)1 283 4 1744 3398 t
+( \(``)1 157(characters visible is a genuinely new function, for which no existing program is suitable.)13 3646 2 720 3518 t
+10 CW f
+(sed -n l)2 426 1 4523 3518 t
+10 R f
+('',)4949 3518 w
+( to occur in)3 470(the closest standard possibility, aborts when given very long input lines, which are more likely)14 3850 2 720 3638 t
+( isn't it appropriate to add the)6 1284( So)1 173( characters.\))1 503(files containing non-printing)2 1180 4 720 3758 t
+10 CW f
+(-v)3902 3758 w
+10 R f
+(option to)1 376 1 4064 3758 t
+10 CW f
+(cat)4482 3758 w
+10 R f
+(to make)1 336 1 4704 3758 t
+(strange characters visible when a file is printed?)7 1920 1 720 3878 t
+( a modification confuses what)4 1202( Such)1 251(The answer is ``No.'')3 858 3 970 4034 t
+10 CW f
+(cat)3307 4034 w
+10 R f
+('s job is \320 concatenating files \320 with)7 1553 1 3487 4034 t
+( UNIX program)2 667( A)1 137( a common special case \320 showing a file on the terminal.)11 2478(what it happens to do in)5 1038 4 720 4154 t
+( one thing well, and leave unrelated tasks to other programs.)10 2517(should do)1 402 2 720 4274 t
+10 CW f
+(cat)3700 4274 w
+10 R f
+('s job is to the data in files.)7 1160 1 3880 4274 t
+(Programs that collect data shouldn't the data;)6 1809 1 720 4394 t
+10 CW f
+(cat)2554 4394 w
+10 R f
+(therefore shouldn't transform its input.)4 1551 1 2759 4394 t
+(The preferred approach in this case is a separate program that deals with non-printable characters.)14 4070 1 970 4550 t
+(We called ours)2 602 1 720 4670 t
+10 CW f
+(vis)1349 4670 w
+10 R f
+( because its job is to make things vis-)8 1502(\(a suggestive, pronounceable, non-English name\))4 1982 2 1556 4670 t
+( visible \320 and as)4 714( usual, the default is to do what most users will want \320 make strange characters)15 3266(ible. As)1 340 3 720 4790 t
+( making)1 330( By)1 172(necessary include options for variations on that theme.)7 2215 3 720 4910 t
+10 CW f
+(vis)3467 4910 w
+10 R f
+(a separate program, related useful)4 1364 1 3676 4910 t
+( example, the option)3 864( For)1 205(functions are easy to provide.)4 1242 3 720 5030 t
+10 CW f
+(-s)3072 5030 w
+10 R f
+( characters,)1 470(strips out \(i.e., discards\) strange)4 1337 2 3233 5030 t
+( treatment and)2 571( options control the)3 778( Other)1 278(which is handy for dealing with files from other operating systems.)10 2693 4 720 5150 t
+( may or may not be considered strange in different situa-)10 2312(format of characters like tabs and backspaces that)7 2008 2 720 5270 t
+( options make sense in)4 917(tions. Such)1 473 2 720 5390 t
+10 CW f
+(vis)2137 5390 w
+10 R f
+( In)1 135(because its focus is entirely on the treatment of such characters.)10 2561 2 2344 5390 t
+10 CW f
+(cat)720 5510 w
+10 R f
+( require an entire sub-language within the)6 1729(, they)1 232 2 900 5510 t
+10 CW f
+(-v)2897 5510 w
+10 R f
+(option, and thus get even further away from the)8 1987 1 3053 5510 t
+( separate program makes conve-)4 1334( providing the function in a)5 1151( Also,)1 276(fundamental purpose of that program.)4 1559 4 720 5630 t
+(nient options such as)3 836 1 720 5750 t
+10 CW f
+(-s)1581 5750 w
+10 R f
+(easier to invent, because it isolates the problem as well as the solution.)12 2819 1 1726 5750 t
+( example, if we want)4 890( For)1 203( efficiency.)1 462(One possible objection to separate programs for each task is)9 2515 4 970 5906 t
+(numbered lines and visible characters it is probably more efficient to run the one command)14 3638 1 720 6026 t
+9 CW f
+(cat -n -v file)3 756 1 1008 6196 t
+10 R f
+(than the two-element pipeline)3 1190 1 720 6376 t
+9 CW f
+(linenumber file | vis)3 1134 1 1008 6546 t
+10 R f
+(In practice, however,)2 849 1 720 6726 t
+10 CW f
+(cat)1598 6726 w
+10 R f
+( common cases be)3 744(is usually used with no options, so it makes sense to have the)12 2489 2 1807 6726 t
+( current research version of the)5 1297( The)1 217(the efficient ones.)2 738 3 720 6846 t
+10 CW f
+(cat)3009 6846 w
+10 R f
+(command is actually about five times faster)6 1814 1 3226 6846 t
+( data in large blocks instead of the byte-at-)8 1734(than the Berkeley and System V versions because it can process)10 2586 2 720 6966 t
+( and this is perhaps more important, it)7 1537( Also,)1 267( is enabled.)2 458(time processing that might be required if an option)8 2058 4 720 7086 t
+( of the real)3 456( Most)1 265( program.)1 397(is hard to imagine any of these examples being the bottleneck of a production)13 3202 4 720 7206 t
+cleartomark
+showpage
+saveobj restore
+end
+%%PageBoundingBox: 61 55 514 764
+%%EndPage: 4 4
+%%Page: 5 5
+%%PageBoundingBox: (atend)
+DpostDict begin
+/saveobj save def
+mark
+5 pagesetup
+10 R f
+(- 5 -)2 166 1 2797 480 t
+( waiting for the user's terminal to display the characters, or even for the user to read)16 3414(time is probably taken)3 906 2 720 840 t
+(them.)720 960 w
+( than wider options; which is better depends on the problem.)10 2457(Separate programs are not always better)5 1613 2 970 1116 t
+( needs a way to perform a new function, one faces the choice of whether to add a new option)19 3739(Whenever one)1 581 2 720 1236 t
+( The)1 209( none of the programmable tools will do the job conveniently\).)10 2546(or write a new program \(assuming that)6 1565 3 720 1356 t
+( are appropri-)2 546( Options)1 369( be that each program does one thing.)7 1511(guiding principle for making the choice should)6 1894 4 720 1476 t
+( there is no such program, then a new)8 1558( If)1 124( the right functionality.)3 946(ately added to a program that already has)7 1692 4 720 1596 t
+( that case, the usual criteria for program design should be used: the program should)14 3325( In)1 133(program is called for.)3 862 3 720 1716 t
+( general as possible, its default behavior should match the most common usage, and it should cooper-)16 4115(be as)1 205 2 720 1836 t
+(ate with other programs.)3 976 1 720 1956 t
+( first)1 187( The)1 206( problem, dealing with fast terminal lines.)6 1677(Let's look at these issues in the context of another)9 2000 4 970 2112 t
+( written in the days when 150 baud was ``fast,'' and all terminals used)13 2897(versions of the UNIX system were)5 1423 2 720 2232 t
+( should we deal with the fact)6 1202( How)1 253( typical, and hard-copy terminals are rare.)6 1721( 9600 baud is)3 560(paper. Today,)1 584 5 720 2352 t
+(that output from programs like)4 1227 1 720 2472 t
+10 CW f
+(cat)1972 2472 w
+10 R f
+(scrolls off the top of the screen faster than one can read it?)12 2332 1 2177 2472 t
+( is to tell each program about the properties of terminals, so it)12 2461( One)1 216(There are two obvious approaches.)4 1393 3 970 2628 t
+( other is to write a command that handles ter-)9 1811( The)1 206(does the right thing \(whether by option or automatically\).)8 2303 3 720 2748 t
+(minals, and leave most programs untouched.)5 1784 1 720 2868 t
+( Berkeley's version of the)4 1039(An example of the first approach is)6 1414 2 970 3024 t
+10 CW f
+(ls)3450 3024 w
+10 R f
+(command, which lists the filenames)4 1443 1 3597 3024 t
+( us call it)3 370( Let)1 185(in a directory.)2 561 3 720 3144 t
+10 CW f
+(lsc)1863 3144 w
+10 R f
+( 7th Edition)2 475( The)1 206(to avoid confusion.)2 771 3 2070 3144 t
+10 CW f
+(ls)3548 3144 w
+10 R f
+(command lists filenames in a sin-)5 1346 1 3694 3144 t
+( directory, the list of filenames disappears off the top of the screen at great speed.)15 3290(gle column, so for a large)5 1030 2 720 3264 t
+10 CW f
+(lsc)720 3384 w
+10 R f
+( columns across the screen \(which is assumed to be 80 columns wide\), so there are typically)16 3770(prints in)1 338 2 932 3384 t
+( option)1 285( The)1 209( as many names on each line, and thus the output usually fits on one screen.)15 3081(four to eight times)3 745 4 720 3504 t
+10 CW f
+(-1)720 3624 w
+10 R f
+(can be used to get the old single-column behavior.)8 2011 1 865 3624 t
+(Surprisingly,)970 3780 w
+10 CW f
+(lsc)1515 3780 w
+10 R f
+(operates differently if its output is a file or pipe:)9 1917 1 1720 3780 t
+9 CW f
+(lsc)1008 3950 w
+10 R f
+(produces output different from)3 1228 1 720 4130 t
+9 CW f
+(lsc | cat)2 486 1 1008 4300 t
+10 R f
+(The reason is that)3 722 1 720 4480 t
+10 CW f
+(lsc)1472 4480 w
+10 R f
+(begins by examining whether or not its output is a terminal, and prints in columns)14 3358 1 1682 4480 t
+( to files or pipes,)4 685( retaining single-column output)3 1273( By)1 172(only if it is.)3 477 4 720 4600 t
+10 CW f
+(lsc)3356 4600 w
+10 R f
+(ensures compatibility with programs)3 1475 1 3565 4600 t
+(like)720 4720 w
+10 CW f
+(grep)895 4720 w
+10 R f
+(or)1160 4720 w
+10 CW f
+(wc)1268 4720 w
+10 R f
+( adjustment of the output format depend-)6 1643( This)1 228(that expect things to be printed one per line.)8 1756 3 1413 4720 t
+(ing on the destination is not only distasteful, it is unique \320 no standard UNIX command has this property.)18 4265 1 720 4840 t
+(A more insidious problem with)4 1266 1 970 4996 t
+10 CW f
+(lsc)2266 4996 w
+10 R f
+(is that the columnation facility, which is actually a useful, gen-)10 2564 1 2476 4996 t
+( Pro-)1 225( is built in and thus inaccessible to other programs that could use a similar compression.)15 3559(eral function,)1 536 3 720 5116 t
+( automatic columnation in)3 1050( The)1 206( special solutions to general problems.)5 1537(grams should not attempt)3 1014 4 720 5236 t
+10 CW f
+(lsc)4553 5236 w
+10 R f
+(is rem-)1 281 1 4759 5236 t
+( the ``wild cards'' found in some systems that provide filename pattern matching only for a par-)16 3896(iniscent of)1 424 2 720 5356 t
+( experience with centralized processing of wild cards in the UNIX shell shows over-)13 3458( The)1 212(ticular program.)1 650 3 720 5476 t
+(whelmingly how important it is to centralize the function where it can be used by all programs.)16 3798 1 720 5596 t
+(One solution for the)3 808 1 970 5752 t
+10 CW f
+(ls)1805 5752 w
+10 R f
+( \320 a separate program for columnation, so that columna-)9 2317(problem is obvious)2 771 2 1952 5752 t
+(tion into say 5 columns is just)6 1196 1 720 5872 t
+9 CW f
+(ls | 5)2 324 1 1008 6042 t
+10 R f
+( the multi-column option of)4 1110(It is easy to build a first-draft version with)8 1687 2 720 6222 t
+10 CW f
+(pr)3543 6222 w
+10 R f
+( commands)1 459(. The)1 231 2 3663 6222 t
+10 CW f
+(2)4379 6222 w
+10 R f
+(,)4439 6222 w
+10 CW f
+(3)4490 6222 w
+10 R f
+(, etc., are all)3 490 1 4550 6222 t
+(links to a single file:)4 817 1 720 6342 t
+9 CW f
+(pr -$0 -t -l1 $*)4 864 1 1008 6512 t
+10 CW f
+($0)720 6692 w
+10 R f
+(is the program name \()4 880 1 866 6692 t
+10 CW f
+(2)1746 6692 w
+10 R f
+(,)1806 6692 w
+10 CW f
+(3)1857 6692 w
+10 R f
+( so)1 116(, etc.\),)1 250 2 1917 6692 t
+10 CW f
+(-$0)2310 6692 w
+10 R f
+(becomes)2517 6692 w
+10 CW f
+(-)2893 6692 w
+10 I f
+(n)2953 6692 w
+10 R f
+(where is the number of columns that)6 1471 1 3030 6692 t
+10 CW f
+(pr)4528 6692 w
+10 R f
+(is to pro-)2 365 1 4675 6692 t
+( normal heading, set the page length to 1 line, and pass the arguments)13 2816( other options suppress the)4 1082(duce. The)1 422 3 720 6812 t
+(on to)1 215 1 720 6932 t
+10 CW f
+(pr)972 6932 w
+10 R f
+( of the use of tools \320 it takes only a moment to write, and it)15 2605( implementation is typical)3 1078(. This)1 265 3 1092 6932 t
+( a more general service is desired, such as automatically)9 2383( If)1 133(serves perfectly well for most applications.)5 1804 3 720 7052 t
+( required, but the one-)4 924(selecting the number of columns for optimal compaction, a C program is probably)12 3396 2 720 7172 t
+(line implementation above satisfies the immediate need and provides a base for experimentation with the)14 4320 1 720 7292 t
+cleartomark
+showpage
+saveobj restore
+end
+%%PageBoundingBox: 61 47 514 764
+%%EndPage: 5 5
+%%Page: 6 6
+%%PageBoundingBox: (atend)
+DpostDict begin
+/saveobj save def
+mark
+6 pagesetup
+10 R f
+(- 6 -)2 166 1 2797 480 t
+(design of a fancier program, should one become necessary.)8 2360 1 720 840 t
+(Similar reasoning suggests a solution for the general problem of data flowing off screens \(colum-)14 4070 1 970 996 t
+( programs are by)3 697( Such)1 258( input and print it a screen at a time.)9 1509(nated or not\): a separate program to take any)8 1856 4 720 1116 t
+( like)1 178(now widely available, under names)4 1419 2 720 1236 t
+10 CW f
+(pg)2345 1236 w
+10 R f
+(and)2493 1236 w
+10 CW f
+(more)2665 1236 w
+10 R f
+( solution affects no other programs, but can be)8 1879(. This)1 256 2 2905 1236 t
+( be enhanced with options)4 1059( usual, once the basic feature is right, the program can)10 2206( As)1 166(used with all of them.)4 889 4 720 1356 t
+( screen size, backing up, searching for patterns, and anything else that proves useful within)14 3755(for specifying)1 565 2 720 1476 t
+(that basic job.)2 558 1 720 1596 t
+( the user forgets to pipe output into)7 1423( If)1 119(There is still a problem, of course.)6 1388 3 970 1752 t
+10 CW f
+(pg)3928 1752 w
+10 R f
+(, the output that goes off)5 992 1 4048 1752 t
+( would be desirable if the facilities of)7 1510( It)1 114( is gone.)2 342(the top of the screen)4 825 4 720 1872 t
+10 CW f
+(pg)3539 1872 w
+10 R f
+(were always present without hav-)4 1353 1 3687 1872 t
+(ing to be requested explicitly.)4 1185 1 720 1992 t
+( not)1 156(There are related useful functions that are typically only available as part of a particular program,)15 3914 2 970 2148 t
+( the history mechanism provided by some versions of the UNIX shell:)11 2844( example is)2 465( One)1 221(in a central service.)3 790 4 720 2268 t
+( why)1 213( But)1 211( with editing.)2 563(commands are remembered, so it's possible to review and repeat them, perhaps)11 3333 4 720 2388 t
+( programs called)2 667( not even general enough to pass input to)8 1653( \(It's)1 218(should this facility be restricted to the shell?)7 1782 4 720 2508 t
+( well; any interactive)3 849( other programs could profit as)5 1244( Certainly)1 424(the shell; it applies to shell commands only.\))7 1803 4 720 2628 t
+( subtly, why should the facility be)6 1412( More)1 275( from the ability to re-execute commands.)6 1726(program could benefit)2 907 4 720 2748 t
+( often useful as input to another.)6 1296(restricted to program Pipes have shown that the output from one program is)12 3024 2 720 2868 t
+( of commands such as)4 890(With a little editing, the output)5 1249 2 720 2988 t
+10 CW f
+(ls)2886 2988 w
+10 R f
+(or)3033 2988 w
+10 CW f
+(make)3143 2988 w
+10 R f
+(can be turned into commands or data for)7 1630 1 3410 2988 t
+(other programs.)1 632 1 720 3108 t
+( com-)1 235(Another facility that could be usefully centralized is typified by the editor escape in some mail)15 3835 2 970 3264 t
+( this is all)3 393( But)1 197( is possible to pick up part of a mail message, edit it, and then include it in a reply.)19 3330(mands. It)1 400 4 720 3384 t
+(done by special facilities within the)5 1418 1 720 3504 t
+10 CW f
+(mail)2163 3504 w
+10 R f
+(command and so its use is restricted.)6 1468 1 2428 3504 t
+( by a different program, which usually has its own syntax and seman-)12 2860(Each such service is provided)4 1210 2 970 3660 t
+( is in contrast to features such as pagination, which is always the same because it is only done by)19 3924(tics. This)1 396 2 720 3780 t
+( output text is more environmental than functional; it is more like the)12 2772( editing of input and)4 811( The)1 205(one program.)1 532 4 720 3900 t
+( since the shell)3 597( But)1 197( automatic numbering of lines of text.)6 1519(shell's expansion of filename metacharacters than)5 2007 4 720 4020 t
+( The)1 211( see the characters sent as input to the programs, it cannot provide such editing.)14 3251(does not)1 341 3 720 4140 t
+10 CW f
+(emacs)4554 4140 w
+10 R f
+(edi-)4885 4140 w
+(tor)720 4260 w
+8 R f
+(3)831 4228 w
+10 R f
+( capability, by processing all UNIX command input and output, but this)11 2901(provides a limited form of this)5 1239 2 900 4260 t
+( the complexities and vagaries of yet another massive subsys-)9 2469(is expensive, clumsy, and subjects the users to)7 1851 2 720 4380 t
+(tem \(which isn't to criticize the inventiveness of the idea\).)9 2324 1 720 4500 t
+(A potentially simpler solution is to let the terminal or terminal interface do the work, with controlled)16 4070 1 970 4656 t
+( have used the)3 574( We)1 190( retransmission of visible text, and review of what has gone before.)11 2703(scrolling, editing and)2 853 4 720 4776 t
+(programmability of the Blit terminal)4 1489 1 720 4896 t
+8 R f
+(4)2209 4864 w
+10 R f
+( capitalize on this)3 726(\320 a programmable bitmap graphics display \320 to)7 2033 2 2281 4896 t
+(possibility, to good effect.)3 1047 1 720 5016 t
+( on the display, which can be edited, rearranged and)9 2210(The Blit uses a mouse to point to characters)8 1860 2 970 5172 t
+( the terminal)2 505( Because)1 382( keyboard.)1 421(transmitted back to the UNIX system as though they had been typed on the)13 3012 4 720 5292 t
+( how the text was created; all the features)8 1659(is essentially simulating typed input, the programs are oblivious to)9 2661 2 720 5412 t
+( general editing capabilities of the terminal, with no changes to the)11 2806(discussed above are provided by the)5 1514 2 720 5532 t
+(UNIX programs.)1 676 1 720 5652 t
+( user's control.)2 600(There are some obvious direct advantages to the Blit's ability to process text under the)14 3470 2 970 5808 t
+( is trivial: commands can be selected with the mouse, edited if desired, and retransmitted.)14 3794(Shell history)1 526 2 720 5928 t
+( equivalent, history is limited neither to the)7 1799(Since from the terminal's viewpoint all text on the display is)10 2521 2 720 6048 t
+( Blit provides editing, most of the interactive features of programs)10 2654( the)1 149( Because)1 384(shell nor to command input.)4 1133 4 720 6168 t
+(like)720 6288 w
+10 CW f
+(mail)895 6288 w
+10 R f
+(are unnecessary; they are done easily, transparently and uniformly by the terminal.)11 3301 1 1160 6288 t
+( interactive fea-)2 639(The most interesting facet of this work, however, is the way it removes the need for)15 3431 2 970 6444 t
+( is the place where interaction is provided, much as the shell is the pro-)14 2907(tures in programs; instead, the Blit)5 1413 2 720 6564 t
+( course, programming the termi-)4 1327( of)1 115( Unfortunately,)1 642(gram that interprets filename-matching metacharacters.)4 2236 4 720 6684 t
+( meshes)1 326(nal demands access to a part of the environment off-limits to most programmers, but the solution)15 3994 2 720 6804 t
+( to provide)2 443( the terminal cannot be modified)5 1321( If)1 120(well with the environment and is appealing in its simplicity.)9 2436 4 720 6924 t
+( a user-level program or perhaps the UNIX kernel itself could be modified fairly easily to do)16 3692(the capabilities,)1 628 2 720 7044 t
+(roughly what the Blit does, with similar results.)7 1903 1 720 7164 t
+cleartomark
+showpage
+saveobj restore
+end
+%%PageBoundingBox: 61 60 514 764
+%%EndPage: 6 6
+%%Page: 7 7
+%%PageBoundingBox: (atend)
+DpostDict begin
+/saveobj save def
+mark
+7 pagesetup
+10 R f
+(- 7 -)2 166 1 2797 480 t
+( to problem-solving on the UNIX system is to identify the right primitive operations and to)15 3740(The key)1 330 2 970 840 t
+( a)1 73( In)1 137( tend to solve general problems rather than special cases.)9 2303( programs)1 407( UNIX)1 304(put them at the right place.)5 1096 6 720 960 t
+( space of jobs to be done \(although with a fair)10 1890(very loose sense, the programs are orthogonal, spanning the)8 2430 2 720 1080 t
+( are placed where they will)5 1092( Functions)1 448( efficiency\).)1 484(amount of overlap for reasons of history, convenience or)8 2296 4 720 1200 t
+( any more than there)4 860(do the most good: there shouldn't be a pager in every program that produces output)14 3460 2 720 1320 t
+(should be filename pattern matching in every program that uses filenames.)10 2981 1 720 1440 t
+( is successful in part because it has a small)9 1772( It)1 119(One thing that UNIX does not need is more features.)9 2179 3 970 1596 t
+( make it easier for users to)6 1077( adding features does not)4 1018( Merely)1 343(number of good ideas that work well together.)7 1882 4 720 1716 t
+( right solution in the right place is always more effective)10 2278( The)1 207(do things \320 it just makes the manual thicker.)8 1835 3 720 1836 t
+(than haphazard hacking.)2 972 1 720 1956 t
+( W. Kernighan and Rob Pike,)5 1179(1. B.)1 342 2 720 2148 t
+10 I f
+(The UNIX Programming Environment,)3 1560 1 2266 2148 t
+10 R f
+(Prentice-Hall \(1984\).)1 848 1 3851 2148 t
+( Norman, ``The Truth about UNIX,'')5 1482(2. D.)1 347 2 720 2304 t
+10 I f
+(Datamation)2574 2304 w
+10 R f
+(\(November, 1981\).)1 762 1 3077 2304 t
+( Gosling, ``UNIX Emacs,'' CMU internal memorandum \(August, 1982\).)8 2907(3. James)1 494 2 720 2460 t
+( Multiplexed Graphics Terminal,'')3 1411( Pike, ``The Blit: A)4 811(4. R.)1 342 3 720 2616 t
+10 I f
+(Bell System Technical Journal)3 1248 1 3319 2616 t
+10 R f
+(\(this issue,)1 438 1 4602 2616 t
+(1984\).)970 2736 w
+cleartomark
+showpage
+saveobj restore
+end
+%%PageBoundingBox: 61 502 514 764
+%%EndPage: 7 7
+%%Trailer
+DpostDict begin
+done
+end
+%%Pages: 7
+%%DocumentFonts: Courier Times-Bold Times-Italic Times-Roman Times-Roman Helvetica-Bold
--- /dev/null
+++ b/pub/sitemap.txt
@@ -1,0 +1,11 @@
+http://harmful.cat-v.org/
+http://harmful.cat-v.org/cat-v/
+http://harmful.cat-v.org/software/
+http://harmful.cat-v.org/software/xml
+http://harmful.cat-v.org/children/
+http://harmful.cat-v.org/children/fuck_the_children
+http://harmful.cat-v.org/children/i_dont_care
+http://harmful.cat-v.org/economics/subsidies
+http://harmful.cat-v.org/economics/
+http://harmful.cat-v.org/economics/minimum_wage
+http://harmful.cat-v.org/economics/rent_controls
--- /dev/null
+++ b/pub/style/sinorca-screen-alt.css
@@ -1,0 +1,292 @@
+/***********************************************
+ * TITLE: Sinorca Alterative Screen Stylesheet *
+ * URI  : sinorca/sinorca-screen-alt.css       *
+ * MODIF: 2003-May-13 18:48 +0800              *
+ ***********************************************/
+
+
+/* ##### Common Styles ##### */
+
+body {
+  color: black;
+  background-color: white;
+  font-family: verdana, helvetica, arial, sans-serif;
+  font-size: 71%;  /* Enables font size scaling in MSIE */
+  margin: 0;
+  padding: 0;
+}
+
+html > body {
+  font-size: 8.5pt;
+}
+
+acronym, .titleTip {
+  border-bottom: 1px dotted rgb(153,153,153);
+  cursor: help;
+  margin: 0;
+  padding: 0 0 0.4px 0;
+}
+
+.doNotDisplay {
+  display: none;
+}
+
+.smallCaps {
+  font-size: 110%;
+  font-variant: small-caps;
+}
+
+
+/* ##### Header ##### */
+
+.superHeader {
+  color: white;
+  background-color: rgb(100,135,220);
+  height: 2em;
+}
+
+.superHeader a {
+  color: white;
+  background-color: transparent;
+  text-decoration: none;
+  font-size: 91%;
+  margin: 0;
+  padding: 0 0.5ex 0 0.25ex;
+}
+
+.superHeader a:hover {
+  text-decoration: underline;
+}
+
+.superHeader .left {
+  position: absolute;
+  left: 1.5mm;
+  top: 0.75ex;
+}
+
+.superHeader .right {
+  position: absolute;
+  right: 1.5mm;
+  top: 0.75ex;
+}
+
+.midHeader {
+  color: rgb(39,78,144);
+  background-color: rgb(140,170,230);
+}
+
+.headerTitle {
+  font-size: 337%;
+  font-weight: normal;
+  margin: 0 0 0 4mm;
+  padding: 0.25ex 0;
+}
+
+.subHeader {
+  color: white;
+  background-color: rgb(0,51,153);
+  margin: 0;
+  padding: 1ex 1ex 1ex 1.5mm;
+}
+
+.subHeader a {
+  color: white;
+  background-color: transparent;
+  text-decoration: none;
+  font-weight: bold;
+  margin: 0;
+  padding: 0 0.75ex 0 0.5ex;
+}  
+
+.subHeader a:hover {
+  text-decoration: underline;
+}
+
+.superHeader .highlight, .subHeader .highlight {
+  color: rgb(253,160,91);
+  background-color: transparent;
+}
+
+
+/* ##### Side Boxes ##### */
+
+#side-bar {
+  width: 14em;
+  margin: 2.5em 0 0 1.25mm;
+  float: left;
+  clear: left;
+}
+
+body > #side-bar {
+  margin-left: 2.5mm;  /* Circumvents a rendering bug in MSIE (6.0) */
+}
+
+.sideBarTitle {
+  color: white;
+  background-color: rgb(100,135,220);
+  font-weight: bold;
+  margin: 0;
+  padding: 0.4ex 0 0.4ex 0.6ex;
+}
+
+#side-bar ul {
+  list-style-type: none;
+  list-style-position: outside;
+  margin: 0;
+  padding: 0 0 2.25em 0;
+}
+
+#side-bar li {
+  margin: 0;
+  padding: 0.1ex 0;  /* Circumvents a rendering bug (?) in MSIE (6.0) */
+}
+
+#side-bar a, .thisPage {
+  color: rgb(0,102,204);
+  background-color: transparent;
+  text-decoration: none;
+  font-weight: bold;
+  margin: 0;
+  padding: 1.3ex 2ex;
+  display: block;
+}
+
+.thisPage {
+  color: black;
+  background-color: transparent;
+}
+
+#side-bar a:hover {
+  color: white;
+  background-color: rgb(100,135,220);
+  text-decoration: none;
+}
+
+.sideBarText {
+  line-height: 1.5em;
+  margin: 0 0 2.5em 0;
+  padding: 1ex 0.5ex 0 0.5ex;
+  display: block;
+}
+
+.sideBarText + .sideBarText {  /* Not recognised by MSIE (6.0) */
+  margin-top: -1.5em;
+}
+
+#side-bar .sideBarText a {
+  text-decoration: underline;
+  font-weight: normal;
+  margin: 0;
+  padding: 0;
+  display: inline;
+}
+
+#side-bar .sideBarText a:hover {
+  color: rgb(0,102,204);
+  background-color: transparent;
+  text-decoration: none;
+}
+
+
+/* ##### Main Copy ##### */
+
+#main-copy {
+  color: black;
+  background-color: transparent;
+  text-align: justify;
+  line-height: 1.5em;
+  margin: -1em 0 0 15em;
+  padding: 0.5mm 5mm 5mm 5mm;
+}
+
+#bodyText {
+  margin: 0 0 0 15.5em;
+  padding: 2mm 5mm 2mm 5mm;
+}
+
+
+#main-copy p {
+  margin: 1em 1ex 2em 1ex;
+  padding: 0;
+}
+
+#main-copy a {
+  color: rgb(0,102,204);
+  background-color: transparent;
+  text-decoration: underline;
+}
+
+#main-copy a:hover {
+  text-decoration: none;
+}
+
+#main-copy h1 {
+  color: rgb(0,102,204);
+  background-color: transparent;
+  font-size: 145.5%;
+  font-weight: bold;
+  margin: 2em 0 0 0;
+  padding: 0.5ex 0 0.5ex 0.6ex;
+  border-bottom: 1px solid rgb(0,102,204);
+}
+
+#main-copy .topOfPage {
+  color: rgb(0,102,204);
+  background-color: transparent;
+  font-size: 91%;
+  font-weight: bold;
+  text-decoration: none;
+  margin: 3ex 1ex 0 0;
+  padding: 0;
+  float: right;
+}
+
+dl {
+  margin: 1em 1ex 2em 1ex;
+  padding: 0;
+}
+
+dt {
+  font-weight: bold;
+  margin: 0 0 0 0;
+  padding: 0;
+}
+
+dd {
+  margin: 0 0 2em 2em;
+  padding: 0;
+}
+
+
+/* ##### Footer ##### */
+
+#footer {
+  color: white;
+  background-color: rgb(100,135,220);
+  font-size: 91%;
+  margin: 0;
+  padding: 1em 2.5mm 2.5ex 2.5mm;
+  clear: both;
+}
+
+#footer .left {
+  text-align: left;
+  line-height: 1.45em;
+  float: left;
+  clear: left;
+}
+
+#footer .right {
+  text-align: right;
+  line-height: 1.45em;
+}
+
+#footer a {
+  color: white;
+  background-color: transparent;
+  text-decoration: underline;
+}
+
+#footer a:hover {
+  text-decoration: none;
+}
\ No newline at end of file
--- /dev/null
+++ b/pub/style/style.css
@@ -1,0 +1,342 @@
+/* Default style */
+/* ##### Common Styles ##### */
+
+body {
+  color: black;
+  background-color: white;
+  font-family: verdana, helvetica, arial, sans-serif;
+  font-size: 71%;  /* Enables font size scaling in MSIE */
+  margin: 0;
+  padding: 0;
+}
+
+html > body {
+  font-size: 8.5pt;
+}
+
+acronym, .titleTip {
+  border-bottom: 1px dotted rgb(153,153,153);
+  cursor: help;
+  margin: 0;
+  padding: 0 0 0.4px 0;
+}
+
+.doNotDisplay {
+  display: none;
+}
+
+.smallCaps {
+  font-size: 110%;
+  font-variant: small-caps;
+}
+
+
+/* ##### Header ##### */
+
+.superHeader {
+  color: white;
+  background-color: rgb(100,135,220);
+  height: 2em;
+}
+
+.superHeader a {
+  color: white;
+  background-color: transparent;
+  text-decoration: none;
+  font-size: 91%;
+  margin: 0;
+  padding: 0 0.5ex 0 0.25ex;
+}
+
+.superHeader a:hover {
+  text-decoration: underline;
+}
+
+.superHeader .left {
+  position: absolute;
+  left: 1.5mm;
+  top: 0.75ex;
+}
+
+.superHeader .right {
+  position: absolute;
+  right: 1.5mm;
+  top: 0.75ex;
+}
+
+.midHeader {
+  color: rgb(39,78,144);
+  background-color: rgb(140,170,230);
+  border: solid 0 black;
+  border-width: 0.3em 0;
+}
+
+.headerTitle {
+  color: black;
+  font-size: 337%;
+  font-weight: normal;
+  margin: 0 0 0 4mm;
+  padding: 0.25ex 0;
+}
+#headerSubTitle {
+  font-size: 50%;
+  font-style: italic;
+}
+
+
+.subHeader {
+display: none;
+  color: white;
+  background-color: rgb(0,51,153);
+  margin: 0;
+  padding: 1ex 1ex 1ex 1.5mm;
+}
+
+.subHeader a {
+  color: white;
+  background-color: transparent;
+  text-decoration: none;
+  font-weight: bold;
+  margin: 0;
+  padding: 0 0.75ex 0 0.5ex;
+}  
+
+.subHeader a:hover {
+  text-decoration: underline;
+}
+
+.superHeader .highlight, .subHeader .highlight {
+  color: rgb(253,160,91);
+  background-color: transparent;
+}
+
+
+/* ##### Side Boxes ##### */
+
+#side-bar {
+  width: 15em;
+  float: left;
+  clear: left;
+  border-right: 1px solid rgb(153,153,153);
+}
+
+#side-bar div {
+  border-bottom: 1px solid rgb(153,153,153);
+}
+
+.sideBarTitle {
+  font-weight: bold;
+  margin: 0 0 0.5em 2.5mm;
+  padding: 1em 0 0 0;
+}
+
+#side-bar ul {
+  list-style-type: none;
+  list-style-position: outside;
+  margin: 0;
+  padding: 0 0 0.3em 0;
+}
+
+li ul {
+    padding-left: 1.2em !important;
+}
+
+#side-bar li {
+  margin: 0;
+  padding: 0.1ex 0;  /* Circumvents a rendering bug (?) in MSIE 6.0 */
+}
+
+#side-bar a, .thisPage {
+  color: rgb(0,102,204);
+  background-color: transparent;
+  text-decoration: none;
+  margin: 0;
+  padding: 0.35em 1ex 0.35em 5mm;
+  display: block;
+  text-transform: capitalize;
+  font-weight: bold;
+}
+
+.thisPage, .thisPage a {
+  color: black!important;
+  background-color: white;
+  padding-left: 5mm;
+  XXXborder-top: 1px solid rgb(153,153,153);
+  XXXborder-bottom: 1px solid rgb(153,153,153);
+  font-weight: 600;
+}
+
+#side-bar a:hover {
+  color: white;
+  background-color: rgb(100,135,220);
+  text-decoration: none;
+}
+
+.sideBarText {
+  line-height: 1.5em;
+  margin: 0 0 1em 0;
+  padding: 0 1.5ex 0 2.5mm;
+  display: block;
+}
+
+#side-bar .sideBarText a {
+  text-decoration: underline;
+  margin: 0;
+  padding: 0;
+  display: inline;
+}
+
+#side-bar .sideBarText a:hover {
+  color: rgb(0,102,204);
+  background-color: transparent;
+  text-decoration: none;
+}
+
+.lighterBackground {
+  color: inherit;
+  background-color: white;
+}
+
+
+
+/* ##### Main Copy ##### */
+
+#main-copy {
+  max-width: 80em;
+  color: black;
+  background-color: transparent;
+  text-align: justify;
+  line-height: 1.5em;
+  margin: 0em 0 0 15em;
+  padding: 0.5mm 5mm 5mm 5mm;
+  border-left: 1px solid rgb(153,153,153);
+}
+
+#bodyText {
+  margin: 0 0 0 15.5em;
+  padding: 2mm 5mm 2mm 5mm;
+}
+
+
+#main-copy p {
+  margin: 1em 1ex 2em 1ex;
+  padding: 0;
+}
+
+#main-copy a {
+  color: rgb(0,102,204);
+  background-color: transparent;
+  text-decoration: underline;
+}
+
+#main-copy a:hover {
+  text-decoration: none;
+}
+
+#main-copy h1 {
+  color: rgb(0,102,204);
+  background-color: transparent;
+  font-size: 145.5%;
+  font-weight: bold;
+  margin: 2em 0 0 0;
+  padding: 0.5ex 0 0.5ex 0.6ex;
+  border-bottom: 1px solid rgb(0,102,204);
+}
+
+#main-copy .topOfPage {
+  color: rgb(0,102,204);
+  background-color: transparent;
+  font-size: 91%;
+  font-weight: bold;
+  text-decoration: none;
+  margin: 3ex 1ex 0 0;
+  padding: 0;
+  float: right;
+}
+
+dl {
+  margin: 1em 1ex 2em 1ex;
+  padding: 0;
+}
+
+dt {
+  font-weight: bold;
+  margin: 0 0 0 0;
+  padding: 0;
+}
+
+dd {
+  margin: 0 0 2em 2em;
+  padding: 0;
+}
+
+
+/* ##### Footer ##### */
+
+#footer {
+  color: white;
+  background-color: rgb(100,135,220);
+  font-size: 91%;
+  margin: 0;
+  padding: 1em 2.5mm 2.5ex 2.5mm;
+  clear: both;
+}
+
+#footer .left {
+  text-align: left;
+  line-height: 1.45em;
+  float: left;
+  clear: left;
+}
+
+#footer .right {
+  text-align: right;
+  line-height: 1.45em;
+}
+
+#footer a {
+  color: white;
+  background-color: transparent;
+  text-decoration: underline;
+}
+
+#footer a:hover {
+  text-decoration: none;
+}
+
+
+/* GENERAL */
+
+/* Spam */
+.spam {
+    text-align: center;
+}
+
+/* Tables */
+table {
+    border: solid 1px black;
+}
+th {
+    background-color: #abc;
+    border: solid 1px black;
+}
+td {
+    background-color: #def;
+    border: solid 1px black;
+}
+
+hr {
+    border-width: 0px 0px 0.1em 0px;
+    border-color: black;
+}
+
+.spam table, .spam th, .spam td {
+	border: none;
+}
+
+/* Code */
+pre {
+    margin-left: 2em; 
+}
+
+
--- /dev/null
+++ b/pub/style/style_old.css
@@ -1,0 +1,330 @@
+/* Old Default style */
+/* ##### Common Styles ##### */
+
+body {
+  color: black;
+  XXXbackground-color: rgb(240,240,240);
+  background-color: white;
+  font-family: verdana, helvetica, arial, sans-serif;
+  font-size: 71%;  /* Enables font size scaling in MSIE */
+  margin: 0;
+  padding: 0;
+}
+
+html > body {
+  font-size: 8.5pt;
+}
+
+acronym, .titleTip {
+  border-bottom: 1px dotted rgb(153,153,153);
+  cursor: help;
+  margin: 0;
+  padding: 0 0 0.4px 0;
+}
+
+.doNotDisplay {
+  display: none;
+}
+
+.smallCaps {
+  font-size: 110%;
+  font-variant: small-caps;
+}
+
+
+/* ##### Header ##### */
+
+.superHeader {
+  color: white;
+  background-color: rgb(100,135,220);
+  height: 2em;
+}
+
+.superHeader a {
+  color: white;
+  background-color: transparent;
+  text-decoration: none;
+  font-size: 91%;
+  margin: 0;
+  padding: 0 0.5ex 0 0.25ex;
+}
+
+.superHeader a:hover {
+  text-decoration: underline;
+}
+
+.superHeader .left {
+  position: absolute;
+  left: 1.5mm;
+  top: 0.75ex;
+}
+
+.superHeader .right {
+  position: absolute;
+  right: 1.5mm;
+  top: 0.75ex;
+}
+
+.midHeader {
+  color: rgb(39,78,144);
+  background-color: rgb(140,170,230);
+  border: solid 0 black;
+  border-width: 0.3em 0;
+}
+
+.headerTitle {
+  color: black;
+  font-size: 337%;
+  font-weight: normal;
+  margin: 0 0 0 4mm;
+  padding: 0.25ex 0;
+}
+#headerSubTitle {
+  font-size: 50%;
+  font-style: italic;
+}
+
+.subHeader {
+display: none;
+  color: white;
+  background-color: rgb(0,51,153);
+  margin: 0;
+  padding: 1ex 1ex 1ex 1.5mm;
+}
+
+.subHeader a {
+  color: white;
+  background-color: transparent;
+  text-decoration: none;
+  font-weight: bold;
+  margin: 0;
+  padding: 0 0.75ex 0 0.5ex;
+}  
+
+.subHeader a:hover {
+  text-decoration: underline;
+}
+
+.superHeader .highlight, .subHeader .highlight {
+  color: rgb(253,160,91);
+  background-color: transparent;
+}
+
+
+/* ##### Side Bar ##### */
+
+#side-bar {
+  width: 15em;
+  float: left;
+  clear: left;
+  border-right: 1px solid rgb(153,153,153);
+}
+
+#side-bar div {
+  border-bottom: 1px solid rgb(153,153,153);
+}
+
+.sideBarTitle {
+  font-weight: bold;
+  margin: 0 0 0.5em 2.5mm;
+  padding: 1em 0 0 0;
+}
+
+#side-bar ul {
+  list-style-type: none;
+  list-style-position: outside;
+  margin: 0;
+  padding: 0 0 1.1em 0;
+}
+
+#side-bar li {
+  margin: 0;
+  padding: 0.1ex 0;  /* Circumvents a rendering bug (?) in MSIE 6.0 */
+}
+
+#side-bar a, .thisPage {
+  color: rgb(0,102,204);
+  background-color: transparent;
+  XXXtext-decoration: none;
+  margin: 0;
+  padding: 0.55em 1ex 0.55em 5mm;
+  display: block;
+}
+
+.thisPage {
+  color: black;
+  background-color: white;
+  padding-left: 5mm;
+  XXXborder-top: 1px solid rgb(153,153,153);
+  XXXborder-bottom: 1px solid rgb(153,153,153);
+  font-weight: 600;
+}
+
+#side-bar a:hover {
+  color: white;
+  background-color: rgb(100,135,220);
+  text-decoration: none;
+}
+
+.sideBarText {
+  line-height: 1.5em;
+  margin: 0 0 1em 0;
+  padding: 0 1.5ex 0 2.5mm;
+  display: block;
+}
+
+#side-bar .sideBarText a {
+  text-decoration: underline;
+  margin: 0;
+  padding: 0;
+  display: inline;
+}
+
+#side-bar .sideBarText a:hover {
+  color: rgb(0,102,204);
+  background-color: transparent;
+  text-decoration: none;
+}
+
+.lighterBackground {
+  color: inherit;
+  background-color: white;
+}
+
+
+/* ##### Main Copy ##### */
+
+#main-copy {
+  max-width: 90em;
+  color: black;
+  background-color: white;
+  text-align: justify;
+  line-height: 1.5em;
+  margin: 0 0 0 15em;
+  padding: 0.5mm 5mm 5mm 5mm;
+  border-left: 1px solid rgb(153,153,153);
+}
+
+#main-copy p {
+  margin: 1em 1ex 2em 1ex;
+  padding: 0;
+}
+
+#main-copy a {
+  color: rgb(0,102,204);
+  background-color: transparent;
+  text-decoration: underline;
+}
+
+#main-copy a:hover {
+  text-decoration: none;
+}
+
+#main-copy h1 {
+  color: white;
+  background-color: rgb(100,135,220);
+  font-size: 100%;
+  font-weight: bold;
+  margin: 3em 0 0 0;
+  padding: 0.5ex 0 0.5ex 1ex;
+}
+
+#main-copy .topOfPage {
+  color: white;
+  background-color: transparent;
+  font-size: 91%;
+  font-weight: bold;
+  text-decoration: none;
+  margin: 2.5ex 1ex 0 0;  /* For MSIE */
+  padding: 0;
+  float: right;
+}
+
+#main-copy > .topOfPage {
+  margin: 2.75ex 1ex 0 0;  /* For fully standards-compliant user agents */
+}
+
+dl {
+  margin: 1em 1ex 2em 1ex;
+  padding: 0;
+}
+
+dt {
+  font-weight: bold;
+  margin: 0 0 0 0;
+  padding: 0;
+}
+
+dd {
+  margin: 0 0 2em 2em;
+  padding: 0;
+}
+
+
+/* ##### Footer ##### */
+
+#footer {
+  color: white;
+  background-color: rgb(100,135,220);
+  font-size: 91%;
+  margin: 0;
+  padding: 1em 2.5mm 2.5ex 2.5mm;
+  clear: both;
+}
+
+#footer .left {
+  line-height: 1.45em;
+  float: left;
+  clear: left;
+}
+
+#footer .right {
+  text-align: right;
+  line-height: 1.45em;
+}
+
+#footer a {
+  color: white;
+  background-color: transparent;
+  text-decoration: underline;
+}
+
+#footer a:hover {
+  text-decoration: none;
+}
+
+
+/* GENERAL */
+/* Spam */
+.spam {
+    text-align: center;
+}
+
+/* Tables */
+table {
+    border: solid 1px black;
+}
+th {
+    background-color: #abc;
+    border: solid 1px black;
+}
+td {
+    background-color: #def;
+    border: solid 1px black;
+}
+
+hr {
+    border-width: 0px 0px 0.1em 0px;
+    border-color: black;
+}
+
+.spam table, .spam th, .spam td {
+	border: none;
+}
+
+/* Code */
+pre {
+    margin-left: 2em; 
+}
+
+
--- /dev/null
+++ b/tpl/_inc/404.tpl
@@ -1,0 +1,49 @@
+<h1>The page requested doesn't exist</h1>
+
+<br />
+Try searching in cat-v.org:
+
+<div class="spam">
+<!-- SiteSearch Google -->
+<form method="get" action="http://www.google.com/custom" target="_top">
+<table border="0" bgcolor="#ffffff">
+<tr><td nowrap="nowrap" valign="top" align="left" height="32">
+
+</td>
+<td nowrap="nowrap">
+<input type="hidden" name="domains" value="harmful.cat-v.org;cat-v.org"></input>
+<label for="sbi" style="display: none">Enter your search terms</label>
+% echo '<input type="text" name="q" size="32" maxlength="255" value="'$title'" id="sbi"></input>'
+<label for="sbb" style="display: none">Submit search form</label>
+<input type="submit" name="sa" value="Google Search" id="sbb"></input>
+</td></tr>
+<tr>
+<td>&nbsp;</td>
+<td nowrap="nowrap">
+<table>
+<tr>
+<td>
+<input type="radio" name="sitesearch" value="" id="ss0"></input>
+<label for="ss0" title="Search the Web"><font size="-1" color="#000000">Web</font></label></td>
+<td>
+<input type="radio" name="sitesearch" value="harmful.cat-v.org" checked id="ss1"></input>
+<label for="ss1" title="Search harmful.cat-v.org"><font size="-1" color="#000000">harmful.cat-v.org</font></label></td>
+</tr>
+<tr>
+<td>
+<input type="radio" name="sitesearch" value="cat-v.org" id="ss2"></input>
+<label for="ss2" title="Search cat-v.org"><font size="-1" color="#000000">cat-v.org</font></label></td>
+<td></td>
+</tr>
+</table>
+<input type="hidden" name="client" value="pub-2060328396151526"></input>
+<input type="hidden" name="forid" value="1"></input>
+<input type="hidden" name="channel" value="6944454412"></input>
+<input type="hidden" name="ie" value="UTF-8"></input>
+<input type="hidden" name="oe" value="UTF-8"></input>
+<input type="hidden" name="cof" value="GALT:#008000;GL:1;DIV:#336699;VLC:663399;AH:center;BGC:FFFFFF;LBGC:336699;ALC:0000FF;LC:0000FF;T:000000;GFNT:0000FF;GIMP:0000FF;LH:48;LW:48;L:http://plan9.bell-labs.com/plan9/img/9logo.jpg;S:http://harmful.cat-v.org;LP:1;FORID:1"></input>
+<input type="hidden" name="hl" value="en"></input>
+</td></tr></table>
+</form>
+<!-- SiteSearch Google -->
+</div>
--- /dev/null
+++ b/tpl/_inc/sidebar.tpl
@@ -1,0 +1,35 @@
+echo '<p class="sideBarTitle">Considered harmful:</p>'
+fn menu {
+    ls -F $1 | sed -e 's,^./,,' -e 's,\.md$,,' | grep -v '^_'| awk '
+    BEGIN { print "<ul class=\"sidebar\">" }
+    END { print "</ul>" }
+    /^([a-zA-Z0-9_\-]+[\/*]?)+$/ && ! /index$/ {
+        isdir = match($0, "/$")
+        sub("[*/]$", "") # The '*' makes no sense to me
+        
+        if(isdir)
+            d = "/"
+        bname = $0
+        sub("^(.*/)?([0-9]+_)?", "", bname)
+        gsub("_", " ", bname)
+
+        bname = bname d
+
+        if(index(ENVIRON["REQUEST_URI"], "/" $0) == 1) {
+            if(isdir) {
+                print "<li><a href=\"/" $0 d "\">&raquo;<i> " bname "</i></a>"
+                system("rc -c ''menu " $0 "''")
+            } else {
+                print "<li><a href=\"/" $0 d "\" class=\"thisPage\">&raquo;<i> " bname "</i></a>"
+            }
+        } else 
+            print "<li><a href=\"/" $0 d "\">&rsaquo; " bname "</a>"
+
+        print "</li>"
+
+    }'
+
+}
+cd tpl
+menu .
+cd ..
--- /dev/null
+++ b/tpl/cat-v/index.md
@@ -1,0 +1,37 @@
+UNIX Style, or cat -v Considered Harmful
+========================================
+
+At the USENIX Summer Conference of 1983 [Rob Pike](http://herpolhode.com/rob/)
+made a presentation titled '*UNIX Style, or cat -v Considered Harmful*' and
+together with Brian Kernighan wrote the paper '*Program Design Design in the
+UNIX Environment*' ([pdf version](unix_prog_design.pdf), [ps
+version](unix_prog_design.ps)).
+
+This was a prelude for their famous book [The Unix Programming
+Environment](http://cm.bell-labs.com/cm/cs/upe/) that today is considered *the
+bible of Unix*.
+
+Unfortunately their advice has been completely ignored, and today Unix has become
+overcome by exactly the kind of mistakes they warned against.
+
+
+    Bell Laboratories
+
+    Murray Hill, NJ (dec!ucb)wav!research!rob
+
+    It seems that UNIX has become the victim of cancerous growth at the hands of
+    organizations such as UCB. 4.2BSD is an order of magnitude larger than Version
+    5, but, Pike claims, not ten times better.
+
+    The talk reviews reasons for UNIX's popularity and shows, using UCB cat as a
+    primary example, how UNIX has grown fat. cat isn't for printing files with line
+    numbers, it isn't for compressing multiple blank lines, it's not for looking at
+    non-printing ASCII characters, it's for concatenating files.
+
+    We are reminded that ls isn't the place for code to break a single column into
+    multiple ones, and that mailnews shouldn't have its own more processing or joke
+    encryption code.
+
+    Rob carried the standard well for the "spirit of UNIX," and you can look
+    forward to a deeper look at the philosophy of UNIX in his forthcoming book.
+
binary files /dev/null b/tpl/children/.i_dont_care.md.swp differ
--- /dev/null
+++ b/tpl/children/fuck_the_children.md
@@ -1,0 +1,82 @@
+George Carlin:
+
+    Something else I'm getting tired of in this country is all this stupid talk
+    I have to listen to about children. That's all you hear about anymore,
+    children: "Help the children, save the children, protect the children." You
+    know what I say? Fuck the children!
+
+    They're getting entirely too much attention. And I know what some of you are
+    thinking: " Jesus, he's not going to attack children, is he?" Yes he is!
+    He's going to attack children. And remember, this is Mr. Conductor talking;
+    I know what I'm talking about.
+
+    And I also know that all you boring single dads and working moms, who think
+    you're such fucking heros, aren't gonna like this, but somebody's gotta tell
+    you for your own good: your children are overrated and overvalued, and
+    you've turned them into little cult objects. You have a child fetish, and
+    it's not healthy. And don't give me all that weak shit, "Well, I love my
+    children." Fuck you! Everybody loves their children; it doesn't make you
+    special. : : : John Wayne Gacy loved his children. Yes, he did. That's not
+    what I'm talking about. What I'm talking about is this constant, mindless
+    yammering in the media, this neurotic fixation that suggests that somehow
+    everything--everything--has to revolve around the lives of children. Ist's
+    completely out of balance.
+
+    Listen, there are a couple of things about kids you have to remember. First
+    of all, they're not all cute. In fact, if you look at 'em real close, most
+    of them are rather unpleasant looking. And a lot of them don't smell too
+    good either. The little ones in particular seem to have a kind of urine and
+    sour-milk combination that I don't care for at all. Stay with me on this
+    folks, the sooner you face it the better off your going to be.
+
+    Second, premise: not all chidren are smart and clever. Got that? Kids are
+    like any other group of people: a few winners, a whole lot of losers! This
+    country is filled with loser kids who simply...aren't...going anywhere! And
+    there's nothing you can do about it, folks. Nothing! You can't save them
+    all. You can't do it. You gotta let 'em go; you gotta cut 'em loose; you
+    gotta stop over-protecting them, because your making 'em too soft.
+
+    Today's kids are way too soft. : : : For one thing, there's too much
+    emphasis on safety and safety equipment: childproof medicine bottles,
+    fireproof pajamas, child restraints, car seats. And helmets! Bicycle,
+    baseball, skateboard, scooter helmets. Kids have to wear helmets now for
+    everything but jerking off. Grown-ups have taken all the fun out of being a
+    kid. : : : What's happened is, these baby boomers, these soft, fruity baby
+    boomers, have raised an entire generation of soft, fruity kids who aren't
+    even allowed hazardous toys, for Chrissakes! What ever happened to natural
+    selection? Survival of the fittest? The kid who swallows too many marbles
+    doesn't grow up to have kids of his own. Simple stuff. Nature knows best!
+
+    Another bunch of ignorant bullshit about your children: school uniforms. Bad
+    theory! The idea that if kids wear uniforms to school, it helps keep order.
+    Hey! Don't these schools do enough damage makin' all these children think
+    alike? Now they're gonna get 'em to look alike, too? : : : And it's not even
+    a new idea; I first saw it in old newsreels from the 1930s, but it was hard
+    to understand, because the narration was in German! But the uniforms looked
+    beautiful. And the children did everything they were told and never
+    questioned authority. Gee, I wonder why someone would want to put our
+    children in uniforms. Can't imagine.
+
+    And one more item about children: this superstitous nonsense of blaming
+    tobacco companies for kids who smoke. Listem! Kids don't smoke because a
+    camel in sunglasses tells them to. They smoke for the same reasons adults
+    do, because it's an enjoyable activity that relieves anxiety and depression.
+
+    And you'd be anxious and depressed too if you had to put up with these
+    pathetic, insecure, yuppie parents who enroll you in college before you've
+    figured out which side of the playpen smells the worst and then fill you
+    with Ritalin to get you in a mood they approve of, and drag you all over
+    town in search of empty, meaningless structure: Little League, Cub Scouts,
+    swimming, soccer, karate, piano, bagpipes, watercolors, witchcraft, glass
+    blowing, and dildo practice. It's absurd. : : : They even have "play dates",
+    for Christ sake! Playing is now done by appointment! But it's true. A lot of
+    these striving, and parents are burning their kids out on structure. I think
+    what every child needs and ought to have every day is two hours of
+    daydreaming. Plain old daydreaming.
+
+    Turn off the internet, the CD-ROMS, and the computer games and let them
+    stare at a tree for a couple of hours. Every now and then they actually come
+    up with one of their own ideas. You want to know how to help your kids?
+    Leave them the fuck alone. 
+
+
--- /dev/null
+++ b/tpl/children/i_dont_care.md
@@ -1,0 +1,58 @@
+    I Don’t Fucking Care About The Children.  18 December 2002
+
+    There. I said it. I don’t care about “the children” - and I don’t care about
+    protecting themselves. Keep your fucking plastic plates away from my outlets.
+    Keep your petitions to shut down the porno houses away from me, let I tear them
+    to bits and urinate upon them. If you tell me to throw away my books, violent
+    movies and games, or the like to keep the minds of children clean - I will tell
+    you to shove your head up your ass, fucker. This insane quest to protect “The
+    Children” is absurd! We coddle and we coddle the damn things and they still
+    turn out maladjusted… wait, maybe they wouldn’t turn out maladjusted if they
+    weren’t coddled! When children used to scream or throw tantrums or beat up
+    other children - they were usually PUNISHED! What a novel concept! Punishment!
+    Negative reinforcement for negative actions - how novel!
+
+    Worst of all, is the foisting of the care and proper raising of these wastes of
+    sperm and egg onto the populace at large! This is of course, when it doesn’t
+    involve the actual mental raising of the child - such as setting limits, or
+    telling the damn thing what it can or cannot do. That will damage it’s precious
+    self-esteem! We can’t have that, can we?! So, if we can’t tell the child
+    they’re doing something wrong, dangerous or illegal - what can we do? We can
+    immediately cease and desist all enjoyable activities that children either
+    cannot, or shoud not be involved in. Activities such as reading books with foul
+    language, playing violent games, watching porn, having pre-marital sex, eating
+    unhealthy foods, or thinking for ourselves.
+
+    Meanwhile, the parents will continue to funnel McDonalds and Easy Mac into
+    junior’s gaping maw because it’s easier than cooking a healthy meal. They will
+    continue to bitch about what’s on the television to politicians while letting
+    junior sit in front of it for 6 hours a day. They complain about women getting
+    abortions, because it “kills precious babies” while letting unwanted children
+    rot in orphanages and state care. They complain about people who say fuck in
+    public, while seeing nothing wrong with assualting anyone who dares tell their
+    child the simple word “No.” They constantly buy all the newest plastic
+    kindercrap, that junior is just going to play with for five minutes, than throw
+    it on the pile. This is the future? A world of spoiled brats who don’t know how
+    to control themselves above being able to hold in their shit until they can
+    find a toilet. A world of morons who blame everyone but themselves for their
+    own shortcomings. A world of closed-minded fuckers who refuse to budge from the
+    Staus Quo?
+
+    For the love of God, I can’t take that! I can’t fucking deal with that shit.
+    It’s not that I want to kill kids. That would involve being near the little
+    buggers long enough to get off a shot. I support public education - assuming
+    it’s good education, and not a glorfied state babysitter who can’t give a child
+    an F without getting reamed by both the parents and the administration. I
+    support socialized health care for everyone - adult and child. That doesn’t
+    mean I think we should suck up and kiss ass to anyone with half a brain and
+    proof of a functioning reproductive system (i.e. a child). Parenting is the
+    parent’s responsibility - not mine, not the government’s. Don’t pass the buck
+    to me, for fuck’s sake. I’m not making you do my computer science homework, so
+    don’t make me suffer the atonal screamings of your twatrocket while I’m trying
+    to eat, and don’t make my put up with your spoiled sprogling demanding what he
+    can’t get.
+
+    It is not my job, fuckers. Parent your own damn children!
+
+    Devo - Jocko Homo/I Need A Chick
+
--- /dev/null
+++ b/tpl/children/index.md
@@ -1,0 +1,16 @@
+Children considered harmful
+===========================
+
+Children are nothing more than a toy some parents use to feed their ego and feel important. They are a nuisance and make life miserable for everyone else around.
+
+Some recommended articles for parents, prospective parents, or anyone that has to suffer the evils caused by little evil goblins.
+
+* [Fuck the children](fuck_the_children) by George Carlin
+* [I Don’t Fucking Care About The Children](i_dont_care) by Devo - Jocko Homo
+
+Alternatives to children
+------------------------
+
+* Contraception
+* Videogames
+
--- /dev/null
+++ b/tpl/default.tpl
@@ -1,0 +1,142 @@
+Content-Type: text/html
+
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+
+<meta name="verify-v1" content="6zEoK0WMlnLmIS/w7Pnh6+srZECHsvnMGN0kQmowSGk=" />
+
+% echo    '<title>'$title'</title>'
+
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta name="copyright" content="&copy; 2007 by k" />
+    <meta name="author" content="uriel" />
+
+    <link rel="stylesheet" href="/style/style.css" type="text/css" media="screen" title="default" />
+    <link rel="stylesheet alternative" type="text/css" href="/style/style_old.css" media="screen" title="Old Style" />
+</head>
+<body>
+
+<div id="header">
+    <div class="superHeader">
+        <div class="left">
+          <a href="http://harmful.cat-v.org">harmful</a> |
+          <a href="http://cat-v.org">cat-v.org</a> |
+          <a href="http://cat-v.org/who/uriel/">uriel</a> |
+          <a href="http://cat-v.org/9p/">9P</a>
+        </div>
+
+        <div class="right">
+          <span class="doNotDisplay">Related sites:</span>
+          <a href="http://9fans.net">Plan 9 from Bell Labs</a> |
+          <a href="http://plan9.us">Plan 9 from User Space</a> |
+          <a href="http://code.google.com/p/inferno-os/">Inferno</a>
+        </div>
+    </div>
+
+    <div class="midHeader">
+        <h1 class="headerTitle">cat-v <span id="headerSubTitle">Considered harmful</span></h1>
+    </div>
+    
+    <div class="subHeader">
+        <br />
+    </div>
+</div>
+
+%if (! ~ $#sidebar 0) {
+<div id="side-bar">
+% #  template.awk $sidebar | rc
+<div>
+%  cat $sidebar | rc
+</div>
+
+    <div class="spam" style="padding: 1em 0;">
+        <script type="text/javascript"><!--
+        google_ad_client = "pub-2060328396151526";
+        google_alternate_color = "3D81EE";
+        google_ad_width = 125;
+        google_ad_height = 125;
+        google_ad_format = "125x125_as";
+        google_ad_type = "text";
+        google_ad_channel = "";
+        google_color_border = "FFFFFF";
+        google_color_bg = "FFFFFF";
+        google_color_link = "0000FF";
+        google_color_text = "000000";
+        google_color_url = "008000";
+        //-->
+        </script>
+        <script type="text/javascript"
+          src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
+        </script>
+    </div>
+</div>
+% }
+
+<div id="main-copy">
+
+    <div class="spam">
+        <script type="text/javascript"><!--
+        google_ad_client = "pub-2060328396151526";
+        google_ad_width = 728;
+        google_ad_height = 15;
+        google_ad_format = "728x15_0ads_al";
+        google_ad_channel = "";
+        google_color_border = "FFFFFF";
+        google_color_bg = "FFFFFF";
+        google_color_link = "0000FF";
+        google_color_text = "000000";
+        google_color_url = "008000";
+        //--></script>
+        <script type="text/javascript"
+          src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
+        </script>
+    </div>
+
+
+% if ( test -f $body ) { cat $body | markdown.pl } 
+% if not { template.awk tpl/_inc/404.tpl | rc }
+
+    <hr />
+
+    <div class="spam">
+        <script type="text/javascript"><!--
+        google_ad_client = "pub-2060328396151526";
+        google_alternate_color = "FFFFFF";
+        google_ad_width = 728;
+        google_ad_height = 90;
+        google_ad_format = "728x90_as";
+        google_ad_type = "text";
+        //2007-05-26: harmful-bottom-banner
+        google_ad_channel = "2301440557";
+        google_color_border = "FFFFFF";
+        google_color_bg = "FFFFFF";
+        google_color_link = "0000FF";
+        google_color_text = "000000";
+        google_color_url = "008000";
+        //-->
+        </script>
+        <script type="text/javascript"
+          src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
+        </script>
+    </div>
+
+</div>
+
+<div id="footer">
+<!--
+%#echo $body
+<br class="doNotDisplay doNotPrint" />
+<div class="right">
+Author: <a href="http://cat-v.org/who/uriel/">uriel</a>
+<br />
+Hosted at: <a href="http://cat-v.org">cat-v.org</a>
+</div>
+-->
+</div>
+
+</body>
+</html>
+
--- /dev/null
+++ b/tpl/economics/index.md
@@ -1,0 +1,34 @@
+Economics
+=========
+
+Economics is a field that is just as often ridiculed, over-simplified, or most often outright ignored.
+
+Despite this economic principles underline every aspect of our world, and the general lack of understanding of this principles is the cause of many of the problems that ail mankind.
+
+In issues of economic policy often (alleged) intentions are given more importance than real consequences, and the generated incentives are ignored.
+
+Here are some of the most misunderstood and harmful economic ideas:
+
+* [Subsidies](subsidies)
+* [Minimum wage](minimum_wage)
+* [Rent controls](rent_controls)
+* Antitrust laws
+
+
+Milton Friedman
+---------------
+
+'*If an exchange between two parties is voluntary, it will not take place unless
+both believe they will benefit from it. Most economic fallacies derive from the
+neglect of this simple insight, from the tendency to assume that there is a fixe
+d pie, that one party can only gain at the expense of another.*'
+
+'*A major source of objection to a free economy is precisely that it ... gives pe
+ople what they want instead of what a particular group thinks they ought to want
+. Underlying most arguments against the free market is a lack of belief in freed
+om itself.*'
+
+'*One of the great mistakes is to judge policies and programmes by their intentio
+ns rather than their results.*'
+
+
--- /dev/null
+++ b/tpl/economics/minimum_wage.md
@@ -1,0 +1,29 @@
+The unintended consequences of the minimum wage
+===============================================
+
+The minimum wage is one of the most persistent and pernicious economic policies, probably only surpassed in ineptitude by [rent controls](rent_controls) and [farm subsidies](subsidies).
+
+Economists have recognized for decades that minimum wage laws result primarily in increased unemployment among the most vulnerable sectors of society, specially poor unskilled teenagers of racial minorities.
+
+The amount of evidence to back this is huge, but still people refuses to accept that just because it sounds like a good idea to magically give poor workers a raise it doesn't mean that it actually works this way.
+
+Ironically the main groups that consistently lobby to raise the minimum wage are unions of skilled workers that already earn much more than the minimum wage, and big business in the retail market who offer salaries slightly above the minimum wage.
+
+This unholy union of unions and big business can be explained if one looks at the real consequences of raising the minimum wage: unskilled workers that might be able to compete with unionized workers thanks to their lower salary are put out of work safewarding the jobs of the well off unionized workers. At the same time small retail business that have very small margins are driven into bankruptcy by big corporations that take advantage of economies of scale and can afford to pay their workers salaries slightly above the minimum wage.
+
+
+Alternatives
+------------
+
+If our goals is to improve the economic situation of disadvantaged workers probably the best known strategy is a negative income tax, this doesn't create negative incentives and preserves the existing positive incentives, it doesn't directly increase unemployment or hurt small business.
+
+
+Links
+-----
+* [50 Years of Research on the Minimum Wage](http://www.house.gov/jec/cost-gov/regs/minimum/50years.htm)
+* [Minimum Wage Teen-age Job Killer](http://www.ncpa.org/ba/ba292.html)
+* [Santa Fe’s Living Wage and the Labor Market](http://www.epionline.org/study_detail.cfm?sid=90)
+* [Spinimum Wage](http://www.tcsdaily.com/article.aspx?id=101606B)
+* [Minimum Wage = Bureaucracy = Disaster](http://unbeknownst.net/?p=71)
+* [Minimum Wage, Maximum Stupidity](http://www.larryelder.com/economics/minimumwage.htm)
+* [The Sin of Wages: The real reason to oppose the minimum wage](http://www.slate.com/id/2103486/)
--- /dev/null
+++ b/tpl/economics/rent_controls.md
@@ -1,0 +1,9 @@
+Rent controls
+=============
+
+"*Rent control appears to be the most efficient technique presently known to destroy a city—except for bombing.*" --  Assar Lindbeck Swedish socialist economist
+
+Links
+-----
+
+* [Rent Control](http://www.econlib.org/library/Enc/RentControl.html) entry in the Concise Encyclopedia of Economics.
--- /dev/null
+++ b/tpl/economics/subsidies.md
@@ -1,0 +1,18 @@
+Subsidies considered harmful
+============================
+
+Farm subsidies are one of the most inept and outright evil economic policies ever invented, trillions of dollars are wasted every year in the world because of farm subsidies in developed countries, while driving into bankruptcy millions of farmers in third world countries.
+
+Millions of tons of food are thrown away because of the ridiculously stupid farm policy of the US and Europe while millions die of starvation.
+
+Links
+-----
+* [In 1985 New Zealand eliminated agricultural subsidies. What happened next?](http://www.tcsdaily.com/article.aspx?id=050907B)
+* [Freeing the Farm: A Farm Bill for All Americans](http://reddit.com/goto?id=1lopk)
+* [farmsubsidy.org](http://farmsubsidy.org)
+* [So that's where the €100 billion went](http://www.guardian.co.uk/eu/story/0,,1995587,00.html)
+* [http://www.heritage.org/Research/Agriculture/BG1542.cfm](http://www.heritage.org/Research/Agriculture/BG1542.cfm)
+* [New Zealand's hardy farm spirit: how ending subsidies created a farming revolution](http://news.bbc.co.uk/2/hi/programmes/from_our_own_correspondent/3747430.stm)
+* [Farming without subsidies? Some lessons from New Zealand](http://www.newfarm.org/features/0303/newzealand_subsidies.shtml)
+
+
--- /dev/null
+++ b/tpl/index.md
@@ -1,0 +1,33 @@
+Encyclopedia of things considered harmful
+=========================================
+
+The world is full of things that most people think are OK or even good, when in
+reality are either evil or plain stupid.
+
+This is my humble contribution to attempt to collect all all the things in the
+world that bother me, if you think I'm missing anything important is missing,
+please feel free to write an article about it and if I agree I will be happy to
+add it to this site.
+
+***Note:*** I just got started, there are hundreds of things I would like to cover, I will try
+to add a new entry every other day or so.
+
+
+The main sections for now are:
+
+* [Software](/software/)
+* [Economics](/economics/)
+
+You can also find other items in the left sidebar.
+
+Recommended sites
+=================
+
+This are sites also dedicated at exposing the stupidity in our world:
+
+* [Bad Science](http://badscience.net) by Ben Goldacre - A great site about crackpot science.
+* [James Randi Educational Foundation](http://www.randi.org/)
+* [Johan Norberg](http://www.johannorberg.net/) - A Swedish writer devoted to globalisation and individual liberty
+* [Free to Choose Media](http://www.freetochoosemedia.org/)
+* [Foundation for a Free Information Infrastructure](http://www.ffii.org/)
+* [Electronic Frontier Foundation](http://www.eff.org/)
--- /dev/null
+++ b/tpl/software/index.md
@@ -1,0 +1,17 @@
+All software sucks
+==================
+
+"*And folks, let's be honest. Sturgeon was an optimist. Way more than 90% of code is crap.*" -- Al viro
+
+"*There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies.*" -- C.A.R. Hoare, The 1980 ACM Turing Award Lecture
+
+"*One of my most productive days was throwing away 1000 lines of code.*" -- Ken Thompson
+
+"*..At first I hoped that such a technically unsound project would collapse but I
+soon realized it was doomed to success. Almost anything in software can be
+implemented, sold, and even used given enough determination. There is nothing a
+mere scientist can say that will stand against the flood of a hundred million
+dollars. But there is one quality that cannot be purchased in this way -and
+that is reliability. The price of reliability is the pursuit of the utmost
+simplicity. It is a price which the very rich find most hard to pay.*" -- C.A.R. Hoare
+
--- /dev/null
+++ b/tpl/software/xml.md
@@ -1,0 +1,32 @@
+XML Sucks
+=========
+
+"*The essence of XML is this: the problem it solves is not hard, and it does not solve the problem well."* -- Phil Wadler, POPL 2003
+
+
+For now see [xmlsucks.org](http://www.xmlsucks.org).
+
+Alternatives
+------------
+
+* Simple custom text formats
+* sexprs
+* csv
+* json
+* ndb-like
+
+Quotes
+------
+
+"*Most xml i've seen makes me think i'm dyslexic.  it also looks constipated,
+and two health problems in one standard is just too much.*" -- Charles Forsyth on 9fans
+
+Alexander Viro on linux-kernel mailing list:
+
+	> > Or even XML. Ouch! No need to throw things at me!
+	>
+	> It seems they would be thrown! XML in kernel is too much. OpenOffice and
+
+	They won't be thrown.  They will be slowly driven under the nails, so that
+	victim could experience the joy equal to that of dealing with XML.
+