Class: SXP::Generator

Inherits:
Object show all
Defined in:
vendor/bundler/ruby/2.4.0/bundler/gems/sxp.rb-0e9ee9d40b94/lib/sxp/generator.rb

Overview

An S-expression generator.

Takes an object and pretty-prints it using reasonable indentation rules

Defined Under Namespace

Classes: Block

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(buffer) ⇒ Generator

Initialize output with a stack of IO buffers

Parameters:



128
129
130
# File 'vendor/bundler/ruby/2.4.0/bundler/gems/sxp.rb-0e9ee9d40b94/lib/sxp/generator.rb', line 128

def initialize(buffer)
  @output = buffer
end

Class Method Details

Format S-expressions to STDOUT

Parameters:

Returns:



106
107
108
# File 'vendor/bundler/ruby/2.4.0/bundler/gems/sxp.rb-0e9ee9d40b94/lib/sxp/generator.rb', line 106

def self.print(*sxps)
  write($stdout, *sxps)
end

.string(*sxps) ⇒ Object

Format S-expressions to a String

Parameters:

Returns:



94
95
96
97
98
99
# File 'vendor/bundler/ruby/2.4.0/bundler/gems/sxp.rb-0e9ee9d40b94/lib/sxp/generator.rb', line 94

def self.string(*sxps)
  require 'stringio' unless defined?(StringIO)
  buf = StringIO.new
  write(buf, *sxps)
  buf.string
end

.write(out, *sxps) ⇒ Object

Write formatted S-expressions to an IO like object

Parameters:

Returns:



116
117
118
119
120
121
122
# File 'vendor/bundler/ruby/2.4.0/bundler/gems/sxp.rb-0e9ee9d40b94/lib/sxp/generator.rb', line 116

def self.write(out, *sxps)
  generator = self.new(out)
  sxps.each do |sxp|
    generator.render(sxp)
  end
  generator
end

Instance Method Details

#render(sexp) ⇒ Block

Render an element. For Array, this recursively renders each constituent into blocks. If the agregate length of a block is less than MIN_BLOCK characters, combine each constituent block into a single line.

Rendering does not perform final formatting, but returns a recursive array of blocks which are each ultimattely formattted onto their own line with leading whitespace.

Parameters:

Returns:



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'vendor/bundler/ruby/2.4.0/bundler/gems/sxp.rb-0e9ee9d40b94/lib/sxp/generator.rb', line 144

def render(sexp)
  block = Block.new(sexp, 0)
  if block.length > 40
    buffer = block.formatted

    # Attempt to fold symbols and strings onto proceeding line
    output = ""
    prev_length = 0
    buffer.lines.each do |line|
      if (stripped = line.strip)[0,1] != '(' &&
        prev_length + stripped.length + 1 < Block::BLOCK_MIN_LENGTH

        # Append to previous line
        start, match, rem = output.rpartition(/\S/)
        output = start + match + " " + stripped + rem
        prev_length += stripped.length + 1
      else
        # Terminate line and append this line
        output += line
        prev_length = line.length - 1
      end
    end
    @output.write output.gsub(/\)\s+\)/, '))')
  else
    @output.puts(block.to_sxp)
  end
end