cheap-impression-presenter 1.1.1 → 1.1.3

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: d17cd3acd2e14f93234d32a413c6356104901a2a9d10a224c9fb191d2dc0f82a
4
- data.tar.gz: 2d2ded7f61c5b0bb2e895097971fd93d321a8253f9d0718dfca0fbdad758a949
3
+ metadata.gz: 559b5a0157ab1677e1e1f57de21cb22327e6b779ef25da65124e5e02f115585f
4
+ data.tar.gz: 4e92ed0ae3c091965b6df6444200b56c240046194646ede5d1637faf165e4a95
5
5
  SHA512:
6
- metadata.gz: 623c58715bc814d8385432867cbfd6aec6f5ef676a9049190a03aca71fa2e1a3f58a23c5cfe305ff2992921f4b5daf801aaecf4a88b82998d58e926d474f216a
7
- data.tar.gz: '0139f72003c626a3b9e4eb17f9eafd93baafeccd193c32951d26e813ec0b1a8026cd8a34e2cf7e825ac76b2d790b3fbb4a2b639b345719191dc91e099e7759b8'
6
+ metadata.gz: 43bdfcddc75072ec0d3767bbb58802c55af33973ceeed469ee3eb9a3ddbfa49cc947b56b629f97184562295a25a98cc5d5b9b3720dfe1fff2088f8491e54c8f1
7
+ data.tar.gz: af3794816e59ea883cfd2149c43350cd22298013a79d9d854db5fba7e0250aff35835952eb0e1fd1c4c75049bf685315dd16f3ef0ab72adc6aba04807f553237
data/README.md CHANGED
@@ -18,7 +18,10 @@ available in the usual linux distributions and homebrew):
18
18
 
19
19
  * ``figlet``: for the figlet plugin.
20
20
  * ``img2sixel`` (from libsixel): for the sixel plugin, i.e. pictures in the terminal.
21
- Your terminal also needs sixel support.
21
+ Your terminal also needs sixel support. On linux a VTE based terminal with
22
+ sixel enabled works well, e.g. Black Box
23
+ (https://flathub.org/apps/com.raggesilver.BlackBox), where sixel has to be
24
+ switched on in the preferences.
22
25
  * ``inkscape``: for svg pictures, in the terminal as well as in the PDF output.
23
26
  * DejaVu Sans Mono font: for the PDF output. If it is not installed, Courier is
24
27
  used, which lacks some characters (e.g. box drawing).
@@ -50,13 +53,21 @@ Everything else is in plugins. The following plugins are existing for now:
50
53
 
51
54
  * Sixel: display graphics in the terminal: `` ```sixel,20 name.png``.
52
55
  * The parameter 20 denotes the size in characters.
53
- * You can add right or center as an additional parameter to align the picture.
54
- * If the picture is right aligned and float is added as an additional parameter, text is added on the left of the picture instead of beneath.
55
- * You can add animate as an additional parameter to return the cursor to where the picture started. Text that follows is then added on top of the picture instead of beneath. Combined with +++ the next picture replaces the current one, which allows for simple animations (see examples/sixel_svg.2.txt).
56
+ * You can add right or center as an additional parameter to align the
57
+ picture.
58
+ * If the picture is right aligned and float is added as an additional
59
+ parameter, text is added on the left of the picture instead of beneath.
60
+ * You can add animate as an additional parameter to return the cursor to
61
+ where the picture started. Text that follows is then added on top of the
62
+ picture instead of beneath. Combined with +++ the next picture replaces the
63
+ current one, which allows for simple animations (see
64
+ examples/sixel_svg.2.txt).
56
65
  * Figlet: display fancy ascii text: `` ```figlet FANCY_TEXT``.
57
66
  * You can add right or center as a parameter to align the fancy text.
58
- * If the fancy text is right aligned, normal text is added on the left of the fancy text instead of beneath.
59
- * You can add bold as an additional parameter to display the fancy text in bold (in the PDF in the bold color).
67
+ * If the fancy text is right aligned, normal text is added on the left of the
68
+ fancy text instead of beneath.
69
+ * You can add bold as an additional parameter to display the fancy text in
70
+ bold (in the PDF in the bold color).
60
71
  * Line Numbers: display line numbers beforce any text (mostly used for code :-).
61
72
  ~~~text
62
73
  ```lnums
@@ -77,8 +88,16 @@ chimp mypresentation.txt
77
88
  ```
78
89
 
79
90
  While presenting you can use the usual button for navigating. In addition, you
80
- can use ``q`` to quit the presentation, and ``r`` to refresh the screen. I
81
- suggest zooming the terminal until about 26 lines are visible. To make this
91
+ can use:
92
+
93
+ * ``q`` to quit the presentation.
94
+ * ``r`` to reload the presentation and refresh the screen. You stay on the
95
+ current slide and part, so you can edit the presentation while it is running
96
+ and see the changes immediately.
97
+ * ``g`` followed by a slide number and enter to go to that slide (e.g.
98
+ ``g12<ENTER>``). Any other key cancels the goto.
99
+
100
+ I suggest zooming the terminal until about 26 lines are visible. To make this
82
101
  easy a ``^`` character is visible at the right end of the footer line. Zoom
83
102
  until the ``^`` character is no longer visible for the most audience friendly
84
103
  results. The ``^`` is shown as long as more than 26 lines are visible, use
@@ -91,27 +110,11 @@ How does it look?
91
110
 
92
111
  ![CHIMP Screenshot](chimp_screenshot.png)
93
112
 
94
- History & Thanks
95
- ================
96
-
97
- Amy Hoy all the way back in 2009 allowed me to use her monkey ascii art for the CHIMP. The
98
- CHIMP was written as an icebreaker for the curucamp, which was a ruby
99
- un-conference in 2009 in Vienna. We had fun, and many cool people from the
100
- community attended.
101
-
102
- I am still using the CHIMP for scientifc presentations, and as sixel terminals
103
- finally are more common, I tried to polish the CHIMP up (2025) and make it available
104
- for easy consumption. Maybe you like it. I use it because I can create
105
- presentations faster than in PP, KN, other programs. Most of the work goes
106
- into graphics anyway, which I create with dedicated tools.
107
-
108
- Drop me a note if you want to be a contributor, or send me merge request if you
109
- have created some plugins. Creating plugins is very simple :-)
110
-
111
113
  PDF Output
