Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 19d9340

Browse files
authored
Merge pull request #24215 from lpsinger/show-source-link-option
Add :shows-source-link: option to Sphinx plot directive
2 parents c1c4b5a + d58fc21 commit 19d9340

File tree

3 files changed

+76
-24
lines changed

3 files changed

+76
-24
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Source links can be shown or hidden for each Sphinx plot directive
2+
------------------------------------------------------------------
3+
The :doc:`Sphinx plot directive </api/sphinxext_plot_directive_api>`
4+
(``.. plot::``) now supports a ``:show-source-link:`` option to show or hide
5+
the link to the source code for each plot. The default is set using the
6+
``plot_html_show_source_link`` variable in :file:`conf.py` (which
7+
defaults to True).

lib/matplotlib/sphinxext/plot_directive.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@
5555
the ``plot_include_source`` variable in :file:`conf.py` (which itself
5656
defaults to False).
5757
58+
``:show-source-link:`` : bool
59+
Whether to show a link to the source in HTML. The default can be
60+
changed using the ``plot_html_show_source_link`` variable in
61+
:file:`conf.py` (which itself defaults to True).
62+
5863
``:encoding:`` : str
5964
If this source file is in a non-UTF8 or non-ASCII encoding, the
6065
encoding must be specified using the ``:encoding:`` option. The
@@ -245,6 +250,7 @@ class PlotDirective(Directive):
245250
'align': Image.align,
246251
'class': directives.class_option,
247252
'include-source': _option_boolean,
253+
'show-source-link': _option_boolean,
248254
'format': _option_format,
249255
'context': _option_context,
250256
'nofigs': directives.flag,
@@ -666,6 +672,7 @@ def run(arguments, content, options, state_machine, state, lineno):
666672
default_fmt = formats[0][0]
667673

668674
options.setdefault('include-source', config.plot_include_source)
675+
options.setdefault('show-source-link', config.plot_html_show_source_link)
669676
if 'class' in options:
670677
# classes are parsed into a list of string, and output by simply
671678
# printing the list, abusing the fact that RST guarantees to strip
@@ -832,7 +839,7 @@ def run(arguments, content, options, state_machine, state, lineno):
832839

833840
# Not-None src_link signals the need for a source link in the generated
834841
# html
835-
if j == 0 and config.plot_html_show_source_link:
842+
if j == 0 and options['show-source-link']:
836843
src_link = source_link
837844
else:
838845
src_link = None
@@ -866,7 +873,7 @@ def run(arguments, content, options, state_machine, state, lineno):
866873
shutil.copyfile(fn, destimg)
867874

868875
# copy script (if necessary)
869-
if config.plot_html_show_source_link:
876+
if options['show-source-link']:
870877
Path(dest_dir, output_base + source_ext).write_text(
871878
doctest.script_from_examples(code)
872879
if source_file_name == rst_file and is_doctest

lib/matplotlib/tests/test_sphinxext.py

Lines changed: 60 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414
minversion=None if sys.version_info < (3, 10) else '4.1.3')
1515

1616

