internal CaseWordVocabularySource(ApplicationModel model, WordVocabularySource source, HeadWordItem target)
            : base(model)
        {
            _source = source;
            _target = target;

            var substitutes = new List <string>();

            var tile       = TileData.FromTokenString(target.Content);
            var content    = tile.Content;
            var isPrefix   = tile.IsPrefix;
            var isSuffix   = tile.IsSuffix;
            var attributes = tile.Attributes;
            var included   = new HashSet <string> {
                target.Content
            };

            var map = WordCaseMap.Create(content);

            if (map.LetterCount != 0)
            {
                var position0 = map.Positions[0];

                CheckedAdd(model.HeadItems[0].Culture.TextInfo.ToTitleCase(content));
                CheckedAdd(content.ToLower());
                CheckedAdd(content.ToUpper());
                CheckedAdd(content.Substring(0, position0) + char.ToUpper(content[position0]) + content.Substring(position0 + 1));

                for (var i = 0; i < map.Positions.Length; i++)
                {
                    var position = map.Positions[i];
                    var ch       = map.Uppers[i] ? char.ToLower(content[position]) : char.ToUpper(content[position]);
                    var cased    = content.Substring(0, position) + ch + content.Substring(position + 1);
                    CheckedAdd(cased);
                }

                void CheckedAdd(string newContent)
                {
                    var newTile = TileData.Create(content: newContent, isSuffix: isPrefix, isPrefix: isSuffix, attributes: attributes);
                    var version = newTile.ToTokenString();

                    if (included.Add(version))
                    {
                        substitutes.Add(version);
                    }
                }
            }

            for (var i = 0; i < 4; i++)
            {
                var spacedTile    = TileData.Create(content: content, isSuffix: (i & 1) != 0, isPrefix: (i & 2) != 0, attributes: attributes);
                var spacedContent = spacedTile.ToTokenString();
                if (included.Add(spacedContent))
                {
                    substitutes.Add(spacedContent);
                }
            }

            _substitutes = substitutes.ToArray();
        }
Пример #2
0
 public void TokeniszationTest()
 {
     foreach (var expected in EqualityTiles)
     {
         var token  = expected.ToTokenString();
         var actual = TileData.FromTokenString(token);
         Assert.AreEqual(expected, actual);
     }
 }
Пример #3
0
        internal ReplacementItem(HeadWordItem predecessor, WordVocabularySource source, string replacement)
            : base(predecessor, source)
        {
            _replacement = replacement;

            Tile = TileData.FromTokenString(replacement);
            UnformattedContent   = Tile.Content;
            IsAttachedToNext     = Tile.IsPrefix;
            IsAttachedToPrevious = Tile.IsSuffix;

            var oldTile = TileData.FromTokenString(predecessor.Content);

            OldUnformattedContent   = oldTile.Content;
            OldIsAttachedToNext     = oldTile.IsPrefix;
            OldIsAttachedToPrevious = oldTile.IsSuffix;
        }
Пример #4
0
        internal WordItem(ITile predecessor, WordVocabularySource source, string word)
            : base(predecessor, source)
        {
            Debug.Assert(!string.IsNullOrWhiteSpace(word));

            Tile = TileData.FromTokenString(word);

            var text   = UnformattedContent;
            var length = text.Length;
            var index  = 0;

            while (index < length && !char.IsLetterOrDigit(text, index))
            {
                index++;
            }
            IsCased = index < length;
        }
Пример #5
0
        public void CheckTokenizationTest()
        {
            CheckTokenization(TileData.Create("Normal"), "Normal");
            CheckTokenization(TileData.Create("Prefix", isPrefix: true), "Prefix\0B");
            CheckTokenization(TileData.Create("Suffix", isSuffix: true), "Suffix\0A");
            CheckTokenization(TileData.Create("Infix", isPrefix: true, isSuffix: true), "Infix\0J");

            void CheckTokenization(TileData tile, string expected)
            {
                var token = tile.ToTokenString();

                Assert.AreEqual(expected, token);

                var reborn = TileData.FromTokenString(token);

                Assert.AreEqual(tile, reborn);
            }
        }
