sphinx-examples-as-code 0.1.0__tar.gz → 0.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/.github/workflows/ci.yml +1 -1
- sphinx_examples_as_code-0.3.2/LICENSE +21 -0
- sphinx_examples_as_code-0.3.2/PKG-INFO +187 -0
- sphinx_examples_as_code-0.3.2/README.md +160 -0
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/pyproject.toml +6 -0
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/sphinx_examples_as_code/__init__.py +498 -65
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/sphinx_examples_as_code/_version.py +3 -3
- sphinx_examples_as_code-0.3.2/sphinx_examples_as_code.egg-info/PKG-INFO +187 -0
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/sphinx_examples_as_code.egg-info/SOURCES.txt +16 -0
- sphinx_examples_as_code-0.3.2/sphinx_examples_as_code.egg-info/scm_file_list.json +34 -0
- sphinx_examples_as_code-0.3.2/sphinx_examples_as_code.egg-info/scm_version.json +8 -0
- sphinx_examples_as_code-0.3.2/tests/gallery_fixture/conf.py +24 -0
- sphinx_examples_as_code-0.3.2/tests/gallery_fixture/examples/GALLERY_HEADER.rst +2 -0
- sphinx_examples_as_code-0.3.2/tests/gallery_fixture/examples/plot_minimal.py +28 -0
- sphinx_examples_as_code-0.3.2/tests/gallery_fixture/index.rst +7 -0
- sphinx_examples_as_code-0.3.2/tests/heading_level_fixture/conf.py +23 -0
- sphinx_examples_as_code-0.3.2/tests/heading_level_fixture/examples/GALLERY_HEADER.rst +2 -0
- sphinx_examples_as_code-0.3.2/tests/heading_level_fixture/examples/plot_reused_level.py +19 -0
- sphinx_examples_as_code-0.3.2/tests/heading_level_fixture/examples/plot_three_levels.py +19 -0
- sphinx_examples_as_code-0.3.2/tests/heading_level_fixture/index.rst +7 -0
- sphinx_examples_as_code-0.3.2/tests/single_function_fixture/conf.py +84 -0
- sphinx_examples_as_code-0.3.2/tests/single_function_fixture/index.rst +4 -0
- sphinx_examples_as_code-0.3.2/tests/single_function_fixture/mymodule.py +13 -0
- sphinx_examples_as_code-0.3.2/tests/test_gallery_downloads.py +263 -0
- sphinx_examples_as_code-0.3.2/tests/test_heading_level_reuse.py +90 -0
- sphinx_examples_as_code-0.3.2/tests/test_single_function_page.py +40 -0
- sphinx_examples_as_code-0.3.2/tests/test_sphinx_examples_as_code.py +2160 -0
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/tests/test_tinypages.py +182 -30
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/tests/tinypages/docstring_cases.py +1 -1
- sphinx_examples_as_code-0.1.0/PKG-INFO +0 -106
- sphinx_examples_as_code-0.1.0/README.md +0 -81
- sphinx_examples_as_code-0.1.0/sphinx_examples_as_code.egg-info/PKG-INFO +0 -106
- sphinx_examples_as_code-0.1.0/sphinx_examples_as_code.egg-info/scm_file_list.json +0 -18
- sphinx_examples_as_code-0.1.0/sphinx_examples_as_code.egg-info/scm_version.json +0 -8
- sphinx_examples_as_code-0.1.0/tests/test_sphinx_examples_as_code.py +0 -1058
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/.github/dependabot.yml +0 -0
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/.github/release.yml +0 -0
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/.gitignore +0 -0
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/.pre-commit-config.yaml +0 -0
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/setup.cfg +0 -0
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/sphinx_examples_as_code.egg-info/dependency_links.txt +0 -0
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/sphinx_examples_as_code.egg-info/requires.txt +0 -0
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/sphinx_examples_as_code.egg-info/top_level.txt +0 -0
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/tests/tinypages/conf.py +0 -0
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/tests/tinypages/docstring_cases.rst +0 -0
- {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.3.2}/tests/tinypages/index.rst +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 The PyVista Developers
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to
|
|
7
|
+
deal in the Software without restriction, including without limitation the
|
|
8
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
9
|
+
sell copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
20
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
21
|
+
IN THE SOFTWARE.
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sphinx-examples-as-code
|
|
3
|
+
Version: 0.3.2
|
|
4
|
+
Summary: Sphinx extension for converting docstring examples into downloadable code.
|
|
5
|
+
Author-email: The PyVista Developers <info@pyvista.org>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/pyvista/sphinx-examples-as-code
|
|
8
|
+
Keywords: download,examples,sphinx
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Framework :: Sphinx :: Extension
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: Operating System :: MacOS
|
|
13
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
14
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: pyvista>=0.48
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# sphinx-examples-as-code
|
|
29
|
+
|
|
30
|
+
A Sphinx extension that turns docstring/page "Examples" sections into downloadable,
|
|
31
|
+
runnable `.py` and/or `.ipynb` files, with a download link inserted into the section.
|
|
32
|
+
|
|
33
|
+
Pages or docstrings without an Examples section are left completely untouched. Adding
|
|
34
|
+
`sphinx_examples_as_code` to `conf.py`'s `extensions` is the only on/off switch.
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install sphinx-examples-as-code
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Add it to your Sphinx `conf.py`:
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
extensions = [
|
|
46
|
+
...,
|
|
47
|
+
'sphinx_examples_as_code',
|
|
48
|
+
]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Configuration
|
|
52
|
+
|
|
53
|
+
Everything lives in one dict in `conf.py`, `sphinx_examples_as_code_conf` -- set only
|
|
54
|
+
the keys you want to change from their default:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
sphinx_examples_as_code_conf = {
|
|
58
|
+
'link_position': 'top',
|
|
59
|
+
'formats': ['py', 'ipynb'],
|
|
60
|
+
'gallery_downloads': False,
|
|
61
|
+
'footer': (
|
|
62
|
+
'Generated by `sphinx-examples-as-code '
|
|
63
|
+
'<https://github.com/pyvista/sphinx-examples-as-code>`_'
|
|
64
|
+
),
|
|
65
|
+
'link_labels': {
|
|
66
|
+
'py': 'Download Python source code',
|
|
67
|
+
'ipynb': 'Download Jupyter notebook',
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
- `link_position`: where the download link(s) land within the Examples section. `'top'`
|
|
73
|
+
(default) or `'bottom'`.
|
|
74
|
+
- `formats`: which downloads to generate. A list containing `'py'`, `'ipynb'`, or both
|
|
75
|
+
(default). Always offered in that order regardless of how the list is written.
|
|
76
|
+
- `link_labels`: the text of the download link(s) themselves, per format. Set only the
|
|
77
|
+
format(s) you want to change; any left unset keep reading their own default shown above.
|
|
78
|
+
- `gallery_downloads`: opt-in takeover of
|
|
79
|
+
[sphinx-gallery](https://sphinx-gallery.github.io)'s own per-example downloads.
|
|
80
|
+
`False` (default) leaves sphinx-gallery pages untouched. See
|
|
81
|
+
[Sphinx-Gallery integration](#sphinx-gallery-integration) below.
|
|
82
|
+
- `footer`: a string appended to the end of every generated file. Defaults to a one-line
|
|
83
|
+
"generated file" credit linking back to this project; set to `None` to omit it
|
|
84
|
+
entirely. Preceded by a blank line and a `-`-only divider line, which also renders as a
|
|
85
|
+
real horizontal rule in `.ipynb`; the footer always gets its own dedicated cell there.
|
|
86
|
+
Parsed as RST: a hyperlink written as `` `text <url>`_ `` becomes a real clickable
|
|
87
|
+
Markdown link in `.ipynb`, and renders inline as `text url` in `.py`. Plain text with no
|
|
88
|
+
markup at all becomes one comment line per line of text, and blank-line-separated
|
|
89
|
+
paragraphs stay separated.
|
|
90
|
+
|
|
91
|
+
An unrecognized key raises a configuration error at build start.
|
|
92
|
+
|
|
93
|
+
Cross-references and hyperlinks resolve into absolute links using Sphinx's own
|
|
94
|
+
[`html_baseurl`](https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-html_baseurl).
|
|
95
|
+
Leave it unset and no links are generated anywhere.
|
|
96
|
+
|
|
97
|
+
Overriding a single key from the command line works via a dotted `-D` flag, e.g.
|
|
98
|
+
`-D sphinx_examples_as_code_conf.link_position=bottom` -- this only touches that one
|
|
99
|
+
key, leaving the rest (`conf.py`'s values, or the defaults) alone.
|
|
100
|
+
|
|
101
|
+
## Conversion rules
|
|
102
|
+
|
|
103
|
+
What happens to the content of an Examples section:
|
|
104
|
+
|
|
105
|
+
- Doctest blocks (`>>> ...` / `... ...`) keep their input lines, prompts stripped, as
|
|
106
|
+
real Python source. Doctest *output* lines are dropped — only the input code matters.
|
|
107
|
+
- `.. code-block:: python` (or `py`) blocks are kept as-is; other languages become
|
|
108
|
+
comments, set off with blank lines on both sides like any other directive.
|
|
109
|
+
- Admonitions (`.. note::`, `.. warning::`, `.. seealso::`, ...) become a `# LABEL:`
|
|
110
|
+
comment followed by their content as comments. "See Also" is recognized in any of its
|
|
111
|
+
three forms (`.. seealso::`, a bare `.. rubric:: See Also`, or a hand-written `See
|
|
112
|
+
Also` heading) and always renders the same way.
|
|
113
|
+
- Cross-references and inline code (`:class:`, `:meth:`, `:func:`, `:attr:`,
|
|
114
|
+
double-backtick literals, ...) keep their display text, wrapped in backticks (e.g.
|
|
115
|
+
``:class:`pyvista.Plotter` `` -> `` `pyvista.Plotter` ``). If `html_baseurl` is set and
|
|
116
|
+
the reference resolves: `.ipynb` turns it into a clickable link everywhere; `.py` only
|
|
117
|
+
writes the link inside a "See Also" part (as `name url` on its own line) — everywhere
|
|
118
|
+
else in `.py` the link is simply omitted.
|
|
119
|
+
- Plain prose-style references (`:ref:`, `:doc:`) are treated the same way, minus the
|
|
120
|
+
backticks.
|
|
121
|
+
- Everything else text-bearing (prose, captions, other non-Python code) becomes a plain
|
|
122
|
+
`#` comment.
|
|
123
|
+
- Figures/images, raw HTML, sphinx-design dropdowns/tab-sets, and sphinx-tags' `.. tags::`
|
|
124
|
+
line are dropped entirely.
|
|
125
|
+
|
|
126
|
+
Generated `.py` files start with a `# Examples from <qualified name>` title header
|
|
127
|
+
(gallery mode uses the page's own title instead -- see below), with a few whitespace
|
|
128
|
+
conventions: prose directly above a code block stays attached to it, a code block is
|
|
129
|
+
always followed by a blank line, and a directive (header, `# NOTE:`-style block) gets
|
|
130
|
+
blank lines on both sides.
|
|
131
|
+
|
|
132
|
+
Generated `.ipynb` notebooks use the same content, split into alternating code/markdown
|
|
133
|
+
cells instead.
|
|
134
|
+
|
|
135
|
+
A download link is only added if the resulting code contains at least one real
|
|
136
|
+
executable statement.
|
|
137
|
+
|
|
138
|
+
## Sphinx-Gallery integration
|
|
139
|
+
|
|
140
|
+
With `sphinx_examples_as_code_conf['gallery_downloads'] = True`, this extension takes
|
|
141
|
+
over the downloads on every page generated by
|
|
142
|
+
[sphinx-gallery](https://sphinx-gallery.github.io): the "Go to the end to download the
|
|
143
|
+
full example code" note and the `.py`/`.ipynb`/`.zip` download footer are removed from
|
|
144
|
+
the page, replaced with download link(s) built by this extension instead — same
|
|
145
|
+
conversion rules as above, applied to the whole page rather than one Examples section.
|
|
146
|
+
The generated file's header uses the page's own title (e.g. `# Create Circular Arcs`)
|
|
147
|
+
rather than the generic `# Examples from <docname>`.
|
|
148
|
+
|
|
149
|
+
The "Total running time" line and the "Gallery generated by Sphinx-Gallery" credit line
|
|
150
|
+
stay on the rendered page untouched, but never make it into the generated download
|
|
151
|
+
itself.
|
|
152
|
+
|
|
153
|
+
Detection is automatic and per-page — any page without a sphinx-gallery download footer
|
|
154
|
+
is left completely untouched. Gallery pages and ordinary docstring/prose pages (using
|
|
155
|
+
the Examples-section behavior above) can coexist on the same site.
|
|
156
|
+
|
|
157
|
+
A `# %%` cell with its own RST heading gets the same header treatment as the file's own
|
|
158
|
+
title, and renders as a real Markdown heading in `.ipynb`. Level is relative to actual
|
|
159
|
+
RST section nesting, not always one below the file's own header: a cell heading nested
|
|
160
|
+
under the page's own title (the common case) is one level below it; one that reuses the
|
|
161
|
+
page title's own underline character is level 1, the same as the file's own header; a
|
|
162
|
+
cell heading nested under *that* is level 2 relative to it, and so on.
|
|
163
|
+
|
|
164
|
+
Each format uses one heading style consistently across every level, rather than mixing
|
|
165
|
+
styles:
|
|
166
|
+
|
|
167
|
+
- `.py` uses an RST-style title + underline, one character per level -- the same
|
|
168
|
+
sequence Sphinx's own documentation uses for sections through sub-paragraphs: `=`, `-`,
|
|
169
|
+
`~`, `^`, `"`, `'` for levels 1 through 6.
|
|
170
|
+
- `.ipynb` always uses ATX syntax (`#`, `##`, `###`, ...), since that's a real Markdown
|
|
171
|
+
heading at any level, whereas an underline only reads as one for the first two.
|
|
172
|
+
|
|
173
|
+
Two things worth knowing before turning this on:
|
|
174
|
+
|
|
175
|
+
- It's built against sphinx-gallery's own RST/HTML output (the same `sphx-glr-*` CSS
|
|
176
|
+
classes its own theming depends on), not a documented extension API. A future
|
|
177
|
+
sphinx-gallery release could shift that structure without warning.
|
|
178
|
+
- sphinx-gallery's own `.py`/`.ipynb`/`.zip` downloads still end up copied into
|
|
179
|
+
`_downloads/`, even though nothing on the page links to them anymore.
|
|
180
|
+
|
|
181
|
+
## Development
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
uv sync --group dev
|
|
185
|
+
uv run pytest
|
|
186
|
+
uv run pre-commit run --all-files
|
|
187
|
+
```
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# sphinx-examples-as-code
|
|
2
|
+
|
|
3
|
+
A Sphinx extension that turns docstring/page "Examples" sections into downloadable,
|
|
4
|
+
runnable `.py` and/or `.ipynb` files, with a download link inserted into the section.
|
|
5
|
+
|
|
6
|
+
Pages or docstrings without an Examples section are left completely untouched. Adding
|
|
7
|
+
`sphinx_examples_as_code` to `conf.py`'s `extensions` is the only on/off switch.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install sphinx-examples-as-code
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Add it to your Sphinx `conf.py`:
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
extensions = [
|
|
19
|
+
...,
|
|
20
|
+
'sphinx_examples_as_code',
|
|
21
|
+
]
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Configuration
|
|
25
|
+
|
|
26
|
+
Everything lives in one dict in `conf.py`, `sphinx_examples_as_code_conf` -- set only
|
|
27
|
+
the keys you want to change from their default:
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
sphinx_examples_as_code_conf = {
|
|
31
|
+
'link_position': 'top',
|
|
32
|
+
'formats': ['py', 'ipynb'],
|
|
33
|
+
'gallery_downloads': False,
|
|
34
|
+
'footer': (
|
|
35
|
+
'Generated by `sphinx-examples-as-code '
|
|
36
|
+
'<https://github.com/pyvista/sphinx-examples-as-code>`_'
|
|
37
|
+
),
|
|
38
|
+
'link_labels': {
|
|
39
|
+
'py': 'Download Python source code',
|
|
40
|
+
'ipynb': 'Download Jupyter notebook',
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
- `link_position`: where the download link(s) land within the Examples section. `'top'`
|
|
46
|
+
(default) or `'bottom'`.
|
|
47
|
+
- `formats`: which downloads to generate. A list containing `'py'`, `'ipynb'`, or both
|
|
48
|
+
(default). Always offered in that order regardless of how the list is written.
|
|
49
|
+
- `link_labels`: the text of the download link(s) themselves, per format. Set only the
|
|
50
|
+
format(s) you want to change; any left unset keep reading their own default shown above.
|
|
51
|
+
- `gallery_downloads`: opt-in takeover of
|
|
52
|
+
[sphinx-gallery](https://sphinx-gallery.github.io)'s own per-example downloads.
|
|
53
|
+
`False` (default) leaves sphinx-gallery pages untouched. See
|
|
54
|
+
[Sphinx-Gallery integration](#sphinx-gallery-integration) below.
|
|
55
|
+
- `footer`: a string appended to the end of every generated file. Defaults to a one-line
|
|
56
|
+
"generated file" credit linking back to this project; set to `None` to omit it
|
|
57
|
+
entirely. Preceded by a blank line and a `-`-only divider line, which also renders as a
|
|
58
|
+
real horizontal rule in `.ipynb`; the footer always gets its own dedicated cell there.
|
|
59
|
+
Parsed as RST: a hyperlink written as `` `text <url>`_ `` becomes a real clickable
|
|
60
|
+
Markdown link in `.ipynb`, and renders inline as `text url` in `.py`. Plain text with no
|
|
61
|
+
markup at all becomes one comment line per line of text, and blank-line-separated
|
|
62
|
+
paragraphs stay separated.
|
|
63
|
+
|
|
64
|
+
An unrecognized key raises a configuration error at build start.
|
|
65
|
+
|
|
66
|
+
Cross-references and hyperlinks resolve into absolute links using Sphinx's own
|
|
67
|
+
[`html_baseurl`](https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-html_baseurl).
|
|
68
|
+
Leave it unset and no links are generated anywhere.
|
|
69
|
+
|
|
70
|
+
Overriding a single key from the command line works via a dotted `-D` flag, e.g.
|
|
71
|
+
`-D sphinx_examples_as_code_conf.link_position=bottom` -- this only touches that one
|
|
72
|
+
key, leaving the rest (`conf.py`'s values, or the defaults) alone.
|
|
73
|
+
|
|
74
|
+
## Conversion rules
|
|
75
|
+
|
|
76
|
+
What happens to the content of an Examples section:
|
|
77
|
+
|
|
78
|
+
- Doctest blocks (`>>> ...` / `... ...`) keep their input lines, prompts stripped, as
|
|
79
|
+
real Python source. Doctest *output* lines are dropped — only the input code matters.
|
|
80
|
+
- `.. code-block:: python` (or `py`) blocks are kept as-is; other languages become
|
|
81
|
+
comments, set off with blank lines on both sides like any other directive.
|
|
82
|
+
- Admonitions (`.. note::`, `.. warning::`, `.. seealso::`, ...) become a `# LABEL:`
|
|
83
|
+
comment followed by their content as comments. "See Also" is recognized in any of its
|
|
84
|
+
three forms (`.. seealso::`, a bare `.. rubric:: See Also`, or a hand-written `See
|
|
85
|
+
Also` heading) and always renders the same way.
|
|
86
|
+
- Cross-references and inline code (`:class:`, `:meth:`, `:func:`, `:attr:`,
|
|
87
|
+
double-backtick literals, ...) keep their display text, wrapped in backticks (e.g.
|
|
88
|
+
``:class:`pyvista.Plotter` `` -> `` `pyvista.Plotter` ``). If `html_baseurl` is set and
|
|
89
|
+
the reference resolves: `.ipynb` turns it into a clickable link everywhere; `.py` only
|
|
90
|
+
writes the link inside a "See Also" part (as `name url` on its own line) — everywhere
|
|
91
|
+
else in `.py` the link is simply omitted.
|
|
92
|
+
- Plain prose-style references (`:ref:`, `:doc:`) are treated the same way, minus the
|
|
93
|
+
backticks.
|
|
94
|
+
- Everything else text-bearing (prose, captions, other non-Python code) becomes a plain
|
|
95
|
+
`#` comment.
|
|
96
|
+
- Figures/images, raw HTML, sphinx-design dropdowns/tab-sets, and sphinx-tags' `.. tags::`
|
|
97
|
+
line are dropped entirely.
|
|
98
|
+
|
|
99
|
+
Generated `.py` files start with a `# Examples from <qualified name>` title header
|
|
100
|
+
(gallery mode uses the page's own title instead -- see below), with a few whitespace
|
|
101
|
+
conventions: prose directly above a code block stays attached to it, a code block is
|
|
102
|
+
always followed by a blank line, and a directive (header, `# NOTE:`-style block) gets
|
|
103
|
+
blank lines on both sides.
|
|
104
|
+
|
|
105
|
+
Generated `.ipynb` notebooks use the same content, split into alternating code/markdown
|
|
106
|
+
cells instead.
|
|
107
|
+
|
|
108
|
+
A download link is only added if the resulting code contains at least one real
|
|
109
|
+
executable statement.
|
|
110
|
+
|
|
111
|
+
## Sphinx-Gallery integration
|
|
112
|
+
|
|
113
|
+
With `sphinx_examples_as_code_conf['gallery_downloads'] = True`, this extension takes
|
|
114
|
+
over the downloads on every page generated by
|
|
115
|
+
[sphinx-gallery](https://sphinx-gallery.github.io): the "Go to the end to download the
|
|
116
|
+
full example code" note and the `.py`/`.ipynb`/`.zip` download footer are removed from
|
|
117
|
+
the page, replaced with download link(s) built by this extension instead — same
|
|
118
|
+
conversion rules as above, applied to the whole page rather than one Examples section.
|
|
119
|
+
The generated file's header uses the page's own title (e.g. `# Create Circular Arcs`)
|
|
120
|
+
rather than the generic `# Examples from <docname>`.
|
|
121
|
+
|
|
122
|
+
The "Total running time" line and the "Gallery generated by Sphinx-Gallery" credit line
|
|
123
|
+
stay on the rendered page untouched, but never make it into the generated download
|
|
124
|
+
itself.
|
|
125
|
+
|
|
126
|
+
Detection is automatic and per-page — any page without a sphinx-gallery download footer
|
|
127
|
+
is left completely untouched. Gallery pages and ordinary docstring/prose pages (using
|
|
128
|
+
the Examples-section behavior above) can coexist on the same site.
|
|
129
|
+
|
|
130
|
+
A `# %%` cell with its own RST heading gets the same header treatment as the file's own
|
|
131
|
+
title, and renders as a real Markdown heading in `.ipynb`. Level is relative to actual
|
|
132
|
+
RST section nesting, not always one below the file's own header: a cell heading nested
|
|
133
|
+
under the page's own title (the common case) is one level below it; one that reuses the
|
|
134
|
+
page title's own underline character is level 1, the same as the file's own header; a
|
|
135
|
+
cell heading nested under *that* is level 2 relative to it, and so on.
|
|
136
|
+
|
|
137
|
+
Each format uses one heading style consistently across every level, rather than mixing
|
|
138
|
+
styles:
|
|
139
|
+
|
|
140
|
+
- `.py` uses an RST-style title + underline, one character per level -- the same
|
|
141
|
+
sequence Sphinx's own documentation uses for sections through sub-paragraphs: `=`, `-`,
|
|
142
|
+
`~`, `^`, `"`, `'` for levels 1 through 6.
|
|
143
|
+
- `.ipynb` always uses ATX syntax (`#`, `##`, `###`, ...), since that's a real Markdown
|
|
144
|
+
heading at any level, whereas an underline only reads as one for the first two.
|
|
145
|
+
|
|
146
|
+
Two things worth knowing before turning this on:
|
|
147
|
+
|
|
148
|
+
- It's built against sphinx-gallery's own RST/HTML output (the same `sphx-glr-*` CSS
|
|
149
|
+
classes its own theming depends on), not a documented extension API. A future
|
|
150
|
+
sphinx-gallery release could shift that structure without warning.
|
|
151
|
+
- sphinx-gallery's own `.py`/`.ipynb`/`.zip` downloads still end up copied into
|
|
152
|
+
`_downloads/`, even though nothing on the page links to them anymore.
|
|
153
|
+
|
|
154
|
+
## Development
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
uv sync --group dev
|
|
158
|
+
uv run pytest
|
|
159
|
+
uv run pre-commit run --all-files
|
|
160
|
+
```
|
|
@@ -11,6 +11,7 @@ dev = [
|
|
|
11
11
|
'pytest-cov',
|
|
12
12
|
'sphinx',
|
|
13
13
|
'sphinx-design',
|
|
14
|
+
'sphinx-gallery>=0.21.0',
|
|
14
15
|
'trame-pyvista',
|
|
15
16
|
]
|
|
16
17
|
|
|
@@ -92,6 +93,10 @@ ignore = ['D203', 'D211', 'D213']
|
|
|
92
93
|
[tool.ruff.lint.per-file-ignores]
|
|
93
94
|
'*/conf.py' = ['E402']
|
|
94
95
|
'tests/*' = ['D103']
|
|
96
|
+
# sphinx-gallery example scripts: the module docstring is an RST page title
|
|
97
|
+
# (title line + underline), not prose -- pydocstyle's summary-line rules don't apply.
|
|
98
|
+
'tests/gallery_fixture/examples/*' = ['D205', 'D400', 'D415', 'T201']
|
|
99
|
+
'tests/heading_level_fixture/examples/*' = ['D205', 'D400', 'D415', 'T201']
|
|
95
100
|
|
|
96
101
|
[tool.ruff.lint.isort]
|
|
97
102
|
combine-as-imports = true
|
|
@@ -100,6 +105,7 @@ force-sort-within-sections = true
|
|
|
100
105
|
required-imports = ['from __future__ import annotations']
|
|
101
106
|
|
|
102
107
|
[tool.setuptools]
|
|
108
|
+
license-files = ['LICENSE']
|
|
103
109
|
packages = ['sphinx_examples_as_code']
|
|
104
110
|
|
|
105
111
|
[tool.setuptools_scm]
|