112
114
  ==========
113
115
 
114
- To send the presentation to people in one file, write it to a PDF:
116
+ Presenting is nice. Sending presentations to people is sometimes mandatory. But many
117
+ people have not embraced the terminal (yet). So send them a PDF:
115
118
 
116
119
  ```bash
117
120
  chimp -o pdf mypresentation.txt
@@ -132,7 +135,24 @@ footer. Colors you leave out keep their default. Solarized dark for example:
132
135
  examples/chimp.txt (light) and examples/markus.txt (dark) show both.
133
136
 
134
137
  A ``#theme:`` line can also be put on any slide (on a line of its own). It
135
- overrides the given colors from there on, for this and all following slides.
138
+ overrides the given colors for all subsequent slides.
139
+
140
+ History & Thanks
141
+ ================
142
+
143
+ Amy Hoy all the way back in 2009 allowed me to use her monkey ascii art for the
144
+ CHIMP. The CHIMP was written as an icebreaker for the curucamp, which was a
145
+ ruby un-conference in 2009 in Vienna. We had fun, and many cool people from the
146
+ community attended.
147
+
148
+ I am still using the CHIMP for scientifc presentations, and as sixel terminals
149
+ finally are more common, I tried to polish the CHIMP up (2025) and make it
150
+ available for easy consumption. Maybe you like it. I use it because I can
151
+ create presentations faster than in PP, KN, other programs. Most of the work
152
+ goes into graphics anyway, which I create with dedicated tools.
153
+
154
+ Drop me a note if you want to be a contributor, or send me merge request if you
155
+ have created some plugins. Creating plugins is very simple :-)
136
156
 
137
157
  LICENSE
138
158
  =======
data/chimp.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "cheap-impression-presenter"
3
- s.version = "1.1.1"
3
+ s.version = "1.1.3"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.license = "GPL-3.0-or-later"
6
6
  s.summary = "CHIMP - Make a cheap impression. Present via terminal."
data/lib/ChimpParser.rb CHANGED
@@ -28,6 +28,13 @@ module Chimp
28
28
  class TagSkipEvent < Exception; end
29
29
  class TagMoveEvent < Exception; end
30
30
  class TagContentSkipEvent < Exception; end
31
+ class ReloadEvent < Exception
32
+ attr_reader :goto # [slide, step] to return to after reloading
33
+ def initialize(goto)
34
+ @goto = goto
35
+ super 'reload'
36
+ end
37
+ end
31
38
 
32
39
  class Output
33
40
  SIZE = 26 # default number of lines of a slide (including the footer), #size: overrides
data/lib/output/pdf.rb CHANGED
@@ -21,6 +21,7 @@ module Chimp
21
21
  WIDTH = 960 # 16:9 page in points
22
22
  HEIGHT = 540
23
23
  MARGIN = 20
24
+ CELL = 2.1 # character cell height / width, as in a terminal with 10x21 pixel cells, so pictures cover the same number of lines
24
25
 
25
26
  #### a virtual terminal that collects what is printed into a character grid {{{
26
27
  class Terminal
@@ -127,8 +128,8 @@ module Chimp
127
128
  #### the slide always has @size lines, the last two of which are the footer
128
129
  def finish_prepare #{{{
129
130
  @rowh = (HEIGHT - 2 * MARGIN).to_f / @size
130
- @fsize = @rowh / 1.2
131
- @cw = @font.decode_utf8('M').first.width * @fsize / 1000.0
131
+ @cw = @rowh / CELL
132
+ @fsize = @cw * 1000.0 / @font.decode_utf8('M').first.width
132
133
  columns = ((WIDTH - 2 * MARGIN) / @cw).floor
133
134
  @left = (WIDTH - columns * @cw) / 2.0
134
135
  @screen = Terminal.new(columns, @size - 2, self)
data/lib/output/screen.rb CHANGED
@@ -21,8 +21,19 @@ module Window #{{{
21
21
  nil
22
22
  end
23
23
  def self::getch()
24
+ number = nil
24
25
  loop do
25
- case $stdin.getch
26
+ ch = $stdin.getch
27
+ if number
28
+ if ch =~ /\d/
29
+ number << ch
30
+ next
31
+ end
32
+ return [:goto, number.to_i] if ch == "\r" && !number.empty?
33
+ number = nil
34
+ end
35
+ case ch
36
+ when 'g' then number = ''
26
37
  when 'r' then return :refresh
27
38
  when 'q' then return :exit
28
39
  when "\r" then return :enter
@@ -83,12 +94,14 @@ module Chimp
83
94
  #### mO + patternname for opening tags ####
84
95
  #### mC + patternname for closing tags ####
85
96
 
97
+ attr_writer :goto
98
+
86
99
  def initialize(fname) #{{{
100
+ @goto = nil
87
101
  @scounter = @ccounter = 0
88
102
  @what = ''
89
103
  @size = SIZE
90
104
  @last = 0
91
- @skip = -1
92
105
  @templates = []
93
106
 
94
107
  @format = Pastel.new
@@ -124,6 +137,8 @@ module Chimp
124
137
  end
125
138
  def mOP_SLIDES(c,tree)
126
139
  #{{{
140
+ ### after a reload, skip the slides before the one we were on
141
+ raise TagSkipEvent if @goto && c.userdata < [@goto[0], @scounter].min
127
142
  @screen.clear
128
143
  lines = @screen.lines
129
144
  columns = @screen.columns
@@ -151,12 +166,25 @@ module Chimp
151
166
  @last = c.close
152
167
  end
153
168
  def mOP_INCREMENTAL(c,tree)
154
- x, y = @screen.get_pos
155
- c.userdata = { :x => x, :y => y }
169
+ @x, @y = @screen.get_pos
170
+ @drawn = []
171
+ c.userdata = { :x => @x, :y => @y, :drawn => @drawn }
172
+ end
173
+ #### the slide the incremental closing at i belongs to, which step it is, and how many steps the slide has
174
+ def position(tree,i)
175
+ b = i.downto(0).find { |x| tree[x].class == OpenTag && tree[x].ttype == "P_SLIDES" }
176
+ steps = tree[b..tree[b].close].select { |t| t.class == CloseTag && t.ttype == "P_INCREMENTAL" }
177
+ [b, steps.index(tree[i]) + 1, steps.length]
156
178
  end
179
+ private :position
180
+
157
181
  def mCP_INCREMENTAL(c,tree,i)
158
- return if @skip > i
159
- @skip = -1
182
+ ### after a reload, show the steps up to the one we were on without waiting
183
+ if @goto
184
+ b, step, steps = position(tree,i)
185
+ return if step < [@goto[1], steps].min
186
+ @goto = nil
187
+ end
160
188
  ### on the first part of the first slide there is nothing to go back to
161
189
  pos = c.open-1
162
190
  first = tree[pos].ttype == "P_SLIDES" && tree[0...pos].none? { |t| t.class == OpenTag && t.ttype == "P_SLIDES" }
@@ -168,12 +196,17 @@ module Chimp
168
196
  @screen.print "Press 'q' to finish making a cheap impression..."
169
197
  end
170
198
  begin
171
- ch = @screen.getch
199
+ ch, slide = @screen.getch
172
200
  rescue Window::WinchError
173
201
  ch = :refresh
174
202
  end
175
- end while (first && ch == :previous) || (@last == i && ![:previous, :exit, :refresh].include?(ch))
203
+ end while (first && ch == :previous) || (@last == i && ![:previous, :exit, :refresh, :goto].include?(ch))
176
204
  case ch
205
+ when :goto
206
+ #{{{
207
+ slide = slide.clamp(1, @scounter)
208
+ raise TagMoveEvent, tree.index { |t| t.class == OpenTag && t.ttype == "P_SLIDES" && t.userdata == slide }
209
+ #}}}
177
210
  when :previous
178
211
  #{{{
179
212
  tag = tree[pos]
@@ -181,29 +214,23 @@ module Chimp
181
214
  raise TagMoveEvent, tree[pos-1].open
182
215
  end
183
216
  if tag.ttype == "P_INCREMENTAL"
184
- pos = tag.open
185
- tag = tree[pos]
186
- columns = @screen.columns
187
- #### get current position
188
- x, y = @screen.get_pos
189
- #### how many spaces needed
190
- howmuch = ((y - tag.userdata[:y] + 1) * columns) - (columns - x) - tag.userdata[:x]
191
- @screen.set_pos tag.userdata[:x], tag.userdata[:y]
192
- # @screen.print x.to_s + ',' + y.to_s
193
- @screen.print ' ' * howmuch
194
- @screen.set_pos tag.userdata[:x], tag.userdata[:y]
195
- ####
217
+ ### erase only what this step has drawn (pictures next to it stay), then wait at the end of the previous step again
218
+ step = tree[c.open].userdata
219
+ step[:drawn].each do |x1,y1,x2,y2|
220
+ y1.upto(y2) do |y|
221
+ @screen.set_pos x1, y
222
+ @screen.print ' ' * (x2-x1+1)
223
+ end
224
+ end
225
+ @screen.set_pos step[:x], step[:y]
196
226
  raise TagMoveEvent, pos
197
227
  end
198
228
  #}}}
199
229
  when :refresh
200
230
  #{{{
201
- (c.open-1).downto(0) do |b|
202
- if tree[b].class == OpenTag && tree[b].ttype == "P_SLIDES"
203
- @skip = i
204
- raise TagMoveEvent, b
205
- end
206
- end
231
+ ### reparse the presentation (it may have changed) and return to the same slide and step
232
+ b, step, steps = position(tree,i)
233
+ raise ReloadEvent, [tree[b].userdata, step]
207
234
  #}}}
208
235
  when :exit
209
236
  @screen.finish
@@ -219,13 +246,22 @@ module Chimp
219
246
  eval('Chimp::Plugin::' + data[:name].upcase).new.prepare(data[:what],data[:parameters],data[:additional])
220
247
  end
221
248
 
222
- def mOP_INCLUDE(data)
249
+ #### plugins may return the area they drew as [x1,y1,x2,y2], otherwise the whole lines they printed on count
250
+ def process(data)
223
251
  require File::dirname(__FILE__) + "/../plugins/#{data[:name]}.rb"
224
- eval('Chimp::Plugin::' + data[:name].upcase).new.process(data[:what],data[:parameters],@screen,data[:additional])
252
+ area = eval('Chimp::Plugin::' + data[:name].upcase).new.process(data[:what],data[:parameters],@screen,data[:additional])
253
+ return unless @drawn
254
+ x, y = @screen.get_pos
255
+ @drawn << (area.is_a?(Array) && area.length == 4 ? area : [1, @y, @screen.columns, y])
256
+ @x, @y = x, y
257
+ end
258
+ private :process
259
+
260
+ def mOP_INCLUDE(data)
261
+ process data
225
262
  end
226
263
  def mOP_RANGE(data)
227
- require File::dirname(__FILE__) + "/../plugins/#{data[:name]}.rb"
228
- eval('Chimp::Plugin::' + data[:name].upcase).new.process(data[:what],data[:parameters],@screen,data[:additional])
264
+ process data
229
265
  end
230
266
 
231
267
  def mOP_STRONG(data); @screen.print "\e[1m"; end
@@ -245,13 +281,24 @@ module Chimp
245
281
  len = @screen.columns
246
282
  if len-data > 0
247
283
  @screen.print ' ' * ((len - data) / 2)
284
+ @x += (len - data) / 2 if @drawn
248
285
  end
249
286
  end
250
287
  def mCP_CENTER(data)
251
- @screen.print "\n"
288
+ string "\n"
252
289
  end
253
290
 
254
291
  def string(data)
292
+ ### remember which part of which line the current step prints, so going back can erase exactly that
293
+ data.split(/(\n)/).each do |part|
294
+ if part == "\n"
295
+ @x = 1
296
+ @y += 1
297
+ elsif !part.empty?
298
+ @drawn << [@x, @y, @x+part.length-1, @y]
299
+ @x += part.length
300
+ end
301
+ end if @drawn
255
302
  @screen.print(data)
256
303
  end
257
304
 
@@ -3,20 +3,21 @@ module Chimp
3
3
  class FIGLET < Base
4
4
  def process(what,parameters,screen,additional)
5
5
  screen.print "\e[1m" if parameters.include? 'bold'
6
+ font = parameters.include?('small') ? ' -f small' : ''
6
7
  if parameters.include? 'right'
7
8
  pos = screen.get_pos
8
9
  len = screen.columns
9
- `figlet #{what}`.each_line do |l|
10
+ `figlet#{font} #{what}`.each_line do |l|
10
11
  screen.print " " * (len-l.length+1) + l
