tpp 1.3.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.
data/bin/tpp ADDED
@@ -0,0 +1,1764 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ version_number = "1.3.1"
4
+
5
+ # Loads the ncurses-ruby module and imports "Ncurses" into the
6
+ # current namespace. It stops the program if loading the
7
+ # ncurses-ruby module fails.
8
+ def load_ncurses
9
+ begin
10
+ require "rubygems"
11
+ require "ncurses"
12
+ include Ncurses
13
+ rescue LoadError
14
+ $stderr.print <<EOF
15
+ There is no Ncurses-Ruby package installed which is needed by TPP.
16
+ You can download it on: http://ncurses-ruby.berlios.de/
17
+ EOF
18
+ Kernel.exit(1)
19
+ end
20
+ end
21
+
22
+ # Maps color names to constants and indexes.
23
+ class ColorMap
24
+
25
+ # Maps color name _color_ to a constant
26
+ def ColorMap.get_color(color)
27
+ colors = { "white" => COLOR_WHITE,
28
+ "yellow" => COLOR_YELLOW,
29
+ "red" => COLOR_RED,
30
+ "green" => COLOR_GREEN,
31
+ "blue" => COLOR_BLUE,
32
+ "cyan" => COLOR_CYAN,
33
+ "magenta" => COLOR_MAGENTA,
34
+ "black" => COLOR_BLACK,
35
+ "default" => -1 }
36
+ colors[color]
37
+ end
38
+
39
+ # Maps color name to a color pair index
40
+ def ColorMap.get_color_pair(color)
41
+ colors = { "white" => 1,
42
+ "yellow" => 2,
43
+ "red" => 3,
44
+ "green" => 4,
45
+ "blue" => 5,
46
+ "cyan" => 6,
47
+ "magenta" => 7,
48
+ "black" => 8,
49
+ "default" =>-1}
50
+ colors[color]
51
+ end
52
+
53
+ end
54
+
55
+ # Opens a TPP source file, and splits it into the different pages.
56
+ class FileParser
57
+
58
+ def initialize(filename)
59
+ @filename = filename
60
+ @pages = []
61
+ end
62
+
63
+ # Parses the specified file and returns an array of Page objects
64
+ def get_pages
65
+ begin
66
+ f = File.open(@filename)
67
+ rescue
68
+ $stderr.puts "Error: couldn't open file: #{$!}"
69
+ Kernel.exit(1)
70
+ end
71
+
72
+ number_pages = 0
73
+
74
+ cur_page = Page.new("slide " + (number_pages + 1).to_s)
75
+
76
+ f.each_line do |line|
77
+ line.chomp!
78
+ case line
79
+ when /^--##/ # ignore comments
80
+ when /^--newpage/
81
+ @pages << cur_page
82
+ number_pages += 1
83
+ name = line.sub(/^--newpage/,"")
84
+ if name == "" then
85
+ name = "slide " + (number_pages+1).to_s
86
+ else
87
+ name.strip!
88
+ end
89
+ cur_page = Page.new(name)
90
+ else
91
+ cur_page.add_line(line)
92
+ end # case
93
+ end # each
94
+ @pages << cur_page
95
+ end
96
+ end # class FileParser
97
+
98
+
99
+ # Represents a page (aka `slide') in TPP. A page consists of a title and one or
100
+ # more lines.
101
+ class Page
102
+
103
+ def initialize(title)
104
+ @lines = []
105
+ @title = title
106
+ @cur_line = 0
107
+ @eop = false
108
+ end
109
+
110
+ # Appends a line to the page, but only if _line_ is not null
111
+ def add_line(line)
112
+ @lines << line if line
113
+ end
114
+
115
+ # Returns the next line. In case the last line is hit, then the end-of-page marker is set.
116
+ def next_line
117
+ line = @lines[@cur_line]
118
+ @cur_line += 1
119
+ if @cur_line >= @lines.size then
120
+ @eop = true
121
+ end
122
+ return line
123
+ end
124
+
125
+ # Returns whether end-of-page has been reached.
126
+ def eop?
127
+ @eop
128
+ end
129
+
130
+ # Resets the end-of-page marker and sets the current line marker to the first line
131
+ def reset_eop
132
+ @cur_line = 0
133
+ @eop = false
134
+ end
135
+
136
+ # Returns all lines in the page.
137
+ def lines
138
+ @lines
139
+ end
140
+
141
+ # Returns the page's title
142
+ def title
143
+ @title
144
+ end
145
+ end
146
+
147
+
148
+
149
+ # Implements a generic visualizer from which all other visualizers need to be
150
+ # derived. If Ruby supported abstract methods, all the do_* methods would be
151
+ # abstract.
152
+ class TppVisualizer
153
+
154
+ def initialize
155
+ # nothing
156
+ end
157
+
158
+ # Splits a line into several lines, where each of the result lines is at most
159
+ # _width_ characters long, caring about word boundaries, and returns an array
160
+ # of strings.
161
+ def split_lines(text,width)
162
+ lines = []
163
+ if text then
164
+ begin
165
+ i = width
166
+ if text.length <= i then # text length is OK -> add it to array and stop splitting
167
+ lines << text
168
+ text = ""
169
+ else
170
+ # search for word boundary (space actually)
171
+ while i > 0 and text[i] != ' '[0] do
172
+ i -= 1
173
+ end
174
+ # if we can't find any space character, simply cut it off at the maximum width
175
+ if i == 0 then
176
+ i = width
177
+ end
178
+ # extract line
179
+ x = text[0..i-1]
180
+ # remove extracted line
181
+ text = text[i+1..-1]
182
+ # added line to array
183
+ lines << x
184
+ end
185
+ end while text.length > 0
186
+ end
187
+ return lines
188
+ end
189
+
190
+ def do_footer(footer_text)
191
+ $stderr.puts "Error: TppVisualizer#do_footer has been called directly."
192
+ Kernel.exit(1)
193
+ end
194
+
195
+ def do_header(header_text)
196
+ $stderr.puts "Error: TppVisualizer#do_header has been called directly."
197
+ Kernel.exit(1)
198
+ end
199
+
200
+
201
+ def do_refresh
202
+ $stderr.puts "Error: TppVisualizer#do_refresh has been called directly."
203
+ Kernel.exit(1)
204
+ end
205
+
206
+ def new_page
207
+ $stderr.puts "Error: TppVisualizer#new_page has been called directly."
208
+ Kernel.exit(1)
209
+ end
210
+
211
+ def do_heading(text)
212
+ $stderr.puts "Error: TppVisualizer#do_heading has been called directly."
213
+ Kernel.exit(1)
214
+ end
215
+
216
+ def do_withborder
217
+ $stderr.puts "Error: TppVisualizer#do_withborder has been called directly."
218
+ Kernel.exit(1)
219
+ end
220
+
221
+ def do_horline
222
+ $stderr.puts "Error: TppVisualizer#do_horline has been called directly."
223
+ Kernel.exit(1)
224
+ end
225
+
226
+ def do_color(text)
227
+ $stderr.puts "Error: TppVisualizer#do_color has been called directly."
228
+ Kernel.exit(1)
229
+ end
230
+
231
+ def do_center(text)
232
+ $stderr.puts "Error: TppVisualizer#do_center has been called directly."
233
+ Kernel.exit(1)
234
+ end
235
+
236
+ def do_right(text)
237
+ $stderr.puts "Error: TppVisualizer#do_right has been called directly."
238
+ Kernel.exit(1)
239
+ end
240
+
241
+ def do_exec(cmdline)
242
+ $stderr.puts "Error: TppVisualizer#do_exec has been called directly."
243
+ Kernel.exit(1)
244
+ end
245
+
246
+ def do_wait
247
+ $stderr.puts "Error: TppVisualizer#do_wait has been called directly."
248
+ Kernel.exit(1)
249
+ end
250
+
251
+ def do_beginoutput
252
+ $stderr.puts "Error: TppVisualizer#do_beginoutput has been called directly."
253
+ Kernel.exit(1)
254
+ end
255
+
256
+ def do_beginshelloutput
257
+ $stderr.puts "Error: TppVisualizer#do_beginshelloutput has been called directly."
258
+ Kernel.exit(1)
259
+ end
260
+
261
+ def do_endoutput
262
+ $stderr.puts "Error: TppVisualizer#do_endoutput has been called directly."
263
+ Kernel.exit(1)
264
+ end
265
+
266
+ def do_endshelloutput
267
+ $stderr.puts "Error: TppVisualizer#do_endshelloutput has been called directly."
268
+ Kernel.exit(1)
269
+ end
270
+
271
+ def do_sleep(time2sleep)
272
+ $stderr.puts "Error: TppVisualizer#do_sleep has been called directly."
273
+ Kernel.exit(1)
274
+ end
275
+
276
+ def do_boldon
277
+ $stderr.puts "Error: TppVisualizer#do_boldon has been called directly."
278
+ Kernel.exit(1)
279
+ end
280
+
281
+ def do_boldoff
282
+ $stderr.puts "Error: TppVisualizer#do_boldoff has been called directly."
283
+ Kernel.exit(1)
284
+ end
285
+
286
+ def do_revon
287
+ $stderr.puts "Error: TppVisualizer#do_revon has been called directly."
288
+ Kernel.exit(1)
289
+ end
290
+
291
+ def do_revoff
292
+ $stderr.puts "Error: TppVisualizer#do_revoff has been called directly."
293
+ Kernel.exit(1)
294
+ end
295
+
296
+ def do_ulon
297
+ $stderr.puts "Error: TppVisualizer#do_ulon has been called directly."
298
+ Kernel.exit(1)
299
+ end
300
+
301
+ def do_uloff
302
+ $stderr.puts "Error: TppVisualizer#do_uloff has been called directly."
303
+ Kernel.exit(1)
304
+ end
305
+
306
+ def do_beginslideleft
307
+ $stderr.puts "Error: TppVisualizer#do_beginslideleft has been called directly."
308
+ Kernel.exit(1)
309
+ end
310
+
311
+ def do_endslide
312
+ $stderr.puts "Error: TppVisualizer#do_endslide has been called directly."
313
+ Kernel.exit(1)
314
+ end
315
+
316
+ def do_command_prompt
317
+ $stderr.puts "Error: TppVisualizer#do_command_prompt has been called directly."
318
+ Kernel.exit(1)
319
+ end
320
+
321
+ def do_beginslideright
322
+ $stderr.puts "Error: TppVisualizer#do_beginslideright has been called directly."
323
+ Kernel.exit(1)
324
+ end
325
+
326
+ def do_beginslidetop
327
+ $stderr.puts "Error: TppVisualizer#do_beginslidetop has been called directly."
328
+ Kernel.exit(1)
329
+ end
330
+
331
+ def do_beginslidebottom
332
+ $stderr.puts "Error: TppVisualizer#do_beginslidebottom has been called directly."
333
+ Kernel.exit(1)
334
+ end
335
+
336
+ def do_sethugefont
337
+ $stderr.puts "Error: TppVisualizer#do_sethugefont has been called directly."
338
+ Kernel.exit(1)
339
+ end
340
+
341
+ def do_huge(text)
342
+ $stderr.puts "Error: TppVisualizer#do_huge has been called directly."
343
+ Kernel.exit(1)
344
+ end
345
+
346
+ def print_line(line)
347
+ $stderr.puts "Error: TppVisualizer#print_line has been called directly."
348
+ Kernel.exit(1)
349
+ end
350
+
351
+ def do_title(title)
352
+ $stderr.puts "Error: TppVisualizer#do_title has been called directly."
353
+ Kernel.exit(1)
354
+ end
355
+
356
+ def do_author(author)
357
+ $stderr.puts "Error: TppVisualizer#do_author has been called directly."
358
+ Kernel.exit(1)
359
+ end
360
+
361
+ def do_date(date)
362
+ $stderr.puts "Error: TppVisualizer#do_date has been called directly."
363
+ Kernel.exit(1)
364
+ end
365
+
366
+ def do_bgcolor(color)
367
+ $stderr.puts "Error: TppVisualizer#do_bgcolor has been called directly."
368
+ Kernel.exit(1)
369
+ end
370
+
371
+ def do_fgcolor(color)
372
+ $stderr.puts "Error: TppVisualizer#do_fgcolor has been called directly."
373
+ Kernel.exit(1)
374
+ end
375
+
376
+ def do_color(color)
377
+ $stderr.puts "Error: TppVisualizer#do_color has been called directly."
378
+ Kernel.exit(1)
379
+ end
380
+
381
+ # Receives a _line_, parses it if necessary, and dispatches it
382
+ # to the correct method which then does the correct processing.
383
+ # It returns whether the controller shall wait for input.
384
+ def visualize(line,eop)
385
+ case line
386
+ when /^--heading /
387
+ text = line.sub(/^--heading /,"")
388
+ do_heading(text)
389
+ when /^--withborder/
390
+ do_withborder
391
+ when /^--horline/
392
+ do_horline
393
+ when /^--color /
394
+ text = line.sub(/^--color /,"")
395
+ text.strip!
396
+ do_color(text)
397
+ when /^--center /
398
+ text = line.sub(/^--center /,"")
399
+ do_center(text)
400
+ when /^--right /
401
+ text = line.sub(/^--right /,"")
402
+ do_right(text)
403
+ when /^--exec /
404
+ cmdline = line.sub(/^--exec /,"")
405
+ do_exec(cmdline)
406
+ when /^---/
407
+ do_wait
408
+ return true
409
+ when /^--beginoutput/
410
+ do_beginoutput
411
+ when /^--beginshelloutput/
412
+ do_beginshelloutput
413
+ when /^--endoutput/
414
+ do_endoutput
415
+ when /^--endshelloutput/
416
+ do_endshelloutput
417
+ when /^--sleep /
418
+ time2sleep = line.sub(/^--sleep /,"")
419
+ do_sleep(time2sleep)
420
+ when /^--boldon/
421
+ do_boldon
422
+ when /^--boldoff/
423
+ do_boldoff
424
+ when /^--revon/
425
+ do_revon
426
+ when /^--revoff/
427
+ do_revoff
428
+ when /^--ulon/
429
+ do_ulon
430
+ when /^--uloff/
431
+ do_uloff
432
+ when /^--beginslideleft/
433
+ do_beginslideleft
434
+ when /^--endslideleft/, /^--endslideright/, /^--endslidetop/, /^--endslidebottom/
435
+ do_endslide
436
+ when /^--beginslideright/
437
+ do_beginslideright
438
+ when /^--beginslidetop/
439
+ do_beginslidetop
440
+ when /^--beginslidebottom/
441
+ do_beginslidebottom
442
+ when /^--sethugefont /
443
+ params = line.sub(/^--sethugefont /,"")
444
+ do_sethugefont(params.strip)
445
+ when /^--huge /
446
+ figlet_text = line.sub(/^--huge /,"")
447
+ do_huge(figlet_text)
448
+ when /^--footer /
449
+ @footer_txt = line.sub(/^--footer /,"")
450
+ do_footer(@footer_txt)
451
+ when /^--header /
452
+ @header_txt = line.sub(/^--header /,"")
453
+ do_header(@header_txt)
454
+ when /^--title /
455
+ title = line.sub(/^--title /,"")
456
+ do_title(title)
457
+ when /^--author /
458
+ author = line.sub(/^--author /,"")
459
+ do_author(author)
460
+ when /^--date /
461
+ date = line.sub(/^--date /,"")
462
+ if date == "today" then
463
+ date = Time.now.strftime("%b %d %Y")
464
+ elsif date =~ /^today / then
465
+ date = Time.now.strftime(date.sub(/^today /,""))
466
+ end
467
+ do_date(date)
468
+ when /^--bgcolor /
469
+ color = line.sub(/^--bgcolor /,"").strip
470
+ do_bgcolor(color)
471
+ when /^--fgcolor /
472
+ color = line.sub(/^--fgcolor /,"").strip
473
+ do_fgcolor(color)
474
+ when /^--color /
475
+ color = line.sub(/^--color /,"").strip
476
+ do_color(color)
477
+ else
478
+ print_line(line)
479
+ end
480
+
481
+ return false
482
+ end
483
+
484
+ def close
485
+ # nothing
486
+ end
487
+
488
+ end
489
+
490
+ # Implements an interactive visualizer which builds on top of ncurses.
491
+ class NcursesVisualizer < TppVisualizer
492
+
493
+ def initialize
494
+ @figletfont = "standard"
495
+ Ncurses.initscr
496
+ Ncurses.curs_set(0)
497
+ Ncurses.cbreak # unbuffered input
498
+ Ncurses.noecho # turn off input echoing
499
+ Ncurses.stdscr.intrflush(false)
500
+ Ncurses.stdscr.keypad(true)
501
+ @screen = Ncurses.stdscr
502
+ setsizes
503
+ Ncurses.start_color()
504
+ Ncurses.use_default_colors()
505
+ do_bgcolor("black")
506
+ #do_fgcolor("white")
507
+ @fgcolor = ColorMap.get_color_pair("white")
508
+ @voffset = 5
509
+ @indent = 3
510
+ @cur_line = @voffset
511
+ @output = @shelloutput = false
512
+ end
513
+
514
+ def get_key
515
+ ch = @screen.getch
516
+ case ch
517
+ when Ncurses::KEY_RIGHT
518
+ return :keyright
519
+ when Ncurses::KEY_DOWN
520
+ return :keydown
521
+ when Ncurses::KEY_LEFT
522
+ return :keyleft
523
+ when Ncurses::KEY_UP
524
+ return :keyup
525
+ when Ncurses::KEY_RESIZE
526
+ return :keyresize
527
+ else
528
+ return ch
529
+ end
530
+ end
531
+
532
+ def clear
533
+ @screen.clear
534
+ @screen.refresh
535
+ end
536
+
537
+
538
+ def setsizes
539
+ @termwidth = Ncurses.getmaxx(@screen)
540
+ @termheight = Ncurses.getmaxy(@screen)
541
+ end
542
+
543
+ def do_refresh
544
+ @screen.refresh
545
+ end
546
+
547
+ def do_withborder
548
+ @withborder = true
549
+ draw_border
550
+ end
551
+
552
+ def do_command_prompt()
553
+ message = "Press any key to continue :)"
554
+ cursor_pos = 0
555
+ max_len = 50
556
+ prompt = "tpp@localhost:~ $ "
557
+ string = ""
558
+ window = @screen.dupwin
559
+ Ncurses.overwrite(window,@screen) # overwrite @screen with window
560
+ Ncurses.curs_set(1)
561
+ Ncurses.echo
562
+ window.move(@termheight/4,1)
563
+ window.clrtoeol()
564
+ window.clrtobot()
565
+ window.mvaddstr(@termheight/4,1,prompt) # add the prompt string
566
+
567
+ loop do
568
+ window.mvaddstr(@termheight/4,1+prompt.length,string) # add the code
569
+ window.move(@termheight/4,1+prompt.length+cursor_pos) # move cursor to the end of code
570
+ ch = window.getch
571
+ case ch
572
+ when Ncurses::KEY_ENTER, ?\n, ?\r
573
+ Ncurses.curs_set(0)
574
+ Ncurses.noecho
575
+ rc = Kernel.system(string)
576
+ if not rc then
577
+ @screen.mvaddstr(@termheight/4+1,1,"Error: exec \"#{string}\" failed with error code #{$?}")
578
+ @screen.mvaddstr(@termheight-2,@termwidth/2-message.length/2,message)
579
+ end
580
+ if rc then
581
+ @screen.mvaddstr(@termheight-2,@termwidth/2-message.length/2,message)
582
+ ch = Ncurses.getch()
583
+ @screen.refresh
584
+ end
585
+ return
586
+ when Ncurses::KEY_LEFT
587
+ cursor_pos = [0, cursor_pos-1].max # jump one character to the left
588
+ when Ncurses::KEY_RIGHT
589
+ cursor_pos = [0, cursor_pos+1].max # jump one character to the right
590
+ when Ncurses::KEY_BACKSPACE
591
+ string = string[0...([0, cursor_pos-1].max)] + string[cursor_pos..-1]
592
+ cursor_pos = [0, cursor_pos-1].max
593
+ window.mvaddstr(@termheight/4, 1+prompt.length+string.length, " ")
594
+ when " "[0]..255
595
+ if (cursor_pos < max_len)
596
+ string[cursor_pos,0] = ch.chr
597
+ cursor_pos += 1
598
+ else
599
+ Ncurses.beep
600
+ end
601
+ else
602
+ Ncurses.beep
603
+ end
604
+ end
605
+ Ncurses.curs_set(0)
606
+
607
+ end
608
+
609
+ def draw_border
610
+ @screen.move(0,0)
611
+ @screen.addstr(".")
612
+ (@termwidth-2).times { @screen.addstr("-") }; @screen.addstr(".")
613
+ @screen.move(@termheight-2,0)
614
+ @screen.addstr("`")
615
+ (@termwidth-2).times { @screen.addstr("-") }; @screen.addstr("'")
616
+ 1.upto(@termheight-3) do |y|
617
+ @screen.move(y,0)
618
+ @screen.addstr("|")
619
+ end
620
+ 1.upto(@termheight-3) do |y|
621
+ @screen.move(y,@termwidth-1)
622
+ @screen.addstr("|")
623
+ end
624
+ end
625
+
626
+ def new_page
627
+ @cur_line = @voffset
628
+ @output = @shelloutput = false
629
+ setsizes
630
+ @screen.clear
631
+ end
632
+
633
+ def do_heading(line)
634
+ @screen.attron(Ncurses::A_BOLD)
635
+ print_heading(line)
636
+ @screen.attroff(Ncurses::A_BOLD)
637
+ end
638
+
639
+ def do_horline
640
+ @screen.attron(Ncurses::A_BOLD)
641
+ @termwidth.times do |x|
642
+ @screen.move(@cur_line,x)
643
+ @screen.addstr("-")
644
+ end
645
+ @screen.attroff(Ncurses::A_BOLD)
646
+ end
647
+
648
+ def print_heading(text)
649
+ width = @termwidth - 2*@indent
650
+ lines = split_lines(text,width)
651
+ lines.each do |l|
652
+ @screen.move(@cur_line,@indent)
653
+ x = (@termwidth - l.length)/2
654
+ @screen.move(@cur_line,x)
655
+ @screen.addstr(l)
656
+ @cur_line += 1
657
+ end
658
+ end
659
+
660
+ def do_center(text)
661
+ width = @termwidth - 2*@indent
662
+ if @output or @shelloutput then
663
+ width -= 2
664
+ end
665
+ lines = split_lines(text,width)
666
+ lines.each do |l|
667
+ @screen.move(@cur_line,@indent)
668
+ if @output or @shelloutput then
669
+ @screen.addstr("| ")
670
+ end
671
+ x = (@termwidth - l.length)/2
672
+ @screen.move(@cur_line,x)
673
+ @screen.addstr(l)
674
+ if @output or @shelloutput then
675
+ @screen.move(@cur_line,@termwidth - @indent - 2)
676
+ @screen.addstr(" |")
677
+ end
678
+ @cur_line += 1
679
+ end
680
+ end
681
+
682
+ def do_right(text)
683
+ width = @termwidth - 2*@indent
684
+ if @output or @shelloutput then
685
+ width -= 2
686
+ end
687
+ lines = split_lines(text,width)
688
+ lines.each do |l|
689
+ @screen.move(@cur_line,@indent)
690
+ if @output or @shelloutput then
691
+ @screen.addstr("| ")
692
+ end
693
+ x = (@termwidth - l.length - 5)
694
+ @screen.move(@cur_line,x)
695
+ @screen.addstr(l)
696
+ if @output or @shelloutput then
697
+ @screen.addstr(" |")
698
+ end
699
+ @cur_line += 1
700
+ end
701
+ end
702
+
703
+ def show_help_page
704
+ help_text = [ "tpp help",
705
+ "",
706
+ "space bar ............................... display next entry within page",
707
+ "space bar, cursor-down, cursor-right .... display next page",
708
+ "b, cursor-up, cursor-left ............... display previous page",
709
+ "q, Q .................................... quit tpp",
710
+ "j, J .................................... jump directly to page",
711
+ "l, L .................................... reload current file",
712
+ "s, S .................................... jump to the first page",
713
+ "e, E .................................... jump to the last page",
714
+ "c, C .................................... start command line",
715
+ "?, h .................................... this help screen" ]
716
+ @screen.clear
717
+ y = @voffset
718
+ help_text.each do |line|
719
+ @screen.move(y,@indent)
720
+ @screen.addstr(line)
721
+ y += 1
722
+ end
723
+ @screen.move(@termheight - 2, @indent)
724
+ @screen.addstr("Press any key to return to slide")
725
+ @screen.refresh
726
+ end
727
+
728
+ def do_exec(cmdline)
729
+ rc = Kernel.system(cmdline)
730
+ if not rc then
731
+ # @todo: add error message
732
+ end
733
+ end
734
+
735
+ def do_wait
736
+ # nothing
737
+ end
738
+
739
+ def do_beginoutput
740
+ @screen.move(@cur_line,@indent)
741
+ @screen.addstr(".")
742
+ (@termwidth - @indent*2 - 2).times { @screen.addstr("-") }
743
+ @screen.addstr(".")
744
+ @output = true
745
+ @cur_line += 1
746
+ end
747
+
748
+ def do_beginshelloutput
749
+ @screen.move(@cur_line,@indent)
750
+ @screen.addstr(".")
751
+ (@termwidth - @indent*2 - 2).times { @screen.addstr("-") }
752
+ @screen.addstr(".")
753
+ @shelloutput = true
754
+ @cur_line += 1
755
+ end
756
+
757
+ def do_endoutput
758
+ if @output then
759
+ @screen.move(@cur_line,@indent)
760
+ @screen.addstr("`")
761
+ (@termwidth - @indent*2 - 2).times { @screen.addstr("-") }
762
+ @screen.addstr("'")
763
+ @output = false
764
+ @cur_line += 1
765
+ end
766
+ end
767
+
768
+ def do_title(title)
769
+ do_boldon
770
+ do_center(title)
771
+ do_boldoff
772
+ do_center("")
773
+ end
774
+
775
+ def do_footer(footer_txt)
776
+ @screen.move(@termheight - 3, (@termwidth - footer_txt.length)/2)
777
+ @screen.addstr(footer_txt)
778
+ end
779
+
780
+ def do_header(header_txt)
781
+ @screen.move(@termheight - @termheight+1, (@termwidth - header_txt.length)/2)
782
+ @screen.addstr(header_txt)
783
+ end
784
+
785
+ def do_author(author)
786
+ do_center(author)
787
+ do_center("")
788
+ end
789
+
790
+ def do_date(date)
791
+ do_center(date)
792
+ do_center("")
793
+ end
794
+
795
+ def do_endshelloutput
796
+ if @shelloutput then
797
+ @screen.move(@cur_line,@indent)
798
+ @screen.addstr("`")
799
+ (@termwidth - @indent*2 - 2).times { @screen.addstr("-") }
800
+ @screen.addstr("'")
801
+ @shelloutput = false
802
+ @cur_line += 1
803
+ end
804
+ end
805
+
806
+ def do_sleep(time2sleep)
807
+ Kernel.sleep(time2sleep.to_i)
808
+ end
809
+
810
+ def do_boldon
811
+ @screen.attron(Ncurses::A_BOLD)
812
+ end
813
+
814
+ def do_boldoff
815
+ @screen.attroff(Ncurses::A_BOLD)
816
+ end
817
+
818
+ def do_revon
819
+ @screen.attron(Ncurses::A_REVERSE)
820
+ end
821
+
822
+ def do_revoff
823
+ @screen.attroff(Ncurses::A_REVERSE)
824
+ end
825
+
826
+ def do_ulon
827
+ @screen.attron(Ncurses::A_UNDERLINE)
828
+ end
829
+
830
+ def do_uloff
831
+ @screen.attroff(Ncurses::A_UNDERLINE)
832
+ end
833
+
834
+ def do_beginslideleft
835
+ @slideoutput = true
836
+ @slidedir = "left"
837
+ end
838
+
839
+ def do_endslide
840
+ @slideoutput = false
841
+ end
842
+
843
+ def do_beginslideright
844
+ @slideoutput = true
845
+ @slidedir = "right"
846
+ end
847
+
848
+ def do_beginslidetop
849
+ @slideoutput = true
850
+ @slidedir = "top"
851
+ end
852
+
853
+ def do_beginslidebottom
854
+ @slideoutput = true
855
+ @slidedir = "bottom"
856
+ end
857
+
858
+ def do_sethugefont(params)
859
+ @figletfont = params
860
+ end
861
+
862
+ def do_huge(figlet_text)
863
+ output_width = @termwidth - @indent
864
+ output_width -= 2 if @output or @shelloutput
865
+ op = IO.popen("figlet -f #{@figletfont} -w #{output_width} -k \"#{figlet_text}\"","r")
866
+ op.readlines.each do |line|
867
+ print_line(line)
868
+ end
869
+ op.close
870
+ end
871
+
872
+ def do_bgcolor(color)
873
+ bgcolor = ColorMap.get_color(color) or COLOR_BLACK
874
+ Ncurses.init_pair(1, COLOR_WHITE, bgcolor)
875
+ Ncurses.init_pair(2, COLOR_YELLOW, bgcolor)
876
+ Ncurses.init_pair(3, COLOR_RED, bgcolor)
877
+ Ncurses.init_pair(4, COLOR_GREEN, bgcolor)
878
+ Ncurses.init_pair(5, COLOR_BLUE, bgcolor)
879
+ Ncurses.init_pair(6, COLOR_CYAN, bgcolor)
880
+ Ncurses.init_pair(7, COLOR_MAGENTA, bgcolor)
881
+ Ncurses.init_pair(8, COLOR_BLACK, bgcolor)
882
+ if @fgcolor then
883
+ Ncurses.bkgd(Ncurses.COLOR_PAIR(@fgcolor))
884
+ else
885
+ Ncurses.bkgd(Ncurses.COLOR_PAIR(1))
886
+ end
887
+ end
888
+
889
+ def do_fgcolor(color)
890
+ @fgcolor = ColorMap.get_color_pair(color)
891
+ Ncurses.attron(Ncurses.COLOR_PAIR(@fgcolor))
892
+ end
893
+
894
+ def do_color(color)
895
+ num = ColorMap.get_color_pair(color)
896
+ Ncurses.attron(Ncurses.COLOR_PAIR(num))
897
+ end
898
+
899
+ def type_line(l)
900
+ l.each_byte do |x|
901
+ @screen.addstr(x.chr)
902
+ @screen.refresh()
903
+ r = rand(20)
904
+ time_to_sleep = (5 + r).to_f / 250;
905
+ # puts "#{time_to_sleep} #{r}"
906
+ Kernel.sleep(time_to_sleep)
907
+ end
908
+ end
909
+
910
+ def slide_text(l)
911
+ return if l == ""
912
+ case @slidedir
913
+ when "left"
914
+ xcount = l.length-1
915
+ while xcount >= 0
916
+ @screen.move(@cur_line,@indent)
917
+ @screen.addstr(l[xcount..l.length-1])
918
+ @screen.refresh()
919
+ time_to_sleep = 1.to_f / 20
920
+ Kernel.sleep(time_to_sleep)
921
+ xcount -= 1
922
+ end
923
+ when "right"
924
+ (@termwidth - @indent).times do |pos|
925
+ @screen.move(@cur_line,@termwidth - pos - 1)
926
+ @screen.clrtoeol()
927
+ maxpos = (pos >= l.length-1) ? l.length-1 : pos
928
+ @screen.addstr(l[0..pos])
929
+ @screen.refresh()
930
+ time_to_sleep = 1.to_f / 20
931
+ Kernel.sleep(time_to_sleep)
932
+ end # do
933
+ when "top"
934
+ # ycount = @cur_line
935
+ new_scr = @screen.dupwin
936
+ 1.upto(@cur_line) do |i|
937
+ Ncurses.overwrite(new_scr,@screen) # overwrite @screen with new_scr
938
+ @screen.move(i,@indent)
939
+ @screen.addstr(l)
940
+ @screen.refresh()
941
+ Kernel.sleep(1.to_f / 10)
942
+ end
943
+ when "bottom"
944
+ new_scr = @screen.dupwin
945
+ (@termheight-1).downto(@cur_line) do |i|
946
+ Ncurses.overwrite(new_scr,@screen)
947
+ @screen.move(i,@indent)
948
+ @screen.addstr(l)
949
+ @screen.refresh()
950
+ Kernel.sleep(1.to_f / 10)
951
+ end
952
+ end
953
+ end
954
+
955
+ def print_line(line)
956
+ width = @termwidth - 2*@indent
957
+ if @output or @shelloutput then
958
+ width -= 2
959
+ end
960
+ lines = split_lines(line,width)
961
+ lines.each do |l|
962
+ @screen.move(@cur_line,@indent)
963
+ if (@output or @shelloutput) and ! @slideoutput then
964
+ @screen.addstr("| ")
965
+ end
966
+ if @shelloutput and (l =~ /^\$/ or l=~ /^%/ or l =~ /^#/) then # allow sh and csh style prompts
967
+ type_line(l)
968
+ elsif @slideoutput then
969
+ slide_text(l)
970
+ else
971
+ @screen.addstr(l)
972
+ end
973
+ if (@output or @shelloutput) and ! @slideoutput then
974
+ @screen.move(@cur_line,@termwidth - @indent - 2)
975
+ @screen.addstr(" |")
976
+ end
977
+ @cur_line += 1
978
+ end
979
+ end
980
+
981
+ def close
982
+ Ncurses.nocbreak
983
+ Ncurses.endwin
984
+ end
985
+
986
+ def read_newpage(pages,current_page)
987
+ page = []
988
+ @screen.clear()
989
+ col = 0
990
+ line = 2
991
+ pages.each_index do |i|
992
+ @screen.move(line,col*15 + 2)
993
+ if current_page == i then
994
+ @screen.printw("%2d %s <=",i+1,pages[i].title[0..80])
995
+ else
996
+ @screen.printw("%2d %s",i+1,pages[i].title[0..80])
997
+ end
998
+ line += 1
999
+ if line >= @termheight - 3 then
1000
+ line = 2
1001
+ col += 1
1002
+ end
1003
+ end
1004
+ prompt = "jump to slide: "
1005
+ prompt_indent = 12
1006
+ @screen.move(@termheight - 2, @indent + prompt_indent)
1007
+ @screen.addstr(prompt)
1008
+ # @screen.refresh();
1009
+ Ncurses.echo
1010
+ @screen.scanw("%d",page)
1011
+ Ncurses.noecho
1012
+ @screen.move(@termheight - 2, @indent + prompt_indent)
1013
+ (prompt.length + page[0].to_s.length).times { @screen.addstr(" ") }
1014
+ if page[0] then
1015
+ return page[0] - 1
1016
+ end
1017
+ return -1 # invalid page
1018
+ end
1019
+
1020
+ def store_screen
1021
+ @screen.dupwin
1022
+ end
1023
+
1024
+ def restore_screen(s)
1025
+ Ncurses.overwrite(s,@screen)
1026
+ end
1027
+
1028
+ def draw_slidenum(cur_page,max_pages,eop)
1029
+ @screen.move(@termheight - 2, @indent)
1030
+ @screen.attroff(Ncurses::A_BOLD) # this is bad
1031
+ @screen.addstr("[slide #{cur_page}/#{max_pages}]")
1032
+ if @footer_txt.to_s.length > 0 then
1033
+ do_footer(@footer_txt)
1034
+ end
1035
+ if @header_txt.to_s.length > 0 then
1036
+ do_header(@header_txt)
1037
+ end
1038
+
1039
+ if eop then
1040
+ draw_eop_marker
1041
+ end
1042
+ end
1043
+
1044
+ def draw_eop_marker
1045
+ @screen.move(@termheight - 2, @indent - 1)
1046
+ @screen.attron(A_BOLD)
1047
+ @screen.addstr("*")
1048
+ @screen.attroff(A_BOLD)
1049
+ end
1050
+
1051
+ end
1052
+
1053
+
1054
+ # Implements a visualizer which converts TPP source to LaTeX-beamer source (http://latex-beamer.sf.net/
1055
+ class LatexVisualizer < TppVisualizer
1056
+
1057
+ def initialize(outputfile)
1058
+ @filename = outputfile
1059
+ begin
1060
+ @f = File.open(@filename,"w+")
1061
+ rescue
1062
+ $stderr.print "Error: couldn't open file: #{$!}"
1063
+ Kernel.exit(1)
1064
+ end
1065
+ @slide_open = false
1066
+ @verbatim_open = false
1067
+ @width = 50
1068
+ @title = @date = @author = false
1069
+ @begindoc = false
1070
+ @f.puts '% Filename: tpp.tex
1071
+ % Purpose: template file for tpp latex export
1072
+ % Authors: (c) Andreas Gredler, Michael Prokop http://grml.org/
1073
+ % License: This file is licensed under the GPL v2.
1074
+ % Latest change: Fre Apr 15 20:34:37 CEST 2005
1075
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1076
+
1077
+ \documentclass{beamer}
1078
+
1079
+ \mode<presentation>
1080
+ {
1081
+ \usetheme{Montpellier}
1082
+ \setbeamercovered{transparent}
1083
+ }
1084
+
1085
+ \usepackage[german]{babel}
1086
+ \usepackage{umlaut}
1087
+ \usepackage[latin1]{inputenc}
1088
+ \usepackage{times}
1089
+ \usepackage[T1]{fontenc}
1090
+
1091
+ '
1092
+ end
1093
+
1094
+ def do_footer(footer_text)
1095
+ end
1096
+
1097
+ def do_header(header_text)
1098
+ end
1099
+
1100
+ def do_refresh
1101
+ end
1102
+
1103
+ def try_close
1104
+ if @verbatim_open then
1105
+ @f.puts '\end{verbatim}'
1106
+ @verbatim_open = false
1107
+ end
1108
+ if @slide_open then
1109
+ @f.puts '\end{frame}'
1110
+ @slide_open = false
1111
+ end
1112
+ end
1113
+
1114
+ def new_page
1115
+ try_close
1116
+ end
1117
+
1118
+ def do_heading(text)
1119
+ try_close
1120
+ @f.puts "\\section{#{text}}"
1121
+ end
1122
+
1123
+ def do_withborder
1124
+ end
1125
+
1126
+ def do_horline
1127
+ end
1128
+
1129
+ def do_color(text)
1130
+ end
1131
+
1132
+ def do_center(text)
1133
+ print_line(text)
1134
+ end
1135
+
1136
+ def do_right(text)
1137
+ print_line(text)
1138
+ end
1139
+
1140
+ def do_exec(cmdline)
1141
+ end
1142
+
1143
+ def do_wait
1144
+ end
1145
+
1146
+ def do_beginoutput
1147
+ # TODO: implement output stuff
1148
+ end
1149
+
1150
+ def do_beginshelloutput
1151
+ end
1152
+
1153
+ def do_endoutput
1154
+ end
1155
+
1156
+ def do_endshelloutput
1157
+ end
1158
+
1159
+ def do_sleep(time2sleep)
1160
+ end
1161
+
1162
+ def do_boldon
1163
+ end
1164
+
1165
+ def do_boldoff
1166
+ end
1167
+
1168
+ def do_revon
1169
+ end
1170
+
1171
+ def do_command_prompt
1172
+ end
1173
+ def do_revoff
1174
+ end
1175
+
1176
+ def do_ulon
1177
+ end
1178
+
1179
+ def do_uloff
1180
+ end
1181
+
1182
+ def do_beginslideleft
1183
+ end
1184
+
1185
+ def do_endslide
1186
+ end
1187
+
1188
+ def do_beginslideright
1189
+ end
1190
+
1191
+ def do_beginslidetop
1192
+ end
1193
+
1194
+ def do_beginslidebottom
1195
+ end
1196
+
1197
+ def do_sethugefont(text)
1198
+ end
1199
+
1200
+ def do_huge(text)
1201
+ end
1202
+
1203
+ def try_open
1204
+ if not @begindoc then
1205
+ @f.puts '\begin{document}'
1206
+ @begindoc = true
1207
+ end
1208
+ if not @slide_open then
1209
+ @f.puts '\begin{frame}[fragile]'
1210
+ @slide_open = true
1211
+ end
1212
+ if not @verbatim_open then
1213
+ @f.puts '\begin{verbatim}'
1214
+ @verbatim_open = true
1215
+ end
1216
+ end
1217
+
1218
+ def try_intro
1219
+ if @author and @title and @date and not @begindoc then
1220
+ @f.puts '\begin{document}'
1221
+ @begindoc = true
1222
+ end
1223
+ if @author and @title and @date then
1224
+ @f.puts '\begin{frame}
1225
+ \titlepage
1226
+ \end{frame}'
1227
+ end
1228
+ end
1229
+
1230
+ def print_line(line)
1231
+ try_open
1232
+ split_lines(line,@width).each do |l|
1233
+ @f.puts "#{l}"
1234
+ end
1235
+ end
1236
+
1237
+ def do_title(title)
1238
+ @f.puts "\\title[#{title}]{#{title}}"
1239
+ @title = true
1240
+ try_intro
1241
+ end
1242
+
1243
+ def do_author(author)
1244
+ @f.puts "\\author{#{author}}"
1245
+ @author = true
1246
+ try_intro
1247
+ end
1248
+
1249
+ def do_date(date)
1250
+ @f.puts "\\date{#{date}}"
1251
+ @date = true
1252
+ try_intro
1253
+ end
1254
+
1255
+ def do_bgcolor(color)
1256
+ end
1257
+
1258
+ def do_fgcolor(color)
1259
+ end
1260
+
1261
+ def do_color(color)
1262
+ end
1263
+
1264
+ def close
1265
+ try_close
1266
+ @f.puts '\end{document}
1267
+ %%%%% END OF FILE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'
1268
+ @f.close
1269
+ end
1270
+
1271
+ end
1272
+
1273
+
1274
+ # Implements a generic controller from which all other controllers need to be derived.
1275
+ class TppController
1276
+
1277
+ def initialize
1278
+ $stderr.puts "Error: TppController.initialize has been called directly!"
1279
+ Kernel.exit(1)
1280
+ end
1281
+
1282
+ def close
1283
+ $stderr.puts "Error: TppController.close has been called directly!"
1284
+ Kernel.exit(1)
1285
+ end
1286
+
1287
+ def run
1288
+ $stderr.puts "Error: TppController.run has been called directly!"
1289
+ Kernel.exit(1)
1290
+ end
1291
+
1292
+ end
1293
+
1294
+ # Implements a non-interactive controller for ncurses. Useful for displaying
1295
+ # unattended presentation.
1296
+ class AutoplayController < TppController
1297
+
1298
+ def initialize(filename,secs,visualizer_class)
1299
+ @filename = filename
1300
+ @vis = visualizer_class.new
1301
+ @seconds = secs
1302
+ @cur_page = 0
1303
+ end
1304
+
1305
+ def close
1306
+ @vis.close
1307
+ end
1308
+
1309
+ def run
1310
+ begin
1311
+ @reload_file = false
1312
+ parser = FileParser.new(@filename)
1313
+ @pages = parser.get_pages
1314
+ if @cur_page >= @pages.size then
1315
+ @cur_page = @pages.size - 1
1316
+ end
1317
+ @vis.clear
1318
+ @vis.new_page
1319
+ do_run
1320
+ end while @reload_file
1321
+ end
1322
+
1323
+ def do_run
1324
+ loop do
1325
+ wait = false
1326
+ @vis.draw_slidenum(@cur_page + 1, @pages.size, false)
1327
+ # read and visualize lines until the visualizer says "stop" or we reached end of page
1328
+ begin
1329
+ line = @pages[@cur_page].next_line
1330
+ eop = @pages[@cur_page].eop?
1331
+ wait = @vis.visualize(line,eop)
1332
+ end while not wait and not eop
1333
+ # draw slide number on the bottom left and redraw:
1334
+ @vis.draw_slidenum(@cur_page + 1, @pages.size, eop)
1335
+ @vis.do_refresh
1336
+
1337
+ if eop then
1338
+ if @cur_page + 1 < @pages.size then
1339
+ @cur_page += 1
1340
+ else
1341
+ @cur_page = 0
1342
+ end
1343
+ @pages[@cur_page].reset_eop
1344
+ @vis.new_page
1345
+ end
1346
+
1347
+ Kernel.sleep(@seconds)
1348
+ end # loop
1349
+ end
1350
+
1351
+ end
1352
+
1353
+ # Implements an interactive controller which feeds the visualizer until it is
1354
+ # told to stop, and then reads a key press and executes the appropiate action.
1355
+ class InteractiveController < TppController
1356
+
1357
+ def initialize(filename,visualizer_class)
1358
+ @filename = filename
1359
+ @vis = visualizer_class.new
1360
+ @cur_page = 0
1361
+ end
1362
+
1363
+ def close
1364
+ @vis.close
1365
+ end
1366
+
1367
+ def run
1368
+ begin
1369
+ @reload_file = false
1370
+ parser = FileParser.new(@filename)
1371
+ @pages = parser.get_pages
1372
+ if @cur_page >= @pages.size then
1373
+ @cur_page = @pages.size - 1
1374
+ end
1375
+ @vis.clear
1376
+ @vis.new_page
1377
+ do_run
1378
+ end while @reload_file
1379
+ end
1380
+
1381
+ def do_run
1382
+ loop do
1383
+ wait = false
1384
+ @vis.draw_slidenum(@cur_page + 1, @pages.size, false)
1385
+ # read and visualize lines until the visualizer says "stop" or we reached end of page
1386
+ begin
1387
+ line = @pages[@cur_page].next_line
1388
+ eop = @pages[@cur_page].eop?
1389
+ wait = @vis.visualize(line,eop)
1390
+ end while not wait and not eop
1391
+ # draw slide number on the bottom left and redraw:
1392
+ @vis.draw_slidenum(@cur_page + 1, @pages.size, eop)
1393
+ @vis.do_refresh
1394
+
1395
+ # read a character from the keyboard
1396
+ # a "break" in the when means that it breaks the loop, i.e. goes on with visualizing lines
1397
+ loop do
1398
+ ch = @vis.get_key
1399
+ case ch
1400
+ when 'q'[0], 'Q'[0] # 'Q'uit
1401
+ return
1402
+ when 'r'[0], 'R'[0] # 'R'edraw slide
1403
+ changed_page = true # @todo: actually implement redraw
1404
+ when 'e'[0], 'E'[0]
1405
+ @cur_page = @pages.size - 1
1406
+ break
1407
+ when 's'[0], 'S'[0]
1408
+ @cur_page = 0
1409
+ break
1410
+ when 'j'[0], 'J'[0] # 'J'ump to slide
1411
+ screen = @vis.store_screen
1412
+ p = @vis.read_newpage(@pages,@cur_page)
1413
+ if p >= 0 and p < @pages.size
1414
+ @cur_page = p
1415
+ @pages[@cur_page].reset_eop
1416
+ @vis.new_page
1417
+ else
1418
+ @vis.restore_screen(screen)
1419
+ end
1420
+ break
1421
+ when 'l'[0], 'L'[0] # re'l'oad current file
1422
+ @reload_file = true
1423
+ return
1424
+ when 'c'[0], 'C'[0] # command prompt
1425
+ screen = @vis.store_screen
1426
+ @vis.do_command_prompt
1427
+ @vis.clear
1428
+ @vis.restore_screen(screen)
1429
+ when '?'[0], 'h'[0]
1430
+ screen = @vis.store_screen
1431
+ @vis.show_help_page
1432
+ ch = @vis.get_key
1433
+ @vis.clear
1434
+ @vis.restore_screen(screen)
1435
+ when :keyright, :keydown, ' '[0]
1436
+ if @cur_page + 1 < @pages.size and eop then
1437
+ @cur_page += 1
1438
+ @pages[@cur_page].reset_eop
1439
+ @vis.new_page
1440
+ end
1441
+ break
1442
+ when 'b'[0], 'B'[0], :keyleft, :keyup
1443
+ if @cur_page > 0 then
1444
+ @cur_page -= 1
1445
+ @pages[@cur_page].reset_eop
1446
+ @vis.new_page
1447
+ end
1448
+ break
1449
+ when :keyresize
1450
+ @vis.setsizes
1451
+ end
1452
+ end
1453
+ end # loop
1454
+ end
1455
+
1456
+ end
1457
+
1458
+
1459
+ # Implements a visualizer which converts TPP source to a nicely formatted text
1460
+ # file which can e.g. be used as handout.
1461
+ class TextVisualizer < TppVisualizer
1462
+
1463
+ def initialize(outputfile)
1464
+ @filename = outputfile
1465
+ begin
1466
+ @f = File.open(@filename,"w+")
1467
+ rescue
1468
+ $stderr.print "Error: couldn't open file: #{$!}"
1469
+ Kernel.exit(1)
1470
+ end
1471
+ @output_env = false
1472
+ @title = @author = @date = false
1473
+ @figletfont = "small"
1474
+ @width = 80
1475
+ end
1476
+
1477
+ def do_footer(footer_text)
1478
+ end
1479
+
1480
+ def do_header(header_text)
1481
+ end
1482
+
1483
+ def do_refresh
1484
+ end
1485
+
1486
+ def new_page
1487
+ @f.puts "--------------------------------------------"
1488
+ end
1489
+
1490
+ def do_heading(text)
1491
+ @f.puts "\n"
1492
+ split_lines(text,@width).each do |l|
1493
+ @f.puts "#{l}\n"
1494
+ end
1495
+ @f.puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
1496
+ end
1497
+
1498
+ def do_withborder
1499
+ end
1500
+
1501
+ def do_horline
1502
+ @f.puts "********************************************"
1503
+ end
1504
+
1505
+ def do_color(text)
1506
+ end
1507
+
1508
+ def do_exec(cmdline)
1509
+ end
1510
+
1511
+ def do_wait
1512
+ end
1513
+
1514
+ def do_beginoutput
1515
+ @f.puts ".---------------------------"
1516
+ @output_env = true
1517
+ end
1518
+
1519
+ def do_beginshelloutput
1520
+ do_beginoutput
1521
+ end
1522
+
1523
+ def do_endoutput
1524
+ @f.puts "`---------------------------"
1525
+ @output_env = false
1526
+ end
1527
+
1528
+ def do_endshelloutput
1529
+ do_endoutput
1530
+ end
1531
+
1532
+ def do_sleep(time2sleep)
1533
+ end
1534
+
1535
+ def do_boldon
1536
+ end
1537
+
1538
+ def do_boldoff
1539
+ end
1540
+
1541
+ def do_revon
1542
+ end
1543
+
1544
+ def do_command_prompt
1545
+ end
1546
+ def do_revoff
1547
+ end
1548
+
1549
+ def do_ulon
1550
+ end
1551
+
1552
+ def do_uloff
1553
+ end
1554
+
1555
+ def do_beginslideleft
1556
+ end
1557
+
1558
+ def do_endslide
1559
+ end
1560
+
1561
+ def do_beginslideright
1562
+ end
1563
+
1564
+ def do_beginslidetop
1565
+ end
1566
+
1567
+ def do_beginslidebottom
1568
+ end
1569
+
1570
+ def do_sethugefont(text)
1571
+ @figletfont = text
1572
+ end
1573
+
1574
+ def do_huge(text)
1575
+ output_width = @width
1576
+ output_width -= 2 if @output_env
1577
+ op = IO.popen("figlet -f #{@figletfont} -w @output_width -k \"#{text}\"","r")
1578
+ op.readlines.each do |line|
1579
+ print_line(line)
1580
+ end
1581
+ op.close
1582
+ end
1583
+
1584
+ def print_line(line)
1585
+ lines = split_lines(line,@width)
1586
+ lines.each do |l|
1587
+ if @output_env then
1588
+ @f.puts "| #{l}"
1589
+ else
1590
+ @f.puts "#{l}"
1591
+ end
1592
+ end
1593
+ end
1594
+
1595
+ def do_center(text)
1596
+ lines = split_lines(text,@width)
1597
+ lines.each do |line|
1598
+ spaces = (@width - line.length) / 2
1599
+ spaces = 0 if spaces < 0
1600
+ spaces.times { line = " " + line }
1601
+ print_line(line)
1602
+ end
1603
+ end
1604
+
1605
+ def do_right(text)
1606
+ lines = split_lines(text,@width)
1607
+ lines.each do |line|
1608
+ spaces = @width - line.length
1609
+ spaces = 0 if spaces < 0
1610
+ spaces.times { line = " " + line }
1611
+ print_line(line)
1612
+ end
1613
+ end
1614
+
1615
+ def do_title(title)
1616
+ @f.puts "Title: #{title}"
1617
+ @title = true
1618
+ if @title and @author and @date then
1619
+ @f.puts "\n\n"
1620
+ end
1621
+ end
1622
+
1623
+ def do_author(author)
1624
+ @f.puts "Author: #{author}"
1625
+ @author = true
1626
+ if @title and @author and @date then
1627
+ @f.puts "\n\n"
1628
+ end
1629
+ end
1630
+
1631
+ def do_date(date)
1632
+ @f.puts "Date: #{date}"
1633
+ @date = true
1634
+ if @title and @author and @date then
1635
+ @f.puts "\n\n"
1636
+ end
1637
+ end
1638
+
1639
+ def do_bgcolor(color)
1640
+ end
1641
+
1642
+ def do_fgcolor(color)
1643
+ end
1644
+
1645
+ def do_color(color)
1646
+ end
1647
+
1648
+ def close
1649
+ @f.close
1650
+ end
1651
+
1652
+ end
1653
+
1654
+ # Implements a non-interactive controller to control non-interactive
1655
+ # visualizers (i.e. those that are used for converting TPP source code into
1656
+ # another format)
1657
+ class ConversionController < TppController
1658
+
1659
+ def initialize(input,output,visualizer_class)
1660
+ parser = FileParser.new(input)
1661
+ @pages = parser.get_pages
1662
+ @vis = visualizer_class.new(output)
1663
+ end
1664
+
1665
+ def run
1666
+ @pages.each do |p|
1667
+ begin
1668
+ line = p.next_line
1669
+ eop = p.eop?
1670
+ @vis.visualize(line,eop)
1671
+ end while not eop
1672
+ end
1673
+ end
1674
+
1675
+ def close
1676
+ @vis.close
1677
+ end
1678
+
1679
+ end
1680
+
1681
+ # Prints a nicely formatted usage message.
1682
+ def usage
1683
+ $stderr.puts "usage: #{$0} [-t <type> -o <file>] <file>\n"
1684
+ $stderr.puts "\t -t <type>\tset filetype <type> as output format"
1685
+ $stderr.puts "\t -o <file>\twrite output to file <file>"
1686
+ $stderr.puts "\t -s <seconds>\twait <seconds> seconds between slides (with -t autoplay)"
1687
+ $stderr.puts "\t --version\tprint the version"
1688
+ $stderr.puts "\t --help\t\tprint this help"
1689
+ $stderr.puts "\n\t currently available types: ncurses (default), autoplay, latex, txt"
1690
+ Kernel.exit(1)
1691
+ end
1692
+
1693
+
1694
+
1695
+ ################################
1696
+ # Here starts the main program #
1697
+ ################################
1698
+
1699
+ input = nil
1700
+ output = nil
1701
+ type = "ncurses"
1702
+ time = 1
1703
+
1704
+ skip_next = false
1705
+
1706
+ ARGV.each_index do |i|
1707
+ if skip_next then
1708
+ skip_next = false
1709
+ else
1710
+ if ARGV[i] == '-v' or ARGV[i] == '--version' then
1711
+ printf "tpp - text presentation program %s\n", version_number
1712
+ Kernel.exit(1)
1713
+ elsif ARGV[i] == '-h' or ARGV[i] == '--help' then
1714
+ usage
1715
+ elsif ARGV[i] == '-t' then
1716
+ type = ARGV[i+1]
1717
+ skip_next = true
1718
+ elsif ARGV[i] == '-o' then
1719
+ output = ARGV[i+1]
1720
+ skip_next = true
1721
+ elsif ARGV[i] == "-s" then
1722
+ time = ARGV[i+1].to_i
1723
+ skip_next = true
1724
+ elsif input == nil then
1725
+ input = ARGV[i]
1726
+ end
1727
+ if output!=nil and output==input then
1728
+ $stderr.puts "Don't use the input file name as the output filename to prevent overwriting it. \n"
1729
+ Kernel.exit(1)
1730
+ end
1731
+ end
1732
+ end
1733
+
1734
+ if input == nil then
1735
+ usage
1736
+ end
1737
+
1738
+ ctrl = nil
1739
+
1740
+ case type
1741
+ when "ncurses"
1742
+ load_ncurses
1743
+ ctrl = InteractiveController.new(input,NcursesVisualizer)
1744
+ when "autoplay"
1745
+ load_ncurses
1746
+ ctrl = AutoplayController.new(input,time,NcursesVisualizer)
1747
+ when "txt"
1748
+ if output == nil then
1749
+ usage
1750
+ else
1751
+ ctrl = ConversionController.new(input,output,TextVisualizer)
1752
+ end
1753
+ when "latex"
1754
+ if output == nil then
1755
+ usage
1756
+ else
1757
+ ctrl = ConversionController.new(input,output,LatexVisualizer)
1758
+ end
1759
+ else
1760
+ usage
1761
+ end # case
1762
+
1763
+ ctrl.run
1764
+ ctrl.close