shithub: freetype+ttf2subf

Download patch

ref: a7a4207d1087a33521f9d76a0a2271141ebd73c8
parent: f1094c0951f1bc5a11a1de82a1690df7d589018d
author: Werner Lemberg <[email protected]>
date: Mon Nov 24 01:44:45 EST 2014

[docmaker] Formatting, copyright, improved documentation.

* src/tools/docmaker/*: No code changes besides trivial
modifications.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2014-11-24  Werner Lemberg  <[email protected]>
+
+	[docmaker] Formatting, copyright, improved documentation.
+
+	* src/tools/docmaker/*: No code changes besides trivial
+	modifications.
+
 2014-11-22  Werner Lemberg  <[email protected]>
 
 	[bdf] Fix Savannah bug #43660.
--- a/src/tools/docmaker/content.py
+++ b/src/tools/docmaker/content.py
@@ -1,57 +1,81 @@
-#  Content (c) 2002, 2004, 2006-2009, 2012, 2013
-#    David Turner <[email protected]>
 #
-#  This file contains routines used to parse the content of documentation
-#  comment blocks and build more structured objects out of them.
+#  content.py
 #
+#    Parse comment blocks to build content blocks (library file).
+#
+#  Copyright 2002, 2004, 2006-2009, 2012-2014 by
+#  David Turner.
+#
+#  This file is part of the FreeType project, and may only be used,
+#  modified, and distributed under the terms of the FreeType project
+#  license, LICENSE.TXT.  By continuing to use, modify, or distribute
+#  this file you indicate that you have read the license and
+#  understand and accept it fully.
 
+#
+# This file contains routines to parse documentation comment blocks,
+# building more structured objects out of them.
+#
+
+
 from sources import *
-from utils import *
+from utils   import *
+
 import string, re
 
 
-# this regular expression is used to detect code sequences. these
-# are simply code fragments embedded in '{' and '}' like in:
 #
-#  {
-#    x = y + z;
-#    if ( zookoo == 2 )
-#    {
-#      foobar();
-#    }
-#  }
+# Regular expressions to detect code sequences.  `Code sequences' are simply
+# code fragments embedded in '{' and '}', as demonstrated in the following
+# example.
 #
-# note that indentation of the starting and ending accolades must be
-# exactly the same. the code sequence can contain accolades at greater
-# indentation
+#   {
+#     x = y + z;
+#     if ( zookoo == 2 )
+#     {
+#       foobar();
+#     }
+#   }
 #
+# Note that the indentation of the first opening brace and the last closing
+# brace must be exactly the same.  The code sequence itself should have a
+# larger indentation than the surrounding braces.
+#
 re_code_start = re.compile( r"(\s*){\s*$" )
 re_code_end   = re.compile( r"(\s*)}\s*$" )
 
 
-# this regular expression is used to isolate identifiers from
-# other text
 #
+# A regular expression to isolate identifiers from other text.
+#
 re_identifier = re.compile( r'((?:\w|-)*)' )
 
 
-# we collect macros ending in `_H'; while outputting the object data, we use
-# this info together with the object's file location to emit the appropriate
-# header file macro and name before the object itself
 #
-re_header_macro = re.compile( r'^#define\s{1,}(\w{1,}_H)\s{1,}<(.*)>' )
-
-
-#############################################################################
+# We collect macro names ending in `_H' (group 1), as defined in
+# `config/ftheader.h'.  While outputting the object data, we use this info
+# together with the object's file location (group 2) to emit the appropriate
+# header file macro and its associated file name before the object itself.
 #
-# The DocCode class is used to store source code lines.
+# Example:
 #
-#   'self.lines' contains a set of source code lines that will be dumped as
-#   HTML in a <PRE> tag.
+#   #define FT_FREETYPE_H <freetype.h>
 #
-#   The object is filled line by line by the parser; it strips the leading
-#   "margin" space from each input line before storing it in 'self.lines'.
-#
+re_header_macro = re.compile( r'^#define\s{1,}(\w{1,}_H)\s{1,}<(.*)>' )
+
+
+################################################################
+##
+##  DOC CODE CLASS
+##
+##  The `DocCode' class is used to store source code lines.
+##
+##  `self.lines' contains a set of source code lines that will be dumped as
+##  HTML in a <PRE> tag.
+##
+##  The object is filled line by line by the parser; it strips the leading
+##  `margin' space from each input line before storing it in `self.lines'.
+##
 class  DocCode:
 
     def  __init__( self, margin, lines ):
@@ -77,12 +101,14 @@
 
 
 
-#############################################################################
-#
-# The DocPara class is used to store "normal" text paragraph.
-#
-#   'self.words' contains the list of words that make up the paragraph
-#
+################################################################
+##
+##  DOC PARA CLASS
+##
+##  `Normal' text paragraphs are stored in the `DocPara' class.
+##
+##  `self.words' contains the list of words that make up the paragraph.
+##
 class  DocPara:
 
     def  __init__( self, lines ):
@@ -123,17 +149,18 @@
         return result
 
 
-
-#############################################################################
-#
-#  The DocField class is used to store a list containing either DocPara or
-#  DocCode objects. Each DocField also has an optional "name" which is used
-#  when the object corresponds to a field or value definition
-#
+################################################################
+##
+##  DOC FIELD CLASS
+##
+##  The `DocField' class stores a list containing either `DocPara' or
+##  `DocCode' objects.  Each DocField object also has an optional `name'
+##  that is used when the object corresponds to a field or value definition.
+##
 class  DocField:
 
     def  __init__( self, name, lines ):
-        self.name  = name  # can be None for normal paragraphs/sources
+        self.name  = name  # can be `None' for normal paragraphs/sources
         self.items = []    # list of items
 
         mode_none  = 0     # start parsing mode
@@ -143,14 +170,14 @@
         margin     = -1    # current code sequence indentation
         cur_lines  = []
 
-        # now analyze the markup lines to see if they contain paragraphs,
-        # code sequences or fields definitions
+        # analyze the markup lines to check whether they contain paragraphs,
+        # code sequences, or fields definitions
         #
         start = 0
         mode  = mode_none
 
         for l in lines:
-            # are we parsing a code sequence ?
+            # are we parsing a code sequence?
             if mode == mode_code:
                 m = re_code_end.match( l )
                 if m and len( m.group( 1 ) ) <= margin:
@@ -161,10 +188,10 @@
                     cur_lines = []
                     mode      = mode_none
                 else:
-                    # nope, continue the code sequence
+                    # otherwise continue the code sequence
                     cur_lines.append( l[margin:] )
             else:
-                # start of code sequence ?
+                # start of code sequence?
                 m = re_code_start.match( l )
                 if m:
                     # save current lines
@@ -222,13 +249,29 @@
         return result
 
 
-
-# this regular expression is used to detect field definitions
 #
-re_field = re.compile( r"\s*(\w*|\w(\w|\.)*\w)\s*::" )
+# A regular expression to detect field definitions.
+#
+# Examples:
+#
+#   foo     ::
+#   foo.bar ::
+#
+re_field = re.compile( r"""
+                         \s*
+                           (
+                             \w*
+                           |
+                             \w (\w | \.)* \w
+                           )
+                         \s* ::
+                       """, re.VERBOSE )
 
 
-
+################################################################
+##
+##  DOC MARKUP CLASS
+##
 class  DocMarkup:
 
     def  __init__( self, tag, lines ):
@@ -242,7 +285,7 @@
         for l in lines:
             m = re_field.match( l )
             if m:
-                # we detected the start of a new field definition
+                # We detected the start of a new field definition.
 
                 # first, save the current one
                 if cur_lines:
@@ -275,7 +318,10 @@
         print " " * margin + "</" + self.tag + ">"
 
 
-
+################################################################
+##
+##  DOC CHAPTER CLASS
+##
 class  DocChapter:
 
     def  __init__( self, block ):
@@ -291,7 +337,10 @@
             self.order = []
 
 
-
+################################################################
+##
+##  DOC SECTION CLASS
+##
 class  DocSection:
 
     def  __init__( self, name = "Other" ):
@@ -327,7 +376,10 @@
         self.block_names = sort_order_list( self.block_names, self.order )
 
 
-
+################################################################
+##
+##  CONTENT PROCESSOR CLASS
+##
 class  ContentProcessor:
 
     def  __init__( self ):
@@ -463,7 +515,10 @@
             self.chapters.append( chap )
 
 
-
+################################################################
+##
+##  DOC BLOCK CLASS
+##
 class  DocBlock:
 
     def  __init__( self, source, follow, processor ):
--- a/src/tools/docmaker/docmaker.py
+++ b/src/tools/docmaker/docmaker.py
@@ -1,17 +1,27 @@
 #!/usr/bin/env python
 #
-#  DocMaker (c) 2002, 2004, 2008, 2013 David Turner <[email protected]>
+#  docmaker.py
 #
-# This program is a re-write of the original DocMaker tool used
-# to generate the API Reference of the FreeType font engine
-# by converting in-source comments into structured HTML.
+#    Convert source code markup to HTML documentation.
 #
-# This new version is capable of outputting XML data, as well
-# as accepts more liberal formatting options.
+#  Copyright 2002, 2004, 2008, 2013, 2014 by
+#  David Turner.
 #
-# It also uses regular expression matching and substitution
-# to speed things significantly.
+#  This file is part of the FreeType project, and may only be used,
+#  modified, and distributed under the terms of the FreeType project
+#  license, LICENSE.TXT.  By continuing to use, modify, or distribute
+#  this file you indicate that you have read the license and
+#  understand and accept it fully.
+
 #
+# This program is a re-write of the original DocMaker tool used to generate
+# the API Reference of the FreeType font rendering engine by converting
+# in-source comments into structured HTML.
+#
+# This new version is capable of outputting XML data as well as accepting
+# more liberal formatting options.  It also uses regular expression matching
+# and substitution to speed up operation significantly.
+#
 
 from sources   import *
 from content   import *
@@ -44,8 +54,8 @@
     global output_dir
 
     try:
-        opts, args = getopt.getopt( sys.argv[1:], \
-                                    "ht:o:p:",    \
+        opts, args = getopt.getopt( sys.argv[1:],
+                                    "ht:o:p:",
                                     ["help", "title=", "output=", "prefix="] )
     except getopt.GetoptError:
         usage()
@@ -56,7 +66,6 @@
         sys.exit( 1 )
 
     # process options
-    #
     project_title  = "Project"
     project_prefix = None
     output_dir     = None
@@ -90,7 +99,9 @@
     # process sections
     content_processor.finish()
 
-    formatter = HtmlFormatter( content_processor, project_title, project_prefix )
+    formatter = HtmlFormatter( content_processor,
+                               project_title,
+                               project_prefix )
 
     formatter.toc_dump()
     formatter.index_dump()
@@ -98,9 +109,7 @@
 
 
 # if called from the command line
-#
 if __name__ == '__main__':
     main( sys.argv )
-
 
 # eof
--- a/src/tools/docmaker/formatter.py
+++ b/src/tools/docmaker/formatter.py
@@ -1,19 +1,37 @@
-#  Formatter (c) 2002, 2004, 2007, 2008 David Turner <[email protected]>
 #
+#  formatter.py
+#
+#    Convert parsed content blocks to a structured document (library file).
+#
+#  Copyright 2002, 2004, 2007, 2008, 2014 by
+#  David Turner.
+#
+#  This file is part of the FreeType project, and may only be used,
+#  modified, and distributed under the terms of the FreeType project
+#  license, LICENSE.TXT.  By continuing to use, modify, or distribute
+#  this file you indicate that you have read the license and
+#  understand and accept it fully.
 
+#
+# This is the base Formatter class.  Its purpose is to convert a content
+# processor's data into specific documents (i.e., table of contents, global
+# index, and individual API reference indices).
+#
+# You need to sub-class it to output anything sensible.  For example, the
+# file `tohtml.py' contains the definition of the `HtmlFormatter' sub-class
+# to output HTML.
+#
+
+
 from sources import *
 from content import *
 from utils   import *
 
-# This is the base Formatter class.  Its purpose is to convert
-# a content processor's data into specific documents (i.e., table of
-# contents, global index, and individual API reference indices).
-#
-# You need to sub-class it to output anything sensible.  For example,
-# the file tohtml.py contains the definition of the HtmlFormatter sub-class
-# used to output -- you guessed it -- HTML.
-#
 
+################################################################
+##
+##  FORMATTER CLASS
+##
 class  Formatter:
 
     def  __init__( self, processor ):
@@ -41,15 +59,17 @@
     def  add_identifier( self, name, block ):
         if self.identifiers.has_key( name ):
             # duplicate name!
-            sys.stderr.write(                                           \
-               "WARNING: duplicate definition for '" + name + "' in " + \
-               block.location() + ", previous definition in " +         \
-               self.identifiers[name].location() + "\n" )
+            sys.stderr.write( "WARNING: duplicate definition for"
+                              + " '" + name + "' "
+                              + "in " + block.location() + ", "
+                              + "previous definition in "
+                              + self.identifiers[name].location()
+                              + "\n" )
         else:
             self.identifiers[name] = block
 
     #
-    #  Formatting the table of contents
+    # formatting the table of contents
     #
     def  toc_enter( self ):
         pass
@@ -97,7 +117,7 @@
             close_output( output )
 
     #
-    #  Formatting the index
+    # formatting the index
     #
     def  index_enter( self ):
         pass
@@ -128,7 +148,7 @@
             close_output( output )
 
     #
-    #  Formatting a section
+    # formatting a section
     #
     def  section_enter( self, section ):
         pass
--- a/src/tools/docmaker/sources.py
+++ b/src/tools/docmaker/sources.py
@@ -1,43 +1,55 @@
-#  Sources (c) 2002-2004, 2006-2009, 2012, 2013
-#    David Turner <[email protected]>
 #
+#  sources.py
 #
-# this file contains definitions of classes needed to decompose
-# C sources files into a series of multi-line "blocks". There are
-# two kinds of blocks:
+#    Convert source code comments to multi-line blocks (library file).
 #
-#   - normal blocks, which contain source code or ordinary comments
+#  Copyright 2002-2004, 2006-2009, 2012-2014 by
+#  David Turner.
 #
-#   - documentation blocks, which have restricted formatting, and
-#     whose text always start with a documentation markup tag like
-#     "<Function>", "<Type>", etc..
+#  This file is part of the FreeType project, and may only be used,
+#  modified, and distributed under the terms of the FreeType project
+#  license, LICENSE.TXT.  By continuing to use, modify, or distribute
+#  this file you indicate that you have read the license and
+#  understand and accept it fully.
+
 #
-# the routines used to process the content of documentation blocks
-# are not contained here, but in "content.py"
+# This library file contains definitions of classes needed to decompose C
+# source code files into a series of multi-line `blocks'.  There are two
+# kinds of blocks.
 #
-# the classes and methods found here only deal with text parsing
-# and basic documentation block extraction
+#   - Normal blocks, which contain source code or ordinary comments.
 #
+#   - Documentation blocks, which have restricted formatting, and whose text
+#     always start with a documentation markup tag like `<Function>',
+#     `<Type>', etc.
+#
+# The routines to process the content of documentation blocks are contained
+# in file `content.py'; the classes and methods found here only deal with
+# text parsing and basic documentation block extraction.
+#
 
+
 import fileinput, re, sys, os, string
 
 
-
-################################################################
+################################################################
 ##
-##  BLOCK FORMAT PATTERN
+##  SOURCE BLOCK FORMAT CLASS
 ##
-##   A simple class containing compiled regular expressions used
-##   to detect potential documentation format block comments within
-##   C source code
+##  A simple class containing compiled regular expressions to detect
+##  potential documentation format block comments within C source code.
 ##
-##   note that the 'column' pattern must contain a group that will
-##   be used to "unbox" the content of documentation comment blocks
+##  The `column' pattern must contain a group to `unbox' the content of
+##  documentation comment blocks.
 ##
+##  Later on, paragraphs are converted to long lines, which simplifies the
+##  regular expressions that act upon the text.
+##
 class  SourceBlockFormat:
 
     def  __init__( self, id, start, column, end ):
-        """create a block pattern, used to recognize special documentation blocks"""
+        """Create a block pattern, used to recognize special documentation
+           blocks."""
         self.id     = id
         self.start  = re.compile( start, re.VERBOSE )
         self.column = re.compile( column, re.VERBOSE )
@@ -44,19 +56,15 @@
         self.end    = re.compile( end, re.VERBOSE )
 
 
-
 #
-# format 1 documentation comment blocks look like the following:
+# Format 1 documentation comment blocks.
 #
-#    /************************************/
+#    /************************************/ (at least 2 asterisks)
 #    /*                                  */
 #    /*                                  */
 #    /*                                  */
