Sheetshow.A1 (Sheetshow v0.1.0)

Copy Markdown View Source

A1 notation: the 'Q1 costs'!B4:C9 strings Google Sheets speaks.

Sheetshow rows and columns are 0-indexed. A1 rows are 1-indexed and A1 columns are bijective base-26 letters (A, Z, AA). This module holds the conversions; Sheetshow.Coord and Sheetshow.Range parse and print with them.

A sheet name is quoted when it could be mistaken for a cell reference or contains anything but letters, digits and underscores, with ' doubled inside quotes, as Sheets does.

Summary

Functions

0-indexed column to letters.

Letters to 0-indexed column. Case-insensitive. Raises ArgumentError on anything but letters.

Parses one endpoint of a reference into {col, row}, 0-indexed, where a missing part is nil. $ anchors are accepted and dropped.

Quotes a sheet name when A1 notation needs it.

Whether a bare string reads as a cell or range reference rather than a sheet name. Sheet names for which this is true need quoting, as in Sheets itself.

Splits an A1 string into {sheet, rest}. The sheet is nil when there is no sheet part; the rest is nil when a quoted name stands alone.

Functions

col_to_letters(col)

@spec col_to_letters(non_neg_integer()) :: String.t()

0-indexed column to letters.

iex> Sheetshow.A1.col_to_letters(0)
"A"
iex> Sheetshow.A1.col_to_letters(27)
"AB"

letters_to_col(letters)

@spec letters_to_col(String.t()) :: non_neg_integer()

Letters to 0-indexed column. Case-insensitive. Raises ArgumentError on anything but letters.

iex> Sheetshow.A1.letters_to_col("ab")
27

parse_ref(ref)

@spec parse_ref(String.t()) ::
  {:ok, {non_neg_integer() | nil, non_neg_integer() | nil}} | :error

Parses one endpoint of a reference into {col, row}, 0-indexed, where a missing part is nil. $ anchors are accepted and dropped.

iex> Sheetshow.A1.parse_ref("B4")
{:ok, {1, 3}}
iex> Sheetshow.A1.parse_ref("$C")
{:ok, {2, nil}}
iex> Sheetshow.A1.parse_ref("10")
{:ok, {nil, 9}}
iex> Sheetshow.A1.parse_ref("A0")
:error

quote_sheet(name)

@spec quote_sheet(String.t()) :: String.t()

Quotes a sheet name when A1 notation needs it.

iex> Sheetshow.A1.quote_sheet("Costs")
"Costs"
iex> Sheetshow.A1.quote_sheet("Q1 costs")
"'Q1 costs'"
iex> Sheetshow.A1.quote_sheet("Q1's")
"'Q1''s'"
iex> Sheetshow.A1.quote_sheet("Tab1")
"'Tab1'"

ref_like?(str)

@spec ref_like?(String.t()) :: boolean()

Whether a bare string reads as a cell or range reference rather than a sheet name. Sheet names for which this is true need quoting, as in Sheets itself.

iex> Sheetshow.A1.ref_like?("Tab1")
true
iex> Sheetshow.A1.ref_like?("A:A")
true
iex> Sheetshow.A1.ref_like?("log")
false

split_sheet(a1)

@spec split_sheet(String.t()) ::
  {:ok, {String.t() | nil, String.t() | nil}} | {:error, Sheetshow.Error.t()}

Splits an A1 string into {sheet, rest}. The sheet is nil when there is no sheet part; the rest is nil when a quoted name stands alone.

iex> Sheetshow.A1.split_sheet("'Q1 costs'!A1:B2")
{:ok, {"Q1 costs", "A1:B2"}}
iex> Sheetshow.A1.split_sheet("Costs!A1")
{:ok, {"Costs", "A1"}}
iex> Sheetshow.A1.split_sheet("A1")
{:ok, {nil, "A1"}}
iex> Sheetshow.A1.split_sheet("'Costs'")
{:ok, {"Costs", nil}}