Have you ever had the desire to convert some RTF text into HTML or take HTML and generate a RTF document? Probably not. But if you did, then you are in luck! I recently had the need to do this conversion and after some searching found out a way to do it by enhancing a sample distributed in the MSDN library called: XAML to HTML Conversion Demo.

That sample has code which converts HTML to and from a XAML Flow Document. But this doesn’t make things easier until you realize that there is a way to convert RTF to XAML and XAML to RTF easily. The key is to use System.Windows.Controls.RichTextBox which can load RTF/XAML from a stream and save it as XAML/RTF.

RTF to XAML 

C#
Edit|Remove
private static string ConvertRtfToXaml(string rtfText) 
{ 
    var richTextBox = new RichTextBox(); 
    if (string.IsNullOrEmpty(rtfText)) return ""; 
    var textRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd); 
    using (var rtfMemoryStream = new MemoryStream()) 
    { 
        using (var rtfStreamWriter = new StreamWriter(rtfMemoryStream)) 
        { 
            rtfStreamWriter.Write(rtfText); 
            rtfStreamWriter.Flush(); 
            rtfMemoryStream.Seek(0, SeekOrigin.Begin); 
            textRange.Load(rtfMemoryStream, DataFormats.Rtf); 
        } 
    } 
    using (var rtfMemoryStream = new MemoryStream()) 
    { 
        textRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd); 
        textRange.Save(rtfMemoryStream, DataFormats.Xaml); 
        rtfMemoryStream.Seek(0, SeekOrigin.Begin); 
        using (var rtfStreamReader = new StreamReader(rtfMemoryStream)) 
        { 
            return rtfStreamReader.ReadToEnd(); 
        } 
    } 
} 
 
 

XAML to RTF 

C#
Edit|Remove
private static string ConvertXamlToRtf(string xamlText) 
{ 
    var richTextBox = new RichTextBox(); 
    if (string.IsNullOrEmpty(xamlText)) return ""; 
    var textRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd); 
    using (var xamlMemoryStream = new MemoryStream()) 
    { 
        using (var xamlStreamWriter = new StreamWriter(xamlMemoryStream)) 
        { 
            xamlStreamWriter.Write(xamlText); 
            xamlStreamWriter.Flush(); 
            xamlMemoryStream.Seek(0, SeekOrigin.Begin); 
            textRange.Load(xamlMemoryStream, DataFormats.Xaml); 
        } 
    } 
    using (var rtfMemoryStream = new MemoryStream()) 
    { 
        textRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd); 
        textRange.Save(rtfMemoryStream, DataFormats.Rtf); 
        rtfMemoryStream.Seek(0, SeekOrigin.Begin); 
        using (var rtfStreamReader = new StreamReader(rtfMemoryStream)) 
        { 
            return rtfStreamReader.ReadToEnd(); 
        } 
    } 
} 
 
 

 With this code we have all we need to convert RTF to HTML and HTML to RTF. I modified the MSDN library sample to add this RTF/XAML to XAML/RTF conversion and then I either run that XAML through HTML converter which results in the HTML text or I run the HTML through the XAML converter and generate XAML text. I added an interface for these conversion utilities and converted the sample into a library so that I would be able to use it from other projects. Here is the interface: 

C#
Edit|Remove
public interface IMarkupConverter 
{ 
    string ConvertXamlToHtml(string xamlText); 
    string ConvertHtmlToXaml(string htmlText); 
    string ConvertRtfToHtml(string rtfText); 
    string ConvertHtmlToRtf(string htmlText); 
} 
 
public class MarkupConverter : IMarkupConverter 
{ 
    public string ConvertXamlToHtml(string xamlText) 
    { 
        return HtmlFromXamlConverter.ConvertXamlToHtml(xamlText, false); 
    } 
 
    public string ConvertHtmlToXaml(string htmlText) 
    { 
        return HtmlToXamlConverter.ConvertHtmlToXaml(htmlText, true); 
    } 
 
    public string ConvertRtfToHtml(string rtfText) 
    { 
        return RtfToHtmlConverter.ConvertRtfToHtml(rtfText); 
    } 
 
    public string ConvertHtmlToRtf(string htmlText) 
    { 
        return HtmlToRtfConverter.ConvertHtmlToRtf(htmlText); 
    } 
} 
 
 

With this I am now able to convert from RTF to HTML and from HTML to RTF. However, there is one catch – the conversion uses the RichTextBox WPF control which requires a single threaded apartment (STA). Therefore in order to run your code that calls the ConvertRtfToHtml or ConvertHtmlToRtf functions, they must also be running in a STA. If you can’t have your program run in a STA (for example: when running an ASP .NET website) then you must create a new STA thread to run the conversion. Like this:

C#
Edit|Remove
MarkupConverter markupConverter = new MarkupConverter(); 
  
private string ConvertRtfToHtml(string rtfText) 
{ 
   var thread = new Thread(ConvertRtfInSTAThread); 
   var threadData = new ConvertRtfThreadData { RtfText = rtfText }; 
   thread.SetApartmentState(ApartmentState.STA); 
   thread.Start(threadData); 
   thread.Join(); 
   return threadData.HtmlText; 
} 
  
private void ConvertRtfInSTAThread(object rtf) 
{ 
   var threadData = rtf as ConvertRtfThreadData; 
   threadData.HtmlText = markupConverter.ConvertRtfToHtml(threadData.RtfText); 
} 
  
  
private class ConvertRtfThreadData 
{ 
   public string RtfText { get; set; } 
   public string HtmlText { get; set; } 
} 
 
 

 That is all there is too it! Hopefully, this will come in handy for anyone needing to perform this conversion.

 

Read more from Matthew Manela at his blog...