class Tabulo::Cell

Represents a single cell within the body of a {Table}.

Attributes

value[R]

@return the underlying value for this Cell

Public Class Methods

new( alignment:, cell_data:, formatter:, left_padding:, padding_character:, right_padding:, styler:, truncation_indicator:, value:, wrap_preserve:, width:) click to toggle source

@!visibility private

# File lib/tabulo/cell.rb, line 14
def initialize(
  alignment:,
  cell_data:,
  formatter:,
  left_padding:,
  padding_character:,
  right_padding:,
  styler:,
  truncation_indicator:,
  value:,
  wrap_preserve:,
  width:)

  @alignment = alignment
  @cell_data = cell_data
  @formatter = formatter
  @left_padding = left_padding
  @padding_character = padding_character
  @right_padding = right_padding
  @styler = styler
  @truncation_indicator = truncation_indicator
  @value = value
  @wrap_preserve = wrap_preserve
  @width = width
end

Public Instance Methods

formatted_content() click to toggle source

@return [String] the content of the Cell, after applying the formatter for this Column (but

without applying any wrapping or the styler).
# File lib/tabulo/cell.rb, line 57
def formatted_content
  @formatted_content ||= apply_formatter
end
height() click to toggle source

@!visibility private

# File lib/tabulo/cell.rb, line 41
def height
  subcells.size
end
padded_truncated_subcells(target_height) click to toggle source

@!visibility private

# File lib/tabulo/cell.rb, line 46
def padded_truncated_subcells(target_height)
  total_padding_amount = @left_padding + @right_padding
  truncated = (height > target_height)
  (0...target_height).map do |subcell_index|
    append_truncator = (truncated && (total_padding_amount != 0) && (subcell_index + 1 == target_height))
    padded_subcell(subcell_index, append_truncator)
  end
end

Private Instance Methods

apply_formatter() click to toggle source
# File lib/tabulo/cell.rb, line 63
def apply_formatter
  if @formatter.arity == 2
    @formatter.call(@value, @cell_data)
  else
    @formatter.call(@value)
  end
end
apply_styler(content, line_index) click to toggle source
# File lib/tabulo/cell.rb, line 71
def apply_styler(content, line_index)
  case @styler.arity
  when 4
    @styler.call(@value, content, @cell_data, line_index)
  when 3
    @styler.call(@value, content, @cell_data)
  else
    @styler.call(@value, content)
  end
end
calculate_subcells() click to toggle source
# File lib/tabulo/cell.rb, line 106
def calculate_subcells
  case @wrap_preserve
  when :rune
    line_index = 0
    formatted_content.split(Util::NEWLINE, -1).flat_map do |substr|
      subsubcells, subsubcell, subsubcell_width = [], String.new(""), 0

      substr.scan(/\X/).each do |rune|
        rune_width = Unicode::DisplayWidth.of(rune)
        if subsubcell_width + rune_width > @width
          subsubcells << style_and_align_cell_content(subsubcell, line_index)
          subsubcell_width = 0
          subsubcell.clear
          line_index += 1
        end

        subsubcell << rune
        subsubcell_width += rune_width
      end

      subsubcells << style_and_align_cell_content(subsubcell, line_index)
      line_index += 1
      subsubcells
    end
  when :word
    line_index = 0
    formatted_content.split(Util::NEWLINE, -1).flat_map do |substr|
      subsubcells, subsubcell, subsubcell_width = [], String.new(""), 0

      substr.split(/(?<= |\-|\—|\–⁠)\b/).each do |word|
        # Each word looks like "this " or like "this-".
        word_width = Unicode::DisplayWidth.of(word)
        combined_width = subsubcell_width + word_width
        if combined_width - 1 == @width && word[-1] == " "
          # do nothing, as we're on the final word of the line and
          # the space at the end will be chopped off.
        elsif combined_width > @width
          content = style_and_align_cell_content(subsubcell, line_index)
          if content.strip.length != 0
            subsubcells << content
            subsubcell_width = 0
            subsubcell.clear
            line_index += 1
          end
        end

        if word_width >= @width
          word.scan(/\X/).each do |rune|
            rune_width = Unicode::DisplayWidth.of(rune)
            if subsubcell_width + rune_width > @width
              if rune != " "
                content = style_and_align_cell_content(subsubcell, line_index)
                subsubcells << content
                subsubcell_width = 0
                subsubcell.clear
                line_index += 1
              end
            end

            subsubcell << rune
            subsubcell_width += rune_width
          end
        else
          subsubcell << word
          subsubcell_width += word_width
        end
      end

      content = style_and_align_cell_content(subsubcell, line_index)
      subsubcells << content
      line_index += 1
      subsubcells
    end
  end
end
padded_subcell(subcell_index, append_truncator) click to toggle source
# File lib/tabulo/cell.rb, line 86
def padded_subcell(subcell_index, append_truncator)
  lpad = @padding_character * @left_padding
  rpad =
    if append_truncator
      styled_truncation_indicator(subcell_index) + padding(@right_padding - 1)
    else
      padding(@right_padding)
    end
  inner = subcell_index < height ? subcells[subcell_index] : padding(@width)
  "#{lpad}#{inner}#{rpad}"
end
padding(amount) click to toggle source
# File lib/tabulo/cell.rb, line 98
def padding(amount)
  @padding_character * amount
end
real_alignment() click to toggle source
# File lib/tabulo/cell.rb, line 202
def real_alignment
  return @alignment unless @alignment == :auto

  case @value
  when Numeric
    :right
  when TrueClass, FalseClass
    :center
  else
    :left
  end
end
style_and_align_cell_content(content, line_index) click to toggle source
# File lib/tabulo/cell.rb, line 182
def style_and_align_cell_content(content, line_index)
  if @wrap_preserve == :word
    content.strip!
  end

  padding = Util.max(@width - Unicode::DisplayWidth.of(content), 0)
  left_padding, right_padding =
    case real_alignment
    when :center
      half_padding = padding / 2
      [padding - half_padding, half_padding]
    when :left
      [0, padding]
    when :right
      [padding, 0]
    end

  "#{' ' * left_padding}#{apply_styler(content, line_index)}#{' ' * right_padding}"
end
styled_truncation_indicator(line_index) click to toggle source
# File lib/tabulo/cell.rb, line 102
def styled_truncation_indicator(line_index)
  apply_styler(@truncation_indicator, line_index)
end
subcells() click to toggle source
# File lib/tabulo/cell.rb, line 82
def subcells
  @subcells ||= calculate_subcells
end