-#    /************************************/
+#    /************************************/ (at least 2 asterisks)
 #
-# we define a few regular expressions here to detect them
-#
-
 start = r'''
   \s*      # any number of whitespace
   /\*{2,}/ # followed by '/' and at least two asterisks then '/'
@@ -75,17 +83,14 @@
 
 
 #
-# format 2 documentation comment blocks look like the following:
+# Format 2 documentation comment blocks.
 #
 #    /************************************ (at least 2 asterisks)
 #     *
+#     *                                    (1 asterisk)
 #     *
-#     *
-#     *
-#     **/       (1 or more asterisks at the end)
+#     */                                   (1 or more asterisks)
 #
-# we define a few regular expressions here to detect them
-#
 start = r'''
   \s*     # any number of whitespace
   /\*{2,} # followed by '/' and at least two asterisks
@@ -107,47 +112,56 @@
 
 
 #
-# the list of supported documentation block formats, we could add new ones
-# relatively easily
+# The list of supported documentation block formats.  We could add new ones
+# quite easily.
 #
 re_source_block_formats = [re_source_block_format1, re_source_block_format2]
 
 
 #
-# the following regular expressions corresponds to markup tags
-# within the documentation comment blocks. they're equivalent
-# despite their different syntax
+# The following regular expressions correspond to markup tags within the
+# documentation comment blocks.  They are equivalent despite their different
+# syntax.
 #
