Skip to content

feat: Add support for rendering .ipynb Jupyter/IPython notebooks - #491

Merged
thomiceli merged 10 commits into
thomiceli:masterfrom
blacklight:390/ipynb-support
Sep 21, 2025
Merged

feat: Add support for rendering .ipynb Jupyter/IPython notebooks#491
thomiceli merged 10 commits into
thomiceli:masterfrom
blacklight:390/ipynb-support

Conversation

@blacklight

@blacklight blacklight commented Jul 30, 2025

Copy link
Copy Markdown
Contributor
  • Basic cells rendering
  • Syntax highlighting
  • Images
  • Markdown rendering
  • Math rendering

Closes: #390

@blacklight
blacklight marked this pull request as draft July 30, 2025 00:01
@blacklight blacklight changed the title WIP: feat: Added support for rendering .ipynb Jupyter/IPython notebooks feat: Add support for rendering .ipynb Jupyter/IPython notebooks Jul 30, 2025
@blacklight
blacklight marked this pull request as ready for review August 3, 2025 15:05
@blacklight

blacklight commented Aug 3, 2025

Copy link
Copy Markdown
Contributor Author

@thomiceli this is ready for review. The implementation is done on the frontend, which AFAIK is what Github does too, so we don't need to over-complicate the backend logic, nor handle any special cases where you have pre-rendered and post-rendered content.

The dependencies added to the bundle are:

  • highlight.js (required because now we have some code that needs to be highlighted directly in the frontend)
  • showdown (required to render Markdown cells directly in the frontend)
  • katex (required to render LaTeX fragments)

I have deployed the branch on my instance, everything seems to work fine and the results are similar to the ones you get on Github - compare this (self-hosted) with this (Github) (btw this rendering logic seems to be one order of magnitude faster than Github's)

I think that, given the use-case of notebooks (they are usually larger JSON files with a lot of base64 blobs), it may probably be safer to provide an Upload file option too rather than only a textarea, what do you think?

@thomiceli

thomiceli commented Aug 18, 2025

Copy link
Copy Markdown
Owner

Hi, thanks a lot for this PR :)
I was thinking maybe it misses Input/Output prompts, and also use dark mode code blocks when we user is in dark mode, what do you think ?

I think that, given the use-case of notebooks (they are usually larger JSON files with a lot of base64 blobs), it may probably be safer to provide an Upload file option too rather than only a textarea, what do you think?

That's indeed a good solution. Maybe we can even allow binary files at this point, like images for latex documents for example.

@blacklight

blacklight commented Aug 18, 2025

Copy link
Copy Markdown
Contributor Author

I was thinking maybe it misses Input/Output prompts

They should be covered by the output_type = 'stream' case - I just uploaded a quick test to validate it.

use dark mode code blocks when we user is in dark mode

Added here 37313e0

That's indeed a good solution. Maybe we can even allow binary files at this point, like images for latex documents for example.

Indeed - I'm working on a generic file uploader in another PR, but I hadn't though of the binary upload case yet (I guess that we may still want to whitelist some specific mimetypes, like images, or maybe other media too?)

Btw LaTeX support in Markdown/text cells comes out of the box in this PR too - the $...$, $$...$$ and \(...\) should all be supported. Rendering happens directly on the client with no need for static images.

@thomiceli

Copy link
Copy Markdown
Owner

They should be covered by the output_type = 'stream' case - I just uploaded a quick test to validate it.

I'm not sure i'm seeing it (lastest versions of Firefox and Chromium)

image

@blacklight

blacklight commented Aug 25, 2025

Copy link
Copy Markdown
Contributor Author

@thomiceli I do see the same indeed, and that's probably what I'd expect in this case. The source code for that cell looks like this:

{
  "cell_type": "code",
  "execution_count": 2,
  "id": "a34a357f-1360-403f-a8ce-0005ec083c3d",
  "metadata": {},
  "outputs": [
    {
      "name": "stdin",
      "output_type": "stream",
      "text": [
        ":  test\n"
      ]
    },
    {
      "name": "stdout",
      "output_type": "stream",
      "text": [
        "test\n"
      ]
    }
  ],
  "source": [
    "a = input(': ')\n",
    "print(a)"
  ]
}

So all information that has output_type="stream" is shown as-is in the output area, regardless of whether it's stdout or stdin.

Could you provide an example with missing input/output text?

@thomiceli

thomiceli commented Aug 31, 2025

Copy link
Copy Markdown
Owner

@blacklight Take this file for example.

The math expressions are not formatted, and input/output prompts are missing ; I just noticed there is also code missing

What I see in https://jupyter.org/try-jupyter/lab/ (similar output on https://gist.github.com) :

image

What I see on Opengist with your changes :

image

I don't know much about Jpynb files so I can't help much

@thomiceli

Copy link
Copy Markdown
Owner

@blacklight I took the liberty to rebase your branch from master, and I will merge this ; we can still apply more fixes later.

@thomiceli
thomiceli merged commit c02bf97 into thomiceli:master Sep 21, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Render Jupyter/IPython notebook

2 participants