From 66acc7f217f6187357be25731085af2df432706d Mon Sep 17 00:00:00 2001 From: Jari Sundell Date: Tue, 16 Jun 2026 16:20:30 +0900 Subject: [PATCH] Updated Parentheses and Braces Syntax (markdown) --- Parentheses-and-Braces-Syntax.md | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/Parentheses-and-Braces-Syntax.md b/Parentheses-and-Braces-Syntax.md index f014436..638d303 100644 --- a/Parentheses-and-Braces-Syntax.md +++ b/Parentheses-and-Braces-Syntax.md @@ -1,10 +1,10 @@ # Scripting: Parentheses and Braces Syntax -Configuration commands use parentheses `(...)` and braces `{...}` to bypass string wrapper parsing, eliminating outer quotation marks and backslash escaping. +Configuration commands use parentheses `(...)` and braces `{...}` to create function objects (cmd + args list) and list objects. -## At a Glance +## Syntax * **`(...)`** instantiates an internal `torrent::Object` with a function flag for runtime evaluation and command execution. * **`((...))`** escapes the function object when passing it directly as an argument to commands like `method.set_key`, `schedule`, and event triggers. @@ -17,16 +17,20 @@ Configuration commands use parentheses `(...)` and braces `{...}` to bypass stri ### Behavior -* Automatically generates a key/args dictionary structure (`torrent::Object`). -* Resolves method strings and tracks down variables on the fly. -* Directs sequential logic via conditional keywords (`branch`, `if`). + * Automatically generates a key/args dictionary object with the function flag. + * Expands commands in arguments that are not double-parenthesis: `(cmd, arg1, ((...)), arg2)` + * The parser may expands arguments (or turn `((...))` into `(...)`), depending on context. ### Detailed Explanation -The configuration engine evaluates everything inside a single parenthesis block `(cmd, ...)` as a dynamic instruction. Instead of interpreting the contents as raw text strings, rTorrent flags the block internally as an executable unit. +A single-parenthesis block `(cmd, ...)` is a function object. -When configuring hooks or automated tasks, you often need to pass functions as arguments to other commands (like `method.set_key` or `schedule`). Writing these loops as double parentheses `((...))` escapes the inner function block. This signals to the root parser that the commas belong to the argument list of the nested function, rather than splitting the parent command prematurely. This mechanism is the preferred and clean way to pass functional logic without wrapping text in quotation marks. +A double-parenthesis block `((cmd, ...))` is a nested function object, and turns into a function object when passed as argument to e.g. `scheduler`. + +A bracket+parenthesis block `{(cmd, ...), ...}` is a list of function objects, and does not expand function objects in arguments. + +The parser splits any non-quoted string by commas, transforming elements into distinct objects of various types. For functions, this is a `dict-key + dict-value(list)` marked with the `function` flag. ### Examples @@ -35,8 +39,11 @@ When configuring hooks or automated tasks, you often need to pass functions as a # Depth-2 double parentheses escape the method, bypassing outer quotes entirely method.set_key = event.download.finished, clear_label, ((d.custom.set, label, "")) -# Expression checks status and falls back to true condition +# Calls d.custom.set if incomplete. (if, (d.custom, incomplete), (d.custom.set, incomplete, 0)) + +# Returns either a string "incomplete" or "foo-bar" and passes it to print. +print=(if, (d.custom, incomplete), incomplete, (cat, foo-, bar)) ``` @@ -70,7 +77,7 @@ Combining braces and parentheses into the **`{(...)}`** syntax provides an elega ### Old Style (Legacy String & Quote Escaping) -The legacy configuration relies heavily on string wrapper passing. This forces nested arguments into multiple layers of outer quotation marks and escaped inner quotes (`\"`), which are error-prone and harder to parse: +The legacy configuration relies heavily on string wrapper passing. This forces nested arguments into multiple layers of outer quotation marks and escaped inner quotes (`\\"`), which are error-prone and harder to parse: ```ini schedule = foo, 0, 10, "load.start=~/Download/watch_old/*.torrent,\"d.custom.set=incomplete,1\"" @@ -82,7 +89,7 @@ method.set_key=event.download.erased, rm_torrent_files,"branch=d.custom=incomple ### New Style (Pure Parenthesis Tree / Escaped Functions) -The preferred, modern alternative drops all quotation marks entirely. By leveraging parenthetical evaluation arrays, function blocks are safely escaped as deep arguments. Note that variables must also be cleanly escaped as functional blocks (e.g., `((d.base_path))`) inside the deepest execution layers: +The preferred, modern alternative drops all quotation marks entirely. By leveraging parenthetical evaluation arrays, function blocks are safely escaped as deep arguments. Note that variables must also be cleanly escaped as functional blocks (e.g., `((d.base_path))`) inside the deepest execution layers to protect their argument commas from higher parser steps: ```ini schedule = foo, 0, 10, ((load.start, ~/Download/watch_old/*.torrent, ((d.custom.set, incomplete, 1)) )) @@ -92,7 +99,7 @@ method.set_key = event.download.erased, rm_torrent_files, ((branch, ((d.custom, ``` -### Preferred Approach: Function List Containment `{(...)}` +### Alternative Approach: Function List `{(...)}` Instead of handling complex multi-layered parenthesis escapes for inner commands and paths, you can pass the logic block as a **list containing a function**. This acts as a robust literal shield, completely removing the need to escape the deepest arguments or variables (allowing you to use a flat `(d.base_path)` call cleanly):