===================================
Contributing a documentation change
===================================

This tutorial will take you through the process of:

* Downloading the current documentation
* Installing required libraries
* Building and previewing the documentation
* Creating a new git branch
* Making a change to the documentation
* Committing the changes and making a pull request

Download the documentation
==========================

1. Sign up to `GitHub <https://github.com>`_ and :gh:`fork pydicom <pydicom/fork>`
2. Install `Git <https://git-scm.com/downloads>`_. If you're new to Git,
   the Django project has a good introduction on `working with Git and GitHub
   <https://docs.djangoproject.com/en/3.0/internals/contributing/writing-code/working-with-git/>`_.
   You can also take a look at the `GitHub branch-based workflow
   <https://guides.github.com/introduction/flow/>`_
3. Using the command line, ``cd`` to the directory where you want your
   local copy of *pydicom* to live. The documentation can then be downloaded
   using::

     git clone https://github.com/YourUsername/pydicom.git

4. (Optional) We recommend that you install your development copy of *pydicom*
   in a virtual environment. See the :doc:`virtual environments<virtualenvs>`
   tutorial for more information.

   Create a new virtualenv ``pyd-doc``, using a Python 3.X version such
   as 3.10, then activate it::

   python3.10 -m venv pyd-doc
   source pyd-doc/bin/activate

5. Install the cloned copy of *pydicom* and the dependencies requires for
   building the documentation (using ``-e`` for an editable install)::

   pip install -e pydicom[docs]


Build and preview the documentation
===================================

*pydicom's* documentation consists of a series of `reStructuredText
<https://thomas-cokelaer.info/tutorials/sphinx/rest_syntax.html>`_ (reST) files
located in the project's ``pydicom/doc`` directory which are converted to
HTML using `Sphinx <http://www.sphinx-doc.org>`_ during our build process.
To build the documentation locally, navigate to the ``doc`` directory and
run ``make html``::

  cd pydicom/doc
  make html

Occasionally you may need to clean up the generated files before a change
gets applied::

  $ make clean && make html

The HTML generated by the build can be viewed by opening
``_build/html/index.html`` in a web browser or by doing::

  cd _build/html
  python -m http.server 9999

And then going to http://localhost:9999


Create a new branch
===================
Create a new branch ``doc-tut`` for your changes (you can choose any name
that you want instead). Any changes made in this branch will be specific to
it and won't affect the main copy (the ``master`` branch) of
the documentation::

  git checkout -b doc-tut


Make a change to the documentation
==================================

Let's add a new guide on how to read a DICOM file. Create a new ``reading.rst``
file in ``doc/tutorials``, open it in a text editor and add in a title and some
text::

  ===================
  Reading DICOM files
  ===================

  In this tutorial we will be reading a DICOM file using *pydicom*.

Save it and build the documentation (``make html``). You should see a warning
in the build output, which we'll ignore for now:

.. code-block:: text

  checking consistency... [/path/to]/pydicom/doc/tutorials/reading.rst: WARNING: document isn't included in any toctree

Open the file ``_build/html/tutorials/reading.html`` in your browser (if you're
not using the Python ``http.server`` command) or
`here <http://localhost:9999/tutorials/reading.html>`__ (if you are). Your new
page should be visible.

The reason we got the warning above is because the page itself hasn't been
included in Sphinx's table of contents (the ``toctree``), which Sphinx
uses to map the relationship between pages in the documentation. It's not
a requirement that a page be included in the ``toctree``, but it's a good idea.

To make our new page a bit easier to find we'll include a link to it in
``tutorials/index.rst``, which will also include it in the ``toctree``::

  .. toctree::
     :maxdepth: 1

     installation
     virtualenvs
     contributing_code
     contributing_docs
     reading

.. |rarr| unicode:: U+2192 .. RIGHTWARDS ARROW

If you rebuild the HTML you should find that the warning is gone and that
your new page is reachable from the main documentation page
(on the left under "Documentation": Tutorials |rarr| Reading DICOM files).

