class MonoclePrint::OutputDevice

Constants

DEFAULT_SIZE
IO_PRINT_METHODS
SIZE_IOCTL
SIZE_STRUCT

Attributes

device[R]
style[RW]

Public Class Methods

buffer( options = {} ) { |out| ... } click to toggle source
# File lib/monocle-print/output-device.rb, line 16
def self.buffer( options = {} )
  case options
  when Numeric then options = { :width => options }
  when nil then options = {}
  end

  buffer = StringIO.new( '', options.fetch( :mode, 'w' ) )
  out = new( buffer, options )
  if block_given?
    begin
      yield( out )
      return( out.string )
    ensure
      out.close
    end
  else
    return out
  end
end
new( output, options = {} ) click to toggle source
Calls superclass method
# File lib/monocle-print/output-device.rb, line 55
def initialize( output, options = {} )
  @device =
    case output
    when String then File.open( output, options.fetch( :mode, 'w' ) )
    when IO then output
    else
      if IO_PRINT_METHODS.all? { | m | output.respond_to?( m ) }
        output
      else
        msg = "%s requires an IO-like object, but was given: %p" % [ self.class, output ]
        raise( ArgumentError, msg )
      end
    end

  super( @device )

  @background_stack = []
  @foreground_stack = []
  @modifier_stack   = []

  @background       = @foreground = @modifier = nil
  @use_color        = options.fetch( :use_color, tty? )

  @cursor           = Pair.new( 0, 0 )
  @tab_width        = options.fetch( :tab_width, 8 )
  @margin           = Pair.new( 0, 0 )

  @newline          = options.fetch( :newline, $/ )

  case margin = options.fetch( :margin, 0 )
  when Numeric then @margin.left = @margin.right = margin.to_i
  else
    @margin.left = margin[ :left ].to_i
    @margin.right = margin[ :right ].to_i
  end

  @tabs          = {}
  @screen_size   = nil
  @forced_width  = options[ :width ]
  @forced_height = options[ :height ]
  @alignment     = options.fetch( :alignment, :left )
  @style         = Style( options[ :style ] )
end
open( path, options = {} ) { |new( file, options )| ... } click to toggle source
# File lib/monocle-print/output-device.rb, line 10
def self.open( path, options = {} )
  File.open( path, options.fetch( :mode, 'w' ) ) do | file |
    return( yield( new( file, options ) ) )
  end
end
stderr( options = {} ) { |device| ... } click to toggle source
# File lib/monocle-print/output-device.rb, line 41
def self.stderr( options = {} )
  device = new( $stderr, options )
  block_given? ? yield( device ) : device
end
stdout( options = {} ) { |device| ... } click to toggle source
# File lib/monocle-print/output-device.rb, line 36
def self.stdout( options = {} )
  device = new( $stdout, options )
  block_given? ? yield( device ) : device
end

Public Instance Methods

background( color = nil ) { || ... } click to toggle source
# File lib/monocle-print/output-device.rb, line 113
def background( color = nil )
  color or return( @background_stack.last )
  begin
    @background_stack.push( color )
    yield
  ensure
    @background_stack.pop
  end
end
Also aliased as: on
clear() click to toggle source
# File lib/monocle-print/output-device.rb, line 387
def clear
  @cursor.line = @cursor.column = 0
  @device.print( set_cursor( 0, 0 ), clear_screen )
  @device.flush
  return( self )
end
clear_line() click to toggle source
# File lib/monocle-print/output-device.rb, line 394
def clear_line
  @device.print( super )
  @device.flush
  return!
end
close() click to toggle source
# File lib/monocle-print/output-device.rb, line 295
def close
  @device.close rescue nil
end
color_code() click to toggle source
# File lib/monocle-print/output-device.rb, line 409
def color_code
  @use_color or return ''
  code = ''

  case fg = @foreground_stack.last
  when Fixnum then code << xterm_color( ?f, fg )
  when String, Symbol then code << ansi_color( ?f, fg )
  end

  case bg = @background_stack.last
  when Fixnum then code << xterm_color( ?b, bg )
  when String, Symbol then code << ansi_color( ?b, bg )
  end

  case mod = @modifier_stack.last
  when String, Symbol then code << ansi_modifier( mod )
  end

  code
