aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKolen Cheung <ickc@users.noreply.github.com>2021-12-09 20:36:56 -0800
committerGitHub <noreply@github.com>2021-12-09 20:36:56 -0800
commit20eb8ac7fded0220278e8818a92968328f9014eb (patch)
tree19d278995f685355c919f7a8275aa91684572beb
parentfa643ba6d78fd97f0a779840dca32bfea3b296f8 (diff)
downloadpandoc-20eb8ac7fded0220278e8818a92968328f9014eb.tar.gz
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
-rw-r--r--src/Text/Pandoc/Writers/Ipynb.hs2
-rw-r--r--test/Tests/Old.hs6
-rw-r--r--test/ipynb/mime.ipynb187
-rw-r--r--test/ipynb/mime.native154
-rw-r--r--test/ipynb/mime.out.ipynb169
5 files changed, 518 insertions, 0 deletions
diff --git a/src/Text/Pandoc/Writers/Ipynb.hs b/src/Text/Pandoc/Writers/Ipynb.hs
index 65299a4c9..47c6e6966 100644
--- a/src/Text/Pandoc/Writers/Ipynb.hs
+++ b/src/Text/Pandoc/Writers/Ipynb.hs
@@ -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)
diff --git a/test/Tests/Old.hs b/test/Tests/Old.hs
index d080f68f1..1d5b0b04e 100644
--- a/test/Tests/Old.hs
+++ b/test/Tests/Old.hs
@@ -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
diff --git a/test/ipynb/mime.ipynb b/test/ipynb/mime.ipynb
new file mode 100644
index 000000000..8789ca857
--- /dev/null
+++ b/test/ipynb/mime.ipynb
@@ -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
+}
diff --git a/test/ipynb/mime.native b/test/ipynb/mime.native
new file mode 100644
index 000000000..21e3444e2
--- /dev/null
+++ b/test/ipynb/mime.native
@@ -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."
+ ]
+ ]
+]
diff --git a/test/ipynb/mime.out.ipynb b/test/ipynb/mime.out.ipynb
new file mode 100644
index 000000000..4cc806a1e
--- /dev/null
+++ b/test/ipynb/mime.out.ipynb
@@ -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": {}
+}