nbcat 0.13.1__py3-none-any.whl → 1.0.0__py3-none-any.whl

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.
nbcat/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.13.1"
1
+ __version__ = "1.0.0"
nbcat/image.py CHANGED
@@ -1,31 +1,26 @@
1
- import base64
2
1
  import shutil
3
2
  from io import BytesIO
4
- from platform import system
5
3
 
6
4
  from PIL import Image as PilImage
7
- from rich.console import Console, ConsoleOptions, RenderResult
8
- from rich.text import Text
9
- from timg import METHODS, Renderer
5
+ from textual_image.renderable import Image
6
+ from textual_image.renderable.halfcell import Image as HalfcellImage
7
+ from textual_image.renderable.sixel import Image as SixelImage
8
+ from textual_image.renderable.tgp import Image as TGPImage
9
+ from textual_image.renderable.unicode import Image as UnicodeImage
10
10
 
11
11
 
12
- class Image:
13
- def __init__(self, image: str, method: str = "a24h"):
14
- img = BytesIO(base64.b64decode(image.replace("\n", "")))
15
- self.image = PilImage.open(img)
16
- self.method = method if system() != "Windows" else "ascii"
12
+ def render_image(image_content: bytes) -> TGPImage | SixelImage | HalfcellImage | UnicodeImage:
13
+ """
14
+ Render an image from raw byte content and adjusts it to fit the terminal width.
17
15
 
18
- def __rich_console__(self, console: Console, options: ConsoleOptions) -> RenderResult:
19
- renderer = Renderer()
20
- renderer.load_image(self.image)
21
- width = shutil.get_terminal_size()[0] - 1
22
- if self.method == "sixel":
23
- width = width * 6
16
+ Args:
17
+ image_content (bytes): The raw byte content of the image.
24
18
 
25
- renderer.resize(width)
26
-
27
- if self.method == "sixel":
28
- renderer.reduce_colors(16)
29
-
30
- output = renderer.to_string(METHODS[self.method]["class"])
31
- yield Text.from_ansi(output, no_wrap=True, end="")
19
+ Returns
20
+ -------
21
+ TGPImage | SixelImage | HalfcellImage | UnicodeImage: A terminal-compatible image
22
+ object adjusted to the current terminal width.
23
+ """
24
+ image = PilImage.open(BytesIO(image_content))
25
+ width = min(image.size[0], shutil.get_terminal_size()[0])
26
+ return Image(image, width=width, height="auto")
nbcat/main.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import argparse
2
+ import base64
2
3
  import sys
3
4
  from pathlib import Path
4
5
 
@@ -14,6 +15,8 @@ from rich.pretty import Pretty
14
15
  from rich.syntax import Syntax
15
16
  from rich.text import Text
16
17
 
18
+ from nbcat.image import render_image
19
+
17
20
  from . import __version__
18
21
  from .enums import CellType, OutputCellType
