using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; using System.Windows; using Microsoft.Phone.Controls; namespace TranslatorByMoth //TODO replace with your namespace, so App can be resolved { public static class RTL { /// /// Calling code can determine whether to use this class or not for the text. /// /// two letter ISO code for the language, e.g. "he" or "ar" /// true for RTL languages supported public static bool RequiresRTL(string lang) { return (lang == "he" || lang == "ar"); } private static int MaxCharactersPerLine { get { #if WINDOWS_PHONE if (((Application.Current as App).RootFrame.Orientation & PageOrientation.Portrait) != 0) return 37; else // Landscape #endif return 50; } } /// /// Accepts a string (multi-line, line breaks, whatever) of the supported RTL languages and reverses it. /// /// text that needs reversing /// whether to break the returned text into lines of MaxCharactersPerLine length /// Arabic is treated specially, due to characters having different appearence dependent on what comes before/after them /// true if the returned string is sent to a service. false if it is to be displayed to the user /// the reversed string ready to be displayed to the user or sent to a service public static string ReverseLengthyMultilineText(string translatedRtlThatIsLtr, bool breakInLines, bool isArabic, bool isFromRTL) { if (translatedRtlThatIsLtr.Trim().Length < 2) //if null, let it throw return translatedRtlThatIsLtr; string[] words = translatedRtlThatIsLtr.Split(new char[] { ' ', Convert.ToChar(160), '\n' }, StringSplitOptions.RemoveEmptyEntries); StringBuilder result = new StringBuilder(); int charCount = -1; List line = new List(); int charsPerLine = breakInLines ? RTL.MaxCharactersPerLine : Int32.MaxValue; foreach (string w in words) { // for spaces between words. charCount++; charCount += w.Length; // if adding this word exceeds the chars per line then add a new line here // and this word will go to the next line. if (breakInLines && charCount > charsPerLine) { result.AppendLine(RTL.ReverseLine(line, isArabic, isFromRTL)); // start a new line... line.Clear(); charCount = w.Length; } line.Add(w); } result.Append(RTL.ReverseLine(line, isArabic, isFromRTL)); return result.ToString(); } private static string ReverseLine(List words, bool isArabic, bool isFromRTL) { List reversedWords = new List(words.Count); for (int i = words.Count - 1; i > -1; i--) reversedWords.Add(RTL.ReverseWord(words[i], isArabic, isFromRTL)); return String.Join(" ", reversedWords.ToArray()); } /// /// Reverses a string that has no spaces or line breaks, taking into account to preserve order of numbers and English strings. /// /// the text to reverse /// Arabic is treated specially, due to characters having different appearence dependent on what comes before/after them /// true if the returned string is sent to a service. false if it is to displayed to the user /// the reversed string ready to be displayed to the user or sent to a service public static string ReverseWord(string word, bool isArabic, bool isFromRTL) { if (word.Length < 2) //if null let it throw return word; Match m = Regex.Match(word, "[a-zA-Z0-9]+.*[a-zA-Z0-9]+"); if (m.Success) { // English or numbers translation // isolate punctuation prefix and suffix. These should be reversed. The English word shouldn't be reversed. string prefix = word.Substring(0, m.Index); string actualWord = m.Value; string suffix = word.Substring(m.Length + m.Index); return RTL.ReverseWord(suffix, isArabic, isFromRTL) + actualWord + ReverseWord(prefix, isArabic, isFromRTL); } else // normal RTL translation if (!isArabic) // regardless of TO or FROM, simple reversing works for Hebrew return new string( System.Linq.Enumerable.ToArray( System.Linq.Enumerable.Reverse(word.ToCharArray()))); else // Arabic if (!isFromRTL) return new string( System.Linq.Enumerable.ToArray( System.Linq.Enumerable.Reverse(new Arabic.Utils.SuperString(word).DisplayText.ToCharArray()))); //Arabic.Utils.SuperString comes from http://arabic4wp7.codeplex.com/ else // TODO nothing here works. Can't get Arabic string and send it to Bing service and get back English :-( return "Sorry, not supported yet"; // get DisplayText - doesn't work //return new Arabic.Utils.SuperString(word).DisplayText; // get Text - doesn't work //return new Arabic.Utils.SuperString(word).Text; // reverse first, then Text - doesn't work //return new Arabic.Utils.SuperString(new string( // System.Linq.Enumerable.ToArray( // System.Linq.Enumerable.Reverse(word.ToCharArray())))).Text; // reverse first, then DisplayText - doesn't work //return new Arabic.Utils.SuperString(new string( // System.Linq.Enumerable.ToArray( // System.Linq.Enumerable.Reverse(word.ToCharArray())))).DisplayText; // get Text then reverse - doesn't work //return new string( // System.Linq.Enumerable.ToArray( // System.Linq.Enumerable.Reverse(new Arabic.Utils.SuperString(word).Text.ToCharArray()))); // get DisplayText then reverse - doesn't work //return new string( // System.Linq.Enumerable.ToArray( // System.Linq.Enumerable.Reverse(new Arabic.Utils.SuperString(word).DisplayText.ToCharArray()))); // just reverse - doesn't work //return new string( // System.Linq.Enumerable.ToArray( // System.Linq.Enumerable.Reverse(word.ToCharArray()))); } } }