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

f:module

:f:mod:

Sets the current module. No content.

f:currentmodule

–

Resets the current module.

f:program

:f:prog:

Main program.

f:subroutine

:f:func:, :f:subr:

Takes an argument list.

f:function

:f:func:

Takes an argument list.

f:interface

:f:func:, :f:subr:

Takes an argument list.

f:type

:f:type:

Derived type, components in :f fields.

f:variable

:f:var:

Module variable, type component.

preferred-crossrefs

–

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, function or interface may 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

p, param, parameter, a, arg, argument

type, ptype, paramtype

shape, pshape

attrs, attr, pattrs

Options

o, optional, opt, option, keyword

otype, optparamtype

oshape

oattrs, oattr

Type fields

f, field, typef, typefield

ftype, fieldtype

fshape

fattrs, fattr

Result

r, return, returns

rtype, returntype

rshape

rattrs, rattr

Called from

calledfrom, from

–

–

–

Call to

callto, 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

:p start:

name only

:p real start:

type real

:p real array(num):

type real, shape (num). The names in a shape are links to the variables of the same name.

:p integer p [in,required]:

attributes in and required

:p character(len=*) name:

type with a parenthesis, no space

:p integer,real x:

several types, for an interface

:r real(kind=dp) y(n) [out]:

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

:f:mod:`linalg`

module

linalg

:f:func:`solve`

function, subroutine or interface

solve()

:f:func_inline:`solve`

same as func

solve (no parentheses)

:f:subr:`solve`

subroutine or interface

solve()

:f:subr_inline:`solve`

same as subr

solve (no parentheses)

:f:type:`matrix`

derived type

matrix

:f:var:`beta`

variable, or type component

beta

:f:prog:`main`

program

main

These roles create hyperlinks to the corresponding documented entities.

How a target is looked up

The lookup is case-insensitive. The target can be:

name

The exact name, then name in no module, then in the current module, and finally any object of a compatible type whose name ends with the target.

module/name

The name in that module, for instance :f:func:`sf_arrays/linspace`.

~module/name

As above, but the title shows only name.

/name

A 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 :p field per argument, and :o for the optional ones

  • Give 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 expressions

  • Do 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.