forked from minhngoc25a/freetype2
[docmaker] Formatting, copyright, improved documentation.
* src/tools/docmaker/*: No code changes besides trivial modifications.
This commit is contained in:
parent
f1094c0951
commit
a7a4207d10
|
@ -1,3 +1,10 @@
|
|||
2014-11-24 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[docmaker] Formatting, copyright, improved documentation.
|
||||
|
||||
* src/tools/docmaker/*: No code changes besides trivial
|
||||
modifications.
|
||||
|
||||
2014-11-22 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[bdf] Fix Savannah bug #43660.
|
||||
|
|
|
@ -1,57 +1,81 @@
|
|||
# Content (c) 2002, 2004, 2006-2009, 2012, 2013
|
||||
# David Turner <david@freetype.org>
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# #define FT_FREETYPE_H <freetype.h>
|
||||
#
|
||||
re_header_macro = re.compile( r'^#define\s{1,}(\w{1,}_H)\s{1,}<(.*)>' )
|
||||
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
# 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'.
|
||||
#
|
||||
################################################################
|
||||
##
|
||||
## 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 @@ class DocCode:
|
|||
|
||||
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
# 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 @@ class DocPara:
|
|||
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 @@ class DocField:
|
|||
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 @@ class DocField:
|
|||
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 @@ class DocField:
|
|||
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 @@ class DocMarkup:
|
|||
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 @@ class DocMarkup:
|
|||
print " " * margin + "</" + self.tag + ">"
|
||||
|
||||
|
||||
|
||||
################################################################
|
||||
##
|
||||
## DOC CHAPTER CLASS
|
||||
##
|
||||
class DocChapter:
|
||||
|
||||
def __init__( self, block ):
|
||||
|
@ -291,7 +337,10 @@ class DocChapter:
|
|||
self.order = []
|
||||
|
||||
|
||||
|
||||
################################################################
|
||||
##
|
||||
## DOC SECTION CLASS
|
||||
##
|
||||
class DocSection:
|
||||
|
||||
def __init__( self, name = "Other" ):
|
||||
|
@ -327,7 +376,10 @@ class DocSection:
|
|||
self.block_names = sort_order_list( self.block_names, self.order )
|
||||
|
||||
|
||||
|
||||
################################################################
|
||||
##
|
||||
## CONTENT PROCESSOR CLASS
|
||||
##
|
||||
class ContentProcessor:
|
||||
|
||||
def __init__( self ):
|
||||
|
@ -463,7 +515,10 @@ class ContentProcessor:
|
|||
self.chapters.append( chap )
|
||||
|
||||
|
||||
|
||||
################################################################
|
||||
##
|
||||
## DOC BLOCK CLASS
|
||||
##
|
||||
class DocBlock:
|
||||
|
||||
def __init__( self, source, follow, processor ):
|
||||
|
|
|
@ -1,16 +1,26 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# DocMaker (c) 2002, 2004, 2008, 2013 David Turner <david@freetype.org>
|
||||
# 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 *
|
||||
|
@ -44,8 +54,8 @@ def main( argv ):
|
|||
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 @@ def main( argv ):
|
|||
sys.exit( 1 )
|
||||
|
||||
# process options
|
||||
#
|
||||
project_title = "Project"
|
||||
project_prefix = None
|
||||
output_dir = None
|
||||
|
@ -90,7 +99,9 @@ def main( argv ):
|
|||
# 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 @@ def main( argv ):
|
|||
|
||||
|
||||
# if called from the command line
|
||||
#
|
||||
if __name__ == '__main__':
|
||||
main( sys.argv )
|
||||
|
||||
|
||||
# eof
|
||||
|
|
|
@ -1,19 +1,37 @@
|
|||
# Formatter (c) 2002, 2004, 2007, 2008 David Turner <david@freetype.org>
|
||||
#
|
||||
# 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 @@ class Formatter:
|
|||
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 @@ class Formatter:
|
|||
close_output( output )
|
||||
|
||||
#
|
||||
# Formatting the index
|
||||
# formatting the index
|
||||
#
|
||||
def index_enter( self ):
|
||||
pass
|
||||
|
@ -128,7 +148,7 @@ class Formatter:
|
|||
close_output( output )
|
||||
|
||||
#
|
||||
# Formatting a section
|
||||
# formatting a section
|
||||
#
|
||||
def section_enter( self, section ):
|
||||
pass
|
||||
|
|
|
@ -1,62 +1,70 @@
|
|||
# Sources (c) 2002-2004, 2006-2009, 2012, 2013
|
||||
# David Turner <david@freetype.org>
|
||||
#
|
||||
# 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 )
|
||||
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,16 +83,13 @@ re_source_block_format1 = SourceBlockFormat( 1, start, column, start )
|
|||
|
||||
|
||||
#
|
||||
# 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)
|
||||
#
|
||||
# we define a few regular expressions here to detect them
|
||||
# */ (1 or more asterisks)
|
||||
#
|
||||
start = r'''
|
||||
\s* # any number of whitespace
|
||||
|
@ -107,47 +112,56 @@ re_source_block_format2 = SourceBlockFormat( 2, start, column, end )
|
|||
|
||||
|
||||
#
|
||||
# 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 @@ url = r"""
|
|||
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,24 +234,16 @@ re_source_keywords = re.compile( '''\\b ( typedef |
|
|||
##
|
||||
## 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
|
||||
##
|
||||
## 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)
|
||||
## 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:
|
||||
|
||||
|
@ -269,7 +280,7 @@ class SourceBlock:
|
|||
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,39 +297,38 @@ class SourceBlock:
|
|||
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
|
||||
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 @@ class SourceProcessor:
|
|||
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 @@ class SourceProcessor:
|
|||
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 @@ class SourceProcessor:
|
|||
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 @@ class SourceProcessor:
|
|||
|
||||
# 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()
|
||||
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
# ToHTML (c) 2002, 2003, 2005-2008, 2013
|
||||
# David Turner <david@freetype.org>
|
||||
#
|
||||
# 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 *
|
||||
|
@ -8,7 +22,7 @@ from formatter import *
|
|||
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 @@ toc_footer_end = """\
|
|||
"""
|
||||
|
||||
|
||||
# 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_header = '<h2>Synopsis</h2>'
|
|||
section_synopsis_footer = ''
|
||||
|
||||
|
||||
# Translate a single line of source to HTML. This will convert
|
||||
# a "<" into "<.", ">" into ">.", etc.
|
||||
# Translate a single line of source to HTML. This converts `<', `>', and
|
||||
# `&' into `<',`>', and `&'.
|
||||
#
|
||||
def html_quote( line ):
|
||||
result = string.replace( line, "&", "&" )
|
||||
result = string.replace( result, "<", "<" )
|
||||
result = string.replace( result, ">", ">" )
|
||||
result = string.replace( line, "&", "&" )
|
||||
result = string.replace( result, "<", "<" )
|
||||
result = string.replace( result, ">", ">" )
|
||||
return result
|
||||
|
||||
|
||||
|
||||
################################################################
|
||||
##
|
||||
## HTML FORMATTER CLASS
|
||||
##
|
||||
class HtmlFormatter( Formatter ):
|
||||
|
||||
def __init__( self, processor, project_title, file_prefix ):
|
||||
|
@ -189,31 +207,32 @@ class HtmlFormatter( Formatter ):
|
|||
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.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.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.columns = 3
|
||||
|
||||
|
@ -224,8 +243,8 @@ class HtmlFormatter( Formatter ):
|
|||
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 @@ class HtmlFormatter( Formatter ):
|
|||
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 @@ class HtmlFormatter( Formatter ):
|
|||
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 @@ class HtmlFormatter( Formatter ):
|
|||
# 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‘\2’\3', \
|
||||
line = re.sub( r"(^|\W)`(.*?)'(\W|$)",
|
||||
r'\1‘\2’\3',
|
||||
line )
|
||||
# convert tilde into non-breakable space
|
||||
line = string.replace( line, "~", " " )
|
||||
|
@ -274,7 +294,7 @@ class HtmlFormatter( Formatter ):
|
|||
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 @@ class HtmlFormatter( Formatter ):
|
|||
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 @@ class HtmlFormatter( Formatter ):
|
|||
|
||||
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 @@ class HtmlFormatter( Formatter ):
|
|||
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 @@ class HtmlFormatter( Formatter ):
|
|||
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 @@ class HtmlFormatter( Formatter ):
|
|||
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 @@ class HtmlFormatter( Formatter ):
|
|||
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 @@ class HtmlFormatter( Formatter ):
|
|||
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 @@ class HtmlFormatter( Formatter ):
|
|||
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 @@ class HtmlFormatter( Formatter ):
|
|||
|
||||
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,20 +443,20 @@ class HtmlFormatter( Formatter ):
|
|||
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
|
||||
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 @@ class HtmlFormatter( Formatter ):
|
|||
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 @@ class HtmlFormatter( Formatter ):
|
|||
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 @@ class HtmlFormatter( Formatter ):
|
|||
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 @@ class HtmlFormatter( Formatter ):
|
|||
|
||||
# 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 @@ class HtmlFormatter( Formatter ):
|
|||
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,15 +583,16 @@ class HtmlFormatter( Formatter ):
|
|||
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
|
||||
|
||||
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
|
||||
|
|
|
@ -1,15 +1,28 @@
|
|||
# Utils (c) 2002, 2004, 2007, 2008 David Turner <david@freetype.org>
|
||||
#
|
||||
# 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 @@ def index_sort( s1, s2 ):
|
|||
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 @@ def sort_order_list( input_list, order_list ):
|
|||
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 @@ def open_output( filename ):
|
|||
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,15 +96,16 @@ def check_output():
|
|||
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
|
||||
|
||||
|
||||
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 file_exists( pathname ):
|
|||
|
||||
|
||||
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:
|
||||
|
|
Loading…
Reference in New Issue