11
12
  end
12
13
  screen.set_pos *pos
13
14
  elsif parameters.include? 'center'
14
15
  len = screen.columns
15
- `figlet #{what}`.each_line do |l|
16
+ `figlet#{font} #{what}`.each_line do |l|
16
17
  screen.print " " * ((len-l.length+1)/2) + l
17
18
  end
18
19
  else
19
- screen.print `figlet #{what}`
20
+ screen.print `figlet#{font} #{what}`
20
21
  end
21
22
  screen.print "\e[0m" if parameters.include? 'bold'
22
23
  end
data/lib/plugins/sixel.rb CHANGED
@@ -40,24 +40,30 @@ module Chimp
40
40
  end
41
41
 
42
42
  restore = parameters.include?('animate') || parameters.include?('float')
43
- pos = screen.get_pos if restore
43
+ width = parameters[0].to_i
44
44
  len = screen.columns
45
+ pos = screen.get_pos
46
+ x, y = pos
47
+ ### move instead of printing spaces, spaces would erase a picture already on this line
45
48
  if parameters.include? 'right'
46
- screen.print " " * (len-parameters[0].to_i)
49
+ x += len-width
47
50
  elsif parameters.include? 'center'
48
- screen.print " " * ((len-parameters[0].to_i)/2)
51
+ x += (len-width)/2
49
52
  end