-# notice how each markup tag _must_ begin a new line
+# A markup tag consists of letters or character `-', to be found in group 1.
 #
+# Notice that a markup tag _must_ begin a new paragraph.
+#
 re_markup_tag1 = re.compile( r'''\s*<((?:\w|-)*)>''' )  # <xxxx> format
 re_markup_tag2 = re.compile( r'''\s*@((?:\w|-)*):''' )  # @xxxx: format
 
 #
-# the list of supported markup tags, we could add new ones relatively
-# easily
+# The list of supported markup tags.  We could add new ones quite easily.
 #
 re_markup_tags = [re_markup_tag1, re_markup_tag2]
 
+
 #
-# used to detect a cross-reference, after markup tags have been stripped
+# A regular expression to detect a cross reference, after markup tags have
+# been stripped off.  Group 1 is the reference, group 2 the rest of the
+# line.
 #
+# A cross reference consists of letters, digits, or characters `-' and `_'.
+#
 re_crossref = re.compile( r'@((?:\w|-)*)(.*)' )    #  @foo
 
 #
-# used to detect italic and bold styles in paragraph text
+# Two regular expressions to detect italic and bold markup, respectively.
+# Group 1 is the markup, group 3 the rest of the line.
 #
+# Note that the markup is limited to words consisting of letters, digits,
+# the character `_', or an apostrophe (but not as the first character).
+#
 re_italic = re.compile( r"_(\w(\w|')*)_(.*)" )     #  _italic_
 re_bold   = re.compile( r"\*(\w(\w|')*)\*(.*)" )   #  *bold*
 
 #
