Skip to content

Commit

Permalink
👌 IMPROVE: hide-output button (#450)
Browse files Browse the repository at this point in the history
It now uses the same margin color as the cell source and, when the cell source is present,
is "connected" to that, to form a single element.
  • Loading branch information
chrisjsewell authored Sep 30, 2022
1 parent 421ca2d commit bb6f5a4
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 78 deletions.
33 changes: 24 additions & 9 deletions docs/render/hiding.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ import numpy as np
data = np.random.rand(2, 100) * 100
```

Here is a cell with a `hide-input` tag. Click the "toggle" button to the
right to show it.
Here is a cell with a `hide-input` tag.

```{code-cell} ipython3
:tags: [hide-input]
Expand All @@ -55,7 +54,17 @@ fig, ax = plt.subplots()
points =ax.scatter(*data, c=data[0], s=data[0])
```

And the following cell has a `hide-cell` tag:
Here's a cell with both `hide-input` and `hide-output` tags:

```{code-cell} ipython3
:tags: [hide-input, hide-output]
# This cell has a hide-output tag
fig, ax = plt.subplots()
points =ax.scatter(*data, c=data[0], s=data[0])
```

Here's a cell with a `hide-cell` tag:

```{code-cell} ipython3
:tags: [hide-cell]
Expand All @@ -65,17 +74,26 @@ fig, ax = plt.subplots()
points =ax.scatter(*data, c=data[0], s=data[0])
```

Finally, a cell with both `remove-input` (see below) and `hide-output` tags:

```{code-cell} ipython3
:tags: [remove-input, hide-output]
fig, ax = plt.subplots()
points = ax.scatter(*data, c=data[0], s=data[0])
```

You can control the hide/show prompts by using the `code_prompt_show` and `code_prompt_hide` configuration options.
`{type}` will be replaced with `content`, `source`, or `outputs`, depending on the hide tag.
The optional `{type}` placeholder will be replaced with `content`, `source`, or `outputs`, depending on the hide tag.
See the {ref}`config/intro` section for more details.

````markdown

```{code-cell} ipython3
:tags: [hide-cell]
:mystnb:
: code_prompt_show: "My show prompt"
: code_prompt_hide: "My hide prompt"
: code_prompt_show: "My show prompt for {type}"
: code_prompt_hide: "My hide prompt for {type}"

print("hallo world")
```
Expand Down Expand Up @@ -131,7 +149,6 @@ the page at all.
```{code-cell} ipython3
:tags: [remove-input]
# This cell has a remove-input tag
fig, ax = plt.subplots()
points =ax.scatter(*data, c=data[0], s=data[0])
```
Expand All @@ -141,7 +158,6 @@ Here's a cell with a `remove-output` tag:
```{code-cell} ipython3
:tags: [remove-output]
# This cell has a remove-output tag
fig, ax = plt.subplots()
points = ax.scatter(*data, c=data[0], s=data[0])
```
Expand All @@ -152,7 +168,6 @@ below, since the cell will be gone).
```{code-cell} ipython3
:tags: [remove-cell]
# This cell has a remove-cell tag
fig, ax = plt.subplots()
points = ax.scatter(*data, c=data[0], s=data[0])
```
2 changes: 1 addition & 1 deletion myst_nb/core/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ def render_nb_cell_code(self: SelfType, token: SyntaxTreeNode) -> None:
if hide_cell:
hide_mode = "all"
elif hide_input and hide_output:
hide_mode = "all"
hide_mode = "input+output"
elif hide_input:
hide_mode = "input"
elif hide_output:
Expand Down
43 changes: 29 additions & 14 deletions myst_nb/sphinx_.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,10 +516,21 @@ def run(self, **kwargs):
has_input = node.children[0].get("nb_element") == "cell_code_source"
has_output = node.children[-1].get("nb_element") == "cell_code_output"

# if we have the code source (input) element,
# and we are collapsing the input or input+output
# then we attach the "collapse button" above the input
if has_input and hide_mode == "input":
if has_input and hide_mode == "all":
# wrap everything and place a summary above the input
wrap_node = HideCodeCellNode(
prompt_show=node["prompt_show"].replace("{type}", "content"),
prompt_hide=node["prompt_hide"].replace("{type}", "content"),
)
wrap_node["classes"].append("above-input")
wrap_node.extend(node.children)
node.children = [wrap_node]

if has_input and has_output and hide_mode in ("output", "input+output"):
node.children[0]["classes"].append("above-output-prompt")

if has_input and hide_mode in ("input", "input+output"):
# wrap just the input and place a summary above the input
wrap_node = HideCodeCellNode(
prompt_show=node["prompt_show"].replace("{type}", "source"),
prompt_hide=node["prompt_hide"].replace("{type}", "source"),
Expand All @@ -529,19 +540,23 @@ def run(self, **kwargs):
wrap_node.append(code)
node.replace(code, wrap_node)

elif has_input and hide_mode == "all":
if has_input and has_output and hide_mode in ("output", "input+output"):
# wrap just the output and place a summary below the input
wrap_node = HideCodeCellNode(
prompt_show=node["prompt_show"].replace("{type}", "content"),
prompt_hide=node["prompt_hide"].replace("{type}", "content"),
prompt_show=node["prompt_show"].replace("{type}", "output"),
prompt_hide=node["prompt_hide"].replace("{type}", "output"),
)
wrap_node["classes"].append("above-input")
wrap_node.extend(node.children)
node.children = [wrap_node]
wrap_node["classes"].append("below-input")
output = node.children[-1]
wrap_node.append(output)
node.replace(output, wrap_node)

# if we don't have the code source (input) element,
# or are only hiding the output,
# then we place the "collapse button" above the output
elif has_output and hide_mode in ("output", "all"):
if (
(not has_input)
and has_output
and hide_mode in ("all", "input+output", "output")
):
# wrap just the output and place a summary above the output
wrap_node = HideCodeCellNode(
prompt_show=node["prompt_show"].replace("{type}", "outputs"),
prompt_hide=node["prompt_hide"].replace("{type}", "outputs"),
Expand Down
118 changes: 66 additions & 52 deletions myst_nb/static/mystnb.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
--mystnb-stdout-border-color: #f7f7f7;
--mystnb-stderr-border-color: #f7f7f7;
--mystnb-traceback-border-color: #ffd6d6;
--mystnb-hide-prompt-opacity: 70%;
--mystnb-source-border-radius: .4em;
--mystnb-source-border-width: 1px;
}

/* Whole cell */
Expand Down Expand Up @@ -36,23 +39,68 @@ div.cell div.cell_input,
div.cell details.above-input>summary {
padding-left: 0em;
padding-right: 0em;
border: 1px var(--mystnb-source-border-color) solid;
border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid;
background-color: var(--mystnb-source-bg-color);
border-left-color: var(--mystnb-source-margin-color);
border-left-width: medium;
border-radius: .4em;
border-radius: var(--mystnb-source-border-radius);
}

div.cell_input>div,
div.cell_output div.output>div.highlight {
margin: 0em !important;
border: none !important;
}

/* All cell outputs */
.cell_output {
padding-left: 1em;
padding-right: 0em;
margin-top: 1em;
}

/* Text outputs from cells */
.cell_output .output.text_plain,
.cell_output .output.traceback,
.cell_output .output.stream,
.cell_output .output.stderr {
margin-top: 1em;
margin-bottom: 0em;
box-shadow: none;
}

.cell_output .output.text_plain,
.cell_output .output.stream {
background: var(--mystnb-stdout-bg-color);
border: 1px solid var(--mystnb-stdout-border-color);
}

.cell_output .output.stderr {
background: var(--mystnb-stderr-bg-color);
border: 1px solid var(--mystnb-stderr-border-color);
}

.cell_output .output.traceback {
background: var(--mystnb-traceback-bg-color);
border: 1px solid var(--mystnb-traceback-border-color);
}

/* Collapsible cell content */
div.cell details.above-input div.cell_input {
border-top-left-radius: 0;
border-top-right-radius: 0;
border-top: 1px var(--mystnb-source-border-color) dashed;
border-top: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed;
}

div.cell div.cell_input.above-output-prompt {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}

div.cell details.above-input>summary {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
border-bottom: 1px var(--mystnb-source-border-color) dashed;
border-bottom: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed;
padding-left: 1em;
margin-bottom: 0;
}
Expand All @@ -61,20 +109,26 @@ div.cell details.above-output>summary {
background-color: var(--mystnb-source-bg-color);
padding-left: 1em;
padding-right: 0em;
border: 1px var(--mystnb-source-border-color) solid;
border-bottom: 1px var(--mystnb-source-border-color) dashed;
border-left-color: blue;
border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid;
border-radius: var(--mystnb-source-border-radius);
border-left-color: var(--mystnb-source-margin-color);
border-left-width: medium;
border-top-left-radius: .4em;
border-top-right-radius: .4em;
}

div.cell details.hide>summary::marker {
opacity: 50%;
div.cell details.below-input>summary {
background-color: var(--mystnb-source-bg-color);
padding-left: 1em;
padding-right: 0em;
border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid;
border-top: none;
border-bottom-left-radius: var(--mystnb-source-border-radius);
border-bottom-right-radius: var(--mystnb-source-border-radius);
border-left-color: var(--mystnb-source-margin-color);
border-left-width: medium;
}

div.cell details.hide>summary>span {
opacity: 50%;
opacity: var(--mystnb-hide-prompt-opacity);
}

div.cell details.hide[open]>summary>span.collapsed {
Expand All @@ -94,52 +148,12 @@ div.cell details.hide:not([open])>summary>span.expanded {
opacity: 1;
}
}

div.cell details.hide[open]>summary~* {
-moz-animation: collapsed-fade-in 0.3s ease-in-out;
-webkit-animation: collapsed-fade-in 0.3s ease-in-out;
animation: collapsed-fade-in 0.3s ease-in-out;
}

div.cell_input>div,
div.cell_output div.output>div.highlight {
margin: 0em !important;
border: none !important;
}

/* All cell outputs */
.cell_output {
padding-left: 1em;
padding-right: 0em;
margin-top: 1em;
}

/* Text outputs from cells */
.cell_output .output.text_plain,
.cell_output .output.traceback,
.cell_output .output.stream,
.cell_output .output.stderr {
margin-top: 1em;
margin-bottom: 0em;
box-shadow: none;
}

.cell_output .output.text_plain,
.cell_output .output.stream {
background: var(--mystnb-stdout-bg-color);
border: 1px solid var(--mystnb-stdout-border-color);
}

.cell_output .output.stderr {
background: var(--mystnb-stderr-bg-color);
border: 1px solid var(--mystnb-stderr-border-color);
}

.cell_output .output.traceback {
background: var(--mystnb-traceback-bg-color);
border: 1px solid var(--mystnb-traceback-border-color);
}

/* Math align to the left */
.cell_output .MathJax_Display {
text-align: left !important;
Expand Down
4 changes: 2 additions & 2 deletions tests/test_render_outputs/test_hide_cell_content.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
<literal_block classes="output stream" language="myst-ansi" linenos="False" xml:space="preserve">
hide-input
<container cell_index="2" cell_metadata="{'tags': ['hide-output']}" classes="cell tag_hide-output" exec_count="2" hide_mode="output" nb_element="cell_code" prompt_hide="Hide code cell {type}" prompt_show="Show code cell {type}">
<container classes="cell_input" nb_element="cell_code_source">
<container classes="cell_input above-output-prompt" nb_element="cell_code_source">
<literal_block language="ipython3" linenos="False" xml:space="preserve">
print("hide-output")
<HideCodeCellNode classes="above-output" prompt_hide="Hide code cell outputs" prompt_show="Show code cell outputs">
<HideCodeCellNode classes="below-input" prompt_hide="Hide code cell output" prompt_show="Show code cell output">
<container classes="cell_output" nb_element="cell_code_output">
<literal_block classes="output stream" language="myst-ansi" linenos="False" xml:space="preserve">
hide-output
Expand Down

0 comments on commit bb6f5a4

Please sign in to comment.