diff --git a/changelog b/changelog
index 5d04a1e..d2a5e23 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,6 @@
+20111118 wxh src/axiom-website/patches.html 20111118.01.tpd.patch
+20111118 tpd src/axiom-website/litprog.html added
+20111118 tpd src/axiom-website/documentation.html add litprog.html
 20111117 wxh src/axiom-website/patches.html 20111117.01.tpd.patch
 20111117 tpd src/interp/c-doc.lisp treeshake compiler
 20111117 tpd books/bookvol9 treeshake compiler
diff --git a/src/axiom-website/documentation.html b/src/axiom-website/documentation.html
index f6a5831..c9cbd91 100644
--- a/src/axiom-website/documentation.html
+++ b/src/axiom-website/documentation.html
@@ -123,6 +123,8 @@
   <h1> Why Literate Programming?</h1>
 </center>
 <br/><br/>
+<a href="litprog.html">An example literate program in HTML</a>
+<br/><br/>
 <blockquote>
 <b>I believe that the time is ripe for significantly better documentation of
 programs, and that we can best achieve this by considering programs to be
diff --git a/src/axiom-website/litprog.html b/src/axiom-website/litprog.html
new file mode 100644
index 0000000..04b3383
--- /dev/null
+++ b/src/axiom-website/litprog.html
@@ -0,0 +1,966 @@
+<html>
+ <head>
+  <title>
+   Example of Literate Programming in HTML
+  </title>
+  <meta http-equiv="content-type" content="text/html;charset=utf-8" />
+ </head>
+ <style>
+ div { max-width: 7in; }
+ </style>
+ <body bgcolor="#ffff66" max-width="43em">
+<div>
+ <pre>
+ 1.0    Literate Programming - A Gentle Introduction
+  1.1     What is the problem?
+  1.2     Is there a better way?
+  1.3     Literate Programming -- The basic idea
+  1.3.1     Literate Programming is NOT documentation
+  1.3.2     Literate Programming is a change in mindset
+  1.3.3     Literate Programming reduces bugs
+  1.4     Understanding the literate programming tangle tool
+  1.4.1     Motivation, or getchunk
+  1.4.2     All of the literate programming tools
+ 2.0    The Tangle Program
+  2.1     Understanding the story of the program
+  2.2     The main task
+  2.3     A complication with HTML
+  2.4     Finding the chunk
+  2.5     Finding the next line in the buffer
+  2.6     At last, finding the chunk
+  2.7     Printing the chunk we found
+  2.8     The simple case, print the line
+  2.9     Checking chunks for getchunk tags
+  2.10    Getting a new chunk name from the getchunk tag
+  2.11    Finding the end of the chunk we are printing
+  2.12    Final cleanup and housekeeping. The preamble
+ 3.0    The tangle source code
+ 4.0    What have we learned?
+ </pre>
+</div>
+  <div>
+<a name="1.0"/>
+<h2>1.0 Literate Programming - A Gentle Introduction</h2>
+<h3>1.1 What is the problem?</h3>
+<p>
+In the 1970s I worked on a PDP11/40, which is the same class of
+machine that was used to develop UNIX. My PDP had 8192 bytes of
+memory. The editor used 4096 bytes and left the other 4096 bytes for
+an edit buffer.
+</p><p>
+This meant that the largest file I could create at any time was 4096
+bytes.  As a result, C programs were limited in size. To get around
+this problem we used <tt>include</tt> files, libraries of code,
+linkers, and overlay loaders.  Segment registers exist on the x86
+processors to help overlay loaders.
+</p><p>
+People program today the same way I programmed in the 1970s.  We write
+programs that are made of tiny pieces of sand in hundreds of little
+files spread across dozens of directories. In order to find anything
+we use grep to search files, or we create tools to pre-search
+the files such as Eclipse and IntelliJ.
+</p><p>
+Imagine taking the same approach to calculus. Create a directory for
+each chapter. Take each equation in the chapter and put it in a file.
+Do this for every chapter. Throw away the textbook. <b>Now try to learn
+calculus</b>.
+</p><p>
+That's the way we program today, just like I did in the 1970s.
+</p><p>
+We program to communicate to the machine, not to communicate to people.<br/>
+<b>That's the problem</b>.
+</p>
+
+<h3>1.2 Is there a better way?</h3>
+<p>
+Consider the best possible world. You've been hired at a company and
+join a team that is already working on a program. They hand you a book,
+tell you to go home and read it over the next two weeks. At the end of
+the two weeks you can work on the program as effectively anyone on the
+team. The team has successfully communicated from one human to another.
+</p><p>
+<b>What is in the book?</b>
+</p><p>
+Remember our calculus textbook? It started from the ideas like limits
+and gradually developed the ideas until they could be expressed in
+equations. By the time you got to the equations you already understood
+the concepts. You could look at the equations and see why they matched
+the text. It is the <b>why</b> that is the important part. It is the
+part that our programs are missing.
+</p><p>
+The book you took home uses the same method. You started with the problem
+in chapter 1. Chapter 2 expresses the ideas needed to solve the problem.
+The next few chapters expand on each idea, gradually becoming more specific
+until the idea is reduced to code. By the time you get to the code it 
+should be perfectly clear what the code should look like. Any part of
+the code you don't understand means that the book needs some additional
+words.
+</p>
+<h3>1.3 Literate Programming -- The basic idea</h3>
+<p>
+It is rather pointless to have code in a book, right? Someone could
+change the code and then the book would be out of date.
+</p><p>
+The way to solve this problem is to extract the code directly from the 
+book. That way, every time you change the code in the book you change
+the actual program.
+</p><p>
+How hard is it to write an extraction program that can find the code in 
+the book and extract it to some files? Well, lets suppose we name each
+section of code and call it a <b>chunk</b>.
+</p><p>
+We need a program that lets us find a chunk in a document and extract it.
+The traditional name for such a program is <b>tangle</b>. The tangle
+program takes two arguments, the name of the book and the name of the
+chunk:
+<pre>
+   tangle mybookname chunkname
+</pre>
+</p><p>
+With this simple tool you can now write books that contain the actual
+source code.
+</p>
+<h4>1.3.1 Literate Programming is <b>NOT</b> documentation</h4>
+<p>
+The first reaction is that this is a new, painful form of documentation.
+It is not. Documentation is a <b>how</b> construct. It is a way of 
+explaining how a program works or how an application interface should
+be used. 
+</p><p>
+Literate programming is about <b>why</b>. It explains the ideas. It is
+communication from one person to another. 
+</p><p>
+The <b>why</b> becomes important when you have to maintain and modify
+a program. You can perfectly understand <b>how</b> a subroutine,
+module, or class works. You can explain its input and outputs. What
+you don't understand is <b>why</b> it exists. Nobody writes that
+down. So when you are joining a group and given the directory
+containing thousand of pieces of code, you have <b>no</b> idea why the
+program is structured the way it is.
+</p>
+<h4>1.3.2 Literate Programming is a change in mindset</h3>
+<p>
+In order to do literate programming you have to change the way you
+think. You have to write english text to communicate ideas. You have
+to move from ideas to implementation in a way that make the <b>story</b>
+clear.
+</p><p>
+If programmers were writing a James Bond novel they would create a
+file for JamesBond, MissMoneyPenny, Q, and TheBadGuys. They would
+create a directory for Scenes with subdirectories for Scene1, Scene2,
+and so on. Then they would box up the whole tree, send it to the 
+audience, and tell them 
+<pre>
+   When this program is run, the bad guy dies
+</pre>
+</p><p>
+We live by stories. We tell stories and we remember stories.
+Characters do things and the author tries to convey their motivations
+(the <b>why</b>). Scenes, flashy cars, trick watches, and other items
+are added to solve local problems in the story. The whole story moves
+from the beginning to the end. You can remember the story and you can
+find places where you think it is weak or cheesy or bad.
+</p><p>
+Subroutines, modules, or classes are like characters in a story. They
+need motivation. They need the <b>why</b>. The factory classes, the
+singletons, the garbage collection routines, and other "items" exist
+to solve local problems in the <b>story</b> of the program.
+</p><p>
+Literate programming is about writing the story of your program. What
+are you trying to solve? How are you solving it? Why did you introduce
+piece of code? Is it part of the main story or is it an item that helps
+solve a local problem?
+</p>
+<h4>1.3.3 Literate Programming reduces bugs</h3>
+<p>
+We are all conditioned to follow stories. We do it all the time.
+If I present you with a piece of code without the story then you 
+have to struggle to understand it. Take, for example, this:
+</p>
+<pre id="example.c">
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;string.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+#include &lt;sys/types.h&gt;
+#include &lt;fcntl.h&gt;
+
+/* forward reference for the C compiler */
+int getchunk(char *chunkname);
+
+char *chunkbegin = "&lt;pre id=\"";     int chunkbeginlen = 9;
+char *chunkend = "&lt;/pre&gt;";           int chunkendlen = 6;
+char *chunkget = "&lt;getchunk id=\"";  int chunkgetlen = 14;
+
+/* a memory mapped buffer copy of the file */
+char *buffer;
+int bufsize;
+
+/* return the length of the next line */
+int nextline(int i) {
+  int j;
+  if (i &gt;= bufsize) return(-1);
+  for (j=0; ((i+j &lt; bufsize) && (buffer[i+j] != '\n')); j++);
+  return(j);
+}
+
+/* output the line we need */
+int printline(int i, int length) {
+  int j; 
+  for (j=0; j&lt;length; j++) { putchar(buffer[i+j]); }
+  printf("\n");
+}
+
+/* handle &lt;pre id="chunkname"&gt;            */
+/* is this chunk name we are looking for? */
+int foundchunk(int i, char *chunkname) {
+  if ((strncmp(&buffer[i],chunkbegin,chunkbeginlen) == 0) &&
+      (strncmp(&buffer[i+9],chunkname,strlen(chunkname)) == 0) &&
+      (buffer[i+chunkbeginlen+strlen(chunkname)] == '"') &&
+      (buffer[i+chunkbeginlen+strlen(chunkname)+1] == '&gt;')) return(1);
+  return(0);
+}
+
+/* handle &lt;/pre&gt;   */
+/* is it really an end? */
+int foundEnd(int i) {
+  if (strncmp(&buffer[i],chunkend,chunkendlen) == 0) {
+    return(1); 
+  }
+  return(0);
+}
+
+/* handle &lt;getchunk id="chunkname"/&gt; */
+/* is this line a getchunk?          */
+int foundGetchunk(int i, int linelen) {
+  int len;
+  if (strncmp(&buffer[i],chunkget,chunkgetlen) == 0) {
+   for(len=1; ((len &lt; linelen) && (buffer[i+chunkgetlen+len] != '\"')); len++);
+   return(len);
+  }
+  return(0);
+}
+
+/* Somebody did a getchunk and we need a copy of the name */
+/* malloc string storage for a copy of the getchunk name  */
+char *getChunkname(int k, int getlen) {
+  char *result = (char *)malloc(getlen+1);
+  strncpy(result,&buffer[k+chunkgetlen],getlen);
+  result[getlen]='\0';
+  return(result);
+}
+
+/* print lines in this chunk, possibly recursing into getchunk */
+int printchunk(int i, int chunklinelen, char *chunkname) {
+  int j;
+  int k;
+  int linelen;
+  char *getname;
+  int getlen = 0;
+  for (k=i+chunklinelen+1; ((linelen=nextline(k)) != -1); ) {
+    if ((getlen=foundGetchunk(k,linelen)) &gt; 0) {
+       getname = getChunkname(k,getlen);
+       getchunk(getname);
+       free(getname);
+       k=k+getlen+17;
+    } else {
+    if ((linelen &gt;= chunkendlen) && (foundEnd(k) == 1)) {
+      return(k+chunkbeginlen);
+    } else {
+      printline(k,linelen);
+      k=k+linelen+1;
+    }
+  }}
+  return(k);
+}
+
+/* find the named chunk and call printchunk on it */
+int getchunk(char *chunkname) {
+  int i;
+  int j;
+  int linelen;
+  int chunklen = strlen(chunkname);
+  for (i=0; ((linelen=nextline(i)) != -1); ) {
+    if ((linelen &gt;= chunklen+11) && (foundchunk(i,chunkname) == 1)) {
+      i=printchunk(i,linelen,chunkname);
+    } else {
+      i=i+linelen+1;
+    }
+  }
+  return(i);
+}
+
+void fixHTMLcode() {
+  int point = 0;
+  int mark = 0;
+  int i=0;
+  for(point = 0; point &lt; bufsize;) {
+    if ((buffer[point] == '&') &&
+        (strncmp(&buffer[point+1],"lt;",3) == 0)) {
+      buffer[mark++] = 60;
+      point = point + 4;  
+    } else
+    if ((buffer[point] == '&') &&
+        (strncmp(&buffer[point+1],"gt;",3) == 0)) {
+      buffer[mark++] = 62;
+      point = point + 4;  
+    } else
+      buffer[mark++] = buffer[point++]; 
+  }
+  bufsize = mark;
+}
+
+/* memory map the input file into the global buffer and get the chunk */
+int main(int argc, char *argv[]) {
+  int fd;
+  struct stat filestat;
+  if ((argc &lt; 2) || (argc &gt; 3)) { 
+    perror("Usage: tangle filename chunkname");
+    exit(-1);
+  }
+  fd = open(argv[1], O_RDONLY);
+  if (fd == -1) {
+    perror("Error opening file for reading");
+    exit(-2);
+  }
+  if (fstat(fd,&filestat) &lt; 0) {
+    perror("Error getting input file size");
+    exit(-3);
+  }
+  bufsize = (int)filestat.st_size;
+  buffer = (char *)malloc(bufsize);
+  read(fd,buffer,bufsize);
+  fixHTMLcode(); 
+  getchunk(argv[2]);
+  close(fd);
+  return(0);
+}
+
+</pre>
+<p>
+Odds are good you just skipped over it, right? It is pretty much just a
+long pile of noise. It really doesn't matter if you are a C programmer 
+or not. It is just noise.
+</p>
+<h3>1.4 Understanding the literate programming tangle tool</h3>
+<p>
+We write literate programs to communicate to both people and machines.
+Since they are combined in a single document we need a markup language
+to distinguish human text from machine text as well as a markup language
+to write readable english.
+<p>
+Literate programs don't care what you use as a documentation markup
+language. I prefer latex but for this example we'll use HTML.
+</p><p>
+HTML has a set of markup tags. One of the markup tags is the <tt>pre</tt>
+tag. Anything between the beginning of a <tt>&lt;pre&gt;</tt> tag and the 
+trailing <tt>&lt;/pre&gt;</tt> tag is quoted and
+printed exactly as written.
+</p><p>
+The <tt>pre</tt> tag also has an <tt>id</tt> field which lets us put a
+name on the tag. So we can have many named <tt>pre</tt> tags in a file.
+</p><p>
+The tangle program reads the HTML file and extracts the text in a 
+<tt>pre</tt> chunk. That's almost all of the magic.
+</p>
+<h4>1.4.1 Motivation, or getchunk</h4>
+<p>
+Remember, though, that we wanted to motivate ideas in a program.
+Motivations get introduced in an order that humans can understand.
+So ideas have to be presented in a particular order for humans and
+a different order for machines. We need a way to reorganize the
+program into pieces. The trick is <b>getchunk</b>.
+</p><p>
+We introduce a special tag called <tt>getchunk</tt>. It only occurs
+within a <tt>pre</tt> tag block. The <tt>getchunk</tt> tag has an 
+<tt>id</tt> field which names another chunk. When we find a 
+<tt>getchunk</tt> tag, we read the id name and replace the 
+<tt>getchunk</tt> tag with the named chunk.
+</p><p>
+This <tt>getchunk</tt> tag allows us to "clip out" a piece of a
+program from the middle of a subroutine, put it into its own chunk,
+and wrap some text around it. 
+</p><p>
+This is useful if you have some tricky loop in the middle of a large
+subroutine that you need to explain. You can clip the loop out, put it
+in a <tt>pre</tt> tag of its own and replace it with a <tt>getchunk</tt>.
+</p>
+<h4>1.4.2 All of the literate programming tools</h4>
+<p>
+So we have a single program, called <b>tangle</b>. It works with three
+HTML tags, the <tt>&lt;pre&gt;</tt> tag, the <tt>&lt;/pre&gt;</tt>
+ and the <tt>&lt;getchunk&gt;</tt> tag. They
+look like:
+<pre>
+   &lt;pre id="main.c"&gt;
+   &lt;/pre&gt;
+   &lt;getchunk id="main.c"&gt;
+</pre>
+</p><p>
+That's all there is. 
+</p><p>
+Now you can embed your subroutines in an HTML file, surround it by
+<tt>pre</tt> tags, replace nasty sections with <tt>getchunk</tt> tags
+so you can explain them separately, and you can extract the whole
+set of subroutines using the tangle program.
+</p><p>
+The <b>big loop</b> of program development is now:
+<pre>
+ do forever {
+    edit the html file
+    tangle thehtmlfile sub1.c >sub1.c
+    tangle thehtmlfile sub2.c >sub2.c
+    tangle thehtmlfile main.c >main.c
+    gcc -o myfile sub1.c sub2.c main.c
+    ./myfile
+ }
+</pre>
+</p><p>
+When you are finished for the day, the week, or the project your 
+whole program is properly explained as well as properly maintained.
+</p><p>
+If you did it right you can just point someone at the HTML file,
+let them go away for a while, and when they return they understand
+enough about your program to take over the whole project.
+</p><p>
+But wait, you say... you skipped over the hard part.
+</p><p>
+Indeed, I did. The hard part is that you need to communicate your
+ideas to another human. And you have to do it in a way that reduces
+your idea to practice. In fact, you need to <b>clearly</b> reduce your
+ideas to practice.
+</p>
+<h2>2.0 The Tangle Program</h2>
+<h3>2.1 Understanding the story of the program</h3>
+<p>
+We will try to illustrate literate programming using the tangle
+program as an example. However, if you want to see a <b>real</b>
+literate program I strongly recommend the book:
+<pre>
+  Lisp in Small Pieces by Christian Queinnec (ISBN 0-521-54566-8)
+</pre>
+</p><p>
+We would like to write programs embedded in documents which surround
+the program text with explanations. Since the compiler cannot
+understand the markup language we need a program, which we will call
+tangle, that wil extract code from a document in a given markup
+language.
+</p><p>
+The tangle program is specific to the markup language used, whether it is
+latex, HTML, or some other language. For this example we are assuming
+that the markup is HTML.
+</p><p>
+The markup language has to have some sort of <tt>verbatim</tt> quoting
+mechanism which allows us to put code inline. It also has to have a way
+to name the quoted pieces of code. We call the quoted pieces of code a
+<tt>chunk</tt>. We call the label the <tt>chunkname</tt>.
+</p><p>
+HTML uses the <tt>pre</tt> tag as its quoting mechanism. Items between
+the opening <tt>pre</tt> tag and the closing <tt>/pre</tt> tag are
+unchanged by HTML processors. The <tt>pre</tt> tag has an <tt>id</tt>
+parameter. We will use the <tt>id</tt> parameter as a chunk name.
+</p><p>
+The tangle program takes two arguments, the name of the document and
+the name of the chunk. It must print the chunk on standard output.
+</p>
+<h3>2.2 The main task</h3>
+<p>
+The main thing we have to do is find a chunk somewhere in our book.
+We specified the book and the chunk name on the command line so we
+ought to check that we have the right inputs. 
+</p><p>
+There can only be two inputs and they are both requires so first
+we check that condition. If there are not two then the user might not
+understand what was required so we print the usual <tt>usage</tt> message.
+</p><p>
+We have huge amounts of memory so we will simply load the file in a 
+single chunk using the <tt>read</tt> function. This 
+requires that we can open the file, which we check. It requires a
+handle to the file, which we get from the open call. It requires the
+size of the file so it can allocate memory, so we use <tt>fstat</tt>.
+</p><p>
+Now that we have all of the <tt>read</tt> parameters we can load the
+file into memory. The <tt>buffer</tt> variable is described as a pointer to
+a character which is C-speak for a string. 
+</p><p>
+We also need to know the size of the buffer at all times so we
+allocate the <tt>bufsize</tt> variable at global scope.
+</p>
+<pre id="buffer">
+
+/* a memory mapped buffer copy of the file */
+char *buffer;
+int bufsize;
+
+</pre>
+<p>
+Since the buffer is being used everywhere we make it global by
+defining it at the top of the program, outside the scope of the
+functions.
+</p>
+<pre id="main">
+/* memory map the input file into the global buffer and get the chunk */
+int main(int argc, char *argv[]) {
+  int fd;
+  struct stat filestat;
+  if ((argc < 2) || (argc > 3)) { 
+    perror("Usage: tangle filename chunkname");
+    exit(-1);
+  }
+  fd = open(argv[1], O_RDONLY);
+  if (fd == -1) {
+    perror("Error opening file for reading");
+    exit(-2);
+  }
+  if (fstat(fd,&filestat) < 0) {
+    perror("Error getting input file size");
+    exit(-3);
+  }
+  bufsize = (int)filestat.st_size;
+  buffer = (char *)malloc(bufsize);
+  read(fd,buffer,bufsize);
+  fixHTMLcode(); 
+  getchunk(argv[2]);
+  close(fd);
+  return(0);
+}
+
+</pre>
+<p>
+If the <tt>read</tt> succeeds we move on to the problem of finding
+the named chunk in the book.
+</p>
+<h3>2.3 A complication with HTML</h3>
+<p>
+HTML is not clever about ignoring HTML symbols in <tt>&lt;pre&gt;</tt>
+blocks of code. This causes us three complications which do not normally
+occur with a tangle program. 
+</p><p>
+The first complication can be seen by viewing the source for this page.
+We need to replace the angle brackets with the HTML escape codes 
+everywhere, including in the verbatim sections. So we have to be careful
+using certain language constructs. Reasonable markup languages such
+as latex do not have this problem.
+</p><p>
+The second complication is that the string search for the <tt>pre</tt>,
+<tt>/pre</tt> and <tt>getchunk</tt> tags need to use the escape code
+sequence for matching.
+</p><p>
+The third complication is that the tangle program has to reverse 
+this translation when printing the program.
+</p><p>
+There is no such thing as a simple job.
+</p><p>
+The trick here will be to walk the buffer and replace every use of
+the HTML code with the corresponding character, appropriately adjusting
+the space. Since HTML codes are always longer than the character they
+replace we can just compress the buffer a bit. And since the buffer is
+never used for anything else we can even replace the HTML codes in parts
+of the buffer where it might be inappropriate.
+</p><p>
+The <tt>point</tt> variable is where we are looking in the buffer.
+The <tt>mark</tt> variable is where we are writing in the buffer.
+Normally we just walk them in parallel. They diverge when they hit an
+HTML code. The <tt>point</tt> is copied to the <tt>mark</tt>. In the
+absence of any codes this is a copy of the buffer to itself.
+</p><p>
+When we hit a code we place the corresponding character at the <tt>mark</tt>,
+bump the <tt>point</tt> over the HTML code, and continue the copy.
+</p><p>
+When we hit the end of the buffer we rewrite the <tt>bufsize</tt> variable
+to reflect the new, shorter buffer size.
+</p><p>
+There is another really subtle point here. Note that we have to do the
+comparison in two pieces otherwise the combined string is a valid HTML
+code and we end up destroying our own search string. If we break it
+into two parts then the substring "lt;" is not a valid HTML code and
+will not be replaced. <b>This</b> is the kind of information that
+literate programming preserves. A clever programmer would combine the
+two tests into the single strncmp and everything will fail.
+<pre id="fixHTMLcode">
+void fixHTMLcode() {
+  int point = 0;
+  int mark = 0;
+  int i=0;
+  for(point = 0; point < bufsize;) {
+    if ((buffer[point] == '&') &&
+        (strncmp(&buffer[point+1],"lt;",3) == 0)) {
+      buffer[mark++] = 60;
+      point = point + 4;  
+    } else
+    if ((buffer[point] == '&') &&
+        (strncmp(&buffer[point+1],"gt;",3) == 0)) {
+      buffer[mark++] = 62;
+      point = point + 4;  
+    } else
+      buffer[mark++] = buffer[point++]; 
+  }
+  bufsize = mark;
+}
+
+</pre>
+<h3>2.4 Finding the chunk</h3>
+<p>
+We are given the chunkname as a string and we have to search the
+file for the <br/><tt>&lt;pre id="name"&gt;</tt> tag. 
+</p><p>
+Since the string came from the command line we know that it ends
+with a null character so we can just call <tt>strlen</tt> to get
+the length.
+</p><p>
+<b>By design</b>, we require the <tt>&lt;pre&gt;</tt> tag to start in the first
+character of the line. We could remove this restriction if we
+felt like being clever but code is usually left-aligned in the
+output so left-aligning the tag is reasonable. 
+</p><p>
+Given this <b>design decision</b> we can walk the book one line at a time.
+We delegate the task of finding the line length <tt>linelen</tt> to
+the <tt>nextline</tt> function.  The "magic number" 11 exists because
+the smallest <tt>pre</tt> tag contains 11 characters:
+<pre>
+&lt;pre id=""&gt;
+</pre>
+</p><p>
+If the line is long enough to contain the <tt>&lt;pre&gt;</tt> tag and its
+associated <tt>id</tt> tag and we find the named chunk then we 
+print it.
+</p><p>
+Another <b>design decision</b> is that we will allow multiple chunks with
+the same name and we will print them in order. This allows us to 
+break a big block into smaller blocks and insert text in the middle.
+So you can write
+</p>
+<pre>
+    &lt;pre id="somename"&gt;
+       the first part of a function
+    &lt;/pre&gt;
+    some explanation
+    &lt;pre id="somename"&gt;
+       the next part of the function
+    &lt;/pre&gt;
+    more explanation
+</pre>
+When you run <tt>tangle filename somename</tt> you will see the output:
+<pre>
+  the first part of a function
+  the next part of the function
+</pre>
+<p>
+This is trivial to implement. All we have to do is keep searching the
+document and printing the same named chunk.
+</p>
+<a name="getchunk"/>
+<pre id="getchunk">
+/* find the named chunk and call printchunk on it */
+int getchunk(char *chunkname) {
+  int i;
+  int j;
+  int linelen;
+  int chunklen = strlen(chunkname);
+  for (i=0; ((linelen=nextline(i)) != -1); ) {
+    if ((linelen &gt;= chunklen+11) && (foundchunk(i,chunkname) == 1)) {
+      i=printchunk(i,linelen,chunkname);
+    } else {
+      i=i+linelen+1;
+    }
+  }
+  return(i);
+}
+
+</pre>
+<h3>2.5 Finding the next line in the buffer</h3>
+<p>
+The <tt>nextline</tt> function just walks the buffer starting at any
+character position and returns the character position after the next
+newline. We only have to check that we don't run off the end of the
+buffer, otherwise we just keep a count of the character position.
+</p>
+<pre id="nextline">
+/* return the length of the next line */
+int nextline(int i) {
+  int j;
+  if (i >= bufsize) return(-1);
+  for (j=0; ((i+j < bufsize) && (buffer[i+j] != '\n')); j++);
+  return(j);
+}
+
+</pre>
+
+<h3>2.6 At last, finding the chunk</h3>
+<p>
+We are positioned at the beginning of a line so we are looking at
+something that looks like:
+<pre>
+&lt;pre id="somechunkname"&gt;
+</pre>
+<p>
+We need to check the format of the line. The first 9 characters must be:
+</p>
+<pre>
+&lt;pre id="
+</pre>
+<p>
+The next substring must be the chunkname we seek and the rest of
+line must be the
+<pre>
+"&gt;
+</pre>
+<p>
+So if we find a properly formed line with the chunk name then we 
+return a 1 indicating success, otherwise we return a 0 indicating failure.
+</p><p>
+In a fit of hasty generality we allocate the <tt>chunkbegin</tt>
+information at the global scope. In theory we would like to be able to
+just change the patterns for different markup languages.
+<pre id="chunkbegin">
+char *chunkbegin = "&lt;pre id=\"";     int chunkbeginlen = 9;
+</pre>
+<pre id="foundchunk">
+/* handle &lt;pre id="chunkname"&gt;            */
+/* is this chunk name we are looking for? */
+int foundchunk(int i, char *chunkname) {
+  if ((strncmp(&buffer[i],chunkbegin,chunkbeginlen) == 0) &&
+      (strncmp(&buffer[i+9],chunkname,strlen(chunkname)) == 0) &&
+      (buffer[i+chunkbeginlen+strlen(chunkname)] == '"') &&
+      (buffer[i+chunkbeginlen+strlen(chunkname)+1] == '&gt;')) return(1);
+  return(0);
+}
+
+</pre>
+
+<h3>2.7 Printing the chunk we found </h3>
+<p>
+So we found our chunk and all we have to do is print it.
+We just print each line until we find the <tt>&lt;/pre&gt;</tt> tag,
+a task we delegate to the <tt>foundEnd</tt> function.
+</p><p>
+Of course, there is no such thing as a simple job and, indeed,
+there is a complication here. We made a <b>design decision</b>
+that we will allow a <tt>getchunk</tt> tag to have special meaning
+within the <tt>pre</tt> tag.
+</p><p>
+We delegate getting the <tt>id</tt> from the <tt>getchunk</tt> tag
+to the <tt>getChunkname</tt> function which we will examine next.
+</p><p>
+Recall that <tt>getchunk</tt> will search the document for the 
+<tt>pre</tt> tag named by the <tt>getchunk's</tt> <tt>id</tt> label.
+This means that we need to
+<pre>
+  1) stop printing the current chunk
+  2) find the chunk named by getchunk and print it
+  3) continue printing the original chunk where we left off
+</pre>
+<p>
+We already have a function to do step 2, the 
+<a href="#getchunk">getchunk</a> function mentioned above.
+We can just call that function which handles both finding and
+printing a chunk.
+</p>
+The magic number 17 occurs because we need to account for all of
+the characters in the line which are not part of the <tt>id</tt>
+string in the <tt>getchunk</tt>. So an empty string, including
+the trailing newline is:
+<pre>
+&lt;getchunk id=""&gt;\n   a total of 17 characters
+</pre>
+<pre id="printchunk">
+/* print lines in this chunk, possibly recursing into getchunk */
+int printchunk(int i, int chunklinelen, char *chunkname) {
+  int j;
+  int k;
+  int linelen;
+  char *getname;
+  int getlen = 0;
+  for (k=i+chunklinelen+1; ((linelen=nextline(k)) != -1); ) {
+    if ((getlen=foundGetchunk(k,linelen)) > 0) {
+       getname = getChunkname(k,getlen);
+       getchunk(getname);
+       free(getname);
+       k=k+getlen+17;
+    } else {
+    if ((linelen >= chunkendlen) && (foundEnd(k) == 1)) {
+      return(k+chunkbeginlen);
+    } else {
+      printline(k,linelen);
+      k=k+linelen+1;
+    }
+  }}
+  return(k);
+}
+
+</pre>
+
+<h3>2.8 The simple case, print the line</h3>
+In the simple case we simply output the line.
+<pre id="printline">
+/* output the line we need */
+int printline(int i, int length) {
+  int j; 
+  for (j=0; j&lt;length; j++) { putchar(buffer[i+j]); }
+  printf("\n");
+}
+
+</pre>
+<h3>2.9 Checking chunks for <tt>getchunk</tt> tags</h3>
+<p>
+Because we treat the <tt>getchunk</tt> tag as a special case when we
+are printing we need a predicate to look for it. We are positioned at
+the beginning of a line when we are called so we only need to check
+for the string we call <tt>chunkget</tt>, that is:
+<pre id="chunkget">
+char *chunkget = "&lt;getchunk id=\"";  int chunkgetlen = 14;
+</pre>
+
+This predicate returns the length of the chunkname or 0 if it is not
+a <tt>getchunk</tt> tag.
+<pre id="foundGetchunk">
+/* handle <getchunk id="chunkname"/> */
+/* is this line a getchunk?          */
+int foundGetchunk(int i, int linelen) {
+  int len;
+  if (strncmp(&buffer[i],chunkget,chunkgetlen) == 0) {
+   for(len=1; ((len < linelen) && (buffer[i+chunkgetlen+len] != '\"')); len++);
+   return(len);
+  }
+  return(0);
+}
+
+</pre>
+
+<h3>2.10 Getting a new chunk name from the getchunk tag</h3>
+<p>
+We have encountered a &lt;getChunkName&gt; tag. We need to strip out
+the <tt>id</tt> string. We malloc a small piece of memory to contain
+the name. Note that this is a potential memory leak since we are 
+letting allocated memory leave this function. The caller must remember
+to free it. If we check the caller, the <tt>printchunk</tt> function
+we see that the buffer is freed and memory does not leak.
+</p>
+<pre id="getChunkname">
+/* Somebody did a getchunk and we need a copy of the name */
+/* malloc string storage for a copy of the getchunk name  */
+char *getChunkname(int k, int getlen) {
+  char *result = (char *)malloc(getlen+1);
+  strncpy(result,&buffer[k+chunkgetlen],getlen);
+  result[getlen]='\0';
+  return(result);
+}
+
+</pre>
+
+<h3>2.11 Finding the end of the chunk we are printing</h3>
+<p>
+The <tt>printchunk</tt> routine delegated the task of finding the
+<tt>&lt;/pre&gt;</tt> tag to <tt>foundEnd</tt>. If we find the
+tag we return 1 otherwise we return 0.
+</p><p>
+The <tt>chunkend</tt> and <tt>chunkendlen</tt> variables are allocated
+in the global scope.
+<pre id="chunkend">
+char *chunkend = "&lt;/pre&gt;";           int chunkendlen = 6;
+</pre>
+
+<pre id="foundEnd">
+/* handle &lt;/pre&gt;   */
+/* is it really an end? */
+int foundEnd(int i) {
+  if (strncmp(&buffer[i],chunkend,chunkendlen) == 0) {
+    return(1); 
+  }
+  return(0);
+}
+
+</pre>
+
+<h3>2.12 Final cleanup and housekeeping. The preamble</h3>
+
+C compilers aren't smart enough to look up symbols everyone uses so we
+have to tell it where to find them. We also need to forward reference
+the <tt>getchunk</tt> function because it is used before it exists.
+Compilers in 1970 couldn't handle such complexity. It is terribly
+hard, you know.
+
+<pre id="include">
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;string.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+#include &lt;sys/types.h&gt;
+#include &lt;fcntl.h&gt;
+
+/* forward reference for the C compiler */
+int getchunk(char *chunkname);
+
+</pre>
+
+<h2>3.0 The tangle source code</h2>
+<p>
+The big chunk of code at the beginning of this book is a working
+tangle program. You can clip it out of a web page, save it as
+tangle.c, type
+<pre>
+   gcc -o tangle tangle.c
+</pre>
+and you now have a working tangle program for HTML files. If you want
+to improve it just modify this web page and run tangle again to extract
+your changes. 
+</p><p>
+Alternatively you can get the tangle source code from 
+<a href="http://daly.literatesoftware.com/lithtml/tangle.c">here</a>
+</p><p>
+When we want the whole program we output this chunk with the command:
+</p>
+<pre>
+    tangle litprog.html tangle.c &gt;tangle.c
+</pre>
+and it recreates the tangle.c function.
+
+<pre id="tangle.c">
+&lt;getchunk id="include"&gt;
+&lt;getchunk id="chunkbegin"&gt;
+&lt;getchunk id="chunkend"&gt;
+&lt;getchunk id="chunkget"&gt;
+&lt;getchunk id="buffer"&gt;
+&lt;getchunk id="nextline"&gt;
+&lt;getchunk id="printline"&gt;
+&lt;getchunk id="foundchunk"&gt;
+&lt;getchunk id="foundEnd"&gt;
+&lt;getchunk id="foundGetchunk"&gt;
+&lt;getchunk id="getChunkname"&gt;
+&lt;getchunk id="printchunk"&gt;
+&lt;getchunk id="getchunk"&gt;
+&lt;getchunk id="fixHTMLcode"&gt;
+&lt;getchunk id="main"&gt;
+</pre>
+
+<h2>4.0 What have we learned?</h2>
+<p>
+We have walked through a fairly simple program in great detail.  You
+now understand why HTML causes problems, you understand what the magic
+numbers in the program mean, and you understand the design decisions
+such as always have <tt>pre</tt> tags in the first column.
+</p><p>
+We have learned that we only need a simple 160 line tangle program to
+handle all of the literate programming tasks. You can make this more
+complex if you like. You could create a tangle plugin for Eclipse. You
+could add automatic indexing. Many people have done similar things
+with their literate tools.
+</p><p>
+Ultimately, though, the <b>important</b> point is that you need to
+write programs to communicate with other people. We do not do that
+now. The result is that there are tens of thousands of programs on
+Sourceforge and Savannah and Github that are never going to be used
+because nobody understands them.
+</p><p>
+We can do better. We can make programs that live. We can communicate
+our ideas in ways that others can understand without talking to us.
+</p><p>
+We can be better programmers.
+</p><p>
+Tim Daly, November 18, 2011
+</p><p>
+  </div>
+ </body>
+</html>
diff --git a/src/axiom-website/patches.html b/src/axiom-website/patches.html
index fef254b..91bde71 100644
--- a/src/axiom-website/patches.html
+++ b/src/axiom-website/patches.html
@@ -3686,5 +3686,7 @@ books/bookvol9 treeshake compiler<br/>
 src/interp/i-spec2.lisp fix AN has sqrt: % -> %<br/>
 <a href="patches/20111117.01.tpd.patch">20111117.01.tpd.patch</a>
 books/bookvol9 treeshake compiler<br/>
+<a href="patches/20111118.01.tpd.patch">20111118.01.tpd.patch</a>
+src/axiom-website/litprog.html added<br/>
  </body>
 </html>
