ipynb writer: handle cell output with raw block of markdown (#7563)
Write RawBlock of markdown in code-cell output. #7561 makes the ipynb reader reads code-cell output with mime "text/markdown" to a RawBlock of markdown This commit makes the ipynb writer writes this RawBlock of markdown back inside a code-cell output with the same mime, preserving this information in round-trip Add tests of ipynb reader (#7561) and ipynb writer (#7563)'s ability to handle a "text/markdown" mime type in a code-cell output
This commit is contained in:
parent
fa643ba6d7
commit
20eb8ac7fd
5 changed files with 518 additions and 0 deletions
|
@ -253,6 +253,8 @@ extractData bs = do
|
|||
return (M.insert "text/html" (TextualData raw) mmap, meta)
|
||||
go (mmap, meta) (RawBlock (Format "latex") raw) =
|
||||
return (M.insert "text/latex" (TextualData raw) mmap, meta)
|
||||
go (mmap, meta) (RawBlock (Format "markdown") raw) =
|
||||
return (M.insert "text/markdown" (TextualData raw) mmap, meta)
|
||||
go (mmap, meta) (Div _ bs') = foldM go (mmap, meta) bs'
|
||||
go (mmap, meta) b = (mmap, meta) <$ report (BlockNotRendered b)
|
||||
|
||||
|
|
|
@ -219,6 +219,12 @@ tests pandocPath =
|
|||
"--markdown-headings=setext", "-t",
|
||||
"ipynb-raw_html-raw_tex+raw_attribute", "-s"]
|
||||
"ipynb/simple.in.native" "ipynb/simple.ipynb"
|
||||
, test' "reader" ["-t", "native", "-f", "ipynb",
|
||||
"--ipynb-output=all"]
|
||||
"ipynb/mime.ipynb" "ipynb/mime.native"
|
||||
, test' "writer" ["-f", "native", "-t", "ipynb",
|
||||
"--wrap=preserve"]
|
||||
"ipynb/mime.native" "ipynb/mime.out.ipynb"
|
||||
]
|
||||
]
|
||||
where
|
||||
|
|
187
test/ipynb/mime.ipynb
Normal file
187
test/ipynb/mime.ipynb
Normal file
|
@ -0,0 +1,187 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "0ad1fbe7-107b-4668-ae4d-8ce4ae9a4400",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from __future__ import annotations\n",
|
||||
"\n",
|
||||
"from dataclasses import dataclass"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "c2d3a9f4-dfdb-4ced-bbcd-3dfd1780af80",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"7.29.0\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import IPython\n",
|
||||
"\n",
|
||||
"print(IPython.__version__)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "21e7a4a1-0cf8-48cc-823c-dca698ae6853",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Supported IPython display formatters:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "053cdbc4-b157-4e3e-9c86-8f374770d006",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"text/plain\n",
|
||||
"text/html\n",
|
||||
"text/markdown\n",
|
||||
"image/svg+xml\n",
|
||||
"image/png\n",
|
||||
"application/pdf\n",
|
||||
"image/jpeg\n",
|
||||
"text/latex\n",
|
||||
"application/json\n",
|
||||
"application/javascript\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"ip = get_ipython()\n",
|
||||
"for mime in ip.display_formatter.formatters:\n",
|
||||
" print(mime)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d79b063d-ce81-497b-a0ea-5b2e2972e845",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Let's write a simple class that will output different mime:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "c847636c-1c45-432e-9d8d-7310dd7f5637",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@dataclass\n",
|
||||
"class Mime:\n",
|
||||
" math: str\n",
|
||||
"\n",
|
||||
" def _repr_mimebundle_(\n",
|
||||
" self,\n",
|
||||
" include: Container[str] | None = None,\n",
|
||||
" exclude: Container[str] | None = None,\n",
|
||||
" **kwargs,\n",
|
||||
" ) -> dict[str, str]:\n",
|
||||
" string = self.math\n",
|
||||
" data = {\n",
|
||||
" \"text/plain\": string,\n",
|
||||
" \"text/html\": (latex := f\"\\\\[{string}\\\\]\"),\n",
|
||||
" \"text/markdown\": f\"$${string}$$\",\n",
|
||||
" # \"image/svg+xml\":,\n",
|
||||
" # \"image/png\":,\n",
|
||||
" # \"application/pdf\":,\n",
|
||||
" # \"image/jpeg\":,\n",
|
||||
" \"text/latex\": latex,\n",
|
||||
" # \"application/json\":,\n",
|
||||
" # \"application/javascript\":,\n",
|
||||
" }\n",
|
||||
" if include:\n",
|
||||
" data = {k: v for k, v in data.items() if k in include}\n",
|
||||
" if exclude:\n",
|
||||
" data = {k: v for k, v in data.items() if k not in exclude}\n",
|
||||
" return data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "4fa54f22-0c3a-4809-91f7-ea7101ff1907",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"mime = Mime(\"E = mc^2\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "c419e6a6-240c-4af0-a244-5f1526705c30",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"\\[E = mc^2\\]"
|
||||
],
|
||||
"text/latex": [
|
||||
"\\[E = mc^2\\]"
|
||||
],
|
||||
"text/markdown": [
|
||||
"$$E = mc^2$$"
|
||||
],
|
||||
"text/plain": [
|
||||
"E = mc^2"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"mime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "bf140b8e-16ac-4670-9778-f1c1d9486f9d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Note that #7561 made ipynb reader aware of this, and #7563 made ipynb writer aware of this."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
154
test/ipynb/mime.native
Normal file
154
test/ipynb/mime.native
Normal file
|
@ -0,0 +1,154 @@
|
|||
[ Div
|
||||
( "0ad1fbe7-107b-4668-ae4d-8ce4ae9a4400"
|
||||
, [ "cell" , "code" ]
|
||||
, [ ( "execution_count" , "1" ) ]
|
||||
)
|
||||
[ CodeBlock
|
||||
( "" , [ "python" ] , [] )
|
||||
"from __future__ import annotations\n\nfrom dataclasses import dataclass"
|
||||
]
|
||||
, Div
|
||||
( "c2d3a9f4-dfdb-4ced-bbcd-3dfd1780af80"
|
||||
, [ "cell" , "code" ]
|
||||
, [ ( "execution_count" , "2" ) ]
|
||||
)
|
||||
[ CodeBlock
|
||||
( "" , [ "python" ] , [] )
|
||||
"import IPython\n\nprint(IPython.__version__)"
|
||||
, Div
|
||||
( "" , [ "output" , "stream" , "stdout" ] , [] )
|
||||
[ CodeBlock ( "" , [] , [] ) "7.29.0\n" ]
|
||||
]
|
||||
, Div
|
||||
( "21e7a4a1-0cf8-48cc-823c-dca698ae6853"
|
||||
, [ "cell" , "markdown" ]
|
||||
, []
|
||||
)
|
||||
[ Para
|
||||
[ Str "Supported"
|
||||
, Space
|
||||
, Str "IPython"
|
||||
, Space
|
||||
, Str "display"
|
||||
, Space
|
||||
, Str "formatters:"
|
||||
]
|
||||
]
|
||||
, Div
|
||||
( "053cdbc4-b157-4e3e-9c86-8f374770d006"
|
||||
, [ "cell" , "code" ]
|
||||
, [ ( "execution_count" , "3" ) ]
|
||||
)
|
||||
[ CodeBlock
|
||||
( "" , [ "python" ] , [] )
|
||||
"ip = get_ipython()\nfor mime in ip.display_formatter.formatters:\n print(mime)"
|
||||
, Div
|
||||
( "" , [ "output" , "stream" , "stdout" ] , [] )
|
||||
[ CodeBlock
|
||||
( "" , [] , [] )
|
||||
"text/plain\ntext/html\ntext/markdown\nimage/svg+xml\nimage/png\napplication/pdf\nimage/jpeg\ntext/latex\napplication/json\napplication/javascript\n"
|
||||
]
|
||||
]
|
||||
, Div
|
||||
( "d79b063d-ce81-497b-a0ea-5b2e2972e845"
|
||||
, [ "cell" , "markdown" ]
|
||||
, []
|
||||
)
|
||||
[ Para
|
||||
[ Str "Let's"
|
||||
, Space
|
||||
, Str "write"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "simple"
|
||||
, Space
|
||||
, Str "class"
|
||||
, Space
|
||||
, Str "that"
|
||||
, Space
|
||||
, Str "will"
|
||||
, Space
|
||||
, Str "output"
|
||||
, Space
|
||||
, Str "different"
|
||||
, Space
|
||||
, Str "mime:"
|
||||
]
|
||||
]
|
||||
, Div
|
||||
( "c847636c-1c45-432e-9d8d-7310dd7f5637"
|
||||
, [ "cell" , "code" ]
|
||||
, [ ( "execution_count" , "4" ) ]
|
||||
)
|
||||
[ CodeBlock
|
||||
( "" , [ "python" ] , [] )
|
||||
"@dataclass\nclass Mime:\n math: str\n\n def _repr_mimebundle_(\n self,\n include: Container[str] | None = None,\n exclude: Container[str] | None = None,\n **kwargs,\n ) -> dict[str, str]:\n string = self.math\n data = {\n \"text/plain\": string,\n \"text/html\": (latex := f\"\\\\[{string}\\\\]\"),\n \"text/markdown\": f\"$${string}$$\",\n # \"image/svg+xml\":,\n # \"image/png\":,\n # \"application/pdf\":,\n # \"image/jpeg\":,\n \"text/latex\": latex,\n # \"application/json\":,\n # \"application/javascript\":,\n }\n if include:\n data = {k: v for k, v in data.items() if k in include}\n if exclude:\n data = {k: v for k, v in data.items() if k not in exclude}\n return data"
|
||||
]
|
||||
, Div
|
||||
( "4fa54f22-0c3a-4809-91f7-ea7101ff1907"
|
||||
, [ "cell" , "code" ]
|
||||
, [ ( "execution_count" , "5" ) ]
|
||||
)
|
||||
[ CodeBlock
|
||||
( "" , [ "python" ] , [] ) "mime = Mime(\"E = mc^2\")"
|
||||
]
|
||||
, Div
|
||||
( "c419e6a6-240c-4af0-a244-5f1526705c30"
|
||||
, [ "cell" , "code" ]
|
||||
, [ ( "execution_count" , "6" ) ]
|
||||
)
|
||||
[ CodeBlock ( "" , [ "python" ] , [] ) "mime"
|
||||
, Div
|
||||
( ""
|
||||
, [ "output" , "execute_result" ]
|
||||
, [ ( "execution_count" , "6" ) ]
|
||||
)
|
||||
[ RawBlock (Format "html") "\\[E = mc^2\\]"
|
||||
, RawBlock (Format "latex") "\\[E = mc^2\\]"
|
||||
, RawBlock (Format "markdown") "$$E = mc^2$$"
|
||||
, CodeBlock ( "" , [] , [] ) "E = mc^2"
|
||||
]
|
||||
]
|
||||
, Div
|
||||
( "bf140b8e-16ac-4670-9778-f1c1d9486f9d"
|
||||
, [ "cell" , "markdown" ]
|
||||
, []
|
||||
)
|
||||
[ Para
|
||||
[ Str "Note"
|
||||
, Space
|
||||
, Str "that"
|
||||
, Space
|
||||
, Str "#7561"
|
||||
, Space
|
||||
, Str "made"
|
||||
, Space
|
||||
, Str "ipynb"
|
||||
, Space
|
||||
, Str "reader"
|
||||
, Space
|
||||
, Str "aware"
|
||||
, Space
|
||||
, Str "of"
|
||||
, Space
|
||||
, Str "this,"
|
||||
, Space
|
||||
, Str "and"
|
||||
, Space
|
||||
, Str "#7563"
|
||||
, Space
|
||||
, Str "made"
|
||||
, Space
|
||||
, Str "ipynb"
|
||||
, Space
|
||||
, Str "writer"
|
||||
, Space
|
||||
, Str "aware"
|
||||
, Space
|
||||
, Str "of"
|
||||
, Space
|
||||
, Str "this."
|
||||
]
|
||||
]
|
||||
]
|
169
test/ipynb/mime.out.ipynb
Normal file
169
test/ipynb/mime.out.ipynb
Normal file
|
@ -0,0 +1,169 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from __future__ import annotations\n",
|
||||
"\n",
|
||||
"from dataclasses import dataclass"
|
||||
],
|
||||
"id": "0ad1fbe7-107b-4668-ae4d-8ce4ae9a4400"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"7.29.0\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import IPython\n",
|
||||
"\n",
|
||||
"print(IPython.__version__)"
|
||||
],
|
||||
"id": "c2d3a9f4-dfdb-4ced-bbcd-3dfd1780af80"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Supported IPython display formatters:"
|
||||
],
|
||||
"id": "21e7a4a1-0cf8-48cc-823c-dca698ae6853"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"text/plain\n",
|
||||
"text/html\n",
|
||||
"text/markdown\n",
|
||||
"image/svg+xml\n",
|
||||
"image/png\n",
|
||||
"application/pdf\n",
|
||||
"image/jpeg\n",
|
||||
"text/latex\n",
|
||||
"application/json\n",
|
||||
"application/javascript\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"ip = get_ipython()\n",
|
||||
"for mime in ip.display_formatter.formatters:\n",
|
||||
" print(mime)"
|
||||
],
|
||||
"id": "053cdbc4-b157-4e3e-9c86-8f374770d006"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Let's write a simple class that will output different mime:"
|
||||
],
|
||||
"id": "d79b063d-ce81-497b-a0ea-5b2e2972e845"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@dataclass\n",
|
||||
"class Mime:\n",
|
||||
" math: str\n",
|
||||
"\n",
|
||||
" def _repr_mimebundle_(\n",
|
||||
" self,\n",
|
||||
" include: Container[str] | None = None,\n",
|
||||
" exclude: Container[str] | None = None,\n",
|
||||
" **kwargs,\n",
|
||||
" ) -> dict[str, str]:\n",
|
||||
" string = self.math\n",
|
||||
" data = {\n",
|
||||
" \"text/plain\": string,\n",
|
||||
" \"text/html\": (latex := f\"\\\\[{string}\\\\]\"),\n",
|
||||
" \"text/markdown\": f\"$${string}$$\",\n",
|
||||
" # \"image/svg+xml\":,\n",
|
||||
" # \"image/png\":,\n",
|
||||
" # \"application/pdf\":,\n",
|
||||
" # \"image/jpeg\":,\n",
|
||||
" \"text/latex\": latex,\n",
|
||||
" # \"application/json\":,\n",
|
||||
" # \"application/javascript\":,\n",
|
||||
" }\n",
|
||||
" if include:\n",
|
||||
" data = {k: v for k, v in data.items() if k in include}\n",
|
||||
" if exclude:\n",
|
||||
" data = {k: v for k, v in data.items() if k not in exclude}\n",
|
||||
" return data"
|
||||
],
|
||||
"id": "c847636c-1c45-432e-9d8d-7310dd7f5637"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"mime = Mime(\"E = mc^2\")"
|
||||
],
|
||||
"id": "4fa54f22-0c3a-4809-91f7-ea7101ff1907"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "execute_result",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"data": {
|
||||
"text/html": [
|
||||
"\\[E = mc^2\\]"
|
||||
],
|
||||
"text/latex": [
|
||||
"\\[E = mc^2\\]"
|
||||
],
|
||||
"text/markdown": [
|
||||
"$$E = mc^2$$"
|
||||
],
|
||||
"text/plain": [
|
||||
"E = mc^2"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"mime"
|
||||
],
|
||||
"id": "c419e6a6-240c-4af0-a244-5f1526705c30"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Note that #7561 made ipynb reader aware of this, and #7563 made ipynb writer aware of this."
|
||||
],
|
||||
"id": "bf140b8e-16ac-4670-9778-f1c1d9486f9d"
|
||||
}
|
||||
],
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5,
|
||||
"metadata": {}
|
||||
}
|
Loading…
Add table
Reference in a new issue