Skip to content
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

🙈 Notebook Cell Tags Documentation #1750

Merged
merged 5 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/clean-meals-scream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"myst-execute": patch
"myst-common": patch
---

Use NotebookCellTags for raises-exception and skip-execution
9 changes: 9 additions & 0 deletions .changeset/gorgeous-trainers-fetch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"myst-to-typst": patch
"myst-to-docx": patch
"myst-to-jats": patch
"myst-to-tex": patch
"myst-to-md": patch
---

Update static exports to hide hidden code cells and blocks.
1 change: 1 addition & 0 deletions docs/myst.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ project:
- file: reuse-jupyter-outputs.md
- file: interactive-notebooks.ipynb
- file: integrating-jupyter.md
- file: notebook-configuration.md
- title: Websites
children:
- file: website-templates.md
Expand Down
51 changes: 51 additions & 0 deletions docs/notebook-configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
title: Notebook Configuration
---

In Jupyter Notebooks you can add cell level configuration by specifying **tags** in the cell metadata.
There are also global controls in the [project settings](#project-settings).

(notebook-cell-tags)=

### Notebook Cell Tags

Tags are a list of strings under the `tags` key in the cell metadata, which can be set in JupyterLab, VSCode or in a {myst:directive}`code-cell` directive.

In the JSON representation of a jupyter notebook these look like:

```json
{
"cell_type": "code",
"source": ["print('hello world')"],
"metadata": {
"tags": ["my-tag1", "my-tag2"]
}
}
```

In Markdown of a jupyter notebook these look like:

````markdown
```{code-cell} python
:tags: remove-input
print("This will show output with no input!")
```
````

:::{table} Notebook cell tags with special meanings
:label: tbl:notebook-cell-tags

| Tag | Description |
| ------------------ | -------------------------------------------------------------------------------------------------------------- |
| `remove-cell` | Remove the cell from the rendered output. |
| `remove-input` | Remove the code cell input/source from the rendered output. |
| `remove-output` | Remove the code cell output from the rendered output. |
| `hide-cell` | Hides the cell from the rendered output. |
| `hide-input` | Hides the code cell input/source from the rendered output. |
| `hide-output` | Hides the code cell output from the rendered output. |
| `remove-stderr` | Remove the code cell output stderr from the rendered output. See also [project config](#setting:output_stderr) |
| `remove-stdout` | Remove the code cell output stdout from the rendered output. See also [project config](#setting:output_stdout) |
| `skip-execution` | Skip this cell, when executing the notebook |
| `raises-exception` | Expect the code cell to raise an Exception (and continue execution) |

:::
4 changes: 2 additions & 2 deletions docs/notebooks-with-markdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ After we declare the frontmatter, the contents of each {myst:directive}`code-cel
Furthermore, you can build MyST Markdown content with other programming languages like JavaScript, R, and Julia by installing the corresponding kernel. For example, to build a page that uses JavaScript in the {myst:directive}`code-cell`, we could:

1. Install a JavaScript kernel, e.g. [ijavascript](https://github.com/n-riesco/ijavascript).
2. Retrieve the kernel name with `jupyter kernelspec list`.
2. Retrieve the kernel name with `jupyter kernelspec list`.
In the default installation, the kernel name is `javascript`.
3. Set the kernelspec in your document's frontmatter:
```yaml
Expand Down Expand Up @@ -112,7 +112,7 @@ print(phrase)
You can add tags to the {myst:directive}`code-cell` directive.
They will be parsed and used in the same way that cell tag metadata is used in `.ipynb` files.

For example, the following code defines a `remove-input` tag:
For example, the following code defines a `remove-input` tag (See all [notebook tag options](#tbl:notebook-cell-tags)):

````markdown
```{code-cell} python
Expand Down
6 changes: 6 additions & 0 deletions docs/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ description: Project and page settings for MyST

The `settings` field in the project or page frontmatter allows you to change how the parsing, transforms, plugins, or other behaviors of mystmd.

(project-settings)=

## Available settings fields

(setting:output_stderr)=
Expand All @@ -16,6 +18,8 @@ output_stderr
- `"remove-warn"` or `"remove-error"`: remove all stderr, and log a warning or error
- `"warn"` or "error": log a warning or error if a stderr is found

: Can be controlled or overridden by a [notebook cell tag](#tbl:notebook-cell-tags).

(setting:output_stdout)=
output_stdout
: Remove, warn or error on stdout outputs. (e.g. long text outputs, like text-based progress bars)
Expand All @@ -25,6 +29,8 @@ output_stdout
- `"remove-warn"` or `"remove-error"`: remove all stdout, and log a warning or error
- `"warn"` or "error": log a warning or error if a stdout is found

: Can be controlled or overridden by a [notebook cell tag](#tbl:notebook-cell-tags).

(setting:output_matplotlib_strings)=
output_matplotlib_strings
: Remove, warn or error on matplotlib strings outputs. (e.g. `<Figure size 720x576 with 1 Axes>` or `Text(0.5, 0.98, 'Test 1')`). These can also be suppressed by ending your cell content with a semicolon in Jupyter Notebooks. The default is to remove these and warn (`"remove-warn"`).
Expand Down
2 changes: 2 additions & 0 deletions packages/myst-common/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export enum NotebookCellTags {
'removeCell' = 'remove-cell',
'removeInput' = 'remove-input',
'removeOutput' = 'remove-output',
'skipExecution' = 'skip-execution',
'raisesException' = 'raises-exception',
}

export type References = {
Expand Down
6 changes: 3 additions & 3 deletions packages/myst-execute/src/execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { Kernel, KernelMessage, Session, SessionManager } from '@jupyterlab
import type { Block, Code, InlineExpression, Output } from 'myst-spec-ext';
import type { IOutput } from '@jupyterlab/nbformat';
import type { GenericNode, GenericParent, IExpressionResult, IExpressionError } from 'myst-common';
import { NotebookCell, fileError } from 'myst-common';
import { NotebookCell, NotebookCellTags, fileError } from 'myst-common';
import type { VFile } from 'vfile';
import path from 'node:path';
import assert from 'node:assert';
Expand Down Expand Up @@ -175,15 +175,15 @@ function isCellBlock(node: GenericNode): node is CodeBlock {
* @param node block to test
*/
function codeBlockRaisesException(node: CodeBlock) {
return !!node.data?.tags?.includes?.('raises-exception');
return !!node.data?.tags?.includes?.(NotebookCellTags.raisesException);
}
/**
* Return true if the given code block should not be executed
*
* @param node block to test
*/
function codeBlockSkipsExecution(node: CodeBlock) {
return !!node.data?.tags?.includes?.('skip-execution');
return !!node.data?.tags?.includes?.(NotebookCellTags.skipExecution);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much better!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small little improvements. I was in there looking to implement this and was surprised it was already done!

}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/myst-to-docx/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const paragraph: Handler<ParagraphNode> = (state, node) => {
};

const block: Handler<Block> = (state, node) => {
if (node.visibility === 'remove') return;
if (node.visibility === 'remove' || node.visibility === 'hide') return;
const metadataTags = getMetadataTags(node);
if (metadataTags.includes('page-break') || metadataTags.includes('new-page')) {
state.current.push(new PageBreak());
Expand Down
2 changes: 1 addition & 1 deletion packages/myst-to-jats/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ const handlers: Handlers = {
state.renderInline(node, 'title');
},
block(node, state) {
if (node.visibility === 'remove') return;
if (node.visibility === 'remove' || node.visibility === 'hide') return;
state.renderChildren(node);
},
blockquote(node, state) {
Expand Down
2 changes: 1 addition & 1 deletion packages/myst-to-md/src/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function comment(node: any, _: Parent, state: State): string {
}

function block(node: any, _: Parent, state: State, info: Info): string {
if (node.visibility === 'remove') return '';
if (node.visibility === 'remove' || node.visibility === 'hide') return '';
const meta = node.meta ? ` ${node.meta}` : '';
const content = state.containerFlow(node, info);
return `+++${meta}\n${content}`;
Expand Down
6 changes: 2 additions & 4 deletions packages/myst-to-tex/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ const handlers: Record<string, Handler> = {
state.write('\\end{frame}\n\n');
return;
}
if (node.visibility === 'remove') return;
if (node.visibility === 'remove' || node.visibility === 'hide') return;
if (metadataTags.includes('no-tex')) return;
if (metadataTags.includes('no-pdf')) return;
if (metadataTags.includes('new-page')) {
Expand Down Expand Up @@ -202,9 +202,7 @@ const handlers: Record<string, Handler> = {
state.renderChildren(node, true);
},
code(node: Code, state) {
if (node.visibility === 'remove') {
return;
}
if (node.visibility === 'remove' || node.visibility === 'hide') return;
addIndexEntries(node, state);
let start = '\\begin{verbatim}\n';
let end = '\n\\end{verbatim}';
Expand Down
6 changes: 2 additions & 4 deletions packages/myst-to-typst/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ const handlers: Record<string, Handler> = {
const metadataTags = getMetadataTags(node);
if (metadataTags.includes('no-typst')) return;
if (metadataTags.includes('no-pdf')) return;
if (node.visibility === 'remove') return;
if (node.visibility === 'remove' || node.visibility === 'hide') return;
if (metadataTags.includes('page-break') || metadataTags.includes('new-page')) {
state.write('#pagebreak(weak: true)\n');
}
Expand Down Expand Up @@ -183,9 +183,7 @@ const handlers: Record<string, Handler> = {
state.renderChildren(node);
},
code(node: Code, state) {
if (node.visibility === 'remove') {
return;
}
if (node.visibility === 'remove' || node.visibility === 'hide') return;
let ticks = '```';
while (node.value.includes(ticks)) {
ticks += '`';
Expand Down
Loading