PERCEPS
The Perl C++ Surveyor
version 3.5.0
A C++ Documentation generator Written in Perl
Copyright (C) 1999 Mark Peskin
Now maintained by Tom Bryan
tbryan@python.net
PERCEPS is a Perl script designed to parse C/C++ header & source files and
automatically generate documentation in a variety of formats based on the class
definitions, declarations, and comment information found in those files. This
allows you to comment your code and generate useful documentation at the same
time with no extra effort. PERCEPS can be useful both as a documentation tool
and a simple but effective collaboration tool for both C and C++ projects.
Unlike some other documentation generation systems, PERCEPS does not produce
a fixed output format. Instead it uses "template" files, plugin filters, and
user-defined variables that can be freely modified to produce an almost
unlimited variety of output. The example template files included with the
distribution produce html pages, but Tex, RTF, man page, plain text or other
formats are also possible.
Please send comments, questions, or bug reports to:
perceps@python.net
PERCEPS home page:
http://starship.python.net/crew/tbryan/PERCEPS/index.html
If you develop interesting new sets of template files and/or plugins for
PERCEPS, particularly for new output formats, you are strongly
encouraged to share them with the PERCEPS user community. Please
contact me (see above) if you would consider allowing your templates to
be distributed with PERCEPS. Your input is appreciated.
Note: In the following documentation, NAME (all-caps) will be used to refer
to a user-defined variable name.
USING PERCEPS
I) Invoking PERCEPS
PERCEPS is invoked from the command line as follows:
perceps [-abefrhmncu] [-s suffixes] [-d odir] [-t tdir | -o tdir] [-i idir]
[(files|directories)...]
Options:
-a : Autolink text. This causes PERCEPS to scan
all comments, argument lists, etc. for
references to documented classes. All such
references are automatically linked to the
html file ClassName.html. For use with
html output only. Autolinking is VERY process
intensive for large projects. Avoid it
if you're in a hurry.
-b : Comment placement. By default PERCEPS assumes
that comments referring to a class member follow
the associated member. The b-switch causes this
assumption to be reversed, so comments coming before
a class member refer to that member.
-c : Causes standard c-style comments to be included
in documentation, unless they are embedded in C++
style comments, in which case they are still
ignored.
-e : Document all. Forces PERCEPS to attempt to document
ALL non-class items regardless of whether they are
commented.
-f : Find all. Causes all directories specified on
the command line to be searched RECURSIVELY for
input files matching the suffix list.
-h : When set, causes header file comments to be
treated as html instead of plaintext. If non-html
template files are used, HTML tags will
automatically be stripped.
-m : Merge function documentation. Causes documentation
found with member function definitions to be
merged with the documetation for the associated
member declaration. When set, member function
definitions will not be documented separately.
-n : Selective class documentation. Normally PERCEPS
documents every class in a project. The -n switch
will cause only classes preceeded by comment info
to be documented.
-q : Quiet mode, supresses diagnostic output
-r : Force re-build. Force all output files to be
re-generated even if the associated header
and template files haven't been modified since
the last build.
-u : Normally, comments that come before a class
definition are only included in the class
description if the follow at least one "short
description" line (i.e. //:). The -u switch
overrides this, causing ALL comments that
follow the previous declaration/definition
to be included.
-s suffixes : A comma delimited list of file suffixes to match
when searching directories for input. Wildcards
(*,?) are permissible. If -s is not specified,
a default suffix list is used (.h,.c,.C,.cpp).
-d odir : Directory in which to place output files
Defaults to the current working directory.
-t tdir : Directory to scan for template files.
Defaults to the output directory.
-o tdir : Same as -t but uses the contents of the
PERCEPS environment variable as a base path
-i idir : An additional path to insert before the
include file name when the include file
is referenced in documentation.
(files|directories)... A list of C or C++ files to parse.
Directories are searched for all files matching
the suffix list. Defaults to the current working
directory.
NOTE: UNIX users. For UNIX systems that support the #! construct in scripts,
you may need to change the first line of the PERCEPS source to point to the
location of your perl installation for the most convenient invocation.
WARNING: PERCEPS keeps track of build times with a ".perceps" file in the
output directory. Deleting this file will force a re-build, and modifying
it may prevent PERCEPS from recognizing updates to your header files. If
you accidentally modify this file, either delete it or invoke PERCEPS with
the -r command line option.
II) Directory Searches:
PERCEPS will now accept directories as command line arguments. If a
directory is specified, it will be searched for all files matching a
suffix list. Allowable suffixes can be specified on the command line
with the -s switch, or the default suffix list can be used. The default
suffix list can easily be changed by editing line 7 of the PERCEPS
source.
If the -f command line switch is specified, directories will be searched
recursively. The "subdir" global variable will be set to the directory
where each item is found. This global can then be used to build
documentation that respects the folder hierarchy of the code distribution.
PERCEPS will search each directory for a ".perceps_conf" file, which can
be used to specify per-directory options. Currently, the .perceps_conf file
may contain 3 different statement types:
suffixes suffix-list
Sets the suffix list for the directory and all subdirectories to
"suffix-list," which is a comma-delimited list of allowable
suffixes for documentable files.
(+/-)recursive
Turns recursive subdirectory searching (on/off)
global NAME = value
Sets the default value of the global variable "NAME" to
"value" for all files in the directory and its subdirectories.
This default value can be overridden using global variable
statements within documented files.
III) Commenting Your Code:
PERCEPS extracts information about your code from source or header files.
Items that are recognized and documented by PERCEPS include classes,
structs, unions, functions, global variables, typedef statements, and
macros. Comment information placed in these files in the proper format
can be extracted by PERCEPS for use in documentation. The comment
formatting rules are as follows:
1) By default only C++ style comments (//) are examined and all text
placed in C-style comments (/* */) will be ignored. This allows you to
create "private" comments that will not appear in documentation.
The "-c" command line switch overrides this behavior, forcing the
inclusion of C-style comments unless they are nested within a
C++ comment.
2) In general, comments that appear before an item (where item is
a class, function, global, typedef, or macro) refer to that item. Detail
description comments and custom comments placed before an item must be
preceded by at least one short description comment (see below) unless
the "-u" command line switch is enabled. This is to prevent stray
comments in the header files from polluting the descriptive comments.
Within classes, structs, or unions, by default, comments must follow
the member to which they refer while comments that appear before any
members refer to the class as a whole. This behavior can be overridden
using the "-b"command line switch, which causes comments within classes
to refer to the following element. However, in this case all comments
referring to the class as a whole must come before the opening brace
of the class definition.
3) By default, non-class items are not documented unless they are commented.
This means all non-class items (functions, globals, typedefs, macros)
that you wish to document should be preceded by a short description
comment (or any comment, if the -u option is specified). This selective
behavior can be overridden by invoking PERCEPS with the -e option, which
will cause ALL non-class items to be documented regardless of whether
they are commented.
4) Comments come in four varieties:
a) Short descriptions:
Short descriptions begin with "//:". Text in short description
comments is concatenated to form a brief one line description of the
class or member.
b) Detail descriptions:
Any C++ comments inside a class definition (or following a short
description comment that proceeds the class definition) that do not
begin with "//:" or "//!" are concatenated to form a detailed
description of the class or member.
c) User-defined Comment Types:
In addition to short and detailed descriptions, you may define your
own custom comment classes. These custom comments can be treated
differently in template files and/or passed to a special set of
plugin filters, allowing extremely flexible output control. The
format for user-defined comments is "//!NAME:", where NAME is a
alphanumeric user-defined comment name. Custom comment names should
be unique, and you should not use the same name for custom comments
and global variables. Also, avoid using any of the reserved names
listed below, as they are already used internally by PERCEPS.
d) User-defined Global Variables:
Global variable definitions begin with "//! ". They must occur
OUTSIDE of any class declarations. Any text in a global variable
definition is searched for special global variable/value pairs
of the form :
NAME=value
These global variables apply to any items found in the header
file following the comment in which they are declared.
Here is an example of a global comment line:
//! author="John Doe" lib=libjdoe.a
As with user-defined comments, global variable names should be
unique and reserved names (see below) should not be used.
There are two predefined global variables. "hfile" contains
the name of the header file in which the current item is defined.
The markers that are used to distinguish various comment types my be
modified by editing the appropriate variables near the beginning of the
PERCEPS source, allowing customization of commenting style.
See the source code for more information.
5) User-defined comments versus global variables:
At this point, you may be wondering why there is a distinction between
user-defined comments and global variable, which are also user-defined,
and how you should use them. Here is a brief comparison of the two
elements:
a) User-defined comments only apply to the adjacent item.
Global variables apply to all items that follow
their definition in a header file, and never apply to
class members.
b) User-defined comments can be piped to plugin filters, while
global variables cannot (except by using the {filter}..
{endfilter construct in the template file... see below).
c) Global variables can be looped over using {foreach}
statements in template files. User-defined comments cannot
be used this way.
IV) Creating template files:
PERCEPS template files are simply text files marked up with special tags
(contained in braces {} by default, see below) used to instruct PERCEPS
where to put documentation information. Most of these tags are simply
replaced with the appropriate data (item names, member names, arguments,
etc.). Several control-flow tags allow blocks of text to be looped over
or created conditionally.
1) Naming Template files:
PERCEPS expects specific naming conventions for template files.
PERCEPS will treat any file in the template directory ending in
".tmpl" as a template file and use it to generate output. In general,
output files will have the same name as the template files from which
they are generated minus the ".tmpl" extension.
Template files with the string "CLASS" (all caps) in the name are treated
specially. PERCEPS will generate an output file for EVERY class from such
template files, substituting the name of the class for "CLASS."
Similarly, template files with the string "@GLOBAL@", where GLOBAL
can be any global variable, cause PERCEPS to generate an output
file for each value of the specified global. The corresponding global
variable value will be substituted for "@GLOBAL@" in the output
file name. For the purposes of filename substitution, spaces and
file separator characters in the file name will be replaced by
underscores ("_").
IMPORTANT: The html autolink feature assumes the existence of a html
file ClassName.html for each class ClassName. Thus users generating
html output who wish to use the autolink feature should always have
a template file named "CLASS.html.tmpl" to generate such files.
2) Template file tags:
Template file tags are indicated by the surrounding braces. Tags are
either substitutional, in which case they are replaced by specific
information, or control flow.
NOTE: In the following documentation, optional parameters are
surrounded by brackets ("[]").
PERCEPS Template Tags
a) Substitutional Tags:
{ name [@]} Either the current item name, member name, or
global variable value depending on context (i.e.
the enclosing foreach loop). If the @
modifier is specified and the name refers to
a global, underscore substitution will be
performed as with template file names
containing "@GLOBAL@" (see above).
{ class } The current class name
{ classname } The current class name (same as {class})
{ classlinked } The current class name with an html
link to the page describing a container
class, if any. Useful for nested classes
and union members.
{ mname } The current member name
{ global } The current global variable value
{ args } Current member arguments (if its a function),
or enumeration members (if its an enumeration)
{ throwclass } If the function or member throws an exception,
the exception class name.
{ throwargs } If the function or member throws an exception,
the exception argument list.
{ member } The current member including any argument list
{ memberef } A html-clean, unique member label for use with
html anchors.
{ defclass } The class in which the member is defined.
{ type } The type of the current member
{ brief } Short description for this member (see above)
{ detail } detailed description for this member (see above)
{ templ } Template data for the current class (if template)
{ parents } A comma separated list of the classes parents
{ rb } Right bracket (}), or delimeter
{ lb } Left bracket ({), or delimeter
{ br } Linebreak. Works even inside {nobreak} blocks
(see below)
{ n } Same as { br }
{ buildtime } Time the current perceps run was started.
{ modtime } Modification time of the header file containing
definition of the current class.
{ NAME [@]} User defined-comment or global variable value for
the current class or member. If the @
modifier is specified underscore substitution
will be performed as with template file names
containing "@GLOBAL@" (see above).
i) Word Wrap
The output of {brief}, {detail}, and user-defined comment ({ NAME })
tags can optionally be word-wrapped by adding a few addional
parameters. The format for word wrapping is (taking the {detail}
tag as an example):
{detail wrap wraplen [nlchar]}
where wraplen is the line length (maximum number of characters on a
line) and nlchar is an optional string to insert before the newlines
while wrapping (it is not counted as part of the line length).
For example, the following tag will pring detail comment information,
wrapping lines at 50 characters and inserting a
before each
newline for html output:
{detail wrap 50
}
b) Control Flow Tags:
i) {foreach argument [all] [sort [sortfunc]]} looptext {next}
A for next loop. looptext (including any tags contained therein) is
evaluated for every member of the set specified by the argument
parameter. Loops can be nested. Recognized values for argument are:
item Loops over all documented items
class Loops over all classes
parent Loops over the parents of the current class
child Loops over the children of the current class
member Loops over all members of the current class
public Loops over the public members of the current class
protected Loops over the protected members of the current class
private Loops over the private members of the current class
friend Loops over friends of the current class
union Loops over all non-member unions.
func Loops over all non-member functions.
global Loops over all non-member variables.
typedef Loops over all typedef statements.
macro Loops over all macro definitions.
NAME Loops over the values of a global variable
INCLUDING null.
If the "all" keyword is specified for loops over member, public,
protected, private, or friend, ALL members of the specified type
will be listed including inherited members. Inheritance syntax is
respected.
If the "all" keyword is specified for loops over parent or child,
then every parent or child, across multiple levels of inheritance,
will be listed.
If the "all" keyword is specified for loops over global variables,
PERCEPS will loop over ALL values of the global variable in question,
INCLUDING null. This allows listing of classes for which
a given global variable is not defined.
The "all" keyword is ignored for other types of loops.
If the "sort" keyword is specified, the loop items are
sorted. If no sortfunc is specified, a default alphabetical
sort is performed. For custom sorts, "sortfunc" can be specified
as either:
1) a quoted block of perl statements comprising
the sort function, or
2) a file (in the template directory) containing
perl statements comprising the sort function.
The rules for creating sort functions are the same as with the perl
"sort" command. The sort function should compare the variables $a
and $b and return either -1,0,or 1 to establish their sort order.
As an example, the following statement will sort classes in reverse
alphabetical order:
{foreach class sort "$b cmp $a;"} ...... {next}
Due to limitations in the PERCEPS template file parser, quoted blocks
cannot contain subexpressions in braces.
ii) {if [!]argument} iftext {endif}
An if-then statement. iftext (including any tags contained therein)
is evaluated if the parameter specified by argument exists, or else
iftext is skipped. If-then blocks can be nested. Recognized values
for argument are:
class True if the current item is a class
struct True if the current item is a structure
func True if the current item or member is a function
global True if the current item is a global
typdef True if the current item is a typdef
macro True if the current item is a macro
union True if the current item is a union
first True if the current item is the first item
in the enclosing foreach loop.
last True if the current item is the last item
in the enclosing foreach loop.
mid True if the current item is neither the
first or last item in the enclosing foreach loop.
templ True if the current class is a template
lib True if the lib global variable is specified
author True if the author global variable is specified
parents True if the current class has parents
type True if the current member has a type
enum True if the current item or member is an enumeration
args True if the current member or function has arguments
throws True if the current member or function throws
exceptions
throwclass True if the current member or function throws
an exception class
throwargs True if the current member or function has
exception arguments
const True if the current member function is const
inherited True if the current member was inherited from
a parent class.
nested True if the current member is a nested class,
structure, or union.
brief True if the current item has a brief description
detail True if the current item has a detailed description
children True if the current class has children
public True if the current class has public members
protected True if the current class has protected members
private True if the current class has private members
friend True if the current class has friends
anypublic True if the current class has public members,
including inherited members.
anyprotected True if the current class has protected members,
including inherited members.
anyprivate True if the current class has private members,
including inherited members.
anyfriend True if the current class has friends,
including inherited friends.
hasinlines True if the current class has inline code
pure True if the current member is a pure virtual
function.
abstract True if the current class has pure virtual
functions (is abstract).
NAME True if the user-defined comment type or global
variable "NAME" is defined (non-null) for the
current class, member, or global-variable loop
iteration.
name /rxp/ True if the current item (matched by the {name}
tag) matches the perl regular expression
"rxp". Due to limitations in the PERCEPS
template file parser, rxp cannot contain braces.
parent /rxp/ True if any parent of the current class, crossing
multiple inheritance levels, matches the perl
regular expression "rxp".
child /rxp/ True if any child of the current class, crossing
multiple inheritance levels, matches the perl
regular expression "rxp".
Any argument can be negated by placing a "!" in front of it.
The {if class}, {if struct}, {if union}, and {if nested} tags,
when applied to class members, switch the context of the {if}
block to the nested class, structure, or union. Thus,
for example, the following code will list the members of nested
classes, structs, and unions inside the documentation for the
container class:
{foreach member}
....
{if nested}
{foreach member}.....{next}
{endif}
....
{next}
iii) {else} elsetext {endelse}
An else statement. elsetext (including any tags contained therein)
is evaluated if the previous if-then statement was false. If there
was no previous if-then statement then elsetext will always be
ignored. The else statement does NOT need to occur immediately
after its corresponding if-then statement (you may place other text
and tags in between).
c) Other Tags:
{ autolink ARGS }
Turns on autolinking if not already on for all following text.
Any text in ARGS is passed to the tag in autolinks.
This allows window targeting for autolinks. For example:
{ autolink TARGET="_top" }
{ !autolink }
Turns off autolinking. Overrides the -a command line switch.
{ keephtml }
Turns on html commenting. All comment text after this switch will
be treated as html. Overrides the -h command line switch.
{ !keephtml }
Turns off html commenting. All comment text after this switch will
be treated as plaintext. Overrides the -h command line switch.
{ applet ARGS }
Inserts the classgraph Java Applet, see below.
{filter FILENAME [kt]}....{endfilter}
Passes text in the enclosed block to the plugin filter specified
by filename after processing. The kt option must be specified in
order to process any tags inserted by the filter. Non-absolute
pathnames are taken relative to the template directory. See
plugin filters, below.
{include FILENAME}
Inserts template code from the specified file. Non-absolute
pathnames are taken relative to the template directory.
{nobreak}....{endnobreak}
Removes linebreaks from the enclosed text. Linebreaks specified
by the {n} tag are still respected.
d) File Generation Blocks:
PERCEPS provides a method for output files to be generated based
on specifications within template files, giving the user precise
control over fiel naming and which files are generated using which
templates for which items. This is done using a file generation block:
{genfile} NAMECODE {|} GENCODE {endgenfile}
The block is divided into two sections by the separator tag ("{|}").
The first section, NAMECODE, is parsed to determine the name for
the output file. If it parses to "stdout", output will be printed
to the screen. The second section, GENCODE, contains template
text to parse to create the output. The following example will
create output files only for classes whose names contain the
string "Obj" using template code in the file "Objtmpl":
{foreach class}
{if name /Obj/}
{genfile}{name}_output.html{|}{include Objtmpl}{endgenfile}
{endif}
{next}
Here is another example that prints a listing of all class members to
the screen:
{foreach class}
...
{genfile}stdout{|}Members of class {name}:\n{endgenfile}
{foreach member}
...
{genfile}stdout{|}\t{member}\n{endgenfile}
{next}
{next}
This ability to selectively print information to the screen can
be particularly useful in conjunction with the -q option, which
turns off other screen output, allowing PERCEPS output to be
piped to other programs in a UNIX environment.
3) Tag format options:
By default, perceps reserves braces ("{" and "}") as tag delimiters.
This can be inconvenient for some output formats, notably LaTex and
RTF, that also use braces as special characters. For added
convenience when working with such formats, PERCEPS allows the
tag delimeters to be specified by the user. To change the tag
delimiters, add the following line to your template files (which
will be ignored in the output):
#ptags open close
where open and close are the new opening and closing delimiters,
respectively. Each delimeter must be a single character, and
two different delimeters must be supplied. The new tag delimeters
will be applied on any lines following the #ptags statement, and
a single template file can contain multiple #ptags statements,
allowing different tag delimeters to be mixed in the same template
file. For example, the follwing line will change the tag
delimeters to square brackets:
#ptags [ ]
When non-standard delimeters are being used, the {lb} and {rb}
tags will produce the delimeters in output.
4) Continuation Lines:
Template file lines ending with a backslash ("\") are continued to
the next line. If, for some reason, you need to end a line with a
backslash, you may do so by adding an additional backslash ("\\").
If you are confused about how to make template files and use tags,
which would be understandable at this point, take a look at the
example files included in this distribution. The example includes a
set of templates to create html pages and uses most of the tags
described above.
V) Using the ClassGraph Applet in HTML documentation:
PERCEPS comes with a Java Applet to display and navigate the C++ class
class structure. To use this applet you must include the { applet }
tag in your template files. Unlike other template tags, the { applet }
tag takes a variable number of arguments that allow control of the
applet's appearance. The form for this tag is:
{ applet [param=value [param=value [...] ] ] }
Recognized parameters are:
height Applet height
width Applet width
target Window target for applet links
background Background color
textcolor Text color
maintextcolor Text color for emphasis
linecolor Line color
textincolor Text color for links with input focus
textdowncolor Text color for links when button is pressed
Colors are expressed as a 6-digit hexadecimal value (no leading #).
Any unrecognized parameters will be passed to the applet via
html tags, allowing you to expand the capabilities of the ClassGraph
applet without modifying PERCEPS.
The Java class files in the classes directory must be copied to the
directory containing the generated html pages for the applet to
function.
IMPORTANT: The html ClassGraph applet assumes the existence of a html
file ClassName.html for each class ClassName. Thus users generating
html output who wish to use the ClassGraph applet should always have
a template file named "CLASS.html.tmpl" to generate such files.
VI) Plugin Filters:
As of version 2, PERCEPS accepts plugin filters, written in Perl, that
give "Power Users" precise control over output.
1) Writing Plugins:
Writing plugins is simple. Filters are simply blocks of perl code
that are exec'd at run time. All filters must contain a subroutine,
"filter," that accepts a single argument (the text to be filtered),
and returns the filtered text. Thus, the format for a plugin file
is as follows:
sub filter {
local($str)=@_;
...
...
...
return $str;
}
WARNING: Filters have access to the PERCEPS global variable space.
Thus, to be safe, all variables used by the filter should be declared
in local blocks to avoid polluting the global name space. If
absolutely necessary, filters may declare global variables (This could
be useful for preserving information across calls to the filter
function), BUT YOU DO SO AT YOUR OWN RISK. Real masochists can
even write filters that manipulate the global data used by PERCEPS, but
this is not recommended, and I do not plan to provide a detailed
description of the perceps internal globals and their uses.
2) Invoking Plugin Filters:
Plugin Filters can be invoked in two ways:
a) Automatically:
PERCEPS automatically searches the template directory for filter
files with specific names. If found, specific data items are
passed to these filters (before autolinking!). PERCEPS searches
for the following filter files automatically:
Filename Item Filtered
input.flt All input files BEFORE parsing/processing
comment.flt All comments or globals
brief.flt All short description comments
brief_c.flt All short descriptions that refer to a class
brief_m.flt All short descriptions that refer to a member
detail.flt All detail description comments
detail_c.flt All detail descriptions that refer to a class
detail_m.flt All detail descriptions that refer to a member
NAME.flt All user defined comments or globals of the NAME type
NAME_c.flt All NAME descriptions that refer to a class
NAME_m.flt All NAME descriptions that refer to a member
args.flt Function Argument Lists
time.flt The time expressions returned by the
{buildtime} and {modtime} tags.
IF more than one filter applies to a given data element, the
most specific filters will be called first. Thus, if brief_c.flt,
brief.flt, and comment.flt all exist. They will be called in that
order on short descriptions that refer to a class.
b) Manually:
Any filter file may be invoked on a block of text within a
template file by using the {filter FILENAME}...{endfilter}
construct. In this case, the filter is called AFTER the
enclosed template text has been processed, so autolinking
will already have taken place.
Plugin filters can also be invoked from within other plugin filters
by calling &FILTER($str,$filename), which returns the filtered $str.
3) Including PERCEPS template tags in filter output:
By default, the output of filters that are invoked automatically will
NOT be processed as if it contains PERCEPS template tags, and such
tags will be ignored. If you would like to create a filter that adds
template tags to the output, you can do so by setting the global switch
$keeptags to true in your filter code. Note that some items may be
passed through several automatically invoked filters, and once the
$keeptags switch is set, it will remain set until the filtered text
is printed.
Text contained in filter blocks invoked manually via template files is
filtered after being processed for tags. Any tags added by the filter
will be processed only if the "kt" option is specified in the
filter invocation. See above.
PERCEPS allows the template creator to specify alternate sets of
template tag delimeters. If you want to include tags in your
filter output but you cannot be sure what delimeters are being used,
you can be safe by using the variables $TO and $TC to stand for the
opening and closing tag delimeters, respectively. Similarly,
$TO_sub and $TC_sub contain the text which is standing in for the
delimeters in output . You may call the function &SAFECHAR($str) which
makes sure any instances of $TO and $TC in $str are replaced by $TO_sub
and $TC_sub, then returns the "safe" (tag-free) string.
Note that if filters add HTML tags to the output stream the -h
command line option should be enabled.
Two example filters, time.flt, which takes the default ctime time format
and extracts the month and day, and param.flt, which turns
information in the "param" custom comment into an html table, have been
included with the example templates.
VII) Known Problems:
The ClassGraph java applet accepts a target parameter which is
passed to the context.showDocument method to set a browser
window target for links. Unfortunately, not all browser/java VM
combinations handle this target parameter properly, causing creation
of an unwanted new window. In particular, I have had this problem
with Internet Explorer for MacIntosh and beta versions of Communicator
for all platforms.
Some versions of Netscape Communicator seem to have trouble parsing the
"<" tag (to display "<"). When this problem occurs it can mangle the
display of templates in html documentation (The html source generated by
PERCEPS is fine... the browser just isn't displaying it properly).
Fix: 1) Use a different browser 2) Hope that browser/JVM developers get
their act together.
Although I have endeavored to make PERCEPS as syntax-transparent as
possible, I cannot guarantee that PERCEPS will properly parse
header files with bizarre syntax (I know, I know, nobody thinks
THEIR syntax is bizarre).