uCalc API Version: 2.1.3-preview.2 Released: 6/16/2026
Warning
uCalc API Preview Release Notice:The documentation describes the intended behavior of the API. The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.
{@Stop}
Product:
Class:
Remarks
Description: A structural directive that truncates the captured match segment at a specific point within the pattern.
The {@Stop} directive provides surgical control over what text is considered the "match" (the {@Self} keyword) versus what text is simply used as "context" for the match.
Capture Truncation
In a standard pattern, the entire sequence of tokens that satisfy the pattern is captured into the replacement buffer. When {@Stop} is inserted:
- The engine continues matching the rest of the pattern to ensure the rule is valid.
- However, the recorded match (
{@Self}) and the replacement boundary are truncated at the point where{@Stop}appeared.
Contextual Matching (Lookahead Behavior)
{@Stop} is effectively used to create a "positive lookahead" without the complexity of standard regex syntax. It allows you to say: "Match X, but only if it is followed by Y. Do not include Y in the replacement."
- Without Stop:
{@Alpha} ;→ Replaces both the word and the semicolon. - With Stop:
{@Alpha} {@Stop} ;→ Replaces only the word, but only if a semicolon follows it.
Examples
1. Succinct (Quick Start: Trailing Punctuation)
Identifying a word that ends with a colon, but replacing only the word itself while leaving the colon in the document.
New(uCalc::Transformer, t)// Match a word, stop, then validate a colon existst.FromTo("{@Alpha} {@Stop} :", "WORD({@Self})")wl(t.Transform("Title: Content"))[Expected Output]WORD(Title): Content
2. Practical (Real World: Assignment Transpiler)
Capturing a variable name for transformation, but only if it is followed by an assignment operator (=). The operator itself should remain untouched for the next rule to process.
New(uCalc::Transformer, t)// Capture variable 'v', stop, then ensure '=' followst.FromTo("{@Alpha:v} {@Stop} =", "VAR_{v}")wl(t.Transform("x = 10"))[Expected Output]VAR_x = 10
3. Internal Test (Parameter Impact)
Verifying how {@Stop} affects the {@Param} indices. Even though the capture stops, the tokens after {@Stop} are still indexed for the duration of the pattern check.
New(uCalc::Transformer, t)// Index 1: Alpha, Stop, Index 2: Numbert.FromTo("{@Alpha} {@Stop} {@Number}", "NAME:{@Param:1} NEXT_TYPE:{@Param:2}")wl(t.Transform("User 123"))[Expected Output]NAME:User NEXT_TYPE:123(Note: The '123' in the source text is replaced because it was part of the pattern logic, even if it was after the 'Stop' command).
Strategy & Critique
- Surgical Replacement:
{@Stop}is the best tool for "context-sensitive" editing where you want to avoid accidentally consuming neighboring tokens that other rules might need to see later. - Performance: It is more efficient than capturing the context into a variable and then re-inserting it in the replacement string (e.g.,
FromTo("X Y", "X' Y")), as the engine doesn't have to perform the extra string concatenation for the context part. - Critique: The name
{@Stop}is highly semantic. It clearly indicates where the "replacement action" stops, even if the "matching logic" continues. - See Also: Refer to Topic 787 (
{@Self}) to see how{@Stop}determines the content of the match reference.
Examples
{@Stop}
using uCalcSoftware;
var uc = new uCalc();
var t = uc.NewTransformer();
// without {@Stop} "end" wouldn't be a match
t.FromTo("StopAt {abc} {@Stop} end", "<{abc}>");
t.FromTo("end", "[The End]");
Console.WriteLine(t.Transform("StopAt a b c end"));
<a b c> [The End] using uCalcSoftware; var uc = new uCalc(); var t = uc.NewTransformer(); // without {@Stop} "end" wouldn't be a match t.FromTo("StopAt {abc} {@Stop} end", "<{abc}>"); t.FromTo("end", "[The End]"); Console.WriteLine(t.Transform("StopAt a b c end"));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto t = uc.NewTransformer();
// without {@Stop} "end" wouldn't be a match
t.FromTo("StopAt {abc} {@Stop} end", "<{abc}>");
t.FromTo("end", "[The End]");
cout << t.Transform("StopAt a b c end") << endl;
}
<a b c> [The End] #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto t = uc.NewTransformer(); // without {@Stop} "end" wouldn't be a match t.FromTo("StopAt {abc} {@Stop} end", "<{abc}>"); t.FromTo("end", "[The End]"); cout << t.Transform("StopAt a b c end") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t = uc.NewTransformer()
'// without {@Stop} "end" wouldn't be a match
t.FromTo("StopAt {abc} {@Stop} end", "<{abc}>")
t.FromTo("end", "[The End]")
Console.WriteLine(t.Transform("StopAt a b c end"))
End Sub
End Module
<a b c> [The End] Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t = uc.NewTransformer() '// without {@Stop} "end" wouldn't be a match t.FromTo("StopAt {abc} {@Stop} end", "<{abc}>") t.FromTo("end", "[The End]") Console.WriteLine(t.Transform("StopAt a b c end")) End Sub End Module