monocle-print 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,229 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'monocle-print/table/segments'
4
+ require 'monocle-print/table/members'
5
+ require 'monocle-print/table/column'
6
+
7
+ module MonoclePrint
8
+ class Table
9
+ include MonoclePrint
10
+ include Presentation
11
+ include Enumerable
12
+
13
+ def self.build( *args )
14
+ table = new( *args ) do | table |
15
+ block_given? and yield( table )
16
+ end
17
+ return( table.render )
18
+ end
19
+
20
+
21
+ def initialize( columns, options = {} )
22
+ initialize_view( options )
23
+
24
+ @titles = nil
25
+ @item = @head = Divider.new( self, :head )
26
+ @foot = Divider.new( self, :foot )
27
+ @columns = []
28
+ @body = []
29
+
30
+ case columns
31
+ when Fixnum
32
+ expand_columns( columns )
33
+ when Array
34
+ title_row( *columns )
35
+ end
36
+
37
+ block_given? and yield( self )
38
+ end
39
+
40
+ def render_content( out )
41
+ style = @style || out.style
42
+ lock do
43
+ width > out.width and resize( out.width )
44
+ each { | member | member.render( out, style ) }
45
+ end
46
+ end
47
+
48
+ def each
49
+ block_given? or return( enum_for( :each ) )
50
+ for item in @head
51
+ yield( item )
52
+ end
53
+ end
54
+
55
+ attr_reader :columns, :titles
56
+
57
+ def row( *members )
58
+ @item = @item.row!( *members )
59
+ end
60
+
61
+ def title_row( *members )
62
+ @titles = @item = @item.title_row!( *members )
63
+ while @titles
64
+ if TitleRow === @titles
65
+ @titles = @titles.cells.map { | c | c.to_s }
66
+ break
67
+ end
68
+ @titles = @titles.before
69
+ end
70
+ self
71
+ end
72
+
73
+ def rows( *list_of_rows )
74
+ for row in list_of_rows do row( *row ) end
75
+ self
76
+ end
77
+
78
+ def section( title, options = {} )
79
+ @item = @item.section!( title, options )
80
+ end
81
+
82
+ def divider( type = :row_divider )
83
+ @item = @item.divider!( type )
84
+ end
85
+
86
+ def fixed_columns( *column_indicies )
87
+ for column_index in column_indicies
88
+ if c = column( column_indicies )
89
+ if Array === c then c.each { | i | i.fixed = true }
90
+ else c.fixed = true
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ def malleable_columns( *column_indicies )
97
+ for column_index in column_indicies
98
+ if c = column( column_index )
99
+ if Array === c then c.each { | i | i.malleable = true }
100
+ else c.malleable = true
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ def column( name_or_index )
107
+ case name_or_index
108
+ when Integer, Range then @columns[ name_or_index ]
109
+ else
110
+ @columns.find do | col |
111
+ name_or_index === col.title
112
+ end
113
+ end
114
+ end
115
+
116
+ def resize( new_size )
117
+ resizable = @columns.select { | c | c.malleable? }
118
+ if resizable.empty?
119
+ warn( "cannot resize #{ self.inspect } as all columns are fixed" )
120
+ return( self )
121
+ end
122
+
123
+ lock do
124
+ difference = new_size - @width
125
+ resize_columns( difference, resizable )
126
+ end
127
+
128
+ return( self )
129
+ end
130
+
131
+
132
+
133
+ def inner_width
134
+ @inner_width or calculate_inner_width
135
+ end
136
+
137
+ def width
138
+ @width or calculate_width
139
+ end
140
+
141
+ def expand_columns(new_size)
142
+ new_size.zero? and return
143
+
144
+ until @columns.length >= new_size
145
+ @columns << Column.new( self, @columns.length )
146
+ end
147
+ end
148
+
149
+ private
150
+
151
+ def resize_columns( amount, columns )
152
+ leftover = amount
153
+ resizable_area = columns.inject( 0 ) do | sz, c |
154
+ sz + c.width
155
+ end
156
+
157
+ for column in columns
158
+ proportion = ( column.width.to_f / resizable_area )
159
+ delta = ( proportion * amount ).round
160
+ column.width += delta
161
+ leftover -= delta
162
+ end
163
+
164
+ columns.last.width += leftover
165
+ end
166
+
167
+ def expand( amount, columns )
168
+ leftover = amount
169
+ resizable_area = columns.inject( 0 ) do | sz, c |
170
+ sz + c.width
171
+ end
172
+
173
+ for column in columns
174
+ proportion = ( column.width.to_f / resizable_area )
175
+ delta = ( proportion * amount ).round
176
+ column.width += delta
177
+ leftover -= delta
178
+ end
179
+
180
+ columns.last.width += leftover
181
+ end
182
+
183
+
184
+
185
+ def lock
186
+ calculate_metrics
187
+ @item.link( @foot )
188
+ yield
189
+ ensure
190
+ @foot.unlink
191
+ clear_metrics
192
+ end
193
+
194
+ def calculate_metrics
195
+ @columns.each { | c | c.calculate_metrics }
196
+ @inner_width = calculate_inner_width
197
+ @width = calculate_width
198
+ end
199
+
200
+ def clear_metrics
201
+ @columns.each { | c | c.clear_metrics }
202
+ @inner_width = nil
203
+ @width = nil
204
+ end
205
+
206
+ def calculate_inner_width
207
+ w = @columns.inject( 0 ) { | w, c | w + c.width }
208
+ w + ( @columns.length - 1 ) * 3
209
+ end
210
+
211
+ def calculate_width
212
+ calculate_inner_width + 4
213
+ end
214
+
215
+ end
216
+
217
+ class ColumnLayout < Table
218
+ def initialize( columns, options = {} )
219
+ super( columns, options ) do
220
+ @item = @head = Blank.new( self )
221
+ @foot = Blank.new( self )
222
+ @style = Style( :blank )
223
+ block_given? and yield( self )
224
+ end
225
+ end
226
+ end
227
+
228
+ end
229
+
@@ -0,0 +1,186 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ #require 'termios'
5
+ #require 'terminfo'
6
+
7
+ module MonoclePrint
8
+ module TerminalEscapes
9
+ ANSI_COLORS = {
10
+ :blue => 4, :white => 7, :magenta => 5,
11
+ :yellow => 3, :green => 2, :black => 0,
12
+ :red => 1, :cyan => 6
13
+ }
14
+
15
+ module_function
16
+
17
+ #def term_info
18
+ # @term_info ||= TermInfo.new
19
+ #end
20
+
21
+ def ansi_color( type, color, bold = nil )
22
+ offset =
23
+ case type
24
+ when ?f then 30 # foreground
25
+ when ?b then 40 # background
26
+ end
27
+ code = offset + ANSI_COLORS.fetch( color.to_sym ) do
28
+ raise( ArgumentError, "unknown color name `%s'" % color )
29
+ end
30
+ "\e[#{ '1;' if bold }#{ code }m"
31
+ end
32
+
33
+ def xterm_color( type, color_index, bold = nil )
34
+ prefix =
35
+ case type
36
+ when ?f then 38 # foreground
37
+ when ?b then 48 # background
38
+ end
39
+ "\e[#{ prefix };5;#{ color_index }m"
40
+ end
41
+
42
+ def konsole_color( type, r, g, b, bold = nil)
43
+ prefix =
44
+ case type
45
+ when ?f then 38 # foreground
46
+ when ?b then 48 # background
47
+ end
48
+ "\e[#{ prefix };2;#{ r };#{ g };#{ b }m"
49
+ end
50
+
51
+ def clear_attr
52
+ "\e[0m"
53
+ end
54
+
55
+ def bold
56
+ "\e[1m"
57
+ end
58
+
59
+ def underline
60
+ "\e[4m"
61
+ end
62
+
63
+ def blink
64
+ "\e[5m"
65
+ end
66
+
67
+ def reverse
68
+ "\e[7m"
69
+ end
70
+
71
+ def conceal
72
+ "\e[8m"
73
+ end
74
+
75
+ def set_cursor( line = 0, column = 0 )
76
+ "\e[%i;%iH" % [ line, column ]
77
+ end
78
+
79
+ def cursor_up( lines = 1 )
80
+ "\e[%iA" % lines
81
+ end
82
+
83
+ def cursor_down( lines = 1 )
84
+ "\e[%iB" % lines
85
+ end
86
+
87
+ def cursor_forward( columns = 1 )
88
+ "\e[%iC" % columns
89
+ end
90
+
91
+ def cursor_backward( columns = 1 )
92
+ "\e[%iD" % columns
93
+ end
94
+
95
+ def save_cursor
96
+ "\e[s"
97
+ end
98
+
99
+ def restore_cursor
100
+ "\e[u"
101
+ end
102
+
103
+ #def clear_line
104
+ # "\e[K"
105
+ #end
106
+
107
+ # VT100 escapes
108
+ def double_height_top
109
+ "\e#3"
110
+ end
111
+
112
+ def dobule_height_bottom
113
+ "\e#4"
114
+ end
115
+
116
+ def single_width
117
+ "\e#5"
118
+ end
119
+
120
+ def double_width
121
+ "\e#6"
122
+ end
123
+
124
+ def clear_right
125
+ "\e[0K"
126
+ end
127
+
128
+ def clear_left
129
+ "\e[1K"
130
+ end
131
+
132
+ def clear_line
133
+ "\e[2K"
134
+ end
135
+
136
+ def clear_down
137
+ "\e[0J"
138
+ end
139
+
140
+ def clear_up
141
+ "\e[1J"
142
+ end
143
+
144
+ def clear_screen
145
+ "\e[2J"
146
+ end
147
+
148
+ end
149
+ end
150
+
151
+ if __FILE__ == $0
152
+
153
+ TE = MonoclePrint::TerminalEscapes
154
+ for attr in %w[ bold underline blink reverse conceal ]
155
+ print( "This should be #{ attr }:".ljust( 30 ) )
156
+ printf( "%swhateva\e[0m\n", TE.send( attr ) )
157
+ end
158
+
159
+ colors = TE::ANSI_COLORS.keys.map(&:to_s).sort!
160
+ for color in colors
161
+ print( "This should be #{ color }:".ljust( 30 ) )
162
+ printf( "%swhateva\e[0m\t", TE.ansi_color( ?f, color ) )
163
+ printf( "%swhateva\e[0m\t", TE.ansi_color( ?b, color ) )
164
+ printf( "%sbright_whateva\e[0m\n", TE.ansi_color( ?f, color, true ) )
165
+ end
166
+
167
+ for dir in %w( left right line )
168
+ name = "clear_#{ dir }"
169
+ code = TE.send( name )
170
+ puts
171
+ puts("[ Clear Code: #{ name } ]")
172
+ puts
173
+ puts("at start")
174
+ printf("%s<= %-14s\n", code, name)
175
+ puts("in middle")
176
+ printf("%-14s =>%s<= %-14s\n", name, code, name)
177
+ puts("at end")
178
+ printf("%-14s =>%s\n", name, code, name)
179
+ end
180
+
181
+ puts( "[ Tabs ]" )
182
+ puts( " \eHx \eHx \eHx ")
183
+ puts( "one\ttwo\tthree\tfour" )
184
+ puts( "\e[3g" )
185
+ puts( "one\ttwo\tthree\tfour" )
186
+ end
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ module MonoclePrint
5
+ module Utils
6
+ module_function
7
+
8
+ def at_least( comparable, min )
9
+ ( comparable >= min ) ? comparable : min
10
+ end
11
+
12
+ def at_most( comparable, max )
13
+ ( comparable <= max ) ? comparable : max
14
+ end
15
+
16
+ def bound( comparable, lower, upper = nil )
17
+ return lower if comparable < lower
18
+ return comparable unless upper
19
+ return upper if comparable > upper
20
+ return comparable
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ module MonoclePrint
5
+ VERSION = '1.0.0'
6
+
7
+ def self.version
8
+ VERSION
9
+ end
10
+
11
+ def self.included( kl )
12
+ super
13
+ kl.extend( self )
14
+ end
15
+
16
+ def self.library_path( *args )
17
+ File.join( File.dirname( __FILE__ ), *args )
18
+ end
19
+
20
+ def self.stdout
21
+ Output( $stdout )
22
+ end
23
+
24
+ module_function
25
+
26
+ def Line( obj )
27
+ SingleLine === obj ? obj : SingleLine.new( obj.to_s )
28
+ end
29
+
30
+ def Output( dev )
31
+ OutputDevice === dev ? dev : OutputDevice.new( dev )
32
+ end
33
+
34
+ def Text( obj )
35
+ case obj
36
+ when Text then obj
37
+ when nil then Text.new( '' )
38
+ else Text.new( obj.to_s )
39
+ end
40
+ end
41
+
42
+ def Style( obj )
43
+ Graphics === obj ? obj : Graphics::NAMED_STYLES[ obj.to_s ]
44
+ end
45
+
46
+ def Rectangle( obj )
47
+ case obj
48
+ when Rectangle then obj
49
+ when Array then Rectangle.new( *obj )
50
+ when Hash then Rectangle.create( obj )
51
+ else Rectangle.new( obj )
52
+ end
53
+ end
54
+
55
+ end
56
+
57
+ $LOAD_PATH.unshift( MonoclePrint.library_path )
58
+
59
+ %w(
60
+ utils
61
+ geometry
62
+ presentation
63
+ terminal-escapes
64
+ atomic
65
+ graphics
66
+ output-device
67
+ progress
68
+ table
69
+ list
70
+ ).each { | lib | require "monocle-print/#{ lib }" }
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: monocle-print
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - monocle-print
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rdoc
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: hoe
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '3.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '3.7'
41
+ description: Fancy console output tools
42
+ email:
43
+ - kyle@ohboyohboyohboy.org
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files:
47
+ - History.txt
48
+ - Manifest.txt
49
+ - README.txt
50
+ files:
51
+ - lib/monocle-print.rb
52
+ - lib/monocle-print/layout.rb
53
+ - lib/monocle-print/table/segments.rb
54
+ - lib/monocle-print/table/members.rb
55
+ - lib/monocle-print/table/column.rb
56
+ - lib/monocle-print/output-device.rb
57
+ - lib/monocle-print/graphics.rb
58
+ - lib/monocle-print/table.rb
59
+ - lib/monocle-print/list.rb
60
+ - lib/monocle-print/progress.rb
61
+ - lib/monocle-print/presentation.rb
62
+ - lib/monocle-print/utils.rb
63
+ - lib/monocle-print/terminal-escapes.rb
64
+ - lib/monocle-print/geometry.rb
65
+ - lib/monocle-print/atomic.rb
66
+ - History.txt
67
+ - Manifest.txt
68
+ - README.txt
69
+ - Rakefile
70
+ - .gemtest
71
+ homepage: http://ohboyohboyohboy.org
72
+ licenses:
73
+ - MIT
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options:
77
+ - --main
78
+ - README.txt
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ! '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubyforge_project: monocle-print
93
+ rubygems_version: 2.0.3
94
+ signing_key:
95
+ specification_version: 4
96
+ summary: Fancy console output tools
97
+ test_files: []