class Prettyrb::Writer

Attributes

break_group_levels[R]
builder[R]
force_break[R]
indent_level[R]
max_length[R]
writer[R]

Public Class Methods

new(builder, indent_level: 0, max_length: 100, force_break: false) click to toggle source
# File lib/prettyrb/writer.rb, line 9
def initialize(builder, indent_level: 0, max_length: 100, force_break: false)
  @builder = builder
  @writer = writer
  @indent_level = indent_level
  @max_length = max_length
  @force_break = force_break
end

Public Instance Methods

render_group(builder) click to toggle source
# File lib/prettyrb/writer.rb, line 17
def render_group(builder)
  # render without force
  # render only non-groups with force
  # render only groups with force
  # render non-groups and groups with force

  # without breaks
  content = builder.parts.compact.map do |part|
    write_child(part, force_break: false)
  end.compact.join("")

  # break self
  if content.split("\n").any? { |l| l.length > max_length }
    content = builder.parts.compact.map do |part|
      write_child(part, force_break: !part.is_a?(Document::Group))
    end.join("")
  end

  # break child groups if over length, but not self
  if content.split("\n").any? { |l| l.length > max_length }
    content = builder.parts.compact.map do |part|
      if part.is_a?(Document::Group)
        possible_output = write_child(part, force_break: false)

        if possible_output && possible_output.split("\n").any? { |l| l.length > max_length }
          content = write_child(part, force_break: true)
        else
          content = possible_output
        end
      else
        write_child(part, force_break: false)
      end
    end.join("")
  end

  # always break self, attempt to break child groups too
  if content.split("\n").any? { |l| l.length > max_length }
    content = builder.parts.compact.map do |part|
      if part.is_a?(Document::Group)
        possible_output = write_child(part, force_break: false)

        if possible_output && possible_output.split("\n").any? { |l| l.length > max_length }
          content = write_child(part, force_break: true)
        else
          content = possible_output
        end
      else
        write_child(part, force_break: true)
      end
    end.join("")
  end

  content
end
to_s() click to toggle source
# File lib/prettyrb/writer.rb, line 72
def to_s
  case builder
  when Document::Join
    separator = break_up? ? builder.separator : builder.separator + " "
    parts = builder.parts.compact

    output = []
    parts.each do |part|
      output << write_child(part)
      output << separator if part != parts.last
    end
    output.join("")
  when Document::Concat
    builder.parts.compact.map { |p| write_child(p) }.compact.join("")
  when Document::Indent
    builder.parts.compact.map do |part|
      if builder.only_when_break && !break_up?
        write_child(part)
      else
        write_child(part, indent_level: indent_level + 1)
      end
    end.compact.join("")
  when Document::Dedent
    builder.parts.compact.map do |part|
      write_child(part, indent_level: indent_level - 1)
    end.compact.join("")
  when Document::Group
    render_group(builder)
  when Document::Hardline
    if builder.skip_indent
      "\n" * builder.count
    else
      "\n" * builder.count + indent_string
    end
  when Document::Softline
    if break_up?
      "\n" + indent_string
    else
      builder.fallback
    end
  when Document::IfBreak
    if break_up?
      builder.with_break
    else
      builder.without_break
    end
  when Symbol, String
    builder.to_s
  when nil
    nil
  else
    raise "unhandled type: #{builder.class}"
  end
end

Private Instance Methods

break_up?() click to toggle source
# File lib/prettyrb/writer.rb, line 133
def break_up?
  force_break
end
indent_string(extra: 0) click to toggle source
# File lib/prettyrb/writer.rb, line 141
def indent_string(extra: 0)
  "  " * (indent_level + extra)
end
write_child(child, indent_level: nil, group_level: nil, force_break: nil) click to toggle source
# File lib/prettyrb/writer.rb, line 145
def write_child(child, indent_level: nil, group_level: nil, force_break: nil)
  indent_level ||= self.indent_level
  force_break ||= self.force_break

  self.class.new(
    child,
    indent_level: indent_level,
    max_length: max_length,
    force_break: force_break,
  ).to_s
end
write_softline?() click to toggle source
# File lib/prettyrb/writer.rb, line 137
def write_softline?
  break_up?
end