Next we'll expand our page a bit to show off how to use some of the reST
markup::

  ===================
  Reading DICOM files
  ===================

  In this tutorial we will be reading a DICOM file using
  `pydicom <https://github.com/pydicom/pydicom>`_. The tasks you'll be doing
  will include:

  * Installing *pydicom*
  * Reading a :dcm:`DICOM dataset<part05/chapter_7.html>`
  * Printing an element

  Installing pydicom
  ==================
  See the :doc:`Installation guide</tutorials/installation>` on how to install
  *pydicom*.

  Reading a DICOM dataset
  =======================
  In a command window start a new **Python** session::

    $ python
    Python 3.6.5 (default, Apr  1 2018, 05:46:30)
    [GCC 7.3.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.

  .. note::

    Your Python version may be different

  *pydicom* includes a number of files which can be accessed through the
  :func:`~pydicom.data.get_testdata_file` function. To read the file
  ``CT_small.dcm`` we use :func:`~pydicom.filereader.dcmread`::

    >>> from pydicom import dcmread
    >>> from pydicom.data import get_testdata_file
    >>> fpath = get_testdata_file("CT_small.dcm")
    >>> fpath
    '[path/to]/pydicom/data/test_files/CT_small.dcm'
    >>> ds = dcmread(fpath)

  Printing an element
  ===================
  To get a :class:`list` of keywords for all the elements in the top level of
  the dataset you can do:

    >>> ds.dir()
    ['AccessionNumber', 'AcquisitionData', ..., 'PatientName', ..., 'XRayTubeCurrent']

  To :func:`print` the value of the (0010,0010) *Patient Name* element:

    >>> print(ds.PatientName)
    CompressedSamples^CT1

  To print the element itself:

    >>> print(ds['PatientName'])
    (0010, 0010) Patient's Name                      PN: 'CompressedSamples^CT1'

If you need help with the reST markup then you can:

* Take a look at the existing documentation to see how it was created
* Check out Sphinx's `reStructuredText primer
  <https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html?highlight=re>`_

There are also a number of directives that tell Sphinx to do certain things
(like inserting code blocks or a table of contents). Sphinx has a list of
these `here <https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html>`_.

For more information on writing documentation for *pydicom*, see
:doc:`writing documentation</guides/writing_documentation>`.

Just like before, you should build and preview the updated page. When you're
happy with the results move on to the next section.

Commit your changes and make a pull request
===========================================
First we add our new file to git::

  git add tutorials/reading.rst

And then stage the remaining changes (``-a``) and commit at the same time::

  git commit -am "Add documentation on reading a DICOM file"

After committing the changes, send them to your fork::

  git push origin doc-tut

You can create a pull request by visiting the :gh:`pydicom GitHub page
<pydicom>` where you should see your branch under *"Your recently push
branches"*. Click *"Compare & pull request"* and fill out the title (with a
``[WIP]`` prefix, i.e. ``[WIP] Add documentation of reading a DICOM file``)
and follow the instructions in the main entry window.

To submit the pull request (PR) for real - **please don't do this for
this example!** - then on the next page you would click *"Create pull
request"*. Creating the PR would automatically start the documentation build
checks which would be visible at the bottom of the PR as the
`CircleCI <https://circleci.com/>`_ check. Depending on when you view it,
the check would either be in progress, have passed or failed. The details of
the CircleCI build could be seen by clicking on "Details"

If the build was successful then the Artifacts tab would be visible (which may
require signing into CircleCI). The artifacts are the generated HTML files
and can be used to preview the results of the build by clicking Artifacts
|rarr| ``circleci/project/doc/_build/html/index.html``

If all the checks passed and you were happy with your changes, you'd change
the PR title prefix to ``[MRG]``. This would indicate that you considered the
PR ready to be reviewed and merged into the main branch.

What happens next?
==================
One or more reviewers would look at your pull request and may make suggestions,
ask for clarification or request changes. Once the reviewers were happy,
the pull request would be approved and your changes merged into the
``master`` branch where they would become part of *pydicom*.

However, because this is just an example, all we're going to do is clean up the
changes we've made. First we switch back to the ``master`` branch::

  git checkout master

We delete the local copy of the branch we created::

  git branch -d doc-tut

And lastly we delete the remote copy on GitHub. Go to
``https://github.com/YourUsername/pydicom/branches``, find the ``doc-tut``
branch and click the corresponding red bin icon. All done!
