added cross-reference generation
diff --git a/ChangeLog b/ChangeLog
index c5a2e4f..5f67e90 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2001-01-11  David Turner <david.turner@freetype.org>
+
+	* docs/docmaker.py: Added cross-references generation as well as  
+	more robust handling of pathname wildward matching
+
 2001-01-10  Werner Lemberg  <wl@gnu.org>
 
 	* docs/docmaker.py: Minor improvements to reduce unwanted spaces
diff --git a/docs/docmaker.py b/docs/docmaker.py
index 752be46..f39ef78 100644
--- a/docs/docmaker.py
+++ b/docs/docmaker.py
@@ -45,14 +45,14 @@
 block_header = "<center><hr width=75%><table width=75%><tr><td>"
 block_footer = "</td></tr></table></center>"
 
-description_header = "<center><table width=65%><tr><td>"
+description_header = "<center><table width=87%><tr><td>"
 description_footer = "</td></tr></table></center><br>"
 
-marker_header = "<center><table width=65% cellpadding=5><tr bgcolor=#EEEEFF><td><em><b>"
+marker_header = "<center><table width=87% cellpadding=5><tr bgcolor=#EEEEFF><td><em><b>"
 marker_inter  = "</b></em></td></tr><tr><td>"
 marker_footer = "</td></tr></table></center>"
 
-source_header = "<center><table width=65%><tr bgcolor=#D6E8FF width=100%><td><pre>"
+source_header = "<center><table width=87%><tr bgcolor=#D6E8FF width=100%><td><pre>"
 source_footer = "</pre></table></center><br>"
 
 
@@ -184,7 +184,7 @@
         return "UNKNOWN_CODE_IDENTIFIER!"
 
 
-    def dump_html( self ):
+    def dump_html( self, identifiers = None ):
         # clean the last empty lines
         #
         l = len( self.lines ) - 1
@@ -239,20 +239,56 @@
         return "UNKNOWN_PARA_IDENTIFIER!"
 
 
-    def dump( self ):
+    def dump( self, identifiers = None ):
         max_width = 50
         cursor    = 0
         line      = ""
+        extra     = None
+        alphanum  = string.lowercase + string.uppercase + string.digits + '_'
 
         for word in self.words:
+
+            # process cross references when needed
+            if identifiers and word and word[0] == '@':
+                word  = word[1:]
+
+                # we need to find non alpha numeric charaters
+                i = len(word)
+                while i > 0 and not word[i-1] in alphanum:
+                    i = i-1
+                    
+                if i > 0:
+                    extra = word[i:]
+                    word  = word[0:i]
+
+                block = identifiers.get( word )
+                if block:
+                    word = '<a href="'+block.html_address()+'">' + word + '</a>'
+                else:
+                    word = '?'+word
+
             if cursor + len( word ) + 1 > max_width:
                 print line
                 cursor = 0
                 line = ""
 
-            line   = line + word + " "
+            line   = line + word
+            if not extra:
+                line = line + " "
             cursor = cursor + len( word ) + 1
 
+            # handle trailing periods, commas, etc.. at the end of
+            # cross references..
+            if extra:
+                if cursor + len( extra ) + 1 > max_width:
+                    print line
+                    cursor = 0
+                    line = ""
+
+                line   = line + extra + " "
+                cursor = cursor + len( extra ) + 1
+                extra  = None
+
         if cursor > 0:
             print line
 
@@ -269,9 +305,9 @@
         return s
 
 
-    def dump_html( self ):
+    def dump_html( self, identifiers = None ):
         print para_header
-        self.dump()
+        self.dump( identifiers )
         print para_footer
 
 
@@ -444,7 +480,7 @@
                 print "</field>"
 
 
-    def dump_html( self ):
+    def dump_html( self, identifiers = None ):
         n        = len( self.items )
         in_table = 0
 
@@ -458,7 +494,7 @@
                     in_table = 0
 
                 for element in item[1]:
-                    element.dump_html()
+                    element.dump_html( identifiers )
 
             else:
                 if not in_table:
@@ -470,13 +506,13 @@
                 print "<b>" + field + "</b></td><td>"
 
                 for element in item[1]:
-                    element.dump_html()
+                    element.dump_html( identifiers )
 
         if in_table:
             print "</td></tr></table>"
 
 
-    def dump_html_in_table( self ):
+    def dump_html_in_table( self, identifiers = None ):
         n        = len( self.items )
         in_table = 0
 
@@ -488,14 +524,14 @@
                 if item[1]:
                     print "<tr><td colspan=2>"
                     for element in item[1]:
