sphinx-examples-as-code 0.4.1__tar.gz → 0.5.0__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.4.1 → sphinx_examples_as_code-0.5.0}/PKG-INFO +6 -17
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/README.md +5 -16
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/sphinx_examples_as_code/__init__.py +19 -86
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/sphinx_examples_as_code/_version.py +3 -3
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/sphinx_examples_as_code.egg-info/PKG-INFO +6 -17
- sphinx_examples_as_code-0.5.0/sphinx_examples_as_code.egg-info/scm_version.json +8 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/test_single_function_page.py +0 -34
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/test_sphinx_examples_as_code.py +18 -284
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/test_tinypages.py +23 -108
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/tinypages/docstring_cases.py +4 -6
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/tinypages/docstring_cases.rst +3 -3
- sphinx_examples_as_code-0.4.1/sphinx_examples_as_code.egg-info/scm_version.json +0 -8
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/.github/dependabot.yml +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/.github/release.yml +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/.github/workflows/ci.yml +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/.gitignore +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/.pre-commit-config.yaml +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/LICENSE +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/pyproject.toml +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/setup.cfg +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/sphinx_examples_as_code.egg-info/SOURCES.txt +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/sphinx_examples_as_code.egg-info/dependency_links.txt +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/sphinx_examples_as_code.egg-info/requires.txt +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/sphinx_examples_as_code.egg-info/scm_file_list.json +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/sphinx_examples_as_code.egg-info/top_level.txt +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/gallery_fixture/conf.py +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/gallery_fixture/examples/GALLERY_HEADER.rst +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/gallery_fixture/examples/plot_minimal.py +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/gallery_fixture/index.rst +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/heading_level_fixture/conf.py +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/heading_level_fixture/examples/GALLERY_HEADER.rst +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/heading_level_fixture/examples/plot_reused_level.py +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/heading_level_fixture/examples/plot_three_levels.py +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/heading_level_fixture/index.rst +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/single_function_fixture/conf.py +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/single_function_fixture/index.rst +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/single_function_fixture/mymodule.py +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/test_gallery_downloads.py +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/test_heading_level_reuse.py +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/tinypages/conf.py +0 -0
- {sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/tinypages/index.rst +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sphinx-examples-as-code
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Sphinx extension for converting docstring examples into downloadable code.
|
|
5
5
|
Author-email: The PyVista Developers <info@pyvista.org>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -66,7 +66,6 @@ sphinx_examples_as_code_conf = {
|
|
|
66
66
|
'py': 'Download Python source code',
|
|
67
67
|
'ipynb': 'Download Jupyter notebook',
|
|
68
68
|
},
|
|
69
|
-
'include_see_also': True,
|
|
70
69
|
}
|
|
71
70
|
```
|
|
72
71
|
|
|
@@ -76,13 +75,6 @@ sphinx_examples_as_code_conf = {
|
|
|
76
75
|
(default). Always offered in that order regardless of how the list is written.
|
|
77
76
|
- `link_labels`: the text of the download link(s) themselves, per format. Set only the
|
|
78
77
|
format(s) you want to change; any left unset keep reading their own default shown above.
|
|
79
|
-
- `include_see_also`: whether "See Also" content is included in the generated file.
|
|
80
|
-
`True` (default) includes it, in any of its forms: a `.. seealso::` admonition, a bare
|
|
81
|
-
`.. rubric:: See Also`, a hand-written `See Also` heading, or numpydoc's own "See Also"
|
|
82
|
-
field (including when it's been reordered outside the Examples section itself, or the
|
|
83
|
-
Examples section has been hoisted to a heading of its own — a setup some projects use to
|
|
84
|
-
get "Examples" listed in the page's own navigation). `False` excludes "See Also" content
|
|
85
|
-
in every one of those forms.
|
|
86
78
|
- `gallery_downloads`: opt-in takeover of
|
|
87
79
|
[sphinx-gallery](https://sphinx-gallery.github.io)'s own per-example downloads.
|
|
88
80
|
`False` (default) leaves sphinx-gallery pages untouched. See
|
|
@@ -114,11 +106,8 @@ What happens to the content of an Examples section:
|
|
|
114
106
|
real Python source. Doctest *output* lines are dropped — only the input code matters.
|
|
115
107
|
- `.. code-block:: python` (or `py`) blocks are kept as-is; other languages become
|
|
116
108
|
comments, set off with blank lines on both sides like any other directive.
|
|
117
|
-
- Admonitions (`.. note::`, `.. warning::`,
|
|
118
|
-
|
|
119
|
-
`.py` only. "See Also" is recognized in any of its three forms (`.. seealso::`, a bare
|
|
120
|
-
`.. rubric:: See Also`, or a hand-written `See Also` heading) and always renders the
|
|
121
|
-
same way.
|
|
109
|
+
- Admonitions (`.. note::`, `.. warning::`, ...) become a `# LABEL:` comment followed by
|
|
110
|
+
their content as comments, indented one level under the label in `.py` only.
|
|
122
111
|
- A bullet/numbered list becomes a `-`/`N.`-marked line per item, set off with a blank
|
|
123
112
|
line on both sides in either format — a bare `#` instead of a real blank line when
|
|
124
113
|
that falls inside an admonition or a definition's own body in `.py`, so the whole
|
|
@@ -128,15 +117,15 @@ What happens to the content of an Examples section:
|
|
|
128
117
|
- Cross-references and inline code (`:class:`, `:meth:`, `:func:`, `:attr:`,
|
|
129
118
|
double-backtick literals, ...) keep their display text, wrapped in backticks (e.g.
|
|
130
119
|
``:class:`pyvista.Plotter` `` -> `` `pyvista.Plotter` ``). If `html_baseurl` is set and
|
|
131
|
-
the reference resolves
|
|
132
|
-
|
|
133
|
-
else in `.py` the link is simply omitted.
|
|
120
|
+
the reference resolves, `.ipynb` turns it into a clickable link; `.py` never writes the
|
|
121
|
+
link, only the display text.
|
|
134
122
|
- Plain prose-style references (`:ref:`, `:doc:`) are treated the same way, minus the
|
|
135
123
|
backticks.
|
|
136
124
|
- Everything else text-bearing (prose, captions, other non-Python code) becomes a plain
|
|
137
125
|
`#` comment.
|
|
138
126
|
- Figures/images, raw HTML, sphinx-design dropdowns/tab-sets, and sphinx-tags' `.. tags::`
|
|
139
127
|
line are dropped entirely.
|
|
128
|
+
- "See Also" content is always dropped.
|
|
140
129
|
|
|
141
130
|
Generated `.py` files start with a `# Examples from <qualified name>` title header
|
|
142
131
|
(gallery mode uses the page's own title instead -- see below), with a few whitespace
|
|
@@ -39,7 +39,6 @@ sphinx_examples_as_code_conf = {
|
|
|
39
39
|
'py': 'Download Python source code',
|
|
40
40
|
'ipynb': 'Download Jupyter notebook',
|
|
41
41
|
},
|
|
42
|
-
'include_see_also': True,
|
|
43
42
|
}
|
|
44
43
|
```
|
|
45
44
|
|
|
@@ -49,13 +48,6 @@ sphinx_examples_as_code_conf = {
|
|
|
49
48
|
(default). Always offered in that order regardless of how the list is written.
|
|
50
49
|
- `link_labels`: the text of the download link(s) themselves, per format. Set only the
|
|
51
50
|
format(s) you want to change; any left unset keep reading their own default shown above.
|
|
52
|
-
- `include_see_also`: whether "See Also" content is included in the generated file.
|
|
53
|
-
`True` (default) includes it, in any of its forms: a `.. seealso::` admonition, a bare
|
|
54
|
-
`.. rubric:: See Also`, a hand-written `See Also` heading, or numpydoc's own "See Also"
|
|
55
|
-
field (including when it's been reordered outside the Examples section itself, or the
|
|
56
|
-
Examples section has been hoisted to a heading of its own — a setup some projects use to
|
|
57
|
-
get "Examples" listed in the page's own navigation). `False` excludes "See Also" content
|
|
58
|
-
in every one of those forms.
|
|
59
51
|
- `gallery_downloads`: opt-in takeover of
|
|
60
52
|
[sphinx-gallery](https://sphinx-gallery.github.io)'s own per-example downloads.
|
|
61
53
|
`False` (default) leaves sphinx-gallery pages untouched. See
|
|
@@ -87,11 +79,8 @@ What happens to the content of an Examples section:
|
|
|
87
79
|
real Python source. Doctest *output* lines are dropped — only the input code matters.
|
|
88
80
|
- `.. code-block:: python` (or `py`) blocks are kept as-is; other languages become
|
|
89
81
|
comments, set off with blank lines on both sides like any other directive.
|
|
90
|
-
- Admonitions (`.. note::`, `.. warning::`,
|
|
91
|
-
|
|
92
|
-
`.py` only. "See Also" is recognized in any of its three forms (`.. seealso::`, a bare
|
|
93
|
-
`.. rubric:: See Also`, or a hand-written `See Also` heading) and always renders the
|
|
94
|
-
same way.
|
|
82
|
+
- Admonitions (`.. note::`, `.. warning::`, ...) become a `# LABEL:` comment followed by
|
|
83
|
+
their content as comments, indented one level under the label in `.py` only.
|
|
95
84
|
- A bullet/numbered list becomes a `-`/`N.`-marked line per item, set off with a blank
|
|
96
85
|
line on both sides in either format — a bare `#` instead of a real blank line when
|
|
97
86
|
that falls inside an admonition or a definition's own body in `.py`, so the whole
|
|
@@ -101,15 +90,15 @@ What happens to the content of an Examples section:
|
|
|
101
90
|
- Cross-references and inline code (`:class:`, `:meth:`, `:func:`, `:attr:`,
|
|
102
91
|
double-backtick literals, ...) keep their display text, wrapped in backticks (e.g.
|
|
103
92
|
``:class:`pyvista.Plotter` `` -> `` `pyvista.Plotter` ``). If `html_baseurl` is set and
|
|
104
|
-
the reference resolves
|
|
105
|
-
|
|
106
|
-
else in `.py` the link is simply omitted.
|
|
93
|
+
the reference resolves, `.ipynb` turns it into a clickable link; `.py` never writes the
|
|
94
|
+
link, only the display text.
|
|
107
95
|
- Plain prose-style references (`:ref:`, `:doc:`) are treated the same way, minus the
|
|
108
96
|
backticks.
|
|
109
97
|
- Everything else text-bearing (prose, captions, other non-Python code) becomes a plain
|
|
110
98
|
`#` comment.
|
|
111
99
|
- Figures/images, raw HTML, sphinx-design dropdowns/tab-sets, and sphinx-tags' `.. tags::`
|
|
112
100
|
line are dropped entirely.
|
|
101
|
+
- "See Also" content is always dropped.
|
|
113
102
|
|
|
114
103
|
Generated `.py` files start with a `# Examples from <qualified name>` title header
|
|
115
104
|
(gallery mode uses the page's own title instead -- see below), with a few whitespace
|
{sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/sphinx_examples_as_code/__init__.py
RENAMED
|
@@ -7,7 +7,6 @@ from __future__ import annotations
|
|
|
7
7
|
|
|
8
8
|
import ast
|
|
9
9
|
from dataclasses import dataclass
|
|
10
|
-
from dataclasses import replace
|
|
11
10
|
import hashlib
|
|
12
11
|
import json
|
|
13
12
|
from pathlib import Path
|
|
@@ -154,9 +153,7 @@ class _RenderContext:
|
|
|
154
153
|
app: Sphinx
|
|
155
154
|
docname: str
|
|
156
155
|
fmt: str # 'py' or 'ipynb'
|
|
157
|
-
in_see_also: bool = False
|
|
158
156
|
in_footer: bool = False
|
|
159
|
-
show_see_also: bool = True
|
|
160
157
|
|
|
161
158
|
|
|
162
159
|
def _normalized_html_baseurl(app: Sphinx) -> str | None:
|
|
@@ -233,9 +230,8 @@ def _render_reference(node: nodes.reference, ctx: _RenderContext) -> str:
|
|
|
233
230
|
"""Render a resolved or unresolved cross-reference/hyperlink.
|
|
234
231
|
|
|
235
232
|
The target URL, if resolved, is used as a clickable markdown link in
|
|
236
|
-
notebooks (always), and as literal URL text in ``.py`` (only within
|
|
237
|
-
|
|
238
|
-
omitted).
|
|
233
|
+
notebooks (always), and as literal URL text in ``.py`` (only within the
|
|
234
|
+
footer -- elsewhere in ``.py`` the link is simply omitted).
|
|
239
235
|
"""
|
|
240
236
|
display = node.astext()
|
|
241
237
|
is_code = any(isinstance(child, nodes.literal) for child in node.children)
|
|
@@ -247,11 +243,6 @@ def _render_reference(node: nodes.reference, ctx: _RenderContext) -> str:
|
|
|
247
243
|
if ctx.fmt == 'ipynb':
|
|
248
244
|
return f'[`{display}`]({url})' if is_code else f'[{display}]({url})'
|
|
249
245
|
|
|
250
|
-
if ctx.in_see_also:
|
|
251
|
-
# Surrounding newlines set this off on its own line; _add_comment
|
|
252
|
-
# splits on them like any other multi-line text.
|
|
253
|
-
return f'\n{display} {url}\n'
|
|
254
|
-
|
|
255
246
|
if ctx.in_footer:
|
|
256
247
|
# Inline, not surrounded by newlines -- "text url" in place, not a
|
|
257
248
|
# markdown link.
|
|
@@ -487,12 +478,11 @@ def _convert_admonition(
|
|
|
487
478
|
node: nodes.Element, label: str, ctx: _RenderContext, *, skip_first_title: bool = False
|
|
488
479
|
) -> list[Segment]:
|
|
489
480
|
"""Convert an admonition-like container to a ``# LABEL:`` directive segment."""
|
|
490
|
-
inner_ctx = replace(ctx, in_see_also=True) if label.upper() == 'SEE ALSO' else ctx
|
|
491
481
|
inner: list[Segment] = [('text', [f'# {label}:'])]
|
|
492
482
|
for child in node.children:
|
|
493
483
|
if skip_first_title and isinstance(child, nodes.title):
|
|
494
484
|
continue
|
|
495
|
-
inner.extend(_convert_node(child,
|
|
485
|
+
inner.extend(_convert_node(child, ctx))
|
|
496
486
|
lines = _indent_label_content(_join_segments(inner), ctx.fmt)
|
|
497
487
|
return [('directive', lines)]
|
|
498
488
|
|
|
@@ -508,16 +498,17 @@ def _convert_node(node: nodes.Node, ctx: _RenderContext) -> list[Segment]:
|
|
|
508
498
|
if isinstance(node, nodes.literal_block):
|
|
509
499
|
return _convert_literal_block(node)
|
|
510
500
|
if type(node) in _ADMONITION_LABELS:
|
|
511
|
-
if _is_see_also_type(node)
|
|
501
|
+
if _is_see_also_type(node):
|
|
502
|
+
# "See Also" content is always dropped -- see _build_segments
|
|
503
|
+
# for the bare-rubric form and _is_see_also_section below for
|
|
504
|
+
# the hand-written-heading form.
|
|
512
505
|
return []
|
|
513
506
|
return _convert_admonition(node, _ADMONITION_LABELS[type(node)], ctx)
|
|
514
507
|
if _is_see_also_section(node):
|
|
515
508
|
# a hand-written "See Also\n--------" heading nests as a full
|
|
516
|
-
# section rather than a flat sibling -
|
|
517
|
-
#
|
|
518
|
-
|
|
519
|
-
return []
|
|
520
|
-
return _convert_admonition(node, 'SEE ALSO', ctx, skip_first_title=True)
|
|
509
|
+
# section rather than a flat sibling - dropped the same as any
|
|
510
|
+
# other "See Also" form.
|
|
511
|
+
return []
|
|
521
512
|
if isinstance(node, nodes.admonition):
|
|
522
513
|
# generic ``.. admonition:: Custom Title`` - use its own title as the label
|
|
523
514
|
title_node = node.next_node(nodes.title)
|
|
@@ -594,42 +585,6 @@ def _is_see_also_type(node: nodes.Node) -> bool:
|
|
|
594
585
|
return type(node) in _ADMONITION_LABELS and _ADMONITION_LABELS[type(node)] == 'SEE ALSO'
|
|
595
586
|
|
|
596
587
|
|
|
597
|
-
def _see_also_in_desc_content(desc: addnodes.desc) -> nodes.Node | None:
|
|
598
|
-
"""Find a "See Also" admonition-type node among a ``desc`` node's own ``desc_content``."""
|
|
599
|
-
content = next(
|
|
600
|
-
(child for child in desc.children if isinstance(child, addnodes.desc_content)), None
|
|
601
|
-
)
|
|
602
|
-
if content is None:
|
|
603
|
-
return None
|
|
604
|
-
return next((child for child in content.children if _is_see_also_type(child)), None)
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
def _find_external_see_also(
|
|
608
|
-
parent: nodes.Element, start: int, end: int, heading: nodes.Node
|
|
609
|
-
) -> nodes.Node | None:
|
|
610
|
-
"""Find a "See Also" part sited outside the normal ``[start, end)`` span.
|
|
611
|
-
|
|
612
|
-
numpydoc's own "See Also" field is canonically reordered to sit before
|
|
613
|
-
"Examples", as a sibling under ``parent``. If "Examples" was written as
|
|
614
|
-
a real RST heading and hoisted out of its own ``desc_content`` to page
|
|
615
|
-
level (see ``_enclosing_descs``), "See Also" -- not a ``nodes.section``,
|
|
616
|
-
so untouched by that hoisting -- stays behind there instead, in the
|
|
617
|
-
``desc_content`` of the one ``desc`` that used to contain this heading.
|
|
618
|
-
Only that nearest enclosing ``desc`` is checked -- not every one
|
|
619
|
-
``_enclosing_descs`` yields -- or a page listing several documented
|
|
620
|
-
objects in a row would leak one object's "See Also" onto another's.
|
|
621
|
-
"""
|
|
622
|
-
for i, child in enumerate(parent.children):
|
|
623
|
-
if start <= i < end:
|
|
624
|
-
continue
|
|
625
|
-
if _is_see_also_type(child):
|
|
626
|
-
return child
|
|
627
|
-
desc = next(_enclosing_descs(heading), None)
|
|
628
|
-
if desc is not None:
|
|
629
|
-
return _see_also_in_desc_content(desc)
|
|
630
|
-
return None
|
|
631
|
-
|
|
632
|
-
|
|
633
588
|
def _examples_spans(doctree: nodes.document) -> list[tuple[nodes.Element, int, int, nodes.Node]]:
|
|
634
589
|
"""Find every "Examples" heading's content span.
|
|
635
590
|
|
|
@@ -868,20 +823,14 @@ def _build_segments(nodes_in_span: list[nodes.Node], ctx: _RenderContext) -> lis
|
|
|
868
823
|
"""Convert a span's nodes into segments.
|
|
869
824
|
|
|
870
825
|
A bare ``.. rubric:: See Also`` heading isn't wrapped in a container the
|
|
871
|
-
way ``.. seealso::`` or a nested section are
|
|
872
|
-
|
|
826
|
+
way ``.. seealso::`` or a nested section are, so everything after it is
|
|
827
|
+
just as much "See Also" content as the heading itself, with no node of
|
|
828
|
+
its own marking where it ends -- dropping the heading and stopping
|
|
829
|
+
there drops all of it.
|
|
873
830
|
"""
|
|
874
831
|
segments: list[Segment] = []
|
|
875
|
-
for
|
|
832
|
+
for node in nodes_in_span:
|
|
876
833
|
if isinstance(node, nodes.rubric) and _is_see_also_heading(node):
|
|
877
|
-
if not ctx.show_see_also:
|
|
878
|
-
break
|
|
879
|
-
inner_ctx = replace(ctx, in_see_also=True)
|
|
880
|
-
inner: list[Segment] = [('text', ['# SEE ALSO:'])]
|
|
881
|
-
for later_node in nodes_in_span[i + 1 :]:
|
|
882
|
-
inner.extend(_convert_node(later_node, inner_ctx))
|
|
883
|
-
lines = _indent_label_content(_join_segments(inner), ctx.fmt)
|
|
884
|
-
segments.append(('directive', lines))
|
|
885
834
|
break
|
|
886
835
|
segments.extend(_convert_node(node, ctx))
|
|
887
836
|
return segments
|
|
@@ -896,7 +845,6 @@ def _build_download_entries(
|
|
|
896
845
|
formats: list[str],
|
|
897
846
|
footer: str | None,
|
|
898
847
|
link_labels: dict[str, str],
|
|
899
|
-
include_see_also: bool,
|
|
900
848
|
) -> list[tuple[str, str]]:
|
|
901
849
|
"""Convert a span of nodes into written ``.py``/``.ipynb`` files, per ``formats``.
|
|
902
850
|
|
|
@@ -909,7 +857,7 @@ def _build_download_entries(
|
|
|
909
857
|
file's own header is the one heading every generated file has exactly
|
|
910
858
|
one of (see ``_title_underline_segment``).
|
|
911
859
|
"""
|
|
912
|
-
py_ctx = _RenderContext(app=app, docname=docname, fmt='py'
|
|
860
|
+
py_ctx = _RenderContext(app=app, docname=docname, fmt='py')
|
|
913
861
|
py_segments = _build_segments(nodes_in_span, py_ctx)
|
|
914
862
|
|
|
915
863
|
if not any(kind == 'code' for kind, _lines in py_segments):
|
|
@@ -930,9 +878,7 @@ def _build_download_entries(
|
|
|
930
878
|
if fmt == 'py':
|
|
931
879
|
rel_path = _write_source(app, name, source)
|
|
932
880
|
else:
|
|
933
|
-
ipynb_ctx = _RenderContext(
|
|
934
|
-
app=app, docname=docname, fmt='ipynb', show_see_also=include_see_also
|
|
935
|
-
)
|
|
881
|
+
ipynb_ctx = _RenderContext(app=app, docname=docname, fmt='ipynb')
|
|
936
882
|
ipynb_segments = _build_segments(nodes_in_span, ipynb_ctx)
|
|
937
883
|
ipynb_header = _title_underline_segment(header_title, 1, 'ipynb')
|
|
938
884
|
# Converted separately from the footer and concatenated, rather
|
|
@@ -958,14 +904,9 @@ def _process_span(
|
|
|
958
904
|
formats: list[str],
|
|
959
905
|
footer: str | None,
|
|
960
906
|
link_labels: dict[str, str],
|
|
961
|
-
include_see_also: bool,
|
|
962
907
|
) -> None:
|
|
963
908
|
"""Convert one Examples span and insert download link(s) if it has real code."""
|
|
964
909
|
nodes_in_span = list(parent.children[start:end])
|
|
965
|
-
if include_see_also:
|
|
966
|
-
external_see_also = _find_external_see_also(parent, start, end, heading)
|
|
967
|
-
if external_see_also is not None:
|
|
968
|
-
nodes_in_span.append(external_see_also)
|
|
969
910
|
|
|
970
911
|
name = _qualified_name_for(heading, docname, counter)
|
|
971
912
|
entries = _build_download_entries(
|
|
@@ -977,7 +918,6 @@ def _process_span(
|
|
|
977
918
|
formats,
|
|
978
919
|
footer,
|
|
979
920
|
link_labels,
|
|
980
|
-
include_see_also,
|
|
981
921
|
)
|
|
982
922
|
if not entries:
|
|
983
923
|
return
|
|
@@ -1058,7 +998,6 @@ def _process_gallery_page(
|
|
|
1058
998
|
formats: list[str],
|
|
1059
999
|
footer: str | None,
|
|
1060
1000
|
link_labels: dict[str, str],
|
|
1061
|
-
include_see_also: bool,
|
|
1062
1001
|
) -> None:
|
|
1063
1002
|
"""Replace a sphinx-gallery page's own download footer with converted downloads.
|
|
1064
1003
|
|
|
@@ -1101,7 +1040,6 @@ def _process_gallery_page(
|
|
|
1101
1040
|
formats,
|
|
1102
1041
|
footer,
|
|
1103
1042
|
link_labels,
|
|
1104
|
-
include_see_also,
|
|
1105
1043
|
)
|
|
1106
1044
|
if not entries:
|
|
1107
1045
|
return
|
|
@@ -1127,12 +1065,9 @@ def _process_doctree(app: Sphinx, doctree: nodes.document, docname: str) -> None
|
|
|
1127
1065
|
formats = conf['formats']
|
|
1128
1066
|
footer = conf['footer']
|
|
1129
1067
|
link_labels = conf['link_labels']
|
|
1130
|
-
include_see_also = conf['include_see_also']
|
|
1131
1068
|
|
|
1132
1069
|
if conf['gallery_downloads']:
|
|
1133
|
-
_process_gallery_page(
|
|
1134
|
-
app, docname, doctree, position, formats, footer, link_labels, include_see_also
|
|
1135
|
-
)
|
|
1070
|
+
_process_gallery_page(app, docname, doctree, position, formats, footer, link_labels)
|
|
1136
1071
|
|
|
1137
1072
|
# Process spans per shared parent, last to first.
|
|
1138
1073
|
spans = _examples_spans(doctree)
|
|
@@ -1152,7 +1087,6 @@ def _process_doctree(app: Sphinx, doctree: nodes.document, docname: str) -> None
|
|
|
1152
1087
|
formats,
|
|
1153
1088
|
footer,
|
|
1154
1089
|
link_labels,
|
|
1155
|
-
include_see_also,
|
|
1156
1090
|
)
|
|
1157
1091
|
|
|
1158
1092
|
|
|
@@ -1170,7 +1104,6 @@ _CONF_DEFAULTS: dict[str, object] = {
|
|
|
1170
1104
|
'gallery_downloads': False,
|
|
1171
1105
|
'footer': _DEFAULT_FOOTER,
|
|
1172
1106
|
'link_labels': _DEFAULT_LINK_LABELS,
|
|
1173
|
-
'include_see_also': True,
|
|
1174
1107
|
}
|
|
1175
1108
|
|
|
1176
1109
|
|
|
@@ -1188,7 +1121,7 @@ def _coerce_conf_value(key: str, value: object) -> object:
|
|
|
1188
1121
|
return value
|
|
1189
1122
|
if key == 'formats':
|
|
1190
1123
|
return value.split(',')
|
|
1191
|
-
if key
|
|
1124
|
+
if key == 'gallery_downloads':
|
|
1192
1125
|
if value == '0':
|
|
1193
1126
|
return False
|
|
1194
1127
|
if value == '1':
|
{sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/sphinx_examples_as_code/_version.py
RENAMED
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.
|
|
22
|
-
__version_tuple__ = version_tuple = (0,
|
|
21
|
+
__version__ = version = '0.5.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 5, 0)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'g7bd70a33e'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sphinx-examples-as-code
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Sphinx extension for converting docstring examples into downloadable code.
|
|
5
5
|
Author-email: The PyVista Developers <info@pyvista.org>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -66,7 +66,6 @@ sphinx_examples_as_code_conf = {
|
|
|
66
66
|
'py': 'Download Python source code',
|
|
67
67
|
'ipynb': 'Download Jupyter notebook',
|
|
68
68
|
},
|
|
69
|
-
'include_see_also': True,
|
|
70
69
|
}
|
|
71
70
|
```
|
|
72
71
|
|
|
@@ -76,13 +75,6 @@ sphinx_examples_as_code_conf = {
|
|
|
76
75
|
(default). Always offered in that order regardless of how the list is written.
|
|
77
76
|
- `link_labels`: the text of the download link(s) themselves, per format. Set only the
|
|
78
77
|
format(s) you want to change; any left unset keep reading their own default shown above.
|
|
79
|
-
- `include_see_also`: whether "See Also" content is included in the generated file.
|
|
80
|
-
`True` (default) includes it, in any of its forms: a `.. seealso::` admonition, a bare
|
|
81
|
-
`.. rubric:: See Also`, a hand-written `See Also` heading, or numpydoc's own "See Also"
|
|
82
|
-
field (including when it's been reordered outside the Examples section itself, or the
|
|
83
|
-
Examples section has been hoisted to a heading of its own — a setup some projects use to
|
|
84
|
-
get "Examples" listed in the page's own navigation). `False` excludes "See Also" content
|
|
85
|
-
in every one of those forms.
|
|
86
78
|
- `gallery_downloads`: opt-in takeover of
|
|
87
79
|
[sphinx-gallery](https://sphinx-gallery.github.io)'s own per-example downloads.
|
|
88
80
|
`False` (default) leaves sphinx-gallery pages untouched. See
|
|
@@ -114,11 +106,8 @@ What happens to the content of an Examples section:
|
|
|
114
106
|
real Python source. Doctest *output* lines are dropped — only the input code matters.
|
|
115
107
|
- `.. code-block:: python` (or `py`) blocks are kept as-is; other languages become
|
|
116
108
|
comments, set off with blank lines on both sides like any other directive.
|
|
117
|
-
- Admonitions (`.. note::`, `.. warning::`,
|
|
118
|
-
|
|
119
|
-
`.py` only. "See Also" is recognized in any of its three forms (`.. seealso::`, a bare
|
|
120
|
-
`.. rubric:: See Also`, or a hand-written `See Also` heading) and always renders the
|
|
121
|
-
same way.
|
|
109
|
+
- Admonitions (`.. note::`, `.. warning::`, ...) become a `# LABEL:` comment followed by
|
|
110
|
+
their content as comments, indented one level under the label in `.py` only.
|
|
122
111
|
- A bullet/numbered list becomes a `-`/`N.`-marked line per item, set off with a blank
|
|
123
112
|
line on both sides in either format — a bare `#` instead of a real blank line when
|
|
124
113
|
that falls inside an admonition or a definition's own body in `.py`, so the whole
|
|
@@ -128,15 +117,15 @@ What happens to the content of an Examples section:
|
|
|
128
117
|
- Cross-references and inline code (`:class:`, `:meth:`, `:func:`, `:attr:`,
|
|
129
118
|
double-backtick literals, ...) keep their display text, wrapped in backticks (e.g.
|
|
130
119
|
``:class:`pyvista.Plotter` `` -> `` `pyvista.Plotter` ``). If `html_baseurl` is set and
|
|
131
|
-
the reference resolves
|
|
132
|
-
|
|
133
|
-
else in `.py` the link is simply omitted.
|
|
120
|
+
the reference resolves, `.ipynb` turns it into a clickable link; `.py` never writes the
|
|
121
|
+
link, only the display text.
|
|
134
122
|
- Plain prose-style references (`:ref:`, `:doc:`) are treated the same way, minus the
|
|
135
123
|
backticks.
|
|
136
124
|
- Everything else text-bearing (prose, captions, other non-Python code) becomes a plain
|
|
137
125
|
`#` comment.
|
|
138
126
|
- Figures/images, raw HTML, sphinx-design dropdowns/tab-sets, and sphinx-tags' `.. tags::`
|
|
139
127
|
line are dropped entirely.
|
|
128
|
+
- "See Also" content is always dropped.
|
|
140
129
|
|
|
141
130
|
Generated `.py` files start with a `# Examples from <qualified name>` title header
|
|
142
131
|
(gallery mode uses the page's own title instead -- see below), with a few whitespace
|
{sphinx_examples_as_code-0.4.1 → sphinx_examples_as_code-0.5.0}/tests/test_single_function_page.py
RENAMED
|
@@ -38,37 +38,3 @@ def test_download_named_after_the_function_not_the_docname(tmp_path: Path):
|
|
|
38
38
|
|
|
39
39
|
lines = py_path.read_text(encoding='utf-8').splitlines()
|
|
40
40
|
assert lines[0] == '# Examples from mymodule.download_bunny'
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def test_hoisted_see_also_field_included_by_default(tmp_path: Path):
|
|
44
|
-
# numpydoc's own "See Also" field is never itself a section, so the
|
|
45
|
-
# hoisting that moves "Examples" out to page level (see conf.py) leaves
|
|
46
|
-
# "See Also" behind in the object's own desc_content -- orphaned from
|
|
47
|
-
# the heading unless _find_external_see_also looks there too.
|
|
48
|
-
html_dir = tmp_path / 'html'
|
|
49
|
-
doctree_dir = tmp_path / 'doctrees'
|
|
50
|
-
returncode, out, err = _run_sphinx_build(_sphinx_build_cmd(FIXTURE_DIR, html_dir, doctree_dir))
|
|
51
|
-
assert returncode == 0, f'sphinx build failed with stdout:\n{out}\nstderr:\n{err}\n'
|
|
52
|
-
|
|
53
|
-
py_path = next((html_dir / '_downloads').rglob('*.py'))
|
|
54
|
-
content = py_path.read_text(encoding='utf-8')
|
|
55
|
-
assert '# SEE ALSO:' in content
|
|
56
|
-
assert 'Download bunny dataset.' in content.split('# SEE ALSO:')[1]
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def test_hoisted_see_also_field_excluded_when_disabled(tmp_path: Path):
|
|
60
|
-
html_dir = tmp_path / 'html'
|
|
61
|
-
doctree_dir = tmp_path / 'doctrees'
|
|
62
|
-
returncode, out, err = _run_sphinx_build(
|
|
63
|
-
_sphinx_build_cmd(
|
|
64
|
-
FIXTURE_DIR,
|
|
65
|
-
html_dir,
|
|
66
|
-
doctree_dir,
|
|
67
|
-
('-D', 'sphinx_examples_as_code_conf.include_see_also=0'),
|
|
68
|
-
),
|
|
69
|
-
)
|
|
70
|
-
assert returncode == 0, f'sphinx build failed with stdout:\n{out}\nstderr:\n{err}\n'
|
|
71
|
-
|
|
72
|
-
py_path = next((html_dir / '_downloads').rglob('*.py'))
|
|
73
|
-
content = py_path.read_text(encoding='utf-8')
|
|
74
|
-
assert '# SEE ALSO:' not in content
|