diff --git a/docs/directives/try_examples.md b/docs/directives/try_examples.md index 271102bb..f5cdb825 100644 --- a/docs/directives/try_examples.md +++ b/docs/directives/try_examples.md @@ -118,6 +118,7 @@ The `try_examples` directive has options * `: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. +* `:warning_text:` Prepend a markdown cell to the notebook containing this text, styled to make it clear this is intended as a warning. Here's an example with some options set @@ -126,6 +127,7 @@ Here's an example with some options set :button_text: Try it in your browser! :height: 400px :example_class: blue-bottom + :warning_text: Interactive examples are experimental and may not always work as expected. The button text has changed and the height now exceeds the size of the content. @@ -148,6 +150,7 @@ and here is the result :button_text: Try it in your browser! :height: 400px :example_class: blue-bottom + :warning_text: Interactive examples are experimental and may not always work as expected. The button text has changed and the height now exceeds the size of the content. @@ -195,13 +198,14 @@ the section header for an examples section will prevent a directive from being i allowing for specification of examples sections which should not be made interactive. -The button text and theme can be set globally with the config variables -`try_examples_global_button_text`, and `try_examples_global_theme`. +The button text, theme, and warning text can be set globally with the config variables +`try_examples_global_button_text`, `try_examples_global_theme`, and `try_examples_global_warning_text`. ```python global_enable_try_examples = True try_examples_global_button_text = "Try it in your browser!" try_examples_global_height = "200px" +try_examples_global_warning_text = "Interactive examples are experimental and may not always work as expected." ``` There is no option to set a global specific height because the proper height diff --git a/jupyterlite_sphinx/_try_examples.py b/jupyterlite_sphinx/_try_examples.py index 01774a6c..bbd3f78f 100755 --- a/jupyterlite_sphinx/_try_examples.py +++ b/jupyterlite_sphinx/_try_examples.py @@ -3,13 +3,17 @@ import re -def examples_to_notebook(input_lines): +def examples_to_notebook(input_lines, *, warning_text=None): """Parse examples section of a docstring and convert to Jupyter notebook. Parameters ---------- input_lines : iterable of str. - Lines within + + warning_text : str[Optional] + If given, add a markdown cell at the top of the generated notebook + containing the given text. The cell will be styled to indicate that + this is a warning. Returns ------- @@ -44,6 +48,12 @@ def examples_to_notebook(input_lines): """ nb = nbf.v4.new_notebook() + if warning_text is not None: + # Two newlines \n\n signal that the inner content should be parsed as + # markdown. + warning = f"
\n\n{warning_text}\n\n
" + nb.cells.append(new_markdown_cell(warning)) + code_lines = [] md_lines = [] output_lines = [] diff --git a/jupyterlite_sphinx/jupyterlite_sphinx.py b/jupyterlite_sphinx/jupyterlite_sphinx.py index b4f0e3ee..a437f816 100644 --- a/jupyterlite_sphinx/jupyterlite_sphinx.py +++ b/jupyterlite_sphinx/jupyterlite_sphinx.py @@ -368,6 +368,7 @@ class TryExamplesDirective(SphinxDirective): "theme": directives.unchanged, "button_text": directives.unchanged, "example_class": directives.unchanged, + "warning_text": directives.unchanged, } def run(self): @@ -382,6 +383,7 @@ def run(self): button_text = self.options.pop("button_text", "Try it with Jupyterlite!") height = self.options.pop("height", None) example_class = self.options.pop("example_class", "") + warning_text = self.options.pop("warning_text", None) # We need to get the relative path back to the documentation root from # whichever file the docstring content is in. @@ -404,7 +406,7 @@ def run(self): self.state.nested_parse(self.content, self.content_offset, content_node) if notebook_unique_name is None: - nb = examples_to_notebook(self.content) + nb = examples_to_notebook(self.content, warning_text=warning_text) self.content = None notebooks_dir = Path(self.env.app.srcdir) / CONTENT_DIR notebook_unique_name = f"{uuid4()}.ipynb".replace("-", "_") @@ -506,6 +508,7 @@ def _process_autodoc_docstrings(app, what, name, obj, options, lines): try_examples_options = { "theme": app.config.try_examples_global_theme, "button_text": app.config.try_examples_global_button_text, + "warning_text": app.config.try_examples_global_warning_text, } try_examples_options = { key: value for key, value in try_examples_options.items() if value is not None @@ -614,6 +617,7 @@ def setup(app): app.add_config_value("global_enable_try_examples", default=False, rebuild=True) app.add_config_value("try_examples_global_theme", default=None, rebuild=True) + app.add_config_value("try_examples_global_warning_text", default=None, rebuild=True) app.add_config_value( "try_examples_global_button_text", default=None,