ohboyohboyohboy-monocle-print 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ module MonoclePrint
5
+ class Table
6
+ class Column
7
+ include MonoclePrint
8
+
9
+ def initialize( table, index )
10
+ @table = table
11
+ @index = index
12
+ @wrap = false
13
+ @flow = false
14
+ @alignment = :left
15
+ @fixed_width = nil
16
+ @cached_width = nil
17
+ end
18
+
19
+ attr_reader :table, :index
20
+ attr_accessor :alignment
21
+
22
+ for m in %w( wrap flow )
23
+ attr_accessor( m )
24
+ alias_method( "#{m}?", m )
25
+ undef_method( m )
26
+ end
27
+
28
+ def malleable?
29
+ @wrap and @flow
30
+ end
31
+
32
+ def malleable=( bool )
33
+ @wrap = @flow = bool
34
+ end
35
+
36
+ def fixed?
37
+ not malleable?
38
+ end
39
+
40
+ def fixed=( bool )
41
+ self.malleable = !bool
42
+ end
43
+
44
+ def title
45
+ @table.titles[ @index ]
46
+ end
47
+
48
+ def cells
49
+ @table.grep( Row ) { | row | row[ @index ] || Line( '' ) }
50
+ end
51
+
52
+ def previous_column
53
+ @index.zero? ? nil : @table.columns[ @index - 1 ]
54
+ end
55
+
56
+ def next_column
57
+ @table.columns[ @index + 1 ]
58
+ end
59
+
60
+ def first?
61
+ @index.zero?
62
+ end
63
+
64
+ def last?
65
+ @index == (table.columns.length - 1)
66
+ end
67
+
68
+ def prepare( cell_text )
69
+ cell_text = cell_text ? cell_text.dup : Text( ' ' )
70
+ @flow and cell_text.reflow!( false )
71
+ @wrap and cell_text = cell_text.wrap( width - 1 )
72
+ cell_text.align!( @alignment, width )
73
+ end
74
+
75
+ def width=( w )
76
+ @fixed_width = Utils.at_least( w.to_i, 1 )
77
+ end
78
+
79
+ def width
80
+ @fixed_width or @cached_width or calculate_width
81
+ end
82
+
83
+ def calculate_metrics
84
+ @cached_width = @fixed_width || calculate_width
85
+ end
86
+
87
+ def clear_metrics
88
+ @cached_width = nil
89
+ end
90
+
91
+ protected
92
+
93
+ def calculate_width
94
+ @table.grep( Row ) { |r| c = r[ @index ] and c.width or 0 }.max || 0
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,252 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ module MonoclePrint
5
+ class Table
6
+ class Member
7
+ include MonoclePrint
8
+ include Enumerable
9
+
10
+ class << self
11
+ attr_reader :member_name
12
+ def define( member_name, sup = self, &body )
13
+ klass =
14
+ Class.new( sup ) do
15
+ @member_name = member_name
16
+ class_eval( &body )
17
+ end
18
+
19
+ define_method( "#{ member_name }!" ) do |*args|
20
+ klass.new( @table, *args ) { |m| link( m ) }.tail
21
+ end
22
+ return( klass )
23
+ end
24
+ end
25
+
26
+ attr_reader :table
27
+ attr_accessor :before, :after
28
+ protected :before=, :after=
29
+
30
+ def initialize( table, *args )
31
+ @table = table
32
+ @before = nil
33
+ @after = nil
34
+ @disabled = false
35
+ block_given? and yield( self )
36
+ initialize!( *args )
37
+ end
38
+
39
+ def initialize!( * )
40
+ # do nothing
41
+ end
42
+
43
+ def inspect( *args )
44
+ content = args.map! { |a| a.inspect }.join(', ')
45
+ "#{self.class.member_name}(#{content})"
46
+ end
47
+
48
+ def each
49
+ block_given? or return( enum_for( __method__ ) )
50
+ node = self
51
+ begin
52
+ yield( node )
53
+ node = node.after
54
+ end while( node )
55
+ end
56
+
57
+ def disable
58
+ @disabled = true
59
+ end
60
+
61
+ def enable
62
+ @disabled = false
63
+ end
64
+
65
+ def enabled?
66
+ not disabled?
67
+ end
68
+
69
+ def disabled?
70
+ @disabled
71
+ end
72
+
73
+ def first?
74
+ @before.nil?
75
+ end
76
+
77
+ def last?
78
+ @after.nil?
79
+ end
80
+
81
+ def link( item )
82
+ after, @after, item.before = @after, item, self
83
+ after ? item.link( after ) : item
84
+ end
85
+
86
+ def unlink
87
+ @before and @before.after = nil
88
+ @before = nil
89
+ return( self )
90
+ end
91
+
92
+ def render( out, style )
93
+ render!( out, style ) unless disabled?
94
+ end
95
+
96
+ def columns
97
+ table.columns
98
+ end
99
+
100
+ def tail
101
+ @after ? @after.tail : self
102
+ end
103
+ end
104
+
105
+ Blank =
106
+ Member.define( 'blank' ) do
107
+ def render!( * )
108
+ end
109
+ end
110
+
111
+ Row =
112
+ Member.define( 'row' ) do
113
+ def initialize!( *content )
114
+ @cells = [ content ].flatten!.map! { | c | Text( c ) }
115
+ @table.expand_columns( @cells.length )
116
+ end
117
+
118
+ def []( index )
119
+ @cells[ index ]
120
+ end
121
+
122
+ def []=(index, value)
123
+ @cells[ index ] = value
124
+ end
125
+
126
+ def cells
127
+ @table.columns.zip( @cells ).
128
+ map! { | col, cell | col.prepare( cell ) }
129
+ end
130
+
131
+ def height
132
+ cells.map! { | c | c.height }.max
133
+ end
134
+
135
+ def render!( out, style )
136
+ cells =
137
+ @table.columns.zip( @cells ).map! do | col, cell |
138
+ col.prepare( cell )
139
+ end
140
+
141
+ height = cells.map { | col, cell | cell ? cell.height : 1 }.max
142
+
143
+ joint = style.format( ' <v> ' )
144
+ left = style.format( '<v> ' )
145
+ right = style.format( ' <v>' )
146
+
147
+ result = cells.inject { | result, cell | result.juxtapose( cell, joint ) }
148
+ result.each do | line |
149
+ out.put!( left + line + right )
150
+ end
151
+ return( out )
152
+ end
153
+
154
+ def inspect
155
+ super( *cells )
156
+ end
157
+
158
+ private
159
+
160
+ def prepare
161
+ height = cells.map { | c | c.height }.max
162
+ if height > 1
163
+ cell_lines.zip( @table.columns ) do | lines, col |
164
+ if lines.length < height
165
+ blank = col.fill_text( ' ' )
166
+ lines.fill( blank, lines.length, height - lines.length )
167
+ end
168
+ end
169
+ end
170
+ return( cell_lines )
171
+ end
172
+
173
+ def pad
174
+ n = @table.columns.length
175
+ m = @cells.length
176
+ @cells.fill( Text(' '), m, n - m ) if n > m
177
+ end
178
+ end
179
+
180
+ TitleRow =
181
+ Member.define( 'title_row', Row ) do
182
+ def initialize!( *content )
183
+ super
184
+ divider!( :title )
185
+ end
186
+ end
187
+
188
+ Divider =
189
+ Member.define( 'divider' ) do
190
+ attr_accessor :type
191
+
192
+ def initialize!( type )
193
+ @type = type.to_sym
194
+ end
195
+
196
+ def render( out, style )
197
+ super( out, style ) unless @after.is_a?( Divider )
198
+ end
199
+
200
+ def inspect( *args )
201
+ super( @type, *args )
202
+ end
203
+
204
+ def render!( out, style )
205
+ fills = @table.columns.map { | c | "<h:#{ c.width + 2 }>" }
206
+ template =
207
+ case @type
208
+ when :row, :title
209
+ '<nse>' << fills.join( '<hv>' ) << '<nsw>'
210
+ when :section_open
211
+ '<nse>' << fills.join( '<hs>' ) << '<nsw>'
212
+ when :section_close
213
+ '<nse>' << fills.join( '<hn>' ) << '<nsw>'
214
+ when :head
215
+ '<se>' << fills.join( '<hs>' ) << '<sw>'
216
+ when :foot
217
+ '<ne>' << fills.join( '<hn>' ) << '<nw>'
218
+ end
219
+ out.puts( style.format( template ) )
220
+ end
221
+ end
222
+
223
+ SectionTitle =
224
+ Member.define( 'section' ) do
225
+ attr_accessor :title, :alignment
226
+
227
+ def initialize!( title, options = {} )
228
+ @title = Text( title )
229
+ @alignment = options.fetch( :align, :left )
230
+ @before.divider!( :section_close )
231
+ divider!( :section_open )
232
+ end
233
+
234
+ def inspect
235
+ super( @title, @alignment )
236
+ end
237
+
238
+ def render!( out, style )
239
+ w = @table.inner_width
240
+ title = @title.width > w ? @title.wrap( w ) : @title
241
+ left = style.format( '<v> ' )
242
+ right = style.format( ' <v>' )
243
+
244
+ for line in title.align( @alignment, w )
245
+ out.puts( left + line + right )
246
+ end
247
+ end
248
+
249
+ end
250
+
251
+ end
252
+ end
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ module MonoclePrint
5
+ class Table
6
+
7
+ Segments = Struct.new(
8
+ :head, :title_row, :title_divider, :row, :row_divider,
9
+ :section, :section_close, :section_open, :foot
10
+ )
11
+
12
+ class Segments
13
+ include MonoclePrint
14
+
15
+ def self.default_filling( style )
16
+ fill = style.new.dup
17
+ new( fill, nil, fill, nil, fill, nil, fill, fill, fill )
18
+ end
19
+
20
+ def self.default_joints( style )
21
+ head = style.format( "<h><hd><h>" )
22
+ row = style.format( " <v> " )
23
+ div = style.format( "<h><hv><h>" )
24
+ foot = style.format( "<h><hu><h>" )
25
+
26
+ new( head, row, div, row, div, nil, foot, head, foot )
27
+ end
28
+
29
+ def self.default_left_edge( style )
30
+ head = style.format( "<dr><h>" )
31
+ row = style.format( "<v> " )
32
+ div = style.format( "<vr><h>" )
33
+ foot = style.format( "<ur><h>" )
34
+ new( head, row, div, row, div, row, div, div, foot )
35
+ end
36
+
37
+ def self.default_right_edge( style )
38
+ head = style.format( "<h><dl>" )
39
+ row = style.format( " <v>" )
40
+ div = style.format( "<h><vl>" )
41
+ foot = style.format( "<h><ul>" )
42
+ new( head, row, div, row, div, row, div, div, foot )
43
+ end
44
+
45
+ def mask( inclusion_settings )
46
+ masked = self.class.new
47
+ each_pair do | name, text |
48
+ if text and inclusion_settings[ name ]
49
+ masked[ name ] = text
50
+ end
51
+ end
52
+ return( masked )
53
+ end
54
+
55
+ def width( inclusion_mask = nil )
56
+ inclusion_mask and return( self.mask( inclusion_mask ).width )
57
+ return( map { |text| text ? text.width : 0 }.max )
58
+ end
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,205 @@
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
+ ANSI_COLOR_NAMES = ANSI_COLORS.keys.freeze
15
+
16
+ ANSI_MODIFIERS =
17
+ {
18
+ :bold => 1,
19
+ :underline => 4,
20
+ :blink => 5,
21
+ :reverse => 7,
22
+ :conceal => 8
23
+ }
24
+ ANSI_MODIFIER_NAMES = ANSI_MODIFIERS.keys.freeze
25
+
26
+ module_function
27
+
28
+ #def term_info
29
+ # @term_info ||= TermInfo.new
30
+ #end
31
+
32
+ def ansi_color( type, color, bold = nil )
33
+ offset =
34
+ case type
35
+ when ?f then 30 # foreground
36
+ when ?b then 40 # background
37
+ end
38
+ code = offset + ANSI_COLORS.fetch( color.to_sym ) do
39
+ raise( ArgumentError, "unknown color name `%s'" % color )
40
+ end
41
+ "\e[#{ '1;' if bold }#{ code }m"
42
+ end
43
+
44
+ def xterm_color( type, color_index, bold = nil )
45
+ prefix =
46
+ case type
47
+ when ?f then 38 # foreground
48
+ when ?b then 48 # background
49
+ end
50
+ "\e[#{ prefix };5;#{ color_index }m"
51
+ end
52
+
53
+ def konsole_color( type, r, g, b, bold = nil)
54
+ prefix =
55
+ case type
56
+ when ?f then 38 # foreground
57
+ when ?b then 48 # background
58
+ end
59
+ "\e[#{ prefix };2;#{ r };#{ g };#{ b }m"
60
+ end
61
+
62
+ def ansi_modifier( name )
63
+ code =
64
+ ANSI_MODIFIERS.fetch( name.to_sym ) do
65
+ fail ArgumentError, "unknown modifier name `%s'" % name
66
+ end
67
+ "\e[#{ code }m"
68
+ end
69
+
70
+ def clear_attr
71
+ "\e[0m"
72
+ end
73
+
74
+ def bold
75
+ "\e[1m"
76
+ end
77
+
78
+ def underline
79
+ "\e[4m"
80
+ end
81
+
82
+ def blink
83
+ "\e[5m"
84
+ end
85
+
86
+ def reverse
87
+ "\e[7m"
88
+ end
89
+
90
+ def conceal
91
+ "\e[8m"
92
+ end
93
+
94
+ def set_cursor( line = 0, column = 0 )
95
+ "\e[%i;%iH" % [ line, column ]
96
+ end
97
+
98
+ def cursor_up( lines = 1 )
99
+ "\e[%iA" % lines
100
+ end
101
+
102
+ def cursor_down( lines = 1 )
103
+ "\e[%iB" % lines
104
+ end
105
+
106
+ def cursor_forward( columns = 1 )
107
+ "\e[%iC" % columns
108
+ end
109
+
110
+ def cursor_backward( columns = 1 )
111
+ "\e[%iD" % columns
112
+ end
113
+
114
+ def save_cursor
115
+ "\e[s"
116
+ end
117
+
118
+ def restore_cursor
119
+ "\e[u"
120
+ end
121
+
122
+ #def clear_line
123
+ # "\e[K"
124
+ #end
125
+
126
+ # VT100 escapes
127
+ def double_height_top
128
+ "\e#3"
129
+ end
130
+
131
+ def dobule_height_bottom
132
+ "\e#4"
133
+ end
134
+
135
+ def single_width
136
+ "\e#5"
137
+ end
138
+
139
+ def double_width
140
+ "\e#6"
141
+ end
142
+
143
+ def clear_right
144
+ "\e[0K"
145
+ end
146
+
147
+ def clear_left
148
+ "\e[1K"
149
+ end
150
+
151
+ def clear_line
152
+ "\e[2K"
153
+ end
154
+
155
+ def clear_down
156
+ "\e[0J"
157
+ end
158
+
159
+ def clear_up
160
+ "\e[1J"
161
+ end
162
+
163
+ def clear_screen
164
+ "\e[2J"
165
+ end
166
+
167
+ end
168
+ end
169
+
170
+ if __FILE__ == $0
171
+
172
+ TE = MonoclePrint::TerminalEscapes
173
+ for attr in %w[ bold underline blink reverse conceal ]
174
+ print( "This should be #{ attr }:".ljust( 30 ) )
175
+ printf( "%swhateva\e[0m\n", TE.send( attr ) )
176
+ end
177
+
178
+ colors = TE::ANSI_COLORS.keys.map(&:to_s).sort!
179
+ for color in colors
180
+ print( "This should be #{ color }:".ljust( 30 ) )
181
+ printf( "%swhateva\e[0m\t", TE.ansi_color( ?f, color ) )
182
+ printf( "%swhateva\e[0m\t", TE.ansi_color( ?b, color ) )
183
+ printf( "%sbright_whateva\e[0m\n", TE.ansi_color( ?f, color, true ) )
184
+ end
185
+
186
+ for dir in %w( left right line )
187
+ name = "clear_#{ dir }"
188
+ code = TE.send( name )
189
+ puts
190
+ puts("[ Clear Code: #{ name } ]")
191
+ puts
192
+ puts("at start")
193
+ printf("%s<= %-14s\n", code, name)
194
+ puts("in middle")
195
+ printf("%-14s =>%s<= %-14s\n", name, code, name)
196
+ puts("at end")
197
+ printf("%-14s =>%s\n", name, code, name)
198
+ end
199
+
200
+ puts( "[ Tabs ]" )
201
+ puts( " \eHx \eHx \eHx ")
202
+ puts( "one\ttwo\tthree\tfour" )
203
+ puts( "\e[3g" )
204
+ puts( "one\ttwo\tthree\tfour" )
205
+ end