sphinx-examples-as-code 0.1.0__tar.gz → 0.2.1__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.
Files changed (37) hide show
  1. sphinx_examples_as_code-0.2.1/PKG-INFO +185 -0
  2. sphinx_examples_as_code-0.2.1/README.md +160 -0
  3. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/pyproject.toml +4 -0
  4. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/sphinx_examples_as_code/__init__.py +419 -54
  5. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/sphinx_examples_as_code/_version.py +3 -3
  6. sphinx_examples_as_code-0.2.1/sphinx_examples_as_code.egg-info/PKG-INFO +185 -0
  7. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/sphinx_examples_as_code.egg-info/SOURCES.txt +9 -0
  8. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/sphinx_examples_as_code.egg-info/scm_file_list.json +9 -0
  9. sphinx_examples_as_code-0.2.1/sphinx_examples_as_code.egg-info/scm_version.json +8 -0
  10. sphinx_examples_as_code-0.2.1/tests/gallery_fixture/conf.py +24 -0
  11. sphinx_examples_as_code-0.2.1/tests/gallery_fixture/examples/GALLERY_HEADER.rst +2 -0
  12. sphinx_examples_as_code-0.2.1/tests/gallery_fixture/examples/plot_minimal.py +28 -0
  13. sphinx_examples_as_code-0.2.1/tests/gallery_fixture/index.rst +7 -0
  14. sphinx_examples_as_code-0.2.1/tests/single_function_fixture/conf.py +84 -0
  15. sphinx_examples_as_code-0.2.1/tests/single_function_fixture/index.rst +4 -0
  16. sphinx_examples_as_code-0.2.1/tests/single_function_fixture/mymodule.py +13 -0
  17. sphinx_examples_as_code-0.2.1/tests/test_gallery_downloads.py +251 -0
  18. sphinx_examples_as_code-0.2.1/tests/test_single_function_page.py +40 -0
  19. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/tests/test_sphinx_examples_as_code.py +831 -42
  20. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/tests/test_tinypages.py +139 -10
  21. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/tests/tinypages/docstring_cases.py +1 -1
  22. sphinx_examples_as_code-0.1.0/PKG-INFO +0 -106
  23. sphinx_examples_as_code-0.1.0/README.md +0 -81
  24. sphinx_examples_as_code-0.1.0/sphinx_examples_as_code.egg-info/PKG-INFO +0 -106
  25. sphinx_examples_as_code-0.1.0/sphinx_examples_as_code.egg-info/scm_version.json +0 -8
  26. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/.github/dependabot.yml +0 -0
  27. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/.github/release.yml +0 -0
  28. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/.github/workflows/ci.yml +0 -0
  29. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/.gitignore +0 -0
  30. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/.pre-commit-config.yaml +0 -0
  31. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/setup.cfg +0 -0
  32. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/sphinx_examples_as_code.egg-info/dependency_links.txt +0 -0
  33. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/sphinx_examples_as_code.egg-info/requires.txt +0 -0
  34. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/sphinx_examples_as_code.egg-info/top_level.txt +0 -0
  35. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/tests/tinypages/conf.py +0 -0
  36. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/tests/tinypages/docstring_cases.rst +0 -0
  37. {sphinx_examples_as_code-0.1.0 → sphinx_examples_as_code-0.2.1}/tests/tinypages/index.rst +0 -0
