Blocks

Blocks are the core concept of TagScript. Each block encapsulates a specific behaviour, like the CaseBlock, which can transform input text to UPPERCASE or lowercase.


Action Blocks

A group of blocks that can be used to signal some sort of action to be taken by the client. Characterised by adding data to the the actions attribute of the Interpreter’s Response return value.

class ya_tagscript.blocks.CommandBlock(limit: int = 3)[source]

Bases: BlockABC

Run a command as if the tag invoker had run it.

By default, only 3 command blocks can be used in a tag.

Usage: {command:<command text>}

Aliases: c, com, cmd, command

Parameter: None

Payload: command text (required)

Examples:

{c:ping}
# adds "ping" to the "commands" list of the Response's actions attribute

{c:ban {target(id)} flooding/spam}
# (Assuming target is a user with ID 123)
# adds "ban 123 flooding/spam"

Response Attribute:

This block sets the following attribute on the Response object:

  • actions
    • actions["commands"]: list[str] | None — A list of command strings or None

Note

This block will only add the processed command strings to the commands actions key as shown above. It is up to the client to implement actual command execution behaviour as desired.

class ya_tagscript.blocks.DeleteBlock[source]

Bases: BlockABC

Signal that the input message should be deleted.

If no expression is provided (just {delete} is used), it will always signal that the message should be deleted.

If an expression is provided, it is processed. If it evaluates to be True, the block will signal that the message should be deleted.

The block is idempotent, i.e. only one is ever needed for a given script. Once one block has set the “delete” actions key, subsequent copies are ignored, even if they provide other expressions with a different outcome.

Usage: {delete(<expression>)}

Aliases: delete, del

Parameter: expression (optional)

Payload: None

Examples:

{delete}
{del(true==true)}

Response Attribute:

This block sets the following attribute on the Response object:

  • actions
    • actions["delete"]: bool — Whether the invoking message should be deleted

Note

This block will only set the delete actions key to True/False. It is up to the client to implement actual deletion behaviour as desired.

class ya_tagscript.blocks.OverrideBlock[source]

Bases: BlockABC

Override a command’s permission requirements.

This block can override the permission requirements attached to a CommandBlock.

Possible overrides are:
  • “admin”: admin permissions

  • “mod”: mod permissions

  • “permissions”: general user permissions

Usage: {override(["admin"|"mod"|"permissions"])}

Aliases: override

Parameter: One of admin, mod, permissions (optional)

Payload: None

Examples:

{override}
# overrides all commands and permissions

{override(admin)}
# overrides commands that require the admin role

{override(permissions)}
{override(mod)}
# overrides commands that require the mod role or have user permission requirements

Response Attribute:

This block sets the following attribute on the Response object:

  • actions
    • actions["overrides"]: dict[Literal["admin", "mod", "permissions"], bool] — A dictionary like {"admin": bool, "mod": bool, "permissions": bool} where each attribute is either True or False

Note

This block only sets the overrides actions key as shown above, combining the provided parameters across the entire script. It is up to the client to implement actual permission override behaviour as desired, including what permissions qualify for “admin”, “mod”, or “permissions”.

class ya_tagscript.blocks.ReactBlock(limit: int = 5)[source]

Bases: BlockABC

Provide a list of reactions to be added to either the input message or the script output.

By default, only 5 emoji can be specified for either the input or output message, for a total of 10 emoji (max. 5 for input + max. 5 for output).

When providing several emoji, they have to be separated by a space.

Behaviour differs between aliases:

  • react: Emoji to add as reactions to the output message

  • reactu: (“react-up”) Emoji to add as reactions to the input message

Note

The emoji can be any strings, regardless of their validity as standard emoji or Discord server emotes. It is up to the client to validate the provided list of emoji.

If the same alias is used again in the script, the previous emoji are overwritten, so only the latest set of emoji is retained.

Usage: {react:<emoji>}

Aliases: react, reactu

Parameter: None

Payload: emoji (required)

Examples:

{react:💩}
# 💩 is added to the list of reactions for the output message

{react:💩 :)}
# both "💩" and ":)" are added to the list of reactions for the output message

{reactu:🤔 :) :D}
# "🤔", ":)", and ":D" are added to the list of reactions for the input message

Response Attribute:

This block sets the following attribute on the Response object:

  • actions
    • actions["reactions"]: dict[Literal["input", "output"], list[str]] — A dictionary like {"input": [...], "output": [...]} (each key may be missing if it wasn’t used in the script)

Note

This block will only set the provided string(s) in the reactions actions key under the appropriate dictionary key as shown above. Each of the keys may be missing if not used in the script. It is up to the client to implement actual reaction adding behaviour as desired.

class ya_tagscript.blocks.RedirectBlock[source]

Bases: BlockABC

Redirect the script output to a given channel, to the invoking user’s DMs, or set it to be a reply to the invoking message.

If it is used more than once in a script, only the latest redirection target will be retained.

Usage: {redirect(<"dm"|"reply"|channel>)}

Aliases: redirect

Parameter: One of "dm", "reply", or channel (required)

Payload: None

channel represents a way to refer to a text channel (e.g. channel name, mention string, ID, etc).

Note

To avoid breaking scripts due to changing channel names, it is generally recommended to use channel IDs or mention strings to reference channels.

Examples:

{redirect(dm)}
# Signals to redirect the output to the user's DMs

{redirect(reply)}
# Signals that the output should be a reply to the invoking message