19
22
  from .exceptions import (
@@ -21,7 +24,6 @@ from .exceptions import (
21
24
  NotebookNotFoundError,
22
25
  UnsupportedNotebookTypeError,
23
26
  )
24
- from .image import Image
25
27
  from .markdown import Markdown
26
28
  from .pager import Pager
27
29
  from .schemas import Cell, Notebook
@@ -94,8 +96,8 @@ def render_cell(cell: Cell) -> RenderableType:
94
96
  def _render_raw(input: str) -> Text:
95
97
  return Text(input)
96
98
 
97
- def _render_image(input: str) -> Image:
98
- return Image(input)
99
+ def _render_image(input: str) -> RenderableType:
100
+ return render_image(base64.b64decode(input.replace("\n", "")))
99
101
 
100
102
  def _render_json(input: str) -> Pretty:
101
103
  return Pretty(input)
nbcat/markdown.py CHANGED
@@ -10,7 +10,6 @@
10
10
 
11
11
  from __future__ import annotations
12
12
 
13
- import base64
14
13
  from pathlib import Path
15
14
  from typing import ClassVar
16
15
 
@@ -19,7 +18,7 @@ from rich import markdown as md
19
18
  from rich.console import Console, ConsoleOptions, RenderResult
20
19
  from rich.text import Text
21
20
 
22
- from .image import Image
21
+ from .image import render_image
23
22
 
24
23
 
25
24
  class Heading(md.Heading):
@@ -53,9 +52,7 @@ class ImageItem(md.ImageItem):
53
52
  except requests.RequestException:
54
53
  return super().__rich_console__(console, options)
55
54
  if image_content:
56
- # TODO: This part can be improved by changing Image class to accept file objects
57
- image = base64.b64encode(image_content).decode("utf-8")
58
- return Image(image).__rich_console__(console, options)
55
+ return render_image(image_content).__rich_console__(console, options)
59
56
  return super().__rich_console__(console, options)
60
57
 
61
58
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nbcat
3
- Version: 0.13.1
3
+ Version: 1.0.0
4
4
  Summary: cat for jupyter notebooks
5
5
  Project-URL: Homepage, https://github.com/akopdev/nbcat
6
6
  Project-URL: Repository, https://github.com/akopdev/nbcat
@@ -28,14 +28,14 @@ License: MIT License
28
28
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
29
  SOFTWARE.
30
30
  License-File: LICENSE
31
- Requires-Python: >=3.9
31
+ Requires-Python: >=3.10
32
32
  Requires-Dist: argcomplete
33
33
  Requires-Dist: markdownify
34
34
  Requires-Dist: pydantic
35
35
  Requires-Dist: requests
36
36
  Requires-Dist: rich
37
37
  Requires-Dist: textual
38
- Requires-Dist: timg
38
+ Requires-Dist: textual-image[textual]
39
39
  Provides-Extra: dev
40
40
  Requires-Dist: pytest; extra == 'dev'
41
41
  Requires-Dist: pytest-cov; extra == 'dev'
@@ -44,9 +44,9 @@ Requires-Dist: pytest-responses; extra == 'dev'
44
44
  Requires-Dist: ruff; extra == 'dev'
45
45
  Description-Content-Type: text/markdown
46
46
 
47
- # nbcat
47
+ <h1 align="center">nbcat: Jupyter notebooks viewer</h1>
48
48
 
49
- `nbcat` let you preview Jupyter notebooks directly in your terminal. Think of it as `cat`, but for `.ipynb` files.
49
+ [nbcat](https://github.com/akopdev/nbcat) let you preview Jupyter notebooks directly in your terminal. Think of it as `cat`, but for `.ipynb` files.
50
50
 
51
51
  <p align="center">
52
52
  <a href="docs/screenshot.png" target="blank"><img src="docs/screenshot.png" width="400" /></a>
@@ -58,7 +58,7 @@ Description-Content-Type: text/markdown
58
58
  - Very fast and lightweight with minimal dependencies.
59
59
  - Preview remote notebooks without downloading them.
60
60
  - Enable paginated view mode with keyboard navigation (similar to `less`).
61
- - Supports image rendering (some protocols in beta)
61
+ - Supports image rendering in high resolution
62
62
  - Supports for all Jupyter notebook versions, including old legacy formats.
63
63
 
64
64
  ## Motivation
@@ -74,12 +74,12 @@ Please note, that `nbcat` doesn't aim to replace JupyterLab. If you need a full-
74
74
  ## Installation
75
75
 
76
76
  ```bash
77
- # Install from PyPI
78
- pip install nbcat
77
+ # Install from PyPI (recommended)
78
+ $ pip install nbcat
79
79
 
80
80
  # Install via Homebrew
81
- brew tab akopdev/formulas/nbcat
82
- brew install nbcat
81
+ $ brew tab akopdev/formulas/nbcat
82
+ $ brew install nbcat
83
83
  ```
84
84
 
85
85
  ## Quickstart
@@ -93,13 +93,37 @@ You can pass URLs as well.
93
93
  ```bash
94
94
  $ nbcat https://raw.githubusercontent.com/akopdev/nbcat/refs/heads/main/tests/assets/test4.ipynb
95
95
  ```
96
+ In most cases system `less` will render images in low resolution. Consider using an internal pager instead:
96
97
 
97
- Example use case with `fzf` command that lists all `.ipynb` files and uses `nbcat` for previewing them:
98
+ ```bash
99
+ $ nbcat notebook.ipynb --page
100
+ ```
101
+ ## Integrations
102
+
103
+ `nbcat` is designed to integrate seamlessly with other tools. Here are a few examples of how easily it can be done.
104
+
105
+ ### FZF (Fuzzy finder)
106
+
107
+ List all `.ipynb` files and use `nbcat` to preview them:
98
108
 
99
109
  ```bash
100
110
  find . -type f -name "*.ipynb" | fzf --preview 'nbcat {}'
101
111
  ```
102
112
 
113
+ ### Ranger
114
+ To enable previews in Ranger, add the `ipynb` extension to the `handle_extension` function in `~/.config/ranger/scope.sh`:
115
+
116
+ ```bash
117
+ ...
118
+
119
+ handle_extension() {
120
+ case "${FILE_EXTENSION_LOWER}" in
121
+ ipynb)
122
+ nbcat "${FILE_PATH}" && exit 5
123
+ exit 1;;
124
+ ...
125
+ ```
126
+
103
127
  ## Testing & Development
104
128
 
105
129
  Run the tests:
@@ -0,0 +1,14 @@
1
+ nbcat/__init__.py,sha256=J-j-u0itpEFT6irdmWmixQqYMadNl1X91TxUmoiLHMI,22
2
+ nbcat/enums.py,sha256=Fn8PIcLl_uY4nQIs1EUvmKTwfhNUIZgmhRFiCSJk9wk,411
3
+ nbcat/exceptions.py,sha256=Ho7LQz9K70VtIMDNtAwuAtGmb-lFKxGxSj7MN3-EpDA,321
4
+ nbcat/image.py,sha256=DSTdYpsVtsQTZj_TU9BZ0vrOmxqOoYfJoJsZ6EonIlM,982
5
+ nbcat/main.py,sha256=8Vf-Cph_D35XT17HKvW8XfKmEosR1FVZIKHCtJj2JNw,6806
6
+ nbcat/markdown.py,sha256=Onw9FsiW_OXAHBBg4Culf22RA4iM0cttGPyQvSzRD3g,2902
7
+ nbcat/pager.py,sha256=Yu0XIh5MvhvT-cmULYVxo6s2Ufjf2CQ-NDS5fcMQ-IM,3184
8
+ nbcat/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ nbcat/schemas.py,sha256=a7GoKgPTHgun199-J-sZq-ahkdQwvyRaCdQVg1gC798,3135
10
+ nbcat-1.0.0.dist-info/METADATA,sha256=TzEH94VbwxQLYfVnDXPWhjtHQn61DoClnc5zOJiIhoU,5122
11
+ nbcat-1.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
12
+ nbcat-1.0.0.dist-info/entry_points.txt,sha256=io_GRDsecAkYuCZALsjyea3VBq91VCoSznqlZEAJshY,42
13
+ nbcat-1.0.0.dist-info/licenses/LICENSE,sha256=7GjUnahXdd5opdvlpJdb1BisLbiXt2iOFhzIUduhdkE,1072
14
+ nbcat-1.0.0.dist-info/RECORD,,
@@ -1,14 +0,0 @@
1
- nbcat/__init__.py,sha256=Zg3oo58_HXe_ieb_PwWnYkKGH2zTvu6G2jly-7GnPGo,23
2
- nbcat/enums.py,sha256=Fn8PIcLl_uY4nQIs1EUvmKTwfhNUIZgmhRFiCSJk9wk,411
3
- nbcat/exceptions.py,sha256=Ho7LQz9K70VtIMDNtAwuAtGmb-lFKxGxSj7MN3-EpDA,321
4
- nbcat/image.py,sha256=hGZZK5mtij7ckWAvQwzim3thqGC92pLW5ZU5CYbRv_Q,995
5
- nbcat/main.py,sha256=pTOt0Kt7WJqf7H--JmXtvBgFJG-bBu6WsBG4KFl9wAE,6727
6
- nbcat/markdown.py,sha256=fbYBy36rR0SKqvNI6Yj75Xv2snwFRmhbCJIC1wCX2Hg,3055
7
- nbcat/pager.py,sha256=Yu0XIh5MvhvT-cmULYVxo6s2Ufjf2CQ-NDS5fcMQ-IM,3184
8
- nbcat/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- nbcat/schemas.py,sha256=a7GoKgPTHgun199-J-sZq-ahkdQwvyRaCdQVg1gC798,3135
10
- nbcat-0.13.1.dist-info/METADATA,sha256=qU0l9XpIN1Beqb3sI5-1s4UvHjSgHHTDFp05RAu9fZc,4443
11
- nbcat-0.13.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
12
- nbcat-0.13.1.dist-info/entry_points.txt,sha256=io_GRDsecAkYuCZALsjyea3VBq91VCoSznqlZEAJshY,42
13
- nbcat-0.13.1.dist-info/licenses/LICENSE,sha256=7GjUnahXdd5opdvlpJdb1BisLbiXt2iOFhzIUduhdkE,1072
14
- nbcat-0.13.1.dist-info/RECORD,,
File without changes