end
colors( fg, bg ) { || ... } click to toggle source
# File lib/monocle-print/output-device.rb, line 109
def colors( fg, bg )
  foreground( fg ) { background( bg ) { yield } }
end
column() click to toggle source
# File lib/monocle-print/output-device.rb, line 379
def column
  @cursor.column
end
column_layout( *args ) { |t| ... } click to toggle source
# File lib/monocle-print/output-device.rb, line 238
def column_layout( *args )
  ColumnLayout.new( *args ) do | t |
    block_given? and yield( t )
    t.render( self )
  end
end
fill( width, char = ' ' ) click to toggle source
# File lib/monocle-print/output-device.rb, line 343
def fill( width, char = ' ' )
  width =
    case width
    when Symbol, String
      distance_to( width )
    when Fixnum
      Utils.at_least( width, 0 )
    end
  if width > 0
    fill_str =
      if char.length > 1 and ( char = SingleLine( char ) ).width > 1
        char.tile( width )
      else
        char * width
      end
    @cursor.column += width
    @device.print( fill_str )
  end
  self
end
foreground( color = nil ) { || ... } click to toggle source
# File lib/monocle-print/output-device.rb, line 99
def foreground( color = nil )
  color or return( @foreground_stack.last )
  begin
    @foreground_stack.push( color )
    yield
  ensure
    @foreground_stack.pop
  end
end
full_width() click to toggle source
# File lib/monocle-print/output-device.rb, line 303
def full_width
  screen_size.width
end
height() click to toggle source
# File lib/monocle-print/output-device.rb, line 299
def height
  screen_size.height
end
indent( n = 0, m = 0 ) { || ... } click to toggle source
# File lib/monocle-print/output-device.rb, line 172
def indent( n = 0, m = 0 )
  n, m = n.to_i, m.to_i
  self.left_margin  += n
  self.right_margin += m
  if block_given?
    begin
      yield
    ensure
      self.left_margin  -= n
      self.right_margin -= m
    end
  else
    self
  end
end
left_margin() click to toggle source
# File lib/monocle-print/output-device.rb, line 196
def left_margin
  @margin.left
end
left_margin=(n) click to toggle source
# File lib/monocle-print/output-device.rb, line 204
def left_margin= n
  @margin.left = n.to_i
end
leger( char = '<h>', w = width ) click to toggle source
# File lib/monocle-print/output-device.rb, line 245
def leger( char = '<h>', w = width )
  puts( @style.format( char ).tile( w ) )
end
line() click to toggle source
# File lib/monocle-print/output-device.rb, line 383
def line
  @cursor.line
end
list( *args ) { |list| ... } click to toggle source
# File lib/monocle-print/output-device.rb, line 222
def list( *args )
  List.new( *args ) do | list |
    list.output = self
    block_given? and yield( list )
    list.render
  end
  return( self )
end
margin=(n) click to toggle source
# File lib/monocle-print/output-device.rb, line 168
def margin= n
  self.left_margin = self.right_margin = Utils.at_least( n.to_i, 0 )
end
modifier( name = nil ) { || ... } click to toggle source
# File lib/monocle-print/output-device.rb, line 125
def modifier( name = nil )
  name or return( @modifier_stack.last )
  begin
    @modifier_stack.push( name )
    yield
  ensure
    @modifier_stack.pop
  end
end
newline!() click to toggle source
# File lib/monocle-print/output-device.rb, line 364
def newline!
  +@cursor
  @device.print( @newline )
  @device.flush
  self
end
on( color = nil )
Alias for: background
outdent( n ) { || ... } click to toggle source
# File lib/monocle-print/output-device.rb, line 188
def outdent( n )
  self.left_margin -= n.to_i
  block_given? and
    begin yield
    ensure self.left_margin += n.to_i
    end
end
print( *objs ) click to toggle source
printf( fmt, *args ) click to toggle source
# File lib/monocle-print/output-device.rb, line 276
def printf( fmt, *args )
  print( sprintf( fmt, *args ) )