-                        element.dump_html()
+                        element.dump_html( identifiers )
                     print "</td></tr>"
 
             else:
                 print "<tr><td><b>" + field + "</b></td><td>"
 
                 for element in item[1]:
-                    element.dump_html()
+                    element.dump_html( identifiers )
 
                 print "</td></tr>"
 
@@ -526,8 +562,10 @@
 class DocBlock:
 
     def __init__( self, block_line_list = [], source_line_list = [] ):
-        self.items   = []                # current ( marker, contents ) list
-        self.section = None              # section this block belongs to
+        self.items    = []                # current ( marker, contents ) list
+        self.section  = None              # section this block belongs to
+        self.filename = "unknown"         # filename defining this block
+        self.lineno   = 0                 # line number in filename
 
         marker       = None              # current marker
         content      = []                # current content lines list
@@ -607,6 +645,17 @@
                 return item[1]
         return None
 
+    def html_address( self ):
+        section = self.section
+        if section and section.filename:
+            return section.filename+'#'+self.name
+
+        return ""  # this block is not in a section ??
+
+
+    def location( self ):
+        return self.filename + ':' + str(self.lineno)
+
 
     def dump( self ):
         for i in range( len( self.items ) ):
@@ -615,9 +664,9 @@
             content.dump()
 
 
-    def dump_html( self ):
+    def dump_html( self, identifiers = None ):
         types      = [ 'type', 'struct', 'functype', 'function',
-                       'constant', 'enum', 'macro' ]
+                       'constant', 'enum', 'macro', 'structure', 'also' ]
 
         parameters = [ 'input', 'inout', 'output', 'return' ]
 
@@ -638,6 +687,7 @@
         # print source code
         #
         if not self.source:
+            print block_footer
             return
 
         lines = self.source
@@ -660,14 +710,14 @@
 
             if marker == "description":
                 print description_header
-                content.dump_html()
+                content.dump_html( identifiers )
                 print description_footer
 
             elif not ( marker in types ):
                 sys.stdout.write( marker_header )
                 sys.stdout.write( marker )
                 sys.stdout.write( marker_inter + '\n' )
-                content.dump_html()
+                content.dump_html( identifiers )
                 print marker_footer
 
         print ""
@@ -716,14 +766,14 @@
         if self.elements.has_key( block.name ):
             sys.stderr.write( "ERROR - duplicate element definition for " +
                               "'" + block.name + "' in section '" +
-                              section.name + "'" )
-            sys.quit()
+                              self.name + "'" )
+            sys.exit()
 
         self.elements[ block.name ] = block
         self.list.append( block )
 
 
-    def dump_html( self ):
+    def dump_html( self, identifiers = None ):
         """make an HTML page from a given DocSection"""
 
         # print HTML header
@@ -739,13 +789,13 @@
         # print description
         #
         print block_header
-        self.description.dump_html()
+        self.description.dump_html( identifiers )
         print block_footer
 
         # print elements
         #
         for element in self.list:
-            element.dump_html()
+            element.dump_html( identifiers )
 
         print html_footer
 
@@ -753,12 +803,11 @@
 class DocSectionList:
 
     def __init__( self ):
-        self.sections        = {}
-        self.list            = []
-        self.current_section = None
-        self.index           = []    # sorted list of blocks that
-                                     # are not sections
-
+        self.sections        = {}    # map section names to section objects
+        self.list            = []    # list of sections (in creation order)
+        self.current_section = None  # current section
+        self.identifiers     = {}    # map identifiers to blocks
+                                     
     def append_section( self, block ):
         name     = string.lower( block.name )
         abstract = block.find_content( "abstract" )
@@ -776,6 +825,10 @@
                 if abstract:
                     stderr.write( "ERROR - duplicate section definition" +
                                   " for '" + name + "'" )
+                    stderr.write( "previous definition in" +
+                                  " '" + section.location() )
+                    stderr.write( "second definition in" +
+                                  " '" + block.location() )
                     sys.quit()
             else:
                 # The old section didn't contain an abstract; we are
@@ -802,10 +855,9 @@
                 self.append_section( block )
 
             elif self.current_section:
-                # sys.stderr.write( "  new block" )
                 self.current_section.add_element( block )
                 block.section = self.current_section
-                self.index.append( block )
+                self.identifiers[block.name] = block
 
 
     def prepare_files( self, file_prefix = None ):
@@ -834,9 +886,10 @@
         self.toc_filename   = prefix + "toc.html"
         self.index_filename = prefix + "index.html"
 
-        # compute the sorted block list for the index
+        # compute the sorted list of identifiers for the index
         #