{redirect(#general)}
# Signals to redirect the output to the #general channel

{redirect(123)}
# Signals to redirect the output to the channel with the ID 123

Response Attribute:

This block sets the following attribute on the Response object:

  • actions
    • actions["target"]: Literal["dm", "reply"] | str — A string indicating the redirection target

Note

This block will only set the target actions key as shown above. It is up to the client to implement actual redirection behaviour, including what constitutes a valid channel input (a client may choose to only accept IDs and reject channel names, for example).

class ya_tagscript.blocks.SilenceBlock[source]

Bases: BlockABC

Signal to suppress the output of command blocks in this script. This should not affect the normal output of the script.

This block may be placed anywhere in a script.

The block is idempotent, so it only needs to be used once. Additional uses have the same effect of setting the “silent” actions key to True.

There is no way to “unset” this key once a silence block has been used.

Usage: {silent}

Aliases: silent, silence

Parameter: None

Payload: None

Examples:

{silent}
# Signals to suppress the outputs of all command blocks in the script

Response Attribute:

This block sets the following attribute on the Response object:

  • actions
    • actions["silent"]: Literal[True] — Always True if a SilenceBlock was used

Note

This block will only set the silent actions key to True. It is up to the client to implement actual silencing behaviour for command block outputs. A client may also choose to let the block affect normal output but this is not recommended.


Conditional Blocks

class ya_tagscript.blocks.AllBlock[source]

Bases: BlockABC

This block checks that all provided expressions are true.

Multiple boolean expressions in the parameter must be separated by | at “zero-depth”, meaning | cannot be added dynamically. See the examples for clarification.

The payload includes the message the block should output.

To provide outputs for both the success and failure cases, the payload must be split by | at “zero-depth”. The part before the | represents the success case, the part after represents the failure case.

If no | can be found at “zero-depth”, the entire payload represents the success case, with no output being returned for the failure case.

If the string for a given case is empty, no output is returned for it.

Usage: {all(<expression|expression|...>):<message>}

Aliases: all, and

Parameter: expression (required)

Payload: message (required)

Examples:

# note how | is at "zero-depth" for the expressions and the responses
{all({args}>=100|{args}<=1000):You picked {args}.|You must provide a number between 100 and 1000.}
# if {args} is 52
You must provide a number between 100 and 1000.

# if {args} is 282
You picked 282.

{all(1==1|2==1):This is my success case message}
# since these conditions fail and no failure case message is defined, no output
# is produced

{all(1==1|hi==hi):|This is my failure case message}
# since the message is empty before the |, meaning no success case message is
# defined, no output is produced

# If the payload is fully nested, it is considered the success case message
# Here, it is obviously _intended_ to be split by the IfBlock but that does not
# happen due to the "zero-depth" separator requirement in payloads
{=(msgs):Success msg|Failure msg}
{all(true|1==1):{msgs}}
# Success msg|Failure msg
class ya_tagscript.blocks.AnyBlock[source]

Bases: BlockABC

This block checks that at least one of the provided expressions is true.

Multiple boolean expressions in the parameter must be separated by | at “zero-depth”, meaning | cannot be added dynamically. See the examples for clarification.

The payload includes the message the block should output.

To provide outputs for both the success and failure cases, the payload must be split by | at “zero-depth”. The part before the | represents the success case, the part after represents the failure case.

If no | can be found at “zero-depth”, the entire payload represents the success case, with no output being returned for the failure case.

If the string for a given case is empty, no output is returned for it.

Usage: {any(<expression|expression|...>):<message>}

Aliases: any, or

Parameter: expression (required)

Payload: message (required)

Examples:

# note how | is at "zero-depth" for the expressions and the responses
{any({args}==hi|{args}==hello|{args}==heyy):Hello {user}!|How rude.}
# if {args} is hi
Hello username#1234!

# if {args} is what's up!
How rude.

{any(1==2|0>1):This is my success case message}
# since these conditions fail and no failure case message is defined, no output
# is produced

{any(1==1|2<5):|This is my failure case message}
# since the message is empty before the |, meaning no success case message is
# defined, no output is produced

# If the payload is fully nested, it is considered the success case message
# Here, it is obviously _intended_ to be split by the IfBlock but that does not
# happen due to the "zero-depth" separator requirement in payloads
{=(msgs):Success msg|Failure msg}
{any(1==1|abc!=abc):{msgs}}
# Success msg|Failure msg
class ya_tagscript.blocks.IfBlock[source]

Bases: BlockABC

This block checks whether the provided condition is true or not and then returns the appropriate message.

The payload includes the message the block should output.

To provide outputs for both the success and failure cases, the payload must be split by | at “zero-depth”. The part before the | represents the success case, the part after represents the failure case.

If no | can be found at “zero-depth”, the entire payload represents the success case, with no output being returned for the failure case.

If the string for a given case is empty, no output is returned for it.

Usage: {if(<condition>):<message>}

Aliases: if

Parameter: condition (required)

Payload: message (required)

Examples:

{if({args}==63):You guessed it! The number I was thinking of was 63!|Too {if({args}<63):low|high}, try again.}
# if args is 63
You guessed it! The number I was thinking of was 63!

# if {args} is 73
Too high, try again.

# if {args} is 14
Too low, try again.

{if(false):This is my success case message}
# since this condition fails and no failure case message is defined, no output
# is produced

{if(true):|This is my failure case message}
# since the message is empty before the |, meaning no success case message is
# defined, no output is produced

# If the payload is fully nested, it is considered the success case message
# Here, it is obviously _intended_ to be split by the IfBlock but that does not
# happen due to the "zero-depth" separator requirement in payloads
{=(msgs):Success msg|Failure msg}
{if(true):{msgs}}
# Success msg|Failure msg

Supported condition operators:

Operator

Check

Example

Description

==

equality

a==a

value 1 is equal to value 2

!=

inequality

a!=b

value 1 is not equal to value 2

>

greater than

5>3

value 1 is greater than value 2

<

less than

4<8

value 1 is less than value 2

>=

greater than or equality

10>=10

value 1 is greater than or equal to value 2

<=

less than or equality

5<=6

value 1 is less than or equal to value 2

true

constant true

true

always true

false

constant false

false

always false


Discord Blocks

class ya_tagscript.blocks.CooldownBlock[source]

Bases: BlockABC

This block implements cooldowns for running a tag.

The parameter requires two values: rate and per, split by | such that the parameter looks like rate|per. rate specifies the number of times the tag can be used within per seconds.

The payload requires a key value, which is used to store the cooldown. The key should be a unique string. For example, if a channel’s ID is used as the key, the cooldown will apply to that channel. Using the same tag in a different channel will have a separate cooldown with the same rate and per values.

The payload also supports an optional message value, which is displayed when the cooldown is exceeded. If provided, it must be split from the key by | such that the payload is key|message. If no message is provided, a default message is used. The cooldown message supports two placeholders: {key} and {retry_after}.

Usage: {cooldown(<rate>|<per>):<key>[|message]}

Aliases: cooldown

Parameter: rate (required), per (required)

Payload: key (required), message (optional)

Examples:

{cooldown(1|10):{user(id)}}
# If the tag user uses the tag more than once in 10 seconds:
# The bucket for 741074175875088424 has reached its cooldown. Retry in 3.25 seconds.

{cooldown(3|3):{channel(id)}|Slow down! This tag can only be used 3 times per 3 seconds per channel. Try again in **{retry_after}** seconds.}
# If the tag is used more than 3 times in 3 seconds in a channel:
# Slow down! This tag can only be used 3 times per 3 seconds per channel. Try again in **0.74** seconds.
class ya_tagscript.blocks.EmbedBlock[source]

Bases: BlockABC

This block includes an embed in the tag response.

There are two ways to use the embed block: manually inputting the accepted embed attributes or using properly formatted embed JSON from an embed generator.

The JSON method allows complete embed customization (including setting attributes not supported by the manual method here), while the manual method provides control over individual attributes without requiring the entire block to be defined at once.

Manual:

The following embed attributes can be set manually:

  • author (see notes below)

  • title

  • description

  • color

  • url

  • thumbnail

  • image

  • footer (see notes below)

  • field (see notes below)

  • timestamp

Note

Some attributes expect a specially formed payload, these are explained below:

  • author: The payload must be 1, 2, or 3 parts in size, with parts split by |. The name is required, the other attributes are optional. If a name and an icon should be used without providing a website URL, leave the website URL empty but keep the | on either side.

    Valid author formats:

    {embed(author):name}
    {embed(author):name|website url}
    {embed(author):name|website url|icon url}
    # Note how the website url is left empty but the | are kept on either side
    {embed(author):name||icon url}
    
  • footer: The payload must be 1 or 2 parts in size, with parts split by |. The text is required, the icon URL is optional.

    Valid footer formats:

    {embed(footer):text}
    {embed(footer):text|icon URL}
    
  • field: The payload must be 2 or 3 parts in size, with parts split by |. The name and value are required, the inline status is optional. If inline is not set explicitly, it defaults to False.

    Valid field formats:

    {embed(field):name|value}
    {embed(field):name|value|true}
    {embed(field):name|value|false}
    

Changed in version 1.5: The specially formed attributes (author, footer, field) now have a “zero-depth” requirement for the | separating their attributes (see below).

Caution

With the introduction of zero-depth restrictions on the EmbedBlock in v1.5.0, nested payloads are no longer supported. Because both author and footer have valid formats which don’t require | at all (i.e. just name for author or just text for footer), they will treat any payload without | at zero-depth as data for their name or text attribute only.

Incorrect example:

{assign(author_payload):some name|https://website.example}
{assign(footer_payload):some text|https://website.example/icon.png}
{embed(author):{author_payload}}
{embed(footer):{footer_payload}}

This would result in the following Embed attributes:

  • embed.author.name: "some name|https://website.example"

  • embed.author.url: None

  • embed.author.icon_url: None (expected)

  • embed.footer.text: "some text|https://website.example/icon.png"

  • embed.footer.icon_url: None

The correct thing to do is this:

{embed(author):some name|https://website.example}
{embed(footer):some text|https://website.example/icon.png}

This would result in the following correct Embed attributes:

  • embed.author.name: "some name"

  • embed.author.url: "https://website.example"

  • embed.author.icon_url: None (expected)

  • embed.footer.text: "some text"

  • embed.footer.icon_url: "https://website.example/icon.png"

Usage: {embed(<attribute>):<value>}

Aliases: embed

Parameter: attribute (required)

Payload: value (required)

Examples:

{embed(color):#37b2cb}
{embed(title):Rules}
{embed(description):Follow these rules to ensure a good experience in our server!}
{embed(field):Rule 1|Respect everyone you speak to.|false}
{embed(footer):Thanks for reading!|{guild(icon)}}
{embed(timestamp):1681234567}

JSON:

Usage: {embed(<json>)}

Aliases: embed

Parameter: json (required)

Payload: None (ignored if JSON is used)

Examples:

# Note how the JSON sits entirely within the block's parameter section, even
# when split across several lines.
{embed({"title":"Hello!", "description":"This is a test embed."})}
{embed({
    "title":"Here's a random duck!",
    "image":{"url":"https://random-d.uk/api/randomimg"},
    "color":15194415
})}

Both methods can be combined to create an embed in a tag. For example, JSON can be used to create an embed with fields, and the embed title can be set later.

Examples:

{embed({"fields":[{"name":"Field 1","value":"field description","inline":false}]})}
{embed(title):my embed title}

Response Attribute:

This block sets the following attribute on the Response object:

Note

This block only sets the embed actions key as shown above. It is up to the client to actually send the discord.Embed object being constructed.


Flow Blocks

class ya_tagscript.blocks.BreakBlock[source]

Bases: BlockABC

This block forces the tag output to only include the payload of this block if the provided condition evaluates to true. If no payload is provided, the tag output will be empty.

Caution

Unlike the StopBlock, which halts all TagScript processing and returns its message, the BreakBlock continues the processing of subsequent blocks.

This means all subsequent blocks may still result in their side effects (if any). For example, a CommandBlock that follows a triggered BreakBlock will still cause the command to be listed in the "commands" key of the Response’s actions attribute, which could cause erroneous command execution by a consuming client.

Usage: {break(<condition>):[message]}

Aliases: break, short, shortcircuit

Parameter: condition (required)

Payload: message (optional)

Examples:

{break({args}==):You did not provide any input.}
class ya_tagscript.blocks.ShortcutRedirectBlock(shortcut_for: str)[source]

Bases: BlockABC

This block acts as a shortcut to redirect processing to another block.

Specifically, this block behaves as if the number was passed as the parameter to the other block (see examples). The declaration must be a number, any other declaration will be rejected.

Usage: {<number>}

Aliases: N/A

Parameter: None

Payload: None

Examples:

# (Python) With a ShortcutRedirectBlock defined and provided to an interpreter instance as such:
ShortcutRedirectBlock("args")

# (TagScript) this block redirects to the "args" variable which contains "hello world"
{1}
# hello

# (TagScript) this is a shortcut to the functionally identical version:
{args(1)}
# hello
class ya_tagscript.blocks.StopBlock[source]

Bases: BlockABC

This block stops tag processing if the provided parameter evaluates to true.

If a payload is provided and the parameter condition evaluates to True, the payload will be returned as the response message. Otherwise, an empty string will be returned.

Caution

Unlike the BreakBlock, which continues processing, the StopBlock immediately aborts all further processing if its condition evaluates to True by means of raising an internal exception that is caught by the interpreter.

This means no subsequent blocks will be interpreted and none of their side effects will occur. For example, a CommandBlock that comes after a triggered StopBlock will NOT have its commands added to the Response’s actions attribute.

Usage: {stop(<condition>):[message]}

Aliases: stop, halt, error

Parameter: condition (required)

Payload: message (optional)

Examples:

{stop({args}==):You must provide arguments for this tag.}
# Enforces providing arguments for a tag

Limiter Blocks

class ya_tagscript.blocks.BlacklistBlock[source]

Bases: BlockABC

Signals to blacklist specific channels or roles, preventing the tag from being used in the specified channels or by users with the specified roles.

If an invocation should be blocked, the optional response payload can be sent.

Note

The blacklist items can be any strings, regardless of their validity as channel or role identifiers. It is up the client to validate the list of blacklisted items.

This block does not interrupt the interpretation of the tag; subsequent blocks are still executed, and the response output continues to be built.

Usage: {blacklist(<blocked>):[response]}

Aliases: blacklist

Parameter: blocked (required)

Payload: response (optional)

Examples:

{blacklist(Muted)}
# Blacklists the "Muted" channel or  role

{blacklist(#support):This tag is not allowed in #support.}
# Blacklists the #support channel or role with a custom response message

{blacklist(Tag Blacklist, 668713062186090506):You are blacklisted from using tags.}
# Blacklists multiple roles or channels with a custom response message

Response Attribute:

This block sets the following attribute on the Response object:

  • actions
    • actions["blacklist"]: dict[Literal["items", "response"], list[str] | str | None] — A dictionary like {"items": [...], "response": "..."}

      • "items": A list of strings representing channels or roles

      • "response": A response str OR None if no response was provided to the block

Note

This block only adds the blacklist information in the blacklist actions key as shown above. It is the responsibility of the client to implement the actual blacklist blocking system. It is also the client’s responsibility to prevent side effects like commands, reactions, etc. from being executed if the tag execution is blacklisted somehow.

class ya_tagscript.blocks.RequireBlock[source]

Bases: BlockABC

Signals to require specific channels or roles, ensuring the tag can only be used in the specified channels or by users with the specified roles or in the specified channels.

If an invocation should be blocked, the optional response payload can be sent.

Note

The required items can be any strings, regardless of their validity as channel or role identifiers. It is up the client to validate the list of required items.

This block does not interrupt the interpretation of the tag; subsequent blocks are still executed, and the response output continues to be built. If the user does not meet the requirements, an optional response message can be sent.

Usage: {require(<required>):[response]}

Aliases: require, whitelist

Parameter: required (required)

Payload: response (optional)

Examples:

{require(Moderator)}
# Requires the "Moderator" channel or role

{require(#general, #bot-cmds):This tag can only be run in #general and #bot-cmds.}
# Requires the #general and #bot-cmds channels or roles with a custom response message

{require(757425366209134764, 668713062186090506, 737961895356792882):You aren't allowed to use this tag.}
# Requires the specified channel or role IDs with a custom response message

Response Attribute:

This block sets the following attribute on the Response object:

  • actions
    • actions["requires"]: dict[Literal["items", "response"], list[str] | str | None] — A dictionary like {"items": [...], "response": "..."}

      • "items": A list of strings representing channels or roles

      • "response": A response str OR None if no response was provided to the block

Note

This block only adds the requirement information in the requires actions key as shown above. It is the responsibility of the client to implement the actual requirement enforcement system. It is also the client’s responsibility to prevent side effects like commands, reactions, etc. from being executed if the tag execution does not meet the requirements and is therefore blocked.


List Blocks

class ya_tagscript.blocks.CycleBlock[source]

Bases: BlockABC

This block retrieves the element from the payload at the index specified by the parameter, looping around to the beginning of the payload if the index is out of bounds (roughly: index = index % len(payload)).

This block is 0-indexed (index 0 returns the first element) and allows for backwards indexing using negative values.

Caution

The payload is interpreted in its entirety before it is split on tildes (~) and the entry at the provided index is returned. This means any blocks contained in the payload will be interpreted as well.

Usage: {cycle(<number>):<payload>}

Aliases: cycle

Parameter: number (required)

Payload: payload (required)

Examples:

{cycle(1):apple~banana~secret third thing}
# banana
{cycle(-3):apple~banana~secret third thing}
# apple
{cycle(10):apple~banana~secret third thing}
# banana

# (assume {items} = "1st~2nd~3rd")
{cycle(0):{items}}
# 1st

Changed in version 1.1: The block no longer has a “zero-depth” restriction (see Caution above)

class ya_tagscript.blocks.ListBlock[source]

Bases: BlockABC

This block retrieves the element from the payload at the index specified by the parameter. If the index is out of bounds, it returns an empty string.

This block is 0-indexed and allows for backwards indexing using negative values.

Caution

The payload is interpreted in its entirety before it is split on tildes (~) and the entry at the provided index is returned. This means any blocks contained in the payload will be interpreted as well.

Usage: {list(<number>):<payload>}

Aliases: list

Parameter: number (required)

Payload: payload (required)

Examples:

{list(1):apple~banana~secret third thing}
# banana
{list(-2):apple~banana~secret third thing}
# banana
{list(10):apple~banana~secret third thing}
# (empty string)

# (assume {items} = "1st~2nd~3rd")
{list(0):{items}}
# 1st

Changed in version 1.1: The block no longer has a “zero-depth” restriction (see Caution above)


Math Blocks

class ya_tagscript.blocks.MathBlock[source]

Bases: BlockABC

This block evaluates mathematical expressions provided in the payload.

All supported constants and functions are listed below.

The output is always rounded to 15 decimal places, unless one of the decimal-free methods mentioned below is used, in which case no decimal places are returned.

For most operations and functions, if a whole number is returned, the number will still carry a .0 with it (e.g. 1+2 = 3.0). The only functions which will never output trailing decimals like that are:

  • sgn — (only returns -1 for negative numbers, 0 for zero, or 1 for positive numbers)

  • trunc(a) — (Truncates a by throwing away all decimal places, e.g. 4.999 -> 4)

  • round(a) — (with no precision argument, a is rounded to the nearest integer, so 4.7 -> 5)

Note

round(a, n) will always return decimal places, including .0 for precision 0, i.e. round(4, 0) -> 4.0)

Usage: {math:<payload>}

Aliases: math, m, +, calc

Parameter: None

Payload: payload (required)

Examples:

{math:1 + 2 * 3}
# 7.0
{math:PI * 2}
# 6.283185307179586
{math:round(10 / 3, 2)}
# 3.33

Supported Mathematical Expressions:

Expression

Description

Notes

a + b

Addition

a - b

Subtraction

a * b

Multiplication

a / b

Division

a % b

Modulo operation (remainder of a / b)

a ^ b

Exponentiation (a to the power of b)

sin(a)

Sine function

sinh(a)

Hyperbolic sine function

cos(a)

Cosine function

cosh(a)

Hyperbolic Cosine function

tan(a)

Tangens function

tanh(a)

Hyperbolic Tangens function

exp(a)

Exponential function (e^a)

ln(a)

Natural logarithm function (log base e)

log(a)

Logarithmic function (log base 10)

log2(a)

Logarithmic function (log base 2)

sqrt(a)

Square root of a

hypot(a,b)

Hypotenuse of a right triangle with sides a and b

abs(a)

Absolute value of a

sgn(a)

Signum function: -1 if a<0, 0 if a==0, 1 if a>0

no decimals (-1 or 0 or 1)

round(a)

Rounds a to the nearest integer

no decimals

round(a,n)

Rounds a to n decimal places

trunc(a)

Truncates a to its integer part

no decimals

E, e

Euler’s number, rounded to 15 decimal places

2.718281828459045

PI, pi, π

Pi, rounded to 15 decimal places

3.141592653589793

TAU, tau, τ

Tau, rounded to 15 decimal places

6.283185307179586

If you’re curious, here is The Numeric String Parser.

class ya_tagscript.blocks.OrdinalBlock[source]

Bases: BlockABC

Returns the ordinal form of a number, including commas as thousands separators.

If the payload is not a number, the block is rejected.

If a parameter is provided, it must be one of the following:

  • c or comma: Adds commas as thousands separators but no indicator

  • i or indicator: Appends the ordinal indicator (e.g., st for 1st, nd for 2nd) but does not include commas as thousands separators

Usage: {ord(["c"|"comma"|"i"|"indicator"]):<number>}

Aliases: o, ord

Parameter: one of c, comma, i, indicator (optional)

Payload: number (required)

Examples:

{ord:1000}
# Returns: 1,000th

{ord(c):1213123}
# Returns: 1,213,123

{ord(i):2022}
# Returns: 2022nd

Meta Blocks

class ya_tagscript.blocks.CommentBlock[source]

Bases: BlockABC

This block can be used to add comments in the script that are ignored during processing and removed from the output.

Caution

Everything inside this block is ignored, including nested blocks.

Usage: {comment([parameter]):[text]}

Aliases: /, //, comment

Parameter: parameter (ignored)

Payload: text (ignored)

Examples:

{comment:My Comment!}
# outputs nothing

{comment(Something):My Comment!}
# outputs nothing

{comment:{cmd:echo hello world}}{cmd:ping}
# outputs nothing and the "echo" command block will NOT be triggered BUT the
# "ping" command WILL be set correctly because it is not nested inside the
# comment block
class ya_tagscript.blocks.DebugBlock[source]

Bases: BlockABC

This block will output a dictionary of all variables known at the time of processing under the debug key of the extra_kwargs attribute of the Response object.

Separate the variables you want to include or exclude with a comma (,) or a tilde (~). These separations must be consistent (only commas or only tildes) and be located at “zero-depth”, i.e. only separators present before interpretation will be used for splitting..

If no parameter and no payload are provided, all variables will be included. ({debug}, which is equivalent to {debug(exclude):})

If no parameter is provided but a payload exists, only variables included in the payload will be included. ({debug:my_var}, which is equivalent to: {debug(include):my_var})

Note

This should always be placed at the very bottom, it will not include any variables (re-)defined after its location in the script.

Usage: {debug(["i"|"include"|"e"|"exclude"]):<variables>}

Aliases: debug

Parameter: one of i, include, e, exclude

Payload: variables

Examples:

# In the following example, the desired output is "Hello" but instead "Bye" is
returned:

{=(something):Hello/World}
{=(parsed):{something(1)}}
{if({parsed}==Hello):Hello|Bye}
# Bye

# We can investigate by adding the DebugBlock at the end of the script:

{debug}

# This will return a dictionary with all known variable names and their values
# at the time of this block's processing.

# In this example, the dictionary would look like this (Python)
{
    "something": "Hello/World",
    "parsed": "Hello/World",
}

# Now we can see that the definition of parsed is missing a custom delimiter in
# order to split the value on the slash /
# We can fix this:

{=(something):Hello/World}
{=(parsed):{something(1):/}}
{if({parsed}==Hello):Hello|Bye}
# Hello

####

# Note how the variables names are split by zero-depth commas and not in a nested block:
# (assume these exist)
{debug:my_var,another var}

Response Attribute:

This block sets the following attribute on the Response object:

  • extra_kwargs
    • extra_kwargs["debug"]: dict[str, str] — A dictionary with all known variables at the time of interpretation (variable names are mapped to their values)

Note

This block only sets the debug extra_kwargs key as shown above. It is the responsibility of the client to somehow surface this data to the user, if this is desired.


RNG Blocks

class ya_tagscript.blocks.FiftyFiftyBlock[source]

Bases: BlockABC

This block has a 50% change of returning the (interpreted) payload, and 50% chance of returning an empty string.

Usage: {5050:<message>}

Aliases: 5050, 50, ?

Parameter: None

Payload: message (required)

Examples:

I pick {if({5050:.}!=):heads|tails}!
# I pick heads! (50% chance)
class ya_tagscript.blocks.RandomBlock[source]

Bases: BlockABC

This block picks a random item from a list split by commas (,) or tildes (~).

The separators must be consistent (only commas or only tildes).

Note

The payload is interpreted before splitting at the separator, so this block does not have a “zero-depth” requirement.

An optional seed can be provided as the parameter to always choose the same item when using that seed.

Items can be weighted differently by adding a weight and | to the item(s). Not all items need to be weighted. If no weight is provided, the item will be handled as if its weight was 1.

Usage: {random([seed]):<list>}

Aliases: random, rand, #

Parameter: seed (optional)

Payload: list (required)

Examples:

{random:Carl,Harold,Josh} attempts to pick the lock!
# Possible Outputs:
# Josh attempts to pick the lock!
# Carl attempts to pick the lock!
# Harold attempts to pick the lock!

{random:5|Cool,3|Lame}
# 5 to 3 odds of "Cool" vs "Lame"

{random:first,10|second,third,4|fourth}
# 10:4:1:1 odds of "second" vs "fourth" vs "first" vs "third"

{assign(items):hello~hi~good morning}
{assign(seed):123}
{random({seed}):{items}}
# 5:1:1 odds for "good morning" vs "hello" vs "hi"
# but because the is seeded with "123": (Output below line)
# ---
# good morning
class ya_tagscript.blocks.RangeBlock[source]

Bases: BlockABC

This block picks a random number from a range of numbers separated by -.

The number range is inclusive (i.e. [lowest, highest]), so the bounding numbers can be returned as well. Both bounds can be negative.

If the lower bound is larger than the upper bound, the block will return an error message.

Behaviour differs between aliases:

  • range: Returns integers (bounds are truncated to integers)

  • rangef: Returns floating point numbers

An optional seed can be provided as the parameter to always choose the same item when using that seed.

Usage: {range([seed]):<lowest>-<highest>}

Aliases: range, rangef

Parameter: seed (optional)

Payload: lowest-highest (both are numbers) (required)

Examples:

Your lucky number is {range:10-30}!
# Your lucky number is 14!

{=(height):{rangef:5-7}}
I am guessing your height is {height}ft.
# I am guessing your height is 5.3ft.

String Blocks

class ya_tagscript.blocks.CaseBlock[source]

Bases: BlockABC

This block modifies the case of the provided payload.

Behaviour differs between aliases:

  • lower: Converts the payload to lowercase

  • upper: Converts the payload to uppercase

Usage: {lower:<text>} or {upper:<text>}

Aliases: lower, upper

Parameter: None

Payload: text (required)

Examples:

{lower:SCREAMING!}
# screaming!

{upper:I am talking.}
# I AM TALKING.
class ya_tagscript.blocks.JoinBlock[source]

Bases: BlockABC

This block replaces spaces in the payload with the provided separator.

If the parameter is missing, the block will be rejected.

To use this block as a pseudo-concatenation block, include the parentheses with no content between them (see examples below).

Usage: {join(<separator>):<text>}

Aliases: join

Parameter: separator (required; can be empty)

Payload: text (required)

Examples:

{join(.):Dot notation is funky}
# Dot.notation.is.funky

{join():I can masquerade as a concat block}
# Icanmasqueradeasaconcatblock
class ya_tagscript.blocks.PythonBlock[source]

Bases: BlockABC

This block supports string operations like containment, word matching, and positional indexing in the payload.

Behaviour differs between aliases:

  • contains: Checks if the parameter matches any word in the payload, split by whitespace.

  • in: Checks if the parameter exists anywhere in the payload.

  • index: Finds the position of the parameter in the payload, split by whitespace. If the parameter is not found, it returns -1.

Usage: {contains(<string>):<payload>}

Aliases: contains, in, index

Parameter: string (required)

Payload: payload (required)

Examples:

{contains(mute):How does it feel to be muted?}
# false

{contains(muted?):How does it feel to be muted?}
# true

{in(apple pie):banana pie apple pie and other pie}
# true

{in(mute):How does it feel to be muted?}
# true

{in(a):How does it feel to be muted?}
# false

{index(food.):I love to eat food. everyone does.}
# 4

{index(pie):I love to eat food. everyone does.}
# -1

Changed in version 1.3: This block was moved from blocks.conditional to blocks.strings. Users should import blocks by doing from ya_tagscript.blocks import PythonBlock so this change should affect very few users.

class ya_tagscript.blocks.ReplaceBlock[source]

Bases: BlockABC

This block replaces all occurrences of a substring in the payload with another substring.

The substring to replace and its replacement are provided as a comma-separated pair in the parameter. If new is omitted or empty, the substring will be removed.

The old substring is case-sensitive, e.g. A is not replaced if old is a, etc.

Usage: {replace(<old>,<new>):<text>}

Aliases: replace

Parameter: old OR old,new (required; new can be empty)

Payload: text (required)

Examples:

{replace(o,i):welcome to the server}
# welcime ti the server

{replace(1,6):{args}}
# if {args} is 1234567
# 6234567

{replace(, ):Test}
# T e s t

{replace(an):An amazing Canadian banana}
# An amazing Cadi ba
class ya_tagscript.blocks.SubstringBlock[source]

Bases: BlockABC

This block extracts a substring from the payload based on the parameter.

The parameter specifies the start and end indices of the substring, separated by a hyphen (-). The starting index is inclusive and the ending index is exclusive.

If only one index is provided, the rest of the payload is returned starting from this index.

This block is 0-indexed. Negative indices are supported.

Note

The indices behave like normal Python slices. That means an index that is too large will return an empty string and an index that is too negative will return the entire string (see examples below).

Usage: {substring(<start>-<end>):<text>}

Aliases: substring, substr

Parameter: <start> OR <start>-<end> (both numbers) (required)

Payload: text (required)

Examples:

{substring(1-4):testing}
# est

{substring(6):hello world}
# world

{substring(100):hello world}
# (an empty string is returned)

{substring(-100):hello world}
# hello world
class ya_tagscript.blocks.URLDecodeBlock[source]

Bases: BlockABC

This block decodes a URL-encoded string back into its original format.

The payload is the URL-encoded string to be decoded.

The parameter determines the decoding style: if the parameter is +, both %20 and + are decoded as a space; otherwise, only %20 is decoded as a space. Other character sequences are decoded as normal in either case.

Usage: {urldecode(<parameter>):<text>}

Aliases: urldecode

Parameter: + (optional) (all other values are ignored)

Payload: text (required)

Examples:

{urldecode:hello%20world}
# hello world

{urldecode(+):Hello+there.+General+Kenobi.}
# Hello there. General Kenobi.

{urldecode(+):this%20is+a%20combined+test}
# this is a combined test

{urldecode:this+will+keep+the+plus+signs}
# this+will+keep+the+plus+signs
class ya_tagscript.blocks.URLEncodeBlock[source]

Bases: BlockABC

This block encodes a string into a URL-safe format.

The payload is the string to be encoded.

The parameter determines the encoding style: if the parameter is +, spaces are encoded as +; otherwise, spaces are encoded as %20.

Usage: {urlencode(<parameter>):<text>}

Aliases: urlencode

Parameter: + (optional) (all other values are ignored)

Payload: text (required)

Examples:

{urlencode:covid-19 sucks}
# covid-19%20sucks

{urlencode(+):im stuck at home writing docs}
# im+stuck+at+home+writing+docs

# the following tagscript can be used to search up tag blocks
# assume {args} = "command block"
<https://ya-tagscript.readthedocs.io/en/latest/search.html?q={urlencode(+):{args}}&check_keywords=yes&area=default>
# <https://ya-tagscript.readthedocs.io/en/latest/search.html?q=command+block&check_keywords=yes&area=default>

Time Blocks

class ya_tagscript.blocks.StrfBlock[source]

Bases: BlockABC

This block formats dates and times using the provided format string.

Behaviour differs between aliases:

  • unix: Returns the current time as a seconds-resolution integer timestamp

  • strf: Returns the current time (or time given in the parameter) formatted according to the format string in the payload

The payload is the format string to be used with strftime().

See also

Python’s datetime documentation

strftime() Format Codes

Note

The unix alias does not take any format string payload and always returns the current Unix Epoch timestamp in seconds-resolution (i.e. seconds since 1970-01-01 at 00:00:00 UTC).

The parameter can be a timestamp or an ISO 8601 string. Many other common formats are supported as well but no exhaustive list can be provided. When in doubt, try it and see.

If no parameter is provided, the block defaults to the current time.

Usage: {strf(<parameter>):<format>}

Aliases: strf, unix

Parameter: timestamp or datetime string (optional)

Payload: format (required for strf)

Examples:

{strf:%Y-%m-%d}
# 2000-01-01

{strf({user(timestamp)}):%c}
# Sat Jan  1 00:00:00 2000

{strf(1735689600):%A %d, %B %Y}
# Wednesday 01, January 2025

{strf(2025-01-01T01:02:00.999):%H:%M %d-%B-%Y}
# 01:02 01-January-2025

{unix}
# 946684800
# (this is 2000-01-01T00:00:00+00:00)
class ya_tagscript.blocks.TimedeltaBlock(time_humanize_fn: Callable[[datetime, datetime], str] | None = None)[source]

Bases: BlockABC

This block calculates the difference between two datetime values and formats it into a human-readable string.

The payload provides the “target” time, i.e. the time for which to calculate the distance from the “origin” time.

The optional parameter provides the “origin” time, i.e. the time to use as a starting point for the calculation. When no parameter is provided, this defaults to the current date and time.

Whether a date & time is provided via the parameter or payload will influence the direction of the calculation (i.e. whether the time difference is considered “in the past” or “in the future”)

The block supports ISO 8601 strings, timestamps, and other common datetime formats. If only a time is provided, it is assumed to be for the current UTC date.

Formats may be mixed between the parameter and the payload.

Usage: {timedelta(<origin datetime>):<target datetime>}

Aliases: timedelta, td

Parameter: origin datetime (optional)

Payload: target datetime (required)

Examples:

# All examples assume the default humanize function is used

{timedelta(2025-01-01T00:00:00):30.01.2024}
# 11 months and 2 days ago

{timedelta:2024-08-31 00:00:00.000000+00:00}
# 4 years, 7 months, and 30 days
# (if the current UTC time was 2020-01-01T00:00:00)

{timedelta(1735689600):946694800}
# 24 years, 11 months, and 30 days ago
# (1735689600 = Wed, 01 Jan 2025 00:00:00 +0000)
# ( 946694800 = Sat, 01 Jan 2000 02:46:40 +0000)

{timedelta(19:30):21:00}
# 1 hour and 30 minutes
__init__(time_humanize_fn: Callable[[datetime, datetime], str] | None = None) None[source]
Parameters:

time_humanize_fn (Callable[[datetime, datetime], str] | None) –

A function that takes two datetime objects and returns a str expressing the distance between the two.

If set to None (the default), an implementation using the dateutil package and its relativedelta is used which returns the three largest nonzero units of time in order. Example outputs may be:

  • 1 year

  • 4 months and 43 seconds

  • 9 days, 1 hour, and 8 seconds


Variable Blocks

class ya_tagscript.blocks.AssignmentBlock[source]

Bases: BlockABC

This block assigns a value to a variable within the context of the script.

The payload represents the value to be assigned, while the parameter specifies the variable name. The variable can then be referenced elsewhere in the script.

Usage: {assign(<variable name>):<value>}

Aliases: =, assign, let, var

Parameter: variable name (required)

Payload: value (required)

Examples:

{assign(prefix):!}
The prefix here is `{prefix}`.
# The prefix here is `!`.

{assign(day):Monday}
{if({day}==Wednesday):It's Wednesday my dudes!|The day is {day}.}
# The day is Monday.
class ya_tagscript.blocks.LooseVariableGetterBlock[source]

Bases: BlockABC

This block attempts to fetch the value of a variable declared in the script. If the variable exists, its value is returned; otherwise, the block is rejected and not interpreted at all.

Note

In contrast to the StrictVariableGetterBlock, this block checks for the existence of the variable only during processing. The earlier call to LooseVariableGetterBlock.will_accept() always returns True.

Usage: {<variable name>}

Aliases: N/A

Parameter: None

Payload: None

Examples:

# Variables can be assigned with the AssignmentBlock
# or supplied to the interpreter via the seed_variables kwarg
{assign(user_name):Carl}

{user_name}
# Carl

{non_existent_variable}
# This block is rejected because the variable doesn't exist (Output below line):
# ---
# {non_existent_variable}

See also

Retrieving partial substrings with parameters

How to retrieve only parts of a string variable (part of the StringAdapter documentation).

will_accept(ctx: Context) Literal[True][source]

Will always return True since the block only checks for variable existence during processing.

Parameters:

ctx (Context) – The Context to check for acceptability (the block ignores this parameter)

Returns:

Always returns True because preconditions are only checked during processing.

Return type:

Literal[True]

class ya_tagscript.blocks.StrictVariableGetterBlock[source]

Bases: BlockABC

This block attempts to fetch the value of a variable declared in the script. If the variable exists, its value is returned; otherwise, the block is rejected and not interpreted at all.

Note

In contrast to the LooseVariableGetterBlock, this block checks for the existence of the variable during the earlier StrictVariableGetterBlock.will_accept() phase, rejecting the block early if the variable does not exist already.

Usage: {<variable name>}

Aliases: N/A

Parameter: None

Payload: None

Examples:

# Variables can be assigned with the AssignmentBlock
# or supplied to the interpreter via the seed_variables kwarg
{assign(user_name):Carl}

{user_name}
# Carl

{non_existent_variable}
# This block is rejected because the variable doesn't exist (Output below line):
# ---
# {non_existent_variable}

See also

Retrieving partial substrings with parameters

How to retrieve only parts of a string variable (part of the StringAdapter documentation).

will_accept(ctx: Context) bool[source]

Checks whether the declaration, when interpreted, exists as a variable name.

Parameters:

ctx (Context) – The current Context to check for acceptability

Returns:

Whether this block can process the provided Context

Return type:

bool