genki-present 0.0.2

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/ChangeLog ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 / 2008-08-31
2
+
3
+ * initial release
4
+
data/README ADDED
@@ -0,0 +1,41 @@
1
+
2
+ = present
3
+
4
+ Presentation tool for terminal.
5
+
6
+ == Description
7
+
8
+ This program is for terminal addicts.
9
+ You can present your slide by using your favorite terminal.
10
+
11
+ == Installation
12
+
13
+ === Archive Installation
14
+
15
+ rake install
16
+
17
+ === Gem Installation
18
+
19
+ gem install present
20
+
21
+
22
+ == Features/Problems
23
+
24
+
25
+ == Synopsis
26
+
27
+ present [options] file [duration] [page]
28
+
29
+ `file` specifies presentation file. there is an example in the sample/ dir.
30
+
31
+ `duration` specifies expected duration in minute. This is optional. The
32
+ default value is 5 min.
33
+
34
+ `page` specifies the page number which will be started from. This is
35
+ optional. The default value is 1.
36
+
37
+ == Copyright
38
+
39
+ Author:: Genki Takiuchi <genki@s21g.com>
40
+ Copyright:: Copyright (c) 2008 Genki Takiuchi
41
+ License::
data/Rakefile ADDED
@@ -0,0 +1,150 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ require 'rake/contrib/sshpublisher'
10
+ require 'fileutils'
11
+
12
+ $:.unshift File.join(File.dirname(__FILE__), 'lib')
13
+ require 'present'
14
+ include FileUtils
15
+
16
+ NAME = "present"
17
+ AUTHOR = "Genki Takiuchi"
18
+ EMAIL = "genki@s21g.com"
19
+ DESCRIPTION = "Presentation tool for terminal."
20
+ RUBYFORGE_PROJECT = "cocktail-party"
21
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
22
+ BIN_FILES = %w(present)
23
+
24
+ VERS = Present::VERSION
25
+ REV = File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
26
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config']
27
+ RDOC_OPTS = [
28
+ '--title', "#{NAME} documentation",
29
+ "--charset", "utf-8",
30
+ "--opname", "index.html",
31
+ "--line-numbers",
32
+ "--main", "README",
33
+ "--inline-source",
34
+ ]
35
+
36
+ task :default => [:test]
37
+ task :package => [:clean]
38
+
39
+ Rake::TestTask.new("test") do |t|
40
+ t.libs << "test"
41
+ t.pattern = "test/**/*_test.rb"
42
+ t.verbose = true
43
+ end
44
+
45
+ spec = Gem::Specification.new do |s|
46
+ s.name = NAME
47
+ s.version = VERS
48
+ s.platform = Gem::Platform::RUBY
49
+ s.has_rdoc = true
50
+ s.extra_rdoc_files = ["README", "ChangeLog"]
51
+ s.rdoc_options += RDOC_OPTS + ['--exclude', '^(examples|extras)/']
52
+ s.summary = DESCRIPTION
53
+ s.description = DESCRIPTION
54
+ s.author = AUTHOR
55
+ s.email = EMAIL
56
+ s.homepage = HOMEPATH
57
+ s.executables = BIN_FILES
58
+ s.rubyforge_project = RUBYFORGE_PROJECT
59
+ s.bindir = "bin"
60
+ s.require_path = "lib"
61
+ #s.autorequire = ""
62
+ s.test_files = Dir["test/*_test.rb"]
63
+
64
+ #s.add_dependency('activesupport', '>=1.3.1')
65
+ s.add_dependency('ncurses')
66
+ s.add_dependency('text')
67
+ s.add_dependency('escape')
68
+ s.add_dependency('redgreen')
69
+ #s.required_ruby_version = '>= 1.8.2'
70
+
71
+ s.files = %w(README ChangeLog Rakefile) +
72
+ Dir.glob("{bin,doc,test,lib,templates,generator,extras,website,script}/**/*") +
73
+ Dir.glob("ext/**/*.{h,c,rb}") +
74
+ Dir.glob("examples/**/*.rb") +
75
+ Dir.glob("tools/*.rb") +
76
+ Dir.glob("rails/*.rb")
77
+
78
+ s.extensions = FileList["ext/**/extconf.rb"].to_a
79
+ end
80
+
81
+ Rake::GemPackageTask.new(spec) do |p|
82
+ p.need_tar = true
83
+ p.gem_spec = spec
84
+ end
85
+
86
+ task :install do
87
+ name = "#{NAME}-#{VERS}.gem"
88
+ sh %{rake package}
89
+ sh %{sudo gem install pkg/#{name}}
90
+ end
91
+
92
+ task :uninstall => [:clean] do
93
+ sh %{sudo gem uninstall #{NAME}}
94
+ end
95
+
96
+
97
+ Rake::RDocTask.new do |rdoc|
98
+ rdoc.rdoc_dir = 'html'
99
+ rdoc.options += RDOC_OPTS
100
+ rdoc.template = "resh"
101
+ #rdoc.template = "#{ENV['template']}.rb" if ENV['template']
102
+ if ENV['DOC_FILES']
103
+ rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/))
104
+ else
105
+ rdoc.rdoc_files.include('README', 'ChangeLog')
106
+ rdoc.rdoc_files.include('lib/**/*.rb')
107
+ rdoc.rdoc_files.include('ext/**/*.c')
108
+ end
109
+ end
110
+
111
+ desc "Publish to RubyForge"
112
+ task :rubyforge => [:rdoc, :package] do
113
+ require 'rubyforge'
114
+ Rake::RubyForgePublisher.new(RUBYFORGE_PROJECT, 'takiuchi').upload
115
+ end
116
+
117
+ desc 'Package and upload the release to rubyforge.'
118
+ task :release => [:clean, :package] do |t|
119
+ v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z"
120
+ abort "Versions don't match #{v} vs #{VERS}" unless v == VERS
121
+ pkg = "pkg/#{NAME}-#{VERS}"
122
+
123
+ require 'rubyforge'
124
+ rf = RubyForge.new.configure
125
+ puts "Logging in"
126
+ rf.login
127
+
128
+ c = rf.userconfig
129
+ # c["release_notes"] = description if description
130
+ # c["release_changes"] = changes if changes
131
+ c["preformatted"] = true
132
+
133
+ files = [
134
+ "#{pkg}.tgz",
135
+ "#{pkg}.gem"
136
+ ].compact
137
+
138
+ puts "Releasing #{NAME} v. #{VERS}"
139
+ rf.add_release RUBYFORGE_PROJECT, NAME, VERS, *files
140
+ end
141
+
142
+ desc 'Show information about the gem.'
143
+ task :debug_gem do
144
+ puts spec.to_ruby
145
+ end
146
+
147
+ desc 'Update gem spec'
148
+ task :gemspec do
149
+ open("#{NAME}.gemspec", 'w').write spec.to_ruby
150
+ end
data/bin/present ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.join(File.dirname(__FILE__), '../lib')
3
+ require 'optparse'
4
+ require 'present'
5
+
6
+ Version = Present::VERSION
7
+ opt = OptionParser.new
8
+ opt.banner = "Usage: present [options] file [duration] [page]"
9
+ opt.on_tail('-v', '--version', 'Show version.'){puts opt.ver; exit}
10
+ opt.order!(ARGV)
11
+
12
+ if ARGV.empty?
13
+ system $0, '-h'
14
+ else
15
+ Present.new(*ARGV).start
16
+ end
data/lib/present.rb ADDED
@@ -0,0 +1,227 @@
1
+ require 'rubygems'
2
+ require 'ncurses'
3
+ require 'text'
4
+ require 'escape'
5
+ require 'nkf'
6
+ require 'present/page'
7
+
8
+ class Present
9
+ VERSION = '0.0.3'
10
+ TIOCGWINSZ = 0x5413
11
+
12
+ def initialize(path, timer = 5, page = 1)
13
+ @source = path
14
+ @script = NKF.nkf('-e', open(path).read)
15
+ @stanzas = @script.split(/\n\n+/)
16
+ str = [0, 0, 0, 0].pack("SSSS")
17
+ if $stdin.ioctl(TIOCGWINSZ, str) >= 0 then
18
+ @rows, @cols, xpixels, ypixels = str.unpack("SSSS")
19
+ else
20
+ @rows, @cols = 13, 40
21
+ end
22
+ @pages = @stanzas.map{|stanza| Page.new(stanza, self)}
23
+ @page = page.to_i - 1
24
+ @timer = timer.to_i * 60
25
+ end
26
+
27
+ def start
28
+ Ncurses.initscr
29
+ Ncurses.raw
30
+ Ncurses.cbreak
31
+ Ncurses.noecho
32
+ Ncurses.start_color
33
+ Ncurses.refresh
34
+ @win = Ncurses::WINDOW.new @rows - 1, @cols, 0, 0
35
+ @win.keypad true
36
+ Ncurses.nodelay @win, 1
37
+ @status = Ncurses::WINDOW.new 1, @cols + 1, @rows - 1, 0
38
+ @status.color_set 1, nil
39
+ @start = Time.now
40
+ @colors = {}
41
+ register_pair Ncurses::COLOR_BLACK, Ncurses::COLOR_WHITE
42
+ while page = @pages[@page]
43
+ @row = @rows / 4
44
+ paginate
45
+ page.start
46
+
47
+ begin
48
+ input = @win.getch
49
+ case input
50
+ when 27, ?q; return # exit
51
+ when ?:; scan_command
52
+ when ?k, ?h, 259, 260; @page = [@page - 1, 0].max
53
+ when ?<; @page = 0
54
+ when ?>; @page = @pages.size - 1
55
+ when ?j, ?l, 10, 13, 32, 258, 261
56
+ @page = [@page + 1, @pages.size - 1].min
57
+ when ?r; reload
58
+ else
59
+ sleep 0.1
60
+ paginate
61
+ end
62
+ end while input == -1
63
+ end
64
+ ensure
65
+ Ncurses.endwin
66
+ end
67
+
68
+ def figlet(font, cols, text)
69
+ font = 'term' if mb?(text)
70
+ cmd = Escape.shell_command(['figlet', '-f', "#{font}.flf", '-w', cols.to_s])
71
+ IO.popen(cmd, 'r+') do |io|
72
+ io.write text
73
+ io.close_write
74
+ io.read
75
+ end
76
+ end
77
+
78
+ def reload
79
+ Ncurses.endwin
80
+ exec "#{$0} #{@source} #{@timer/60} #{@page + 1}"
81
+ end
82
+
83
+ def center(text, options = {})
84
+ return if text.empty?
85
+ font = options[:font] || 'mini'
86
+ text = figlet font, @cols, text
87
+ rows, cols = sizeof(text)
88
+ top = (@rows - rows)/2
89
+ left = (@cols - cols)/2
90
+ @win.attron Ncurses::A_BOLD
91
+ text = text.split("\n").each_with_index do |line, i|
92
+ mvwprintw top + i, left, line
93
+ end
94
+ @win.attroff Ncurses::A_BOLD
95
+ end
96
+
97
+ def caption(text, options = {})
98
+ return if text.empty?
99
+ font = options[:font] || 'mini'
100
+ text = figlet font, @cols, text
101
+ rows, cols = sizeof(text)
102
+ top = (@rows - rows - 2)/2
103
+ left = (@cols - cols)/2
104
+ @win.attron Ncurses::A_BOLD
105
+ text = text.split("\n").each_with_index do |line, i|
106
+ mvwprintw top + i, left, line
107
+ end
108
+ @win.attroff Ncurses::A_BOLD
109
+ @row = top + rows + 1
110
+ end
111
+
112
+ def line(text, options = {})
113
+ return @row += 1 if text.empty?
114
+ font = options[:font] || 'term'
115
+ @row = options[:row] if options[:row]
116
+ @row += options[:padding] if options[:padding]
117
+ text = figlet font, @cols, text
118
+ rows, cols = sizeof(text)
119
+ left = options[:left] || (@cols - cols)/2
120
+ left = @cols - cols - options[:right] if right = options[:right]
121
+ @win.attron Ncurses::A_BOLD if options[:bold]
122
+ text = text.split("\n").each_with_index do |line, i|
123
+ mvwprintw @row + i, left, line
124
+ end
125
+ @win.attroff Ncurses::A_BOLD if options[:bold]
126
+ @row += rows + options[:margin].to_i
127
+ end
128
+
129
+ def color(front, back = Ncurses::COLOR_BLACK)
130
+ if front =~ /^\d+$/
131
+ pair_id = front.to_i
132
+ elsif front.is_a?(String)
133
+ front = eval "Ncurses::COLOR_#{front.upcase}"
134
+ end
135
+ if back.is_a?(String)
136
+ back = eval "Ncurses::COLOR_#{back.upcase}"
137
+ end
138
+ pair_id ||= register_pair front, back
139
+ @win.color_set pair_id, nil
140
+ end
141
+
142
+ def wait(time)
143
+ if time == 0.0
144
+ case input = @status.getch
145
+ when ?j, 32, 10, 13, 27
146
+ else Ncurses.ungetch input
147
+ end
148
+ else
149
+ sleep time
150
+ end
151
+ end
152
+
153
+ def sizeof(text)
154
+ lines = text.split("\n")
155
+ cols = lines.map{|line| line.length}.max
156
+ [lines.size, cols]
157
+ end
158
+
159
+ def mb?(text)
160
+ text.split(//u).size != text.length
161
+ end
162
+
163
+ def paginate
164
+ @status.mvwprintw 0, 0, " " * @cols
165
+ pages = @pages.size
166
+ k = pages.to_s.length
167
+ j = 2 + k*2
168
+ @status.mvwprintw 0, 0, "%#{k}d/%#{k}d|" % [@page + 1, pages]
169
+ cols = @cols - 6 - j
170
+ q = cols % pages
171
+ r = q > 0 ? pages / q : 0
172
+ w = [cols / pages, 1].max
173
+ w += 1 if r > 0 && @page % r == r - 1
174
+ x = (@page*cols + pages/2) / pages
175
+ @status.mvwprintw 0, x + j, "*" * w
176
+ time = Time.now.to_i - @start.to_i
177
+ min, sec = time / 60, time % 60
178
+ @status.mvwprintw 0, cols + j, "|%02d:%02d" % [min, sec]
179
+ @status.refresh
180
+ end
181
+
182
+ def scan_command
183
+ @status.mvwprintw 0, 0, " "*@cols
184
+ @status.mvwprintw 0, 0, ':'
185
+ buf = []
186
+ begin
187
+ case input = @status.getch
188
+ when 10, 13; break
189
+ when 27; return nil
190
+ when 127; buf.pop
191
+ else buf << input
192
+ end
193
+ @status.mvwprintw 0, 1, " "*(@cols - 1)
194
+ @status.mvwprintw 0, 1, buf.pack('C*')
195
+ @status.refresh
196
+ end while input > 0
197
+ command, *args = buf.pack('C*').split(/\s+/)
198
+ command = "do_#{command}"
199
+ send command, *args rescue nil if respond_to? command
200
+ end
201
+
202
+ def register_pair(front, back)
203
+ key = [front, back]
204
+ return @colors[key] if @colors[key]
205
+ pair_id = @colors.size + 1
206
+ Ncurses.init_pair pair_id, front, back
207
+ @colors[key] = pair_id
208
+ end
209
+
210
+ def method_missing(method, *args, &block)
211
+ @win.send method, *args, &block
212
+ end
213
+
214
+ def do_go(page)
215
+ @page = [[0, page.to_i - 1].max, @pages.size - 1].min
216
+ end
217
+
218
+ def do_sh
219
+ Ncurses.endwin
220
+ system ENV['SHELL'] || 'sh'
221
+ Ncurses.resetty
222
+ end
223
+
224
+ def do_q
225
+ exit
226
+ end
227
+ end
@@ -0,0 +1,55 @@
1
+ class Present
2
+ class Page
3
+ def initialize(stanza, screen)
4
+ @lines = stanza.split("\n")
5
+ @screen = screen
6
+ end
7
+
8
+ def start
9
+ @screen.clear
10
+ stack = [['cap', '']]
11
+ execute_command = proc do
12
+ command, text = stack.pop
13
+ dispatch_command command, text
14
+ @screen.refresh
15
+ end
16
+ @lines.each do |line|
17
+ text, command = line.split(/\s+/, 2).reverse
18
+ if command
19
+ execute_command.call
20
+ stack.push [command, text]
21
+ else
22
+ stack.last[1] += "\n#{text}"
23
+ end
24
+ end
25
+ execute_command.call
26
+ end
27
+
28
+ private
29
+ def dispatch_command(command, text)
30
+ case command
31
+ when '='
32
+ @screen.caption text
33
+ when '-'
34
+ @screen.line text
35
+ when '<'
36
+ @screen.line text, :left => 1, :padding => 1
37
+ when '>'
38
+ @screen.line text, :right => 1, :padding => 1
39
+ when /(\++)(\-?)/
40
+ @screen.line '- ' + text, :left => $1.length*2 - 1,
41
+ :padding => $2.empty? ? 1 : 0
42
+ when '*'
43
+ @screen.line text, :row => 1, :bold => true
44
+ when '.'
45
+ @screen.center text.empty? ? "fin" : text, :font => 'mini'
46
+ when '#'
47
+ @screen.center text, :font => 'mini'
48
+ when '%'
49
+ @screen.color *text.split(/\s+/)
50
+ when ','
51
+ @screen.wait text.to_f
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ require "test/unit"
4
+ class PresentTest < Test::Unit::TestCase
5
+ def test_run
6
+ bin = File.join(File.dirname(__FILE__), '..', 'bin', 'present')
7
+ assert system("#{bin} 2>&1 > /dev/null")
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../lib/present'
3
+ require 'rubygems'
4
+ require 'redgreen'
5
+
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: genki-present
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Genki Takiuchi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-08-31 00:00:00 -07:00
13
+ default_executable: present
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: ncurses
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: text
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: "0"
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: escape
35
+ version_requirement:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: "0"
41
+ version:
42
+ description: Presentation tool for terminal.
43
+ email: genki@s21g.com
44
+ executables:
45
+ - present
46
+ extensions: []
47
+
48
+ extra_rdoc_files:
49
+ - README
50
+ - ChangeLog
51
+ files:
52
+ - README
53
+ - ChangeLog
54
+ - Rakefile
55
+ - bin/present
56
+ - test/test_helper.rb
57
+ - test/present_test.rb
58
+ - lib/present
59
+ - lib/present/page.rb
60
+ - lib/present.rb
61
+ has_rdoc: true
62
+ homepage: http://cocktail-party.rubyforge.org
63
+ post_install_message:
64
+ rdoc_options:
65
+ - --title
66
+ - present documentation
67
+ - --charset
68
+ - utf-8
69
+ - --opname
70
+ - index.html
71
+ - --line-numbers
72
+ - --main
73
+ - README
74
+ - --inline-source
75
+ - --exclude
76
+ - ^(examples|extras)/
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ version:
91
+ requirements: []
92
+
93
+ rubyforge_project: cocktail-party
94
+ rubygems_version: 1.2.0
95
+ signing_key:
96
+ specification_version: 2
97
+ summary: Presentation tool for terminal.
98
+ test_files:
99
+ - test/present_test.rb