5.7. Glossary and FAQ

This book looks straightforward, but we had to take a roundabout approach to the organization. We wanted to organize the book as a collection of chapters, similar to the rest of the books. This meant that instead of using the <glossary> tag which would have created a glossary outside of the chapter structure, we used the <glosslist> tag to hold the <glossentry> tags.

The List of Terms for the glossary is automatically generated by a Gamma program (shown below) that reads the doc/i/glossary/gl.sgml file, extracts the term names, and creates a new SGML file, doc/i/glossary/termslist.sgml, which is a list of all the terms in the glossary linked to their respective entries.

[Important]

The Gamma program is not a sophisticated SGML parser--it only parses a few elements, and it can only parse these elements if they are written on one line. So make sure when you edit the doc/i/glossary/gl.sgml or add new entries, not to reformat or wrap the lines.

This is the code for writeglosstoc.g:

#!/usr/cogent/bin/gamma

/* This program reads a list of DocBook <glossaryentry> elements,
   extracts the term names, and writes a DocBook page of the
   term names, with links to the glossary.
 */

function write_line (file, printstring)
{
  local fd;
  if (fd = open (file, "a"))
    {
      writec (fd, printstring);
      flush(fd);
      close(fd);
    }
  else
    error (string("Failed to open file: ", file));
}

function pick_a_word(ln, startpt, endpt, ptlength)
{
  local wordstart, wordend, results;
  wordstart = strstr(ln, startpt);
  if (wordstart != -1)
    {
      wordstart = wordstart + ptlength;
      wordend = strstr(ln, endpt);
      results = string(substr(ln, wordstart, wordend - wordstart));
      results;
    }
}

function get_terms(file)
{
  local fd, termlist = list(), line = nil, idstart, idend,
  termid, termstart, termend, term;
  
  fd = open(file, "r");
  while (line != _eof_)
    {
      line = read_line(fd);
      idstart = strstr(line,"<glossentry id=");
      if (idstart != -1)
	{
	  termid = pick_a_word(line, "<glossentry id=", "\">", 16);
	  line = read_line(fd);
	  term = pick_a_word(line, "<glossterm>", "</glossterm>", 11);
	  termset = list(termid, term);

	  termset = reverse(termset);
	  termlist = cons(termset, termlist);
	}
      else
	{
	  idstart = strstr(line, "<glossentry>");
	  if (idstart != -1)
	    {
	      line = read_line(fd);
	      termstart = strstr(line,"<glossterm>");
	      term = pick_a_word(line, "<glossterm>", "</glossterm>", 11);
	      termidstart = strstr(line,"<glosssee otherterm=\"");
	      line = read_line(fd);
	      termid = pick_a_word(line, "<glosssee otherterm=\"", "\">", 21);
	      termset = list(termid, term);
	      termset = reverse(termset);
	      termlist = cons(termset, termlist);
	    }
	}
    }      
  close(fd);
  termlist = reverse(termlist);
  termlist;
}


function write_term(filename, termname, idname)
{
	write_line(filename, string (
"<member><glossterm linkend=\"", idname, "\"\>", termname, "</glossterm></member>\n"));
}


function main()
{
  local termlist, writefile, trm;
  
  termlist = get_terms("gl.sgml");
  writefile = "termslist.sgml";
  unlink(writefile);

  
  with trm in termlist do
    {
      write_term(writefile, car(trm), cadr(trm));
    }
}