inlay 0.2.0 → 0.2.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d97c1adc5805bd106533e8d79ca1f4c0d4a53b7c12a0fd2fb7bf63019fb31850
4
- data.tar.gz: c3269a059efd2d082b2490236c045bf13d1784561fd211b432ec58092e632506
3
+ metadata.gz: 6273a1bf011d3c9cd941d30b87f50d5724eb203c00a06697c4a9247c992274ff
4
+ data.tar.gz: bdc9b71941f4742ba3b7ef41f2a9c597d4c60d1be5ebe84dbc918ea6561894d3
5
5
  SHA512:
6
- metadata.gz: 2f6dee9822a3703252c9ab592e7349b24a2a7e309d8fa208a2280726b2d77a3093f6a55009e33ae797bea2f311ebde574bc5093c8bbe206a30530463e52b7130
7
- data.tar.gz: 2bf9bd10319948f0cbc6b48a86525bd83bd0c40906a5fd58feb1b9469d3c0cd4ff88d706c01af2da6a9666f0b6681db0603360735397c61f733d49f50066442d
6
+ metadata.gz: 1eceb81681746d2fcb025f69c78280be9eefbf8213aed812b398e37466dc9150afb603ef53c74d52e5885519603fb21d39103cd2e3722b5e67e7fa7d3e16cccf
7
+ data.tar.gz: 3765bcfe8b45a28d015f7339a5106ff52bc950667332d3bfd9e0c86b5d46eb076c4fd745d49d045008c33c37ba81aae39b54bcb156d61eb1cd589711e730beb8
data/CHANGELOG.md CHANGED
@@ -1,8 +1,15 @@
1
1
  # Changelog
2
2
 
3
- ## 0.2.0
3
+ ## [0.2.1] - Unreleased
4
4
 
5
- - Add terminal image output and explicit `Inlay.show` API.
6
- - Add `to_inlay` normalization and custom adapters.
7
- - Integrate IRB, Pry, and IRuby display registries.
8
- - Support notebook SVG, PNG, and animated GIF output.
5
+ - Fit terminal images to protocol-specific cell dimensions.
6
+ - Preserve SVG chart output when optional PNG dependencies are unavailable.
7
+
8
+ ## [0.2.0] - 2026-09-25
9
+
10
+ - Add terminal image output, `Inlay.show`, normalization, and custom adapters.
11
+ - Integrate image display with IRB, Pry, and IRuby, including SVG, PNG, and animated GIF notebook output.
12
+
13
+ ## [0.1.0] - 2026-09-25
14
+
15
+ Initial release
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2026 ydah
3
+ Copyright (c) 2026 Yudai Takada
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Inlay
2
2
 
3
- Render Ruby graphics where you inspect them. Inlay shows Tessel images, RBGL surfaces, and chart output in IRB, Pry, and IRuby, using terminal graphics protocols or notebook MIME output.
3
+ Render Ruby graphics where you inspect them. Inlay shows Tessel images, RBGL surfaces, and chart output in terminals, IRB, and Pry.
4
4
 
5
5
  ## Install
6
6
 
@@ -8,7 +8,7 @@ Render Ruby graphics where you inspect them. Inlay shows Tessel images, RBGL sur
8
8
  gem install inlay
9
9
  ```
10
10
 
11
- Add `inlay` to your Gemfile. Inlay uses [Tessel](https://github.com/rbgfx/tessel) for images and [Termvas](https://github.com/rbgfx/termvas) for terminal output. Flipbook adds animated GIF display in IRuby.
11
+ Add `inlay` to your Gemfile. Inlay uses [Tessel](https://github.com/rbgfx/tessel) for images and [Termvas](https://github.com/rbgfx/termvas) for terminal output.
12
12
 
13
13
  ## Use in IRB
14
14
 
@@ -31,7 +31,21 @@ Pry uses the same integration style:
31
31
  require "inlay/pry"
32
32
  ```
33
33
 