53
+ screen.set_pos x, y
50
54
  if screen.respond_to?(:image) # pdf output
51
- screen.image what, parameters[0].to_i, additional[:fname]
55
+ screen.image what, width, additional[:fname]
52
56
  else
53
- screen.print sixel(what,parameters[0].to_i,additional[:fname])
57
+ screen.print sixel(what,width,additional[:fname])
54
58
  end
59
+ _, bottom = screen.get_pos
55
60
  if restore
56
61
  screen.set_pos *pos
57
62
  else
58
- x, y = screen.get_pos
59
- screen.set_pos 0,y
63
+ screen.set_pos 0, bottom
60
64
  end
65
+ ### the area the picture covers, so going back can erase exactly that
66
+ [x, y, x+width-1, bottom]
61
67
  end
62
68
  end
63
69
  end
data/tools/chimp CHANGED
@@ -26,8 +26,15 @@ if ARGV.length == 0 || !File.exist?(ARGV[0])
26
26
  end
27
27
 
28
28
  fname = File.realpath(ARGV[0])
29
- grammy = Chimp::Parser::SimpleGrammar.parse File::read(fname), :fname => fname
30
29
  require_relative "../lib/output/#{output}"
31
- screen = Chimp::Parser.const_get(output.capitalize).new fname
32
- grammy.prepare screen
33
- grammy.output screen
30
+ goto = nil
31
+ begin
32
+ grammy = Chimp::Parser::SimpleGrammar.parse File::read(fname), :fname => fname
33
+ screen = Chimp::Parser.const_get(output.capitalize).new fname
34
+ screen.goto = goto if goto
35
+ grammy.prepare screen
36
+ grammy.output screen
37
+ rescue Chimp::Parser::ReloadEvent => e # refresh
38
+ goto = e.goto
39
+ retry
40
+ 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.1
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juergen eTM Mangler