Edit

kc3-lang/freetype/docs/docmaker.py

Branch :

  • Show log

    Commit

  • Author : Werner Lemberg
    Date : 2001-02-14 04:59:57
    Hash : 0b2137e5
    Message : * docs/docmaker.py (DocSection::add_element): Use `self.print_error()'. to support chapters and section block ordering. Updated the public

  • docs/docmaker.py
  • #!/usr/bin/env python
    #
    # DocMaker is a very simple program used to generate HTML documentation
    # from the source files of the FreeType packages.
    #
    # I should really be using regular expressions to do this, but hey,
    # i'm too lazy right now, and the damn thing seems to work :-)
    #   - David
    #
    
    import fileinput, sys, string, glob
    
    html_header = """\
    <html>
    <header>
    <title>FreeType 2 API Reference</title>
    <basefont face="Georgia, Arial, Helvetica, Geneva">
    <style content="text/css">
      P { text-align=justify }
      H1 { text-align=center }
      LI { text-align=justify }
    </style>
    </header>
    <body text=#000000
          bgcolor=#FFFFFF
          link=#0000EF
          vlink=#51188E
          alink=#FF0000>
    <center><h1>FreeType 2 API Reference</h1></center>
    """
    
    html_footer = """\
    </body>
    </html>"""
    
    section_title_header = "<center><h1>"
    section_title_footer = "</h1></center>"
    
    code_header = "<font color=blue><pre>"
    code_footer = "</pre></font>"
    
    para_header = "<p>"
    para_footer = "</p>"
    
    block_header = "<center><table width=75%><tr><td>"
    block_footer = "</td></tr></table><hr width=75%></center>"
    
    description_header = "<center><table width=87%><tr><td>"
    description_footer = "</td></tr></table></center><br>"
    
    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=87%><tr bgcolor=#D6E8FF width=100%><td><pre>"
    source_footer = "</pre></table></center><br>"
    
    chapter_header = "<center><table width=75%><tr><td><h2>"
    chapter_inter  = "</h2><ul>"
    chapter_footer = "</ul></td></tr></table></center>"
    
    current_section = None
    
    
    # This function is used to sort the index.  It's a simple lexicographical
    # sort, except that it places capital letters before small ones.
    #
    def index_sort( s1, s2 ):
        if not s1:
            return -1
    
        if not s2:
            return 1
    
        l1 = len( s1 )
        l2 = len( s2 )
        m1 = string.lower( s1 )
        m2 = string.lower( s2 )
    
        for i in range( l1 ):
            if i >= l2 or m1[i] > m2[i]:
                return 1
    
            if m1[i] < m2[i]:
                return -1
    
            if s1[i] < s2[i]:
                return -1
    
            if s1[i] > s2[i]:
                return 1
    
        if l2 > l1:
            return -1
    
        return 0
    
    
    # sort input_list, placing the elements of order_list in front
    #
    def sort_order_list( input_list, order_list ):
        new_list = order_list[:]
        for id in input_list:
            if not id in order_list:
                new_list.append( id )
        return new_list
    
    
    # The FreeType 2 reference is extracted from the source files. These contain
    # various comment blocks that follow one of the following formats:
    #
    #  /**************************
    #   *
    #   *  FORMAT1
    #   *
    #   *
    #   *
    #   *
    #   *************************/
    #
    #  /**************************/
    #  /*                        */
    #  /*  FORMAT2               */
    #  /*                        */
    #  /*                        */
    #  /*                        */
    #  /*                        */
    #
    #  /**************************/
    #  /*                        */
    #  /*  FORMAT3               */
    #  /*                        */
    #  /*                        */
    #  /*                        */
    #  /*                        */
    #  /**************************/
    #
    # Each block contains a list of markers; each one can be followed by
    # some arbitrary text or a list of fields. Here's an example:
    #
    #    <Struct>
    #       MyStruct
    #
    #    <Description>
    #       this structure holds some data
    #
    #    <Fields>
    #       x :: horizontal coordinate
    #       y :: vertical coordinate
    #
    #
    # This example defines three markers: 'Struct', 'Description' & 'Fields'.
    # The first two markers contain arbitrary text, while the last one contains
    # a list of fields.
    #
    # Each field is simple of the format:  WORD :: TEXT...
    #
    # Note that typically each comment block is followed by some source
    # code declaration that may need to be kept in the reference.
    #
    # Note that markers can alternatively be written as "@MARKER:"
    # instead of "<MARKER>". All marker identifiers are converted to
    # lower case during parsing in order to simply sorting.
    #
    # We associate with each block the following source lines that do not
    # begin with a comment. For example, the following:
    #
    #   /**********************************
    #    *
    #    * <mytag>  blabla
    #    *
    #    */
    #
    #    bla_bla_bla
    #     bilip_bilip
    #
    #   /* - this comment acts as a separator - */
    #
    #     blo_blo_blo
    #
    #
    #  will only keep the first two lines of sources with
    #  the "blabla" block.
    #
    #  However, the comment will be kept, with following source lines
    #  if it contains a starting '#' or '@' as in:
    #
    #     /*@.....*/
    #     /*#.....*/
    #     /* @.....*/
    #     /* #.....*/
    #
    
    
    
    #############################################################################
    #
    # 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 = 0 ):
            self.lines  = []
            self.margin = margin
    
    
        def add( self, line ):
            # remove margin whitespace
            #
            if string.strip( line[: self.margin] ) == "":
                line = line[self.margin :]
            self.lines.append( line )
    
    
        def dump( self ):
            for line in self.lines:
                print "--" + line
            print ""
    
    
        def get_identifier( self ):
            # this function should never be called
            #
            return "UNKNOWN_CODE_IDENTIFIER!"
    
    
        def dump_html( self, identifiers = None ):
            # clean the last empty lines
            #
            l = len( self.lines ) - 1
            while l > 0 and string.strip( self.lines[l - 1] ) == "":
                l = l - 1
    
            # the code footer should be directly appended to the last code
            # line to avoid an additional blank line
            #
            sys.stdout.write( code_header )
            for line in self.lines[0 : l+1]:
                sys.stdout.write( '\n' + line )
            sys.stdout.write( code_footer )
    
    
    
    #############################################################################
    #
    # The DocParagraph is used to store text paragraphs.
    # 'self.words' is simply a list of words for the paragraph.
    #
    # The paragraph is filled line by line by the parser.
    #
    class DocParagraph:
    
        def __init__( self ):
            self.words = []
    
    
        def add( self, line ):
            # Get rid of unwanted spaces in the paragraph.
            #
            # The following two lines are the same as
            #
            #   self.words.extend( string.split( line ) )
            #
            # but older Python versions don't have the `extend' attribute.
            #
            last = len( self.words )
            self.words[last : last] = string.split( line )
    
    
        # This function is used to retrieve the first word of a given
        # paragraph.
        #
        def get_identifier( self ):
            if self.words:
                return self.words[0]
    
            # should never happen
            #
            return "UNKNOWN_PARA_IDENTIFIER!"
    
    
        def get_words( self ):
            return self.words[:]
    
    
        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 if needed
                #
                if identifiers and word and word[0] == '@':
                    word = word[1 :]
    
                    # we need to find non-alphanumeric characters
                    #
                    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
                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
    
            # print "