/* Function: ConvertToJSON * Converts the passed search index to JSON. After this you can build the data files. */ public void ConvertToJSON(SearchIndex.Manager searchIndex, Context context) { this.context = context; // The searchIndex parameter is really just for API consistency with the other JSON builders. We can get it from the context. #if DEBUG if ((object)searchIndex != (object)context.Target.SearchIndex) { throw new Exception("The search index passed to ConvertToJSON must be the same as the one in the context's target."); } #endif // That's it. We're going to build the JSON for the data files on demand, so this function is also just for API consistency with // the other JSON builders. }
// Group: Functions // __________________________________________________________________________ public TopicEntry(Topic topic, SearchIndex.Manager manager) : base() { this.topic = topic; var commentType = manager.EngineInstance.CommentTypes.FromID(topic.CommentTypeID); var language = manager.EngineInstance.Languages.FromID(topic.LanguageID); // Get the title without any parameters. We don't want to include parameters in the index. Multiple functions that // differ only by parameter will be treated as one entry. string title, ignore; ParameterString.SplitFromParameters(topic.Title, out title, out ignore); title = title.TrimEnd(); // Figure out the extra scope text that should be added to the title to make it a fully resolved symbol. We do this by // comparing the symbol from the topic to one generated from the title. We don't just use the symbol to begin with // because we want to show the title as written; there's some normalization that occurs when generating symbols // that we want to bypass. string extraScope = null; SymbolString titleSymbol = SymbolString.FromPlainText_NoParameters(title); string titleSymbolString = titleSymbol.FormatWithSeparator(language.MemberOperator); string symbolString = topic.Symbol.FormatWithSeparator(language.MemberOperator); if (symbolString.Length > titleSymbolString.Length) { // We have to go by LastIndexOf rather than EndsWith because operator<string> will have <string> cut off as a parameter. // We have to go by LastIndexOf instead of IndexOf so constructors don't get cut off (Package.Class.Class). int titleIndex = symbolString.LastIndexOf(titleSymbolString); #if DEBUG if (titleIndex == -1) { throw new Exception("Title symbol string \"" + titleSymbolString + "\" isn't part of symbol string \"" + symbolString + "\" which " + "was assumed when creating a search index entry."); } #endif extraScope = symbolString.Substring(0, titleIndex); } // Remove the space in "operator <". This prevents them from appearing as two keywords, and also makes sure "operator <" and // "operator<" are always displayed consistently, which will be important for sorting. title = SpaceAfterOperatorKeywordRegex.Replace(title, ""); displayName = (extraScope == null ? title : extraScope + title); searchText = Normalize(displayName); if (commentType.Flags.File) { endOfDisplayNameQualifiers = EndOfQualifiers(displayName, FileSplitSymbolsRegex.Matches(displayName)); endOfSearchTextQualifiers = EndOfQualifiers(searchText, FileSplitSymbolsRegex.Matches(searchText)); } else if (commentType.Flags.Code) { endOfDisplayNameQualifiers = EndOfQualifiers(displayName, CodeSplitSymbolsRegex.Matches(displayName)); endOfSearchTextQualifiers = EndOfQualifiers(searchText, CodeSplitSymbolsRegex.Matches(searchText)); } else // documentation topic { if (extraScope == null) { endOfDisplayNameQualifiers = 0; endOfSearchTextQualifiers = 0; } else { endOfDisplayNameQualifiers = extraScope.Length; // Don't need +1 because only leading separators are removed. The trailing separator will still be there. endOfSearchTextQualifiers = Normalize(extraScope).Length; } } keywords = new List <string>(); if (endOfDisplayNameQualifiers == 0) { AddKeywords(displayName, commentType.Flags.Documentation); } else { AddKeywords(displayName.Substring(endOfDisplayNameQualifiers), commentType.Flags.Documentation); } }