Example #1
0
        /// <summary>
        /// Forbid compoundings when there are special patterns at word bound.
        /// </summary>
        public bool Check(string word, int pos, WordEntry r1, WordEntry r2, bool affixed)
        {
            var wordAfterPos = word.Substring(pos);

            foreach (var patternEntry in items)
            {
                int len;
                if (
                    StringEx.IsSubset(patternEntry.Pattern2, wordAfterPos)
                    &&
                    (
                        r1 == null
                        ||
                        patternEntry.Condition.IsZero
                        ||
                        r1.ContainsFlag(patternEntry.Condition)
                    )
                    &&
                    (
                        r2 == null
                        ||
                        patternEntry.Condition2.IsZero
                        ||
                        r2.ContainsFlag(patternEntry.Condition2)
                    )
                    &&
                    // zero length pattern => only TESTAFF
                    // zero pattern (0/flag) => unmodified stem (zero affixes allowed)
                    (
                        string.IsNullOrEmpty(patternEntry.Pattern)
                        ||
                        (
                            (
                                patternEntry.Pattern.StartsWith('0') &&
                                r1.Word.Length <= pos &&
                                StringEx.EqualsOffset(word, pos - r1.Word.Length, r1.Word, 0, r1.Word.Length)
                            )
                            ||
                            (
                                !patternEntry.Pattern.StartsWith('0')
                                &&
                                (
                                    (
                                        len = patternEntry.Pattern.Length
                                    ) != 0
                                )
                                &&
                                StringEx.EqualsOffset(word, pos - len, patternEntry.Pattern, 0, len)
                            )
                        )
                    )
                    )
                {
                    return(true);
                }
            }

            return(false);
        }
            public SpellCheckResult CheckDetails()
            {
                var word = WordToCheck;

                if (string.IsNullOrEmpty(word) || word.Length >= MaxWordUtf8Len || !WordList.HasEntries)
                {
                    return(new SpellCheckResult(false));
                }
                if (word == DefaultXmlToken)
                {
                    // Hunspell supports XML input of the simplified API (see manual)
                    return(new SpellCheckResult(true));
                }

                // input conversion
                if (!Affix.InputConversions.HasReplacements || !Affix.InputConversions.TryConvert(word, out string convertedWord))
                {
                    convertedWord = word;
                }

                if (!CleanWord2(out string scw, convertedWord, out CapitalizationType capType, out int abbv))
                {
                    return(new SpellCheckResult(false));
                }

                if (HunspellTextFunctions.IsNumericWord(word))
                {
                    // allow numbers with dots, dashes and commas (but forbid double separators: "..", "--" etc.)
                    return(new SpellCheckResult(true));
                }

                var       resultType = SpellCheckResultType.None;
                string    root       = null;
                WordEntry rv         = null;

                if (capType == CapitalizationType.Huh || capType == CapitalizationType.HuhInit || capType == CapitalizationType.None)
                {
                    if (capType == CapitalizationType.HuhInit)
                    {
                        resultType |= SpellCheckResultType.OrigCap;
                    }

                    rv = CheckWord(scw, ref resultType, out root);
                    if (abbv != 0 && rv == null)
                    {
                        rv = CheckWord(scw + ".", ref resultType, out root);
                    }
                }
                else if (capType == CapitalizationType.All)
                {
                    rv = CheckDetailsAllCap(abbv, ref scw, ref resultType, out root);
                }

                if (capType == CapitalizationType.Init || (capType == CapitalizationType.All && rv == null))
                {
                    rv = CheckDetailsInitCap(abbv, capType, ref scw, ref resultType, out root);
                }

                if (rv != null)
                {
                    if (rv.ContainsFlag(Affix.Warn))
                    {
                        resultType |= SpellCheckResultType.Warn;

                        if (Affix.ForbidWarn)
                        {
                            return(new SpellCheckResult(root, resultType, false));
                        }
                    }

                    return(new SpellCheckResult(root, resultType, true));
                }

                // recursive breaking at break points
                if (Affix.BreakPoints.HasItems && !EnumEx.HasFlag(resultType, SpellCheckResultType.Forbidden))
                {
                    // calculate break points for recursion limit
                    if (Affix.BreakPoints.FindRecursionLimit(scw) >= 10)
                    {
                        return(new SpellCheckResult(root, resultType, false));
                    }

                    // check boundary patterns (^begin and end$)
                    foreach (var breakEntry in Affix.BreakPoints)
                    {
                        if (breakEntry.Length == 1 || breakEntry.Length > scw.Length)
                        {
                            continue;
                        }

                        var pLastIndex = breakEntry.Length - 1;
                        if (
                            breakEntry.StartsWith('^') &&
                            StringEx.EqualsOffset(scw, 0, breakEntry, 1, pLastIndex) &&
                            Check(scw.Substring(pLastIndex))
                            )
                        {
                            return(new SpellCheckResult(root, resultType, true));
                        }

                        if (breakEntry.EndsWith('$'))
                        {
                            var wlLessBreakIndex = scw.Length - breakEntry.Length + 1;
                            if (
                                StringEx.EqualsOffset(scw, wlLessBreakIndex, breakEntry, 0, pLastIndex) &&
                                Check(scw.Substring(0, wlLessBreakIndex))
                                )
                            {
                                return(new SpellCheckResult(root, resultType, true));
                            }
                        }
                    }

                    // other patterns
                    foreach (var breakEntry in Affix.BreakPoints)
                    {
                        var found           = scw.IndexOfOrdinal(breakEntry);
                        var remainingLength = scw.Length - breakEntry.Length;
                        if (found > 0 && found < remainingLength)
                        {
                            var found2 = scw.IndexOfOrdinal(breakEntry, found + 1);
                            // try to break at the second occurance
                            // to recognize dictionary words with wordbreak
                            if (found2 > 0 && (found2 < remainingLength))
                            {
                                found = found2;
                            }

                            if (!Check(scw.Substring(found + breakEntry.Length)))
                            {
                                continue;
                            }

                            // examine 2 sides of the break point
                            if (Check(scw.Substring(0, found)))
                            {
                                return(new SpellCheckResult(root, resultType, true));
                            }

                            // LANG_hu: spec. dash rule
                            if (Affix.IsHungarian && "-".Equals(breakEntry, StringComparison.Ordinal))
                            {
                                if (Check(scw.Substring(0, found + 1)))
                                {
                                    return(new SpellCheckResult(root, resultType, true));
                                }
                            }
                        }
                    }

                    // other patterns (break at first break point)
                    foreach (var breakEntry in Affix.BreakPoints)
                    {
                        var found           = scw.IndexOfOrdinal(breakEntry);
                        var remainingLength = scw.Length - breakEntry.Length;
                        if (found > 0 && found < remainingLength)
                        {
                            if (!Check(scw.Substring(found + breakEntry.Length)))
                            {
                                continue;
                            }

                            // examine 2 sides of the break point
                            if (Check(scw.Substring(0, found)))
                            {
                                return(new SpellCheckResult(root, resultType, true));
                            }

                            // LANG_hu: spec. dash rule
                            if (Affix.IsHungarian && "-".Equals(breakEntry, StringComparison.Ordinal))
                            {
                                if (Check(scw.Substring(0, found + 1)))
                                {
                                    return(new SpellCheckResult(root, resultType, true));
                                }
                            }
                        }
                    }
                }

                return(new SpellCheckResult(root, resultType, false));
            }
 private static bool PatternWordCheck(string word, int pos, string other) =>
 other.Length <= pos &&
 StringEx.EqualsOffset(word, pos - other.Length, other, 0, other.Length);
 internal bool Pattern3DoesNotMatch(string word, int offset) =>
 Pattern3.Length == 0 || !StringEx.EqualsOffset(word, offset, Pattern3, 0, Pattern3.Length);