end
put( str, options = nil ) click to toggle source
# File lib/monocle-print/output-device.rb, line 311
def put( str, options = nil )
  if options
    fill  = @style.format( options.fetch( :fill, ' ' ) )
    align = options.fetch( :align, @alignment )
  else
    fill, align = ' ', @alignment
  end

  str = SingleLine.new( str ).align!( align, width, fill )
  code = color_code
  str.gsub!( /\e\[0m/ ) { "\e[0m" << code }

  fill( @margin.left )
  @device.print( code )
  @device.print( str )
  @cursor + str.width
  @device.print( clear_attr )
  fill( screen_size.width - @cursor.column )
  self
end
put!( str, options = nil ) click to toggle source
# File lib/monocle-print/output-device.rb, line 332
def put!( str, options = nil )
  put( str, options )
  newline!
end
puts( *objs ) click to toggle source
# File lib/monocle-print/output-device.rb, line 266
def puts( *objs )
  text = Text( [ objs ].flatten!.join( @newline ) )
  ( text.empty? or text.last.empty? ) and text << Line( '' )
  for line in text
    put( line )
    newline!
  end
  self
end
putsf( fmt, *args ) click to toggle source
# File lib/monocle-print/output-device.rb, line 280
def putsf( fmt, *args )
  puts( sprintf( fmt, *args ) )
end
reset!() click to toggle source
# File lib/monocle-print/output-device.rb, line 212
def reset!
  @fg_stack.clear
  @bg_stack.clear
  @margin = Pair.new( 0, 0 )
  @cursor = Pair.new( 0, 0 )
  @screen_size = nil
end
return!() click to toggle source
# File lib/monocle-print/output-device.rb, line 337
def return!
  ~@cursor
  @device.print("\r")
  @device.flush
end
right_margin() click to toggle source
# File lib/monocle-print/output-device.rb, line 200
def right_margin
  @margin.right
end
right_margin=(n) click to toggle source
# File lib/monocle-print/output-device.rb, line 208
def right_margin= n
  @margin.right = n.to_i
end
space( n_lines = 1 ) click to toggle source
# File lib/monocle-print/output-device.rb, line 371
def space( n_lines = 1 )
  n_lines.times do
    put( '' )
    newline!
  end
  self
end
table( *args ) { |t| ... } click to toggle source
# File lib/monocle-print/output-device.rb, line 231
def table( *args )
  Table.new( *args ) do | t |
    block_given? and yield( t )
    t.render( self )
  end
end
use_color( v = nil ) click to toggle source
# File lib/monocle-print/output-device.rb, line 159
def use_color( v = nil )
  v.nil? or self.use_color = v
  return( @use_color )
end
Also aliased as: use_color?
use_color=(v) click to toggle source
# File lib/monocle-print/output-device.rb, line 164
def use_color= v
  @use_color = !!v
end
use_color?() click to toggle source
# File lib/monocle-print/output-device.rb, line 155
def use_color?
  @use_color
end
width() click to toggle source
# File lib/monocle-print/output-device.rb, line 307
def width
  screen_size.width - @margin.left - @margin.right
end

Private Instance Methods

abs( col ) click to toggle source
# File lib/monocle-print/output-device.rb, line 432
def abs( col )
  col < 0 and col += width
  Utils.bound( col, 0, width - 1 )
end
default_height() click to toggle source
# File lib/monocle-print/output-device.rb, line 466
def default_height
  ( @forced_height || ENV[ 'LINES' ] || DEFAULT_SIZE.height ).to_i
end
default_size() click to toggle source
# File lib/monocle-print/output-device.rb, line 462
def default_size
  Pair.new( default_width, default_height )
end
default_width() click to toggle source
# File lib/monocle-print/output-device.rb, line 470
def default_width
  ( @forced_width || ENV[ 'COLUMNS' ] || DEFAULT_SIZE.width ).to_i
end
distance_to( tab ) click to toggle source
# File lib/monocle-print/output-device.rb, line 438
def distance_to( tab )
  Utils.at_least( abs( @tabs[ tab ] ) - @cursor.columm, 0 )
end
screen_size() click to toggle source
# File lib/monocle-print/output-device.rb, line 442
def screen_size
  @screen_size ||=
    begin
      if device.respond_to?( :winsize )
        detected_height, detected_width = device.winsize
      elsif data = SIZE_STRUCT.dup and device.ioctl( SIZE_IOCTL, data ) >= 0
        detected_height, detected_width = data.unpack( "SS" )
      else
        size = default_size
        detected_height, detected_width = size.height, size.width
      end
      Pair.new(
        @forced_width  || detected_width,
        @forced_height || detected_height
      )
    rescue Exception
      default_size
    end
end