Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## Unreleased

- SVG `<foreignObject>` support: text labels in SVGs generated by mermaid-cli, draw.io, and D3.js now render correctly. Embedded HTML is converted to native SVG `<text>` elements before rendering. Structural HTML (tables, lists, nested divs) is preserved as readable text with row/cell separation.
- SVG text inherits fill color and font-family from the document's stylesheet.
- SVG `<foreignObject>` elements inside `<switch>` with an existing `<text>` fallback are left untouched.
- SVG `<foreignObject>` x/y positioning attributes are respected.
- Expanded HTML entity decoding: numeric character references (`&#NNN;`, `&#xHHH;`) and common named entities (`&nbsp;`, `&mdash;`, `&rarr;`, etc.) are now decoded in foreignObject text.

## 0.1.2

- Animated GIF playback via `--animate` flag (kitty animation protocol)
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "kittyview"
version = "0.1.2"
edition = "2024"
rust-version = "1.85"
rust-version = "1.87"
license = "Apache-2.0"
description = "Display images in kitty-compatible terminals"
repository = "https://github.com/gominimal/kittyview"
Expand Down Expand Up @@ -30,3 +30,4 @@ resvg = "0.47"
clap = { version = "4", features = ["derive"] }
clap_complete = "4"
base64 = "0.22"
roxmltree = "0.21"
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ kittyview completions fish > ~/.config/fish/completions/kittyview.fish
| PNG | `.png` |
| JPEG | `.jpg`, `.jpeg` |
| GIF | `.gif` |
| SVG | `.svg`, `.svgz` (with full text rendering) |
| SVG | `.svg`, `.svgz` (text rendering, see [SVG notes](#svg-text-rendering)) |
| WebP | `.webp` |
| BMP | `.bmp` |
| TIFF | `.tif`, `.tiff` |
Expand All @@ -113,6 +113,19 @@ kittyview completions fish > ~/.config/fish/completions/kittyview.fish

SVG files are detected by extension or by content sniffing (`<svg` in the first 1KB).

## SVG text rendering

kittyview renders SVGs using [resvg](https://github.com/linebender/resvg), which supports native SVG `<text>` elements out of the box.

Many tools (mermaid-cli, draw.io, D3.js) generate SVGs that use `<foreignObject>` with embedded HTML for text labels instead of native `<text>` elements. kittyview detects these and converts them to `<text>` on a best-effort basis. This covers the common cases well, but has some limitations:

- **Text wrapping**: HTML text that relies on CSS word-wrap (without explicit `<br>` tags) will render as a single line. Most mermaid diagrams use `<br>` and are unaffected.
- **Rich formatting**: Bold, italic, and per-element font size or color differences inside labels are not preserved. The global font and color from the SVG's stylesheet are used.
- **Structural HTML**: Tables, lists, and nested divs are rendered as readable plain text (cells separated by tabs, rows and list items on separate lines) but without visual table/list formatting. MathML and form elements are not supported.
- **Edge label backgrounds**: Semi-transparent background rectangles behind edge labels are not reproduced.

SVGs that already use native `<text>` elements (e.g. Inkscape, some mermaid-cli configurations) render without these limitations.

## SVG resource access

When rendering SVGs, external file references (`<image href="...">`) are blocked by default. Use `--svg-resources` to control this:
Expand Down Expand Up @@ -147,7 +160,7 @@ cat diagram.svg | kittyview --svg-resources tree

## Building from source

Requires Rust 1.85+ (edition 2024).
Requires Rust 1.87+ (edition 2024).

```
cargo build --release
Expand Down
1 change: 1 addition & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Do **not** open a public issue for security vulnerabilities.
Security-relevant areas of kittyview include:

- **SVG rendering**: SVGs are a rich format that can reference external files, embed scripts, and contain deeply nested structures. kittyview uses [resvg](https://github.com/linebender/resvg) (pure Rust, no scripting support) and defaults to blocking external file access (`--svg-resources none`).
- **SVG foreignObject conversion**: SVGs containing `<foreignObject>` elements (common in mermaid-cli, draw.io, and D3.js output) are preprocessed before rendering. Embedded HTML is stripped to plain text and replaced with native SVG `<text>` elements. No HTML is interpreted or executed -- all markup is discarded and only text content is preserved. Entity decoding is limited to a fixed set of named entities and numeric character references.
- **Image decoding**: Malformed images could trigger bugs in decoder libraries. All decoders are pure Rust (no C code).
- **Terminal escape sequences**: Malformed output could corrupt terminal state. kittyview buffers all protocol output before writing and validates terminal support before emitting.

Expand Down
Loading