Skip to content

Add Jupyter Notebook (.ipynb) Rendering Support#37433

Draft
karthikbhandary2 wants to merge 66 commits intogo-gitea:mainfrom
karthikbhandary2:main
Draft

Add Jupyter Notebook (.ipynb) Rendering Support#37433
karthikbhandary2 wants to merge 66 commits intogo-gitea:mainfrom
karthikbhandary2:main

Conversation

@karthikbhandary2
Copy link
Copy Markdown
Contributor

Summary

Closes #37308
Adds native rendering support for Jupyter notebook files (.ipynb) in Gitea, allowing users to view formatted notebooks with code cells, markdown, outputs, and visualizations directly in the repository browser.

Motivation

Jupyter notebooks are widely used in data science, machine learning, and scientific computing. Currently, Gitea displays .ipynb files as raw JSON, making them difficult to read. This feature enables users to view notebooks in a formatted, readable way similar to GitHub and GitLab.

Implementation Approach

Initially attempted to use the notebookjs library as suggested by @silverwind but encountered several issues:

  • Module bundling failures: Library didn't integrate properly with Vite/Rolldown build system
  • Runtime errors: API incompatibilities causing "F is not a function" errors
  • Maintenance concerns: Library not actively maintained (last activity 2 years ago)

So Implemented a custom renderer that:

  • Provides full control over HTML structure and styling
  • Integrates seamlessly with Gitea's existing CSS framework
  • Handles edge cases gracefully with proper error messages
  • Uses existing KaTeX dependency for math rendering
  • No additional dependencies required

Features

Supported Cell Types

  • Markdown cells: Rendered with full formatting (headers, bold, code, tables, etc.)
  • Code cells: Syntax-highlighted Python code with execution counts
  • Output cells: Multiple output types in a single cell

Supported Output Types

  • ✅ Text/plain outputs
  • ✅ Images (PNG, JPEG, SVG) with base64 encoding
  • ✅ HTML outputs (tables, formatted text)
  • ✅ LaTeX/math equations (rendered with KaTeX)
  • ✅ Error outputs with traceback (styled in red)
  • ✅ Stream outputs (stdout/stderr)
  • ✅ Interactive widget placeholders (Plotly, ipywidgets) with informative messages
  • ✅ JavaScript output warnings (disabled for security)

