viewinline 0.2.1__tar.gz → 0.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- viewinline-0.2.1/README.md → viewinline-0.2.3/PKG-INFO +58 -9
- viewinline-0.2.1/PKG-INFO → viewinline-0.2.3/README.md +25 -39
- {viewinline-0.2.1 → viewinline-0.2.3}/pyproject.toml +4 -4
- {viewinline-0.2.1 → viewinline-0.2.3}/src/viewinline/viewinline.py +161 -16
- viewinline-0.2.3/viewinline_gif1.gif +0 -0
- viewinline-0.2.3/viewinline_gif2.gif +0 -0
- {viewinline-0.2.1 → viewinline-0.2.3}/.github/FUNDING.yml +0 -0
- {viewinline-0.2.1 → viewinline-0.2.3}/.gitignore +0 -0
- {viewinline-0.2.1 → viewinline-0.2.3}/LICENSE +0 -0
- {viewinline-0.2.1 → viewinline-0.2.3}/src/viewinline/__init__.py +0 -0
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: viewinline
|
|
3
|
+
Version: 0.2.3
|
|
4
|
+
Summary: Quick look geospatial viewer for the terminal, with inline image previews
|
|
5
|
+
Project-URL: Homepage, https://github.com/nkeikon/viewinline
|
|
6
|
+
Project-URL: Repository, https://github.com/nkeikon/viewinline
|
|
7
|
+
Project-URL: Issues, https://github.com/nkeikon/viewinline/issues
|
|
8
|
+
Author: Keiko Nomura
|
|
9
|
+
License: Apache-2.0
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Python: >=3.9
|
|
12
|
+
Requires-Dist: geopandas
|
|
13
|
+
Requires-Dist: matplotlib
|
|
14
|
+
Requires-Dist: numpy
|
|
15
|
+
Requires-Dist: pandas
|
|
16
|
+
Requires-Dist: pillow
|
|
17
|
+
Requires-Dist: pyogrio
|
|
18
|
+
Requires-Dist: rasterio
|
|
19
|
+
Provides-Extra: all
|
|
20
|
+
Requires-Dist: duckdb; extra == 'all'
|
|
21
|
+
Requires-Dist: h5py; extra == 'all'
|
|
22
|
+
Requires-Dist: netcdf4; extra == 'all'
|
|
23
|
+
Requires-Dist: pyarrow; extra == 'all'
|
|
24
|
+
Provides-Extra: hdf5
|
|
25
|
+
Requires-Dist: h5py; extra == 'hdf5'
|
|
26
|
+
Provides-Extra: netcdf
|
|
27
|
+
Requires-Dist: netcdf4; extra == 'netcdf'
|
|
28
|
+
Provides-Extra: parquet
|
|
29
|
+
Requires-Dist: pyarrow; extra == 'parquet'
|
|
30
|
+
Provides-Extra: sql
|
|
31
|
+
Requires-Dist: duckdb; extra == 'sql'
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
1
34
|
# viewinline
|
|
2
35
|
[](https://pepy.tech/project/viewinline)
|
|
3
36
|
[](https://pypi.org/project/viewinline/)
|
|
@@ -6,13 +39,18 @@
|
|
|
6
39
|
**Quick-look geospatial viewer for compatible terminals.**
|
|
7
40
|
Displays rasters, vectors, and tabular data directly in the terminal with no GUI and no temporary files.
|
|
8
41
|
|
|
42
|
+
<p align="center">
|
|
43
|
+
<a href="viewinline_gif1.gif"><img src="viewinline_gif1.gif" width="49%"></a>
|
|
44
|
+
<a href="viewinline_gif2.gif"><img src="viewinline_gif2.gif" width="49%"></a>
|
|
45
|
+
</p>
|
|
46
|
+
|
|
9
47
|
Think of it as `ls` for geospatial files — designed for quick visual inspection at the command line, not a replacement for QGIS, ArcGIS, or analytical workflows.
|
|
10
48
|
|
|
11
49
|
Particularly useful on HPC systems and remote servers accessed via SSH. Images render on your local terminal without X11 forwarding, VNC, or file downloads.
|
|
12
50
|
|
|
13
51
|
This tool combines the core display logic of `viewtif` and `viewgeom`, but is **non-interactive**: you can't zoom, pan, or switch colormaps on the fly. Instead, you control everything through command-line options (e.g. --display, --color-by, --colormap).
|
|
14
52
|
|
|
15
|
-
It uses the iTerm2 inline image protocol (OSC 1337) to
|
|
53
|
+
It uses the iTerm2 inline image protocol (OSC 1337) in supported terminals, and falls back to `chafa` in others, which displays real high-res images in terminals like kitty and Ghostty, and colored block-art (ASCII art) previews in Terminal.app, VS Code, and most Linux terminals. Without `chafa` installed, non-iTerm2-family terminals show an info message instead.
|
|
16
54
|
|
|
17
55
|
## Installation
|
|
18
56
|
Requires Python 3.9 or later.
|
|
@@ -58,18 +96,32 @@ viewinline data.geoparquet --table --where "POP > 100000" --sort POP --desc
|
|
|
58
96
|
|
|
59
97
|
## Compatible terminals
|
|
60
98
|
|
|
61
|
-
|
|
99
|
+
Native (no extra install required): images render via the iTerm2 inline image protocol on:
|
|
62
100
|
|
|
63
101
|
- **iTerm2** (macOS)
|
|
64
102
|
- **WezTerm** (cross-platform)
|
|
65
103
|
- **Konsole** (Linux/KDE)
|
|
66
104
|
- **Rio**, **Contour** (cross-platform)
|
|
67
105
|
|
|
68
|
-
|
|
106
|
+
Via `chafa` (recommended for everyone else): install chafa and viewinline works in nearly every terminal:
|
|
107
|
+
- kitty, Ghostty, foot — real high-resolution images via the kitty graphics protocol or sixel
|
|
108
|
+
- Terminal.app, VS Code, GNOME Terminal, Alacritty, Warp, Hyper — colored block-art previews with 24-bit color
|
|
109
|
+
|
|
110
|
+
Install chafa once (it's a system binary, available across all conda/virtualenv environments):
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
brew install chafa # macOS
|
|
114
|
+
sudo apt install chafa # Debian/Ubuntu
|
|
115
|
+
sudo dnf install chafa # Fedora
|
|
116
|
+
```
|
|
117
|
+
Without chafa, terminals outside the native list above show an info message instead of an image.
|
|
118
|
+
You can also force the chafa path on any terminal by setting `INLINE_VIEWER_ENGINE=chafa`.
|
|
69
119
|
|
|
70
120
|
**SSH/HPC usage:** Works over SSH when connecting from a compatible terminal. Images render on your local machine, not the remote server. No X11 forwarding or VNC required.
|
|
71
121
|
|
|
72
|
-
**tmux/screen:** Inline images
|
|
122
|
+
**tmux/screen:** Inline images work inside tmux only when the outer terminal is iTerm2 (or WezTerm/Konsole/Rio/Contour). In tmux with other outer terminals (kitty, Terminal.app, etc.), viewinline displays ASCII art previews instead of full-quality images.
|
|
123
|
+
|
|
124
|
+
**Fallback:** In terminals that do not support inline images, you can fallback to ASCII art by installing [`chafa`](https://hpjansson.org/chafa/) command-line tool. Install `chafa` with your package manager (e.g. `brew install chafa` or `sudo apt install chafa`). You can also force the use of `chafa` by setting the environment variable `INLINE_VIEWER_ENGINE=chafa`.
|
|
73
125
|
|
|
74
126
|
## Features
|
|
75
127
|
- Previews rasters, vectors, and tabular data directly in the terminal
|
|
@@ -130,6 +182,7 @@ The iTerm2 inline image protocol (OSC 1337) is supported by:
|
|
|
130
182
|
- `numpy`, `pandas` — data handling
|
|
131
183
|
|
|
132
184
|
**Optional dependencies:**
|
|
185
|
+
- `chafa` — strongly recommended for terminal coverage beyond iTerm2/WezTerm/Konsole/Rio/Contour. System binary, not a Python package. See "Terminal support" above for install instructions.
|
|
133
186
|
- `duckdb` — required for `--where`, `--sort`, `--sql`, `--limit` with filtering
|
|
134
187
|
```bash
|
|
135
188
|
pip install duckdb
|
|
@@ -188,11 +241,7 @@ CSV and Parquet:
|
|
|
188
241
|
```
|
|
189
242
|
|
|
190
243
|
## Need help?
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
👉 [Ask the viewtif + viewgeom + viewinline Helper](https://chatgpt.com/g/g-698b61c42f788191b884aed1b99dfcd8-viewtif-viewgeom-viewinline-helper)
|
|
194
|
-
|
|
195
|
-
👉 For NASA staff: find 'viewtif + viewgeom + viewinline Helper' via the ChatGSFC Agent Marketplace
|
|
244
|
+
NASA staff can ask questions about usage via the documentation-based assistant 'viewtif + viewgeom + viewinline Helper' via the ChatGSFC Agent Marketplace.
|
|
196
245
|
|
|
197
246
|
## License
|
|
198
247
|
This project is released under the Apache License 2.0 © 2026 Keiko Nomura.
|
|
@@ -1,33 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: viewinline
|
|
3
|
-
Version: 0.2.1
|
|
4
|
-
Summary: Quick look geospatial viewer for iTerm2 compatible terminals
|
|
5
|
-
Project-URL: Homepage, https://github.com/nkeikon/viewinline
|
|
6
|
-
Project-URL: Repository, https://github.com/nkeikon/viewinline
|
|
7
|
-
Project-URL: Issues, https://github.com/nkeikon/viewinline/issues
|
|
8
|
-
Author: Keiko Nomura
|
|
9
|
-
License: Apache-2.0
|
|
10
|
-
License-File: LICENSE
|
|
11
|
-
Requires-Python: >=3.9
|
|
12
|
-
Requires-Dist: geopandas
|
|
13
|
-
Requires-Dist: matplotlib
|
|
14
|
-
Requires-Dist: numpy
|
|
15
|
-
Requires-Dist: pandas
|
|
16
|
-
Requires-Dist: pillow
|
|
17
|
-
Requires-Dist: pyogrio
|
|
18
|
-
Requires-Dist: rasterio
|
|
19
|
-
Provides-Extra: all
|
|
20
|
-
Requires-Dist: duckdb; extra == 'all'
|
|
21
|
-
Requires-Dist: h5py; extra == 'all'
|
|
22
|
-
Requires-Dist: pyarrow; extra == 'all'
|
|
23
|
-
Provides-Extra: hdf5
|
|
24
|
-
Requires-Dist: h5py; extra == 'hdf5'
|
|
25
|
-
Provides-Extra: parquet
|
|
26
|
-
Requires-Dist: pyarrow; extra == 'parquet'
|
|
27
|
-
Provides-Extra: sql
|
|
28
|
-
Requires-Dist: duckdb; extra == 'sql'
|
|
29
|
-
Description-Content-Type: text/markdown
|
|
30
|
-
|
|
31
1
|
# viewinline
|
|
32
2
|
[](https://pepy.tech/project/viewinline)
|
|
33
3
|
[](https://pypi.org/project/viewinline/)
|
|
@@ -36,13 +6,18 @@ Description-Content-Type: text/markdown
|
|
|
36
6
|
**Quick-look geospatial viewer for compatible terminals.**
|
|
37
7
|
Displays rasters, vectors, and tabular data directly in the terminal with no GUI and no temporary files.
|
|
38
8
|
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="viewinline_gif1.gif"><img src="viewinline_gif1.gif" width="49%"></a>
|
|
11
|
+
<a href="viewinline_gif2.gif"><img src="viewinline_gif2.gif" width="49%"></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
39
14
|
Think of it as `ls` for geospatial files — designed for quick visual inspection at the command line, not a replacement for QGIS, ArcGIS, or analytical workflows.
|
|
40
15
|
|
|
41
16
|
Particularly useful on HPC systems and remote servers accessed via SSH. Images render on your local terminal without X11 forwarding, VNC, or file downloads.
|
|
42
17
|
|
|
43
18
|
This tool combines the core display logic of `viewtif` and `viewgeom`, but is **non-interactive**: you can't zoom, pan, or switch colormaps on the fly. Instead, you control everything through command-line options (e.g. --display, --color-by, --colormap).
|
|
44
19
|
|
|
45
|
-
It uses the iTerm2 inline image protocol (OSC 1337) to
|
|
20
|
+
It uses the iTerm2 inline image protocol (OSC 1337) in supported terminals, and falls back to `chafa` in others, which displays real high-res images in terminals like kitty and Ghostty, and colored block-art (ASCII art) previews in Terminal.app, VS Code, and most Linux terminals. Without `chafa` installed, non-iTerm2-family terminals show an info message instead.
|
|
46
21
|
|
|
47
22
|
## Installation
|
|
48
23
|
Requires Python 3.9 or later.
|
|
@@ -88,18 +63,32 @@ viewinline data.geoparquet --table --where "POP > 100000" --sort POP --desc
|
|
|
88
63
|
|
|
89
64
|
## Compatible terminals
|
|
90
65
|
|
|
91
|
-
|
|
66
|
+
Native (no extra install required): images render via the iTerm2 inline image protocol on:
|
|
92
67
|
|
|
93
68
|
- **iTerm2** (macOS)
|
|
94
69
|
- **WezTerm** (cross-platform)
|
|
95
70
|
- **Konsole** (Linux/KDE)
|
|
96
71
|
- **Rio**, **Contour** (cross-platform)
|
|
97
72
|
|
|
98
|
-
|
|
73
|
+
Via `chafa` (recommended for everyone else): install chafa and viewinline works in nearly every terminal:
|
|
74
|
+
- kitty, Ghostty, foot — real high-resolution images via the kitty graphics protocol or sixel
|
|
75
|
+
- Terminal.app, VS Code, GNOME Terminal, Alacritty, Warp, Hyper — colored block-art previews with 24-bit color
|
|
76
|
+
|
|
77
|
+
Install chafa once (it's a system binary, available across all conda/virtualenv environments):
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
brew install chafa # macOS
|
|
81
|
+
sudo apt install chafa # Debian/Ubuntu
|
|
82
|
+
sudo dnf install chafa # Fedora
|
|
83
|
+
```
|
|
84
|
+
Without chafa, terminals outside the native list above show an info message instead of an image.
|
|
85
|
+
You can also force the chafa path on any terminal by setting `INLINE_VIEWER_ENGINE=chafa`.
|
|
99
86
|
|
|
100
87
|
**SSH/HPC usage:** Works over SSH when connecting from a compatible terminal. Images render on your local machine, not the remote server. No X11 forwarding or VNC required.
|
|
101
88
|
|
|
102
|
-
**tmux/screen:** Inline images
|
|
89
|
+
**tmux/screen:** Inline images work inside tmux only when the outer terminal is iTerm2 (or WezTerm/Konsole/Rio/Contour). In tmux with other outer terminals (kitty, Terminal.app, etc.), viewinline displays ASCII art previews instead of full-quality images.
|
|
90
|
+
|
|
91
|
+
**Fallback:** In terminals that do not support inline images, you can fallback to ASCII art by installing [`chafa`](https://hpjansson.org/chafa/) command-line tool. Install `chafa` with your package manager (e.g. `brew install chafa` or `sudo apt install chafa`). You can also force the use of `chafa` by setting the environment variable `INLINE_VIEWER_ENGINE=chafa`.
|
|
103
92
|
|
|
104
93
|
## Features
|
|
105
94
|
- Previews rasters, vectors, and tabular data directly in the terminal
|
|
@@ -160,6 +149,7 @@ The iTerm2 inline image protocol (OSC 1337) is supported by:
|
|
|
160
149
|
- `numpy`, `pandas` — data handling
|
|
161
150
|
|
|
162
151
|
**Optional dependencies:**
|
|
152
|
+
- `chafa` — strongly recommended for terminal coverage beyond iTerm2/WezTerm/Konsole/Rio/Contour. System binary, not a Python package. See "Terminal support" above for install instructions.
|
|
163
153
|
- `duckdb` — required for `--where`, `--sort`, `--sql`, `--limit` with filtering
|
|
164
154
|
```bash
|
|
165
155
|
pip install duckdb
|
|
@@ -218,11 +208,7 @@ CSV and Parquet:
|
|
|
218
208
|
```
|
|
219
209
|
|
|
220
210
|
## Need help?
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
👉 [Ask the viewtif + viewgeom + viewinline Helper](https://chatgpt.com/g/g-698b61c42f788191b884aed1b99dfcd8-viewtif-viewgeom-viewinline-helper)
|
|
224
|
-
|
|
225
|
-
👉 For NASA staff: find 'viewtif + viewgeom + viewinline Helper' via the ChatGSFC Agent Marketplace
|
|
211
|
+
NASA staff can ask questions about usage via the documentation-based assistant 'viewtif + viewgeom + viewinline Helper' via the ChatGSFC Agent Marketplace.
|
|
226
212
|
|
|
227
213
|
## License
|
|
228
214
|
This project is released under the Apache License 2.0 © 2026 Keiko Nomura.
|
|
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "viewinline"
|
|
7
|
-
version = "0.2.
|
|
8
|
-
description = "Quick look geospatial viewer for
|
|
7
|
+
version = "0.2.3"
|
|
8
|
+
description = "Quick look geospatial viewer for the terminal, with inline image previews"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "Apache-2.0" }
|
|
11
11
|
authors = [
|
|
@@ -22,12 +22,12 @@ dependencies = [
|
|
|
22
22
|
"pyogrio",
|
|
23
23
|
"pandas"
|
|
24
24
|
]
|
|
25
|
-
|
|
26
25
|
[project.optional-dependencies]
|
|
27
26
|
sql = ["duckdb"]
|
|
28
27
|
parquet = ["pyarrow"]
|
|
29
28
|
hdf5 = ["h5py"]
|
|
30
|
-
|
|
29
|
+
netcdf = ["netCDF4"]
|
|
30
|
+
all = ["duckdb", "pyarrow", "h5py", "netCDF4"]
|
|
31
31
|
|
|
32
32
|
[project.scripts]
|
|
33
33
|
viewinline = "viewinline.viewinline:main"
|
|
@@ -26,13 +26,14 @@ import pandas as pd
|
|
|
26
26
|
from PIL import Image, ImageOps, ImageDraw, ImageFont
|
|
27
27
|
from matplotlib import colormaps
|
|
28
28
|
import matplotlib as mpl
|
|
29
|
+
import subprocess
|
|
29
30
|
|
|
30
31
|
import warnings
|
|
31
32
|
|
|
32
33
|
warnings.filterwarnings("ignore", message="More than one layer found", category=UserWarning)
|
|
33
34
|
warnings.filterwarnings("ignore", message="Dataset has no geotransform", category=UserWarning)
|
|
34
35
|
|
|
35
|
-
__version__ = "0.2.
|
|
36
|
+
__version__ = "0.2.3"
|
|
36
37
|
|
|
37
38
|
AVAILABLE_COLORMAPS = [
|
|
38
39
|
"viridis", "inferno", "magma", "plasma",
|
|
@@ -40,6 +41,119 @@ AVAILABLE_COLORMAPS = [
|
|
|
40
41
|
"Spectral", "cubehelix", "tab10", "turbo"
|
|
41
42
|
]
|
|
42
43
|
|
|
44
|
+
# Terminals that don't natively support the iTerm2 OSC 1337 inline image
|
|
45
|
+
# protocol. Output for these is routed through chafa instead.
|
|
46
|
+
#
|
|
47
|
+
# Note: presence in this list does NOT mean "no images." Chafa auto-detects
|
|
48
|
+
# the terminal and picks the best output:
|
|
49
|
+
# - kitty (xterm-kitty) → real images via kitty graphics protocol
|
|
50
|
+
# - some others (e.g. foot, Ghostty) → may render real images via sixel
|
|
51
|
+
# or kitty protocol depending on chafa's detection
|
|
52
|
+
# - most others → Unicode block-art preview with 24-bit color
|
|
53
|
+
# (Terminal.app, VS Code, GNOME Terminal, Alacritty, Warp, etc.)
|
|
54
|
+
# Only terminals without chafa installed see no rendering at all.
|
|
55
|
+
|
|
56
|
+
_TERMINALS_WITHOUT_IMAGES = [
|
|
57
|
+
# macOS
|
|
58
|
+
'Apple_Terminal', # $TERM_PROGRAM for Terminal.app
|
|
59
|
+
|
|
60
|
+
# kitty (renders real images via chafa → kitty graphics protocol)
|
|
61
|
+
'xterm-kitty', # $TERM in kitty
|
|
62
|
+
|
|
63
|
+
# tmux / screen (TERM strings; $TMUX env var also signals tmux)
|
|
64
|
+
'screen', 'screen-256color',
|
|
65
|
+
'tmux', 'tmux-256color',
|
|
66
|
+
|
|
67
|
+
# Editors / IDE terminals
|
|
68
|
+
'vscode', # $TERM_PROGRAM in VS Code integrated terminal
|
|
69
|
+
|
|
70
|
+
# Cross-platform terminals known not to support OSC 1337
|
|
71
|
+
'alacritty',
|
|
72
|
+
'foot', # supports sixel → chafa renders real images
|
|
73
|
+
'ghostty', 'xterm-ghostty',
|
|
74
|
+
'WarpTerminal', # $TERM_PROGRAM in Warp
|
|
75
|
+
'Hyper', # $TERM_PROGRAM in Hyper
|
|
76
|
+
|
|
77
|
+
# Generic / legacy
|
|
78
|
+
'unknown',
|
|
79
|
+
'cygwin',
|
|
80
|
+
'rxvt', 'rxvt-unicode', 'rxvt-unicode-256color',
|
|
81
|
+
'st-256color', # suckless st
|
|
82
|
+
|
|
83
|
+
# Linux desktop terminals (most are VTE-based, no OSC 1337)
|
|
84
|
+
'gnome-terminal',
|
|
85
|
+
'xfce4-terminal',
|
|
86
|
+
'lxterminal',
|
|
87
|
+
'terminator',
|
|
88
|
+
'tilix',
|
|
89
|
+
'sakura',
|
|
90
|
+
'terminology',
|
|
91
|
+
'guake',
|
|
92
|
+
'tilda',
|
|
93
|
+
'deepin-terminal',
|
|
94
|
+
'eterm',
|
|
95
|
+
|
|
96
|
+
# Windows
|
|
97
|
+
'putty',
|
|
98
|
+
'Windows Terminal',
|
|
99
|
+
]
|
|
100
|
+
|
|
101
|
+
def detect_terminal() -> dict[str, str]:
|
|
102
|
+
"""Detect terminal emulator by checking environment variables and parent process.
|
|
103
|
+
Returns a dictionary of detected terminal-related variables.
|
|
104
|
+
"""
|
|
105
|
+
env = os.environ
|
|
106
|
+
terms = {}
|
|
107
|
+
# Check for common terminal-specific variables
|
|
108
|
+
for var in [
|
|
109
|
+
"TERM_PROGRAM", "KONSOLE_VERSION", "KONSOLE_PROFILE_NAME",
|
|
110
|
+
"VTE_VERSION", "TERMINATOR_UUID", "ALACRITTY_SOCKET",
|
|
111
|
+
"WEZTERM_EXECUTABLE", "ITERM_SESSION_ID"
|
|
112
|
+
]:
|
|
113
|
+
if var in env:
|
|
114
|
+
term = env[var]
|
|
115
|
+
if term:
|
|
116
|
+
terms[var] = term
|
|
117
|
+
# Fallback: check parent process
|
|
118
|
+
if not terms:
|
|
119
|
+
try:
|
|
120
|
+
ppid = os.getppid()
|
|
121
|
+
parent = subprocess.check_output(["ps", "-p", str(ppid), "-o", "comm="]).decode().strip()
|
|
122
|
+
if parent:
|
|
123
|
+
terms["PARENT_PROCESS"] = parent
|
|
124
|
+
except Exception:
|
|
125
|
+
pass
|
|
126
|
+
term = env.get("TERM")
|
|
127
|
+
if term:
|
|
128
|
+
terms["TERM"] = term
|
|
129
|
+
return terms
|
|
130
|
+
|
|
131
|
+
def is_terminal_without_images(term_info: dict[str, str]) -> bool:
|
|
132
|
+
"""Determine if the terminal is likely to support inline images based on detected info.
|
|
133
|
+
Args:
|
|
134
|
+
term_info: Dictionary of terminal-related environment variables.
|
|
135
|
+
Returns:
|
|
136
|
+
True if terminal is likely supported, False if known to be unsupported.
|
|
137
|
+
"""
|
|
138
|
+
if os.environ.get("INLINE_VIEWER_ENGINE") == "chafa":
|
|
139
|
+
return True
|
|
140
|
+
terms = term_info.values()
|
|
141
|
+
for unsupported in _TERMINALS_WITHOUT_IMAGES:
|
|
142
|
+
if unsupported in terms:
|
|
143
|
+
return True
|
|
144
|
+
return False
|
|
145
|
+
|
|
146
|
+
def is_chafa_available() -> bool:
|
|
147
|
+
"""Check if the 'chafa' command-line tool is available for ASCII art fallback."""
|
|
148
|
+
try:
|
|
149
|
+
subprocess.run(["chafa", "--version"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
150
|
+
return True
|
|
151
|
+
except FileNotFoundError:
|
|
152
|
+
return False
|
|
153
|
+
|
|
154
|
+
_TERMINAL_INFO = detect_terminal()
|
|
155
|
+
_TERMINAL_SUPPORTS_IMAGES = not is_terminal_without_images(_TERMINAL_INFO)
|
|
156
|
+
|
|
43
157
|
# ---------------------------------------------------------------------
|
|
44
158
|
# Display utilities
|
|
45
159
|
# ---------------------------------------------------------------------
|
|
@@ -52,7 +166,8 @@ def show_inline_image(image_array: np.ndarray, display_scale = None, is_vector:
|
|
|
52
166
|
buffer = BytesIO()
|
|
53
167
|
# Use lower compression level for performance in speed
|
|
54
168
|
Image.fromarray(image_array).save(buffer, format="PNG", compress_level=1, optimize=False)
|
|
55
|
-
|
|
169
|
+
image_bytes = buffer.getvalue()
|
|
170
|
+
encoded = base64.b64encode(image_bytes).decode("utf-8")
|
|
56
171
|
|
|
57
172
|
if display_scale is None:
|
|
58
173
|
width_pct = 33 # same default for both
|
|
@@ -67,31 +182,60 @@ def show_inline_image(image_array: np.ndarray, display_scale = None, is_vector:
|
|
|
67
182
|
# Clamp range
|
|
68
183
|
width_pct = max(5, min(width_pct, 400))
|
|
69
184
|
|
|
70
|
-
|
|
185
|
+
if _TERMINAL_SUPPORTS_IMAGES:
|
|
186
|
+
sys.stdout.write(f"\033]1337;File=inline=1;width={width_pct}%:{encoded}\a\n")
|
|
187
|
+
else:
|
|
188
|
+
# if is_chafa_available():
|
|
189
|
+
# chafa_output = subprocess.check_output(
|
|
190
|
+
# ["chafa", "-"],
|
|
191
|
+
# input=image_bytes
|
|
192
|
+
# ).decode()
|
|
193
|
+
|
|
194
|
+
# sys.stdout.write(f"\n{chafa_output}\a\n")
|
|
195
|
+
if is_chafa_available():
|
|
196
|
+
# Inside tmux, force chafa to use block-art symbols instead of
|
|
197
|
+
# graphics protocols. Tmux mangles kitty graphics and sixel
|
|
198
|
+
# protocols, producing dot-character garbage on screen. Block-art
|
|
199
|
+
# passes through tmux reliably on every outer terminal.
|
|
200
|
+
chafa_args = ["chafa", "-"]
|
|
201
|
+
if os.environ.get("TMUX"):
|
|
202
|
+
chafa_args = ["chafa", "-f", "symbols", "-"]
|
|
203
|
+
chafa_output = subprocess.check_output(
|
|
204
|
+
chafa_args,
|
|
205
|
+
input=image_bytes
|
|
206
|
+
).decode()
|
|
207
|
+
|
|
208
|
+
sys.stdout.write(f"\n{chafa_output}\a\n")
|
|
209
|
+
|
|
210
|
+
else:
|
|
211
|
+
sys.stdout.write(f"[INFO] Use supported terminal or install 'chafa' for ascii art fallback. Detected: {_TERMINAL_INFO}\n")
|
|
212
|
+
|
|
71
213
|
sys.stdout.flush()
|
|
72
214
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
"""Attempt inline image display. No fallbacks, no detection.
|
|
215
|
+
def show_image_auto(img: np.ndarray, display_scale=None, is_vector: bool = False) -> None:
|
|
216
|
+
"""Render an image inline, with chafa fallback for non-iTerm2 terminals.
|
|
76
217
|
|
|
77
|
-
|
|
78
|
-
|
|
218
|
+
Cascade:
|
|
219
|
+
1. If terminal supports OSC 1337 → emit iTerm2 inline image sequence.
|
|
220
|
+
2. Else if chafa is installed → pipe through chafa (which auto-detects
|
|
221
|
+
and emits the terminal's native graphics protocol or block-art).
|
|
222
|
+
3. Else → print an info message suggesting chafa installation.
|
|
79
223
|
|
|
224
|
+
The branching happens inside show_inline_image(); this wrapper handles
|
|
225
|
+
status messaging and exception safety.
|
|
80
226
|
"""
|
|
81
|
-
if os.environ.get("TMUX"):
|
|
82
|
-
print("[WARN] Inside tmux — inline images won't display even with allow-passthrough on (known iTerm2/tmux issue). Use a plain terminal tab.")
|
|
83
|
-
return
|
|
84
|
-
|
|
85
227
|
try:
|
|
86
228
|
show_inline_image(img, display_scale, is_vector)
|
|
87
|
-
|
|
229
|
+
if _TERMINAL_SUPPORTS_IMAGES:
|
|
230
|
+
print("[VIEW] Image rendered")
|
|
231
|
+
elif is_chafa_available():
|
|
232
|
+
print("[VIEW] Rendered via chafa")
|
|
233
|
+
# If neither path applies, show_inline_image already printed the info message
|
|
88
234
|
except Exception as e:
|
|
89
|
-
|
|
90
|
-
print(f"[ERROR] Failed to encode image: {e}")
|
|
235
|
+
print(f"[ERROR] Failed to render image: {e}")
|
|
91
236
|
import traceback
|
|
92
237
|
traceback.print_exc()
|
|
93
238
|
|
|
94
|
-
|
|
95
239
|
def resize_to_terminal(img: np.ndarray) -> tuple[np.ndarray, float]:
|
|
96
240
|
"""Resize image to fit terminal window (approx 8x16 pixel cells)."""
|
|
97
241
|
cols, rows = shutil.get_terminal_size((100, 40))
|
|
@@ -515,6 +659,7 @@ def render_raster(paths: list[str], args) -> None:
|
|
|
515
659
|
# Handle NetCDF/HDF with subdatasets
|
|
516
660
|
if path.lower().endswith(('.nc', '.hdf', '.hdf5', '.h5')):
|
|
517
661
|
try:
|
|
662
|
+
|
|
518
663
|
with rasterio.open(path) as src:
|
|
519
664
|
subdatasets = src.subdatasets
|
|
520
665
|
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|