Skip to content

Commit 5ee6560

Browse files
authored
Merge pull request matplotlib#30741 from duncanmmacleod/plot-directive-code-caption
Add :code-caption: option to plot directive
2 parents 1ab3332 + ce4789a commit 5ee6560

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

lib/matplotlib/sphinxext/plot_directive.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@
8484
figure. This overwrites the caption given in the content, when the plot
8585
is generated from a file.
8686
87+
``:code-caption:`` : str
88+
If specified, the option's argument will be used as a caption for the
89+
code block (when ``:include-source:`` is used). This is added as the
90+
``:caption:`` option to the ``.. code-block::`` directive.
91+
8792
Additionally, this directive supports all the options of the `image directive
8893
<https://docutils.sourceforge.io/docs/ref/rst/directives.html#image>`_,
8994
except for ``:target:`` (since plot will add its own target). These include
@@ -281,6 +286,7 @@ class PlotDirective(Directive):
281286
'context': _option_context,
282287
'nofigs': directives.flag,
283288
'caption': directives.unchanged,
289+
'code-caption': directives.unchanged,
284290
}
285291

286292
def run(self):
@@ -952,8 +958,11 @@ def run(arguments, content, options, state_machine, state, lineno):
952958
if is_doctest:
953959
lines = ['', *code_piece.splitlines()]
954960
else:
955-
lines = ['.. code-block:: python', '',
956-
*textwrap.indent(code_piece, ' ').splitlines()]
961+
lines = ['.. code-block:: python']
962+
if 'code-caption' in options:
963+
code_caption = options['code-caption'].replace('\n', ' ')
964+
lines.append(f' :caption: {code_caption}')
965+
lines.extend(['', *textwrap.indent(code_piece, ' ').splitlines()])
957966
source_code = "\n".join(lines)
958967
else:
959968
source_code = ""

lib/matplotlib/tests/test_sphinxext.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,30 @@ def test_plot_html_show_source_link_custom_basename(tmp_path):
205205
assert 'custom-name.py' in html_content
206206

207207

208+
def test_plot_html_code_caption(tmp_path):
209+
# Test that :code-caption: option adds caption to code block
210+
shutil.copyfile(tinypages / 'conf.py', tmp_path / 'conf.py')
211+
shutil.copytree(tinypages / '_static', tmp_path / '_static')
212+
doctree_dir = tmp_path / 'doctrees'
213+
(tmp_path / 'index.rst').write_text("""
214+
.. plot::
215+
:include-source:
216+
:code-caption: Example plotting code
217+
218+
import matplotlib.pyplot as plt
219+
plt.plot([1, 2, 3], [1, 4, 9])
220+
""")
221+
html_dir = tmp_path / '_build' / 'html'
222+
build_sphinx_html(tmp_path, doctree_dir, html_dir)
223+
224+
# Check that the HTML contains the code caption
225+
html_content = (html_dir / 'index.html').read_text(encoding='utf-8')
226+
assert 'Example plotting code' in html_content
227+
# Verify the caption is associated with the code block
228+
# (appears in a caption element)
229+
assert '<p class="caption"' in html_content or 'caption' in html_content.lower()
230+
231+
208232
def test_srcset_version(tmp_path):
209233
shutil.copytree(tinypages, tmp_path, dirs_exist_ok=True,
210234
ignore=shutil.ignore_patterns('_build', 'doctrees',

0 commit comments

Comments
 (0)