-        self.index.sort( block_lexicographical_compare )
+        self.index = self.identifiers.keys()
+        self.index.sort()
 
 
     def dump_html_toc( self ):
@@ -857,7 +910,7 @@
                 sys.stdout.write( '<a href="' + section.filename + '">' )
                 sys.stdout.write( section.title )
                 sys.stdout.write( "</a></td><td>" + '\n' )
-                section.abstract.dump_html()
+                section.abstract.dump_html( self.identifiers )
                 print "</td></tr>"
 
         print "</table></center>"
@@ -874,7 +927,7 @@
             if section.filename:
                 new_file   = open( section.filename, "w" )
                 sys.stdout = new_file
-                section.dump_html()
+                section.dump_html( self.identifiers )
                 new_file.close()
 
         sys.stdout = old_stdout
@@ -893,17 +946,20 @@
         print "<center><h1>General Index</h1></center>"
         print "<center><table cellpadding=5><tr valign=top><td>"
 
-        for block in self.index:
-            sys.stdout.write( '<a href="' + block.section.filename +
-                              '#' + block.name + '">' )
-            sys.stdout.write( block.name )
-            sys.stdout.write( "</a><br>" + '\n' )
+        for ident in self.index:
+            block = self.identifiers[ident]
+            if block:
+                sys.stdout.write( '<a href="' + block.html_address() + '">' )
+                sys.stdout.write( block.name )
+                sys.stdout.write( '</a><br>' + '\n' )
 
-            if line * num_columns >= total:
-                print "</td><td>"
-                line = 0
+                if line * num_columns >= total:
+                    print "</td><td>"
+                    line = 0
+                else:
+                    line = line + 1
             else:
-                line = line + 1
+                sys.stderr.write( "identifier '"+ident+"' has no definition" + '\n' )
 
         print "</tr></table></center>"
         print html_footer
@@ -962,24 +1018,51 @@
     print html_footer
 
 
-def make_block_list_inner():
+def file_exists( pathname ):
+    result = 1
+    try:
+        file = open( pathname, "r" )
+        file.close()
+    except:
+        result = None
+
+    return result
+
+
+def add_new_block( list, filename, lineno, block_lines, source_lines ):
+    """add a new block to the list"""
+    block = DocBlock( block_lines, source_lines )
+    block.filename = filename
+    block.lineno   = lineno
+    list.append( block )
+
+
+def make_block_list():
     """parse a file and extract comments blocks from it"""
 
     file_list = []
     sys.stderr.write( repr( sys.argv[1:] ) + '\n' )
 
     for pathname in sys.argv[1:]:
-        newpath = glob.glob( pathname )
-        sys.stderr.write( repr(newpath) + '\n' )
+        if string.find( pathname, '*' ) >= 0:
+            newpath = glob.glob( pathname )
+            newpath.sort()  # sort files, this is important because the order of files
+        else:
+            newpath = [ pathname ]
+
         last = len( file_list )
         file_list[last:last] = newpath
 
     if len( file_list ) == 0:
         file_list = None
+    else:
+        # now filter the file list to remove non-existing ones
+        file_list = filter( file_exists, file_list )
 
     list   = []
     block  = []
     format = 0
+    lineno = 0
 
     # We use "format" to store the state of our parser:
     #
@@ -1018,7 +1101,7 @@
         if format >= 4 and l > 2 and line2[0 : 2] == '/*':
             if l < 4 or ( line2[3] != '@' and line2[3:4] != ' @' and
                           line2[3] != '#' and line2[3:4] != ' #'):
-                list.append( ( block, source ) )
+                add_new_block( list, fileinput.filename(), lineno, block, source )
                 format = 0
 
         if format == 0:  #### wait for beginning of comment ####
@@ -1034,6 +1117,7 @@
                     block  = []
                     source = []
                     format = 1
+                    lineno = fileinput.lineno()
 
                 elif i == l - 1 and line2[i] == '/':
                     # this is '/**' followed by any number of '*', followed
@@ -1042,6 +1126,7 @@
                     block  = []
                     source = []
                     format = 2
+                    lineno = fileinput.lineno()
 
         ##############################################################
         #
@@ -1120,23 +1205,11 @@
                 source.append( line )
 
     if format >= 4:
-        list.append( [block, source] )
+        add_new_block( list, fileinput.filename(), lineno, block, source )
 
     return list
 
 
-# create a list of DocBlock elements
-#
-def make_block_list():
-    source_block_list = make_block_list_inner()
-    list              = []
-
-    for block in source_block_list:
-        docblock = DocBlock( block[0], block[1] )
-        list.append( docblock )
-
-    return list
-
 
 # This function is only used for debugging
 #