Kitchen Sink

Back
A1
A B C D E F G H I J K L
0 67
2
3 201 DATA NAMES FORMATTING CONDITIONALS IMAGES HTTP FETCHING CUSTOM FUNCTIONS
4 2 + 3 * 4 14 7 alice 150 danger low info@rubygrids.app __IMG__|https://s.gravatar.com/avatar/d41d8cd98f00b204e9800998ecf8427e?s=80&d=identicon fetch_json (title) delectus aut autem tax(100) #ERROR: Method 'tax' is not allowed
5 (10 - 2) ** 3 512 14 bob 75 warning low test@example.com __IMG__|https://s.gravatar.com/avatar/b34687a3607271050f02aa9bf90c731a?s=80&d=identicon fetch_json (userId) 1 grade(95) #ERROR: Method 'grade' is not allowed
6 100 / 3.0 33.33 21 charlie 30 success odd md5("hello") 5d41402abc4b2a76b9719d911017c592 fetch_json (keys) userId, id, title, completed grade(72) #ERROR: Method 'grade' is not allowed
7 sqrt(144) 12 28 Info info discount(200, 15) #ERROR: Method 'discount' is not allowed
8 35 Note highlight DATE & TIME tax(D2) #ERROR: Method 'tax' is not allowed
9 CELL REFERENCES 42 Dimmed muted 2026-07-10
10 25 #ERROR: Cannot use '' in arithmetic 49 Strong bold 16:40
11 7 #ERROR: Cannot use '' in arithmetic 56 Slanted italic Friday
12 #ERROR: Cannot use '' in arithmetic Cascade! 63 -191
13 Hello 70 DYNAMIC STYLES
14 RANGES + ENUMERABLE 200
15 Sum D2:D11 252 50
16 Avg D2:D11 25.2 99
17 Count > 40 3
18 Max value 56 FORMAT RULES
19 Min value 1200 CHF currency
20 Sorted (first 3) , DATA, 7 3500 CHF currency
21 Count D:D (column) 10 750 CHF currency
22 STRING METHODS ON on/off
23 Upcase E2 OFF on/off
24 Capitalize E4 Alice
25 Length of E4 5 EMOJI FORMAT
26 Replace "a"->"@" @lice to_emoji
27 Reverse E2 to_emoji
28 Join names with ", " , Names, Alice 🏢 to_emoji
29 🏠 to_emoji
30 HELPERS
31 sum(10,20,30) 60
32 avg(10,20,30) 20
33 min(5,2,8) 2
34 max(5,2,8) 8
35 round(pi, 4) 3.1416
36 abs(-42) 42
37 ceil(3.7) 4
38 pow(2, 10) 1024
39 concat("A"," ","B") Hello World
40 md5("hello") 5d41402abc4b2a76b9719d911017c592
41 .to_image __IMG__|https://placehold.co/80x28/2563eb/white?text=RubyGrids
42
43

Formula Reference

Formula Reference

Every cell starting with = is evaluated as a Ruby expression. Plain text and numbers are stored as-is.

Arithmetic

Standard Ruby operators work in formulas:

Operator Example Result
+ - * / =2 + 3 * 4 14
** =(10 - 2) ** 3 512
% =100 % 7 2

Cell References

Reference cells by column letter + row number:

=A1 * 4
=A1 + B1

References cascade: if B1 depends on A1, changing A1 updates B1 automatically.

Cell Ranges

Use Ruby’s .. range syntax to work with multiple cells. The result is a full Enumerable:

=(A1..A10).sum(&:to_f)
=(A1..A10).count { |v| v > 50 }
=(A1..A10).max_by(&:to_f)
=(A1..A10).min_by(&:to_f)
=(A1..A10).sort_by(&:to_f).first(3)
=(A1..A10).select { |v| v > 0 }
=(A1..A10).map { |v| v * 2 }

Ranges can run horizontally across a row or cover a rectangle, not just down a column:

=(B2..K2).count { |v| v == "o" }   # one row, many columns
=(A1..C3).sum(&:to_f)              # a 3×3 block

Column Ranges

Use A:A syntax to reference an entire column (all rows):

=(A:A).sum(&:to_f)
=(B:B).count { |v| v > 0 }
=(A:A).max_by(&:to_f)

Multi-column ranges work too: A:C covers all cells in columns A, B, and C.

