Expression.Callbacks (expression v0.1.0)

Link to this section Summary

Functions

Returns the absolute value of a number

Returns TRUE if and only if all its arguments evaluate to TRUE

Convert a string function name into an atom meant to handle that function

Returns the character specified by a number

Removes all non-printable characters from a text string

Returns a numeric code for the first character in a text string

Joins text strings into one text string

Defines a new date value

Converts date stored in text to an actual date, using strftime formatting.

Returns only the day of the month of a date (1 to 31)

Moves a date by the given number of months

Returns the first word in the given text - equivalent to WORD(text, 1)

Formats the given number in decimal format using a period and commas

Handle a function call while evaluating the AST.

Returns only the hour of a datetime (0 to 23)

Returns one value if the condition evaluates to TRUE, and another value if it evaluates to FALSE

Returns TRUE if the argument is a boolean.

Returns TRUE if the argument is a number.

Returns TRUE if the argument is a string.

Returns the first characters in a text string

Returns the number of characters in a text string

Converts a text string to lowercase

Returns the maximum value of all arguments

Returns the minimum value of all arguments

Returns only the minute of a datetime (0 to 59)

Returns only the month of a date (1 to 12)

Returns the current date time as UTC

Returns TRUE if any argument is TRUE

Formats a number as a percentage

Returns the result of a number raised to a power - equivalent to the ^ operator

Capitalizes the first letter of every word in a text string

Formats digits in text for reading in TTS

Removes the first word from the given text. The remaining text will be unchanged

Repeats text a given number of times

Returns the last characters in a text string

Returns only the second of a datetime (0 to 59)

Substitutes new_text for old_text in a text string. If instance_num is given, then only that instance will be substituted

Returns the sum of all arguments, equivalent to the + operator

Defines a time value which can be used for time arithmetic

Converts time stored in text to an actual time

Returns the current date

Returns the unicode character specified by a number

Returns a numeric code for the first character in a text string

Converts a text string to uppercase

Returns the day of the week of a date (1 for Sunday to 7 for Saturday)

Extracts the nth word from the given text string. If stop is a negative number, then it is treated as count backwards from the end of the text. If by_spaces is specified and is TRUE then the function splits the text into words only by spaces. Otherwise the text is split by punctuation characters as well

Returns the number of words in the given text string. If by_spaces is specified and is TRUE then the function splits the text into words only by spaces. Otherwise the text is split by punctuation characters as well

Extracts a substring of the words beginning at start, and up to but not-including stop. If stop is omitted then the substring will be all words from start until the end of the text. If stop is a negative number, then it is treated as count backwards from the end of the text. If by_spaces is specified and is TRUE then the function splits the text into words only by spaces. Otherwise the text is split by punctuation characters as well

Returns only the year of a date

Link to this section Functions

Link to this function

abs(ctx, number)

Returns the absolute value of a number

The absolute value of -1 is @ABS(-1)

Example

iex> Expression.Callbacks.abs(%{}, -1)
1
Link to this function

and_vargs(ctx, arguments)

Returns TRUE if and only if all its arguments evaluate to TRUE

@AND(contact.gender = "F", contact.age >= 18)

Example

iex> Expression.Callbacks.handle("and", [true, true], %{})
{:ok, true}
iex> Expression.Callbacks.and_vargs(%{}, [true, true])
true
iex> Expression.Callbacks.and_vargs(%{}, [true, false])
false
iex> Expression.Callbacks.and_vargs(%{}, [false, false])
false
Link to this function

atom_function_name(function_name)

Convert a string function name into an atom meant to handle that function

Reserved words such as and, if, and or are automatically suffixed with an _ underscore.

Link to this function

char(ctx, code)

Returns the character specified by a number

As easy as @CHAR(65), @CHAR(66), @CHAR(67)

Example

iex> Expression.Callbacks.char(%{}, 65)
"A"
Link to this function

clean(ctx, binary)

Removes all non-printable characters from a text string

You entered @CLEAN(step.value)

Example

iex> Expression.Callbacks.clean(%{}, <<65, 0, 66, 0, 67>>)
"ABC"

Returns a numeric code for the first character in a text string

The numeric code of A is @CODE("A")

Example

iex> Expression.Callbacks.code(%{}, "A")
65
Link to this function

concatenate_vargs(ctx, arguments)

Joins text strings into one text string

Your name is @CONCATENATE(contact.first_name, " ", contact.last_name)

Example

iex> Expression.Callbacks.handle("concatenate", ["name", " ", "surname"], %{})
{:ok, "name surname"}
Link to this function

date(ctx, year, month, day)

Defines a new date value

This is a date @DATE(2012, 12, 25)

Example

