class IndentedIO::IndentedIO

An IO device that writes indented text

IndentedIO objects forms a chain that acts as a stack. The lowest element in the stack is always a “pure” IO object (eg. $stdout) and as indentation levels rise or fall IndentedIO objects are moved on and off the stack

Note that new is private. The only way to create a IndentedIO object is to call indent on an object that supports it ({Kernel}, {IO}, or {StringIO})

Attributes

base[R]

First IndentedIO object on the stack. Equal to self if self is the first indentation object. The base object is used to keep track of bol for the whole stack of IndentedIO objects

combined_indent[R]

The combined indent strings of previous levels plus this device's indent string

device[R]

Reference to the pure IO object at the bottom of the stack. It is used to write directly to the IO object without having to recurse down the IndentedIO stack

levels[R]

Number of indent levels

parent[R]

Parent IndentedIO or IO object

this_indent[R]

Indent string for this device

Public Class Methods

new(parent, levels, this_indent, bol) click to toggle source

Hide new

# File lib/indented_io/indented_io.rb, line 122
def initialize(parent, levels, this_indent, bol)
  if levels < 0
    parent.is_a?(::IndentedIO::IndentedIO) or raise IndentedIO::Error.new "Negative levels argument"
    parent.level + levels >= 0 or raise IndentedIO::Error.new "levels out of range"
    sibling = parent
    while parent.is_a?(::IndentedIO::IndentedIO) && levels < 0
      levels += parent.levels
      sibling = parent
      parent = parent.parent
    end
    this_indent ||= sibling.indent
  end
  @parent = parent
  @levels = levels
  @this_indent = this_indent
  if @parent.is_a?(::IndentedIO::IndentedIO)
    @device = @parent.device
    @base = @parent.base
    @combined_indent = @parent.combined_indent + @this_indent * @levels
    self.bol = bol if !bol.nil?
  else
    @device = parent
    @base = self
    @combined_indent = @this_indent * @levels
    self.bol = (bol.nil? ? true : bol)
  end
end

Public Instance Methods

indent(levels=1, string_ = self.this_indent, string: string_, bol: nil, &block) click to toggle source

(see IndentedIO::IndentedIOInterface#indent)

# File lib/indented_io/indented_io.rb, line 19
def indent(levels=1, string_ = self.this_indent, string: string_, bol: nil, &block)
  interface_indent(levels, string, bol: bol, &block)
end
Also aliased as: interface_indent
interface_indent(levels=1, string_ = self.this_indent, string: string_, bol: nil, &block)

@!visibility private

Alias for: indent
method_missing(method, *args) click to toggle source

Make IndentedIO behave like the underlying @device @!visibility private

# File lib/indented_io/indented_io.rb, line 77
def method_missing(method, *args)
  device.send(method, *args)
end
p(*args) click to toggle source

Indent and print args to the underlying device. p has the same semantic as Kernel#p. Please note that p is only defined on Kernel in the Ruby core library but can be used on any IndentedIO object

# File lib/indented_io/indented_io.rb, line 58
def p(*args)
  if bol
    args.each { |arg| write(arg.inspect, "\n") }
  else
    @device.write(args.first.inspect, "\n")
    bol = true
    args[1..-1].each { |arg| write(arg.inspect, "\n") }
  end
  args.size == 1 ? args.first : args
end
print(*args) click to toggle source

Indent and print args to the underlying device. print has the same semantic as Kernel#print

printf(format, *args) click to toggle source

Indent and print args to the underlying device. printf has the same semantic as Kernel#printf

# File lib/indented_io/indented_io.rb, line 44
def printf(format, *args)
  write format % args
end
puts(*args) click to toggle source

Indent and print args to the underlying device. puts has the same semantic as Kernel#puts

# File lib/indented_io/indented_io.rb, line 50
def puts(*args)
  write args.join("\n"), "\n"
  nil
end
respond_to?(method, include_all = false) click to toggle source

Make IndentedIO behave like the underlying @device @!visibility private

# File lib/indented_io/indented_io.rb, line 71
def respond_to?(method, include_all = false)
  [:indent, :level, :print, :printf, :puts, :p].include?(method) || device.respond_to?(method)
end
write(*args) click to toggle source

Indent and print args to the underlying device. write has the same semantic as IO#write

# File lib/indented_io/indented_io.rb, line 25
def write(*args)
  str = args.join
  return if str.empty?
  s = (bol && str[0] != "\n" ? @combined_indent : "") + str.gsub(/\n([^\n])/m, "\n#{@combined_indent}\\1")
  self.bol = (s[-1] == "\n")
  @device.write(s)
end

Protected Instance Methods

bol() click to toggle source

True iff at Beginning-Of-Line

# File lib/indented_io/indented_io.rb, line 105
def bol()
  @base == self ? @bol : @base.bol # @bol only exists in the #base object
end
bol=(bol) click to toggle source

Set Beginning-Of-Line to true or false

# File lib/indented_io/indented_io.rb, line 110
def bol=(bol)
  @base.instance_variable_set(:@bol, bol) # @bol only exists in the #base object
end
level() click to toggle source

Current level

# File lib/indented_io/indented_io.rb, line 115
def level
  @level ||= @levels + (parent.is_a?(::IndentedIO::IndentedIO) ? parent.level : 0)
end