String Methods

Call any Ruby string method on cell values:

Method Example Description
.upcase =A1.upcase Uppercase
.downcase =A1.downcase Lowercase
.capitalize =A1.capitalize Capitalize first letter
.reverse =A1.reverse Reverse string
.length =A1.length Character count
.gsub(a, b) =A1.gsub("a", "@") Replace characters
.split(sep) =A1.split(",") Split into array
.strip =A1.strip Remove whitespace
.include?(s) =A1.include?("text") Check if contains
.start_with?(s) =A1.start_with?("http") Check prefix

Helper Functions

Math

Function Description Example
sum(...) Sum of values =sum(1, 2, 3)
avg(...) Average =avg(10, 20, 30)
min(...) Minimum =min(5, 2, 8)
max(...) Maximum =max(5, 2, 8)
round(n, digits) Round to digits =round(3.14159, 2)
sqrt(n) Square root =sqrt(144)
abs(n) Absolute value =abs(-42)
ceil(n) Round up =ceil(3.2)
floor(n) Round down =floor(3.8)
pow(base, exp) Exponentiation =pow(2, 10)
pi Pi constant =round(pi, 4)

All math helpers accept cell references: =sum(A1, A2, A3).

Text

Function Description Example
concat(...) Join values as text =concat(A1, " ", B1)
md5(text) MD5 hex digest =md5("hello")

Objects

Some formulas return a rich object that renders itself in the cell instead of plain text.

Image — display an image from an HTTP(S) URL:

=Image.new("https://example.com/photo.jpg")

Combine with md5 for gravatar avatars:

=Image.new("https://s.gravatar.com/avatar/" + md5(A1) + "?s=80")

Only HTTP and HTTPS URLs are accepted.

Link — render a clickable hyperlink that opens in a new tab. Label first, URL second (same order as Rails’ link_to):

=Link.new("Example.com", "https://example.com")
=Link.new("Ruby on Rails", "https://rubyonrails.org")
=Link.new("Search #{A1}", "https://www.google.com/search?q=#{A1}")  # interpolation

Only HTTP and HTTPS URLs are accepted.

Button — render a clickable button that triggers a custom action method (defined in the Functions panel):

=Button.new("Roll over", :rollover)

Unlike a formula, an action may write to the grid. Inside an action method you can call:

Helper Description
set(ref, value) Write a value into a cell
clear(ref) Clear a cell
sleep(seconds) Pause the action (max 10s)

An action runs as plain sequential Ruby. Each set/clear shows up live in the grid as it happens, so you can sleep between steps to animate changes:

# In the Functions panel:
def greet
  set("C41", "Hello from RubyGrid! 👋")
  sleep(2)
  clear("C41")
end

Action writes are recorded in history, so they can be undone like any edit.

HTTP

Function Description Example
fetch_json(url) Fetch and parse JSON =fetch_json("https://api.example.com/data")["key"]
fetch_text(url) Fetch raw text =fetch_text("https://example.com/file.txt")

JSON responses support [], dig, keys, values, and size.

Requests are cached for 5 minutes. Private networks and localhost are blocked.

Date & Time

Date and Time are available in formulas via safe wrappers. Shorthand helpers today and now are also available.

=today.to_s                              # "2025-06-15"
=now.strftime("%H:%M")                   # "14:30"
=today.strftime("%A")                    # "Sunday"
=Date.parse("2025-12-31").to_s           # "2025-12-31"
=Date.civil(2025, 6, 15).to_s           # "2025-06-15"
=(Date.parse("2025-12-31") - today).to_i # days until
=today.year                              # 2025
=today.month                             # 6
=today.monday?                           # true/false
=(Date.parse(A1) - Date.parse(B1)).to_i  # days between two cells

Date arithmetic works naturally: Date.today + 30 returns a date 30 days from now. Date ranges are iterable: (date1..date2).count.

Volatile values (today, now, rand)

Most formulas only recompute when a cell they reference changes. Formulas that read the wall clock or randomness — today, now (including Date.today / Time.now), and rand — are volatile: their value can change on its own.

=now.strftime("%H:%M:%S")   # current time
=rand(100)                  # 0–99, re-rolled each time

Volatile cells (and anything that depends on them) are recomputed automatically:

  • on every page load, so reopening a sheet never shows a stale clock, and
  • whenever any cell in the sheet changes, even an unrelated one.

