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.

Project: Implementing a BBCode to Markdown Converter

Product: 

Class: 

A step-by-step guide to building a simple BBCode to Markdown converter using the declarative rules of the uCalc Transformer.

Remarks

💡 Project: Building a BBCode to Markdown Converter

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.

The Goal

We'll create a transformer that can convert common BBCode tags into Markdown:

BBCodeMarkdown
[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.

⚖️ Why uCalc Instead of Regex?

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.


Step 1: Setting Up the Transformer

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;

Step 2: Defining the Rules

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.

Simple Inline Tags (Bold, Italic, Underline)

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.

Examples

A complete, single-pass transformer that converts common BBCode tags (bold, italic, underline, URL, and quote) to their Markdown equivalents.

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']'", "<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));
}
				
			
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;
   }
}
				
			
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
				
			
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.