Converting between RTF and HTML

m2v3g5 2016-08-12 01:17:26
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#
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#
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#
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#
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);
}

bjdkfp1688.bandcamp.com
nndkfp1688.bandcamp.com
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.
...全文
1788 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

703

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder ActiveX/COM/DCOM
社区管理员
  • ActiveX/COM/DCOM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