-
Notifications
You must be signed in to change notification settings - Fork 27
Improve TryExamples customization #129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
.try_examples_button { | ||
background-color: #f7dc1e; | ||
border: none; | ||
padding: 5px 10px; | ||
border-radius: 15px; | ||
font-family: vibur; | ||
font-size: larger; | ||
box-shadow: 0 2px 5px rgba(108,108,108,0.2); | ||
} | ||
|
||
.try_examples_button:hover { | ||
background-color: #fff221; | ||
transform: scale(1.02); | ||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); | ||
cursor: pointer; | ||
} | ||
|
||
.try_examples_button_container { | ||
display: flex; | ||
justify-content: flex-end; | ||
} | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,4 +28,7 @@ | |
] | ||
} | ||
|
||
html_static_path = ["_static"] | ||
html_css_files = ["try_examples.css"] | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
suppress_warnings = ["myst.xref_missing"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,28 @@ | ||
# TryExamples directive | ||
|
||
`jupyterlite-sphinx` provides the experimental `try_examples` directive which allows | ||
docstring examples sections written in [doctestformat](https://docs.python.org/3/library/doctest.html) to be swapped with an embedded classic Notebook at the push of a button. | ||
docstring examples sections written in [doctest format](https://docs.python.org/3/library/doctest.html) to be swapped with an embedded classic Notebook at the push of a button. | ||
|
||
Below is an example of the directive in use. The button has been styled with custom | ||
css as explained in the configuration section below. Without custom css, the button will | ||
be plain and unadorned. | ||
|
||
|
||
```rst | ||
Examples | ||
-------- | ||
.. try_examples:: | ||
:button_css: | ||
background-color: #f7dc1e; | ||
border: none; | ||
padding: 5px 10px; | ||
border-radius: 15px; | ||
font-family: vibur; | ||
font-size: x-large; | ||
box-shadow: 0 2px 5px rgba(108,108,108,0.2); | ||
:button_hover_css: | ||
background-color: #fff221; | ||
transform: scale(1.02); | ||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); | ||
cursor: pointer; | ||
:button_horizontal_position: right | ||
:button_vertical_position: top | ||
:button_text: Try it in a classic notebook! | ||
:min_height: 200px | ||
|
||
|
||
Doctest examples sections are parsed and converted to notebooks. Blocks of text | ||
like this become markdown cells. Codeblocks begin with `>>>`. Contiguous blocks | ||
like this become markdown cells. Codeblocks begin with ``>>>``. Contiguous blocks | ||
of code are combined into a single code cell. | ||
|
||
>>> x = 2 | ||
>>> y = 2 | ||
>>> x + y | ||
4 | ||
|
||
`...` is used to continue multiline statements. | ||
``...`` is used to continue multiline statements. | ||
|
||
>>> def f(x, y): | ||
... return x + y | ||
|
@@ -54,28 +40,13 @@ Examples | |
markdown format. | ||
``` | ||
|
||
and here is how this looks and works when rendered. | ||
|
||
|
||
```{eval-rst} | ||
Examples | ||
-------- | ||
.. try_examples:: | ||
:button_css: | ||
background-color: #f7dc1e; | ||
border: none; | ||
padding: 5px 10px; | ||
border-radius: 15px; | ||
font-family: vibur; | ||
font-size: x-large; | ||
box-shadow: 0 2px 5px rgba(108,108,108,0.2); | ||
:button_hover_css: | ||
background-color: #fff221; | ||
transform: scale(1.02); | ||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); | ||
cursor: pointer; | ||
:button_horizontal_position: right | ||
:button_vertical_position: top | ||
:button_text: Try it in a classic notebook! | ||
:min_height: 200px | ||
|
||
Doctest examples sections are parsed and converted to notebooks. Blocks of text | ||
like this become markdown cells. Codeblocks begin with `>>>`. Contiguous blocks | ||
|
@@ -104,75 +75,144 @@ Examples | |
markdown format. | ||
``` | ||
|
||
By default, the height of the embedded notebook's iframe container is calculated to match the height of the rendered doctest examples so that it takes up the same amount of space on the | ||
page. | ||
|
||
## Configuration | ||
|
||
The button's text, position, and style can be configured to match your page design. The | ||
text can be configured with the option `:button_text:`. The options `:button_css:` and | ||
`:button_hover_css:` take lists of css properties as in the example above, and | ||
apply them to the button. `:button_horizontal_position:` can be one of `left`, `right`, or | ||
`center` and `:button_vertical_position:` can be one of `top` or `bottom`. The position | ||
is with respect to the rendered examples block / embedded notebook | ||
(depending on which is active). | ||
The position and style of the button can be customized to match your documentation's | ||
design by adding custom css as explained in Sphinx's documentation [here](https://docs.readthedocs.io/en/stable/guides/adding-custom-css.html#how-to-add-custom-css-or-javascript-to-sphinx-documentation). The buttons have class `try_examples_button`. The buttons are placed within | ||
containers with class `try_examples_button_container`, which can be selected to adjust the | ||
positioning of the button. The css for the example above is | ||
|
||
```css | ||
|
||
.try_examples_button { | ||
color: white; | ||
background-color: #0054a6; | ||
border: none; | ||
padding: 5px 10px; | ||
border-radius: 10px; | ||
margin-bottom: 5px; | ||
box-shadow: 0 2px 5px rgba(108,108,108,0.2); | ||
} | ||
|
||
.try_examples_button:hover { | ||
background-color: #0066cc; | ||
transform: scale(1.02); | ||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); | ||
cursor: pointer; | ||
} | ||
|
||
.try_examples_button_container { | ||
display: flex; | ||
justify-content: flex-end; | ||
} | ||
``` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
|
||
The height of the embedded notebook's iframe container is calculated to match the height | ||
of the rendered doctest examples so that it takes up the same amount of space on the | ||
page. The `:min_height:` option can be used to ensure that the embedded notebook will not | ||
be unuseably small for very short examples blocks, though its use can cause the contents | ||
of the page to shift when the button is pressed. | ||
|
||
the `:theme:` option available for other `jupyterlite-sphinx` directives is also | ||
available. | ||
The `try_examples` directive has options | ||
* `:height:` To set a specific value for the height of the [iframe](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) containing the embeddednotebook. | ||
* `:button_text` To customize the text of the button that replaces the rendered examples with an embedded notebook. | ||
* `:theme:` This works the same as for the other JupyterLite-Sphinx directives. | ||
* `:example_class:` An html class to attach to the outer container for the rendered | ||
examples content and embedded notebook. This can be used in a custom css file to allow | ||
for more precise customization, eg. different button styles across different examples. | ||
|
||
If you are using [sphinx.ext.autodoc](https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html) with [numpydoc](https://numpydoc.readthedocs.io/en/latest/format.html) or [sphinx.ext.napoleon](https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html), you | ||
can set the option | ||
Here's an example with some options set | ||
|
||
```rst | ||
.. try_examples:: | ||
:button_text: Try it in your browser! | ||
:height: 400px | ||
|
||
The button text has changed and the height now exceeds the size of the content. | ||
|
||
>>> x = 2 | ||
>>> y = 2 | ||
>>> x + y | ||
4 | ||
|
||
``` | ||
|
||
and here is the result | ||
|
||
```{eval-rst} | ||
.. try_examples:: | ||
:button_text: Try it in your browser! | ||
:height: 400px | ||
|
||
The button text has changed and the height now exceeds the size of the content. | ||
|
||
>>> x = 2 | ||
>>> y = 2 | ||
>>> x + y | ||
4 | ||
|
||
```python | ||
global_enable_try_examples = True | ||
``` | ||
|
||
in your sphinx `conf.py` in order to automatically insert the `try_examples` directive | ||
in examples sections during the `"autodoc-process-docstring"` event. Configuration values | ||
can be set globally for the inserted `try_examples` directives by setting the config values | ||
`try_examples_global_button_css`, etc. as below. All valid config values are supported | ||
by prepending `try_examples_global_`. | ||
|
||
### Global Configuration | ||
|
||
For projects with a large number of existing doctest examples, it would be tedious to add | ||
the `try_examples` directive manually to each docstring example. If you are using [sphinx.ext.autodoc](https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html) with either [numpydoc](https://numpydoc.readthedocs.io/en/latest/format.html) or [sphinx.ext.napoleon](https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html), you | ||
can set the option. | ||
|
||
```python | ||
global_enable_try_examples = True | ||
try_examples_global_button_css = """ | ||
color: white; | ||
background-color: #0054a6; | ||
border: none; | ||
padding: 5px 10px; | ||
border-radius: 5px; | ||
cursor: pointer; | ||
""" | ||
try_examples_global_button_hover_css = """ | ||
background-color: #0066cc; | ||
transform: scale(1.02); | ||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); | ||
""" | ||
|
||
try_examples_global_button_text = "Try it in your browser!" | ||
try_examples_global_min_height = "200px" | ||
``` | ||
|
||
in your sphinx `conf.py` in order to automatically insert the `try_examples` directive | ||
in examples sections during the `"autodoc-process-docstring"` event. This works by | ||
identifying section headings. An examples section includes all of the content beneath | ||
an examples heading, and up to either the next heading or the end of the docstring if | ||
there are no further headings. One of `numpydoc` or `sphinx.ext.napoleon` is required | ||
because these map the section headers to a standardized format. | ||
|
||
If an examples section already contains a `try_examples` directive, no additional | ||
directives will be inserted, allowing for specific cases to be separately configured | ||
if needed. Adding the comment `..! disable_try_examples` as the first non-empty line under | ||
if needed. Adding the comment | ||
|
||
|
||
```rst | ||
..! disable_try_examples` | ||
``` | ||
|
||
as the first non-empty line under | ||
the section header for an examples section will prevent a directive from being inserted, | ||
allowing for specification of examples sections which should not be made interactive. | ||
|
||
## Other considerations | ||
If you are using the `TryExamples` directive in your documentation, you'll need to ensure | ||
that the version of the package installed in the Jupyterlite kernel you are using | ||
matches that of the version you are documenting. | ||
|
||
## Configuration without rebuilding | ||
The button text and theme can be set globally with the config variables | ||
`try_examples_global_button_text`, and `try_examples_global_theme`. | ||
|
||
```python | ||
global_enable_try_examples = True | ||
try_examples_global_button_text = "Try it in your browser!" | ||
try_examples_global_height = "200px" | ||
``` | ||
|
||
There is no option to set a global specific height because the proper height | ||
should depend on the size of the examples content. Again, the default height of | ||
the embedded notebook's iframe container matches the height of the associated | ||
rendered doctest example so that it takes up the same amount of space on the | ||
page. For very small examples this may lead to an unusably small notebook. It's possible | ||
to set a global minimum height in the `try_examples.json` configuration file described | ||
below. | ||
|
||
### try_examples.json configuration file. | ||
|
||
Users may place a configuration file `try_examples.json` in the source root of | ||
their documentation. This configuration file will be copied to the build root of | ||
the deployed documentation. Changes to the configuration file in the build root | ||
will be respected without rebuilding the documentation, allowing for runtime | ||
configuration. | ||
|
||
The `TryExamples` directive supports disabling interactive examples without rebuilding | ||
the documentation. This can be helpful for projects requiring substantial documentation | ||
build time. Users may add a json config file entitled `.try_examples.json` to the root | ||
directory of the build directory for the deployed documentation. The format is a list of | ||
The current options are | ||
|
||
#### "ignore_patterns" | ||
|
||
The format is a list of | ||
[JavaScript Regex patterns](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions) attached to the key `"ignore_patterns"` like below. | ||
|
||
```json | ||
|
@@ -184,23 +224,38 @@ directory of the build directory for the deployed documentation. The format is a | |
`TryExamples` buttons will be hidden in url pathnames matching at least one of these | ||
patterns, effectively disabling the interactive documentation. In the provided example: | ||
|
||
* The pattern `".*latest/.*" disables interactive examples for urls for the documentation | ||
* The pattern `"^/latest/.*"` disables interactive examples for urls for the documentation | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good catch. |
||
for the latest version of the package, which may be useful if this documentation is | ||
for a development version for which a corresponding package build is not available | ||
in a Jupyterlite kernel. | ||
|
||
* The pattern `".*stable/reference/generated/example.html"` targets a particular url | ||
* The pattern `"^/stable/reference/generated/example.html"` targets a particular url | ||
in the documentation for the latest stable release. | ||
|
||
Note that these patterns should match the [pathname](https://developer.mozilla.org/en-US/docs/Web/API/Location/pathname) of the url, not the full url. This is the path portion of | ||
the url. For instance, the pathname of https://jupyterlite-sphinx.readthedocs.io/en/latest/directives/try_examples.html is `/en/latest/directives/try_examples.html`. | ||
|
||
Again, the configuration file can be added or edited within the deployed documentation, | ||
allowing for disabling or enabling examples without rebuilding the documentation. | ||
|
||
A default configuration file can be specified in `conf.py` with the option | ||
`try_examples_default_runtime_config`. | ||
#### "global_min_height" | ||
To avoid having unusably small notebooks for very small examples due to the default of | ||
having the embedded notebooks' iframe containers take the same amount of space as the | ||
rendered content they replace, users can set a global minimum height in | ||
`try_examples.json`. | ||
|
||
```python | ||
try_examples_default_runtime_config = { | ||
"ignore_patterns": ["^/latest/.*", "^/stable/reference/generated/example.html"] | ||
```json | ||
{ | ||
"global_min_height": "400px" | ||
} | ||
``` | ||
|
||
This allows the minimum height to be set or changed without rebuilding the docs. This | ||
configuration value will be ignored when a specific height is supplied as an option to | ||
`.. try_examples::`. | ||
|
||
|
||
## Other considerations | ||
If you are using the `TryExamples` directive in your documentation, you'll need to ensure | ||
that the version of the package installed in the Jupyterlite kernel you are using | ||
matches that of the version you are documenting. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Thanks for your patience on the review, I'm just back from PTO.