@@ -0,0 +1,185 @@
1
+ Metadata-Version: 2.4
2
+ Name: sphinx-examples-as-code
3
+ Version: 0.2.1
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
+ Requires-Dist: pyvista>=0.48
25
+
26
+ # sphinx-examples-as-code
27
+
28
+ A Sphinx extension that turns docstring/page "Examples" sections into downloadable,
29
+ runnable `.py` and/or `.ipynb` files, with a download link inserted into the section.
30
+
31
+ Pages or docstrings without an Examples section are left completely untouched. Adding
32
+ `sphinx_examples_as_code` to `conf.py`'s `extensions` is the only on/off switch.
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ pip install sphinx-examples-as-code
38
+ ```
39
+
40
+ Add it to your Sphinx `conf.py`:
41
+
42
+ ```python
43
+ extensions = [
44
+ ...,
45
+ 'sphinx_examples_as_code',
46
+ ]
47
+ ```
48
+
49
+ ## Configuration
50
+
51
+ Everything lives in one dict in `conf.py`, `sphinx_examples_as_code_conf` -- set only
52
+ the keys you want to change from their default:
53
+
54
+ ```python
55
+ sphinx_examples_as_code_conf = {
56
+ 'link_position': 'top',
57
+ 'formats': ['py', 'ipynb'],
58
+ 'base_url': None,
59
+ 'gallery_downloads': False,
60
+ 'footer': (
61
+ 'Generated by `sphinx-examples-as-code '
62
+ '<https://github.com/pyvista/sphinx-examples-as-code>`_'
63
+ ),
64
+ }
65
+ ```
66
+
67
+ - `link_position`: where the download link(s) land within the Examples section. `'top'`
68
+ (default) or `'bottom'`.
69
+ - `formats`: which downloads to generate. A list containing `'py'`, `'ipynb'`, or both
70
+ (default). Always offered in that order regardless of how the list is written.
71
+ - `base_url`: the site's published base URL (e.g. `'https://docs.pyvista.org/'`), used
72
+ to turn cross-references into absolute links a downloaded, standalone file can
73
+ actually use. `None` (default) means no links are generated anywhere. A missing
74
+ trailing slash is added automatically; a value with no scheme or host raises a
75
+ configuration error at build start.
76
+ - `gallery_downloads`: opt-in takeover of
77
+ [sphinx-gallery](https://sphinx-gallery.github.io)'s own per-example downloads.
78
+ `False` (default) leaves sphinx-gallery pages untouched. See
79
+ [Sphinx-Gallery integration](#sphinx-gallery-integration) below.
80
+ - `footer`: a string appended to the end of every generated file. Defaults to a one-line
81
+ "generated file" credit linking back to this project; set to `None` to omit it
82
+ entirely. Preceded by a blank line and a `-`-only divider line, marking it as trailing
83
+ boilerplate rather than more of the example's own commentary -- the divider also
84
+ renders as a real horizontal rule in `.ipynb`, where the footer always gets its own
85
+ dedicated cell, regardless of what content precedes it. Parsed as RST, the same as any
86
+ other prose this extension handles: a hyperlink written as `` `text <url>`_ `` becomes
87
+ a real clickable Markdown link in `.ipynb`, and renders inline as `text url` in `.py`.
88
+ Plain text with no markup at all becomes one comment line per line of text, and
89
+ blank-line-separated paragraphs stay separated -- a longer, multi-paragraph custom
90
+ footer is laid out the same way any other prose in this extension is.
91
+
92
+ An unrecognized key (a typo, or a leftover from an older release) raises a configuration
93
+ error at build start rather than silently doing nothing.
94
+
95
+ Overriding a single key from the command line works via a dotted `-D` flag, e.g.
96
+ `-D sphinx_examples_as_code_conf.link_position=bottom` -- this only touches that one
97
+ key, leaving the rest (`conf.py`'s values, or the defaults) alone.
98
+
99
+ ## Conversion rules
100
+
101
+ What happens to the content of an Examples section:
102
+
103
+ - Doctest blocks (`>>> ...` / `... ...`) keep their input lines, prompts stripped, as
104
+ real Python source. Doctest *output* lines are dropped — only the input code matters.
105
+ - `.. code-block:: python` (or `py`) blocks are kept as-is; other languages become
106
+ comments, set off with blank lines on both sides like any other directive -- so a
107
+ preformatted block (e.g. an RST `::`-block illustrating a data format) still reads as
108
+ a distinct block rather than melting into the surrounding prose.
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 `base_url` 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 -- none of them are documentation content a downloaded,
125
+ standalone file has any use for.
126
+
127
+ Generated `.py` files start with a `# Examples from <qualified name>` title header
128
+ (gallery mode uses the page's own title instead -- see below) and follow a few
129
+ whitespace conventions so the result reads like normal Python: prose
130
+ directly above a code block stays attached to it, a code block is always followed by a
131
+ blank line, and a directive (header, `# NOTE:`-style block) gets blank lines on both
132
+ sides.
133
+
134
+ Generated `.ipynb` notebooks use the same content, split into alternating code/markdown
135
+ cells instead.
136
+
137
+ A download link is only added if the resulting code contains at least one real
138
+ executable statement.
139
+
140
+ ## Sphinx-Gallery integration
141
+
142
+ With `sphinx_examples_as_code_conf['gallery_downloads'] = True`, this extension takes
143
+ over the downloads on every page generated by
144
+ [sphinx-gallery](https://sphinx-gallery.github.io): the "Go to the end to download the
145
+ full example code" note and the `.py`/`.ipynb`/`.zip` download footer are removed from
146
+ the page, replaced with download link(s) built by this extension instead — same
147
+ conversion rules as above, applied to the whole page rather than one Examples section.
148
+ The generated file's header uses the page's own title (e.g. `# Create Circular Arcs`)
149
+ rather than the generic `# Examples from <docname>` — gallery mode converts the whole
150
+ page, not an Examples section carved out of a larger docstring, so there's no "from"
151
+ framing to make.
152
+
153
+ The "Total running time" line and the "Gallery generated by Sphinx-Gallery" credit line
154
+ stay on the rendered page untouched, but never make it into the generated download
155
+ itself: a "Total running time" sitting inside a file you just downloaded and ran
156
+ yourself would read like it's timing *your* run, not the build's, and a "Generated by
157
+ Sphinx-Gallery" credit is simply wrong inside a file this extension generated.
158
+
159
+ Detection is automatic and per-page — any page without a sphinx-gallery download footer
160
+ is left completely untouched, so turning this on is safe even on a site that mixes
161
+ gallery pages with ordinary docstring/prose pages using the Examples-section behavior
162
+ above.
163
+
164
+ A `# %%` cell with its own RST heading gets the same title-plus-underline treatment as
165
+ the file's own header, rather than melting into whatever prose follows it -- and for
166
+ that reason renders as a real Markdown heading in `.ipynb`, not just plain text.
167
+
168
+ Two things worth knowing before turning this on:
169
+
170
+ - It's built against sphinx-gallery's own long-standing RST/HTML output (the same
171
+ `sphx-glr-*` CSS classes its own theming depends on), not a documented extension API.
172
+ It's unlikely to change, but a future sphinx-gallery release could still shift that
173
+ structure without warning.
174
+ - sphinx-gallery registers its own `.py`/`.ipynb`/`.zip` downloads for copying into
175
+ `_downloads/` before this extension gets a chance to remove the links pointing to
176
+ them, so those files still end up in the build output even though nothing on the page
177
+ links to them anymore.
178
+
179
+ ## Development
180
+
181
+ ```bash
182
+ uv sync --group dev
183
+ uv run pytest
184
+ uv run pre-commit run --all-files
185
+ ```
@@ -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
+ 'base_url': None,
34
+ 'gallery_downloads': False,
35
+ 'footer': (
36
+ 'Generated by `sphinx-examples-as-code '
37
+ '<https://github.com/pyvista/sphinx-examples-as-code>`_'
38
+ ),
39
+ }
40
+ ```
41
+
42
+ - `link_position`: where the download link(s) land within the Examples section. `'top'`
43
+ (default) or `'bottom'`.
44
+ - `formats`: which downloads to generate. A list containing `'py'`, `'ipynb'`, or both
45
+ (default). Always offered in that order regardless of how the list is written.
46
+ - `base_url`: the site's published base URL (e.g. `'https://docs.pyvista.org/'`), used
47
+ to turn cross-references into absolute links a downloaded, standalone file can
48
+ actually use. `None` (default) means no links are generated anywhere. A missing
49
+ trailing slash is added automatically; a value with no scheme or host raises a
50
+ configuration error at build start.
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, marking it as trailing
58
+ boilerplate rather than more of the example's own commentary -- the divider also
59
+ renders as a real horizontal rule in `.ipynb`, where the footer always gets its own
60
+ dedicated cell, regardless of what content precedes it. Parsed as RST, the same as any
61
+ other prose this extension handles: a hyperlink written as `` `text <url>`_ `` becomes
62
+ a real clickable Markdown link in `.ipynb`, and renders inline as `text url` in `.py`.
63
+ Plain text with no markup at all becomes one comment line per line of text, and
64
+ blank-line-separated paragraphs stay separated -- a longer, multi-paragraph custom
65
+ footer is laid out the same way any other prose in this extension is.
66
+
67
+ An unrecognized key (a typo, or a leftover from an older release) raises a configuration
68
+ error at build start rather than silently doing nothing.
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 -- so a
82
+ preformatted block (e.g. an RST `::`-block illustrating a data format) still reads as
83
+ a distinct block rather than melting into the surrounding prose.
84
+ - Admonitions (`.. note::`, `.. warning::`, `.. seealso::`, ...) become a `# LABEL:`
85
+ comment followed by their content as comments. "See Also" is recognized in any of its
86
+ three forms (`.. seealso::`, a bare `.. rubric:: See Also`, or a hand-written `See
87
+ Also` heading) and always renders the same way.
88
+ - Cross-references and inline code (`:class:`, `:meth:`, `:func:`, `:attr:`,
89
+ double-backtick literals, ...) keep their display text, wrapped in backticks (e.g.
90
+ ``:class:`pyvista.Plotter` `` -> `` `pyvista.Plotter` ``). If `base_url` is set and
91
+ the reference resolves: `.ipynb` turns it into a clickable link everywhere; `.py` only
92
+ writes the link inside a "See Also" part (as `name url` on its own line) — everywhere
93
+ else in `.py` the link is simply omitted.
94
+ - Plain prose-style references (`:ref:`, `:doc:`) are treated the same way, minus the
95
+ backticks.
96
+ - Everything else text-bearing (prose, captions, other non-Python code) becomes a plain
97
+ `#` comment.
98
+ - Figures/images, raw HTML, sphinx-design dropdowns/tab-sets, and sphinx-tags' `.. tags::`
99
+ line are dropped entirely -- none of them are documentation content a downloaded,
100
+ standalone file has any use for.
101
+
102
+ Generated `.py` files start with a `# Examples from <qualified name>` title header
103
+ (gallery mode uses the page's own title instead -- see below) and follow a few
104
+ whitespace conventions so the result reads like normal Python: prose
105
+ directly above a code block stays attached to it, a code block is always followed by a
106
+ blank line, and a directive (header, `# NOTE:`-style block) gets blank lines on both
107
+ sides.
108
+
109
+ Generated `.ipynb` notebooks use the same content, split into alternating code/markdown
110
+ cells instead.
111
+
112
+ A download link is only added if the resulting code contains at least one real
113
+ executable statement.
114
+
115
+ ## Sphinx-Gallery integration
116
+
117
+ With `sphinx_examples_as_code_conf['gallery_downloads'] = True`, this extension takes
118
+ over the downloads on every page generated by
119
+ [sphinx-gallery](https://sphinx-gallery.github.io): the "Go to the end to download the
120
+ full example code" note and the `.py`/`.ipynb`/`.zip` download footer are removed from
121
+ the page, replaced with download link(s) built by this extension instead — same
122
+ conversion rules as above, applied to the whole page rather than one Examples section.
123
+ The generated file's header uses the page's own title (e.g. `# Create Circular Arcs`)
124
+ rather than the generic `# Examples from <docname>` — gallery mode converts the whole
125
+ page, not an Examples section carved out of a larger docstring, so there's no "from"
126
+ framing to make.
127
+
128
+ The "Total running time" line and the "Gallery generated by Sphinx-Gallery" credit line
129
+ stay on the rendered page untouched, but never make it into the generated download
130
+ itself: a "Total running time" sitting inside a file you just downloaded and ran
131
+ yourself would read like it's timing *your* run, not the build's, and a "Generated by
132
+ Sphinx-Gallery" credit is simply wrong inside a file this extension generated.
133
+
134
+ Detection is automatic and per-page — any page without a sphinx-gallery download footer
135
+ is left completely untouched, so turning this on is safe even on a site that mixes
136
+ gallery pages with ordinary docstring/prose pages using the Examples-section behavior
137
+ above.
138
+
139
+ A `# %%` cell with its own RST heading gets the same title-plus-underline treatment as
140
+ the file's own header, rather than melting into whatever prose follows it -- and for
141
+ that reason renders as a real Markdown heading in `.ipynb`, not just plain text.
142
+
143
+ Two things worth knowing before turning this on:
144
+
145
+ - It's built against sphinx-gallery's own long-standing RST/HTML output (the same
146
+ `sphx-glr-*` CSS classes its own theming depends on), not a documented extension API.
147
+ It's unlikely to change, but a future sphinx-gallery release could still shift that
148
+ structure without warning.
149
+ - sphinx-gallery registers its own `.py`/`.ipynb`/`.zip` downloads for copying into
150
+ `_downloads/` before this extension gets a chance to remove the links pointing to
151
+ them, so those files still end up in the build output even though nothing on the page
152
+ 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,9 @@ 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']
95
99
 
96
100
  [tool.ruff.lint.isort]
97
101
  combine-as-imports = true