using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; namespace Volian.Base.Library { public class RtfTools { public static List SplitText(string text, int len) { { List results = new List(); if (text.Contains("\\LINE ") || text.Contains("\r\n") || text.Contains("\\line ")) { string[] mySplit = { "\\LINE ", "\r\n", "\\line " }; return new List(text.Split(mySplit, StringSplitOptions.None)); } int width = 0; // width of text, non-rtf int start = 0; // start of line (index into string 'text'), includes rtf int lastspace = 0; // location of lastspace (index into string 'text'), includes rtf int startNonRtf = 0; // start of line, non-rtf (used for determining starting position to determine width if there was a break) string rtfprefix = ""; string nextprefix = ""; for (int indx = 0; indx < text.Length; indx++) { if (text[indx] == '\\') //rtf command { // look for three things at beginning of string: hex, unicode, rtfcommand. Match m = Regex.Match(text.Substring(indx), @"^\\'[a-fA-F0-9][a-fA-F0-9]"); //hex if (m.Success) { indx += m.Length - 1; width++; } else { m = Regex.Match(text.Substring(indx), @"^\\[uU][a-fA-F0-9][a-fA-F0-9][a-fA-F0-9][?]"); // 3 char unicode, for example \u160? (hardspace) if (m.Success) { indx += m.Length - 1; width++; } else { m = Regex.Match(text.Substring(indx), @"^\\[uU][a-fA-F0-9][a-fA-F0-9][a-fA-F0-9][a-fA-F0-9][?]"); if (m.Success) { indx += m.Length - 1; width++; } else { m = Regex.Match(text.Substring(indx), @"^\\[^ ]*? "); if (m.Success) { indx += m.Length - 1; rtfprefix = AdjustRtfPrefix(rtfprefix, m.Value); } } } } } else { if (text[indx] == ' ') { lastspace = indx; startNonRtf = width; } width++; if (width > len) { // what should be done if lastspace == 0 // cannot find space char to split on, so break the word // not ideal but PROMS was bombing otherwise - jsj 7/7/2014 if (lastspace == 0) { lastspace = indx; startNonRtf = width - 1; } results.Add(nextprefix + text.Substring(start, lastspace - start).Trim(" ".ToCharArray())); nextprefix = rtfprefix; if (nextprefix != "") nextprefix += " "; start = lastspace + 1; width = (width - startNonRtf - 1) > 0 ? width - startNonRtf - 1 : 0; lastspace = 0; } } } if (width > 0 || start < text.Length) results.Add(nextprefix + text.Substring(start).Trim(" ".ToCharArray())); return results; } } private static string AdjustRtfPrefix(string rtfprefix, string rtfcommand) { if (rtfcommand.Contains(@"\ulnone") || rtfcommand.Contains(@"\ul0")) // off rtfprefix = rtfprefix.Replace(@"\ul", ""); else if (rtfcommand.Contains(@"\ul")) rtfprefix += @"\ul"; if (rtfcommand.Contains(@"\up0") || rtfcommand.Contains(@"\dn0")) rtfprefix = rtfprefix.Replace(@"\up2", "").Replace(@"\dn2", ""); else if (rtfcommand.Contains(@"\up")) rtfprefix += @"\up2"; else if (rtfcommand.Contains(@"\dn")) rtfprefix += @"\dn2"; if (rtfcommand.Contains(@"\b0")) rtfprefix = rtfprefix.Replace(@"\b", ""); else if (rtfcommand.Contains(@"\b")) rtfprefix += @"\b"; if (rtfcommand.Contains(@"\i0")) rtfprefix = rtfprefix.Replace(@"\i", ""); else if (rtfcommand.Contains(@"\i")) rtfprefix += @"\i"; return rtfprefix; } public static string RTFConvertedSymbolsToUnicode(string str) { string rtnStr = str; // convert \~ to a hard spece. RTF is automatically converting \u160? to \~ but will then convert // the \~ to a regular space! rtnStr = rtnStr.Replace(@"\~", @"\u160?"); rtnStr = rtnStr.Replace(@"\'a0", @"\u160?"); // convert \'99 to \u8482? this is for the trade mark symbol. RTF is automatically // converting the unicode \u8482? to \'99, but once this is done, PROMS StepRTB (edit windows) does not show it rtnStr = rtnStr.Replace(@"\'99", @"\u8482?"); // convert \'ae to \u174? this is for the registered symbol. RTF converts the unicode character to \'ae rtnStr = rtnStr.Replace(@"\'ae",@"\u174?"); // convert \'a9 to \u169? this is for the copyright symbol. RTF converts the unicode character to \'a9 rtnStr = rtnStr.Replace(@"\'a9",@"\u169?"); // B2021-039: paste of the greek symbols was not working correctly, RTF was converting unicode, similar to above // B2022-052: Division symbol converted to an x, caused by fix B2021-039. The code below was translating the division // symbol but it should only be translated if the character's font is Greek or Baltic. Unfortunately this is not // a complete solution since it converts characters it shouldn't, for example, using the following steps: all // of Proms symbols are entered into a step; a ctrl-a/ctrl-c is used to copy these and then ctrl-v to paste // into another new step. The paste (from the underlying richtextbox) causes some characters to be in plain // arial font, and others to be in arial with Greek flag. Some character codes exist in each font, for example f7. // The code below does not look into what font is used, just converts the character. Since any kind of font // can occur during paste, if from an external program, a message will be given stating that a symbol may be incorrect // because an unsupported font was pasted. It was felt that this was sufficient based on estimate of fix versus chance of // occurrence. Note that the message was moved into StepRTB since this code is called by non-UI code (5/26/22) if (str.ToUpper().Contains("GREEK") || str.ToUpper().Contains("BALTIC")) { //System.Windows.Forms.MessageBox.Show("Pasted text may use an unsupported font so some characters may not paste correctly and may require delete/reenter of character from within Proms.", // "Paste Font Issue", System.Windows.Forms.MessageBoxButtons.OK); for (int i = 0; i < 26; i++) { rtnStr = rtnStr.Replace(string.Format("\\'{0:x2}", 0xc0 + i) // upper case Greek , string.Format("\\u{0}?", 912 + i)); rtnStr = rtnStr.Replace(string.Format("\\'{0:x2}", 0xe0 + i) // lower case Greek , string.Format("\\u{0}?", 944 + i)); } } return rtnStr; } } }