monocle-print 1.0.0

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.
@@ -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: []