Пример #6
0
        private static ApplicationRobotAction GetCaseWordAction(ApplicationModel model, TileData startWord, TileData targetWord, CultureInfo culture)
        {
            ApplicationRobotAction action;

            var firstOfFirst = model.SuggestionLists[0].First();

            if (IsItem <CommandItem>(firstOfFirst, out var commandItem))
            {
                switch (commandItem.Command)
                {
                case TileCommand.Typing:
                    action = ApplicationRobotAction.CreateSuggestion(0, 0);
                    break;

                default:
                    action = ApplicationRobotAction.CreateInterstitial(0);
                    break;
                }
            }
            else if (!(firstOfFirst is ReplacementItem))
            {
                Debug.Assert(model.SuggestionInterstitials[0] is InterstitialGapItem);
                action = ApplicationRobotAction.CreateInterstitial(0);
            }
            else
            {
                var startTile  = startWord;
                var targetTile = targetWord;

                var startMap  = WordCaseMap.Create(startTile.Content);
                var targetMap = WordCaseMap.Create(targetTile.Content);
                Debug.Assert(startMap.LetterCount == targetMap.LetterCount);

                var startDistance = targetMap.GetDistanceTo(startMap);
                if (targetTile.IsPrefix != startTile.IsPrefix)
                {
                    startDistance++;
                }
                if (targetTile.IsSuffix != startTile.IsSuffix)
                {
                    startDistance++;
                }

                var bestReplacementIndex    = -1;
                var bestReplacementDistance = startDistance;

                var index = 0;
                foreach (var list in model.SuggestionLists)
                {
                    var replacement   = (ReplacementItem)list.First();
                    var suggestedTile = TileData.FromTokenString(replacement.Content);
                    var suggestedMap  = WordCaseMap.Create(suggestedTile.Content);
                    Debug.Assert(suggestedMap.LetterCount == targetMap.LetterCount);

                    var suggestionDistance = targetMap.GetDistanceTo(suggestedMap);
                    if (targetTile.IsPrefix != suggestedTile.IsPrefix)
                    {
                        suggestionDistance++;
                    }
                    if (targetTile.IsSuffix != suggestedTile.IsSuffix)
                    {
                        suggestionDistance++;
                    }

                    if (suggestionDistance < bestReplacementDistance)
                    {
                        bestReplacementDistance = suggestionDistance;
                        bestReplacementIndex    = index;
                    }

                    index++;
                }

                if (bestReplacementIndex != -1)
                {
                    action = ApplicationRobotAction.CreateSuggestion(bestReplacementIndex, 0);
                }
                else
                {
                    Debug.Assert(model.SuggestionInterstitials[model.SuggestionInterstitials.Count - 1] is InterstitialGapItem);
                    action = ApplicationRobotAction.CreateInterstitial(model.SuggestionInterstitials.Count - 1);
                }
            }

            return(action);
        }
Пример #7
0
        internal void Commit(ITile stopTile)
        {
            ParanoidAssertValid();

            // Find position from which to work backwards to rebirth ghost items.
            ITile position;

            if (_selectedIndex == 0 &&
                stopTile is GhostStopItem)
            {
                position = _headItems[_headItems.Count - 1].Predecessor;
            }
            else
            {
                position = stopTile.Predecessor;
            }

            var wordList = new List <string>();

            while (!ReferenceEquals(LastTile, position))
            {
                wordList.Insert(0, position.Content);
                position = position.Predecessor;
            }

            AddWords(wordList);

            if (_selectedIndex == 0 &&
                2 < _headItems.Count &&
                _headItems[_headItems.Count - 1] is GhostStopItem)
            {
                TransferRunOnToSuccessors(_headItems[_headItems.Count - 2]);
            }

            ParanoidAssertValid();

            var selection = new List <int>(Context)
            {
                0
            };

            RollbackAndAddSequence(selection, PersistedSequenceWeight);

            var predecessor = _headItems[0];

            for (var i = 1; i <= _selectedIndex; i++)
            {
                var selected = _headItems[i];
                var ghost    = CreateGhostWordItem(predecessor, selected.Content);
                _headItems[i] = ghost;
                predecessor   = ghost;
            }

            while (_selectedIndex + 1 < _headItems.Count)
            {
                _headItems.RemoveAt(_headItems.Count - 1);
            }

            selection.RemoveAt(0);
            selection.RemoveAt(selection.Count - 1);
            var tiles = new List <TileData>();

            foreach (var token in selection)
            {
                var tokenString = _tokens.GetString(token);
                var tile        = TileData.FromTokenString(tokenString);
                tiles.Add(tile);
            }
            var utterance = TileSequence.FromData(tiles);

            SetSelectedIndex(0);
            var tail = new GhostStopItem(predecessor, this);

            _headItems.Add(tail);

            Model.SaveUtterance(utterance);

            InitializeUtterance();
            SetSuggestionsViewComplete();

            ParanoidAssertValid();
        }