1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
|
.. _docs_guidelines:
*************
Documentation
*************
Overview
========
All code must be documented and we follow these style conventions described here:
* `numpydoc <https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard>`__
We recommend familiarizing yourself with this style.
Referring to other code
-----------------------
To link to other methods, classes, or modules in sunpy you have to use backticks, for example:
.. code-block:: rst
`sunpy.map.GenericMap`
generates a link like this: `sunpy.map.GenericMap`.
We use the sphinx setting ``default_role = 'obj'`` so that you do not nor **SHOULD NOT** use the ``:class:`` qualifier, but ``:func:``, ``:meth:`` are different (more on this below).
Often, you don't want to show the full package and module name.
As long as the target is unambiguous you can simply leave them out:
.. code-block:: rst
`.GenericMap`
and the link still works: `.GenericMap`.
If there are multiple code elements with the same name (e.g. ``peek()`` is a method in multiple classes), you'll have to extend the definition:
.. code-block:: rst
`.GenericMap.peek` or `.CompositeMap.peek`
These will show up as `.GenericMap.peek` or `.CompositeMap.peek`.
To still show only the last segment you can add a tilde as prefix:
.. code-block:: rst
`~.GenericMap.peek` or `~.CompositeMap.peek`
will render as `~.GenericMap.peek` or `~.CompositeMap.peek`.
Other packages can also be linked via
`intersphinx <http://www.sphinx-doc.org/en/master/ext/intersphinx.html>`__:
.. code-block:: rst
`numpy.mean`
will return this link: `numpy.mean`.
This works for Python, Numpy and Astropy (full list is in :file:`docs/conf.py`).
With Sphinx, if you use ``:func:`` or ``:meth:``, it will add closing brackets to the link.
If you get the wrong pre-qualifier, it will break the link, so we suggest that you double check if what you are linking is a method or a function.
.. code-block:: rst
:class:`numpy.mean()`
:meth:`numpy.mean()`
:func:`numpy.mean()`
will return two broken links ("class" and "meth") but "func" will work.
sunpy-Specific Rules
--------------------
* For **all** RST files, we enforce a one sentence per line rule and ignore the line length.
* Standards on docstring length and style are enforced using `docformatter <https://pypi.org/project/docformatter/>`__:
.. code-block:: bash
docformatter -r -i --pre-summary-newline --make-summary-multi-line
* Heading style is the following for all RST files:
.. code-block:: rst
* with overline, for titles
= for sections
- for subsections
^ for subsubsections
" for paragraphs
* Anchors for each page should follow this format: ``sunpy-<section>-<subsection>-<summary of title>``., e.g., ``sunpy-tutorial-acquiring-data-index``.
* Use of ``.. code-block:`` is required for all code examples.
.. _Docs Guidelines for Data Sources:
Documenting Data Sources
------------------------
Subclasses of `~sunpy.map.GenericMap` or `~sunpy.timeseries.TimeSeries` must provide a detailed docstring providing an overview of the data source that the object represents.
In order to maintain consistency and completeness, the following information must be provided by a data source docstring, if available, and preferably in the following order:
* the name of the mission and instrument and the institution that built it
* short description of the instrument (e.g. Cassegrain reflector, Wolter-1 grazing incidence x-ray, coronagraph) including the type of detector
* description of the platform (e.g. satellite in 28 deg inclined orbit, a telescope on the summit of Mauna Kea in Hawaii)
* description of the primary purpose or science goals of the instrument.
* list of all wavelength(s) or passbands in appropriate units
* description of the emission processes which dominate in those passbands
* appropriate measurement properties such as field of view, angular resolution, time resolution
* description of the operational concept (e.g. operates 24/7, observes from 7 am to 5 pm UT) including mention of unusual operations scenarios (e.g. calibration seasons, eclipse seasons)
* the start and end of the data set
In addition, a reference section must be provided with links to the following resources, if available,
* the mission web page
* the instrument web page
* relevant wikipedia page(s)
* relevant user guide(s)
* the mission paper and instrument paper
* information to interpret metadata keywords such as FITS header reference
* the data archive
Examples can be found in any class defined in any Python file in ``sunpy/map/sources/`` such as `~sunpy.map.sources.AIAMap`.
Citing Publications
-------------------
Whenever possible, publications should be cited using BibTeX through the :doc:`sphinxcontrib.bibtex <sphinxcontrib_bibtex:index>` extension.
To do so, first add the appropriate entry in :file:`docs/references.bib`.
Then, you can add a citation to the docstring like so:
.. code-block:: rst
:cite:t:`franz_heliospheric_2002`
to insert a textual citation.
Similarly, you can use
.. code-block:: rst
:cite:p:`franz_heliospheric_2002`
to insert a parenthetical citation.
For more details on how to cite publications with ``sphinxcontrib_bibtex``, see :doc:`this page <sphinxcontrib_bibtex:usage>`.
Sphinx
======
All of the sunpy documentation (like this page) is built by `Sphinx <https://www.sphinx-doc.org/en/stable/>`__, which is a tool especially well-suited for documenting Python projects.
Sphinx works by parsing files written using a `a Mediawiki-like syntax <https://docutils.sourceforge.io/docs/user/rst/quickstart.html>`__ called `reStructuredText <https://docutils.sourceforge.io/rst.html>`__.
In addition to parsing static files of reStructuredText, Sphinx can also be told to parse code comments.
In fact, in addition to what you are reading right now, the `Python documentation <https://www.python.org/doc/>`__ was also created using Sphinx.
Usage
-----
All of the sunpy documentation is contained in the "docs" folder and code documentation strings.
The examples from the example gallery can be found in the "examples" folder.
In the root directory run::
tox -e build_docs-gallery
This will generate HTML documentation for sunpy in the "docs/_build/html" directory.
You can open the "index.html" file to browse the final product.
The gallery examples are located under "docs/_build/html/generated/gallery".
Sphinx builds documentation iteratively, only adding things that have changed.
If you want to build the documentation without executing the gallery examples, i.e. to reduce build times while working on other sections of the documentation you can run::
tox -e build_docs
If you'd like to start from scratch (i.e., remove the tox cache) then change to the :file:`docs/` directory and run::
make clean
cd ..
tox -r -e build_docs-gallery
To build the documentation in your current python environment you must have all the dependencies specified in ``pyproject.toml`` installed (``pip install -e .[docs,docs-gallery]``).
Then change to the :file:`docs/` directory and run::
make html
For more information on how to use Sphinx, consult the `Sphinx documentation <http://www.sphinx-doc.org/en/stable/contents.html>`__.
Special Sphinx directives
-------------------------
``minigallery`` directive
^^^^^^^^^^^^^^^^^^^^^^^^^
Sphinx will automatically record which functions, classes, etc. are used in each gallery example.
In the documentation, you can insert a mini-gallery of the subset of the gallery examples that uses a particular function, class, etc.
For example, the following RST block::
.. minigallery:: sunpy.coordinates.RotatedSunFrame
produces this mini-gallery:
.. minigallery:: sunpy.coordinates.RotatedSunFrame
If you want to specify more than one object, separate them by spaces.
This is particularly useful if you need to cover multiple namespaces in which an object may be accessed, e.g.::
.. minigallery:: sunpy.coordinates.RotatedSunFrame sunpy.coordinates.metaframes.RotatedSunFrame
``generate`` directive
^^^^^^^^^^^^^^^^^^^^^^
In rare circumstances, one may want to insert "raw" HTML directly into the pages written by Sphinx.
For HTML that is statically available (i.e., already written in some form), one can use the `"raw" directive <https://docutils.sourceforge.io/docs/ref/rst/directives.html#raw-data-pass-through>`__.
For HTML that is generated by Python code, sunpy provides the custom directive ``generate``.
Here's an example RST block::
.. generate:: html
:html_border:
import os
from sunpy.data.sample import file_dict
print("<table>")
for key, value in file_dict.items():
print(f"<tr><th>{key}</th><td>{os.path.basename(value)}</td></tr>")
print("</table>")
to insert the following HTML table:
.. generate:: html
:html_border:
import os
from sunpy.data.sample import file_dict
print("<table>")
for key, value in file_dict.items():
print(f"<tr><th>{key}</th><td>{os.path.basename(value)}</td></tr>")
print("</table>")
Troubleshooting
----------------
Sphinx can be very particular about formatting, and the warnings and errors aren't always obvious.
Below are some commonly-encountered warning/error messages along with a human-readable translation:
**WARNING: Duplicate explicit target name: "xxx".**
If you reference the same URL, etc more than once in the same document sphinx will complain.
To avoid, use double-underscores instead of single ones after the URL.
**ERROR: Malformed table. Column span alignment problem at line offset n**
Make sure there is a space before and after each colon in your class and
function docs (e.g. attribute : type, instead of attribute: type).
Also, for some sections (e.g. Attributes) numpydoc seems to complain when a description spans more than one line, particularly if it is the first attribute listed.
**WARNING: Block quote ends without a blank line; unexpected unindent.**
Lists should be indented one level from their parents.
**ERROR: Unknown target name: "xxx"**
In addition to legitimate errors of this type, this error will also occur when variables have a trailing underscore, e.g., ``xxx_``.
**WARNING: Explicit markup ends without a blank line; unexpected unindent.**
This usually occurs when the text following a directive is wrapped to the next line without properly indenting a multi-line text block.
**WARNING: toctree references unknown document '...'** / **WARNING: toctree contains reference to nonexisting document**
This pair of errors is due to the way numpydoc scrapes class members.
|