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.

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.

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.

// Rule for Bold textt.FromTo("[b]{text}[/b]", "**{text}**");// Rule for Italic textt.FromTo("[i]{text}[/i]", "*{text}*");// Rule for Underline (converts to HTML)t.FromTo("[u]{text}[/u]", "<u>{text}</u>");

The URL Tag (with an attribute)

This rule is slightly more complex as it needs to capture the URL from the tag's attribute.

// 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.

t.FromTo("[quote]{content}[/quote]", "> {content}");

Step 3: Putting It All Together

The 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.
				
					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.