cheap-impression-presenter 1.1.3 → 1.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 +4 -4
- data/INSTALL.md +10 -4
- data/README.md +18 -5
- data/chimp.gemspec +1 -1
- data/lib/output/screen.rb +27 -4
- data/lib/plugins/kitty.rb +117 -0
- data/lib/plugins/pic.rb +59 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4209c6083d151bd361c30b8f9023a0423129a9c574dbbbbf1a985604b92ce613
|
|
4
|
+
data.tar.gz: fdeae446fbbab6131e8c9057f8497742216e236e23c435fda32faebb3d13eb50
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9871191241cc17fff202da966deafa55bc51f05300d02d19608e165d1cb52f902ec8a859787f08091ba2f49d086a399769d770eccec0c68e87ad39e1b25eb29b
|
|
7
|
+
data.tar.gz: ed9f7d89cd31fc5f9f97257795d2116b38aac833b475e8ca37076932aa55b3e4d9356d8803368cdde545d09060aa5dc43650d7b13b4600a78e932af859870c51
|
data/INSTALL.md
CHANGED
|
@@ -6,11 +6,17 @@ It wont work in a windows terminal for now.
|
|
|
6
6
|
|
|
7
7
|
You can utilize 'figlet' (chimp has a plugin).
|
|
8
8
|
|
|
9
|
-
You can utilize 'img2sixel' if you want to display graphics on
|
|
10
|
-
(chimp has a sixel plugin).
|
|
9
|
+
You can utilize 'img2sixel' if you want to display graphics on a terminal with
|
|
10
|
+
sixel support (chimp has a sixel plugin).
|
|
11
11
|
|
|
12
|
-
You can utilize '
|
|
13
|
-
|
|
12
|
+
You can utilize 'magick' (ImageMagick 7) if you want to display graphics on a
|
|
13
|
+
terminal with kitty graphics support, e.g. kitty, Ghostty, WezTerm (chimp has a
|
|
14
|
+
kitty plugin).
|
|
15
|
+
|
|
16
|
+
The pic plugin uses whichever of the two your terminal supports.
|
|
17
|
+
|
|
18
|
+
You can utilize 'inkscape' if you want to display svgs as graphics on your
|
|
19
|
+
terminal, or include them in the PDF output.
|
|
14
20
|
|
|
15
21
|
The PDF output (chimp -o pdf) uses the DejaVu Sans Mono font if it is
|
|
16
22
|
installed. Otherwise Courier is used, which lacks some characters (e.g. box
|
data/README.md
CHANGED
|
@@ -17,11 +17,17 @@ features need external programs, which have to be installed separately (all are
|
|
|
17
17
|
available in the usual linux distributions and homebrew):
|
|
18
18
|
|
|
19
19
|
* ``figlet``: for the figlet plugin.
|
|
20
|
-
*
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
(
|
|
24
|
-
|
|
20
|
+
* Pictures in the terminal need a terminal that supports either sixel or the
|
|
21
|
+
kitty graphics protocol. The pic plugin finds out which one your terminal
|
|
22
|
+
has and uses it, so you only need the program for that one:
|
|
23
|
+
* ``img2sixel`` (from libsixel): for sixel (the sixel plugin). On linux a
|
|
24
|
+
VTE based terminal with sixel enabled works well, e.g. Black Box
|
|
25
|
+
(https://flathub.org/apps/com.raggesilver.BlackBox), where sixel has to be
|
|
26
|
+
switched on in the preferences.
|
|
27
|
+
* ``magick`` (ImageMagick 7): for the kitty graphics protocol (the kitty
|
|
28
|
+
plugin), e.g. in kitty (https://sw.kovidgoyal.net/kitty/), Ghostty
|
|
29
|
+
(https://ghostty.org) or WezTerm (https://wezterm.org). Pictures are sent
|
|
30
|
+
through the terminal, so this also works via ssh.
|
|
25
31
|
* ``inkscape``: for svg pictures, in the terminal as well as in the PDF output.
|
|
26
32
|
* DejaVu Sans Mono font: for the PDF output. If it is not installed, Courier is
|
|
27
33
|
used, which lacks some characters (e.g. box drawing).
|
|
@@ -51,6 +57,11 @@ their own center parameter.
|
|
|
51
57
|
|
|
52
58
|
Everything else is in plugins. The following plugins are existing for now:
|
|
53
59
|
|
|
60
|
+
* Pic: display graphics in the terminal, with whatever the terminal supports
|
|
61
|
+
(kitty graphics protocol or sixel, kitty if both, nothing if neither):
|
|
62
|
+
`` ```pic,20 name.png``. This is the one to use, it takes the same
|
|
63
|
+
parameters as Sixel (see below). If the detection is wrong, set
|
|
64
|
+
``CHIMP_PIC`` to ``kitty``, ``sixel`` or ``none``.
|
|
54
65
|
* Sixel: display graphics in the terminal: `` ```sixel,20 name.png``.
|
|
55
66
|
* The parameter 20 denotes the size in characters.
|
|
56
67
|
* You can add right or center as an additional parameter to align the
|
|
@@ -62,6 +73,8 @@ Everything else is in plugins. The following plugins are existing for now:
|
|
|
62
73
|
picture instead of beneath. Combined with +++ the next picture replaces the
|
|
63
74
|
current one, which allows for simple animations (see
|
|
64
75
|
examples/sixel_svg.2.txt).
|
|
76
|
+
* Kitty: the same as Sixel, but with the kitty graphics protocol:
|
|
77
|
+
`` ```kitty,20 name.png``. All parameters of the Sixel plugin work.
|
|
65
78
|
* Figlet: display fancy ascii text: `` ```figlet FANCY_TEXT``.
|
|
66
79
|
* You can add right or center as a parameter to align the fancy text.
|
|
67
80
|
* If the fancy text is right aligned, normal text is added on the left of the
|
data/chimp.gemspec
CHANGED
data/lib/output/screen.rb
CHANGED
|
@@ -4,7 +4,18 @@ require 'io/console'
|
|
|
4
4
|
|
|
5
5
|
module Window #{{{
|
|
6
6
|
class WinchError < Exception; end
|
|
7
|
+
|
|
8
|
+
def self::sync_begin()
|
|
9
|
+
$stdout << "\e[?2026h"
|
|
10
|
+
$stdout.flush
|
|
11
|
+
end
|
|
12
|
+
def self::sync_end()
|
|
13
|
+
$stdout << "\e[?2026l"
|
|
14
|
+
$stdout.flush
|
|
15
|
+
end
|
|
16
|
+
|
|
7
17
|
def self::init()
|
|
18
|
+
self::sync_begin
|
|
8
19
|
self::clear
|
|
9
20
|
$stdout << "\e[?25l"
|
|
10
21
|
$stdout.flush
|
|
@@ -17,10 +28,11 @@ module Window #{{{
|
|
|
17
28
|
self::clear
|
|
18
29
|
self::set_pos 0, 0
|
|
19
30
|
$stdout << "\e[?25h"
|
|
20
|
-
|
|
31
|
+
self::sync_end
|
|
21
32
|
nil
|
|
22
33
|
end
|
|
23
34
|
def self::getch()
|
|
35
|
+
self::sync_end
|
|
24
36
|
number = nil
|
|
25
37
|
loop do
|
|
26
38
|
ch = $stdin.getch
|
|
@@ -49,6 +61,8 @@ module Window #{{{
|
|
|
49
61
|
end
|
|
50
62
|
end
|
|
51
63
|
end
|
|
64
|
+
ensure
|
|
65
|
+
self::sync_begin
|
|
52
66
|
end
|
|
53
67
|
def self::lines()
|
|
54
68
|
TTY::Screen.lines
|
|
@@ -56,7 +70,13 @@ module Window #{{{
|
|
|
56
70
|
def self::columns()
|
|
57
71
|
TTY::Screen.columns
|
|
58
72
|
end
|
|
73
|
+
#### how often the screen was cleared; plugins check if what they
|
|
74
|
+
#### drew is still there
|
|
75
|
+
def self::cleared()
|
|
76
|
+
@cleared || 0
|
|
77
|
+
end
|
|
59
78
|
def self::clear()
|
|
79
|
+
@cleared = cleared + 1
|
|
60
80
|
$stdout << "\e[2J"
|
|
61
81
|
$stdout.flush
|
|
62
82
|
self
|
|
@@ -216,11 +236,12 @@ module Chimp
|
|
|
216
236
|
if tag.ttype == "P_INCREMENTAL"
|
|
217
237
|
### erase only what this step has drawn (pictures next to it stay), then wait at the end of the previous step again
|
|
218
238
|
step = tree[c.open].userdata
|
|
219
|
-
step[:drawn].each do |x1,y1,x2,y2|
|
|
239
|
+
step[:drawn].each do |x1,y1,x2,y2,erase|
|
|
220
240
|
y1.upto(y2) do |y|
|
|
221
241
|
@screen.set_pos x1, y
|
|
222
242
|
@screen.print ' ' * (x2-x1+1)
|
|
223
243
|
end
|
|
244
|
+
erase.call if erase
|
|
224
245
|
end
|
|
225
246
|
@screen.set_pos step[:x], step[:y]
|
|
226
247
|
raise TagMoveEvent, pos
|
|
@@ -246,13 +267,15 @@ module Chimp
|
|
|
246
267
|
eval('Chimp::Plugin::' + data[:name].upcase).new.prepare(data[:what],data[:parameters],data[:additional])
|
|
247
268
|
end
|
|
248
269
|
|
|
249
|
-
#### plugins may return the area they drew as [x1,y1,x2,y2],
|
|
270
|
+
#### plugins may return the area they drew as [x1,y1,x2,y2],
|
|
271
|
+
#### otherwise the whole lines they printed on count an
|
|
272
|
+
#### optional fifth element is called to erase, e.g., kitty pics
|
|
250
273
|
def process(data)
|
|
251
274
|
require File::dirname(__FILE__) + "/../plugins/#{data[:name]}.rb"
|
|
252
275
|
area = eval('Chimp::Plugin::' + data[:name].upcase).new.process(data[:what],data[:parameters],@screen,data[:additional])
|
|
253
276
|
return unless @drawn
|
|
254
277
|
x, y = @screen.get_pos
|
|
255
|
-
@drawn << (area.is_a?(Array) && area.length
|
|
278
|
+
@drawn << (area.is_a?(Array) && [4, 5].include?(area.length) ? area : [1, @y, @screen.columns, y])
|
|
256
279
|
@x, @y = x, y
|
|
257
280
|
end
|
|
258
281
|
private :process
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'base64'
|
|
3
|
+
require 'io/console'
|
|
4
|
+
|
|
5
|
+
module Chimp
|
|
6
|
+
module Plugin
|
|
7
|
+
class KITTY < Base
|
|
8
|
+
@@placed = {} # [x,y] => [id, width, screen clears so far, what it replaced], the pictures on the screen
|
|
9
|
+
#### pixel size of a character cell: from the terminal if it knows, else 10x21 as for sixel and the pdf
|
|
10
|
+
def cell_size
|
|
11
|
+
rows, cols, xpix, ypix = [0, 0, 0, 0].pack('S4').then { |buf| $stdout.ioctl(0x5413, buf); buf.unpack('S4') } # TIOCGWINSZ
|
|
12
|
+
return [xpix / cols, ypix / rows] if xpix > 0 && ypix > 0
|
|
13
|
+
[10, 21]
|
|
14
|
+
rescue StandardError
|
|
15
|
+
[10, 21]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# converted images are cached in .PRESENTATIONNAME/ next to the presentation
|
|
19
|
+
def cache_file(what,width,fname)
|
|
20
|
+
dir = File.join(File.dirname(fname),'.' + File.basename(fname,'.*'))
|
|
21
|
+
File.join(dir,"#{what.gsub('/','_')}.#{width}.kitty.png")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
#### kitty only takes png. the terminal scales it to the width, so it does not depend on the zoom
|
|
25
|
+
#### (which would convert everything again for each zoom). as for sixel 10 pixels per character,
|
|
26
|
+
#### and 5 bits per color, which keeps it small (it goes through the terminal, maybe via ssh)
|
|
27
|
+
def png(what,width,fname)
|
|
28
|
+
src = File.join(File.dirname(fname),what)
|
|
29
|
+
pixels = width * 10
|
|
30
|
+
cache = cache_file(what,width,fname)
|
|
31
|
+
if File.exist?(cache) && File.exist?(src) && File.mtime(cache) >= File.mtime(src)
|
|
32
|
+
return File.binread(cache)
|
|
33
|
+
end
|
|
34
|
+
convert = if what =~ /\.svg$/
|
|
35
|
+
"inkscape -D -d 300 --export-type=png #{src} -o - | magick - -resize #{pixels}x -depth 5 png:-"
|
|
36
|
+
else
|
|
37
|
+
"magick #{src} -resize #{pixels}x -depth 5 png:-"
|
|
38
|
+
end
|
|
39
|
+
result = `#{convert}`
|
|
40
|
+
if $?.success? && !result.empty?
|
|
41
|
+
FileUtils.mkdir_p(File.dirname(cache))
|
|
42
|
+
File.binwrite(cache,result)
|
|
43
|
+
end
|
|
44
|
+
result
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def prepare(what,parameters,additional)
|
|
48
|
+
return if parameters[0] !~ /\d/
|
|
49
|
+
png(what,parameters[0].to_i,additional[:fname])
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def process(what,parameters,screen,additional)
|
|
53
|
+
if parameters[0] !~ /\d/
|
|
54
|
+
screen.print 'Use ```kitty,NUM with NUM beeing the width if the picture in characters.'
|
|
55
|
+
return
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
restore = parameters.include?('animate') || parameters.include?('float')
|
|
59
|
+
width = parameters[0].to_i
|
|
60
|
+
len = screen.columns
|
|
61
|
+
pos = screen.get_pos
|
|
62
|
+
x, y = pos
|
|
63
|
+
### move instead of printing spaces, spaces would erase a picture already on this line
|
|
64
|
+
if parameters.include? 'right'
|
|
65
|
+
x += len-width
|
|
66
|
+
elsif parameters.include? 'center'
|
|
67
|
+
x += (len-width)/2
|
|
68
|
+
end
|
|
69
|
+
screen.set_pos x, y
|
|
70
|
+
if screen.respond_to?(:image) # pdf output
|
|
71
|
+
screen.image what, width, additional[:fname]
|
|
72
|
+
_, bottom = screen.get_pos
|
|
73
|
+
last = bottom
|
|
74
|
+
erase = nil
|
|
75
|
+
else
|
|
76
|
+
data = png(what,width,additional[:fname])
|
|
77
|
+
return if data.empty?
|
|
78
|
+
### the terminal scales the png to the width, which says how many lines it covers
|
|
79
|
+
w, h = data[16,8].unpack('NN')
|
|
80
|
+
cw, ch = cell_size
|
|
81
|
+
bottom = y + (width * cw * h / (w * ch).to_f).ceil
|
|
82
|
+
### bottom is the line after the picture, erasing it would erase what is there (e.g. the footer)
|
|
83
|
+
last = bottom - 1
|
|
84
|
+
id = rand(1...2**31)
|
|
85
|
+
### a picture drawn at the same place as another one replaces it (e.g. for animations). only its placement
|
|
86
|
+
### goes, the terminal keeps the data so going back can show it again. clearing the screen (next slide)
|
|
87
|
+
### removes all pictures, so whatever was placed before that is not there to replace.
|
|
88
|
+
covered = @@placed[[x, y]]
|
|
89
|
+
covered = nil unless covered && covered[2] == screen.cleared
|
|
90
|
+
### all chunks in one write, a flush per chunk stutters, q=2 keeps the terminal from answering
|
|
91
|
+
chunks = Base64.strict_encode64(data).scan(/.{1,4096}/)
|
|
92
|
+
screen.print (covered ? "\e_Ga=d,d=i,i=#{covered[0]},q=2\e\\" : '') + chunks.each_with_index.map { |chunk,i|
|
|
93
|
+
keys = i == 0 ? "a=T,f=100,i=#{id},c=#{width},C=1,q=2," : ''
|
|
94
|
+
"\e_G#{keys}m=#{i < chunks.length-1 ? 1 : 0};#{chunk}\e\\"
|
|
95
|
+
}.join
|
|
96
|
+
@@placed[[x, y]] = [id, width, screen.cleared, covered]
|
|
97
|
+
### pictures are not part of the text, printing spaces does not erase them. bring back what it replaced.
|
|
98
|
+
erase = lambda do
|
|
99
|
+
screen.print "\e_Ga=d,d=I,i=#{id},q=2\e\\"
|
|
100
|
+
if covered
|
|
101
|
+
screen.set_pos x, y
|
|
102
|
+
screen.print "\e_Ga=p,i=#{covered[0]},c=#{covered[1]},C=1,q=2\e\\"
|
|
103
|
+
end
|
|
104
|
+
@@placed[[x, y]] = covered
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
if restore
|
|
108
|
+
screen.set_pos *pos
|
|
109
|
+
else
|
|
110
|
+
screen.set_pos 0, bottom
|
|
111
|
+
end
|
|
112
|
+
### the area the picture covers, so going back can erase exactly that
|
|
113
|
+
[x, y, x+width-1, last, erase].compact
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
data/lib/plugins/pic.rb
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require 'io/console'
|
|
2
|
+
require_relative 'sixel'
|
|
3
|
+
require_relative 'kitty'
|
|
4
|
+
|
|
5
|
+
module Chimp
|
|
6
|
+
module Plugin
|
|
7
|
+
class PIC < Base
|
|
8
|
+
#### ask the terminal once: a kitty graphics query, then a device attributes query (4 means sixel),
|
|
9
|
+
#### which every terminal answers, so we know when to stop waiting for the kitty answer
|
|
10
|
+
def detect
|
|
11
|
+
return ENV['CHIMP_PIC'].to_sym if %w{kitty sixel none}.include?(ENV['CHIMP_PIC'])
|
|
12
|
+
return :none unless $stdin.tty? && $stdout.tty?
|
|
13
|
+
res = ''
|
|
14
|
+
$stdin.raw do
|
|
15
|
+
$stdout << "\e_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA\e\\\e[c"
|
|
16
|
+
$stdout.flush
|
|
17
|
+
while IO.select([$stdin], nil, nil, 1) && (c = $stdin.getc)
|
|
18
|
+
res << c
|
|
19
|
+
break if res =~ /\e\[\?[\d;]*c/
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
if res.include?("\e_Gi=31;OK")
|
|
23
|
+
:kitty
|
|
24
|
+
elsif res =~ /\e\[\?([\d;]*)c/ && $1.split(';').include?('4')
|
|
25
|
+
:sixel
|
|
26
|
+
else
|
|
27
|
+
:none
|
|
28
|
+
end
|
|
29
|
+
rescue StandardError
|
|
30
|
+
:none
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def graphics
|
|
34
|
+
@@graphics ||= detect
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def delegate(screen=nil)
|
|
38
|
+
### the pdf does not care, both plugins hand the picture to it
|
|
39
|
+
return SIXEL.new if screen.respond_to?(:image)
|
|
40
|
+
case graphics
|
|
41
|
+
when :kitty then KITTY.new
|
|
42
|
+
when :sixel then SIXEL.new
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def prepare(what,parameters,additional)
|
|
47
|
+
delegate&.prepare(what,parameters,additional)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def process(what,parameters,screen,additional)
|
|
51
|
+
if parameters[0] !~ /\d/
|
|
52
|
+
screen.print 'Use ```pic,NUM with NUM beeing the width if the picture in characters.'
|
|
53
|
+
return
|
|
54
|
+
end
|
|
55
|
+
delegate(screen)&.process(what,parameters,screen,additional)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cheap-impression-presenter
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1
|
|
4
|
+
version: 1.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Juergen eTM Mangler
|
|
@@ -72,7 +72,9 @@ files:
|
|
|
72
72
|
- lib/output/pdf.rb
|
|
73
73
|
- lib/output/screen.rb
|
|
74
74
|
- lib/plugins/figlet.rb
|
|
75
|
+
- lib/plugins/kitty.rb
|
|
75
76
|
- lib/plugins/lnums.rb
|
|
77
|
+
- lib/plugins/pic.rb
|
|
76
78
|
- lib/plugins/sixel.rb
|
|
77
79
|
- tools/chimp
|
|
78
80
|
homepage: https://github.com/etm/chimp
|