Class: CSVPlusPlus::Entities::CellReference

Inherits:
Entity
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/csv_plus_plus/entities/cell_reference.rb

Overview

A reference to a cell. Internally it is represented by a simple cell_index and row_index but there are functions for converting to and from A1-style formats. Supported formats are:

  • 1 - A reference to the entire first row

  • A - A reference to the entire first column

  • A1 - A reference to the first cell (top left)

  • A1:D10 - The range defined between A1 and D10

  • ‘Sheet1!B2` - Cell B2 on the sheet “Sheet1”

rubocop:disable Metrics/ClassLength

Constant Summary collapse

A1_NOTATION_REGEXP =

TODO: this is getting gross, maybe define an actual parser

/
  ^
    (?:
      (?:
        (?:'([^'\\]|\\.)*') # allow for a single-quoted sheet name
        |
        (\w+)               # or if it's not quoted, just allow \w+
      )
      !                     # if a sheet name is specified, it's always followed by a !
    )?
    ([a-zA-Z0-9]+)          # the only part required - something alphanumeric
    (?: :([a-zA-Z0-9]+))?   # and they might make it a range
  $
/x

Instance Attribute Summary collapse

Attributes inherited from Entity

#id, #type

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cell_index: nil, ref: nil, row_index: nil, scoped_to_expand: nil) ⇒ CellReference

Either ref, cell_index or row_index must be specified.

rubocop:disable Metrics/MethodLength

Parameters:

  • cell_index (Integer, nil) (defaults to: nil)

    The index of the cell being referenced.

  • ref (Integer, nil) (defaults to: nil)

    An A1-style cell reference (that will be parsed into it’s row/cell indexes).

  • row_index (Integer, nil) (defaults to: nil)

    The index of the row being referenced.

  • scoped_to_expand (Expand) (defaults to: nil)

    The [[expand]] that this cell reference will be scoped to. In other words, it will only be able to be resolved if the runtime is within the bounds of the expand (it can’t be referenced outside of the expand.)

Raises:

  • (::ArgumentError)


96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/csv_plus_plus/entities/cell_reference.rb', line 96

def initialize(cell_index: nil, ref: nil, row_index: nil, scoped_to_expand: nil)
  raise(::ArgumentError, 'Must specify :ref, :cell_index or :row_index') unless ref || cell_index || row_index

  super(::CSVPlusPlus::Entities::Type::CellReference)

  if ref
    from_a1_ref!(ref)
  else
    @cell_index = ::T.let(cell_index, ::T.nilable(::Integer))
    @row_index = ::T.let(row_index, ::T.nilable(::Integer))

    @upper_cell_index = ::T.let(nil, ::T.nilable(::Integer))
    @upper_row_index = ::T.let(nil, ::T.nilable(::Integer))
  end

  @scoped_to_expand = scoped_to_expand
end

Instance Attribute Details

#cell_indexInteger? (readonly)

The cell index of the cell being referenced

Returns:

  • (Integer, nil)

    the current value of cell_index



25
26
27
# File 'lib/csv_plus_plus/entities/cell_reference.rb', line 25

def cell_index
  @cell_index
end

#row_indexInteger? (readonly)

The row index of the cell being referenced

Returns:

  • (Integer, nil)

    the current value of row_index



25
26
27
# File 'lib/csv_plus_plus/entities/cell_reference.rb', line 25

def row_index
  @row_index
end

#scoped_to_expandExpand? (readonly)

If set, the expand in which this variable is scoped to. It cannot be resolved outside of the given expand.

Returns:

  • (Expand, nil)

    the current value of scoped_to_expand



25
26
27
# File 'lib/csv_plus_plus/entities/cell_reference.rb', line 25

def scoped_to_expand
  @scoped_to_expand
end

#sheet_nameString?

The name of the sheet reference

Returns:

  • (String, nil)

    the current value of sheet_name



25
26
27
# File 'lib/csv_plus_plus/entities/cell_reference.rb', line 25

def sheet_name
  @sheet_name
end

#upper_cell_indexInteger? (readonly)

If set, the cell reference is a range and this is the upper cell index of it

Returns:

  • (Integer, nil)

    the current value of upper_cell_index



25
26
27
# File 'lib/csv_plus_plus/entities/cell_reference.rb', line 25

def upper_cell_index
  @upper_cell_index
end

#upper_row_indexInteger? (readonly)

If set, the cell reference is a range and this is the upper row index of it

Returns:

  • (Integer, nil)

    the current value of upper_row_index



25
26
27
# File 'lib/csv_plus_plus/entities/cell_reference.rb', line 25

def upper_row_index
  @upper_row_index
end

Class Method Details

.valid_cell_reference?(cell_reference_string) ⇒ ::T::Boolean

Does the given cell_reference_string conform to a valid cell reference?

https://developers.google.com/sheets/api/guides/concepts

Parameters:

  • cell_reference_string (::String)

    The string to check if it is a valid cell reference (we assume it’s in A1 notation but maybe can support R1C1)

Returns:

  • (::T::Boolean)


75
76
77
# File 'lib/csv_plus_plus/entities/cell_reference.rb', line 75

def self.valid_cell_reference?(cell_reference_string)
  !(cell_reference_string =~ ::CSVPlusPlus::Entities::CellReference::A1_NOTATION_REGEXP).nil?
end

Instance Method Details

#==(other) ⇒ boolean

rubocop:disable Metrics/CyclomaticComplexity

Parameters:

Returns:

  • (boolean)


120
121
122
123
124
125
126
# File 'lib/csv_plus_plus/entities/cell_reference.rb', line 120

def ==(other)
  return false unless super

  other.is_a?(self.class) && @cell_index == other.cell_index && @row_index == other.row_index \
    && @sheet_name == other.sheet_name && @scoped_to_expand == other.scoped_to_expand \
    && @upper_cell_index == other.upper_cell_index && @upper_row_index == other.upper_row_index
end

#evaluate(runtime) ⇒ ::String

Get the A1-style cell reference

Parameters:

  • runtime (Runtime)

    The current runtime

Returns:

  • (::String)

    An A1-style reference



135
136
137
138
139
140
141
# File 'lib/csv_plus_plus/entities/cell_reference.rb', line 135

def evaluate(runtime)
  # unless in_scope?(runtime)
  #   runtime.raise_modifier_syntax_error(message: 'Reference is out of scope', bad_input: runtime.cell.value)
  # end

  to_a1_ref(runtime) || ''
end

#range?boolean

Is the cell_reference a range? - something like A1:D10

Returns:

  • (boolean)


147
148
149
# File 'lib/csv_plus_plus/entities/cell_reference.rb', line 147

def range?
  !upper_row_index.nil? || !upper_cell_index.nil?
end