iex> to_string(Expression.Callbacks.date(%{}, 2012, 12, 25))
"2012-12-25 00:00:00Z"
Link to this function

datevalue(ctx, date, format \\ "%Y-%m-%d %H:%M:%S")

Converts date stored in text to an actual date, using strftime formatting.

It will fallback to "%Y-%m-%d %H:%M:%S" if no formatting is supplied

You joined on @DATEVALUE(contact.joined_date, "%Y-%m%-d")

Example

iex> date = Expression.Callbacks.date(%{}, 2020, 12, 20)
iex> Expression.Callbacks.datevalue(%{}, date)
"2020-12-20 00:00:00"
iex> Expression.Callbacks.datevalue(%{}, date, "%Y-%m-%d")
"2020-12-20"

Returns only the day of the month of a date (1 to 31)

The current day is @DAY(contact.joined_date)

Example

iex> now = DateTime.utc_now()
iex> day = Expression.Callbacks.day(%{}, now)
iex> day == now.day
true
Link to this function

edate(ctx, date, months)

Moves a date by the given number of months

Next month's meeting will be on @EDATE(date.today, 1)

Example

iex> now = DateTime.utc_now()
iex> future = Timex.shift(now, months: 1)
iex> date = Expression.Callbacks.edate(%{}, now, 1)
iex> future == date
true
Link to this function

first_word(ctx, binary)

Returns the first word in the given text - equivalent to WORD(text, 1)

The first word you entered was @FIRST_WORD(step.value)

Example

iex> Expression.Callbacks.first_word(%{}, "foo bar baz")
"foo"
Link to this function

fixed(ctx, number, precision, no_commas \\ false)

Formats the given number in decimal format using a period and commas

You have @FIXED(contact.balance, 2) in your account

Example

iex> Expression.Callbacks.fixed(%{}, 4.209922, 2, false)
"4.21"
iex> Expression.Callbacks.fixed(%{}, 4000.424242, 4, true)
"4,000.4242"
iex> Expression.Callbacks.fixed(%{}, 3.7979, 2, false)
"3.80"
iex> Expression.Callbacks.fixed(%{}, 3.7979, 2)
"3.80"
Link to this function

handle(function_name, arguments, context)

Specs

handle(function_name :: binary(), arguments :: [any()], context :: map()) ::
  {:ok, any()} | {:error, :not_implemented}

Handle a function call while evaluating the AST.

Handlers in this module are either:

  1. The function name as is
  2. The function name with an underscore suffix if the function name is a reserved word
  3. The function name suffixed with _vargs if the takes a variable set of arguments
Link to this function

hour(ctx, date)

Returns only the hour of a datetime (0 to 23)

The current hour is @HOUR(NOW())

Example

iex> now = DateTime.utc_now()
iex> hour = Expression.Callbacks.hour(%{}, now)
iex> now.hour == hour
true
Link to this function

if_(ctx, condition, yes, no)

Returns one value if the condition evaluates to TRUE, and another value if it evaluates to FALSE

Dear @IF(contact.gender = "M", "Sir", "Madam")

Example

iex> Expression.Callbacks.handle("if", [true, "Yes", "No"], %{})
{:ok, "Yes"}
iex> Expression.Callbacks.handle("if", [false, "Yes", "No"], %{})
{:ok, "No"}
Link to this function

isbool(ctx, var)

Returns TRUE if the argument is a boolean.

@ISBOOL(block.value) will return TRUE if the block returned a boolean value.

Example

iex> Expression.Callbacks.isbool(%{}, true)
true
iex> Expression.Callbacks.isbool(%{}, false)
true
iex> Expression.Callbacks.isbool(%{}, 1)
false
iex> Expression.Callbacks.isbool(%{}, 0)
false
iex> Expression.Callbacks.isbool(%{}, "true")
false
iex> Expression.Callbacks.isbool(%{}, "false")
false
Link to this function

isnumber(ctx, var)

Returns TRUE if the argument is a number.

@ISNUMBER(contact.age) will return TRUE if the contact's age is a number.

Example

iex> Expression.Callbacks.isnumber(%{}, 1)
true
iex> Expression.Callbacks.isnumber(%{}, 1.0)
true
iex> Expression.Callbacks.isnumber(%{}, Decimal.new("1.0"))
true
iex> Expression.Callbacks.isnumber(%{}, "1.0")
true
iex> Expression.Callbacks.isnumber(%{}, "a")
false
Link to this function

isstring(ctx, binary)

Returns TRUE if the argument is a string.

@ISSTRING(contact.name) will return TRUE if the contact's name is a string.

Example

iex> Expression.Callbacks.isstring(%{}, "hello")
true
iex> Expression.Callbacks.isstring(%{}, false)
false
iex> Expression.Callbacks.isstring(%{}, 1)
false
iex> Expression.Callbacks.isstring(%{}, Decimal.new("1.0"))
false
Link to this function

left(ctx, binary, size)

Returns the first characters in a text string

You entered PIN @LEFT(step.value, 4)

Example

iex> Expression.Callbacks.left(%{}, "foobar", 4)
"foob"
Link to this function

len(ctx, binary)

Returns the number of characters in a text string

You entered @LEN(step.value) characters

Example

iex> Expression.Callbacks.len(%{}, "foo")
3
iex> Expression.Callbacks.len(%{}, "zoë")
3
Link to this function

lower(ctx, binary)

Converts a text string to lowercase

Welcome @LOWER(contact)
```

# Example

    iex> Expression.Callbacks.lower(%{}, "Foo Bar")
    "foo bar"
Link to this function

max_vargs(ctx, arguments)

Returns the maximum value of all arguments

Please complete at most @MAX(flow.questions, 10) questions

Example

iex> Expression.Callbacks.handle("max", [1, 2, 3], %{})
{:ok, 3}
Link to this function

min_vargs(ctx, arguments)

Returns the minimum value of all arguments

Please complete at least @MIN(flow.questions, 10) questions

Example

iex> Expression.Callbacks.handle("min", [1, 2, 3], %{})
{:ok, 1}
Link to this function

minute(ctx, date)

Returns only the minute of a datetime (0 to 59)

The current minute is @MINUTE(NOW())

Example

iex> now = DateTime.utc_now()
iex> minute = Expression.Callbacks.minute(%{}, now)
iex> now.minute == minute
true
Link to this function

month(ctx, date)

Returns only the month of a date (1 to 12)

The current month is @MONTH(NOW())

Example

iex> now = DateTime.utc_now()
iex> month = Expression.Callbacks.month(%{}, now)
iex> now.month == month
true

Returns the current date time as UTC

It is currently @NOW()

Example

iex> DateTime.utc_now() == Expression.Callbacks.now(%{})

Link to this function

or_vargs(ctx, arguments)

Returns TRUE if any argument is TRUE

@OR(contact.state = "GA", contact.state = "WA", contact.state = "IN")

Example

iex> Expression.Callbacks.handle("or", [true, false], %{})
{:ok, true}
iex> Expression.Callbacks.handle("or", [true, true], %{})
{:ok, true}
iex> Expression.Callbacks.handle("or", [false, false], %{})
{:ok, false}
Link to this function

percent(ctx, float)

Formats a number as a percentage

You've completed @PERCENT(contact.reports_done / 10) reports

Example

iex> Expression.Callbacks.percent(%{}, 2/10)
"20%"
iex> Expression.Callbacks.percent(%{}, "0.2")
"20%"
iex> Expression.Callbacks.percent(%{}, Decimal.new("0.2"))
"20%"
Link to this function

power(ctx, a, b)

Returns the result of a number raised to a power - equivalent to the ^ operator

2 to the power of 3 is @POWER(2, 3)
Link to this function

proper(ctx, binary)

Capitalizes the first letter of every word in a text string

Your name is @PROPER(contact)

Example

iex> Expression.Callbacks.proper(%{}, "foo bar")
"Foo Bar"
Link to this function

read_digits(ctx, binary)

Formats digits in text for reading in TTS

Your number is @READ_DIGITS(contact.tel_e164)

Example

iex> Expression.Callbacks.read_digits(%{}, "+271")
"plus two seven one"
Link to this function

remove_first_word(ctx, binary, separator \\ " ")

Removes the first word from the given text. The remaining text will be unchanged

You entered @REMOVE_FIRST_WORD(step.value)

Example

iex> Expression.Callbacks.remove_first_word(%{}, "foo bar")
"bar"
iex> Expression.Callbacks.remove_first_word(%{}, "foo-bar", "-")
"bar"
Link to this function

rept(ctx, value, amount)

Repeats text a given number of times

Stars! @REPT("*", 10)

Example

iex> Expression.Callbacks.rept(%{}, "*", 10)
"**********"
Link to this function

right(ctx, binary, size)

Returns the last characters in a text string

Your input ended with ...@RIGHT(step.value, 3)

Example

iex> Expression.Callbacks.right(%{}, "testing", 3)
"ing"
Link to this function

second(ctx, date)

Returns only the second of a datetime (0 to 59)

The current second is @SECOND(NOW())

Example

iex> now = DateTime.utc_now()
iex> second = Expression.Callbacks.second(%{}, now)
iex> now.second == second
true
Link to this function

substitute(map, subject, pattern, replacement)

Substitutes new_text for old_text in a text string. If instance_num is given, then only that instance will be substituted

@SUBSTITUTE(step.value, "can't", "can")

Example

iex> Expression.Callbacks.substitute(%{}, "I can't", "can't", "can do") "I can do"

Link to this function

sum_vargs(ctx, arguments)

Returns the sum of all arguments, equivalent to the + operator

You have @SUM(contact.reports, contact.forms) reports and forms

Example

iex> Expression.Callbacks.handle("sum", [1, 2, 3], %{})
{:ok, 6}
Link to this function

time(ctx, hours, minutes, seconds)

Defines a time value which can be used for time arithmetic

2 hours and 30 minutes from now is @(date.now + TIME(2, 30, 0))

Example

iex> Expression.Callbacks.time(%{}, 12, 13, 14)
%Time{hour: 12, minute: 13, second: 14}
Link to this function

timevalue(ctx, expression)

Converts time stored in text to an actual time

Your appointment is at @(date.today + TIME("2:30"))

Example

iex> Expression.Callbacks.timevalue(%{}, "2:30")
%Time{hour: 2, minute: 30, second: 0}

iex> Expression.Callbacks.timevalue(%{}, "2:30:55")
%Time{hour: 2, minute: 30, second: 55}

Returns the current date

Today's date is @TODAY()

Example

iex> today = Date.utc_today()
iex> today == Expression.Callbacks.today(%{})
true
Link to this function

unichar(ctx, code)

Returns the unicode character specified by a number

As easy as @UNICHAR(65), @UNICHAR(66) , @UNICHAR(67)

Example

iex> Expression.Callbacks.unichar(%{}, 65) "A" iex> Expression.Callbacks.unichar(%{}, 233) "é"

Link to this function

unicode(ctx, arg)

Returns a numeric code for the first character in a text string

The numeric code of A is @UNICODE("A")

Example

iex> Expression.Callbacks.unicode(%{}, "A")
65
iex> Expression.Callbacks.unicode(%{}, "é")
233
Link to this function

upper(ctx, binary)

Converts a text string to uppercase

WELCOME @UPPER(contact)!!

Example

iex> Expression.Callbacks.upper(%{}, "foo")
"FOO"
Link to this function

weekday(ctx, date)

Returns the day of the week of a date (1 for Sunday to 7 for Saturday)

Today is day no. @WEEKDAY(TODAY()) in the week

Example

iex> today = DateTime.utc_now()
iex> expected = Timex.weekday(today)
iex> weekday = Expression.Callbacks.weekday(%{}, today)
iex> weekday == expected
true
Link to this function

word(ctx, binary, n, by_spaces \\ false)

Extracts the nth word from the given text string. If stop is a negative number, then it is treated as count backwards from the end of the text. If by_spaces is specified and is TRUE then the function splits the text into words only by spaces. Otherwise the text is split by punctuation characters as well

Example

iex> Expression.Callbacks.word(%{}, "hello cow-boy", 2)
"cow"
iex> Expression.Callbacks.word(%{}, "hello cow-boy", 2, true)
"cow-boy"
iex> Expression.Callbacks.word(%{}, "hello cow-boy", -1)
"boy"
Link to this function

word_count(ctx, binary, by_spaces \\ false)

Returns the number of words in the given text string. If by_spaces is specified and is TRUE then the function splits the text into words only by spaces. Otherwise the text is split by punctuation characters as well

You entered @WORD_COUNT(step.value) words

Example

iex> Expression.Callbacks.word_count(%{}, "hello cow-boy")
3
iex> Expression.Callbacks.word_count(%{}, "hello cow-boy", true)
2
Link to this function

word_slice(ctx, binary, start)

Extracts a substring of the words beginning at start, and up to but not-including stop. If stop is omitted then the substring will be all words from start until the end of the text. If stop is a negative number, then it is treated as count backwards from the end of the text. If by_spaces is specified and is TRUE then the function splits the text into words only by spaces. Otherwise the text is split by punctuation characters as well

Example

iex> Expression.Callbacks.word_slice(%{}, "RapidPro expressions are fun", 2, 4)
"expressions are"
iex> Expression.Callbacks.word_slice(%{}, "RapidPro expressions are fun", 2)
"expressions are fun"
iex> Expression.Callbacks.word_slice(%{}, "RapidPro expressions are fun", 1, -2)
"RapidPro expressions"
iex> Expression.Callbacks.word_slice(%{}, "RapidPro expressions are fun", -1)
"fun"
Link to this function

word_slice(ctx, binary, start, stop, by_spaces \\ false)

Link to this function

year(ctx, date)

Returns only the year of a date

The current year is @YEAR(NOW())

Example

iex> %{year: year} = now = DateTime.utc_now()
iex> year == Expression.Callbacks.year(%{}, now)