Karthik Bhandary
e82352f156
feat(web): Add Jupyter Notebook (.ipynb) Rendering Support ( #37433 )
...
### Summary
Closes #37308
Adds native rendering support for Jupyter notebook files (`.ipynb`) in
Gitea using backend rendering, 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
**Evolution:** Initially implemented frontend rendering using `marked`
and `Shiki` libraries. After review feedback, migrated to backend
rendering for better performance, security, and consistency with Gitea
architecture.
#### Backend Rendering Advantages
- Server-side HTML generation eliminates client-side parsing overhead
- Integrates with Gitea existing markup sanitizer for security
- Uses Chroma for syntax highlighting (consistent with code files)
- Uses Goldmark for markdown rendering (consistent with `.md` files)
- No additional frontend dependencies required
- Better performance for large notebooks
### Features
#### Supported Cell Types
- **Markdown cells:** Rendered with Goldmark (tables, lists, links, code
blocks, etc.)
- **Code cells:** Syntax-highlighted with Chroma, execution counts,
language detection from notebook metadata
- **Output cells:** Multiple output types in a single cell
#### Supported Output Types
- ✅ Text/plain outputs
- ✅ Images (PNG, JPEG, SVG) with base64 data URIs
- ✅ HTML outputs (tables, DataFrames, formatted text)
- ✅ LaTeX/math equations (rendered as code blocks)
- ✅ Error outputs with traceback (styled in red)
- ✅ Stream outputs (`stdout`/`stderr`)
- ⚠️ Interactive widgets (Plotly, ipywidgets) show informative messages
- ⚠️ JavaScript outputs show security warning (disabled for safety)
#### 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
- Execution count of `null` or `0`
- `nbformat` version compatibility (only renders `nbformat 4+`, shows
message for older versions)
### Changes
#### Backend (Go)
- `modules/markup/jupyter/jupyter.go` (**NEW**)
- Jupyter notebook renderer implementation
- Parses `.ipynb` JSON structure and generates HTML
- Integrates Chroma for code syntax highlighting
- Integrates Goldmark for markdown cell rendering
- Dynamic language detection from notebook metadata
- Handles all standard Jupyter output types
- Comprehensive error handling with user-friendly messages
- `modules/markup/renderer.go` (**MODIFIED**)
- Registered Jupyter renderer in markup system
- `main.go` (**MODIFIED**)
- Import Jupyter renderer package for initialization
#### Styling (CSS)
- `web_src/css/markup/jupyter.css` (**NEW**)
- Comprehensive styling for notebook cells, code, outputs
- Uses Gitea CSS variables for consistent theming
- Responsive layout with proper spacing
- Table styling for DataFrame outputs
- Removed parent container padding for consistency with other renderers
#### Sanitizer Rules
- `modules/markup/jupyter/jupyter.go` → `SanitizerRules()`
- Configured HTML sanitization rules for safe rendering:
- Cell structure (markdown, code, input/output wrappers)
- Code highlighting (Chroma classes)
- Images (base64 data URIs only)
- Tables (DataFrames)
- Markdown elements (headers, lists, links, etc.)
### Security Considerations
- Server-side rendering: No client-side JavaScript execution
- HTML sanitization: Strict allowlist for HTML elements and attributes
- Image security: Only base64 data URIs allowed (no external URLs)
- JavaScript disabled: `application/javascript` outputs show warning
- XSS protection: Gitea markup sanitizer handles all HTML output
### Testing
Manual testing performed with various notebooks:
- Markdown rendering (headers, lists, tables, links, code blocks)
- Code cells with execution counts and syntax highlighting
- Multiple output types (text, images, HTML, LaTeX, errors, streams)
- Error handling for edge cases
- Theme compatibility (light/dark mode)
### Screenshots
<img width="1080" height="553" alt="image"
src="https://github.com/user-attachments/assets/aef9afa7-ed96-434d-98b0-b160565fc967 "
/>
<img width="1092" height="552" alt="image"
src="https://github.com/user-attachments/assets/6e61e792-4737-41c1-851e-5c375c1f932a "
/>
<img width="1104" height="622" alt="image"
src="https://github.com/user-attachments/assets/4ac630c1-3a75-4e1c-9bba-c0a27484d001 "
/>
<img width="1104" height="529" alt="image"
src="https://github.com/user-attachments/assets/33750c47-70de-4ab2-893d-e5d09fa8d9c4 "
/>
<img width="1111" height="343" alt="image"
src="https://github.com/user-attachments/assets/52107d9f-0e06-420b-9ab4-1603dcd676b1 "
/>
<img width="1091" height="650" alt="image"
src="https://github.com/user-attachments/assets/0addae21-efa4-44bb-a56e-0418e3d4d227 "
/>
<img width="1077" height="298" alt="image"
src="https://github.com/user-attachments/assets/a3a8c5be-638c-45ff-82f3-816264254ead "
/>
### Dependencies
No new dependencies required:
- Chroma (existing) - Syntax highlighting
- Goldmark (existing) - Markdown rendering
- Standard library - JSON parsing
### Key Design Decisions
- Backend rendering for performance and security
- Reuses existing Gitea infrastructure (Chroma, Goldmark, sanitizer)
- Consistent styling with other markup renderers
- Graceful degradation for unsupported features
---
**Development Note:** This PR was developed with assistance from Amazon
Q Developer and Claude AI for implementation, debugging, and testing.
---------
Signed-off-by: Karthik Bhandary <34509856+karthikbhandary2@users.noreply.github.com >
Co-authored-by: karthik.bhandary <karthik.bhandary@kfintech.com >
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com >
Co-authored-by: bircni <bircni@icloud.com >
2026-06-14 15:52:37 +02:00
Brecht Van Lommel
a46b16f10f
Edit file workflow for creating a fork and proposing changes ( #34240 )
...
When viewing a file that the user can't edit because they can't write to
the branch, the new, upload, patch, edit and delete functionality is no
longer disabled.
If no user fork of the repository exists, there is now a page to create one.
It will automatically create a fork with a single branch matching the one
being viewed, and a unique repository name will be automatically picked.
When a fork exists, but it's archived, a mirror or the user can't write
code to it, there will instead be a message explaining the situation.
If the usable fork exists, a message will appear at the top of the edit page
explaining that the changes will be applied to a branch in the fork. The
base repository branch will be pushed to a new branch to the fork, and
then the edits will be applied on top.
The suggestion to fork happens when accessing /_edit/, so that for
example online documentation can have an "edit this page" link to
the base repository that does the right thing.
Also includes changes to properly report errors when trying to commit
to a new branch that is protected, and when trying to commit to an
existing branch when choosing the new branch option.
Resolves #9017 , #20882
---------
Co-authored-by: Brecht Van Lommel <brecht@blender.org >
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com >
2025-06-22 12:43:43 +00:00