-# this regular expression code to identify an URL has been taken from
+# This regular expression code to identify an URL has been taken from
 #
 #   http://mail.python.org/pipermail/tutor/2002-September/017228.html
 #
-# (with slight modifications)
+# (with slight modifications).
 #
-
 urls = r'(?:https?|telnet|gopher|file|wais|ftp)'
 ltrs = r'\w'
 gunk = r'/#~:.?+=&%@!\-'
@@ -177,17 +191,22 @@
 re_url = re.compile( url, re.VERBOSE | re.MULTILINE )
 
 #
-# used to detect the end of commented source lines
+# A regular expression that stops collection of comments for the current
+# block.
 #
-re_source_sep = re.compile( r'\s*/\*\s*\*/' )
+re_source_sep = re.compile( r'\s*/\*\s*\*/' )   #  /* */
 
 #
-# used to perform cross-reference within source output
+# A regular expression to find possible C identifiers while outputting
+# source code verbatim, covering things like `*foo' or `(bar'.  Group 1 is
+# the prefix, group 2 the identifier -- since we scan lines from left to
+# right, sequentially splitting the source code into prefix and identifier
+# is fully sufficient for our purposes.
 #
 re_source_crossref = re.compile( r'(\W*)(\w*)' )
 
 #
-# a list of reserved source keywords
+# A regular expression that matches a list of reserved C source keywords.
 #
 re_source_keywords = re.compile( '''\\b ( typedef   |
                                           struct    |
@@ -215,25 +234,17 @@
 ##
 ##  SOURCE BLOCK CLASS
 ##
-##   A SourceProcessor is in charge of reading a C source file
-##   and decomposing it into a series of different "SourceBlocks".
-##   each one of these blocks can be made of the following data:
+##  There are two important fields in a `SourceBlock' object.
 ##
-##   - A documentation comment block that starts with "/**" and
-##     whose exact format will be discussed later
+##    self.lines
+##      A list of text lines for the corresponding block.
 ##
-##   - normal sources lines, including comments
+##    self.content
+##      For documentation comment blocks only, this is the block content
+##      that has been `unboxed' from its decoration.  This is `None' for all
+##      other blocks (i.e., sources or ordinary comments with no starting
+##      markup tag)
 ##
-##   the important fields in a text block are the following ones:
-##
-##     self.lines   : a list of text lines for the corresponding block
-##
-##     self.content : for documentation comment blocks only, this is the
-##                    block content that has been "unboxed" from its
-##                    decoration. This is None for all other blocks
-##                    (i.e. sources or ordinary comments with no starting
-##                     markup tag)
-##
 class  SourceBlock:
 
     def  __init__( self, processor, filename, lineno, lines ):
@@ -269,7 +280,7 @@
     def  location( self ):
         return "(" + self.filename + ":" + repr( self.lineno ) + ")"
 
-    # debugging only - not used in normal operations
+    # debugging only -- not used in normal operations
     def  dump( self ):
         if self.content:
             print "{{{content start---"
@@ -286,27 +297,25 @@
             print line
 
 
-
-################################################################
+################################################################
 ##
 ##  SOURCE PROCESSOR CLASS
 ##
-##   The SourceProcessor is in charge of reading a C source file
-##   and decomposing it into a series of different "SourceBlock"
-##   objects.
+##  The `SourceProcessor' is in charge of reading a C source file and
+##  decomposing it into a series of different `SourceBlock' objects.
 ##
-##   each one of these blocks can be made of the following data:
+##  A SourceBlock object consists of the following data.
 ##
-##   - A documentation comment block that starts with "/**" and
-##     whose exact format will be discussed later
+##    - A documentation comment block using one of the layouts above.  Its
+##      exact format will be discussed later.
 ##
-##   - normal sources lines, include comments
+##    - Normal sources lines, including comments.
 ##
 ##
 class  SourceProcessor:
 
     def  __init__( self ):
-        """initialize a source processor"""
+        """Initialize a source processor."""
         self.blocks   = []
         self.filename = None
         self.format   = None
@@ -313,12 +322,13 @@
         self.lines    = []
 
     def  reset( self ):
-        """reset a block processor, clean all its blocks"""
+        """Reset a block processor and clean up all its blocks."""
         self.blocks = []
         self.format = None
 
     def  parse_file( self, filename ):
-        """parse a C source file, and add its blocks to the processor's list"""
+        """Parse a C source file and add its blocks to the processor's
+           list."""
         self.reset()
 
         self.filename = filename
@@ -337,16 +347,16 @@
                 self.process_normal_line( line )
             else:
                 if self.format.end.match( line ):
-                    # that's a normal block end, add it to 'lines' and
-                    # create a new block
+                    # A normal block end.  Add it to `lines' and create a
+                    # new block
                     self.lines.append( line )
                     self.add_block_lines()
                 elif self.format.column.match( line ):
-                    # that's a normal column line, add it to 'lines'
+                    # A normal column line.  Add it to `lines'.
                     self.lines.append( line )
                 else:
-                    # humm.. this is an unexpected block end,
-                    # create a new block, but don't process the line
+                    # An unexpected block end.  Create a new block, but
+                    # don't process the line.
                     self.add_block_lines()
 
                     # we need to process the line again
@@ -356,7 +366,8 @@
         self.add_block_lines()
 
     def  process_normal_line( self, line ):
-        """process a normal line and check whether it is the start of a new block"""
+        """Process a normal line and check whether it is the start of a new
+           block."""
         for f in re_source_block_formats:
             if f.start.match( line ):
                 self.add_block_lines()
@@ -366,9 +377,12 @@
         self.lines.append( line )
 
     def  add_block_lines( self ):
-        """add the current accumulated lines and create a new block"""
+        """Add the current accumulated lines and create a new block."""
         if self.lines != []:
-            block = SourceBlock( self, self.filename, self.lineno, self.lines )
+            block = SourceBlock( self,
+                                 self.filename,
+                                 self.lineno,
+                                 self.lines )
 
             self.blocks.append( block )
             self.format = None
@@ -376,7 +390,7 @@
 
     # debugging only, not used in normal operations
     def  dump( self ):
-        """print all blocks in a processor"""
+        """Print all blocks in a processor."""
         for b in self.blocks:
             b.dump()
 
--- a/src/tools/docmaker/tohtml.py
+++ b/src/tools/docmaker/tohtml.py
@@ -1,6 +1,20 @@
-#  ToHTML (c) 2002, 2003, 2005-2008, 2013
-#    David Turner <[email protected]>
+#
+#  tohtml.py
+#
+#    A sub-class container of the `Formatter' class to produce HTML.
+#
+#  Copyright 2002, 2003, 2005-2008, 2013, 2014 by
+#  David Turner.
+#
+#  This file is part of the FreeType project, and may only be used,
+#  modified, and distributed under the terms of the FreeType project
+#  license, LICENSE.TXT.  By continuing to use, modify, or distribute
+#  this file you indicate that you have read the license and
+#  understand and accept it fully.
 
+# The parent class is contained in file `formatter.py'.
+
+
 from sources import *
 from content import *
 from formatter import *
@@ -8,7 +22,7 @@
 import time
 
 
-# The following defines the HTML header used by all generated pages.
+# The following strings define the HTML header used by all generated pages.
 html_header_1 = """\
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">
@@ -158,7 +172,7 @@
 """
 
 
-# source language keyword coloration/styling
+# Source language keyword coloration and styling.
 keyword_prefix = '<span class="keyword">'
 keyword_suffix = '</span>'
 
@@ -166,16 +180,20 @@
 section_synopsis_footer = ''
 
 
-# Translate a single line of source to HTML.  This will convert
-# a "<" into "&lt.", ">" into "&gt.", etc.
+# Translate a single line of source to HTML.  This converts `<', `>', and
+# `&' into `&lt;',`&gt;', and `&amp;'.
+#
 def  html_quote( line ):
-    result = string.replace( line, "&", "&amp;" )
-    result = string.replace( result, "<", "&lt;" )
-    result = string.replace( result, ">", "&gt;" )
+    result = string.replace( line,   "&", "&amp;" )
+    result = string.replace( result, "<", "&lt;"  )
+    result = string.replace( result, ">", "&gt;"  )
     return result
 
 
-
+################################################################
+##
+##  HTML FORMATTER CLASS
+##
 class  HtmlFormatter( Formatter ):
 
     def  __init__( self, processor, project_title, file_prefix ):
@@ -189,32 +207,33 @@
         else:
             file_prefix = ""
 
-        self.headers           = processor.headers
-        self.project_title     = project_title
-        self.file_prefix       = file_prefix
-        self.html_header       = html_header_1 + project_title +              \
-                                 html_header_2 +                              \
-                                 html_header_3 + file_prefix + "index.html" + \
-                                 html_header_4 + file_prefix + "toc.html" +   \
-                                 html_header_5 + project_title +              \
-                                 html_header_6
+        self.headers       = processor.headers
+        self.project_title = project_title
+        self.file_prefix   = file_prefix
+        self.html_header   = (
+          html_header_1 + project_title
+          + html_header_2
+          + html_header_3 + file_prefix + "index.html"
+          + html_header_4 + file_prefix + "toc.html"
+          + html_header_5 + project_title
+          + html_header_6 )
+        self.html_index_header = (
+          html_header_1 + project_title
+          + html_header_2
+          + html_header_3i + file_prefix + "toc.html"
+          + html_header_5 + project_title
+          + html_header_6 )
+        self.html_toc_header = (
+          html_header_1 + project_title
+          + html_header_2
+          + html_header_3 + file_prefix + "index.html"
+          + html_header_5t + project_title
+          + html_header_6 )
+        self.html_footer = (
+          "<center><font size=""-2"">generated on "
+          + time.asctime( time.localtime( time.time() ) )
+          + "</font></center>" + html_footer )
 
-        self.html_index_header = html_header_1 + project_title +             \
-                                 html_header_2 +                             \
-                                 html_header_3i + file_prefix + "toc.html" + \
-                                 html_header_5 + project_title +             \
-                                 html_header_6
-
-        self.html_toc_header   = html_header_1 + project_title +              \
-                                 html_header_2 +                              \
-                                 html_header_3 + file_prefix + "index.html" + \
-                                 html_header_5t + project_title +             \
-                                 html_header_6
-
-        self.html_footer       = "<center><font size=""-2"">generated on " +     \
-                                 time.asctime( time.localtime( time.time() ) ) + \
-                                 "</font></center>" + html_footer
-
         self.columns = 3
 
     def  make_section_url( self, section ):
@@ -224,8 +243,8 @@
         return self.make_section_url( block.section ) + "#" + block.name
 
     def  make_html_word( self, word ):
-        """analyze a simple word to detect cross-references and styling"""
-        # look for cross-references
+        """Analyze a simple word to detect cross-references and markup."""
+        # handle cross-references
         m = re_crossref.match( word )
         if m:
             try:
@@ -236,11 +255,11 @@
                 return '<a href="' + url + '">' + name + '</a>' + rest
             except:
                 # we detected a cross-reference to an unknown item
-                sys.stderr.write( \
-                   "WARNING: undefined cross reference '" + name + "'.\n" )
+                sys.stderr.write( "WARNING: undefined cross reference"
+                                  + " '" + name + "'.\n" )
                 return '?' + name + '?' + rest
 
-        # look for italics and bolds
+        # handle markup for italic and bold
         m = re_italic.match( word )
         if m:
             name = m.group( 1 )
@@ -256,7 +275,8 @@
         return html_quote( word )
 
     def  make_html_para( self, words ):
-        """ convert words of a paragraph into tagged HTML text, handle xrefs """
+        """Convert words of a paragraph into tagged HTML text.  Also handle
+           cross references."""
         line = ""
         if words:
             line = self.make_html_word( words[0] )
@@ -265,8 +285,8 @@
             # handle hyperlinks
             line = re_url.sub( r'<a href="\1">\1</a>', line )
             # convert `...' quotations into real left and right single quotes
-            line = re.sub( r"(^|\W)`(.*?)'(\W|$)",  \
-                           r'\1&lsquo;\2&rsquo;\3', \
+            line = re.sub( r"(^|\W)`(.*?)'(\W|$)",
+                           r'\1&lsquo;\2&rsquo;\3',
                            line )
             # convert tilde into non-breakable space
             line = string.replace( line, "~", "&nbsp;" )
@@ -274,7 +294,7 @@
         return para_header + line + para_footer
 
     def  make_html_code( self, lines ):
-        """ convert a code sequence to HTML """
+        """Convert a code sequence to HTML."""
         line = code_header + '\n'
         for l in lines:
             line = line + html_quote( l ) + '\n'
@@ -282,7 +302,7 @@
         return line + code_footer
 
     def  make_html_items( self, items ):
-        """ convert a field's content into some valid HTML """
+        """Convert a field's content into HTML."""
         lines = []
         for item in items:
             if item.lines:
@@ -297,7 +317,9 @@
 
     def  print_html_field( self, field ):
         if field.name:
-            print "<table><tr valign=top><td><b>" + field.name + "</b></td><td>"
+            print( "<table><tr valign=top><td><b>"
+                   + field.name
+                   + "</b></td><td>" )
 
         print self.make_html_items( field.items )
 
@@ -318,12 +340,14 @@
                     result = result + prefix + '<b>' + name + '</b>'
                 elif re_source_keywords.match( name ):
                     # this is a C keyword
-                    result = result + prefix + keyword_prefix + name + keyword_suffix
+                    result = ( result + prefix
+                               + keyword_prefix + name + keyword_suffix )
                 elif self.identifiers.has_key( name ):
                     # this is a known identifier
                     block = self.identifiers[name]
-                    result = result + prefix + '<a href="' + \
-                             self.make_block_url( block ) + '">' + name + '</a>'
+                    result = ( result + prefix
+                               + '<a href="' + self.make_block_url( block )
+                               + '">' + name + '</a>' )
                 else:
                     result = result + html_quote( line[:length] )
 
@@ -339,10 +363,14 @@
         print "<table cellpadding=3 border=0>"
         for field in fields:
             if len( field.name ) > 22:
-              print "<tr valign=top><td colspan=0><b>" + field.name + "</b></td></tr>"
+              print( "<tr valign=top><td colspan=0><b>"
+                     + field.name
+                     + "</b></td></tr>" )
               print "<tr valign=top><td></td><td>"
             else:
-              print "<tr valign=top><td><b>" + field.name + "</b></td><td>"
+              print( "<tr valign=top><td><b>"
+                     + field.name
+                     + "</b></td><td>" )
 
             self.print_html_items( field.items )
             print "</td></tr>"
@@ -352,10 +380,9 @@
         table_fields = []
         for field in markup.fields:
             if field.name:
-                # we begin a new series of field or value definitions, we
-                # will record them in the 'table_fields' list before outputting
-                # all of them as a single table
-                #
+                # We begin a new series of field or value definitions.  We
+                # record them in the `table_fields' list before outputting
+                # all of them as a single table.
                 table_fields.append( field )
             else:
                 if table_fields:
@@ -368,7 +395,7 @@
             self.print_html_field_list( table_fields )
 
     #
-    #  Formatting the index
+    # formatting the index
     #
     def  index_enter( self ):
         print self.html_index_header
@@ -380,7 +407,7 @@
         self.index_items[name] = url
 
     def  index_exit( self ):
-        # block_index already contains the sorted list of index names
+        # `block_index' already contains the sorted list of index names
         count = len( self.block_index )
         rows  = ( count + self.columns - 1 ) / self.columns
 
@@ -392,7 +419,8 @@
                 if i < count:
                     bname = self.block_index[r + c * rows]
                     url   = self.index_items[bname]
-                    line = line + '<td><a href="' + url + '">' + bname + '</a></td>'
+                    line  = ( line + '<td><a href="' + url + '">'
+                              + bname + '</a></td>' )
                 else:
                     line = line + '<td></td>'
             line = line + "</tr>"
@@ -400,9 +428,9 @@
 
         print "</table>"
 
-        print index_footer_start +            \
-              self.file_prefix + "toc.html" + \
-              index_footer_end
+        print( index_footer_start
+               + self.file_prefix + "toc.html"
+               + index_footer_end )
 
         print self.html_footer
 
@@ -415,7 +443,7 @@
         Formatter.index_dump( self, index_filename )
 
     #
-    #  Formatting the table of content
+    # formatting the table of contents
     #
     def  toc_enter( self ):
         print self.html_toc_header
@@ -422,13 +450,13 @@
         print "<center><h1>Table of Contents</h1></center>"
 
     def  toc_chapter_enter( self, chapter ):
-        print  chapter_header + string.join( chapter.title ) + chapter_inter
+        print chapter_header + string.join( chapter.title ) + chapter_inter
         print "<table cellpadding=5>"
 
     def  toc_section_enter( self, section ):
         print '<tr valign=top><td class="left">'
-        print '<a href="' + self.make_section_url( section ) + '">' + \
-               section.title + '</a></td><td>'
+        print( '<a href="' + self.make_section_url( section ) + '">'
+               + section.title + '</a></td><td>' )
 
         print self.make_html_para( section.abstract )
 
@@ -440,14 +468,14 @@
         print chapter_footer
 
     def  toc_index( self, index_filename ):
-        print chapter_header +                                      \
-              '<a href="' + index_filename + '">Global Index</a>' + \
-              chapter_inter + chapter_footer
+        print( chapter_header
+               + '<a href="' + index_filename + '">Global Index</a>'
+               + chapter_inter + chapter_footer )
 
     def  toc_exit( self ):
-        print toc_footer_start +                \
-              self.file_prefix + "index.html" + \
-              toc_footer_end
+        print( toc_footer_start
+               + self.file_prefix + "index.html"
+               + toc_footer_end )
 
         print self.html_footer
 
@@ -461,7 +489,7 @@
         Formatter.toc_dump( self, toc_filename, index_filename )
 
     #
-    #  Formatting sections
+    # formatting sections
     #
     def  section_enter( self, section ):
         print self.html_header
@@ -495,7 +523,8 @@
                     line = line + '<td></td><td>'
                     if i < count:
                         name = section.block_names[i]
-                        line = line + '<a href="#' + name + '">' + name + '</a>'
+                        line = ( line + '<a href="#' + name + '">'
+                                 + name + '</a>' )
 
                     line = line + '</td>'
                 line = line + "</tr>"
@@ -513,7 +542,8 @@
 
         # place html anchor if needed
         if block.name:
-            print '<h4><a name="' + block.name + '">' + block.name + '</a></h4>'
+            print( '<h4><a name="' + block.name + '">'
+                   + block.name + '</a></h4>' )
 
         # dump the block C source lines now
         if block.code:
@@ -524,8 +554,9 @@
                     break;
 
 #           if not header:
-#               sys.stderr.write( \
-#                 'WARNING: No header macro for ' + block.source.filename + '.\n' )
+#               sys.stderr.write(
+#                 "WARNING: No header macro for"
+#                 + " '" + block.source.filename + "'.\n" )
 
             if header:
                 print header_location_header
@@ -552,9 +583,9 @@
             print marker_footer
 
     def  block_exit( self, block ):
-        print block_footer_start + self.file_prefix + "index.html" + \
-              block_footer_middle + self.file_prefix + "toc.html" +  \
-              block_footer_end
+        print( block_footer_start + self.file_prefix + "index.html"
+               + block_footer_middle + self.file_prefix + "toc.html"
+               + block_footer_end )
 
     def  section_exit( self, section ):
         print html_footer
@@ -561,6 +592,7 @@
 
     def  section_dump_all( self ):
         for section in self.sections:
-            self.section_dump( section, self.file_prefix + section.name + '.html' )
+            self.section_dump( section,
+                               self.file_prefix + section.name + '.html' )
 
 # eof
--- a/src/tools/docmaker/utils.py
+++ b/src/tools/docmaker/utils.py
@@ -1,15 +1,28 @@
-#  Utils (c) 2002, 2004, 2007, 2008  David Turner <[email protected]>
 #
+#  utils.py
+#
+#    Auxiliary functions for the `docmaker' tool (library file).
+#
+#  Copyright 2002, 2004, 2007, 2008, 2014 by
+#  David Turner.
+#
+#  This file is part of the FreeType project, and may only be used,
+#  modified, and distributed under the terms of the FreeType project
+#  license, LICENSE.TXT.  By continuing to use, modify, or distribute
+#  this file you indicate that you have read the license and
+#  understand and accept it fully.
 
+
 import string, sys, os, glob
 
+
 # current output directory
 #
 output_dir = None
 
 
-# This function is used to sort the index.  It is a simple lexicographical
-# sort, except that it places capital letters before lowercase ones.
+# A function to sort the index.  It is a simple lexicographical sort, except
+# that it places capital letters before lowercase ones.
 #
 def  index_sort( s1, s2 ):
     if not s1:
@@ -42,7 +55,7 @@
     return 0
 
 
-# Sort input_list, placing the elements of order_list in front.
+# Sort `input_list', placing the elements of `order_list' in front.
 #
 def  sort_order_list( input_list, order_list ):
     new_list = order_list[:]
@@ -52,9 +65,9 @@
     return new_list
 
 
-# Open the standard output to a given project documentation file.  Use
-# "output_dir" to determine the filename location if necessary and save the
-# old stdout in a tuple that is returned by this function.
+# Divert standard output to a given project documentation file.  Use
+# `output_dir' to determine the filename location if necessary and save the
+# old stdout handle in a tuple that is returned by this function.
 #
 def  open_output( filename ):
     global output_dir
@@ -69,7 +82,7 @@
     return ( new_file, old_stdout )
 
 
-# Close the output that was returned by "close_output".
+# Close the output that was returned by `open_output'.
 #
 def  close_output( output ):
     output[0].close()
@@ -83,8 +96,9 @@
     if output_dir:
         if output_dir != "":
             if not os.path.isdir( output_dir ):
-                sys.stderr.write( "argument" + " '" + output_dir + "' " + \
-                                  "is not a valid directory" )
+                sys.stderr.write( "argument"
+                                  + " '" + output_dir + "' "
+                                  + "is not a valid directory" )
                 sys.exit( 2 )
         else:
             output_dir = None
@@ -91,7 +105,7 @@
 
 
 def  file_exists( pathname ):
-    """checks that a given file exists"""
+    """Check that a given file exists."""
     result = 1
     try:
         file = open( pathname, "r" )
@@ -104,12 +118,12 @@
 
 
 def  make_file_list( args = None ):
-    """builds a list of input files from command-line arguments"""
+    """Build a list of input files from command-line arguments."""
     file_list = []
     # sys.stderr.write( repr( sys.argv[1 :] ) + '\n' )
 
     if not args:
-        args = sys.argv[1 :]
+        args = sys.argv[1:]
 
     for pathname in args:
         if string.find( pathname, '*' ) >= 0: