Expression.Callbacks behaviour (expression v2.3.1)

The function callbacks for the standard function set available in FLOIP expressions.

This should be relatively swappable with another implementation. The only requirement is the handle/3 function.

FLOIP functions are case insensitive. All functions in this callback module are implemented as lowercase names.

Some functions accept a variable amount of arguments. Elixir doesn't support variable arguments in functions.

If a function accepts a variable number of arguments the convention is to call the <function_name>_vargs/2 callback where the context is given as the first argument and the argument list as a second argument.

Reserved names such as and, if, and or are suffixed with an underscore.

Link to this section Summary

Callbacks

Handle a function call while evaluating the AST.

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

Evaluate the given AST against the context and return the value after evaluation.

Evaluate the given AST values against the context and return the values after evaluation.

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

Tests whether all the words are contained in text

Tests whether any of the words are contained in the text

Tests whether text starts with beginning

Tests whether expression contains a date formatted according to our environment

Tests whether expression is a date equal to date_string

Tests whether expression is a date after the date date_string

Tests whether expression contains a date before the date date_string

Tests whether an email is contained in text

Returns whether the contact is part of group with the passed in UUID

Tests whether expression contains a number

Tests whether expression contains a number equal to the value

Tests whether expression contains a number greater than min

Tests whether expression contains a number greater than or equal to min

Tests whether expression contains a number less than max

Tests whether expression contains a number less than or equal to max

Tests whether the text contains only phrase

Returns whether two text values are equal (case sensitive). In the case that they are, it will return the text as the match.

Tests whether expression matches the regex pattern

Tests whether expresssion contains a phone number. The optional country_code argument specifies the country to use for parsing.

Tests whether phrase is contained in expression

Tests whether there the expression has any characters in it

Tests whether expression contains a time.

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. This is Unicode safe.

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 FALSE if the argument supplied evaluates to truth-y

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. This is Unicode safe.

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 Callbacks

Link to this callback

handle(function_name, arguments, context)

@callback 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 section Functions

Link to this function

abs(ctx, number)

Returns the absolute value of a number

Example

iex> Expression.evaluate_as_string!("The absolute value of -1 is @ABS(-1)")
"The absolute value of -1 is 1"
Link to this function

and_vargs(ctx, arguments)

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

Example

iex> Expression.evaluate_as_boolean!("@AND(contact.gender = \"F\", contact.age >= 18)", %{
iex>  "contact" => %{
iex>    "gender" => "F",
iex>    "age" => 32
iex>  }})
true

iex> Expression.evaluate_as_boolean!("@AND(contact.gender = \"F\", contact.age >= 18)", %{
iex>  "contact" => %{
iex>    "gender" => "?",
iex>    "age" => 32
iex>  }})
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

Example

iex> Expression.evaluate_as_string!("As easy as @CHAR(65), @CHAR(66), @CHAR(67)")
"As easy as A, B, C"
Link to this function

clean(ctx, binary)

Removes all non-printable characters from a text string

Example

iex> Expression.evaluate_as_string!("You entered @CLEAN(step.value)", %{
iex>   "step" => %{
iex>     "value" => <<65, 0, 66, 0, 67>>
iex>   }
iex> })
"You entered ABC"
Link to this function

code(ctx, code_ast)

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

Example

iex> Expression.evaluate_as_string!("The numeric code of A is @CODE(\"A\")")
"The numeric code of A is 65"
Link to this function

concatenate_vargs(ctx, arguments)

Joins text strings into one text string

Example

iex> Expression.evaluate_as_string!("Your name is @CONCATENATE(contact.first_name, \" \", contact.last_name)", %{
iex>   "contact" => %{
iex>     "first_name" => "name",
iex>     "last_name" => "surname"
iex>    }
iex> })
"Your name is name surname"
Link to this function

date(ctx, year, month, day)

Defines a new date value

Example

iex> Expression.evaluate!("@date(2012, 12, 15)")
~U[2012-12-15 00:00:00Z]
Link to this function

datevalue(ctx, date)

Link to this function

datevalue(ctx, date, format)

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

Example

iex> Expression.evaluate!("@datevalue(date(2020, 12, 20))")
"2020-12-20 00:00:00"
iex> Expression.evaluate!("@datevalue(date(2020, 12, 20), '%Y-%m-%d')")
"2020-12-20"

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

Example

iex> now = DateTime.utc_now()
iex> day = Expression.evaluate!("@day(now())")
iex> day == now.day
true
Link to this function

edate(ctx, date, months)

Moves a date by the given number of months

Example

iex> now = DateTime.utc_now()
iex> future = Timex.shift(now, months: 1)
iex> date = Expression.evaluate!("@edate(now(), 1)")
iex> future.month == date.month
true
Link to this function

eval!(ast, ctx)

@spec eval!(term(), map()) :: term()

Evaluate the given AST against the context and return the value after evaluation.

Link to this function

eval_args!(args, ctx)

@spec eval_args!([term()], map()) :: [term()]

Evaluate the given AST values against the context and return the values after evaluation.

Link to this function

first_word(ctx, binary)

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

Example

iex> Expression.evaluate!("@first_word(\"foo bar baz\")")
"foo"
Link to this function

fixed(ctx, number, precision)

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

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

Example

iex> Expression.evaluate!("@fixed(4.209922, 2, false)")
"4.21"
iex> Expression.evaluate!("@fixed(4000.424242, 4, true)")
"4,000.4242"
iex> Expression.evaluate!("@fixed(3.7979, 2, false)")
"3.80"
iex> Expression.evaluate!("@fixed(3.7979, 2)")
"3.80"
Link to this function

fixed(ctx, number, precision, boolean)

Link to this function

handle(function_name, arguments, context)

@spec handle(function_name :: binary(), arguments :: [any()], context :: map()) ::
  {:ok, any()} | {:error, :not_implemented}
Link to this function

has_all_words(ctx, haystack, words)

Tests whether all the words are contained in text

The words can be in any order and may appear more than once.

Example

iex> Expression.evaluate!("@has_all_words(\"the quick brown FOX\", \"the fox\")")
true
iex> Expression.evaluate!("@has_all_words(\"the quick brown FOX\", \"red fox\")")
false
Link to this function

has_any_word(ctx, haystack, words)

Tests whether any of the words are contained in the text

Only one of the words needs to match and it may appear more than once.

Example

iex> Expression.evaluate!("@has_any_word(\"The Quick Brown Fox\", \"fox quick\")")
true
iex> Expression.evaluate!("@has_any_word(\"The Quick Brown Fox\", \"yellow\")")
false
Link to this function

has_beginning(ctx, text, beginning)

Tests whether text starts with beginning

Both text values are trimmed of surrounding whitespace, but otherwise matching is strict without any tokenization.

Example

iex> Expression.evaluate!("@has_beginning(\"The Quick Brown\", \"the quick\")")
true
iex> Expression.evaluate!("@has_beginning(\"The Quick Brown\", \"the    quick\")")
false
iex> Expression.evaluate!("@has_beginning(\"The Quick Brown\", \"quick brown\")")
false
Link to this function

has_date(ctx, expression)

Tests whether expression contains a date formatted according to our environment

This is very naively implemented with a regular expression.

Supported:

Example

iex> Expression.evaluate!("@has_date(\"the date is 15/01/2017\")")
true
iex> Expression.evaluate!("@has_date(\"there is no date here, just a year 2017\")")
false
Link to this function

has_date_eq(ctx, expression, date_string)

Tests whether expression is a date equal to date_string

Examples

iex> Expression.evaluate!("@has_date_eq(\"the date is 15/01/2017\", \"2017-01-15\")")
true
iex> Expression.evaluate!("@has_date_eq(\"there is no date here, just a year 2017\", \"2017-01-15\")")
false
Link to this function

has_date_gt(ctx, expression, date_string)

Tests whether expression is a date after the date date_string

Example

iex> Expression.evaluate!("@has_date_gt(\"the date is 15/01/2017\", \"2017-01-01\")")
true
iex> Expression.evaluate!("@has_date_gt(\"the date is 15/01/2017\", \"2017-03-15\")")
false
Link to this function

has_date_lt(ctx, expression, date_string)

Tests whether expression contains a date before the date date_string

Example

iex> Expression.evaluate!("@has_date_lt(\"the date is 15/01/2017\", \"2017-06-01\")")
true
iex> Expression.evaluate!("@has_date_lt(\"the date is 15/01/2021\", \"2017-03-15\")")
false
Link to this function

has_email(ctx, expression)

Tests whether an email is contained in text

Example:

iex> Expression.evaluate!("@has_email(\"my email is foo1@bar.com, please respond\")")
true
iex> Expression.evaluate!("@has_email(\"i'm not sharing my email\")")
false
Link to this function

has_group(ctx, groups, uuid)

Returns whether the contact is part of group with the passed in UUID

Example:

iex> contact = %{
...>   "groups" => [%{
...>     "uuid" => "b7cf0d83-f1c9-411c-96fd-c511a4cfa86d"
...>   }]
...> }
iex> Expression.evaluate!("@has_group(contact.groups, \"b7cf0d83-f1c9-411c-96fd-c511a4cfa86d\")", %{"contact" => contact})
true
iex> Expression.evaluate!("@has_group(contact.groups, \"00000000-0000-0000-0000-000000000000\")", %{"contact" => contact})
false
Link to this function

has_number(ctx, expression)

Tests whether expression contains a number

Example

iex> true = Expression.evaluate!("@has_number(\"the number is 42 and 5\")")
iex> true = Expression.evaluate!("@has_number(\"العدد ٤٢\")")
iex> true = Expression.evaluate!("@has_number(\"٠.٥\")")
iex> true = Expression.evaluate!("@has_number(\"0.6\")")
Link to this function

has_number_eq(ctx, expression, decimal)

Tests whether expression contains a number equal to the value

Example

iex> true = Expression.evaluate!("@has_number_eq(\"the number is 42\", 42)")
iex> true = Expression.evaluate!("@has_number_eq(\"the number is 42\", 42.0)")
iex> true = Expression.evaluate!("@has_number_eq(\"the number is 42\", \"42\")")
iex> true = Expression.evaluate!("@has_number_eq(\"the number is 42.0\", \"42\")")
iex> false = Expression.evaluate!("@has_number_eq(\"the number is 40\", \"42\")")
iex> false = Expression.evaluate!("@has_number_eq(\"the number is 40\", \"foo\")")
iex> false = Expression.evaluate!("@has_number_eq(\"four hundred\", \"foo\")")
Link to this function

has_number_gt(ctx, expression, decimal)

Tests whether expression contains a number greater than min

Example

iex> true = Expression.evaluate!("@has_number_gt(\"the number is 42\", 40)")
iex> true = Expression.evaluate!("@has_number_gt(\"the number is 42\", 40.0)")
iex> true = Expression.evaluate!("@has_number_gt(\"the number is 42\", \"40\")")
iex> true = Expression.evaluate!("@has_number_gt(\"the number is 42.0\", \"40\")")
iex> false = Expression.evaluate!("@has_number_gt(\"the number is 40\", \"40\")")
iex> false = Expression.evaluate!("@has_number_gt(\"the number is 40\", \"foo\")")
iex> false = Expression.evaluate!("@has_number_gt(\"four hundred\", \"foo\")")
Link to this function

has_number_gte(ctx, expression, decimal)

Tests whether expression contains a number greater than or equal to min

Example

iex> true = Expression.evaluate!("@has_number_gte(\"the number is 42\", 42)")
iex> true = Expression.evaluate!("@has_number_gte(\"the number is 42\", 42.0)")
iex> true = Expression.evaluate!("@has_number_gte(\"the number is 42\", \"42\")")
iex> false = Expression.evaluate!("@has_number_gte(\"the number is 42.0\", \"45\")")
iex> false = Expression.evaluate!("@has_number_gte(\"the number is 40\", \"45\")")
iex> false = Expression.evaluate!("@has_number_gte(\"the number is 40\", \"foo\")")
iex> false = Expression.evaluate!("@has_number_gte(\"four hundred\", \"foo\")")
Link to this function

has_number_lt(ctx, expression, decimal)

Tests whether expression contains a number less than max

Example

iex> true = Expression.evaluate!("@has_number_lt(\"the number is 42\", 44)")
iex> true = Expression.evaluate!("@has_number_lt(\"the number is 42\", 44.0)")
iex> false = Expression.evaluate!("@has_number_lt(\"the number is 42\", \"40\")")
iex> false = Expression.evaluate!("@has_number_lt(\"the number is 42.0\", \"40\")")
iex> false = Expression.evaluate!("@has_number_lt(\"the number is 40\", \"40\")")
iex> false = Expression.evaluate!("@has_number_lt(\"the number is 40\", \"foo\")")
iex> false = Expression.evaluate!("@has_number_lt(\"four hundred\", \"foo\")")
Link to this function

has_number_lte(ctx, expression, decimal)

Tests whether expression contains a number less than or equal to max

Example

iex> true = Expression.evaluate!("@has_number_lte(\"the number is 42\", 42)")
iex> true = Expression.evaluate!("@has_number_lte(\"the number is 42\", 42.0)")
iex> true = Expression.evaluate!("@has_number_lte(\"the number is 42\", \"42\")")
iex> false = Expression.evaluate!("@has_number_lte(\"the number is 42.0\", \"40\")")
iex> false = Expression.evaluate!("@has_number_lte(\"the number is 40\", \"foo\")")
iex> false = Expression.evaluate!("@has_number_lte(\"four hundred\", \"foo\")")
Link to this function

has_only_phrase(ctx, expression, phrase)

Tests whether the text contains only phrase

The phrase must be the only text in the text to match

Example

iex> Expression.evaluate!("@has_only_phrase(\"Quick Brown\", \"quick brown\")")
true
iex> Expression.evaluate!("@has_only_phrase(\"\", \"\")")
true
iex> Expression.evaluate!("@has_only_phrase(\"The Quick Brown Fox\", \"quick brown\")")
false
Link to this function

has_only_text(ctx, expression_one, expression_two)

Returns whether two text values are equal (case sensitive). In the case that they are, it will return the text as the match.

Example

iex> Expression.evaluate!("@has_only_text(\"foo\", \"foo\")")
true
iex> Expression.evaluate!("@has_only_text(\"\", \"\")")
true
iex> Expression.evaluate!("@has_only_text(\"foo\", \"FOO\")")
false
Link to this function

has_pattern(ctx, expression, pattern)

Tests whether expression matches the regex pattern

Both text values are trimmed of surrounding whitespace and matching is case-insensitive.

Examples

iex> Expression.evaluate!("@has_pattern(\"Buy cheese please\", \"buy (\\w+)\")")
true
iex> Expression.evaluate!("@has_pattern(\"Sell cheese please\", \"buy (\\w+)\")")
false
Link to this function

has_phone(ctx, expression)

Tests whether expresssion contains a phone number. The optional country_code argument specifies the country to use for parsing.

Example

iex> Expression.evaluate!("@has_phone(\"my number is +12067799294 thanks\")")
true
iex> Expression.evaluate!("@has_phone(\"my number is 2067799294 thanks\", \"US\")")
true
iex> Expression.evaluate!("@has_phone(\"my number is 206 779 9294 thanks\", \"US\")")
true
iex> Expression.evaluate!("@has_phone(\"my number is none of your business\", \"US\")")
false
Link to this function

has_phone(ctx, expression, country_code)

Link to this function

has_phrase(ctx, expression, phrase)

Tests whether phrase is contained in expression

The words in the test phrase must appear in the same order with no other words in between.

Examples

iex> Expression.evaluate!("@has_phrase(\"the quick brown fox\", \"brown fox\")")
true
iex> Expression.evaluate!("@has_phrase(\"the quick brown fox\", \"quick fox\")")
false
iex> Expression.evaluate!("@has_phrase(\"the quick brown fox\", \"\")")
true
Link to this function

has_text(ctx, expression)

Tests whether there the expression has any characters in it

Examples

iex> Expression.evaluate!("@has_text(\"quick brown\")")
true
iex> Expression.evaluate!("@has_text(\"\")")
false
iex> Expression.evaluate!("@has_text(\" \n\")")
false
iex> Expression.evaluate!("@has_text(123)")
true
Link to this function

has_time(ctx, expression)

Tests whether expression contains a time.

Examples

iex> Expression.evaluate!("@has_time(\"the time is 10:30\")")
true
iex> Expression.evaluate!("@has_time(\"the time is 10:00 pm\")")
true
iex> Expression.evaluate!("@has_time(\"the time is 10:30:45\")")
true
iex> Expression.evaluate!("@has_time(\"there is no time here, just the number 25\")")
false
Link to this function

hour(ctx, date)

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

Example

iex> now = DateTime.utc_now()
iex> hour = Expression.evaluate!("@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

Example

iex> Expression.evaluate!("@if(true, \"Yes\", \"No\")")
"Yes"
iex> Expression.evaluate!("@if(false, \"Yes\", \"No\")")
"No"
Link to this function

implements(module \\ __MODULE__, function_name, arguments)

Link to this function

isbool(ctx, var)

Returns TRUE if the argument is a boolean.

Example

iex> Expression.evaluate!("@isbool(true)")
true
iex> Expression.evaluate!("@isbool(false)")
true
iex> Expression.evaluate!("@isbool(1)")
false
iex> Expression.evaluate!("@isbool(0)")
false
iex> Expression.evaluate!("@isbool(\"true\")")
false
iex> Expression.evaluate!("@isbool(\"false\")")
false
Link to this function

isnumber(ctx, var)

Returns TRUE if the argument is a number.

Example

iex> Expression.evaluate!("@isnumber(1)")
true
iex> Expression.evaluate!("@isnumber(1.0)")
true
iex> Expression.evaluate!("@isnumber(dec)", %{"dec" => Decimal.new("1.0")})
true
iex> Expression.evaluate!("@isnumber(\"1.0\")")
true
iex> Expression.evaluate!("@isnumber(\"a\")")
false
Link to this function

isstring(ctx, binary)

Returns TRUE if the argument is a string.

Example

iex> Expression.evaluate!("@isstring(\"hello\")")
true
iex> Expression.evaluate!("@isstring(false)")
false
iex> Expression.evaluate!("@isstring(1)")
false
iex> Expression.evaluate!("@isstring(d)", %{"d" => Decimal.new("1.0")})
false
Link to this function

left(ctx, binary, size)

Returns the first characters in a text string. This is Unicode safe.

Example

iex> Expression.evaluate!("@left(\"foobar\", 4)")
"foob"

iex> Expression.evaluate!("@left(\"Умерла Мадлен Олбрайт - первая женщина на посту главы Госдепа США\", 20)")
"Умерла Мадлен Олбрай"
Link to this function

len(ctx, binary)

Returns the number of characters in a text string

Example

iex> Expression.evaluate!("@len(\"foo\")")
3
iex> Expression.evaluate!("@len(\"zoë\")")
3
Link to this function

lower(ctx, binary)

Converts a text string to lowercase

Example

iex> Expression.evaluate!("@lower(\"Foo Bar\")")
"foo bar"
Link to this function

map(ctx, enumerable, mapper)

Link to this function

max_vargs(ctx, arguments)

Returns the maximum value of all arguments

Example

iex> Expression.evaluate!("@max(1, 2, 3)")
3
Link to this function

min_vargs(ctx, arguments)

Returns the minimum value of all arguments

Example

iex> Expression.evaluate!("@min(1, 2, 3)")
1
Link to this function

minute(ctx, date)

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

Example

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

month(ctx, date)

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

Example

iex> now = DateTime.utc_now()
iex> month = Expression.evaluate!("@month(now)", %{"now" => now})
iex> now.month == month
true
Link to this function

not_(ctx, argument)

Returns FALSE if the argument supplied evaluates to truth-y

Example

iex> Expression.evaluate!("@and(not(false), true)")
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

Example

iex> Expression.evaluate!("@or(true, false)")
true
iex> Expression.evaluate!("@or(true, true)")
true
iex> Expression.evaluate!("@or(false, false)")
false
iex> Expression.evaluate!("@or(false, \"foo\")")
"foo"
Link to this function

percent(ctx, decimal)

Formats a number as a percentage

Example

iex> Expression.evaluate!("@percent(2/10)")
"20%"
iex> Expression.evaluate!("@percent(0.2)")
"20%"
iex> Expression.evaluate!("@percent(d)", %{"d" => 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

Example

iex> Expression.evaluate!("@proper(\"foo bar\")")
"Foo Bar"
Link to this function

read_digits(ctx, binary)

Formats digits in text for reading in TTS

Example

iex> Expression.evaluate!("@read_digits(\"+271\")")
"plus two seven one"
Link to this function

remove_first_word(ctx, binary)

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

Example

iex> Expression.evaluate!("@remove_first_word(\"foo bar\")")
"bar"
iex> Expression.evaluate!("@remove_first_word(\"foo-bar\", \"-\")")
"bar"
Link to this function

remove_first_word(ctx, binary, separator)

Link to this function

rept(ctx, value, amount)

Repeats text a given number of times

Example

iex> Expression.evaluate!("@rept(\"*\", 10)")
"**********"
Link to this function

right(ctx, binary, size)

Returns the last characters in a text string. This is Unicode safe.

Example

iex> Expression.evaluate!("@right(\"testing\", 3)")
"ing"

iex> Expression.evaluate!("@right(\"Умерла Мадлен Олбрайт - первая женщина на посту главы Госдепа США\", 20)")
"ту главы Госдепа США"
Link to this function

second(ctx, date)

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

Example

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

substitute(ctx, 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

Example

iex> Expression.evaluate!("@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.evaluate!("@sum(1, 2, 3)")
6
Link to this function

time(ctx, hours, minutes, seconds)

Defines a time value which can be used for time arithmetic

Example

iex> Expression.evaluate!("@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

Example

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

iex> Expression.evaluate!("@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

Example

iex> Expression.evaluate!("@unichar(65)")
"A"
iex> Expression.evaluate!("@unichar(233)")
"é"
Link to this function

unicode(ctx, letter)

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

Example

iex> Expression.evaluate!("@unicode(\"A\")")
65
iex> Expression.evaluate!("@unicode(\"é\")")
233
Link to this function

upper(ctx, binary)

Converts a text string to uppercase

Example

iex> Expression.evaluate!("@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)

Example

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

word(ctx, binary, n)

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.evaluate!("@word(\"hello cow-boy\", 2)")
"cow"
iex> Expression.evaluate!("@word(\"hello cow-boy\", 2, true)")
"cow-boy"
iex> Expression.evaluate!("@word(\"hello cow-boy\", -1)")
"boy"
Link to this function

word(ctx, binary, n, by_spaces)

Link to this function

word_count(ctx, binary)

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.evaluate!("@word_count(\"hello cow-boy\")")
3
iex> Expression.evaluate!("@word_count(\"hello cow-boy\", true)")
2
Link to this function

word_count(ctx, binary, by_spaces)

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.evaluate!("@word_slice(\"RapidPro expressions are fun\", 2, 4)")
"expressions are"
iex> Expression.evaluate!("@word_slice(\"RapidPro expressions are fun\", 2)")
"expressions are fun"
iex> Expression.evaluate!("@word_slice(\"RapidPro expressions are fun\", 1, -2)")
"RapidPro expressions"
iex> Expression.evaluate!("@word_slice(\"RapidPro expressions are fun\", -1)")
"fun"
Link to this function

word_slice(ctx, binary, start, stop)

Link to this function

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

Link to this function

year(ctx, date)

Returns only the year of a date

Example

iex> %{year: year} = now = DateTime.utc_now()
iex> year == Expression.evaluate!("@year(now)", %{"now" => now})