autodoc.git
/
traditional_manual
/
chapter_21.html
version
»
Context lines:
10
20
40
80
file
none
3
autodoc.git/traditional_manual/chapter_21.html:1:
<!doctype html><html><head><title>Pike Reference Manual</title> <meta charset='utf-8'></head>
-
<body><dl><dt><h1 class='header'>21. Pike
AutoDoc markup
</h1></dt><dd><
/dd
>
-
<dt><a
name
='
1
'>
</a>
-
<h2
class='header'>21.1.
Syntax
</
h2
></dt>
-
<
dd></dd><
dt><
h3
class
='
header
'>
21.
1.
1.
Line orientation
</
h3
></dt><dd><
p>The markup is line oriented. If you need to write
a
line which is very
-
long, it can be broken into several lines
.
A trailing <tt
>
@</tt> on the line
-
indicates that it continues on the next line
.
The <tt>@</tt> and the newline
-
character will be discarded, and the lines merged
.
Thus:
</
p
><
p><
/
p
>
<pre>
-
//! @variable thisVariableNameIsSoLong@
-
//!YouJustCantBelieveIt
-
<
/pre
><
p></p>
-
<p>will
appear to the parser as:</p><p></p><pre>
-
//! @variable thisVariableNameIsSoLongYouJustCantBelieveIt
-
</pre><p></p>
-
<p>This is sometimes necessary because keywords that take parameters
-
expect all the parameters to appear on the same line and treat the end
-
of the line as the end of the parameter list.</p><p>The character
'
\r' is also discarded
.
The same applies to all other
-
non-printable and control characters except for
'
\n' and '\t'.</p
>
<p>In text (see the nonterminal 'text' in the grammar at the end of this
-
file), a blank line with surrounding non-blank lines will give a
-
paragraph break
.
Thus:</p><p></p><pre>
-
//! - I love you, said Danny
.
-
//!
-
//! - You have no right to come here after what you did to
-
//! my little dog, screamed Penny in despair.
-
</
pre
><
p><
/
p
>
-
<
p>will generate the following XML:</p><p><pre>
-
<p> - I love you, said Danny.</p>
-
<p> - You have no right to come here after what you did to
-
my little dog, screamed Penny in despair.</p>
-
</pre></p></
dd><
dt><h3
class
='
header
'>
21.
1.
2
.
Keywords</h3></dt><dd><p>Keywords
always
begin
with
an
at-sign:
<
tt>@<
/
tt
>
. A
<
tt>@<
/
tt
>
is quoted by writing two
-
of them:
<
tt
>
@@
<
/tt>.
There are four types of keywords (the keywords in []
'
s
-
are examples of keywords of the different types):</p
>
<ol>
-
<li><p> Meta keywords <tt>[@decl, @class, @endclass, @module and @endmodule]</tt>
-
Must stand alone on one line, preceded only by whitespace
.
These are
-
not really part of the markup
.
They
must come before any text or
-
other keywords in the doc block. They provide information about what
-
is
being documented etc. and do not result in any text in the
-
documentation. Meta keywords have keyword specific parameter
-
syntaxes.
</
p
></
li
>
-
-
<
li
><
p>
Delimiter keywords <tt>[@param, @member, @item, @note,
.
..]</tt
>
-
Must stand alone on one line, preceded only by whitespace
.
These are
-
keywords that begin a section inside their block
.
They
have no end
-
marker, but rather the section ends when the next delimiter keyword
-
on the same level is found. Can have parameters.
</
p
></
li
>
-
-
<
li
><
p>
Block/endblock keywords <tt>[@dl - @enddl, @mapping - @endmapping,
.
..]</tt
>
-
Must stand alone on one line, preceded only by whitespace
.
These
open
-
or close a block. If a block is started with @foo, it must end with a
-
matching @endfoo. The lines inside the block can be divided into
-
sections by using delimiter keywords. The start keyword can have
-
parameters, but the corresponding end keyword can not.
</
p
></
li
>
-
-
<
li
><
p>
Short markup keywords <tt>[@ref{
.
.@}, @i{..@}, ...]</tt
>
-
These are used in the text to perform cosmetic tasks, for example
-
changing text to italic (<tt>@i</tt>), teletype(<tt>@tt</tt>) or marking a word as a
-
reference to a pike entity (<tt>@ref</tt>)
.
They can be nested, but a short
-
markup keyword can not contain a keyword of types
1
-3
.
They begin
-
with
<
tt>@keyword{ and end with @}<
/
tt
>
.
</
p
>
</li>
-
-
<
li
><
p> The magic keyword <tt>@xml{ ... @}</tt>
-
This is
a
special keyword that provides an escape to XML
.
All ordinary
-
text inside it is passed unquoted to the output. However, the short
-
markup keywords are still valid and may be used inside it, and thus
-
<tt
>
@</tt> must still be quoted with <tt>@@</tt>
.
<tt><</tt> and <tt>></tt> must also be quoted unless
-
the intention really is to write XML
.
For example:
</
p
>
-
-
<
example>
-
/
/! He is so @xml{<i>italic</i> and @b{bold@}!@}!!
-
</example
>
-
-
<
p
>
will generate the following XML:
<
/p>
-
-
<p
>
<pre>
-
He is so <i>italic</i> and <b>bold</b>!!!
-
</pre></p></li>
-
</ol><p>NOTA BENE: Delimiter keywords (
2
) and block keywords (
3
)
must
stand
-
alone
(with
their parameters, if any) on one line.
</
p
></dd><dt><
h3
class
='
header
'>
21.1.
3.
Delimiter keyword grouping
</
h3
></dt><dd><
p>Delimiter keywords that indicate
a
new section inside the block can be
-
grouped together in the interest of not writing the same docstring for
-
multiple parameters etc
.
Delimiters are grouped if they appear on
-
consecutive lines. For example, when documenting a method:</p
>
<p></p><pre>
-
//! @decl int dist(int x, int y)
-
//! Calculates the distance
.
-
//! @param x
-
//! @param y
-
//! The coordinates of the vector.
-
</
pre
><
p><
/
p
>
-
<
p
>
Above, the two
<
tt>@param</tt>'s
x and y are grouped together and share the
-
same docstring: "The coordinates of the vector
.
". It is an error to
-
try to group together different keywords:</p><p></p><pre>
-
//! Error, can
'
t group @note and @param:
-
//! @param x
-
//! @note
-
//! Don't use this function
.
At all
.
Ever.
-
</
pre
><
p><
/
p
>
-
<
/
dd><
dt><h3
class
='
header
'>
21
.
1
.
4.
Keyword
parameters
</
h3
></
dt
><dd><
p>After the leading <tt>@keyword</tt> (that may be preceded only by whitespace)
-
on the line, the rest of the line is interpreted as
a
parameter list
.
-
The syntax of this parameter list can be different depending on the
-
keyword:</p
>
<ol>
-
<li><p> Special keyword parameter list syntax
-
Here the parameters can be parsed according to Pike syntax or in
-
some other way
.
Examples
of keywords that use these kinds of special
-
syntaxes are all the meta keywords, @member and @elem.
</
p
></
li
>
-
-
<
li
><
p> Default parameter list syntax
-
The meaning of parameters is determined by the order in which they
-
appear, much like the arguments in
a
unix shell command line - hence
-
they are not named as in HTML or XML
.
Parameters are separated by
-
whitespace. If you wish to have a parameter string with whitespace in
-
it, you must surround the string with a pair of
'
or "
.
When the
-
quoting character itself is in the string, a duplication is used to
-
quote it:
</
p>
-
-
<example>
-
//! @question "He is
a
""swapper""?!"
-
</example
>
-
-
<
p>However, if your parameter contains only one of ' and ", then it is
-
smarter to choose the other one as the quouting character:<
/
p
>
-
-
<
example
>
-
//! @question 'He is
a
"swapper"?!
'
-
</example
>
-
-
<p>It
is
an error not to end a quote before the end of the line:
</
p>
-
-
<example>
-
//! @wrong "Aww, come on now, this worked fine in C64 basic!
-
</example>
-
-
<p>If
a
quoted parameter is too long to fit in one line, use the <tt
>
@
</
tt
>
at
-
the end of the line to merge it with the following:
<
/p
>
-
-
<
example>
-
//! @right "Oh, joy! Now I can make my parameters just as@
-
//! long as I want them!"
-
</example
>
-
-
<p>The parameters are not parsed so you can not have markup inside
-
them
.
Pike style quoting is not used either, which means that if
-
you write:</p>
-
-
<example>
-
//! @look "\n"
-
</example>
-
-
<p>
The
parameter
will
be a string with two characters, a backslash
-
followed by
the
letter n.
</
p
></
li
>
-
<
/ol></
dd><
dt><h3
class
='
header
'>
21
.
1
.
5.
Grammar
</
h3
></
dt><
dd>
<p>Here comes a BNF-ish grammar for documentation blocks. Note that
-
before the parsing of the block, all lines ending with a
<
tt
>
@
<
/tt> will be
-
merged with the next line (see (
a
)
above)</p><p><pre>
-
docblock:
-
metaline*, blockbody
-
-
metaline:
-
start_of_line, white_space*, metakeyword, any_char_but_newline,
-
end_of_line
-
-
blockbody:
-
section?, (delimiter+, section)*, delimiter?
-
-
delimiter:
-
start_of_line, white_space*, delimiterkeyword, parameterlist,
-
end_of_line
-
-
section:
-
(text|block)+
-
-
block:
-
blockbegin, blockbody, blockend
-
-
blockbegin:
-
start_of_line, white_space*, blockkeyword, parameterlist,
-
end_of_line
-
-
blockend:
-
start_of_line, white_space*, blockkeyword, white_space*, end_of_line
-
-
parameterlist:
-
white_space*, (parameter, white_space+)*
-
-
parameter:
-
qoutedparameter | any_char_but_white_space+
-
-
quotedparameter:
-
(
'
"', (any
_
char_but_new_line_or_" |
'
""'),
'"')
-
| ('\'', (any_char_but_new_line_or_' | '\'\''), '\'')
-
-
text:
-
(character|shortmarkup|xmlescape)+
-
-
xmlescape:
-
'@xml{', any_char_sequence_not_containing_@}, '@}'
-
-
character:
-
any_char_but_@ | '@@'
-
-
shortmarkup:
-
shortmarkupkeyword, '{', text, '@}'
-
-
metakeyword, blockkeyword, delimiterkeyword, shortmarkupkeyword:
-
keyword
-
-
keyword:
-
'@', alpha_char+
-
-
endblockkeyword:
-
'@end', alpha_char+
-
-
white_space:
-
' ' | '\t'
-
</
pre
></
p></
dd>
-
<dt><a
name
='
2
'>
</a>
-
<h2 class='header'>21
.
2.
Pike autodoc inlining
</
h2
></dt>
-
<dd><
p>The autodoc extractor works either in C mode or in Pike mode. The
-
reason why the two modes are not the same is that they perform two
-
very different tasks. The C mode only has to find comments in the
-
file, and ignores the surrounding code totally, while the Pike mode on
-
the other hand is supposed to be smarter and distill
a
lot of
-
information from the Pike code that surrounds the comments
.
</p
>
<p>Both work at the file level
.
That makes it easy to use for example
-
"make" to generate documentation for the source tree
.
Another
benefit
-
is that the generation will not have to reparse all of the tree if
-
only one source file is changed.
</
p
><
p
>
For Pike module trees, the extractor can recurse through the file tree
-
on its own, but for C files, where the directory structure gives
-
insufficient cues about what is what, there must be make targets set
-
up manually. All generated XML files can then be merged together into
-
the final Pike namespace.
<
/p></
dd><
dt><h3
class
='
header
'>
21
.2.
1.
C
files
</
h3
></
dt><
dd>
<p>In C files, the doc comments look like:</p><p></p><pre>
-
/*! yadda yadda
-
*! yadda yadda yadda
-
*/
-
<
/pre
><
p></p>
-
<p>Note
that only lines that start with <tt>*!</tt> count, so above are only two
-
doc lines
.
Any whitespace before the leading <tt
>
*!</tt> is skipped, so that
-
the lines can be indented freely
.
</p><p>In the C files, no parsing of the surrounding code is done
.
The
-
context
lies completely in the doc comments themselves,
and
the target
-
of the doc comment is determined by special meta keywords that are not
-
really part of the doc blocks, but rather modifiers that tell which
-
Pike entity the doc is about.
</
p
><
p><
/
p
><
pre
>
-
/*! @module Foo
-
*! ... doc for the Foo module ...
-
*! ... */
-
-
/*! @decl int
a
()
-
*!
...
doc
for the method Foo.a() ...
-
*! .... */
-
-
/*! @class Bar
-
*! ... doc for the class Foo.Bar ...
-
*! ... */
-
-
/*! @decl mapping(string:string) userprefs()
-
*! ... doc for the method Foo.Bar->userprefs() ...
-
*! ... */
-
-
/*! @decl int a
-
*! @decl int b
-
*! ... doc for the variables Foo.Bar->a and Foo.Bar->b ...
-
*! ... */
-
-
/*! @endclass */
-
-
/*! @endmodule */
-
</
pre
><
p><
/
p
>
-
<
p
>
The
<
tt>@module</tt>
and <tt>@class</tt> too keywords are to work like segment
-
directives in assembler source files
.
That is, you can have <tt
>
@module
-
foo</tt> in several C files, if the module source is spread over multiple
-
files
.
However,
if you write doc for the module itself in several
-
places, an error will be triggered.
</
p
></dd><
dt
><
h3
class
='
header
'>
21
.
2
.
2.
Pike
files
</
h3
></
dt><
dd>
<p>Doc comments look like:</p><p></p><pre>
-
//! yadda yadda yadda
-
//! yadda yadda
-
<
/pre
><
p></p>
-
<p>To be considered one doc block, the comments must be separated only by
-
whitespace and <tt>\n</tt>, that is they have to be on adjacent lines
-
in the code. Each doc block in the Pike code has one or more targets;
-
the Pike entities (modules, classes, variables etc.) that the doc
-
block is documenting. The target of
a
doc comment is the coherent
-
block of declarations adjacent to (immediately before or after) it in
-
the code, without intervening blank lines
.
Examples:</p
>
<p></p><pre>
-
//! Doc for alpha
-
int alpha()
-
{
-
return 4711;
-
}
-
-
protected int undocumented;
-
-
//! Error! This doc block has no destination!
-
-
int beta;
-
//! Doc for beta
-
-
//! Doc for gamma, delta, and epsilon
-
int gamma, delta;
-
float epsilon;
-
-
//! Error here!
-
int zeta;
-
//! ambiguous which doc to associate with zeta
.
-
-
int eta;
-
//! Error here too! ambiguous which variable is documented.
-
int theta;
-
-
//! Doc for two methods. This is so UGLY! We strongly recommend
-
//! using the decl keywords instead to accomplish this effect.
-
int methodOne()
-
{
-
...
-
}
-
int methodTwo()
-
{
-
...
-
}
-
-
//! However, it can be useful sometimes, for really short methods:
-
int very_short() { return 4711; }
-
int even_shorter() { return 0; }
-
</
pre
><
p><
/
p
>
-
<
p
>
In Pike files, you can not use
<
tt>@class</tt> or <tt>@module</tt> to tell which module
-
or class you are in. To document
a
class, you simply write:</p
>
<p></p><pre>
-
//! Doc for the class
-
class CheeseMaker
-
{
-
//! You can even document inherits!
-
inherit Earth : earth;
-
-
//! Doc for CheeseMaker->a()
-
int a()
-
{
-
..
.
-
}
-
-
void create(string s) { ... }
-
}
-
</
pre><p></p>
-
<p>The parser will automatically identify <tt>
a
()</tt
>
as a member method of the
-
class
<
tt>CheeseMaker<
/
tt
>
, and will detect that <tt>Earth</tt> is inherited by
-
<
tt
>
CheeseMaker
<
/tt>. If
a
class has no documentation comment, it
'
s internals
-
will not be examined, thus it is an error if a class contains
-
documentation comments but is itself undocumented:</p
>
<p></p><pre>
-
class a()
-
{
-
//! @decl foo
-
//!
..
.
doc for foo ...
-
}
-
</
pre
><
p><
/
p
>
-
<
p
>
A
special inlining case is that of functions and classes
.
When documenting
-
these, the doc comment can be put between the head of the function/class,
-
and the opening <tt
>
{</tt>, like this:</p><p></p><pre>
-
class Roy
-
//! Documentation for Roy
-
{
-
..
..
-
}
-
-
int un_randomize(int x)
-
//! This function takes a random number, and transforms it into
-
//! a predictable number.
-
{
-
return x = 4711;
-
}
-
</
pre
><
p><
/
p
>
-
<
p
>
If
a
doc block is the first in a file, and it has no target, then it
-
is treated as doc for the file (or rather: the module/class that the
-
file compiles into) itself
.
In any other case it is an error to have a
-
targetless doc block
.
A target can also be set with the
<
tt>@decl<
/
tt> meta
-
keyword. If
a
doc comment begins with some <tt
>
@decl
</
tt
>
keywords, these
-
<
tt
>
@decl
<
/tt>'s
act just like real declarations standing next to the doc
.
-
Thus:</p
>
<p></p><pre>
-
//! @decl int a(int x)
-
//! @decl int b(int x)
-
//! Here is some doc for these functions
.
...
-
</
pre
><
p><
/
p
>
-
<
p
>
is autodocwise equivalent to:
<
/p><p></p><pre>
-
//! Here is some doc for these functions....
-
int
a
(int
x)
-
{
-
...
..
-
}
-
int b(int x)
-
{
-
.....
-
}
-
</
pre
><
p><
/
p
>
-
<
p
>
In case it is legal to have both an adjacent declaration and
-
the
<
tt>@decl</tt> keyword at the block beginning. That is when you document
-
"polymorph" methods. Then the adjacent declaration must be
a
method,
-
and all <tt>@decl</tt>
'
s must be methods that have the same name as the real
-
method:</p
>
<p></p><pre>
-
//! @decl float cube(float x)
-
//! @decl int cube(int x)
-
//! Gives x**3
.
-
//! @param x
-
//! The number to cube
.
-
int|float cube(int|float x)
-
{
-
....
-
}
-
</
pre
><
p><
/
p
>
-
<
p
>
The real method prototype is discarded in favour to the
<
tt>@decl</tt>'ed
-
variants,
who will be shown in the documentation instead
.
</p><p>One problem that is unsolved so far is how to handle <tt>
#
if .. #else ..
-
#endif</tt
>
constructions
.
The approach so far has been to ignore
-
preprocessor directives totally
.
For
example,
the
parser does not
-
handle:
</
p
><
p><
/
p
><
pre
>
-
#ifdef MALE
-
int bertil()
-
#else
-
int berit()
-
#endif
-
{
-
..
.
body ...
-
}
-
</
pre
><
p><
/
p
>
-
<
p
>
It
a
portion of the code is unextractable because it contains too much
-
preprocessor macros and stuff, you can make the extractor skip it by using
-
<tt
>
@ignore</tt>:</p><p></p><pre>
-
/
/! @ignore
-
-
HERE_ARE_SOME_STRANGE_THINGS
-
#ifdef A
-
A
-
#endif
-
-
//! @endignore
-
</
pre
><
p><
/
p
>
-
<
p
>
All
<
tt>@ignore-@endignore</tt>
sections of the file are removed before any extraction
-
is done, so they can cross class boundaries and the like
.
You can nest <tt
>
@ignore</tt>
-
inside eachother
.
Another
application
for
<
tt
>
@ignore
</
tt
>
is to hide actual class
-
boundaries from the extractor:
<
/p
><
p></p><pre>
-
//! @ignore
-
class C {
-
//! @endignore
-
-
//! To the parser, this function appears to be on the top level
-
int f() {
..
.
}
-
-
//! @ignore
-
}
-
//! @endignore
-
</
pre
><
p><
/
p
>
-
<
/dd>
-
<
dt><a
name
='
3
'>
</a>
-
<h2 class='header'>21
.
3.
Pike
autodoc tags
</
h2
></dt>
-
<
dd
><
p>We
have defined some different categories of markup, each with its own
-
semantics
.
Seen from the parser, there are two main construct levels:
</
p
><
ul>
-
<li><p> The "what-are-we-documenting level" constructs; <tt>@decl<
/
tt
>
for Pike files
-
and
<
tt
>
@module
<
/tt>,
<tt
>
@endmodule</tt>, <tt>@class</tt> and <tt>@endclass</tt>
-
on top of that for C files
.
These
are the meta level tags covered in section a).
</
p
></
li
>
-
-
<
li
><
p>
Inside-of-comment level constructs for documentation markup,
-
covered in sections b), c) and d)
.
</p
>
</li>
-
</ul><p>All
markup
can
also be divided into categories based on their look
-
and semantics; there are three categories here (with examples):
</
p
><
ul
>
-
<
li
><
p> Grouping constructs that mark the opening/closing of
a
section of
-
some sort (<tt
>
@mapping/@endmapping, @dl/@enddl, @module/@endmodule</tt>)
.
-
Most
of these not already covered by secion a) appear in b).
</
p
></
li
>
-
-
<
li
><
p>
subdividers that break up an outer grouping construct into
-
subsections (<tt
>
@member,
@item,
@param
</
tt
>
)
</
p
>
</li>
-
-
<
li
><
p>
short text markup constructs that basically map to XML containers
-
(<tt
>
@i{
.
..@},
@ref{...@}
</
tt
>
)
</
p
>
</li>
-
<
/ul></
dd><
dt><h3
class
='
header
'>
21
.
3.
1.
Meta
level tags
</
h3
></
dt
><dd><
p>These
tags all serve the purpose of denoting what pike entities your
-
comments should be tied to
.
This is particularly needed in (and in
-
part only applies to) C files, where the autodoc extractor does not
-
try to interpret and parse class and method definitions.</p
>
<p><pre>
-
Keyword:
@module
-
Legal for: C files only (neither needed nor legal for
Pike
files)
-
Arguments: (the last segment of) the module name (ie no "
.
" allowed)
-
</
pre
></
p
>
<p>Example: To document the module <tt>Parser.XML</tt> module, you need two
-
consecutive module tags:
<
/p
><
p></p><pre>
-
/*! @module Parser */
-
/*! @module XML */
-
</pre
>
<p></p>
-
<p>A
<tt>@module</tt>
keyword sets the scope of documentation comments following
-
it
.
<tt>@module</tt> tags nest, as shown in the example above,
and
must be
-
ended with a matching number of @endmodule tags, as in:
</
p
><
p><
/
p
>
<pre>
-
/*! @endmodule XML */
-
/*! @endmodule Parser */
-
<
/pre
><
p></p>
-
<p>A <tt>@module</tt> keyword may also have
a
text child documenting the module
-
itself:</p
>
<p></p><pre>
-
/*! @module Parser
-
*!
-
*! The common roof under which parsers of various kinds, such as
-
*! @[Parser
.
XML],
@[Parser.
Pike
]
and @[Parser.C] are housed.
-
*/
-
</
pre
><
p><
/
p
>
-
<
p
>
There are two special @module targets available; the
<
tt>predef::</tt>
module
-
and the <tt
>
lfun::</tt> module
.
The
<tt>predef::</tt>
module, although more of a scope
-
than a module, contains the definitions for all methods
in Pike
's
-
<
tt>predef::<
/
tt> scope, as in:</p><p></p><pre>
-
/*! @module predef::
-
*! @decl int equal(mixed
a
, mixed b)
-
*! This function checks if the values @[a] and @[b] are equal.
-
*! @endmodule
-
*/
-
</pre
><
p><
/
p
>
-
<
p
>
The
<
tt>lfun::</tt>
module scope does not legally exist in Pike, but it
-
houses the docs for all lfuns (the virtual methods for fulfilling the
-
Pike object API)
.
An example:</p
>
<p></p><pre>
-
/*! @module lfun::
-
*! @decl int(0
..
1)
`!=(mixed
arg1,
mixed
arg2, mixed ... extras)
-
*! The inequality operator.
-
*! @endmodule
-
*/
-
</
pre
><
p><
/
p
>
-
<
p
>
This also means that referencing (via
<
tt>@ref{
.
..@}</tt
>
or <tt>@[
..
.]</tt>)
the
lfun
-
documentation
strings
can
be done using
<
tt
>
@[lfun::`!=]
</
tt
>
and the like, as
-
can predefs via
<
tt
>
@[predef::sort()]
<
/tt>
et cetera
.
</p
>
<p><pre>
-
Keyword:
@endmodule
-
Legal for: C files only (neither needed nor legal for
Pike
files)
-
Arguments:
(the last segment of) the module name (optional)
-
</
pre
>
>
</
p
>
<p>When the optional argument to <tt>@endmodule</tt> is given (for code clarity),
-
the extractor will verify that the module scope you close was indeed
-
the one you opened, as in the
<
tt
>
@module
<
/tt>
example above
.
The following
-
would trigger an error:</p
>
<p></p><pre>
-
/*! @module Parser
-
*! @module XML */
-
-
/*!
..
.
some
autodoc comments ... */
-
-
/*! @endmodule Parser
-
*! @endmodule XML */
-
</
pre
><
p><
/
p
>
-
<
p
>
while the same example, ending in
<
/p><p></p><pre>
-
/*! @endmodule
-
*! @endmodule */
-
</pre><p></p>
-
<p>would be considered legal
.
</p
>
<p><pre>
-
Keyword: @class
-
Legal for: C files only (neither needed nor legal for Pike files)
-
Arguments: (the last segment of) the class name (ie no "
.
" allowed)
-
</pre></p><p>Example: to document the <tt>Process
.
create_process</tt>
class,
you
would use:
</
p
><
p><
/
p
>
<pre>
-
/*! @module Process
-
*! @class create_process */
-
<
/pre
><
p></p>
-
<p>And
end the scope similar to <tt>@module</tt>:</p><p></p><pre>
-
/*! @endclass create
_
process
-
*! @endmodule Process */
-
</pre><p></p>
-
<p>Like <tt>@module</tt> tags, <tt>@class</tt> tags may be nested any number of levels
-
(when documenting subclasses to subclasses to subclasses to
.
..).</p
>
<p><pre>
-
Keyword:
@endclass
-
Legal for: C files only (neither needed nor legal for
Pike
files)
-
Arguments:
(the last segment of) the class name (optional)
-
</
pre
></
p
>
<p>When the optional argument to <tt>@endclass</tt> is given (for code clarity),
-
the extractor will verify that the class scope you close was indeed
-
the one you opened, just as with
<
tt
>
@endmodule
<
/tt>
above
.
</p
>
<p><pre>
-
Keyword: @decl
-
Legal for: All source code (C and Pike files)
-
Arguments: (the last segment of) the identifier name (ie "
.
"
illegal)
-
</
pre
></
p
><
p
>
The
<
tt>@decl</tt> keyword is used to target
a
specific (
...
more
to
come!
:-)
</
p
><
p
><
pre
>
-
-
-
-
+--------------------------------------+
-
| Pike autodoc markup - the XML format |
-
+--------------------------------------+
-
-
======================================================================
-
a
)
Introduction
-
----------------------------------------------------------------------
-
-
When a piece of documentation is viewed in human-readable format, it
-
has gone through the following states:
-
-
1
.
Doc written in comments in source code (C or Pike).
-
-
2. A lot of smaller XML files, one for each source code file.
-
-
3.
A big chunk of XML, describing the whole hierarchy.
-
-
4. A repository of smaller and more manageable XML files.
-
-
5. A HTML page rendered from one such file.
-
(Or a PDF file, or whatever).
-
-
The transition from state 1 to state 2 is the extraction of
-
documentation from source files. There are several (well, at
-
least two) markup formats, and there are occasions where it is
-
handy to generate documentation automatically &c. This document
-
describes how a file in state 2 should be structured in order to
-
be handled correctly by subsequent passes and presented in a
-
consistent manner.
-
-
======================================================================
-
b) Overall structure
-
----------------------------------------------------------------------
-
-
Each source file adds some number of entities to the whole hierarchy.
-
It can contain a class or a module. It can contain an empty module,
-
that has its methods and members defined in some other source file,
-
and so on. Suppose we have a file containing documentation for the
-
class Class in the module Module. The XML skeleton of the file
-
would then be:
-
-
<module name="">
-
<module name="Module">
-
<class name="Class">
-
... perhaps some info on inherits, members &c ...
-
<doc>
-
... the documentation of the class Module.Class ...
-
</doc>
-
</class>
-
</module>
-
</module>
-
-
The <module name=""> refers to the top module. That element, and its
-
child <module name="Module">, exist only to put the <class name="Class">
-
in its correct position in the hierarchy. So we can divide the elements
-
in the XML file into two groups: skeletal elements and content elements.
-
-
Each actual module/class/whatever in the Pike hierarchy maps to at most
-
one content element, however it can map to any number of skeletal elements.
-
For example, the top module is mapped to a skeletal element in each XML
-
file extracted from a single source file. To get from state 2 to state
3
-
in the list above, all XML files are merged into one big
.
All the elements
-
that a module or class map to are merged into one, and if one of those
-
elements contains documentation (=is a content element), then that
-
documentation becomes a child of the merger of the elements.
-
-
======================================================================
-
c) Grouping
-
----------------------------------------------------------------------
-
-
Classes and modules always appear as <module> and <class> elements.
-
Methods, variables, constants &c, however, can be grouped in the
-
source code:
-
-
//! Two variables:
-
int a;
-
int b;
-
-
Even a single variable is considered as a group with one member.
-
Continuing the example in the previous section, suppose that Module.Class
-
has two member variables, a and b, that are documented as a group:
-
-
<module name="">
-
<module name="Module">
-
<class name="Class">
-
... perhaps some info on inherits, members &c ...
-
-
<docgroup homogen-type="variable">
-
<variable name="a"><type><int/></type></variable>
-
<variable name="b"><type><int/></type></variable>
-
<doc>
-
... documentation for Module.Class.a and Module.Class.b ...
-
</doc>
-
</docgroup>
-
-
<doc>
-
... the documentation of the class Module.Class ...
-
</doc>
-
</class>
-
</module>
-
</module>
-
-
If all the children of a <docgroup> are of the same type, e.g. all are
-
<method> elements, then the <docgroup> has the attribute homogen-type
-
(="method" in the example). If all the children have identical name="..."
-
attributes, then the <docgroup> gets a homogen-name="..." attribute aswell.
-
-
The <docgroup> has a <doc> child containing the docmentation for the other
-
children of the <docgroup>. An entity that cannot be grouped (class, module,
-
enum), has a <doc> child of its own instead.
-
-
======================================================================
-
d)
Pike
entities
-
----------------------------------------------------------------------
-
-
Pike
entities - classes, modules, methods, variables, constants, &c, have some
-
things in common, and many parts of the xml format are the same for all of
-
these entities. All entities are represented with an XML element, namely one
-
of:
-
-
<class>
-
<constant>
-
<enum>
-
<inherit>
-
<method>
-
<modifier>
-
<module>
-
<typedef>
-
<variable>
-
-
The names speak for themselves, except: <modifier> which is used for modifier
-
ranges:
-
-
/
/! Some variables:
-
protected final {
-
int x, y;
-
-
string n;
-
}
-
-
A Pike entity may also have the following properties:
-
-
Name - Given as
a
name="..." attribute:
-
<variable name="i"> ... <
/
variable>
-
-
Modifiers - Given as
a
child element <modifiers>:
-
<variable name
=
"i">
-
<modifiers>
-
<optional/><protected/><private/>
-
</modifiers>
-
.
..
-
</variable>
-
If there are no modifiers before the declaration of the entity, the
-
<modifiers> element can be omitted.
-
-
Source position - Given as a child element <source-position>:
-
<variable name="i">
-
<source-position file="/home/rolf/hejhopp.pike" first-line="12"/>
-
<modifiers>
-
<optional/><protected/><private/>
-
</modifiers>
-
...
-
</variable>
-
The source position is the place in the code tree where the entity is
-
declared or defined. For a method, the attribute last-line="..." can be
-
added to <source-position> to give the range of lines that the method
-
body spans in the source code.
-
-
And then there are some things that are specific to each of the types of
-
entities:
-
-
<class>
-
All inherits of the class are given as child elements <inherit>. If there
-
is doc for the inherits, the <inherit> is repeated inside the appropriate
-
<docgroup>:
-
-
class Bosse {
-
inherit "arne.pike" : Arne;
-
inherit Benny;
-
-
//! Documented inherit
-
inherit Sven;
-
}
-
-
<class name="Bosse">
-
<inherit name="Arne"><source-position ... />
-
<classname>"arne.pike"</classname></inherit>
-
<inherit><source-position ... />
-
<classname>Benny</classname></inherit>
-
<inherit><source-position ... />
-
<classname>Sven</classname></inherit>
-
<docgroup homogen-type="inherit">
-
<doc>
-
<text><p>Documented inherit</p></text>
-
</doc>
-
<inherit><source-position ... />
-
<classname>Sven</classname></inherit>
-
</docgroup>
-
...
-
</class>
-
-
<constant>
-
Only has a name. The element is empty (or has a <source-position> child.)
-
-
<enum>
-
Works as a container. Has a <doc> child element with the documentation of
-
the enum itself, and <docgroup> elements with a <constant> for each enum
-
constant. So:
-
-
enum E
-
//! enum E
-
{
-
//! Three constants:
-
a, b, c,
-
-
//! One more:
-
d
-
}
-
-
becomes:
-
-
<enum name="E">
-
<doc><text><p>enum E</p></text></doc>
-
<docgroup homogen-type="constant">
-
<doc><text><p>Three constants:</p></text></doc>
-
<constant name="a"/>
-
<constant name="b"/>
-
<constant name="c"/>
-
</docgroup>
-
<docgroup homogen-name="d" homogen-type="constant">
-
<doc><text><p>One more:</p></text></doc>
-
<constant name="d"/>
-
</docgroup>
-
</enum>
-
-
Both the <enum> element and the <constant> elements could have
-
<source-position> children, of course.
-
-
<inherit>
-
The name="..." attribute gives the name after the colon, if any. The name
-
of the inherited class is given in a <classname> child. If a file name is
-
used, the class name is the file name surrounded by quotes (see <class>).
-
-
<method>
-
The arguments are given inside an <arguments> child. Each argument is
-
given as an <argument name="..."> element. Each <argument> has a <type>
-
child, with the type of the argument. The return type of the method is
-
given inside a <returntype> container:
-
-
int a(int x, int y);
-
-
<method name="a">
-
<arguments>
-
<argument name="x"><type><int/></type></argument>
-
<argument name="y"><type><int/></type></argument>
-
</arguments>
-
<returntype><int/></returntype>
-
</method>
-
-
<modifier>
-
Works as a container ... ???
-
-
<module>
-
Works just like <class>.
-
-
<typedef>
-
The type is given in a <type> child:
-
-
typedef float Boat;
-
-
<typedef name="Boat"><type><float/></type></typedef>
-
-
<variable>
-
The type of the variable is given in a <type> child:
-
-
int x;
-
-
<variable name="x"><type><int/></type></variable>
-
-
======================================================================
-
e) Pike types
-
----------------------------------------------------------------------
-
-
Above we have seen the types int and float represented as <int/> and <float/>.
-
Some of the types are complex, some are simple. The simpler types are just on
-
the form <foo/>:
-
-
<float/>
-
<mixed/>
-
<program/>
-
<string/>
-
<void/>
-
-
The same goes for mapping, array, function, object, multiset, &c that have
-
no narrowing type qualification: <mapping/>, <array/>, <function/> ...
-
-
The complex types are represented as follows:
-
-
array
-
If the type of the elements of the array is specified it is given in a
-
<valuetype> child element:
-
-
array(int)
-
-
<array><valuetype><int/></valuetype></array>
-
-
function
-
The types of the arguments and the return type are given (the order
-
of the <argtype> elements is significant, of course):
-
-
function(int, string: mixed)
-
-
<function>
-
<argtype><int/></argtype>
-
<argtype><string/></argtype>
-
<returntype><mixed/></returntype>
-
</function>
-
-
int
-
An int type can have a min and/or max value. The values can be numbers or
-
identifiers:
-
-
int(0..MAX)
-
-
<int><min>0</min><max>MAX</max></int>
-
-
mapping
-
The types of the indices and values are given:
-
-
mapping(int:int)
-
-
<mapping>
-
<indextype><int/></indextype>
-
<valuetype><int/></valuetype>
-
-
multiset
-
The type of the indices is given:
-
-
multiset(string)
-
-
<multiset>
-
<indextype><string/></indextype>
-
</multiset>
-
-
object
-
If the program/class is specified, it is given as the text child of
-
the <object> element:
-
-
object(Foo.Bar.Ippa)
-
-
<object>Foo.Bar.Ippa</object>
-
-
Then there are two special type constructions. A disjunct type is written
-
with the <or> element:
-
-
string|int
-
-
<or><string/><int/></or>
-
-
An argument to a method can be of the varargs type:
-
-
function(string, mixed ... : void)
-
-
<function>
-
<argtype><string/></argtype>
-
<argtype><varargs><mixed/></varargs></argtype>
-
<returntype><void/></returntype>
-
</function>
-
-
======================================================================
-
f) Other XML tags
-
----------------------------------------------------------------------
-
-
p
-
Paragraph.
-
-
i
-
Italic.
-
-
b
-
Bold.
-
-
tt
-
Terminal Type.
-
-
pre
-
Preformatted text.
-
-
code
-
Program code.
-
-
image
-
An image object. Contains the original file path to the image. Has the
-
optional attributes width, height and file, where file is the path to
-
the normalized-filename file.
-
-
======================================================================
-
g) XML generated from the doc markup
-
----------------------------------------------------------------------
-
-
The documentation for an entity is put in a <doc> element. The <doc> element
-
is either a child of the element representing the entity (in the case of
-
<class>, <module>, <enum>, or <modifiers>) or a child of the <docgroup> that
-
contains the element representing the entity.
-
-
The doc markup has two main types of keywords. Those that create a container
-
and those that create a new subsection within a container, implicitly closing
-
the previous subsection. Consider e.g.:
-
-
//! @mapping
-
//! @member int "ip"
-
//! The IP# of the host.
-
//! @member string "address"
-
//! The name of the host.
-
//! @member float "latitude"
-
//! @member float "longitude"
-
//! The coordinates of its physical location.
-
//! @endmapping
-
-
Here @mapping and @endmapping create a container, and each @member start a
-
new subsection. The two latter @member are grouped together and thus they
-
form ONE new subsection together. Each subsection is a <group>, and the
-
<group> has one or more <member> children, and a <text> child that contains
-
the text that describes the <member>s:
-
-
<mapping>
-
<group>
-
<member><type><int/></type><index>"ip"</index></member>
-
<text>
-
<p>The IP# of the host.</p>
-
</text>
-
</group>
-
<group>
-
<member><type><string/></type><index>"address"</index></member>
-
<text>
-
<p>The name of the host.</p>
-
</text>
-
</group>
-
<group>
-
<member><type><float/></type><index>"latitude"</index></member>
-
<member><type><float/></type><index>"longitude"</index></member>
-
<text>
-
<p>The coordinates of its physical location.</p>
-
</text>
-
</group>
-
</mapping>
-
-
Inside a <text> element, there can not only be text, but also a nested level
-
of, say @mapping - @endmapping. In that case, the <mapping> element is put in
-
the document order place as a sibling of the <p> that contain the text:
-
-
//! @mapping
-
//! @member mapping "nested-mapping"
-
//! A mapping inside the mapping:
-
//! @mapping
-
//! @member string "zip-code"
-
//! The zip code.
-
//! @endmapping
-
//! And some more text ...
-
//! @endmapping
-
-
becomes:
-
-
<mapping>
-
<group>
-
<member><type><mapping/></type><index>"nested-mapping"</index></member>
-
<text>
-
<p>A mapping inside the mapping:</p>
-
<mapping>
-
<group>
-
<member><type><string/></type><index>"zip-code"</index></member>
-
<text>
-
<p>The zip code.</p>
-
</text>
-
</group>
-
</mapping>
-
<p>And some more text ...</p>
-
</text>
-
</group>
-
</mapping>
-
-
Inside the <p> elements, there may also be some more "layout-ish" tags like
-
<b>, <code>, <tt>, <i>, needed to make the text more readable. Those tags are
-
expressed as @i{ ... @} in the doc markup. However there are no <br>. A
-
paragraph break is done by ending the <p> and beginning a new. A </p><p> is
-
inserted for each sequence of blank lines in the doc markup:
-
-
//! First paragraph.
-
//!
-
//! Second paragraph.
-
//!
-
//!
-
-
becomes:
-
-
<p>First paragraph.</p><p>Second paragraph.</p>
-
-
Note that the text is trimmed from leading and ending whitespaces, and there
-
are never any empty <p> elements.
-
-
In the example above the keyword `@mapping
'
translated into <mapping>, whereas
-
the keyword `@member string "zip-code"' translated into:
-
<member><type><string/></type><index>"zip-code"</index></member>
-
-
The translation of keyword->XML is done differently for each keyword
.
How it
-
is done can be seen in lib/modules/Tools.pmod/AutoDoc.pmod/DocParser.pmod. Most
-
keywords just interpret the arguments as a space-separated list, and put their
-
values in attributes to the element. In some cases (such as @member) though,
-
some more intricate parsing must be done, and the arguments may be complex
-
(like
Pike
types) and are represented as child elements of the element.
-
-
======================================================================
-
h) Top level sections of different Pike entities.
-
----------------------------------------------------------------------
-
-
In every doc comment there is an implicit "top container", and subsections can
-
be opened in it. E.g.:
-
-
/
/! A method.
-
//! @param x
-
//! The horizontal coordinate.
-
//! @param y
-
//! The vertical coordinate.
-
//! @returns
-
//! Nothing :)
-
void foo(int x, int y)
-
-
becomes:
-
-
<docgroup homogen-name="foo" homogen-type="method">
-
<doc>
-
<text><p>A method.</p></text>
-
<group>
-
<param name="x"/>
-
<text><p>The horizontal coordinate.</p></text>
-
</group>
-
<group>
-
<param name="y"/>
-
<text><p>The vertical coordinate.</p></text>
-
</group>
-
<group>
-
<returns/>
-
<text><p>Nothing :)</p></text>
-
</group>
-
</doc>
-
<method name="foo">
-
......
-
</method>
-
</docgroup>
-
-
Which "top container" subsections are allowed depends on what type of entity is
-
documented:
-
-
ALL - <bugs/>
-
<deprecated> ... </deprecated>
-
<example/>
-
<note/>
-
<seealso/>
-
-
<method> - <param name="..."/>
-
<returns/>
-
<throws/>
-
</
pre
></
p
></dd></dl></body></html>
+
<body><dl><dt><h1 class='header'>21. Pike
BNF
</h1></dt><dd><
dl
>
+
<dt><a
href
='
index.html
'>
Table
of
Contents
</
a
></dt>
+
<dt><
a
href
='
chapter_1.html
'>1.
Introduction
</
a
></dt>
+
<dd><a
href='chapter_1
.
html#1'
>
1
.
1
.
Overview
</
a
></
dd
>
+
<
dd
><
a
href=
'
chapter_1
.
html#2
'>
1
.
2
.
The
history
of
Pike
</
a
></
dd
>
+
<dd><
a
href
='
chapter_1.html#3
'>1.
3
.
A
comparison
with
other
languages
</
a
></
dd
>
+
<
dd
><
a
href=
'
chapter_1.html#4'
>
1
.
4
.
What
is
Pike
</
a
></
dd
>
+
<
dd
><
a
href='chapter_1
.
html#5'
>
1
.
5
.
Pike
License
</
a
></
dd
>
+
<
dt
><
a
href='chapter_2
.
html'
>
2
.
Control
Structures
</
a
></
dt
>
+
<
dd
><
a
href='chapter_2
.
html#1'
>
2
.1.
Conditions
</
a
></
dd
>
+
<
dd
><a
href='chapter_2
.
html#2'
>
2
.
2
.
Loops
</
a
></
dd
>
+
<
dd
><
a
href='chapter_2.html#3'
>2
.
3
.
Breaking
out
of
loops
</
a
></dd>
+
<dt><
a
href
='
chapter_3.html
'>3.
Operators
</
a
></dt>
+
<dd><a
href='chapter_3
.
html#1'>3
.
1.
Arithmetic
operators
</
a
></
dd
>
+
<
dd
><
a
href=
'
chapter_3
.
html#2'
>
3
.
2.
Comparison
operators
</
a
></
dd
>
+
<dd><
a
href
='
chapter_3.html#3
'>
3
.
3
.
Logical
operators
</
a
></
dd
>
+
<dd><a
href='chapter_3
.
html#4'
>
3
.
4.
Bitwise/set
operators
</
a
></
dd
>
+
<
dd
><a
href='chapter_3
.
html#5
'
>3
.
5.
Indexing
</
a
></
dd
>
+
<
dd
><a
href=
'
chapter_3.html#6'
>
3.6.
The
assignment
operators
</a></
dd
>
+
<
dd
><
a
href='chapter_3.html#7'
>
3
.
7.
The
rest
of
the
operators
</
a
></
dd
>
+
<dd><
a
href
='
chapter_3.html#8
'>
3
.
8
.
Operator precedence
</
a
></dd>
+
<
dd
><a
href=
'
chapter
_
3.html#9
'
>3.9.
Operator
functions
</
a
></dd>
+
<dt><a
href
='
chapter_4.html
'>
4
.
Preprocessor
</
a
></dt>
+
<dd><a
href='chapter_4
.
html#1'
>
4
.
1
.
Charset
Heuristics
</
a
><
/dd
>
+
<dd><
a
href
='
chapter_4.html#2
'>
4
.2.
Code
Normalization
</
a
></dd>
+
<
dd
><
a
href='chapter_4
.
html#3'
>
4
.
3
.
Defines
and
Macros
</
a
><
/dd
>
+
<
dd
><a
href='chapter_4
.
html#4'>4
.
4
.
Preprocessor
Directives<
/a></
dd
>
+
<
dd
><
a
href='chapter_4
.
html#5'
>
4
.
5.
Predefined
defines
</
a
></dd>
+
<
dd
><
a
href
='
chapter_4.html#6
'>
4
.
6
.
Test
functions
</
a
></dd>
+
<
dt
><a
href='chapter_5
.
html'
>
5
.
Special
Functions
</
a
></
dt
>
+
<
dd
><
a
href='chapter_5
.
html#1'
>
5
.
1
.
sscanf
</a></
dd
>
+
<
dd
><a
href=
'
chapter_5.html#2'
>
5
.
2
.
catch
</
a
></
dd
>
+
<
dd
>
<a
href='chapter_5
.
html#3'
>
5
.
3
.
gauge<
/a></
dd
>
+
<
dd
>
<
a
href='chapter_5
.
html#4'>5
.
4.
typeof
</a></
dd
>
+
<
dt
><
a href=
'
chapter_6
.
html'
>
6. Hilfe
</a></
dt
>
+
<
dd
><a
href='chapter_6
.
html#1'>6
.
1
.
Basic
operations
</
a
></
dd
>
+
<
dd
><a
href=
'
chapter_6.html#2'
>
6
.
2
.
Commands
</
a
></
dd
>
+
<
dd
>
<a
href=
'
chapter_6
.
html
#
3'
>
6
.
3
.
Bugs
and
possible
improvements
</
a
><
/dd
>
+
<
dt
><
a
href='chapter_7
.
html'>7
.
LFUN
</
a
></
dt
>
+
<
dt
>
<
a
href='chapter_8.html'
>
8.
I
/
O
</
a
></
dt
>
+
<
dt
><
a
href='chapter_9
.
html'
>
9
.
Specific
Datatype
Modules
<
/a
></
dt
>
+
<
dt
><
a
href='chapter_10
.
html'>10
.
Parsers
</
a
></
dt
>
+
<dt><a
href
='
chapter_11.html
'>
11
.
Image
Module
</
a
></dt>
+
<
dt
><
a
href='chapter_12
.
html'>12.
Protocols
</
a
></
dt
>
+
<
dt
><
a
href='chapter_13.html'
>
13.
Database
Access
</a></
dt
>
+
<
dt
><
a
href='chapter_14
.
html'
>
14.
Graphic
User
Interface
</
a
><
/dt
>
+
<
dt
><a
href='chapter_15.html'
>
15
.
3D
Vector
Graphics
</
a
></
dt
>
+
<
dt
><
a
href='chapter_16.html'
>
16.
The
rest
</
a
></
dt
>
+
<
dt
><
a
href='chapter_17.html'
>
17
.
Backward Compatibility
</
a
></
dt
>
+
<dd><
a
href
='
chapter_17.html#1
'>
17
.1.
Pike
8.0
</
a
></
dd
>
+
<dd><
a
href='chapter_17
.
html#2'>17
.
2.
Pike
7
.
8
</
a
></
dd
>
+
<
dd
><
a
href='chapter_17.html#3'
>
17.3.
Pike
7
.
6
and
earlier
</
a
></
dd
>
+
<
dt
><a
href='chapter_18.html'
>
18.
Writing
Pike
Modules
</
a
></
dt
>
+
<
dd
><
a
href='chapter_18.html#1'
>
18
.
1.
Writing
Modules
in Pike</a></
dd
>
+
<
dd
><
a
href='chapter_18
.
html#2'
>
18
.
2
.
Writing
Modules
in
C
</
a
></
dd
>
+
<
dd
>
<a
href='chapter_18
.
html#3'
>
18
.
3
.
Special
Module
Variables
and
functions
<
/a
></
dd
>
+
<
dt
><
a
href='chapter_19
.
html'
>
19.
Pike
Test
Suite
</
a
></
dt
>
+
<
dd
><
a
href='chapter_19
.
html#1'
>
19
.
1
.
Running
Tests
</
a
></
dd
>
+
<
dd
><
a
href='chapter_19
.
html#2'
>
19
.
2
.
Writing
New
Tests
</
a
></
dd
>
+
<
dt
><
a
href='chapter_20.html'
>
20.
Pike
AutoDoc
markup
</
a
></
dt
>
+
<
dd
><
a
href='chapter_20.html#1'
>
20
.
1
.
Syntax
</
a
></
dd
>
+
<
dd
><
a
href='chapter_20
.
html#2'
>
20.2.
Pike
autodoc
inlining
</
a
></
dd
>
+
<
dd
><a
href
=
'chapter_20
.
html#
3
'>20
.3. Pike
autodoc
tags<
/a
><
/
dd>
+
<dt><
a
href
=
'chapter_21
.
html'>21
. Pike
BNF<
/a
>
</
dt
>
+
</
dl
></dd></dl></body></html>