34
- Inlay uses the terminal protocol selected by Termvas: Kitty, iTerm2, Sixel, or true-color half blocks. Piped output, `TERM=dumb`, `INLAY=off`, and `NO_COLOR` with half blocks show only the summary.
34
+ ## Use in IRuby / Jupyter
35
+
36
+ Install [IRuby](https://github.com/SciRuby/iruby) 0.8 or newer, then require Inlay after the optional graphics gems you use:
37
+
38
+ ```ruby
39
+ require "inkplot" # optional: charts
40
+ require "inlay/iruby"
41
+
42
+ Tessel.read("brick.png")
43
+ Inkplot.line(prices, x: :date, y: :close) # when Inkplot is installed
44
+ ```
45
+
46
+ IRuby provides PNG for images and both SVG and PNG for charts, with SVG listed first. Animations use an installed Flipbook to produce a GIF data URI; if Flipbook is unavailable, Inlay displays the first frame as PNG. These integrations are opt-in and do not load IRuby, Inkplot, or Flipbook when you only `require "inlay"`.
47
+
48
+ Inlay uses the terminal protocol selected by Termvas: Kitty, iTerm2, Sixel, or true-color half blocks. Image limits use terminal columns and rows; pixel protocols use Termvas cell-size estimates (8 × 16 by default, configurable with `TERMVAS_CELL_WIDTH` and `TERMVAS_CELL_HEIGHT`). Piped output, `TERM=dumb`, `INLAY=off`, and `NO_COLOR` with half blocks show only the summary.
35
49
 
36
50
  ## Use in a script
37
51
 
@@ -51,14 +65,6 @@ Objects can implement `to_inlay` and return a `Tessel::Image`, `{ png: bytes }`,
51
65
  Inlay.register(MySurface) { |surface| surface.to_tessel_image }
52
66
  ```
53
67
 
54
- ## Use in IRuby
55
-
56
- ```ruby
57
- require "inlay/iruby"
58
- ```
59
-
60
- Images are returned as PNG, SVG output as SVG, and animations as an embedded GIF when Flipbook is installed. Without Flipbook, an animation displays its first frame.
61
-
62
68
  ## Configuration
63
69
 
64
70
  `Inlay.config.enabled` toggles terminal rendering. `max_rows` caps terminal height and `max_pixels` limits decoded and displayed input size. Small images (up to 32×32) are enlarged with nearest-neighbor scaling; larger images are reduced with alpha-aware area averaging. Set `INLAY=off` to disable terminal output for a process.
@@ -70,6 +76,8 @@ bundle install
70
76
  bundle exec rake verify
71
77
  ```
72
78
 
79
+ Run `bundle exec rbs -I sig validate` to check the published signatures. The manual terminal and notebook checklist is in [docs/manual-checks.md](docs/manual-checks.md).
80
+
73
81
  ## License
74
82
 
75
83
  MIT
data/docs/index.html ADDED
@@ -0,0 +1,28 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <meta name="theme-color" content="#101114">
7
+ <meta name="description" content="Render Ruby graphics where you inspect them with Inlay.">
8
+ <title>Inlay — graphics where you work</title>
9
+ <style>
10
+ :root{color-scheme:dark;--bg:#101114;--panel:#191b20;--line:#2b2e35;--text:#f1f0ec;--muted:#a3a5ad;--accent:#f0a66e;--mono:ui-monospace,SFMono-Regular,Menlo,monospace;--sans:Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif}
11
+ *{box-sizing:border-box}body{margin:0;background:radial-gradient(ellipse at 86% 0%,#3a2b21,transparent 38%),var(--bg);color:var(--text);font:16px/1.65 var(--sans)}a{color:inherit;text-decoration:none}a:hover{color:var(--accent)}.wrap{width:min(1020px,calc(100% - 40px));margin:auto}.nav{height:76px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--line)}.brand{font-size:20px;font-weight:750;letter-spacing:-.04em}.brand i,.label{font-style:normal;color:var(--accent)}.navlinks{display:flex;gap:24px;color:var(--muted);font-size:14px}.hero{padding:94px 0 72px;max-width:780px}.label{font:12px var(--mono);text-transform:uppercase;letter-spacing:.14em}h1{font-size:clamp(48px,8vw,82px);line-height:1;letter-spacing:-.075em;margin:20px 0}.hero p{font-size:19px;color:var(--muted);max-width:620px}.actions{display:flex;gap:12px;flex-wrap:wrap;margin:28px 0}.button{padding:10px 16px;border:1px solid var(--line);border-radius:5px;font-weight:650}.primary{color:#21160f;background:var(--accent);border-color:var(--accent)}.install{display:inline-flex;gap:16px;background:#090a0c;border:1px solid var(--line);border-radius:6px;padding:12px 15px;font:14px var(--mono)}.install span{color:#777}.section{padding:42px 0 64px;border-top:1px solid var(--line)}.section h2{font-size:28px;letter-spacing:-.045em;margin:8px 0 10px}.section>p{color:var(--muted);max-width:640px}.cards{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:25px}.card{padding:20px;background:var(--panel);border:1px solid var(--line);border-radius:7px}.num{font:12px var(--mono);color:var(--accent)}.card h3{font-size:17px;margin:16px 0 6px}.card p{font-size:14px;color:var(--muted);margin:0}.code{background:#090a0c;border:1px solid var(--line);border-radius:7px;padding:18px;overflow:auto;font:14px/1.8 var(--mono);color:#e7d5c7}.foot{padding:24px 0 36px;border-top:1px solid var(--line);color:var(--muted);font-size:13px;display:flex;justify-content:space-between;gap:16px}
12
+ @media(max-width:700px){.hero{padding:68px 0 54px}.navlinks{gap:14px}.cards{grid-template-columns:1fr}.foot{flex-direction:column}}
13
+ </style>
14
+ </head>
15
+ <body><div class="wrap">
16
+ <nav class="nav" aria-label="Main navigation"><a class="brand" href="#top">inlay<i>.</i></a><div class="navlinks"><a href="#integrations">Integrations</a><a href="https://github.com/rbgfx/inlay">GitHub</a><a href="https://rubygems.org/gems/inlay">RubyGems</a></div></nav>
17
+ <main id="top">
18
+ <section class="hero"><div class="label">Ruby graphics, inline</div><h1>See what your<br>code makes.</h1><p>Inlay renders images, surfaces, charts, and animations where you inspect them: in IRB, Pry, Jupyter, or a supported terminal.</p><div class="actions"><a class="button primary" href="https://github.com/rbgfx/inlay#use-in-irb">Get started ↗</a><a class="button" href="https://github.com/rbgfx/inlay/blob/main/docs/manual-checks.md">Compatibility notes</a></div><div class="install"><span>$</span> gem install inlay</div></section>
19
+ <section class="section" id="integrations"><div class="label">One small adapter</div><h2>Fits the way you already work</h2><p>Install the optional adapter for your environment. Inlay keeps notebook and terminal integrations opt-in, so a basic install stays small.</p><div class="cards"><article class="card"><div class="num">01 / REPL</div><h3>IRB &amp; Pry</h3><p>Return an image at the prompt and see it inline, with a short summary ready for the next command.</p></article><article class="card"><div class="num">02 / NOTEBOOK</div><h3>IRuby &amp; Jupyter</h3><p>Display PNG images, SVG or PNG charts, and animated GIF output with a first-frame fallback.</p></article><article class="card"><div class="num">03 / TERMINAL</div><h3>Kitty, iTerm2 &amp; Sixel</h3><p>Choose the terminal protocol through Termvas, with true-color blocks as a portable fallback.</p></article></div></section>
20
+ <section class="section"><div class="label">In IRB</div><h2>Require it once</h2><pre class="code"><code># ~/.irbrc
21
+ require "inlay/irb"
22
+
23
+ # Then return an image from any prompt
24
+ image = Tessel.read("brick.png").scale_nearest(64, 64)
25
+ image</code></pre></section>
26
+ </main><footer class="foot"><span>Inlay · Render Ruby graphics where you inspect them</span><span><a href="https://github.com/rbgfx/inlay">Source</a> · MIT License</span></footer>
27
+ </div></body>
28
+ </html>
@@ -0,0 +1,13 @@
1
+ # Manual integration checks
2
+
3
+ Run these checks with a real terminal or JupyterLab session before marking them complete. Automated specs cover the IRB PTY path and IRuby's display registry, but cannot confirm each frontend's rendering.
4
+
5
+ | Frontend | Check | Status |
6
+ | --- | --- | --- |
7
+ | Kitty | Image appears inline and the next prompt is intact | Not run |
8
+ | WezTerm | Image appears inline and the next prompt is intact | Not run |
9
+ | iTerm2 | Image appears inline and the next prompt is intact | Not run |
10
+ | Ghostty | Image appears inline and the next prompt is intact | Not run |
11
+ | VS Code integrated terminal | Image appears inline with image support enabled | Not run |
12
+ | tmux | Image appears inline and the next prompt is intact | Not run |
13
+ | JupyterLab | Image, chart SVG, and animation/fallback render in cells | Not run |
data/docs/spikes.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Integration spikes
2
2
 
3
- - IRB 1.18's `IRB::Inspector` supports a streaming inspector that writes into IRB's result buffer. Inlay writes terminal escapes to `$stdout` separately and leaves a short summary in the buffer. IRB paging and assignment truncation therefore only see the summary. The supported minimum is IRB 1.13, the first version with the supported inspector API.
4
- - `.irbrc` runs before the first prompt, so environment-based terminal detection can be cached at install time without competing with Reline input. Inlay does not issue device queries.
5
- - Rails console uses IRB's configured inspector when initialized after `.irbrc`; re-running `Inlay.irb_install!` wraps a subsequently selected inspector. Rails itself is not part of the test dependency set.
6
- - Pry's configured printer receives `(output, value, pry_instance)`; the adapter retains that printer and passes it the summary.
7
- - IRuby's public display registry supports predicate matchers and dynamic MIME pairs. SVG is preferred; PNG and GIF-in-HTML are selected from the normalized return value.
3
+ - Verified with IRB 1.18 in a PTY: Inlay's inspector writes the Kitty image sequence directly and leaves the one-line summary in IRB's result buffer. Both an assignment and a later expression display correctly, and the following prompt remains usable. The supported minimum is IRB 1.13, which provides the inspector API used here.
4
+ - Terminal protocol selection uses Termvas environment detection during `require "inlay/irb"`; Inlay does not send device queries. The PTY test forces IRB's pager through `tee` for a long value, then checks the following Kitty image sequence and prompt remain intact. Real pager navigation and terminal rendering still need frontend checks.
5
+ - Verified with a temporary Rails 8.1.4 console and project `.irbrc` loading `inlay/irb`: ordinary values and Tessel image assignments keep the prompt usable. This caught and fixed the wrapped Inspector's missing initializer call (`IRB::ColorPrinter` on pretty-print output).
6
+ - Pry's configured printer receives `(output, value, pry_instance)`; the adapter retains that printer and passes it the summary. The configured printer path is covered by a spec.
7
+ - IRuby 0.8.3's display registry supports predicate matchers and MIME-specific renderers. Registry specs verify PNG, SVG, and HTML GIF output; a local integration check against Flipbook also produced a GIF data URI. JupyterLab frontend rendering has not been manually checked.
8
8
  - `@ruby/3.4-wasm-wasi` 2.10.1 / Ruby 3.4.1 with Larb and JS host bindings completed 3,600 simulated 60 fps callbacks in 61.95 seconds. With one stable JS trampoline and Ruby/JS GC every 600 frames, WASM memory changed from 71,499,776 to 71,565,312 bytes; JS heap grew 4,261,280 bytes. This validates the callback strategy under Node, not a browser or GPU workload.
data/lib/inlay/irb.rb CHANGED
@@ -14,7 +14,10 @@ module Inlay
14
14
  selected = mode.is_a?(IRB::Inspector) ? mode : IRB::Inspector::INSPECTORS[mode] || IRB::Inspector::INSPECTORS[mode.to_s] || IRB::Inspector::INSPECTORS[:p]
15
15
  return false unless selected
16
16
 
17
- @original = selected unless mode.equal?(@wrapper)
17
+ unless mode.equal?(@wrapper)
18
+ @original = selected
19
+ @original.init
20
+ end
18
21
  @protocol = TerminalOutput.protocol
19
22
  @wrapper = IRB::Inspector.new(proc do |value, output, colorize: true|
20
23
  begin
data/lib/inlay/iruby.rb CHANGED
@@ -1,53 +1,115 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "base64"
3
4
  require "inlay"
4
- require "mime/types"
5
5
  require "iruby/display"
6
- require "base64"
7
- require "tempfile"
8
- begin
9
- require "flipbook"
10
- rescue LoadError
11
- # Animation falls back to its first frame when Flipbook is unavailable.
12
- end
6
+ require "mime/types"
13
7
 
14
8
  module Inlay
15
9
  module IRubyIntegration
16
10
  module_function
17
11
 
12
+ module MimeBundle
13
+ def to_iruby_mimebundle(include: [])
14
+ return super if defined?(super)
15
+
16
+ Inlay::IRubyIntegration.mimebundle(self, include: include)
17
+ end
18
+ end
19
+
18
20
  def install
19
- return if @installed
21
+ unless @registered
22
+ registry = IRuby::Display::Registry
23
+ registry.match { |object| Inlay.displayable?(object) }
24
+ registry.format("text/html") { |object| html(object) }
25
+ registry.format("image/svg+xml") { |object| svg(object) }
26
+ registry.format("image/png") { |object| png(object) }
27
+ @registered = true
28
+ end
29
+ install_mimebundle
30
+ true
31
+ end
32
+
33
+ def html(object)
34
+ animation_html(Inlay.normalize(object))
35
+ rescue StandardError
36
+ nil
37
+ end
20
38
 
21
- registry = IRuby::Display::Registry
22
- registry.match { |object| Inlay.displayable?(object) }
23
- registry.priority(100)
24
- registry.format(nil) { |object| render(object) }
25
- @installed = true
39
+ def svg(object)
40
+ Inlay.normalize(object).svg
41
+ rescue StandardError
42
+ nil
26
43
  end
27
44
 
28
- def render(object)
45
+ def png(object)
46
+ png_content(Inlay.normalize(object))
47
+ rescue LoadError, StandardError
48
+ nil
49
+ end
50
+
51
+ def mimebundle(object, include: [])
29
52
  normalized = Inlay.normalize(object)
30
- if normalized.svg
31
- ["image/svg+xml", normalized.svg]
32
- elsif normalized.png.is_a?(String)
33
- ["image/png", normalized.png]
34
- elsif normalized.frames
35
- animation(normalized.frames, normalized.fps)
36
- else
37
- ["image/png", Tessel::PNG.encode(Normalizer.terminal_image(normalized))]
53
+ formats = {}
54
+ formats["text/html"] = animation_html(normalized) if normalized.frames
55
+ formats["image/svg+xml"] = normalized.svg if normalized.svg
56
+ png_bytes = png_content(normalized)
57
+ formats["image/png"] = Base64.strict_encode64(png_bytes) if png_bytes
58
+ formats.select! { |mime, _| include.empty? || include.include?(mime) }
59
+ [formats, {}]
60
+ rescue StandardError
61
+ [{}, {}]
62
+ end
63
+
64
+ def install_mimebundle
65
+ classes = [Tessel::Image]
66
+ classes << RBGL::Engine::Framebuffer if defined?(RBGL::Engine::Framebuffer)
67
+ classes << RBGL::Engine::Texture if defined?(RBGL::Engine::Texture)
68
+ classes << Inkplot::Chart if defined?(Inkplot::Chart)
69
+ classes.uniq.each do |klass|
70
+ klass.prepend(MimeBundle) unless klass.ancestors.include?(MimeBundle)
38
71
  end
39
72
  end
73
+ private_class_method :install_mimebundle
74
+
75
+ def animation_html(normalized)
76
+ return unless normalized.frames
77
+
78
+ writer = flipbook_writer
79
+ return unless writer
40
80
 
41
- def animation(frames, fps)
42
- if defined?(Flipbook)
43
- Tempfile.create(["inlay", ".gif"]) do |file|
44
- Flipbook.write(file.path, frames, fps: fps)
45
- ["text/html", "<img alt=\"animation\" src=\"data:image/gif;base64,#{Base64.strict_encode64(File.binread(file.path))}\">"]
46
- end
47
- else
48
- ["image/png", Tessel::PNG.encode(frames.first)]
81
+ require "tempfile"
82
+ gif = Tempfile.create(["inlay-", ".gif"]) do |file|
83
+ writer.write(file.path, normalized.frames, fps: normalized.fps)
84
+ File.binread(file.path)
49
85
  end
86
+ "<img alt=\"Animation with #{normalized.frames.length} frames\" src=\"data:image/gif;base64,#{Base64.strict_encode64(gif)}\">"
87
+ rescue LoadError, StandardError
88
+ nil
89
+ end
90
+
91
+ def png_content(normalized)
92
+ image = normalized.image || normalized.frames&.first
93
+ return Tessel::PNG.encode(image) if image
94
+
95
+ value = normalized.png
96
+ value = value.call if value.respond_to?(:call)
97
+ return value if value.is_a?(String)
98
+ return Tessel::PNG.encode(value) if value.is_a?(Tessel::Image)
99
+ rescue LoadError, StandardError
100
+ nil
101
+ end
102
+ private_class_method :animation_html, :png_content
103
+
104
+ def flipbook_writer
105
+ return Flipbook if defined?(Flipbook) && Flipbook.respond_to?(:write)
106
+
107
+ require "flipbook"
108
+ Flipbook if defined?(Flipbook) && Flipbook.respond_to?(:write)
109
+ rescue LoadError => error
110
+ raise unless error.path == "flipbook"
50
111
  end
112
+ private_class_method :flipbook_writer
51
113
  end
52
114
  end
53
115
 
data/lib/inlay/sizer.rb CHANGED
@@ -4,14 +4,26 @@ module Inlay
4
4
  module Sizer
5
5
  module_function
6
6
 
7
- def fit(image, width: nil, height: nil, scale: :auto, columns: nil, rows: nil)
7
+ def fit(image, width: nil, height: nil, scale: :auto, columns: nil, rows: nil, protocol: :blocks, env: ENV)
8
8
  raise TypeError, "expected a Tessel::Image" unless image.is_a?(Tessel::Image)
9
9
  raise ArgumentError, "unknown scale mode: #{scale}" unless %i[auto fit pixel none].include?(scale)
10
10
  return image if image.width.zero? || image.height.zero?
11
11
 
12
- columns ||= width || Termvas::Terminal.new(alt_screen: false).size[0]
13
- width = [Integer(width || columns), Integer(columns)].min
14
- height = [Integer(height || Inlay.config.max_rows * 2), Inlay.config.max_rows * 2].min
12
+ terminal = Termvas::Terminal.new(alt_screen: false, env: env)
13
+ terminal_columns, terminal_rows = terminal.size
14
+ columns ||= terminal_columns
15
+ rows ||= terminal_rows
16
+ block_pixels = protocol.to_sym == :blocks
17
+ cell_width, cell_height = terminal.cell_size
18
+ available_width = columns * (block_pixels ? 1 : cell_width)
19
+ available_height = [rows, Inlay.config.max_rows].min * (block_pixels ? 2 : cell_height)
20
+ if available_width * available_height > Inlay.config.max_pixels
21
+ factor = Math.sqrt(Inlay.config.max_pixels.to_f / (available_width * available_height))
22
+ available_width = [(available_width * factor).floor, 1].max
23
+ available_height = [(available_height * factor).floor, 1].max
24
+ end
25
+ width = [Integer(width || available_width), available_width].min
26
+ height = [Integer(height || available_height), available_height].min
15
27
  raise ArgumentError, "display dimensions must be positive" unless width.positive? && height.positive?
16
28
  pixel_scale = scale == :pixel || (scale == :auto && image.width <= 32 && image.height <= 32)
17
29
  max_factor = [width / [image.width, 1].max, height / [image.height, 1].max].min
@@ -5,10 +5,7 @@ module Inlay
5
5
  module_function
6
6
 
7
7
  def protocol(output: $stdout, env: ENV)
8
- return :none unless Inlay.config.enabled
9
- return :none unless output.tty?
10
- return :none unless env["INLAY"] != "off"
11
- return :none if env["TERM"] == "dumb"
8
+ return :none unless enabled?(output: output, env: env)
12
9
 
13
10
  selected = Termvas::Detector.protocol(env)
14
11
  return :none if selected == :blocks && env.key?("NO_COLOR")
@@ -18,11 +15,11 @@ module Inlay
18
15
 
19
16
  def write(image, width: nil, height: nil, scale: :auto, protocol: nil, output: $stdout, env: ENV)
20
17
  selected = (protocol || self.protocol(output: output, env: env)).to_sym
21
- return false unless Inlay.config.enabled && output.tty? && selected != :none
18
+ return false unless enabled?(output: output, env: env) && selected != :none
22
19
  return false if selected == :blocks && env.key?("NO_COLOR")
23
20
  return false if image.width * image.height > Inlay.config.max_pixels
24
21
 
25
- image = Sizer.fit(image, width: width, height: height, scale: scale)
22
+ image = Sizer.fit(image, width: width, height: height, scale: scale, protocol: selected, env: env)
26
23
  bytes = image.bytes
27
24
  encoded = case selected.to_sym
28
25
  when :blocks then Termvas::Encoders::Blocks.encode(bytes, image.width, image.height)
@@ -38,6 +35,11 @@ module Inlay
38
35
  true
39
36
  end
40
37
 
38
+ def enabled?(output:, env:)
39
+ Inlay.config.enabled && output.tty? && env["INLAY"] != "off" && env["TERM"] != "dumb"
40
+ end
41
+ private_class_method :enabled?
42
+
41
43
  def next_kitty_id
42
44
  @kitty_id_lock ||= Mutex.new
43
45
  @kitty_id_lock.synchronize { @kitty_id = (@kitty_id.to_i % 2_147_483_647) + 1 }
data/lib/inlay/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Inlay
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.1"
5
5
  end
data/sig/inlay.rbs CHANGED
@@ -17,7 +17,7 @@ module Inlay
17
17
  end
18
18
 
19
19
  def self.config: () -> Config
20
- def self.register: (Module klass) { (untyped object) -> untyped } -> Module
20
+ def self.register: (Module klass) { (untyped object) -> untyped } -> untyped
21
21
  def self.normalize: (untyped object, ?allow_path: bool) -> Normalized
22
22
  def self.displayable?: (untyped object) -> bool
23
23
  def self.protocol: () -> Symbol
@@ -26,6 +26,14 @@ module Inlay
26
26
  def self.irb_uninstall!: () -> (bool | nil)
27
27
  end
28
28
 
29
+ module Inlay::IRubyIntegration
30
+ def self.install: () -> bool
31
+ def self.html: (untyped object) -> String?
32
+ def self.svg: (untyped object) -> String?
33
+ def self.png: (untyped object) -> String?
34
+ def self.mimebundle: (untyped object, ?include: Array[String]) -> [Hash[String, String], Hash[untyped, untyped]]
35
+ end
36
+
29
37
  module Kernel
30
38
  private
31
39
  def inlay: (untyped object, **untyped options) -> String
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inlay
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yudai Takada
@@ -36,7 +36,7 @@ dependencies:
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: 0.2.0
39
+ version: 0.3.0
40
40
  - - "<"
41
41
  - !ruby/object:Gem::Version
42
42
  version: '1'
@@ -46,7 +46,7 @@ dependencies:
46
46
  requirements:
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: 0.2.0
49
+ version: 0.3.0
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
52
  version: '1'
@@ -56,14 +56,20 @@ dependencies:
56
56
  requirements:
57
57
  - - ">="
58
58
  - !ruby/object:Gem::Version
59
- version: '0'
59
+ version: '0.2'
60
+ - - "<"
61
+ - !ruby/object:Gem::Version
62
+ version: '1'
60
63
  type: :runtime
61
64
  prerelease: false
62
65
  version_requirements: !ruby/object:Gem::Requirement
63
66
  requirements:
64
67
  - - ">="
65
68
  - !ruby/object:Gem::Version
66
- version: '0'
69
+ version: '0.2'
70
+ - - "<"
71
+ - !ruby/object:Gem::Version
72
+ version: '1'
67
73
  - !ruby/object:Gem::Dependency
68
74
  name: irb
69
75
  requirement: !ruby/object:Gem::Requirement
@@ -71,6 +77,9 @@ dependencies:
71
77
  - - ">="
72
78
  - !ruby/object:Gem::Version
73
79
  version: '1.13'
80
+ - - "<"
81
+ - !ruby/object:Gem::Version
82
+ version: '2'
74
83
  type: :development
75
84
  prerelease: false
76
85
  version_requirements: !ruby/object:Gem::Requirement
@@ -78,34 +87,29 @@ dependencies:
78
87
  - - ">="
79
88
  - !ruby/object:Gem::Version
80
89
  version: '1.13'
90
+ - - "<"
91
+ - !ruby/object:Gem::Version
92
+ version: '2'
81
93
  - !ruby/object:Gem::Dependency
82
94
  name: iruby
83
95
  requirement: !ruby/object:Gem::Requirement
84
96
  requirements:
85
97
  - - ">="
86
98
  - !ruby/object:Gem::Version
87
- version: '0'
88
- type: :development
89
- prerelease: false
90
- version_requirements: !ruby/object:Gem::Requirement
91
- requirements:
92
- - - ">="
93
- - !ruby/object:Gem::Version
94
- version: '0'
95
- - !ruby/object:Gem::Dependency
96
- name: flipbook
97
- requirement: !ruby/object:Gem::Requirement
98
- requirements:
99
- - - ">="
99
+ version: '0.8'
100
+ - - "<"
100
101
  - !ruby/object:Gem::Version
101
- version: '0'
102
+ version: '1'
102
103
  type: :development
103
104
  prerelease: false
104
105
  version_requirements: !ruby/object:Gem::Requirement
105
106
  requirements:
106
107
  - - ">="
107
108
  - !ruby/object:Gem::Version
108
- version: '0'
109
+ version: '0.8'
110
+ - - "<"
111
+ - !ruby/object:Gem::Version
112
+ version: '1'
109
113
  - !ruby/object:Gem::Dependency
110
114
  name: pry
111
115
  requirement: !ruby/object:Gem::Requirement
@@ -113,6 +117,9 @@ dependencies:
113
117
  - - ">="
114
118
  - !ruby/object:Gem::Version
115
119
  version: '0'
120
+ - - "<"
121
+ - !ruby/object:Gem::Version
122
+ version: '1'
116
123
  type: :development
117
124
  prerelease: false
118
125
  version_requirements: !ruby/object:Gem::Requirement
@@ -120,6 +127,9 @@ dependencies:
120
127
  - - ">="
121
128
  - !ruby/object:Gem::Version
122
129
  version: '0'
130
+ - - "<"
131
+ - !ruby/object:Gem::Version
132
+ version: '1'
123
133
  - !ruby/object:Gem::Dependency
124
134
  name: rspec
125
135
  requirement: !ruby/object:Gem::Requirement
@@ -134,8 +144,8 @@ dependencies:
134
144
  - - "~>"
135
145
  - !ruby/object:Gem::Version
136
146
  version: '3.0'
137
- description: Render Tessel images, graphics buffers, and chart output in IRB, Pry,
138
- and IRuby.
147
+ description: Render Tessel images, graphics buffers, charts, and animations in terminals,
148
+ IRB, Pry, and IRuby.
139
149
  email:
140
150
  - t.yudai92@gmail.com
141
151
  executables: []
@@ -146,6 +156,8 @@ files:
146
156
  - LICENSE.txt
147
157
  - README.md
148
158
  - Rakefile
159
+ - docs/index.html
160
+ - docs/manual-checks.md
149
161
  - docs/spikes.md
150
162
  - lib/inlay.rb
151
163
  - lib/inlay/adapters.rb
@@ -184,5 +196,5 @@ requirements: []
184
196
  rubygems_version: 3.4.19
185
197
  signing_key:
186
198
  specification_version: 4
187
- summary: Display Ruby graphics in terminals and notebooks
199
+ summary: Display Ruby graphics in terminals and REPLs
188
200
  test_files: []