Skip to content

Utilities/Sphinx: Add a directive to document command signatures

Add a signature directive to offer a CMake version of Sphinx's function directive, similar to that found in other domains (py, cpp, etc.). Like others, this takes one or more signatures as arguments and creates dt/dd nodes from the signatures and the directive contents.

Besides more closely following the conventions used to document other languages (e.g. Python, C++), the cmake:signature directive (the cmake domain is the default in our use and may be elided) combines generation of dt/dd nodes (which are more semantically correct and indent in a way that is easier to read, especially in long sets of signatures) with code highlighting (which is obviously beneficial, especially for more complicated signatures). Previously, the documentation author had to choose one or the other.

Demonstrate the new directive by converting the cmake_language command documentation. Other commands can be converted in follow-up MRs.

Details of original description moved to documentation in the change.

Additionally, targets are automatically generated from the leading set of "keywords", where a "keyword" is defined as 'anything that starts with a letter'. This should work well for most cases as variables usually start with <. For example, command(FOO BAR <var>) will generate the link "FOO BAR". This is roughly equivalent to .. _`FOO BAR`:, but hovering over the signature will cause a '¶' to appear offering a "permalink to this definition", similar to how this feature already exists for section headers. Browsers may also now highlight the signature when jumping to a signature (note dt:target from basic.css), which aids readers in locating the relevant section more quickly, especially near the bottom of a page.

If the generated target name is already in use, no target will be generated. If the generated target name is incorrect, the :target: option may be used to override it.

Multiple signatures may be given to a single signature directive by placing them on separate lines. A line ending with ) denotes the end of a signature, which is likely an adequate heuristic for now, but could be improved if needed. When using :target: together with multiple signatures, an alternate target name should be provided for each signature, one per line. For example (the first newline after :target: is optional):

.. signature::
  command(FOO)
  command(BAR)
  :target:
    COMMAND FOO
    COMMAND BAR

  Descriptive text.

Due to ROFF limitations, whitespace in signatures is not preserved. We might revisit this in the future, though it is likely the best we can do is preserve whitespace only in specific output formats (e.g. HTML). For very long signatures, we recommend using an abbreviated form as the 'heading' and giving a more complete expansion as a code-block in the description.

Some "gotchas" to be aware of when using this:

  • There must not be a blank line after .. signature::. (If you really want, you can also put the signature on the same line immediately after the ::.) If you add one, you will get an angry message, "Error in "signature" directive: 1 argument(s) required, 0 supplied." and documentation generation will fail.
  • :ref: does not work with the generated targets. This was observed for example while fiddling with string.rst. These, e.g. :ref:`GET <JSON_GET>`, need to be converted to e.g. `GET <JSON GET_>`_. (Note that we also changed the target name in this example from JSON_GET to JSON GET for consistency.)
Edited by Brad King

Merge request reports