Skip to content

Commit e3b6824

Browse files
authored
Merge pull request #847 from python-cmd2/generating_output_docs
Generating output docs
2 parents d455696 + 64c05ab commit e3b6824

File tree

15 files changed

+569
-158
lines changed

15 files changed

+569
-158
lines changed

cmd2/ansi.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ def strip_style(text: str) -> str:
9494
def style_aware_wcswidth(text: str) -> int:
9595
"""
9696
Wrap wcswidth to make it compatible with strings that contains ANSI style sequences
97+
9798
:param text: the string being measured
99+
:return: the width of the string when printed to the terminal
98100
"""
99101
# Strip ANSI style sequences since they cause wcswidth to return -1
100102
return wcswidth(strip_style(text))
@@ -103,6 +105,7 @@ def style_aware_wcswidth(text: str) -> int:
103105
def style_aware_write(fileobj: IO, msg: str) -> None:
104106
"""
105107
Write a string to a fileobject and strip its ANSI style sequences if required by allow_style setting
108+
106109
:param fileobj: the file object being written to
107110
:param msg: the string being written
108111
"""
@@ -115,9 +118,10 @@ def style_aware_write(fileobj: IO, msg: str) -> None:
115118
def fg_lookup(fg_name: str) -> str:
116119
"""
117120
Look up ANSI escape codes based on foreground color name.
121+
118122
:param fg_name: foreground color name to look up ANSI escape code(s) for
119123
:return: ANSI escape code(s) associated with this color
120-
:raises ValueError if the color cannot be found
124+
:raises ValueError: if the color cannot be found
121125
"""
122126
try:
123127
ansi_escape = FG_COLORS[fg_name.lower()]
@@ -129,9 +133,10 @@ def fg_lookup(fg_name: str) -> str:
129133
def bg_lookup(bg_name: str) -> str:
130134
"""
131135
Look up ANSI escape codes based on background color name.
136+
132137
:param bg_name: background color name to look up ANSI escape code(s) for
133138
:return: ANSI escape code(s) associated with this color
134-
:raises ValueError if the color cannot be found
139+
:raises ValueError: if the color cannot be found
135140
"""
136141
try:
137142
ansi_escape = BG_COLORS[bg_name.lower()]
@@ -193,8 +198,13 @@ def style(text: Any, *, fg: str = '', bg: str = '', bold: bool = False,
193198
# These can be altered to suit an application's needs and only need to be a
194199
# function with the following structure: func(str) -> str
195200
style_success = functools.partial(style, fg='green')
201+
"""Partial function supplying arguments to :meth:`cmd2.ansi.style()` which colors text to signify success"""
202+
196203
style_warning = functools.partial(style, fg='bright_yellow')
204+
"""Partial function supplying arguments to :meth:`cmd2.ansi.style()` which colors text to signify a warning"""
205+
197206
style_error = functools.partial(style, fg='bright_red')
207+
"""Partial function supplying arguments to :meth:`cmd2.ansi.style()` which colors text to signify an error"""
198208

199209

200210
def async_alert_str(*, terminal_columns: int, prompt: str, line: str, cursor_offset: int, alert_msg: str) -> str:
@@ -255,6 +265,6 @@ def set_title_str(title: str) -> str:
255265
"""Get the required string, including ANSI escape codes, for setting window title for the terminal.
256266
257267
:param title: new title for the window
258-
:return string to write to sys.stderr in order to set the window title to the desired test
268+
:return: string to write to sys.stderr in order to set the window title to the desired test
259269
"""
260270
return colorama.ansi.set_title(title)

cmd2/cmd2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ def __init__(self, completekey: str = 'tab', stdin=None, stdout=None, *,
290290
# The error that prints when a non-existent command is run
291291
self.default_error = "{} is not a recognized command, alias, or macro"
292292

293-
# If this string is non-empty, then this warning message will print if a broken pipe error occurs while printing
293+
# If non-empty, this string will be displayed if a broken pipe error occurs
294294
self.broken_pipe_warning = ''
295295

296296
# Commands that will run at the beginning of the command loop

docs/api/ansi.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
cmd2.ansi
2+
=========
3+
4+
.. automodule:: cmd2.ansi
5+
:members:

docs/api/cmd.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,20 @@ cmd2.Cmd
33

44
.. autoclass:: cmd2.cmd2.Cmd
55
:members:
6+
7+
.. attribute:: help_error
8+
9+
The error message displayed to the user when they request help for a
10+
command with no help defined.
11+
12+
.. attribute:: default_error
13+
14+
The error message displayed when a non-existent command is run.
15+
16+
.. attribute:: settable
17+
18+
This dictionary contains the name and description of all settings available to users.
19+
20+
Users use the :ref:`features/builtin_commands:set` command to view and
21+
modify settings. Settings are stored in instance attributes with the
22+
same name as the setting.

docs/api/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ API Reference
77
cmd
88
decorators
99
exceptions
10+
ansi
1011
utility_classes
1112
utility_functions

docs/doc_conventions.rst

Lines changed: 140 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -19,61 +19,115 @@ In addition:
1919
documentation, and to the API reference
2020

2121

22+
Style Checker
23+
-------------
24+
25+
Use `doc8 <https://pypi.org/project/doc8/>`_ to check the style of the
26+
documentation. This tool can be invoked using the proper options by typing:
27+
28+
.. code-block:: shell
29+
30+
$ invoke doc8
31+
32+
2233
Naming Files
2334
------------
2435

25-
- all lower case file names
36+
All source files in the documentation must:
37+
38+
- have all lower case file names
2639
- if the name has multiple words, separate them with an underscore
27-
- all documentation file names end in '.rst'
40+
- end in '.rst'
2841

2942

30-
Heirarchy of headings
31-
---------------------
43+
Indenting
44+
---------
3245

33-
show the heirarchy of sphinx headings we use, and the conventions (underline
34-
only, no overline)
46+
In reStructuredText all indenting is significant. Use 2 spaces per indenting
47+
level.
3548

36-
Use '=', then '-', then '~'. If your document needs more levels than that,
37-
break it into separate documents.
3849

39-
You only have to worry about the heirarchy of headings within a single file.
40-
Sphinx handles the intra-file heirarchy magically on it's own.
50+
Wrapping
51+
--------
4152

42-
Use two blank lines before every heading unless it's the first heading in the
43-
file. Use one blank line after every heading
53+
Hard wrap all text so that line lengths are no greater than 79 characters. It
54+
makes everything easier when editing documentation, and has no impact on
55+
reading documentation because we render to html.
4456

4557

46-
Code
47-
----
58+
Titles and Headings
59+
-------------------
4860

49-
This documentation declares python as the default Sphinx domain. Python code
50-
or interactive python sessions can be presented by either:
61+
reStructuredText allows flexibility in how headings are defined. You only have
62+
to worry about the heirarchy of headings within a single file. Sphinx magically
63+
handles the intra-file heirarchy on it's own. This magic means that no matter
64+
how you style titles and headings in the various files that comprise the
65+
documentation, Sphinx will render properly structured output. To ensure we have
66+
a similar consistency when viewing the source files, we use the following
67+
conventions for titles and headings:
5168

52-
- finishing the preceding paragraph with a ``::`` and indenting the code
53-
- use the ``.. code-block::`` directive
69+
1. When creating a heading for a section, do not use the overline and underline
70+
syntax. Use the underline syntax only::
71+
72+
Document Title
73+
==============
74+
75+
2. The string of adornment characters on the line following the heading should
76+
be the same length as the title.
77+
78+
3. The title of a document should use the '=' adornment character on the next
79+
line and only one heading of this level should appear in each file.
80+
81+
4. Sections within a document should have their titles adorned with the '-'
82+
character::
83+
84+
Section Title
85+
-------------
86+
87+
5. Subsections within a section should have their titles adorned with the '~'
88+
character::
89+
90+
Subsection Title
91+
~~~~~~~~~~~~~~~~
5492

55-
If you want to show other code, like shell commands, then use ``.. code-block:
56-
shell``.
93+
6. Use two blank lines before every title unless it's the first heading in the
94+
file. Use one blank line after every heading.
5795

96+
7. If your document needs more than three levels of sections, break it into
97+
separate documents.
98+
99+
100+
Inline Code
101+
-----------
102+
103+
This documentation declares ``python`` as the default Sphinx domain. Python
104+
code or interactive Python sessions can be presented by either:
105+
106+
- finishing the preceding paragraph with a ``::`` and indenting the code
107+
- use the ``.. code-block::`` directive
58108

59-
Table of Contents and Captions
60-
------------------------------
109+
If you want to show non-Python code, like shell commands, then use ``..
110+
code-block: shell``.
61111

62112

63-
Hyperlinks
64-
----------
113+
External Hyperlinks
114+
-------------------
65115

66116
If you want to use an external hyperlink target, define the target at the top
67-
of the page, not the bottom.
117+
of the page or the top of the section, not the bottom. The target definition
118+
should always appear before it is referenced.
68119

69120

121+
Links To Other Documentation Pages and Sections
122+
-----------------------------------------------
123+
70124
We use the Sphinx `autosectionlabel
71125
<http://www.sphinx-doc.org/en/master/usage/extensions/autosectionlabel.html>`_
72126
extension. This allows you to reference any header in any document by::
73127

74128
See :ref:`features/argument_processing:Help Messages`
75129

76-
or ::
130+
or::
77131

78132
See :ref:`custom title<features/argument_processing:Help Messages>`
79133

@@ -85,44 +139,80 @@ and
85139

86140
See :ref:`custom title<features/argument_processing:Help Messages>`
87141

88-
[TODO what's the right way to link to source code? Can we make it link to the
89-
tag that the documentation is rendered from?]
90142

143+
API Documentation
144+
-----------------
91145

92-
Autolinking
93-
-----------
146+
The API documentation is mostly pulled from docstrings in the source code using
147+
the Sphinx `autodoc
148+
<https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html>`_
149+
extension. However, Sphinx has issues generating documentation for instance
150+
attributes (see `cmd2 issue 821
151+
<https://github.com/python-cmd2/cmd2/issues/821>`_ for the full discussion). We
152+
have chosen to not use code as the source of instance attribute documentation.
153+
Instead, it is added manually to the documentation files in ``cmd2/docs/api``.
154+
See ``cmd2/docs/api/cmd.rst`` to see how to add documentation for an attribute.
94155

156+
For module data members and class attributes, the ``autodoc`` extension allows
157+
documentation in a comment with special formatting (using a #: to start the
158+
comment instead of just #), or in a docstring after the definition. This
159+
project has standardized on the docstring after the definition approach. Do not
160+
use the specially formatted comment approach.
95161

96-
Referencing cmd2 API documentation
97-
----------------------------------
98162

163+
Links to API Reference
164+
----------------------
99165

100-
Info and Warning Callouts
101-
-------------------------
166+
To reference a method or function, use one of the following approaches:
102167

168+
1. Reference the full dotted path of the method::
103169

104-
Wrapping
105-
--------
170+
The :meth:`cmd2.cmd2.Cmd.poutput` method is similar to the Python built-in
171+
print function.
106172

107-
Hard wrap all text with line lengths no greater than 79 characters. It makes
108-
everything easier when editing documentation, and has no impact on reading
109-
documentation because we render to html.
173+
Which renders as: The :meth:`cmd2.cmd2.Cmd.poutput` method is similar to the
174+
Python built-in print function.
110175

176+
2. Reference the full dotted path to the method, but only display the method
177+
name::
111178

112-
Referencing cmd2
113-
-----------------
179+
The :meth:`~cmd2.cmd2.Cmd.poutput` method is similar to the Python built-in print function.
114180

115-
Whenever you reference ``cmd2`` in the documentation, enclose it in double
116-
backticks. This indicates an inline literal in restructured text, and makes it
117-
stand out when rendered as html.
181+
Which renders as: The :meth:`~cmd2.cmd2.Cmd.poutput` method is similar to the
182+
Python built-in print function.
118183

119-
Style Checker
120-
-------------
184+
3. Reference a portion of the dotted path of the method::
121185

122-
Use `doc8 <https://pypi.org/project/doc8/>`_ to check the style of the
123-
documentation. This tool can be invoked using the proper options by typing:
186+
The :meth:`.cmd2.Cmd.poutput` method is similar to the Python built-in print
187+
function.
124188

125-
.. code-block:: shell
189+
Which renders as: The :meth:`.cmd2.Cmd.poutput` method is similar to the Python
190+
built-in print function.
126191

127-
$ invoke doc8
192+
Avoid either of these approaches:
193+
194+
1. Reference just the class name without enough dotted path::
195+
196+
The :meth:`.Cmd.poutput` method is similar to the Python built-in print
197+
function.
198+
199+
Because ``cmd2.Cmd`` subclasses ``cmd.Cmd`` from the standard library, this
200+
approach does not clarify which class it is referring to.
201+
202+
2. Reference just a method name::
203+
204+
The :meth:`poutput` method is similar to the Python built-in print
205+
function.
206+
207+
While Sphinx may be smart enough to generate the correct output, the potential
208+
for multiple matching references is high, which causes Sphinx to generate
209+
warnings. The build pipeline that renders the documentation treats warnings as
210+
fatal errors. It's best to just be specific about what you are referencing.
128211

212+
213+
Referencing cmd2
214+
-----------------
215+
216+
Whenever you reference ``cmd2`` in the documentation, enclose it in double
217+
backticks. This indicates an inline literal in restructured text, and makes it
218+
stand out when rendered as html.

0 commit comments

Comments
 (0)