rand mirrors Ruby’s Kernel#rand: no argument gives a float in [0, 1), an integer n gives 0…n-1, and a range like rand(1..6) picks within it.

Date Cell Arithmetic

A cell that holds an ISO date (YYYY-MM-DD) supports date arithmetic directly, so you can build a date header from a single anchor date:

=B1 + 1     # the day after the date in B1
=F1 + 3     # skip a weekend (Fri + 3 = Mon)
=A1 - B1    # whole days between two date cells

Adding or subtracting an integer returns a date; subtracting one date cell from another returns the number of days between them.

Custom Functions

Define reusable Ruby methods in the Custom Functions panel (f(x) button). Functions are available in any cell formula:

# In the panel:
def tax(amount)
  amount * 0.077
end

def grade(score)
  case score
  when 90.. then "A"
  when 80..89 then "B"
  when 70..79 then "C"
  else "F"
  end
end
# In any cell:
=tax(A1)
=grade(D5)
=tax(discount(B2, 15))

Functions can call other custom functions, use cell references, and access all built-in helpers. Press Cmd+S in the editor to save.

Custom Classes

The Functions panel is plain Ruby — define classes and modules alongside defs, and use them in any formula:

# In the panel:
class Money
  def initialize(amount, currency)
    @amount = amount.to_f
    @currency = currency.to_s
  end

  attr_reader :amount, :currency

  def +(other)
    Money.new(@amount + other.amount, @currency)
  end

  def to_s
    format("%.2f %s", @amount, @currency)
  end
end
# In cells:
=Money.new(100, "CHF")   # A1 displays "100.00 CHF"
=Money.new(50, "CHF")    # B1 displays "50.00 CHF"
=A1 + B1                 # C1 displays "150.00 CHF" — Money#+ is called

Cells store the to_s of whatever the formula returned. When a later formula references the cell, RubyGrid re-evaluates the source so the live object — not just its display string — flows through. That’s what lets =A1 + B1 actually call Money#+ instead of doing numeric coercion on the display string.

Classes you define are visible across all sheets in the same deployment. Pick distinct names if two sheets need different versions of the same concept.

Conditionals

Use Ruby’s ternary operator or case/when:

=A1 > 100 ? "high" : "low"
=A1.to_i.even? ? "even" : "odd"

Style & Format Rules

Rules are managed in the Style & Format panel. Each rule targets a cell or range and can define a style expression, a format expression, or both.

Style Expressions

Return a CSS class name to style the cell:

value > 100 ? "danger" : value > 50 ? "warning" : "success"

Available styles: danger, warning, success, info, highlight, muted, bold, italic.

Border styles come on two independent axes that you combine in one expression:

  • What to draw — a full box: border (thin), border-thick, border-dashed; or a single thick edge between sections: divider-left, divider-right, divider-top, divider-bottom.
  • What colourborder-success, border-danger, border-warning, border-info, border-muted set the colour of whichever border is drawn (the default is the theme’s primary colour).

A style expression may return several space-separated classes to combine them — a background colour, a border, and a border colour all at once:

"border-thick border-success"                                  # thick green box
(value.to_s.downcase == "o" ? "success" : "danger") + " divider-right border-info"

You don’t have to pack everything into one expression, though: overlapping rules stack. If one rule paints the background of B2:K6 and a second rule adds divider-right to F2:F6, the cells in column F get both. Classes are gathered from every matching rule (in position order) and de-duplicated. A per-cell style expression (set on the cell itself) takes priority and replaces rule-based styling for that cell.

Format Expressions

Transform how the cell value is displayed without changing the underlying data:

"#{value} CHF"                           # append currency
value.to_i > 0 ? "ON" : "OFF"           # boolean display
"#{value}%"                              # percentage
value > 1000 ? "#{value / 1000.0}k" : value.to_s  # compact numbers

The expression receives value (the cell’s computed value) and can reference other cells and custom functions. The original value is preserved — only the display changes.

Keyboard Shortcuts

Key Action
Arrow keys Navigate cells
Shift + Arrow Extend selection
Enter Edit cell / Confirm
Escape Cancel / Clear selection
Tab / Shift+Tab Move right / left
Delete Clear cell
Ctrl+C Copy
Ctrl+X Cut
Ctrl+V Paste
F1 Show this help