mirror of
https://github.com/wagesj45/butterflow-ui.git
synced 2025-08-02 06:38:22 -05:00
Adding generated help documents.
This commit is contained in:
parent
1a143b9e81
commit
fb517aba9d
405 changed files with 6421 additions and 1 deletions
233
docs/SearchHelp.aspx
Normal file
233
docs/SearchHelp.aspx
Normal file
|
@ -0,0 +1,233 @@
|
|||
<%@ Page Language="C#" EnableViewState="False" %>
|
||||
|
||||
<script runat="server">
|
||||
//===============================================================================================================
|
||||
// System : Sandcastle Help File Builder
|
||||
// File : SearchHelp.aspx
|
||||
// Author : Eric Woodruff (Eric@EWoodruff.us)
|
||||
// Updated : 05/15/2014
|
||||
// Note : Copyright 2007-2015, Eric Woodruff, All rights reserved
|
||||
// Compiler: Microsoft C#
|
||||
//
|
||||
// This file contains the code used to search for keywords within the help topics using the full-text index
|
||||
// files created by the help file builder.
|
||||
//
|
||||
// This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be
|
||||
// distributed with the code. It can also be found at the project website: https://GitHub.com/EWSoftware/SHFB. This
|
||||
// notice, the author's name, and all copyright notices must remain intact in all applications, documentation,
|
||||
// and source files.
|
||||
//
|
||||
// Date Who Comments
|
||||
// ==============================================================================================================
|
||||
// 06/24/2007 EFW Created the code
|
||||
// 02/17/2012 EFW Switched to JSON serialization to support websites that use something other than ASP.NET
|
||||
// such as PHP.
|
||||
// 05/15/2014 EFW Updated for use with the lightweight website presentation styles
|
||||
//===============================================================================================================
|
||||
|
||||
/// <summary>
|
||||
/// This class is used to track the results and their rankings
|
||||
/// </summary>
|
||||
private class Ranking
|
||||
{
|
||||
public string Filename, PageTitle;
|
||||
public int Rank;
|
||||
|
||||
public Ranking(string file, string title, int rank)
|
||||
{
|
||||
Filename = file;
|
||||
PageTitle = title;
|
||||
Rank = rank;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Render the search results
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer to which the results are written</param>
|
||||
protected override void Render(HtmlTextWriter writer)
|
||||
{
|
||||
JavaScriptSerializer jss = new JavaScriptSerializer();
|
||||
string searchText, ftiFile;
|
||||
char letter;
|
||||
bool sortByTitle = false;
|
||||
|
||||
jss.MaxJsonLength = Int32.MaxValue;
|
||||
|
||||
// The keywords for which to search should be passed in the query string
|
||||
searchText = this.Request.QueryString["Keywords"];
|
||||
|
||||
if(String.IsNullOrEmpty(searchText))
|
||||
{
|
||||
writer.Write("<strong>Nothing found</strong>");
|
||||
return;
|
||||
}
|
||||
|
||||
// An optional SortByTitle option can also be specified
|
||||
if(this.Request.QueryString["SortByTitle"] != null)
|
||||
sortByTitle = Convert.ToBoolean(this.Request.QueryString["SortByTitle"]);
|
||||
|
||||
List<string> keywords = this.ParseKeywords(searchText);
|
||||
List<char> letters = new List<char>();
|
||||
List<string> fileList;
|
||||
Dictionary<string, List<long>> ftiWords, wordDictionary = new Dictionary<string,List<long>>();
|
||||
|
||||
// Load the file index
|
||||
using(StreamReader sr = new StreamReader(Server.MapPath("fti/FTI_Files.json")))
|
||||
{
|
||||
fileList = jss.Deserialize<List<string>>(sr.ReadToEnd());
|
||||
}
|
||||
|
||||
// Load the required word index files
|
||||
foreach(string word in keywords)
|
||||
{
|
||||
letter = word[0];
|
||||
|
||||
if(!letters.Contains(letter))
|
||||
{
|
||||
letters.Add(letter);
|
||||
ftiFile = Server.MapPath(String.Format(CultureInfo.InvariantCulture, "fti/FTI_{0}.json", (int)letter));
|
||||
|
||||
if(File.Exists(ftiFile))
|
||||
{
|
||||
using(StreamReader sr = new StreamReader(ftiFile))
|
||||
{
|
||||
ftiWords = jss.Deserialize<Dictionary<string, List<long>>>(sr.ReadToEnd());
|
||||
}
|
||||
|
||||
foreach(string ftiWord in ftiWords.Keys)
|
||||
wordDictionary.Add(ftiWord, ftiWords[ftiWord]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Perform the search and return the results as a block of HTML
|
||||
writer.Write(this.Search(keywords, fileList, wordDictionary, sortByTitle));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Split the search text up into keywords
|
||||
/// </summary>
|
||||
/// <param name="keywords">The keywords to parse</param>
|
||||
/// <returns>A list containing the words for which to search</returns>
|
||||
private List<string> ParseKeywords(string keywords)
|
||||
{
|
||||
List<string> keywordList = new List<string>();
|
||||
string checkWord;
|
||||
string[] words = Regex.Split(keywords, @"\W+");
|
||||
|
||||
foreach(string word in words)
|
||||
{
|
||||
checkWord = word.ToLower(CultureInfo.InvariantCulture);
|
||||
|
||||
if(checkWord.Length > 2 && !Char.IsDigit(checkWord[0]) && !keywordList.Contains(checkWord))
|
||||
keywordList.Add(checkWord);
|
||||
}
|
||||
|
||||
return keywordList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Search for the specified keywords and return the results as a block of HTML
|
||||
/// </summary>
|
||||
/// <param name="keywords">The keywords for which to search</param>
|
||||
/// <param name="fileInfo">The file list</param>
|
||||
/// <param name="wordDictionary">The dictionary used to find the words</param>
|
||||
/// <param name="sortByTitle">True to sort by title, false to sort by ranking</param>
|
||||
/// <returns>A block of HTML representing the search results</returns>
|
||||
private string Search(List<string> keywords, List<string> fileInfo,
|
||||
Dictionary<string, List<long>> wordDictionary, bool sortByTitle)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(10240);
|
||||
Dictionary<string, List<long>> matches = new Dictionary<string, List<long>>();
|
||||
List<long> occurrences;
|
||||
List<int> matchingFileIndices = new List<int>(), occurrenceIndices = new List<int>();
|
||||
List<Ranking> rankings = new List<Ranking>();
|
||||
|
||||
string filename, title;
|
||||
string[] fileIndex;
|
||||
bool isFirst = true;
|
||||
int idx, wordCount, matchCount;
|
||||
|
||||
foreach(string word in keywords)
|
||||
{
|
||||
if(!wordDictionary.TryGetValue(word, out occurrences))
|
||||
return "<strong>Nothing found</strong>";
|
||||
|
||||
matches.Add(word, occurrences);
|
||||
occurrenceIndices.Clear();
|
||||
|
||||
// Get a list of the file indices for this match
|
||||
foreach(long entry in occurrences)
|
||||
occurrenceIndices.Add((int)(entry >> 16));
|
||||
|
||||
if(isFirst)
|
||||
{
|
||||
isFirst = false;
|
||||
matchingFileIndices.AddRange(occurrenceIndices);
|
||||
}
|
||||
else
|
||||
{
|
||||
// After the first match, remove files that do not appear for
|
||||
// all found keywords.
|
||||
for(idx = 0; idx < matchingFileIndices.Count; idx++)
|
||||
if(!occurrenceIndices.Contains(matchingFileIndices[idx]))
|
||||
{
|
||||
matchingFileIndices.RemoveAt(idx);
|
||||
idx--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(matchingFileIndices.Count == 0)
|
||||
return "<strong>Nothing found</strong>";
|
||||
|
||||
// Rank the files based on the number of times the words occurs
|
||||
foreach(int index in matchingFileIndices)
|
||||
{
|
||||
// Split out the title, filename, and word count
|
||||
fileIndex = fileInfo[index].Split('\x0');
|
||||
|
||||
title = fileIndex[0];
|
||||
filename = fileIndex[1];
|
||||
wordCount = Convert.ToInt32(fileIndex[2]);
|
||||
matchCount = 0;
|
||||
|
||||
foreach(string word in keywords)
|
||||
{
|
||||
occurrences = matches[word];
|
||||
|
||||
foreach(long entry in occurrences)
|
||||
if((int)(entry >> 16) == index)
|
||||
matchCount += (int)(entry & 0xFFFF);
|
||||
}
|
||||
|
||||
rankings.Add(new Ranking(filename, title, matchCount * 1000 / wordCount));
|
||||
|
||||
if(rankings.Count > 99)
|
||||
break;
|
||||
}
|
||||
|
||||
// Sort by rank in descending order or by page title in ascending order
|
||||
rankings.Sort(delegate (Ranking x, Ranking y)
|
||||
{
|
||||
if(!sortByTitle)
|
||||
return y.Rank - x.Rank;
|
||||
|
||||
return x.PageTitle.CompareTo(y.PageTitle);
|
||||
});
|
||||
|
||||
// Format the file list and return the results
|
||||
sb.Append("<ol>");
|
||||
|
||||
foreach(Ranking r in rankings)
|
||||
sb.AppendFormat("<li><a href=\"{0}\" target=\"_blank\">{1}</a></li>", r.Filename, r.PageTitle);
|
||||
|
||||
sb.Append("</ol>");
|
||||
|
||||
if(rankings.Count < matchingFileIndices.Count)
|
||||
sb.AppendFormat("<p>Omitted {0} more results</p>", matchingFileIndices.Count - rankings.Count);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue