Fortran Domain
The Fortran domain provided by sphinxfortran_ng defines a set of
directives and roles for documenting Fortran entities explicitly.
Unlike the autodoc directives, which extract documentation directly from source files, the Fortran domain directives are written manually and give full control over structure, formatting, and content.
The domain name for all directives and roles is f. Activate it with:
extensions += ["sphinxfortran_ng.fortran_domain"]
Overview
The Fortran domain supports documentation of:
programs
modules
subroutines
functions
generic interfaces
variables
derived types
Each entity can be documented using a dedicated directive, and entities
can be cross-referenced using domain-specific roles. The f:auto* directives
of Fortran Autodoc do nothing else than generating this text.
Directive |
Role(s) |
Notes |
|---|---|---|
|
|
Sets the current module. No content. |
|
– |
Resets the current module. |
|
|
Main program. |
|
|
Takes an argument list. |
|
|
Takes an argument list. |
|
|
Takes an argument list. |
|
|
Derived type, components in |
|
|
Module variable, type component. |
|
– |
Not in the domain: disambiguates references (see Ambiguous references). |
Module and Program Directives
.. f:module::
Declare a Fortran module. It records the module in the module index, creates
the target of the module and makes it the current module for the objects
that follow, until the next f:module or f:currentmodule.
The directive takes no content: the description of the module is written as normal paragraphs after it, not indented under it.
Syntax
.. f:module:: module_name
:synopsis: Short description shown in the module index
:platform: any
:deprecated:
:noindex:
Description of the module, written as ordinary paragraphs.
Options
:synopsis:One line shown in the Fortran module index, and as the tooltip of the references to the module.
:platform:Platforms on which the module is available, printed as a line Platforms: … under the declaration.
:deprecated:Flag the module as deprecated in the index and in the references.
:noindex:Do not add the module to the index.
.. f:currentmodule::
Document objects without linking them to a module. It resets the current
module to nothing, whatever its optional argument. The objects that follow are
then registered as _/name and are found by their short name. The
f:auto* directives use it for the objects they insert.
.. f:program::
Declare and describe a Fortran program unit. It accepts the same content and fields as a routine.
Syntax
.. f:program:: program_name
Description of the program.
:calledfrom: nothing
Routine Directives
.. f:subroutine::
Document a Fortran subroutine. The word subroutine is added in front of
the name in the signature automatically, and the module is shown in front of it
when the Sphinx option add_module_names is true.
Syntax
.. f:subroutine:: subroutine_name(arg1, arg2[, opt1, opt2])
Description of the subroutine.
Optional arguments are enclosed in square brackets, exactly as in a
Python signature: the brackets open before the first optional argument and
close after the last one (a[, b[, c]] nests them). The signature is
otherwise free text, with these exceptions:
it can be prefixed by the module and a slash:
.. f:subroutine:: sf_arrays/linspace(a, b);the words
subroutine,functionorinterfacemay also be written first;the arguments must be a flat list in one pair of parentheses.
Warning
A trailing result(...) clause, or a type in front (real function),
makes the signature unparsable: it is then displayed as a plain string and
the object gets no index entry and no cross-reference target. Give the
result in a :r field instead.
.. f:function::
Document a Fortran function. Same syntax as f:subroutine; describe the
value with a :r field.
.. f:function:: linspace(start, stop, num[, istart, iend, mesh])
Returns an array of evenly spaced numbers over a specified interval.
:p real start: Starting value of the sequence
:p real stop: End value of the sequence
:p integer num: Number of samples to generate
:o logical istart: If :code:`.true.`, :f:var:`start` is included
:o logical iend: If :code:`.true.`, :f:var:`stop` is included
:o real mesh: If present, the step is saved in this variable
:r real array(num): The :f:var:`num` samples
.. f:interface::
Document a generic interface. Same syntax and fields as a function. Where the
specific procedures have different types, list them separated by commas:
:p integer,real x: ....
Options common to all objects
The directives of routines, types, programs and variables accept:
:noindex:Do not register the object nor add an index entry.
:module:Name of the module the object belongs to, when it differs from the current module.
:type:,:shape:,:attrs:Type, shape and attributes displayed in the signature of a variable (see below).
Argument and Variable Descriptions
Subroutines, functions, interfaces, programs and derived types accept field lists to describe arguments, components and results.
Each family of fields collects a description together with the type, the shape and the attributes of a name. They can be given in the field name itself:
:p real(kind=dp) A(n,m) [in]: Coefficient matrix
or in separate fields (see the table below):
:p A: Coefficient matrix
:type A: real(kind=dp)
:shape A: (n,m)
:attrs A: in
Available fields
Title shown |
Field names |
Type |
Shape |
Attributes |
|---|---|---|---|---|
Parameters |
|
|
|
|
Options |
|
|
|
|
Type fields |
|
|
|
|
Result |
|
|
|
|
Called from |
|
– |
– |
– |
Call to |
|
– |
– |
– |
In the generated documentation, :p is used for required arguments, :o
for optional ones, :r for the result and :f for the components of a
type. Any other field, such as :use: or :Default: in the output of the
autodoc directives, is displayed as it is, with the first letter capitalised.
Note
Parameters and Options are the arguments of a routine or a
program. They have nothing to do with the Fortran parameter attribute.
Syntax of the field name
The name of the :p, :o, :f and :r fields is analysed as:
[type] name[(shape)] [[attr1,attr2]]
Field |
Reading |
|---|---|
|
name only |
|
type |
|
type |
|
attributes |
|
type with a parenthesis, no space |
|
several types, for an interface |
|
result, with kind, shape and attribute |
Keep the type, the shape and the attributes free of spaces and commas, except
the comma between the attributes of the brackets: forms such as
:p real, dimension(:,:) A: or :p real x [intent(in), optional]: are
not analysed correctly. Put such a type in a separate field instead:
:type A: real, dimension(:,:).
The name of the type is a link to the f:type of that name if there is one;
the intrinsic types are left as text.
The result field always needs a name. Write :r real y: Description:
a bare :returns: Description is not accepted and stops the build with an
IndexError.
Call relationships
:calledfrom: and :callto: take a list of names, written as
references to routines, in the body of the field; each is displayed on a
single line.
:calledfrom: :f:func:`upminterval`
:callto: :f:func:`linspace`
Documenting a routine, fully
.. f:function:: upmspace(start, stop, p, u, ndim[, base, istart, iend, mesh])
Returns an array of numbers spaced linearly between exponentially spaced
checkpoints. The interval is first divided into :f:var:`p` coarse
regions, each of which is then divided linearly into :f:var:`u`
subintervals.
:p real start: First element of the array
:p real stop: Last element of the array
:p integer p: Number of coarse subdivisions
:p integer u: Number of fine subdivisions
:p integer ndim: Length of the output array, :math:`p \cdot u` or :math:`p \cdot u + 1`
:o real base: Base of the exponential spacing (default :code:`2`)
:o logical istart: If :code:`.true.`, :f:var:`start` is included
:o logical iend: If :code:`.true.`, :f:var:`stop` is included
:o real mesh(ndim): Distances between consecutive points
:r real aout(ndim): The generated points
:calledfrom: :f:func:`upminterval`
:callto: :f:func:`linspace`
Derived Types
.. f:type::
Document a Fortran derived type. While its content is parsed, the type is the current type, which is used to resolve the references of its components.
Syntax
.. f:type:: matrix
Derived type representing a dense matrix.
:f integer nrow: Number of rows
:f integer ncol: Number of columns
:f real(kind=dp) data(nrow,ncol): Matrix storage array
The components are described with the fields :f (aliases field,
typef, typefield), with the same name syntax as an argument. Since
nrow and ncol appear in a shape, they become links to the components
of that name.
Variables
.. f:variable::
Document a module variable or a type component.
Syntax
.. f:variable:: beta
:type: real
:attrs: default=1000d0
Inverse temperature, at zero temperature it is used as a IR cut-off.
.. f:variable:: uloc(5)
:type: real
:attrs: bind
Values of the local interaction per orbital.
Options
:type:Type of the variable, linked to the type of that name when there is one.
:shape:Shape, for instance
(n, m). The parentheses are added if missing. The shape can also be written in the signature:uloc(5). Identifiers in it are links to variables.:attrs:Comma separated attributes, displayed after the type. An attribute starting with
default=shows its value, with the identifiers linked to the variables.
The signature is displayed as name (shape) [type,attrs].
The autodoc directives add the description fields :Type:,
:Attributes:, :Bindings: and :Default: to the content of the
variables. They are ordinary fields and do not belong to the domain.
Cross-Referencing
Fortran entities can be referenced using domain roles:
Role |
Refers to |
Displayed as |
|---|---|---|
|
module |
|
|
function, subroutine or interface |
|
|
same as |
|
|
subroutine or interface |
|
|
same as |
|
|
derived type |
|
|
variable, or type component |
|
|
program |
|
These roles create hyperlinks to the corresponding documented entities.
How a target is looked up
The lookup is case-insensitive. The target can be:
nameThe exact name, then
namein no module, then in the current module, and finally any object of a compatible type whose name ends with the target.module/nameThe name in that module, for instance
:f:func:`sf_arrays/linspace`.~module/nameAs above, but the title shows only
name./nameA relative search: the current module comes first, and the type of the object must fit the role.
Explicit titles work as in the other domains:
:f:func:`the linspace function <sf_arrays/linspace>`. References to a
module also show its synopsis as a tooltip.
When a name is not defined in the project but exists in an Intersphinx inventory that holds Fortran objects, the link goes to that inventory.
Ambiguous references
If several objects share a name (for instance a variable beta defined by
two modules), Sphinx uses the first one it finds and prints a message. The
preferred-crossrefs directive chooses the target for the references of
one document. Each line of its content is name: complete/target, where
the target is the full name of the object, module/name:
.. preferred-crossrefs::
beta: ed_input_vars/beta
linspace: sf_arrays/linspace
Note
The directive is registered without a domain prefix, and it is not validated: a wrong target raises an error at the first reference to it.
Indices
The domain contributes the Fortran Module Index, which lists the modules
declared by f:module (or f:automodule) with their synopsis, platforms
and deprecation status. It is available through
:ref:`f-modindex`
The modules, and the other objects, are also added to the general index and
to the search index. The text of the index entries is
name() (fortran function), followed by in module <name> when
add_module_names is true.
Formatting Guidelines
To produce consistent and readable documentation:
Use one
:pfield per argument, and:ofor the optional onesGive the type of each argument in the field, so that it links to the type definition
Keep field descriptions concise; use paragraphs above them for details
Give the default value of an optional argument in its description
Use inline literals (
:code:) for Fortran symbols and expressionsDo not write
result(...)in a signature
When to Use the Fortran Domain
Manual Fortran domain directives are recommended when:
Autodoc output needs customization
Code cannot be parsed automatically
Documentation must be written independently of source layout
Autodoc and manual directives may be freely mixed in the same project: for
instance f:automodule with :hide-output: 1 declares the module, and the
routines are then written by hand or inserted one by one with
f:autoroutine in the order of your choice.