17-
def test_tinypages(tmpdir):
18-
source_dir = Path(tmpdir) / 'src'
19-
shutil.copytree(Path(__file__).parent / 'tinypages', source_dir)
20-
html_dir = source_dir / '_build' / 'html'
21-
doctree_dir = source_dir / 'doctrees'
17+
def test_tinypages(tmp_path):
18+
shutil.copytree(Path(__file__).parent / 'tinypages', tmp_path,
19+
dirs_exist_ok=True)
20+
html_dir = tmp_path / '_build' / 'html'
21+
doctree_dir = tmp_path / 'doctrees'
2222
# Build the pages with warnings turned into errors
2323
cmd = [sys.executable, '-msphinx', '-W', '-b', 'html',
2424
'-d', str(doctree_dir),
@@ -32,7 +32,7 @@ def test_tinypages(tmpdir):
3232
out, err = proc.communicate()
3333

3434
# Build the pages with warnings turned into errors
35-
build_sphinx_html(source_dir, doctree_dir, html_dir)
35+
build_sphinx_html(tmp_path, doctree_dir, html_dir)
3636

3737
def plot_file(num):
3838
return html_dir / f'some_plots-{num}.png'
@@ -75,13 +75,13 @@ def plot_directive_file(num):
7575
assert filecmp.cmp(range_6, plot_file(17))
7676

7777
# Modify the included plot
78-
contents = (source_dir / 'included_plot_21.rst').read_bytes()
78+
contents = (tmp_path / 'included_plot_21.rst').read_bytes()
7979
contents = contents.replace(b'plt.plot(range(6))', b'plt.plot(range(4))')
80-
(source_dir / 'included_plot_21.rst').write_bytes(contents)
80+
(tmp_path / 'included_plot_21.rst').write_bytes(contents)
8181
# Build the pages again and check that the modified file was updated
8282
modification_times = [plot_directive_file(i).stat().st_mtime
8383
for i in (1, 2, 3, 5)]
84-
build_sphinx_html(source_dir, doctree_dir, html_dir)
84+
build_sphinx_html(tmp_path, doctree_dir, html_dir)
8585
assert filecmp.cmp(range_4, plot_file(17))
8686
# Check that the plots in the plot_directive folder weren't changed.
8787
# (plot_directive_file(1) won't be modified, but it will be copied to html/
@@ -98,35 +98,73 @@ def plot_directive_file(num):
9898
assert filecmp.cmp(range_6, plot_file(5))
9999

100100

101-
def test_plot_html_show_source_link(tmpdir):
102-
source_dir = Path(tmpdir) / 'src'
103-
source_dir.mkdir()
101+
def test_plot_html_show_source_link(tmp_path):
104102
parent = Path(__file__).parent
105-
shutil.copyfile(parent / 'tinypages/conf.py', source_dir / 'conf.py')
106-
shutil.copytree(parent / 'tinypages/_static', source_dir / '_static')
107-
doctree_dir = source_dir / 'doctrees'
108-
(source_dir / 'index.rst').write_text("""
103+
shutil.copyfile(parent / 'tinypages/conf.py', tmp_path / 'conf.py')
104+
shutil.copytree(parent / 'tinypages/_static', tmp_path / '_static')
105+
doctree_dir = tmp_path / 'doctrees'
106+
(tmp_path / 'index.rst').write_text("""
109107
.. plot::
110108
111109
plt.plot(range(2))
112110
""")
113111
# Make sure source scripts are created by default
114-
html_dir1 = source_dir / '_build' / 'html1'
115-
build_sphinx_html(source_dir, doctree_dir, html_dir1)
112+
html_dir1 = tmp_path / '_build' / 'html1'
113+
build_sphinx_html(tmp_path, doctree_dir, html_dir1)
116114
assert "index-1.py" in [p.name for p in html_dir1.iterdir()]
117115
# Make sure source scripts are NOT created when
118116
# plot_html_show_source_link` is False
119-
html_dir2 = source_dir / '_build' / 'html2'
120-
build_sphinx_html(source_dir, doctree_dir, html_dir2,
117+
html_dir2 = tmp_path / '_build' / 'html2'
118+
build_sphinx_html(tmp_path, doctree_dir, html_dir2,
121119
extra_args=['-D', 'plot_html_show_source_link=0'])
122120
assert "index-1.py" not in [p.name for p in html_dir2.iterdir()]
123121

124122

125-
def build_sphinx_html(source_dir, doctree_dir, html_dir, extra_args=None):
123+
@pytest.mark.parametrize('plot_html_show_source_link', [0, 1])
124+
def test_show_source_link_true(tmp_path, plot_html_show_source_link):
125+
# Test that a source link is generated if :show-source-link: is true,
126+
# whether or not plot_html_show_source_link is true.
127+
parent = Path(__file__).parent
128+
shutil.copyfile(parent / 'tinypages/conf.py', tmp_path / 'conf.py')
129+
shutil.copytree(parent / 'tinypages/_static', tmp_path / '_static')
130+
doctree_dir = tmp_path / 'doctrees'
131+
(tmp_path / 'index.rst').write_text("""
132+
.. plot::
133+
:show-source-link: true
134+
135+
plt.plot(range(2))
136+
""")
137+
html_dir = tmp_path / '_build' / 'html'
138+
build_sphinx_html(tmp_path, doctree_dir, html_dir, extra_args=[
139+
'-D', f'plot_html_show_source_link={plot_html_show_source_link}'])
140+
assert "index-1.py" in [p.name for p in html_dir.iterdir()]
141+
142+
143+
@pytest.mark.parametrize('plot_html_show_source_link', [0, 1])
144+
def test_show_source_link_false(tmp_path, plot_html_show_source_link):
145+
# Test that a source link is NOT generated if :show-source-link: is false,
146+
# whether or not plot_html_show_source_link is true.
147+
parent = Path(__file__).parent
148+
shutil.copyfile(parent / 'tinypages/conf.py', tmp_path / 'conf.py')
149+
shutil.copytree(parent / 'tinypages/_static', tmp_path / '_static')
150+
doctree_dir = tmp_path / 'doctrees'
151+
(tmp_path / 'index.rst').write_text("""
152+
.. plot::
153+
:show-source-link: false
154+
155+
plt.plot(range(2))
156+
""")
157+
html_dir = tmp_path / '_build' / 'html'
158+
build_sphinx_html(tmp_path, doctree_dir, html_dir, extra_args=[
159+
'-D', f'plot_html_show_source_link={plot_html_show_source_link}'])
160+
assert "index-1.py" not in [p.name for p in html_dir.iterdir()]
161+
162+
163+
def build_sphinx_html(tmp_path, doctree_dir, html_dir, extra_args=None):
126164
# Build the pages with warnings turned into errors
127165
extra_args = [] if extra_args is None else extra_args
128166
cmd = [sys.executable, '-msphinx', '-W', '-b', 'html',
129-
'-d', str(doctree_dir), str(source_dir), str(html_dir), *extra_args]
167+
'-d', str(doctree_dir), str(tmp_path), str(html_dir), *extra_args]
130168
proc = Popen(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True,
131169
env={**os.environ, "MPLBACKEND": ""})
132170
out, err = proc.communicate()

0 commit comments

Comments
 (0)