11 Commits
Author SHA1 Message Date
7b1cde99d0 perf(charset): skip plain ASCII text when escaping control characters (#39937)
Every line of file, blame, diff and code preview views goes through
`EscapeControlHTML`, which streamed it through a 32 KiB read buffer and
copied every tag and text part. Views render the `EscapeStatus` before
the content, so every caller holds the complete HTML and streaming can't
help. It is now escaped in one pass over the string and returned
unchanged when nothing needs escaping.

- Skip text of printable ASCII, tabs and newlines, such lines return
immediately
- Render markup and wiki pages into a buffer instead of a pipe and
goroutine, and remove `EscapeControlReader`
- Analyze long text parts in windows overlapping by the detection
context, which bounds memory without changing results
- Escape invalid bytes before a tag, they were moved into the tag part
unescaped and could hide a `<math>` tag

| | before | after |
|---|---|---|
| ASCII line | 5.1 µs, 59 allocs | 0.08 µs, 1 alloc |
| line with one `é` | 3.9 µs, 30 allocs | 0.29 µs, 3 allocs |
| 150 KB document | 2.5 ms, 5.6 MB | 0.27 ms, 0.6 KB |

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-11-09 03:42:30 +00:00
wxiaoguangandLunny Xiao c0ceea2f8f chore: fix various problems (#39298)
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-09-14 22:15:21 +02:00
Sergio Benitezandwxiaoguang 1e13badb39 enhance: truncate but show long lines in diffs (#39279)
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-09-12 11:56:25 +00:00
wxiaoguang dea71bb8ba enhance: user-friendly packages setup manual (#38946)
* replace #35564
* fix #36992
2026-08-17 17:43:34 +00:00
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
wxiaoguang 523822090c chore: introduce HTMLBuilder (#37688) 2026-05-13 17:06:53 +00:00
Heath Dutton🕴️andwxiaoguang 0f78b99998 Fix markup heading parsing, fix emphasis parsing (#36284)
Fixes #36106, fix #17958

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-23 20:24:58 +00:00
silverwindandwxiaoguang 1e50cec0b3 Improve labels-list rendering (#34846)
Make labels list use consistent gap

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-06-27 23:12:25 +08:00
wxiaoguangandsilverwind 327048c106 Refactor template helper (#34819)
FIx abuses and remove unused code

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2025-06-24 01:27:35 +08:00
wxiaoguang 386c1ed908 Refactor HTMLFormat, update chroma render, fix js error (#33136)
A small refactor to improve HTMLFormat, to help to prevent low-level
mistakes.

And fix #33141, fix #33139
2025-01-08 03:44:32 +00:00
wxiaoguang 8a20fba8eb Refactor markup render system (#32533)
Remove unmaintainable sanitizer rules. No need to add special "class"
regexp rules anymore, use RenderInternal.SafeAttr instead, more details
(and examples) are in the tests
2024-11-18 13:25:42 +08:00