uCalc API Version: 5.7.0-preview.1 Released: 7/30/2026
Warning
uCalc API Preview Release Notice:This preview documentation describes the intended behavior of the API. It is not fully accurate or complete.The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.Use of the preview version in your production code is not recommended.
A step-by-step guide to building a simple BBCode to Markdown converter using the declarative rules of the uCalc Transformer.
This project will guide you through building a simple but functional converter for BBCode, a lightweight markup language commonly used in forums and message boards. We'll transform BBCode syntax into its more modern equivalent, Markdown, using the declarative power of the uCalc.Transformer.
This is a perfect real-world example of a "transpiler"—a tool that converts source code from one language to another. It showcases how uCalc's token-aware patterns can handle structured text safely and readably.
We'll create a transformer that can convert common BBCode tags into Markdown:
| BBCode | Markdown |
|---|---|
[b]bold text[/b] | **bold text** |
[i]italic text[/i] | *italic text* |
[u]underline text[/u] | <u>underline text</u> |
[url=http://example.com]link[/url] | [link](http://example.com) |
[quote]quoted text[/quote] | > quoted text |
Note: Since Markdown has no standard syntax for underlining, we'll convert [u] tags to their HTML equivalent.
While you could attempt this with a series of Regex.Replace calls, you would quickly run into problems, especially with nested tags. A simple regex for [b]...[/b] would greedily match from the first [b] to the last [/b] in a string like [b]bold[/b] and [b]more bold[/b], breaking the structure.
uCalc's Transformer avoids this by being token-aware. It understands the structure of the tags and can handle nested content correctly and safely.
First, we need a Transformer instance. Since BBCode content can span multiple lines, we must disable StatementSensitive on the DefaultRuleSet. This tells the transformer to treat newlines as simple whitespace, allowing variable captures like {text} to span multiple lines.
csharp
var t = new uCalc.Transformer();
t.DefaultRuleSet.StatementSensitive = false;
Next, we'll define our conversion logic using FromTo() rules. The key is to use a pattern that captures the tag name and content, using backreferences to ensure the opening and closing tags match.
The pattern [{tag}]{content}[/{tag}] is perfect for this. The {tag} variable captures the tag name (like b or i), and the backreference [/{tag}] ensures it only matches the corresponding closing tag.
These rules are straightforward find-and-replace operations.
### The URL Tag (with an attribute)This rule is slightly more complex as it needs to capture the URL from the tag's attribute.```csharp
// Pattern captures the URL into {href} and the link text into {text}
t.FromTo("[url={href}]{text}[/url]", "[{text}]({href})");
```### The Quote Tag (Block-level)This rule converts the `[quote]` block into a Markdown blockquote.```csharp
t.FromTo("[quote]{content}[/quote]", "> {content}");
```## Step 3: Putting It All TogetherThe complete example below combines these rules to process a sample BBCode document. The transformer will correctly handle all the tags in a single, efficient pass.ID: 1434
using uCalcSoftware;
var uc = new uCalc();
// 1. Setup the Transformer
using (var t = new uCalc.Transformer()) {
// Allow patterns to match across multiple lines
t.DefaultRuleSet.StatementSensitive = false;
// 2. Define the conversion rules
// Simple inline tags
t.FromTo("'['b']'{text}'['/b']'", "**{text}**");
t.FromTo("'['i']'{text}'['/i']'", "*{text}*");
t.FromTo("'['u']'{text}'['/u']'", "{text}");
// URL tag with attribute
t.FromTo("'['url={href}']'{text}'['/url']'", "[{text}]({href})");
// Quote block tag
t.FromTo("'['quote']'{content}'['/quote']'", "> {content}");
// 3. Define the input BBCode text
var bbCode = """
Hello, this is a test of the converter.
This text is [b]bold[/b] and this is [i]italic[/i].
You can also [u]underline[/u] text.
Here is a link to the uCalc website: [url=https://www.ucalc.com]uCalc[/url].
[quote]This is a block of quoted text.
It can span multiple lines.[/quote]
""";
// 4. Run the transformation and print the result
Console.WriteLine(t.Transform(bbCode));
}
Hello, this is a test of the converter.
This text is **bold** and this is *italic*.
You can also <u>underline</u> text.
Here is a link to the uCalc website: [uCalc](https://www.ucalc.com).
> This is a block of quoted text.
It can span multiple lines.
using uCalcSoftware; var uc = new uCalc(); // 1. Setup the Transformer using (var t = new uCalc.Transformer()) { // Allow patterns to match across multiple lines t.DefaultRuleSet.StatementSensitive = false; // 2. Define the conversion rules // Simple inline tags t.FromTo("'['b']'{text}'['/b']'", "**{text}**"); t.FromTo("'['i']'{text}'['/i']'", "*{text}*"); t.FromTo("'['u']'{text}'['/u']'", "<u>{text}</u>"); // URL tag with attribute t.FromTo("'['url={href}']'{text}'['/url']'", "[{text}]({href})"); // Quote block tag t.FromTo("'['quote']'{content}'['/quote']'", "> {content}"); // 3. Define the input BBCode text var bbCode = """ Hello, this is a test of the converter. This text is [b]bold[/b] and this is [i]italic[/i]. You can also [u]underline[/u] text. Here is a link to the uCalc website: [url=https://www.ucalc.com]uCalc[/url]. [quote]This is a block of quoted text. It can span multiple lines.[/quote] """; // 4. Run the transformation and print the result Console.WriteLine(t.Transform(bbCode)); }
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
// 1. Setup the Transformer
{
uCalc::Transformer t;
t.Owned(); // Causes t to be released when it goes out of scope
// Allow patterns to match across multiple lines
t.DefaultRuleSet().StatementSensitive(false);
// 2. Define the conversion rules
// Simple inline tags
t.FromTo("'['b']'{text}'['/b']'", "**{text}**");
t.FromTo("'['i']'{text}'['/i']'", "*{text}*");
t.FromTo("'['u']'{text}'['/u']'", "{text}");
// URL tag with attribute
t.FromTo("'['url={href}']'{text}'['/url']'", "[{text}]({href})");
// Quote block tag
t.FromTo("'['quote']'{content}'['/quote']'", "> {content}");
// 3. Define the input BBCode text
auto bbCode = R"(
Hello, this is a test of the converter.
This text is [b]bold[/b] and this is [i]italic[/i].
You can also [u]underline[/u] text.
Here is a link to the uCalc website: [url=https://www.ucalc.com]uCalc[/url].
[quote]This is a block of quoted text.
It can span multiple lines.[/quote]
)";
// 4. Run the transformation and print the result
cout << t.Transform(bbCode) << endl;
}
}
Hello, this is a test of the converter.
This text is **bold** and this is *italic*.
You can also <u>underline</u> text.
Here is a link to the uCalc website: [uCalc](https://www.ucalc.com).
> This is a block of quoted text.
It can span multiple lines.
#include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; // 1. Setup the Transformer { uCalc::Transformer t; t.Owned(); // Causes t to be released when it goes out of scope // Allow patterns to match across multiple lines t.DefaultRuleSet().StatementSensitive(false); // 2. Define the conversion rules // Simple inline tags t.FromTo("'['b']'{text}'['/b']'", "**{text}**"); t.FromTo("'['i']'{text}'['/i']'", "*{text}*"); t.FromTo("'['u']'{text}'['/u']'", "<u>{text}</u>"); // URL tag with attribute t.FromTo("'['url={href}']'{text}'['/url']'", "[{text}]({href})"); // Quote block tag t.FromTo("'['quote']'{content}'['/quote']'", "> {content}"); // 3. Define the input BBCode text auto bbCode = R"( Hello, this is a test of the converter. This text is [b]bold[/b] and this is [i]italic[/i]. You can also [u]underline[/u] text. Here is a link to the uCalc website: [url=https://www.ucalc.com]uCalc[/url]. [quote]This is a block of quoted text. It can span multiple lines.[/quote] )"; // 4. Run the transformation and print the result cout << t.Transform(bbCode) << endl; } }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
'// 1. Setup the Transformer
Using t As New uCalc.Transformer()
'// Allow patterns to match across multiple lines
t.DefaultRuleSet.StatementSensitive = false
'// 2. Define the conversion rules
'// Simple inline tags
t.FromTo("'['b']'{text}'['/b']'", "**{text}**")
t.FromTo("'['i']'{text}'['/i']'", "*{text}*")
t.FromTo("'['u']'{text}'['/u']'", "{text}")
'// URL tag with attribute
t.FromTo("'['url={href}']'{text}'['/url']'", "[{text}]({href})")
'// Quote block tag
t.FromTo("'['quote']'{content}'['/quote']'", "> {content}")
'// 3. Define the input BBCode text
Dim bbCode = "
Hello, this is a test of the converter.
This text is [b]bold[/b] and this is [i]italic[/i].
You can also [u]underline[/u] text.
Here is a link to the uCalc website: [url=https://www.ucalc.com]uCalc[/url].
[quote]This is a block of quoted text.
It can span multiple lines.[/quote]
"
'// 4. Run the transformation and print the result
Console.WriteLine(t.Transform(bbCode))
End Using
End Sub
End Module
Hello, this is a test of the converter.
This text is **bold** and this is *italic*.
You can also <u>underline</u> text.
Here is a link to the uCalc website: [uCalc](https://www.ucalc.com).
> This is a block of quoted text.
It can span multiple lines.
Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() '// 1. Setup the Transformer Using t As New uCalc.Transformer() '// Allow patterns to match across multiple lines t.DefaultRuleSet.StatementSensitive = false '// 2. Define the conversion rules '// Simple inline tags t.FromTo("'['b']'{text}'['/b']'", "**{text}**") t.FromTo("'['i']'{text}'['/i']'", "*{text}*") t.FromTo("'['u']'{text}'['/u']'", "<u>{text}</u>") '// URL tag with attribute t.FromTo("'['url={href}']'{text}'['/url']'", "[{text}]({href})") '// Quote block tag t.FromTo("'['quote']'{content}'['/quote']'", "> {content}") '// 3. Define the input BBCode text Dim bbCode = " Hello, this is a test of the converter. This text is [b]bold[/b] and this is [i]italic[/i]. You can also [u]underline[/u] text. Here is a link to the uCalc website: [url=https://www.ucalc.com]uCalc[/url]. [quote]This is a block of quoted text. It can span multiple lines.[/quote] " '// 4. Run the transformation and print the result Console.WriteLine(t.Transform(bbCode)) End Using End Sub End Module