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(); }
public void TokeniszationTest() { foreach (var expected in EqualityTiles) { var token = expected.ToTokenString(); var actual = TileData.FromTokenString(token); Assert.AreEqual(expected, actual); } }
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; }
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; }
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); } }
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); }
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(); }