質問
文字列「Européen」をRTF形式の文字列「Europ\'e9en」に変換するにはどうすればよいですか?
_[TestMethod]
public void Convert_A_Word_To_Rtf()
{
// Arrange
string Word = "Européen";
string expected = "Europ\'e9en";
string actual = string.Empty;
// Act
// actual = ... // How?
// Assert
Assert.AreEqual(expected, actual);
}
_
これまでに見つけたもの
RichTextBox
RichTextBoxは特定の目的に使用できます。例:
_RichTextBox richTextBox = new RichTextBox();
richTextBox.Text = "Européen";
string rtfFormattedString = richTextBox.Rtf;
_
しかし、rtfFormattedStringは、文字列「Europ\'e9en」だけでなく、RTF形式のドキュメント全体であることがわかります。
Stackoverflow
Webで他にもたくさんのリソースを見つけましたが、問題を完全に解決するものは何もありませんでした。
回答
result
の前のスペースを削除するには、Trim()
を追加する必要がありました。それ以外は、BradChristieのソリューションは機能しているようです。
RTF形式の文字列を取得するには、SubStringを実行し、RichTextBoxをトリムする必要があるため、直感が悪い場合でも、このソリューションを使用して実行します。
テストケース:
_[TestMethod]
public void Test_To_Verify_Brad_Christies_Stackoverflow_Answer()
{
Assert.AreEqual(@"Europ\'e9en", "Européen".ConvertToRtf());
Assert.AreEqual(@"d\'e9finitif", "définitif".ConvertToRtf());
Assert.AreEqual(@"\'e0", "à".ConvertToRtf());
Assert.AreEqual(@"H\'e4user", "Häuser".ConvertToRtf());
Assert.AreEqual(@"T\'fcren", "Türen".ConvertToRtf());
Assert.AreEqual(@"B\'f6den", "Böden".ConvertToRtf());
}
_
拡張メソッドとしてのロジック:
_public static class StringExtensions
{
public static string ConvertToRtf(this string value)
{
RichTextBox richTextBox = new RichTextBox();
richTextBox.Text = value;
int offset = richTextBox.Rtf.IndexOf(@"\f0\fs17") + 8; // offset = 118;
int len = richTextBox.Rtf.LastIndexOf(@"\par") - offset;
string result = richTextBox.Rtf.Substring(offset, len).Trim();
return result;
}
}
_
RichTextBox
は常に同じヘッダー/フッターを持っていませんか?オフセットの場所に基づいてコンテンツを読み取り、それを使用して解析を続けることができます。 (私が思う?私が間違っているなら私を訂正してください)
利用可能なライブラリはありますが、個人的には幸運に恵まれたことはありません(ただし、可能性を完全に使い果たす前に、常に別の方法を見つけました)。さらに、より良いもののほとんどは通常、わずかな料金が含まれています。
[〜#〜]編集[〜#〜]
一種のハックですが、これで必要なことをやり遂げることができます(私は願っています):
RichTextBox rich = new RichTextBox();
Console.Write(rich.Rtf);
String[] words = { "Européen", "Apple", "Carrot", "Touché", "Résumé", "A Européen eating an Apple while writing his Résumé, Touché!" };
foreach (String Word in words)
{
rich.Text = Word;
Int32 offset = rich.Rtf.IndexOf(@"\f0\fs17") + 8;
Int32 len = rich.Rtf.LastIndexOf(@"\par") - offset;
Console.WriteLine("{0,-15} : {1}", Word, rich.Rtf.Substring(offset, len).Trim());
}
編集2
コードの内訳RTF制御コード は次のとおりです。
\par
は、段落の終わりであることを指定しています。うまくいけば、それはいくつかのことをクリアします。 ;-)
これが私が行った方法です:
private string ConvertString2RTF(string input)
{
//first take care of special RTF chars
StringBuilder backslashed = new StringBuilder(input);
backslashed.Replace(@"\", @"\\");
backslashed.Replace(@"{", @"\{");
backslashed.Replace(@"}", @"\}");
//then convert the string char by char
StringBuilder sb = new StringBuilder();
foreach (char character in backslashed.ToString())
{
if (character <= 0x7f)
sb.Append(character);
else
sb.Append("\\u" + Convert.ToUInt32(character) + "?");
}
return sb.ToString();
}
RichTextBox
の使用は次のようになります。
1)やり過ぎ
2)Wordで作成されたRTFドキュメントで動作させるために何日も費やした後、RichTextBox
が好きではありません。
実際にRichTextBox自体を使用して変換を行う素晴らしいソリューションを見つけました。
private static string FormatAsRTF(string DirtyText)
{
System.Windows.Forms.RichTextBox rtf = new System.Windows.Forms.RichTextBox();
rtf.Text = DirtyText;
return rtf.Rtf;
}
http://www.baltimoreconsulting.com/blog/development/easily-convert-a-string-to-rtf-in-net/
しばらく経ちましたが、これがお役に立てば幸いです。
このコードは、私が手に入れることができるすべての変換コードを試した後、私のために働いています:
titleTextとcontentTextは、通常のTextBoxに入力される単純なテキストです。
var rtb = new RichTextBox();
rtb.AppendText(titleText)
rtb.AppendText(Environment.NewLine);
rtb.AppendText(contentText)
rtb.Refresh();
rtb.rtfはrtfテキストを保持するようになりました。
次のコードは、rtfテキストを保存し、ファイルを開いて編集し、RichTextBoxに再度ロードできるようにします。
rtb.SaveFile(path, RichTextBoxStreamType.RichText);
以下は、文字列をRTF文字列に変換する醜い例です:
class Program
{
static RichTextBox generalRTF = new RichTextBox();
static void Main()
{
string foo = @"Européen";
string output = ToRtf(foo);
Trace.WriteLine(output);
}
private static string ToRtf(string foo)
{
string bar = string.Format("!!@@!!{0}!!@@!!", foo);
generalRTF.Text = bar;
int pos1 = generalRTF.Rtf.IndexOf("!!@@!!");
int pos2 = generalRTF.Rtf.LastIndexOf("!!@@!!");
if (pos1 != -1 && pos2 != -1 && pos2 > pos1 + "!!@@!!".Length)
{
pos1 += "!!@@!!".Length;
return generalRTF.Rtf.Substring(pos1, pos2 - pos1);
}
throw new Exception("Not sure how this happened...");
}
}