diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..40f159c1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "vendor/juxtapose"] + path = vendor/juxtapose + url = https://github.com/NUKnightLab/juxtapose diff --git a/README.md b/README.md index 44c52ac1..fd7afdf3 100644 --- a/README.md +++ b/README.md @@ -66,11 +66,15 @@ Formatting with black can be done this way: 2. `black --python-cell-magics splity splitview_magic.ipynb` +## Developer Installation +1. `git clone --recurse https://github.com/kolibril13/jupyter-splitview` +(Note: In case that the repo was already cloned e.g. with the GitHub Desktop client, the GitHub submodule has to be loaded via `git submodule update --init --recursive` ) +2. `poetry install` ## Changelog -## Milestones for >0.0.5 +## Milestones for >0.0.5 * Handle cases where n ≠ 2 images. Currently: All further img are ignored. * implement tests, find out how to test a magic class diff --git a/example_notebook.ipynb b/example_notebook.ipynb index 35b56240..2a8b9bc5 100644 --- a/example_notebook.ipynb +++ b/example_notebook.ipynb @@ -11,6 +11,371 @@ "text": [ "Jupyter Splitview v0.0.4\n" ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ @@ -27,17 +392,31 @@ { "data": { "text/html": [ + "
\n", "\n", - "
\n", - "
\n", - " ' '\n", - "
\n", - "
\n", - " \n", - " \n", - " " + "" ], "text/plain": [ "" @@ -74,17 +453,31 @@ { "data": { "text/html": [ + "
\n", "\n", - "
\n", - "
\n", - " ' '\n", - "
\n", - "
\n", - " \n", - " \n", - " " + "" ], "text/plain": [ "" @@ -135,7 +528,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.13" + "version": "3.9.12" } }, "nbformat": 4, diff --git a/jupyter_splitview/__init__.py b/jupyter_splitview/__init__.py index 909a5d1e..7ccbf2f9 100644 --- a/jupyter_splitview/__init__.py +++ b/jupyter_splitview/__init__.py @@ -1,5 +1,9 @@ +from pathlib import Path + from .sw_cellmagic import SplitViewMagic -from IPython import get_ipython # register cell magic +from IPython import get_ipython +from IPython.core.display import HTML +from IPython.display import display import pkg_resources __version__: str = pkg_resources.get_distribution(__name__).version @@ -10,5 +14,17 @@ ipy = get_ipython() ipy.register_magics(SplitViewMagic) + css_path = Path(__file__).parents[1] / "vendor/juxtapose/build/css/juxtapose.css" + js_path = Path(__file__).parents[1] / "vendor/juxtapose/build/js/juxtapose.min.js" + + html_code = f""" + + + """ + display(HTML(html_code)) + + except AttributeError: - print("Can not load SplitViewMagic because this is not a notebook") \ No newline at end of file + print("Can not load SplitViewMagic because this is not a notebook") + + diff --git a/jupyter_splitview/inject.html b/jupyter_splitview/inject.html new file mode 100644 index 00000000..71af1053 --- /dev/null +++ b/jupyter_splitview/inject.html @@ -0,0 +1,43 @@ +
+
+
+ + + + + diff --git a/jupyter_splitview/sw_cellmagic.py b/jupyter_splitview/sw_cellmagic.py index df2fb171..4dc13f4e 100644 --- a/jupyter_splitview/sw_cellmagic.py +++ b/jupyter_splitview/sw_cellmagic.py @@ -1,4 +1,5 @@ import io +import os from base64 import b64decode from IPython.core import magic_arguments @@ -8,6 +9,15 @@ from IPython.utils.capture import capture_output from PIL import Image +from jinja2 import Template, StrictUndefined + +g_cell_id = 0 + +def compile_template(in_file: str, **variables) -> str: + with open(f"{in_file}", "r", encoding="utf-8") as file: + template = Template(file.read(), undefined=StrictUndefined) + return template.render(**variables) + @magics_class class SplitViewMagic(Magics): @@ -16,16 +26,15 @@ class SplitViewMagic(Magics): "--position", "-p", default="50%", - help=("The position where the slider starts"), + help=("The start position of the slider"), ) @magic_arguments.argument( "--height", "-h", default="300", help=( - "The height that the widget has. The width will be adjusted automatically. \ - If height is choosen 'auto', the height will be defined by the resolution \ - in vertical direction of the first image." + "The widget's height. The width will be adjusted automatically. \ + If height is `auto`, the vertical resolution of the first image is used." ), ) @cell_magic @@ -43,7 +52,7 @@ def splity(self, line, cell): png_bytes_data = data["image/png"] out_images_base64.append(png_bytes_data) - # get the parameters the configure the widget + # get the parameters that configure the widget args = magic_arguments.parse_argstring(SplitViewMagic.splity, line) slider_position = args.position @@ -53,17 +62,20 @@ def splity(self, line, cell): imgdata = b64decode(out_images_base64[0]) # maybe possible without the PIL dependency? im = Image.open(io.BytesIO(imgdata)) - width, height = im.size - widget_height = height + widget_height = im.size[1] - html_code = f""" -
-
- ' ' -
-
- - - """ + image_data_urls = [f"data:image/jpeg;base64,{base64.strip()}" for base64 in out_images_base64] + + # every juxtapose html node needs unique id + global g_cell_id + html_code = compile_template( + os.path.join((os.path.dirname(__file__)), "inject.html"), + cell_id=g_cell_id, + image_data_urls=image_data_urls, + slider_position=slider_position, + wrapper_height=int(widget_height)+4, + height=int(widget_height), + ) + g_cell_id += 1 display(HTML(html_code)) - \ No newline at end of file + diff --git a/pyproject.toml b/pyproject.toml index dbdc181c..d973aa18 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,20 +4,26 @@ version = "0.0.4" description = "Making before/after image sliders in JupyterLab" authors = ["kolibril13 <44469195+kolibril13@users.noreply.github.com>"] license = "MIT" +include = [ + "vendor/juxtapose/build/css/juxtapose.css", + "vendor/juxtapose/build/js/juxtapose.min.js", +] [tool.poetry.dependencies] python = ">=3.8,<3.11" ipython = ">=7.0.0" ipykernel = ">=6.13.0" Pillow = ">=9.1.0" +Jinja2 = "^3.1.2" [tool.poetry.dev-dependencies] -black = {extras = ["jupyter"], version = ">=22.3.0"} +black = { extras = ["jupyter"], version = ">=22.3.0" } matplotlib = ">=3.5.1" scipy = ">=1.8.0" scikit-image = ">=0.19.2" pytest = ">=7.1.2" isort = ">=5.10.1" +jupyterlab = "^3.4.3" [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/vendor/juxtapose b/vendor/juxtapose new file mode 160000 index 00000000..975e8f73 --- /dev/null +++ b/vendor/juxtapose @@ -0,0 +1 @@ +Subproject commit 975e8f730bbc73c98af70b47e721d0ea67ba01ff