Sep 232011
 

I’m working on a Silverlight project, where I wanted to enable my users to send private messages to each other, while enjoying the features of the RichTextBox. I also wanted to implement a search feature, so that my users could find their messages easily.

It turns out, that the only way, that I could easily get a serialized string out of the RichTextBox, was to use the RichTextBox.Xaml property. I created a test Silverlight project, and watched how the generated Xaml looked like:


As you can see, the generated Xaml code is very bloated. I intend to save all the private messages in a database, so that the database can perform search queries.

But saving the raw Xaml code wouldn’t be a very good solution, the entire messaging system would be taking much more space than was actually needed. So I came up with the idea to transform that Xaml code into the well known BB code, which is a very compact way of formatting text and is widely spread over the internet.

First I searched for existing solutions, with little success. Many solutions depend on third party RichTextBoxes, some of them aren’t free, and some other people have already created a one-way BBCode to Xaml Parser. But I needed a two-way conversion between BBCode and Xaml, which leads to the most beloved:

Do it yourself.

So while seeing how the RichTextBox generated Xaml, I quickly realized that it wouldn’t be an easy and clean job, because of several reasons:

  1. The standard way of encoding a newline (by pressing Return) is to create a new paragraph tag:
    <Paragraph><Run>This is some</Run></Paragraph>
    <Paragraph><Run>multiline test.</Run></Paragraph>
  2. Each time a new format for the text started, the current run tag was closed and a new one was opened, with the entire formatting information, regardless of the previous format:
    <Run FontWeight="Bold">This is some bold </Run>
    <Run FontWeight="Bold" FontStyle="Italic">and italic text</Run>
    
  3. Hyperlinks don’t support line breaks out of the box; pressing the Return key while having the caret inside of a hyperlink in the RichEditBox didn’t do anything.

So after thinking it over several times, I decided that if I really wanted to generate BB-Code as everyone knows it, I had to keep track of the open BB-Code tags, and if the text had a completely new format, I needed to close them in reverse order, just like in html, and open new tags. Since I was rolling up my own system, and my main goal was to create a compact, search friendly serialization of rich formatted text, I decided to disregard the context-sensitive nature of existing BB-code. Thus I developed a new way of serializing rich-formatted text, which is fully BB-Code compatible. I’ll call it eBB (e for easy). With eBB you can no longer think of the code as some sort of tag-tree, instead you must think of it as a state machine. When a eBB tag opens, it means that from that moment on in the text that state is active. When a tag closes, that state becomes inactive. This also implies that tags don’t have to be closed in the end.

What I also needed to change is the way that the RichTextBox interpreted the Return key press. I wanted it to genereate line breaks instead of new paragraphs. So I overloaded the KeyDown event of my RichTextBox:

private void rtbOriginal_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Enter)
    {
        rtbOriginal.Selection.Insert(new LineBreak());
        e.Handled = true;
    }
}

Converting Xaml to eBB is now a piece of cake: Each time a Run or Hyperlink tag opens, I compare the new format to the old format, and open or close an eBB tag whenever I need to. I currently only support these tags:

  • [color=#FFFFFFFF]text[/color]
  • [url=http://example.com]text[/url]
  • [size=14]bigger text[/size]
  • [b]bold[/b]
  • [i]italic[/i]
  • [u]underline[/u]

Suppose I wanted to encode this line of text, the eBB-code would look this way:

A line with rich-formatted text and link

A line [b]with rich-[i]formatted[/i] text [url=http://example.com]and[/b] link

Notice that I don’t necessarily need to close the url tag, and that I close the bold tag directly after having opened the url tag. This context-free syntax would be invalid in standard BB-code, but it serves my purpose. What’s implicitly great is that standard BB-Code is supported and will be parsed correctly.

Converting eBB back to Xaml is also very simple. Each time a tag opens or closes, I update a structure containing all formatting infos, and generate corresponding Run or Hyperlink Xaml tags with all needed formatting infos.

A demo application with complete source code for the converter class can be downloaded from this site: XamlBBConverter.zip

 Posted by at 3:29 pm

  One Response to “Two-way XAML to BB-code converter”

  1. Frank,

    I really like this. Thank you for this post. This could be of great help towards me in a project, and could end up getting enhanced and used. The project is a well-known and trafficked financial message board.

    Regards,

    – Eric