Copyright © 2003 Richard Carlsson
Version: 0.4 alpha
Authors: Richard Carlsson (richardc@csd.uu.se).
EDoc is the Erlang program documentation generator. Inspired by the JavadocTM tool for the JavaTM programming language, EDoc is adapted to the conventions of the Erlang world, and has several features not found in Javadoc. Since the first and previously only public release (v. 0.1), a lot of new functionality has been added, and most of the code has been completely rewritten. However, the old main interface (the functionedoc:file/2
) has been preserved for backwards compatibility, and
there should be few or no incompatibilities with existing EDoc-comments
in Erlang code.
EDoc lets you write the documentation of an Erlang program as
comments in the source code itself, using tags on the form
"@Name ...
". A source file does not have to contain tags
for EDoc to generate its documentation, but without tags the result will
only contain the basic available information that can be extracted from
the module.
A tag must be the first thing on a comment line, except for leading
'%
' characters and whitespace. The comment must be between
program declarations, and not on the same line as any program text. All
the following text - including consecutive comment lines - up until the
end of the comment or the next tagged line, is taken as the
content of the tag.
Tags are associated with the nearest following program construct "of significance" (the module name declaration and function definitions). Other constructs are ignored; e.g., in:
%% @doc Prints the value X. -record(foo, {x, y, z}). print(X) -> ...the
@doc
tag is associated with the function
print/1
.
Note that in a comment such as:
% % @doc ...the tag is ignored, because only the first '
%
' character is
considered "leading". This allows tags to be "commented out".
Some tags, such as @type
, do not need to be associated
with any program construct. These may be placed at the end of the file,
in the "footer".
For the time being, just see the module edoc
.
The following tags can be used anywhere within a module:
@clear
@clear
tag itself. The text following the tag
is also ignored. This is typically only useful in code
containing conditional compilation, when preprocessing is turned
on. (Preprocessing is turned off by default.) E.g., in
-ifdef(DEBUG). %% @doc ... foo(...) -> ... -endif. %% @clear %% @doc ... bar(...) -> ...the
@clear
tag makes sure that EDoc does not see
two @doc
tags before the function bar
,
even if the code for function foo
is removed by
preprocessing. (There is no way for EDoc to see what the first
@doc
tag "really" belongs to, since preprocessing
strips away all such information.)@end
%% ---------------------------------- %% ... %% @doc ... %% ... %% @end %% ----------------------------------to avoid including the last "ruler" line in the
@doc
tag.
Note: using some other "dummy" @
-tag for
the same purpose might work in a particular implementation of
EDoc, but is not guaranteed to. Always use @end
to ensure future compatibility.
@type
.
") separator and XHTML
text describing the type (i.e., its purpose, use, etc.). There
must be at least one whitespace character between the
".
" and the text. See Type
specification syntax below for syntax and examples.
All data type descriptions are placed in a separate section of
the documentation, regardless of where the tags occur.The following tags can be used before a module declaration:
@author
<...>
delimiters, and a URI within
[...]
delimiters. Both e-mail and URI are
optional, and any surrounding whitespace is stripped from all
strings.
The name is the first nonempty string that is not within
<...>
or [...]
, and does not
contain only whitespace. (In other words, the name can come
before, between, or after the e-mail and URI, but cannot be
split up; any sections after the first are ignored.) If an
e-mail address is given, but no name, the e-mail string will be
used also for the name. If no <...>
section
is present, but the name string contains an "@
"
character, it is assumed to be an e-mail address. Not both name
and e-mail may be left out.
Examples:
%% @author Richard Carlsson
%% @author Richard Carlsson <richardc@csd.uu.se> %% [http://www.csd.uu.se/~richardc/]
%% @author <richardc@csd.uu.se>
%% @author richardc@csd.uu.se [http://www.csd.uu.se/~richardc/]
@copyright
%% @copyright 2001-2003 Richard Carlsson
@deprecated
{@link}
reference to a
replacement; as in:
%% @deprecated Please use the module {@link foo} instead.
@doc
@doc
function tag below
for details). For example.:
%% @doc This is a <em>very</em> useful module. It is ...
@hidden
@private
@reference
%% @reference Pratchett, T., <em>Interesting Times</em>, %% Victor Gollancz Ltd, 1994.
%% @reference See <a href="www.google.com">Google</a> for %% more information.
@see
@see
function tag
below for details.@since
@version
The following tags can be used before a function definition:
@deprecated
@deprecated
module tag for details.@doc
.
") or exclamation mark
("!
") that is followed by a whitespace character, a
line break, or the end of the tag text, and is not within XML
markup.@equiv
@doc
. @hidden
@private
spawn
. (Non-exported functions are
always "private".) The content can be used as a comment; it is
ignored by EDoc.@see
.
"), one or more whitespace characters, and
XHTML text to be used for the label; for example "@see
edoc
" or "@see edoc. <b>EDoc</b>
".
If no label text is specified, the reference itself is used as the
label.@since
@version
module tag. The content can be arbitrary text.@spec
@type
@type
module tag
for details. Placing a @type
tag by a function
definition may be convenient, but does not affect where the
description is placed in the generated documentation.In several contexts (@see
tags, @link
macros, etc.), EDoc lets
you refer to the generated documentation for modules, functions,
datatypes, and applications, using a simple and compact syntax. The
possible formats for references are:
Reference syntax | Example |
---|---|
Module | edoc_run |
Function/Arity | file/2 (*) |
Module:Function/Arity | edoc:application/2 |
Type() | filename() (*) |
Module:Type() | edoc:edoc_module() |
//Application | //edoc |
//Application/Module | //edoc/edoc_doclet |
//Application/Module:Function/Arity | //edoc/edoc_run:file/1 |
//Application/Module:Type() | //edoc/edoc:edoc_module() |
EDoc will resolve references using the information it finds in
edoc-info
-files at the locations specified with the doc_path
option. EDoc will automatically (and somewhat intelligently) try to find
any local edoc-info
-files using the current code path, and add them to
the end of the doc_path
list. The target doc-directory is also
searched for an existing info file; this allows documentation to be
built incrementally. (Use the new
option to ignore any old info
file.)
Note that if the name of a module, function or datatype is explicitly
qualified with an application (as in "//edoc/edoc_run
"), this
overrides any other information about that name, and the reference will
be made relative to the location of the application (if it can be
found). This makes it possible to refer to e.g. a module "fred
" as
"//foo/fred
" without accidentally getting a reference to
"//bar/fred
". You should not use this form of explicit references for
names that are local to the application you are currently creating -
they will always be resolved correctly.
(*) Local references such as these only work properly within a module. In an overview-page like this (i.e., the one you are currently reading), no module context is available.
In several places, XHTML markup can be used in the documentation
text, in particular in @doc
tags. The main differences from
HTML are the following:
<a
name="top">
.<br>
, which has no
actual content, you can write either the full
<br></br>
, or better, use the XHTML abbreviated
form <br/>
.
The HTML heading tags h1
and h2
are
reserved for use by EDoc. Headings in documentation source code should
start at h3
.
EDoc uses XMerL to parse and export XML markup.
@spec
tag:
Spec |
::= | FunType Def*
|
FunctionName |
::= | Atom |
FunType |
::= | "(" UnionTypes? ")" "->" UnionType |
UnionTypes |
::= | UnionType
|
UnionType |
::= | UnionList
|
Name |
::= | Variable |
UnionList |
::= | Type
|
Type |
::= | TypeVariable
|
TypeVariable |
::= | Variable |
TypeName |
::= | Atom |
ModuleName |
::= | Atom
|
AppName |
::= | Atom |
Def |
::= | TypeVariable "=" UnionType
|
TypeVariables |
::= | TypeVariable
|
Examples:
%% @spec my_function(X::integer()) -> integer()
%% @spec (X::integer()) -> integer()
%% @spec sqrt(float()) -> float()
%% @spec pair(S, T) -> {S, T}
%% @spec append(List, List) -> List %% List = [term()]
%% @spec append(A::List, B::List) -> List %% List = [term()]
%% @spec open(File::filename()) -> file_descriptor() %% filename() = string() + atom()
%% @spec close(graphics:window()) -> okIn the above examples,
X
, A
, B
and File
are parameter names, used for referring to the
parameters from the documentation text. The type variables
S
, T
and List
are used to
simplify the type specifications, and may be supplied with
definitions. It is also possible to give definitions for named types,
which means that the name is simply an alias. (Use the
@type
tag to document abstract data types.) If a named type
is defined in another module, it can be referred to as
Module:TypeName(...)
.
Both the "|
" and the "+
" character may be
used to separate alternatives in union types; there is no semantic
difference. Note that the notation [Type]
means "proper
(nil-terminated) list whose elements all belong to Type
";
For example, [atom()|integer()]
means the same thing as
[atom()+integer()]
, i.e., a proper list of atoms and/or
integers.
If only a type variable is given for a parameter, as in
"pair(S, T) -> ...
", the same variable name may implicitly
be used as the parameter name; there is no need to write
"pair(S::S, T::T) -> ...
".
EDoc automatically extracts possible parameter names from the source
code, to be used if no parameter name is given in the specification (or
if the specification is missing altogether). If this fails, EDoc will
generate a dummy parameter name, such as X1
. This way, EDoc
can often produce helpful documentation even for code that does not
contain any annotations at all.
@type
tag:
Typedef |
::= | TypeName "(" TypeVariables? ")" Def*
|
%% @type myList(X). A special kind of lists ...
%% @type filename() = string(). Atoms not allowed!
%% @type thing(A) = {thong, A} %% A = term(). %% A kind of wrapper type thingy.
The following data types are predefined by EDoc, and may not be redefined:
any() atom() binary() bool() char() cons() deep_string() float() function() integer() list() nil() none() number() pid() port() reference() string() term() tuple()Details:
any()
means "any Erlang data type".
term()
is simply an alias for any()
.atom()
, binary()
,
float()
, function()
,
integer()
, pid()
, port()
and reference()
are primitive data types of
the Erlang programming language.bool()
is the subset of atom()
consisting
of the atoms true
and false
.char()
is a subset of
integer()
representing character codes.tuple()
is the set of all tuples {...}
.list(T)
is just an alias for [T]
.nil()
is an alias for the empty list []
.cons(H,T)
is the list constructor. This is usually not
used directly. It is possible to recursively define list(T)
:= nil()+cons(T,list(T))
.string()
is an alias for [char()]
.deep_string()
is recursively defined as
[char()+deep_string()]
.none()
means "no data type". E.g., a function
that never returns has type (...) -> none()
{@name}or
{@name argument}where name and argument are separated by one or more whitespace characters. The argument can be any text, which may contain other macro calls. The number of non-escaped "
{@
" and
"}
" delimiters must be balanced.
The argument text is first expanded in the current environment, and
the result is bound to the macro parameter, written
{@?}
. (If no argument is given, {@?}
is
bound to the empty string.) The macro definition is then substituted
for the call, and expansion continues over the resulting text. Recursive
macro expansions are not allowed.
def
EDoc
option; see edoc:file/2
and edoc:get_doc/2
for more
information.
{@date}
{@docRoot}
"../../.."
) from the current page to the root
directory of the generated documentation. This can be used to
create XHTML references such as <img
src="{@docRoot}/images/logo.jpeg">
that are independent
of how deep down in a package structure they occur. If packages
are not used (i.e., if all modules are in the "empty" package),
{@docRoot}
will always resolve to the empty
string.{@link reference.
description}
@see
function tag above for
details. The description text (including the period separator)
is optional; if no text is given, the reference itself is
used. For example, {@link edoc:file/2}
creates the
link edoc:file/2
, and {@link
edoc:file/2. <em>this</em>}
creates this link.{@module}
{@package}
{@type
type-expression}
{@type {options, List::edoc:option_list()@}}
generates "{options, List::edoc:option_list()}
". (Cf.
Escape sequences below.){@time}
{@
" in the output, use a
"}
" character in the argument text of a macro call,
the following escape sequences may be used: @{
{
". Example:
%% @doc An inline macro starts with the sequence "@{@".
@}
}
". Example:
%% @doc ...{@foo ...{Key, Value@}...}...
@@
@
". Example:
%% @doc Contact us at support@@{@hostname}Will generate the text "Contact us at support@vaporware.acme.com" if the macro
hostname
is bound to
"vaporware.acme.com
". Also:
%% @doc You might want to write something like %% @@foo that will expand to @foo but does not start %% a new tag even if it appears first in a line.