¿Cómo convertir una cadena a RTF en C #?

Pregunta

¿Cómo convierto la cadena “Européen” a la cadena con formato 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); } 

Lo que he encontrado hasta ahora

RichTextBox

RichTextBox se puede usar para ciertas cosas. Ejemplo:

 RichTextBox richTextBox = new RichTextBox(); richTextBox.Text = "Européen"; string rtfFormattedString = richTextBox.Rtf; 

Pero luego rtfFormattedString resulta ser el documento completo con formato RTF, no solo la cadena “Europ \ ‘e9en”.

Desbordamiento de stack

  • Insertar cadena con caracteres especiales en RTF
  • Cómo dar salida a una cadena Unicode a RTF (usando C #)
  • Salida de caracteres especiales RTF a Unicode
  • Convierte caracteres especiales para RTF (iPhone)

Google

También encontré muchos otros recursos en la web, pero nada solucionó mi problema.

Responder

La respuesta de Brad Christie

Tuve que agregar Trim() para eliminar el espacio anterior en el result . Aparte de eso, la solución de Brad Christie parece funcionar.

Voy a correr con esta solución por ahora, aunque tengo una mala intuición, ya que tenemos que SubString y Trim the RichtextBox para obtener una cadena con formato RTF.

Caso de prueba:

 [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()); } 

Lógica como método de extensión:

 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 no siempre tiene el mismo encabezado / pie de página? Podrías leer el contenido según la ubicación establecida y continuar utilizándolo para analizar. (Creo que por favor corrígeme si estoy equivocado)

Hay bibliotecas disponibles, pero nunca he tenido buena suerte con ellas personalmente (aunque siempre encontré otro método antes de agotar completamente las posibilidades). Además, la mayoría de los mejores suelen incluir una tarifa nominal.


EDITAR
Es un truco, pero esto debería guiarte en lo que necesitas atravesar (espero):

 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()); } 

EDIT 2

El desglose de los códigos código de control RTF son los siguientes:

  • Encabezamiento
    • \f0 – Utilice la fuente 0-index (primera fuente en la lista, que generalmente es Microsoft Sans Serif (anotada en la tabla de fonts en el encabezado: {\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}} )))
    • \fs17 – Formato de fuente, especifique que el tamaño es 17 (17 siendo en medio punto)
  • Pie de página
    • \par especifica que es el final de un párrafo.

Espero que eso aclare algunas cosas. 😉

Así es como fui:

 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(); } 

Creo que usar un RichTextBox es:
1) exagerado
2) No me gusta RichTextBox después de pasar días tratando de hacerlo funcionar con un documento RTF creado en Word.

A continuación se muestra un feo ejemplo de convertir una cadena en una cadena 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..."); } } 

Sé que ha pasado un tiempo, espero que esto ayude …

Este código me funciona después de probar cada código de conversión que pude poner en mis manos:

titleText y contentText son texto simple rellenado en un TextBox regular

 var rtb = new RichTextBox(); rtb.AppendText(titleText) rtb.AppendText(Environment.NewLine); rtb.AppendText(contentText) rtb.Refresh(); 

rtb.rtf ahora contiene el texto rtf.

El siguiente código guardará el texto rtf y le permitirá abrir el archivo, editarlo y luego volver a cargarlo en un RichTextBox:

 rtb.SaveFile(path, RichTextBoxStreamType.RichText); 

Encontré una buena solución que realmente usa el RichTextBox para hacer la conversión:

 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/

No es el método más elegante, pero bastante óptimo y rápido:

 public static string PlainTextToRtf(string plainText) { if (string.IsNullOrEmpty(plainText)) return ""; string escapedPlainText = plainText.Replace(@"\", @"\\").Replace("{", @"\{").Replace("}", @"\}"); escapedPlainText = EncodeCharacters(escapedPlainText); string rtf = @"{\rtf1\ansi\ansicpg1250\deff0{\fonttbl\f0\fswiss Helvetica;}\f0\pard "; rtf += escapedPlainText.Replace(Environment.NewLine, "\\par\r\n ") + ; rtf += " }"; return rtf; } 

.

Método de encoding de caracteres (polacos):

 private static string EncodeCharacters(string text) { if (string.IsNullOrEmpty(text)) return ""; return text .Replace("ą", @"\'b9") .Replace("ć", @"\'e6") .Replace("ę", @"\'ea") .Replace("ł", @"\'b3") .Replace("ń", @"\'f1") .Replace("ó", @"\'f3") .Replace("ś", @"\'9c") .Replace("ź", @"\'9f") .Replace("ż", @"\'bf") .Replace("Ą", @"\'a5") .Replace("Ć", @"\'c6") .Replace("Ę", @"\'ca") .Replace("Ł", @"\'a3") .Replace("Ń", @"\'d1") .Replace("Ó", @"\'d3") .Replace("Ś", @"\'8c") .Replace("Ź", @"\'8f") .Replace("Ż", @"\'af"); }