Open choldgraf opened 8 months ago
continuing #1559 here:
An example for this would be the following:
My problem now is, that I have 2-20 different structures. For each I get graphs based on the same code. Right now the only solution is to put them all below each other, leading to a quite long doc.
Better would be to have
and/or
A simplified example might be statistics about bank accounts (not scientific, but less abstract).
For different use-cases different approaches might be best. I'm wondering what might be possible:
{include}
I discovered this workaround today, it's a bit cludgy but isn't too hacky. It takes advantage of the fact that code cells are executed before a page is parsed by MyST. This means that you can do something like the following:
## Generate content with Jupyter
```{code-cell} python
from pathlib import Path
p = Path("../_build/txt/tmp.txt")
p.parent.mkdir(parents=True, exist_ok=True)
_ = p.write_text("- **Testing**\n- Testing two\n- Testing three")
And then include it in the page with MyST markdown like so:
This will:
1. Generate some MyST Markdown in Jupyter
2. Write it to a `.txt` file
3. And later in the page, in MyST MD, we reference that `.txt` file with an `{include}` statement
So the file is first executed, the `txt` file is created, and MyST then includes it
@choldgraf we should also make it possible to include
files with .myst.json
extensions, to support pulling in AST.
Yeah I was thinking that too. It also made me wonder if the notebook cell MyST support could be more like the plugin structure, rather than making it language specific.
For example, a cell tag like output-myst
or output-myst-ast
that would tell MyST to parse stdout as MyST (similar to what executable plugins do).
Does that make sense? If so I can update the issue body to reflect that suggestion.
@choldgraf the natural way to do this would be to define a MIME type for MyST AST, and recognise it in our transforms!
That sounds like a good idea. Though if it were the only way, then each kernel would need to have a package that outputs MyST right? The benefit of tags and stdout is that anybody in any language could use it without developing anything specific.
Although we don't need a package for this (certainly with ipython, you can just use display
), I'm curious to understand your thought process - are you picturing a user printing stringified json to the stdout? Or myst markup, I.e text/markdown?
My idea was inspired by the way that you handled "black box" outputs for the executable plugins infrastructure. So below I'll share a Python and an R cell that would generate either MyST MD or MyST AST. At build time, if the tag was identified on a cell, then any text/plain
output (or however stdout gets logged) would be parsed differently. Without those tags, the output would just be parsed like any other stdout.
Below I'll use Print, but I think since Jupyter "returns" the result of the final executed line, it may not be necessary. It'd also cool if this worked with variables too, so that you could insert generated MyST elsewhere.
Python - MyST MD
```{code-cell} python
:tags: output-myst-md
print("- **Bolded** list item")
Python - MyST AST[^1]
:tags: output-myst-ast
ast = {
"type": "list",
"ordered": false,
"spread": false,
"children": [
{
"type": "listItem",
"spread": True,
"children": [
{
"type": "strong",
"children": [
{
"type": "text",
"value": "Bolded"
}
]
},
{
"type": "text",
"value": " list item"
}
]
}
]
}
print(ast)
[^1]: This is also a good demonstration of why I think it's way nicer to be able to parse MyST MD directly and not _only_ MyST AST :-)
I love the idea of parsing plain/MysT mardkown proper, as it's very easy to generate from many tools. In my code I very often have something like
from IPython.display import display, Markdown
md = lambda s: display(Markdown(s))
and I use md(x)
everywhere as a "print markdown" shorthand to generate legible, pretty reporting with zero fuss.
Having the ability to properly handle that (along perhaps with a new MyST
object in IPython.display
) would be very useful, I think.
I decided to create a separate issue to track generating MyST AST directly from cell outputs, since that might be an easier short-term solution and get us part of the way there:
Jupyter notebook cells can produce text output that is specific to markdown (
text/markdown
). It'd be useful if MyST could parse this output along with the rest of the markdown in the notebook. This would allow for programmatic generation of notebook content, and along with the{embed}
directive could allow you to nicely stitch together MyST content via any Jupyter Kernel.For example:
As an example, the MyST-nb Sphinx extension documents this functionality here.
An example from our docs where this would be useful
In the admonitions docs here:
https://github.com/executablebooks/mystmd/blob/c0f51ee51890158081736722cb01bcf510699786/docs/admonitions.md?plain=1#L34-L98
We have a big list of all the different types of admonitions for demonstration. It's just boilerplate myst repeated over and over. If we parsed Markdown outputs as MyST, we could replace it with something like:
template = """
Related