Exemple #1
0
        /// <summary>
        /// Joining groups text, uses first group type as result group type
        /// </summary>
        private static TextGroup JoinGroups(IList <TextGroup> groups)
        {
            if (groups.Count == 0)
            {
                return(null);
            }

            // the new group type
            TextGroupType type = groups[0].Type;

            var sb = new StringBuilder();

            foreach (TextGroup g in groups)
            {
                sb.Append(g.Text);
            }
            return(new TextGroup(type, sb));
        }
Exemple #2
0
 public TextGroup(TextGroupType type, StringBuilder text)
 {
     Type = type;
     Text = text;
 }
Exemple #3
0
 public TextGroup(TextGroupType type)
 {
     Type = type;
     Text = new StringBuilder();
 }
Exemple #4
0
        /// <summary>
        /// Reordering RTL groups to display corrently in LTR context
        /// </summary>
        private static List <TextGroup> ReorderRtlGroupsForLtr(List <TextGroup> strGroups)
        {
            var           lstFinal      = new List <TextGroup>();
            TextGroupType lastGroupType = TextGroupType.Start;
            var           lstTemp       = new List <TextGroup>();

            // previous command required to skip the upcoming group
            bool skipTheNextGroup = false;

            Func <TextGroupAction?> commandToDo = null;

            for (int i = 0; i < strGroups.Count; i++)
            {
                TextGroupAction textGroupAction = TextGroupAction.FlushLastAndJustAdd;

                TextGroup     group               = strGroups[i];
                TextGroupType thisGroupType       = group.Type;
                TextGroupType?changeLastGroupType = null;

                // -----------------------------
                // Initializations
                int nextItemIndex     = i + 1;
                int futureItemIndex   = i + 2;
                int previousItemIndex = i - 1;

                TextGroup nextItem = null, futureItem = null;
                TextGroup previousItem = null;
                if (nextItemIndex < strGroups.Count)
                {
                    nextItem = strGroups[nextItemIndex];
                }
                if (futureItemIndex < strGroups.Count)
                {
                    futureItem = strGroups[futureItemIndex];
                }
                if (previousItemIndex >= 0 && previousItemIndex < strGroups.Count)
                {
                    previousItem = strGroups[previousItemIndex];
                }

                // -------------------------
                // conditions
                // -------------------------

                // the previous action requires this group to be skipped
                if (skipTheNextGroup)
                {
                    textGroupAction  = TextGroupAction.SkipThis;
                    skipTheNextGroup = false;
                }
                else if (thisGroupType == TextGroupType.Space)
                {
                    // Status = 1
                    if (lastGroupType == TextGroupType.Start)
                    {
                        textGroupAction = TextGroupAction.FlushLastAndJustAdd;
                    }
                    else
                    {
                        textGroupAction = TextGroupAction.FlushLastAndJustAdd;
                    }
                }
                else if (thisGroupType == TextGroupType.English)
                {
                    if (nextItem != null)
                    {
                        if (nextItem.Type == TextGroupType.Persian)
                        {
                            // status 5
                            textGroupAction = TextGroupAction.JoinCheckedThenFlush;
                        }
                        else if (nextItem.Type == TextGroupType.English)
                        {
                            // impossoble
                            textGroupAction = TextGroupAction.JoinThisCheckLast;
                        }
                        else if (nextItem.Type == TextGroupType.Number)
                        {
                            // staus  = 16
                            textGroupAction = TextGroupAction.JoinThisCheckLast;
                        }
                        else if (nextItem.Type == TextGroupType.Symbol)
                        {
                            // status 15
                            textGroupAction = TextGroupAction.JoinThisCheckLast;
                        }
                        else if (nextItem.Type == TextGroupType.Space)
                        {
                            if (futureItem == null)
                            {
                                // status 8
                                textGroupAction = TextGroupAction.JoinThisCheckLast;
                            }
                            else if (futureItem.Type == TextGroupType.Persian)
                            {
                                // status = ??
                                textGroupAction = TextGroupAction.JoinCheckedThenFlush;
                            }
                            else if (futureItem.Type == TextGroupType.Symbol)
                            {
                                TextGroupType?foundType;
                                int           foundIndex;
                                bool          has = HasInFuture(strGroups, i, new[] { TextGroupType.English, },
                                                                new[] { TextGroupType.Symbol, TextGroupType.Number, TextGroupType.Space, },
                                                                out foundType, out foundIndex);
                                if (has)
                                {
                                    // status ??
                                    textGroupAction  = TextGroupAction.JoinThisAndNextCheckLast;
                                    skipTheNextGroup = true;
                                }
                                else
                                {
                                    // status = ??
                                    textGroupAction = TextGroupAction.JoinThisCheckLast;
                                }
                            }
                            else
                            {
                                // status 14
                                textGroupAction  = TextGroupAction.JoinThisAndNextCheckLast;
                                skipTheNextGroup = true;
                            }
                        }
                        else
                        {
                            throw new Exception("Unknown condition!");
                            textGroupAction = TextGroupAction.FlushLastAndJustAdd;
                        }
                    }
                    else
                    {
                        // statsu =??
                        textGroupAction = TextGroupAction.JoinCheckedThenFlush;
                    }
                }
                else if (thisGroupType == TextGroupType.Persian)
                {
                    if (nextItem != null)
                    {
                        if (nextItem.Type == TextGroupType.Persian)
                        {
                            // statusu =self
                            textGroupAction = TextGroupAction.JoinThisCheckLast;
                        }
                        else if (nextItem.Type == TextGroupType.English)
                        {
                            // staus 4
                            textGroupAction = TextGroupAction.JoinCheckedThenFlush;
                        }
                        else if (nextItem.Type == TextGroupType.Number)
                        {
                            // staus  = 7
                            textGroupAction = TextGroupAction.JoinThisCheckLast;
                        }
                        else if (nextItem.Type == TextGroupType.Symbol)
                        {
                            // status 9
                            textGroupAction = TextGroupAction.JoinThisCheckLast;
                        }
                        else if (nextItem.Type == TextGroupType.Space)
                        {
                            if (futureItem == null)
                            {
                                // status 8
                                textGroupAction = TextGroupAction.JoinThisCheckLast;
                            }
                            else if (futureItem.Type == TextGroupType.English)
                            {
                                // status = ??
                                textGroupAction = TextGroupAction.JoinCheckedThenFlush;
                            }
                            else if (futureItem.Type == TextGroupType.Symbol)
                            {
                                TextGroupType?foundType;
                                int           foundIndex;
                                bool          has = HasInFuture(strGroups, i, new[] { TextGroupType.Persian, },
                                                                new[] { TextGroupType.Symbol, TextGroupType.Number, TextGroupType.Space, },
                                                                out foundType, out foundIndex);
                                if (has)
                                {
                                    // status ??
                                    textGroupAction  = TextGroupAction.JoinThisAndNextCheckLast;
                                    skipTheNextGroup = true;
                                }
                                else
                                {
                                    // status = ??
                                    textGroupAction = TextGroupAction.JoinThisCheckLast;
                                }
                            }
                            else
                            {
                                // status 10
                                textGroupAction  = TextGroupAction.JoinThisAndNextCheckLast;
                                skipTheNextGroup = true;
                            }
                        }
                        else
                        {
                            throw new Exception("Unknown condition!");
                            textGroupAction = TextGroupAction.FlushLastAndJustAdd;
                        }
                    }
                    else
                    {
                        // statsu =??
                        textGroupAction = TextGroupAction.JoinCheckedThenFlush;
                    }
                }
                else if (thisGroupType == TextGroupType.Symbol)
                {
                    int           foundIndex;
                    TextGroupType?prevAlphabet;

                    // is there any alphabet in previous secions?
                    bool hasAlphabetInPrevious = HasInPrevious(strGroups, i,
                                                               new[] { TextGroupType.Persian, TextGroupType.English, },
                                                               new[] { TextGroupType.Symbol, TextGroupType.Space, TextGroupType.Number, },
                                                               out prevAlphabet,
                                                               out foundIndex);

                    if (hasAlphabetInPrevious)
                    {
                        TextGroupType?nextAlphabet;
                        // is there any same alphabet in coming groups?
                        bool hasAlphabetInNext = HasInFuture(strGroups, i,
                                                             new[] { prevAlphabet.Value, },
                                                             new[] { TextGroupType.Symbol, TextGroupType.Space, TextGroupType.Number, },
                                                             out nextAlphabet,
                                                             out foundIndex);

                        if (hasAlphabetInNext)
                        {
                            // status=??
                            textGroupAction = TextGroupAction.DoCommand;
                            commandToDo     =
                                () =>                                 // do TextGroupAction
                            {
                                // let the loop continute on the alphabet, intead of anything else
                                foundIndex--;


                                for (int index = i; index <= foundIndex; index++)
                                {
                                    // adding all the groups in the range/ they behave same
                                    lstTemp.Add(strGroups[index]);
                                }

                                TextGroup combined = JoinGroups(lstTemp);
                                lstTemp.Clear();
                                lstTemp.Add(combined);


                                // changing index of current group/ skiping added groups
                                i = foundIndex;

                                // changing the last group type
                                group = combined;

                                // don't do anything
                                return(TextGroupAction.SkipThis);
                            };
                        }
                        else
                        {
                            // no alphabet in upcoming group so ,bracket kind characters should be switched
                            group.Text = ReverseBrackedKindChar(group.Text);

                            if (prevAlphabet != null && prevAlphabet.Value == TextGroupType.English)
                            {
                                // in english, if there is number after symbol, orders changes

                                TextGroupType?hasNumber;
                                // is there any same alphabet in coming groups?
                                bool hasNumberInNext = HasInFuture(strGroups, i,
                                                                   new[] { TextGroupType.Number, },
                                                                   new[] { TextGroupType.Symbol, TextGroupType.Space, TextGroupType.Number, },
                                                                   out nextAlphabet,
                                                                   out foundIndex);
                                if (hasNumberInNext)
                                {
                                    textGroupAction     = TextGroupAction.JoinThisDontCheck;
                                    changeLastGroupType = prevAlphabet.Value;

                                    //// next group checks the type, needed
                                    group.Type = prevAlphabet.Value;
                                }
                                else
                                {
                                    // status = 17, 18, 19, 20, 2
                                    textGroupAction = TextGroupAction.FlushLastAndJustAdd;
                                }
                            }
                            else
                            {
                                // status = 17, 18, 19, 20, 2
                                textGroupAction = TextGroupAction.FlushLastAndJustAdd;
                            }
                        }
                    }
                    else
                    {
                        // status = 17, 18, 19, 20, 2
                        textGroupAction = TextGroupAction.FlushLastAndJustAdd;
                    }
                }
                else if (thisGroupType == TextGroupType.Number)
                {
                    int           foundIndex;
                    TextGroupType?prevAlphabet;

                    // is there any alphabet in previous secions?
                    bool hasAlphabetInPrevious = HasInPrevious(strGroups, i,
                                                               new[] { TextGroupType.Persian, TextGroupType.English, },
                                                               new[] { TextGroupType.Symbol, TextGroupType.Space, TextGroupType.Number, },
                                                               out prevAlphabet,
                                                               out foundIndex);

                    if (hasAlphabetInPrevious)
                    {
                        TextGroupType?nextAlphabet;
                        // is there any same alphabet in coming groups?
                        bool hasAlphabetInNext = HasInFuture(strGroups, i,
                                                             new[] { prevAlphabet.Value, },
                                                             new[] { TextGroupType.Symbol, TextGroupType.Space, TextGroupType.Number, },
                                                             out nextAlphabet,
                                                             out foundIndex);
                        if (hasAlphabetInNext)
                        {
                            textGroupAction = TextGroupAction.DoCommand;
                            commandToDo     =
                                () =>                                 // do TextGroupAction
                            {
                                // let the loop continute on the alphabet, intead of anything else
                                foundIndex--;


                                for (int index = i; index <= foundIndex; index++)
                                {
                                    // adding all the groups in the range/ they behave same
                                    lstTemp.Add(strGroups[index]);
                                }

                                TextGroup combined = JoinGroups(lstTemp);
                                lstTemp.Clear();
                                lstTemp.Add(combined);


                                // changing index of current group/ skiping added groups
                                i = foundIndex;

                                // chaning the last group type
                                group = combined;

                                // don't do anything
                                return(TextGroupAction.SkipThis);
                            };
                        }
                        else
                        {
                            // is previous item alphabet?
                            if (previousItem != null &&
                                (previousItem.Type == TextGroupType.Persian || previousItem.Type == TextGroupType.English))
                            {
                                // status =??
                                textGroupAction     = TextGroupAction.JoinThisDontCheck;
                                changeLastGroupType = previousItem.Type;

                                // next group checks the type, needed
                                group.Type = previousItem.Type;
                            }
                            else
                            {
                                // is next item alphabet?
                                if (nextItem != null && (nextItem.Type == TextGroupType.Persian || nextItem.Type == TextGroupType.English))
                                {
                                    // status =??
                                    textGroupAction     = TextGroupAction.JoinThisDontCheck;
                                    changeLastGroupType = nextItem.Type;

                                    // next group checks the type, needed
                                    group.Type = nextItem.Type;
                                }
                                else
                                {
                                    // status = ??
                                    textGroupAction = TextGroupAction.JoinThisDontCheck;
                                }
                            }
                        }
                    }
                    else
                    {
                        if (nextItem != null && (nextItem.Type == TextGroupType.Persian || nextItem.Type == TextGroupType.English))
                        {
                            // status =??
                            textGroupAction     = TextGroupAction.JoinThisDontCheck;
                            changeLastGroupType = nextItem.Type;

                            // next group checks the type, needed
                            group.Type = nextItem.Type;
                        }
                        else
                        {
                            // status = ??
                            textGroupAction = TextGroupAction.FlushLastAndJustAdd;
                        }
                    }
                }
                else
                {
                    // status = ??
                    textGroupAction = TextGroupAction.FlushLastAndJustAdd;
                }


                // -------------------------
                // performing the specified actions
                // -------------------------

                // if any specific command requred!
                if (textGroupAction == TextGroupAction.DoCommand)
                {
                    if (commandToDo != null)
                    {
                        // setting the result
                        textGroupAction = commandToDo() ?? TextGroupAction.SkipThis;
                    }
                }

                // the actions
                switch (textGroupAction)
                {
                // ------------------------
                case TextGroupAction.FlushLastAndJustAdd:

                    TextGroup combinedFlush = JoinGroups(lstTemp);
                    if (combinedFlush != null)
                    {
                        lstFinal.Add(combinedFlush);
                    }
                    lstTemp.Clear();

                    // just add
                    lstFinal.Add(group);
                    break;

                // ------------------------
                case TextGroupAction.JoinCheckedThenFlush:

                    if (lstTemp.Count > 0 && lstTemp[0].Type != thisGroupType)
                    {
                        TextGroup combine1 = JoinGroups(lstTemp);
                        if (combine1 != null)
                        {
                            lstFinal.Add(combine1);
                        }
                        lstTemp.Clear();
                    }

                    // add to grouop first
                    lstTemp.Add(group);
                    TextGroup combine2 = JoinGroups(lstTemp);
                    if (combine2 != null)
                    {
                        lstFinal.Add(combine2);
                    }
                    lstTemp.Clear();
                    break;

                // ------------------------
                case TextGroupAction.JoinThisCheckLast:

                    // check the previous type, if it differs then flush it!
                    if (lstTemp.Count > 0 && lstTemp[0].Type != thisGroupType)
                    {
                        TextGroup combine = JoinGroups(lstTemp);
                        if (combine != null)
                        {
                            lstFinal.Add(combine);
                        }
                        lstTemp.Clear();
                    }
                    lstTemp.Add(group);

                    break;

                // ------------------------
                case TextGroupAction.JoinThisAndNextCheckLast:
                    // check the previous type, if it differs then flush it!
                    if (lstTemp.Count > 0 && lstTemp[0].Type != thisGroupType)
                    {
                        TextGroup combine = JoinGroups(lstTemp);
                        if (combine != null)
                        {
                            lstFinal.Add(combine);
                        }
                        lstTemp.Clear();
                    }
                    lstTemp.Add(group);
                    if (nextItem != null)
                    {
                        lstTemp.Add(nextItem);
                    }

                    break;

                // ------------------------
                case TextGroupAction.JoinThisDontCheck:

                    lstTemp.Add(group);
                    break;

                // ------------------------
                case TextGroupAction.DoCommand:
                    // already done!
                    break;

                // ------------------------
                case TextGroupAction.SkipThis:
                    // do nothing!
                    break;
                }

                // saving last group type
                // check if custom type is requested
                if (changeLastGroupType != null)
                {
                    lastGroupType = changeLastGroupType.Value;
                }
                else
                {
                    lastGroupType = group.Type;
                }
            }

            TextGroup combineFinal = JoinGroups(lstTemp);

            if (combineFinal != null)
            {
                lstFinal.Add(combineFinal);
            }

            lstFinal.Reverse();
            return(lstFinal);
        }