Edge Cases Handled

  • Empty notebooks or notebooks with no outputs
  • Corrupted JSON with graceful error display
  • Mixed output types in single cell
  • Large base64-encoded images
  • Per-output error handling (one failed output doesn't break entire notebook)

Changes

Frontend (TypeScript/JavaScript)

  • web_src/js/render/plugins/frontend-jupyter-notebook.ts (NEW)

    • Custom Jupyter notebook renderer implementation
    • Parses .ipynb JSON structure and generates formatted HTML
    • Handles all standard Jupyter output types
    • Integrates with existing KaTeX for math rendering
    • Comprehensive error handling with user-friendly messages
  • web_src/js/external-render-frontend.ts

    • Registered Jupyter notebook renderer in frontend plugin system

Styling (CSS)

  • web_src/css/features/jupyter.css (NEW)
    • Comprehensive styling for notebook cells, code, outputs
    • Matches Gitea's design system with CSS variables
    • Responsive layout with proper spacing
    • Syntax highlighting integration
    • Table styling for dataframe outputs

Backend (Go)

  • modules/markup/external/frontend.go

    • Added notebook data structures (notebookCell, notebookData)
    • Preprocessing function to render markdown cells server-side
    • Integration with external renderer framework
    • Proper error handling for malformed notebooks
  • modules/markup/external/external.go

    • Registered .ipynb file pattern for frontend rendering
    • Configured iframe sandbox settings for security

Tests (E2E)

  • tests/e2e/jupyter-render.test.ts (NEW)
    • Comprehensive test suite covering:
      • Basic notebook rendering (markdown + code + outputs)
      • Notebooks with no outputs
      • Error output rendering
      • Mixed output types in single cell
    • Batch file creation to avoid git conflicts
    • Validates proper HTML structure and content

Security Considerations

  • XSS Protection: Error messages use DOM methods instead of innerHTML
  • JavaScript Execution: Disabled by default with warning message
  • Content Sandbox: Notebooks rendered in iframe with restricted permissions
  • HTML Sanitization: Embedded HTML outputs are sandboxed

Testing

Run E2E tests:

GITEA_TEST_E2E_URL=http://localhost:3000 GITEA_TEST_E2E_USER=user1 GITEA_TEST_E2E_PASSWORD=pass npx playwright test tests/e2e/jupyter-render.test.ts

All tests pass with validation for:

  • Markdown rendering with formatting
  • Code cells with execution counts and prompts
  • Multiple output types (text, images, HTML, LaTeX, errors)
  • Error handling for edge cases
  • Proper iframe sizing and layout

Screenshots

image image image image image

Dependencies

No new dependencies added. Uses existing:

  • KaTeX (already in package.json) for math rendering
  • Gitea's markdown renderer for markdown cells

Development Note: This PR was developed with assistance from Amazon Q Developer and Claude AI for implementation, debugging, and testing.

Comment thread web_src/css/index.css Outdated
@silverwind silverwind requested a review from Copilot April 28, 2026 04:40
@wxiaoguang wxiaoguang marked this pull request as ready for review April 28, 2026 04:40
@wxiaoguang wxiaoguang removed their request for review April 28, 2026 04:41
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new frontend external renderer to display .ipynb files as formatted Jupyter notebooks inside Gitea’s repository file viewer, instead of showing raw JSON.

Changes:

  • Register a new jupyter-notebook frontend renderer for *.ipynb.
  • Add a custom TypeScript notebook renderer plugin + dedicated CSS styling.
  • Add Playwright e2e coverage for basic notebook rendering scenarios.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
web_src/js/render/plugins/frontend-jupyter-notebook.ts Implements client-side parsing/rendering of notebook cells and outputs (markdown/code/output types).
web_src/js/external-render-frontend.ts Registers the new jupyter-notebook frontend plugin for the external-render framework.
web_src/css/features/jupyter.css Adds notebook-specific styling for cells, prompts, code blocks, and outputs.
tests/e2e/jupyter-render.test.ts Adds e2e tests to validate notebook rendering in the external-render iframe.
modules/markup/external/external.go Registers *.ipynb to use the frontend external renderer.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread web_src/js/render/plugins/frontend-jupyter-notebook.ts
Comment thread web_src/js/render/plugins/frontend-jupyter-notebook.ts Outdated
Comment thread web_src/js/render/plugins/frontend-jupyter-notebook.ts Outdated
Comment thread web_src/js/render/plugins/frontend-jupyter-notebook.ts
Comment thread web_src/css/features/jupyter.css Outdated
Comment thread tests/e2e/jupyter-render.test.ts
Comment thread web_src/js/render/plugins/frontend-jupyter-notebook.ts Outdated
Comment thread web_src/js/render/plugins/frontend-jupyter-notebook.ts
@karthikbhandary2
Copy link
Copy Markdown
Contributor Author

Hey suggested changes were made. Please check now.

@karthikbhandary2
Copy link
Copy Markdown
Contributor Author

Here is the result after using maker:
image
image
image
image
image

It is working as expected.

Comment thread web_src/js/render/plugins/frontend-jupyter-notebook.ts Outdated
Comment thread web_src/js/render/plugins/frontend-jupyter-notebook.ts Outdated
Comment thread web_src/js/render/plugins/frontend-jupyter-notebook.ts Outdated
Comment thread web_src/js/render/plugins/frontend-jupyter-notebook.ts Outdated
@wxiaoguang wxiaoguang marked this pull request as draft April 29, 2026 08:01
@silverwind
Copy link
Copy Markdown
Member

silverwind commented Apr 29, 2026

Here is the result after using maker

Are these fonts the same as the regular gitea pages uses? I see serif fonts and Gitea never renders serif, those should be sans-serif and use the existing font stacks from CSS variables.

If that library injects CSS, I'd recommend disabling that and make it work with Gitea's existing markup CSS in https://github.com/go-gitea/gitea/tree/main/web_src/css/markup which applies to .markup class which you probably need to import into the iframe.

karthik.bhandary and others added 2 commits April 29, 2026 11:18
@karthikbhandary2
Copy link
Copy Markdown
Contributor Author

Here is the result after using maker

Are these fonts the same as the regular gitea pages uses? I see serif fonts and Gitea never renders serif, those should be sans-serif and use the existing font stacks from CSS variables.

If that library injects CSS, I'd recommend disabling that and make it work with Gitea's existing markup CSS in https://github.com/go-gitea/gitea/tree/main/web_src/css/markup which applies to .markup class which you probably need to import into the iframe.

Now its only using san-serif and existing font-stack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. type/feature Completely new functionality. Can only be merged if feature freeze is not active.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Native Jupyter Notebook (.ipynb) Rendering

5 participants