/** * Prepares the given string s for presentation on an html * page. * * Enhances the method TextToHtml by permitting ranges of * the text to be highlighted. Each range is placed in a * span-tag with css class 'highlight'. Thus, the nature * of the highlighting is controlled by the css on the * page. * * Html encodes the special characters as follows: * * single quote: "'" * double quote: """ * less than: "<" * greater than: ">" * ampersand: "&" * * Replaces tabs by blanks relative to the given tabsize. * Default: tabsize = 4 * * Prefaces each line with a line number if desired. * Default: showlinenumbers = true * * Permits the caller to decide whether to show all lines or * to show only the lines with highlights. * Default: showall = false * * The reason for these defaults is that this method is used * to show the results of a search. In this situation, the * user is most interested in seeing the lines that contain * search results and not all other lines. By setting * showlinenumbers = true * showall = false * the lines that contain search results are identified and * no other lines are displayed. * * Line numbers displayed start at 1 to follow the pattern * used in Visual Studio. * * There is an interesting edge case if no ranges are given * to be highlighted. In that case: * * If showall=false, there is nothing to show and this * method returns an empty string. * * If showall=true, this method simply calls TextToHtml. * * If any transformations take place then the return string * normalizes the line breaks to '\n'. * * The result of this method should be displayed using * preformatted text, that is, via a pre-tag or via the css * setting white-space:pre. */ public static string HighlightMarkup (string s, List <Range> highlightlist, int tabsize = 4, bool showlinenumbers = true, bool showall = false) { if (IsTrivial(s)) { return(s); } if (IsTrivial(highlightlist)) { if (showall) { return(TextToHtml(s, tabsize, showlinenumbers)); } else { return(""); } } StringBuilder builder = new StringBuilder(); int length = s.Length; // Set up for line processing List <Range> linerangelist = StringTools.LineRangeList(s); int linecount = linerangelist.Count; int lineindex = 0; // Set up for highlight processing int highcount = highlightlist.Count; int highindex = 0; // data for dealing with the highlight overlap range list // for hightlight ranges than intersect a line range // overlap: the list of highlight range overlaps // overlapcount = overlap.Count // next: next highlight overlap range to process // nextrange = overlap[next] // open: nextrange.start // shut: nextrange.limit List <Range> overlap = null; int overlapcount = 0; int next = 0; Range nextrange; int open = -1; int shut = -1; while (lineindex < linecount) { // process the line at the lineindex Range linerange = linerangelist[lineindex]; int start = linerange.start; int limit = linerange.limit; // increment lineindex here // since visible line numbers start at 1 // // this guarantees that lineindex is updated // if this line will be skipped later because // it has no highlights lineindex++; // construct the overlap highlight ranges that // intersect this line range, if any overlap = null; overlapcount = 0; if (highindex < highcount) { while ((highindex < highcount) && (highlightlist[highindex].limit < start)) { highindex++; } while ((highindex < highcount) && (highlightlist[highindex].start < limit)) { Range?r = Range.Intersect(linerange, highlightlist[highindex]); if (r.HasValue) { Range rv = r.Value; if (rv.length > 0) { if (overlap == null) { overlap = new List <Range>(); } overlap.Add(rv); } if (highlightlist[highindex].limit <= limit) { highindex++; } else { break; } } else { break; } } } if (overlap != null) { overlapcount = overlap.Count; } // skip this line if // showall is false // and // there is no highlight to do if ((!showall) && (overlapcount == 0)) { continue; } // if showlinenumbers is true, add the line number // at this stage of the processing if (showlinenumbers) { builder.Append(lineindex.ToString("000000 ")); } // index is the character position in the string int index = start; // position is the character position on the line // after any earlier replacement of tabs by blanks // // characters used for the line number are ignored int position = 0; // get set to process highlights next = 0; if (next < overlapcount) { nextrange = overlap[next]; open = nextrange.start; shut = nextrange.limit; } else { open = -1; shut = -1; } while (index < limit) { // step 1: deal with highlight at this index if (index == shut) { builder.Append(highlightshut); next++; if (next < overlapcount) { nextrange = overlap[next]; open = nextrange.start; shut = nextrange.limit; } else { open = -1; shut = -1; } } if (index == open) { builder.Append(highlightopen); } // step 2: deal with character at this index char c = s[index]; if (c == '\t') { if (tabsize > 0) { int spaces = tabsize - (position % tabsize); for (int i = 0; i < spaces; i++) { builder.Append(' '); } position += spaces; } else { builder.Append(c); position++; } } else { if (isHtmlSpecial(c)) { builder.Append(HtmlEncode(c)); } else { builder.Append(c); } position++; } index++; } if (limit == shut) { builder.Append(highlightshut); } if (limit < length) { builder.Append('\n'); } } return(builder.ToString()); }
/* * Returns the unescaped version of * * request.Url.OriginalString * * using the method * * StringTools.Unescape */ public static string Url(HttpRequest request) { return(StringTools.Unescape(request.Url.OriginalString)); }
/* * Returns a string with the tabs in s converted to blanks * based on the given tabsize. * * If omitted, tabsize defaults to 4. * * Returns the original string if: * s is trivial * s does not contain a tab character * The given tabsize is less than or equal to 0 * * This method simply converts tabs and does no other task. * * If tabs are converted then the return string normalizes * the line breaks to '\n'. */ public static string TabsToBlanks (string s, int tabsize = 4) { if (IsTrivial(s)) { return(s); } if (tabsize <= 0) { return(s); } if (!hasTabRegex.IsMatch(s)) { return(s); } StringBuilder builder = new StringBuilder(); int length = s.Length; List <Range> linerangelist = StringTools.LineRangeList(s); int linecount = linerangelist.Count; int lineindex = 0; while (lineindex < linecount) { // process the line at the lineindex Range linerange = linerangelist[lineindex]; int start = linerange.start; int limit = linerange.limit; // increment lineindex here lineindex++; // index is the character position in the string int index = start; // position is the character position on the line // after any earlier replacement of tabs by blanks int position = 0; while (index < limit) { char c = s[index]; if (c == '\t') { int spaces = tabsize - (position % tabsize); for (int i = 0; i < spaces; i++) { builder.Append(' '); } position += spaces; } else { builder.Append(c); position++; } index++; } if (limit < length) { builder.Append('\n'); } } return(builder.ToString()); }
/** * Prepares the given string s for presentation on an html * page. * * Html encodes the special characters as follows: * * single quote: "'" * double quote: """ * less than: "<" * greater than: ">" * ampersand: "&" * * Replaces tabs by blanks relative to the given tabsize. * Default: tabsize = 4 * * Prefaces each line with a line number if desired. * Default: showlinenumbers = false * * Line numbers displayed start at 1 to follow the pattern * used in Visual Studio. * * Will return the original string s if s does not need any * of the following transformations: * html encoding * tabs to blanks * line numbering * * If any transformations take place then the return string * normalizes the line breaks to '\n'. * * The result of this method should be displayed using * preformatted text, that is, via a pre-tag or via the css * setting white-space:pre. */ public static string TextToHtml (string s, int tabsize = 4, bool showlinenumbers = false) { if (IsTrivial(s)) { return(s); } bool replaceHtml = hasHtmlSpecialRegex.IsMatch(s); bool replaceTabs = (tabsize > 0) && (hasTabRegex.IsMatch(s)); bool needsWork = replaceHtml || replaceTabs || showlinenumbers; if (!needsWork) { return(s); } StringBuilder builder = new StringBuilder(); int length = s.Length; List <Range> linerangelist = StringTools.LineRangeList(s); int linecount = linerangelist.Count; int lineindex = 0; while (lineindex < linecount) { // process the line at the lineindex Range linerange = linerangelist[lineindex]; int start = linerange.start; int limit = linerange.limit; // increment lineindex here // since visible line numbers start at 1 lineindex++; // if showlinenumbers is true, add the line number if (showlinenumbers) { builder.Append(lineindex.ToString("000000 ")); } // index is the character position in the string int index = start; // position is the character position on the line // after any earlier replacement of tabs by blanks // // characters used for the line number are ignored int position = 0; while (index < limit) { char c = s[index]; if (c == '\t') { if (tabsize > 0) { int spaces = tabsize - (position % tabsize); for (int i = 0; i < spaces; i++) { builder.Append(' '); } position += spaces; } else { builder.Append(c); position++; } } else { if (isHtmlSpecial(c)) { builder.Append(HtmlEncode(c)); } else { builder.Append(c); } position++; } index++; } if (limit < length) { builder.Append('\n'); } } return(builder.ToString()); }
/// <summary> /// Searches for the given pattern in the file starting at the /// start line. /// /// Will stop searching after max successful lines are emitted. /// /// If max lines are never emitted then will search until the /// end of the file. This may unfortunately be slow when the /// file is very large. /// </summary> /// <param name="server">The server to convert to real file paths</param> /// <param name="tildeFilePath">The tilde file path</param> /// <param name="pattern">The search pattern</param> /// <param name="isRegex">If true, the pattern is a regex</param> /// <param name="ignoreCase">If true, do case-insensitive search</param> /// <param name="StartLine">The start line for the list</param> /// <param name="MaxLines">The maximum number of lines to list</param> /// <param name="showLineNumbers">If true, show line numbers</param> /// <returns></returns> public static string ListLinesFromSearch (HttpServerUtility server, string tildeFilePath, string pattern, bool isRegex, bool ignoreCase, long StartLine, long MaxLines, bool showLineNumbers, bool showAllLines) { if (StringTools.IsTrivial(pattern)) { return(""); } StringBuilder builder = new StringBuilder(); string filePath = null; FileInfo info = null; if (TildeFilePathExistsAndIsText(server, tildeFilePath, ref filePath, ref info)) { if (StartLine < 1) { StartLine = 1; } if (MaxLines < 1) { MaxLines = 1; } long LineNumber = 1; long FoundMatch = 0; using (StreamReader reader = new StreamReader(filePath)) { // Skip lines up to StartLine while ((LineNumber < StartLine) && !reader.EndOfStream) { string foobar = reader.ReadLine(); LineNumber++; } if (reader.EndOfStream) { NoLinesErrorMessage(builder); } else { builder.Append("<pre>"); while ((FoundMatch < MaxLines) && !reader.EndOfStream) { string line = reader.ReadLine(); List <Range> range = SearchTools.Search (line, pattern, 0, isRegex, ignoreCase); if (showAllLines || (range.Count > 0)) { string result = StringTools.HighlightMarkupForOneLine (line, range, 4, showLineNumbers, LineNumber); builder.Append(result); builder.Append("\n"); FoundMatch++; } LineNumber++; } if (FoundMatch > 0) { builder.Append("</pre>\n"); } else { builder = new StringBuilder(); NoLinesErrorMessage(builder); } } } } else { TildeFilePathErrorMessage(builder); } return(builder.ToString()); }
/// <summary> /// Returns a list of lines in a file. /// /// If trim is true then all lines are trimmed and any lines /// that then have length 0 are discarded. /// /// If trim is false then all lines are added unchanged. /// /// The file path is an absolute path. /// /// This method is a generalization of a method originally /// in the Teaching Preferences web application. /// /// If an exception occurs, a list with 0 items will be /// returned. /// /// In August 2009, refactored to use StringTools.LineList. /// </summary> /// <param name="filepath">The absolute file path</param> /// <returns>The list of the non-empty lines</returns> public static List <string> FileDataAbsolutePath(string filepath, bool trim) { string content = GetFileAsText(filepath); return(StringTools.LineList(content, trim)); }
/// <summary> /// Returns the markup from the search /// of a file given its tilde path. /// /// Preconditions: The page that calls this method must: /// /// 1. Have executed the call /// /// SourceTools.LoadCSSandJavascript(this); /// /// during the initial call to PageLoad. /// /// 2. Be able to guarantee that the file is OK to serve /// in context. /// </summary> /// <param name="page"> /// The page calling this method</param> /// <param name="tildeFilePath"> /// The file to search</param> /// <param name="pattern"> /// The search pattern</param> /// <param name="isRegex"> /// Is the pattern a regular expression?</param> /// <param name="ignoreCase"> /// Ignore case in the search?</param> /// <param name="statistics"> /// Include file statistics markup?</param> /// <param name="download"> /// Include download button markup?</param> /// <param name="showAllLines"> /// Show all lines in the file?</param> /// <param name="onlyPublic"> /// Whether or not to restrict to public directories</param> public static string SearchFileMarkup (Page page, string tildeFilePath, string pattern, bool isRegex, bool ignoreCase, bool statistics, bool download, bool showAllLines, bool onlyPublic) { string content = null; List <Range> nameMatches = SearchFileName(tildeFilePath, pattern, isRegex, ignoreCase); List <Range> contentMatches = SearchFileContent (page, tildeFilePath, pattern, isRegex, ignoreCase, out content); bool matchName = !StringTools.IsTrivial(nameMatches); bool matchContent = !StringTools.IsTrivial(contentMatches); if (!(matchName || matchContent)) { return(""); } StringBuilder builder = new StringBuilder(); // markup for highlighted tilde file path // with possible file view link string markupText = matchName ? StringTools.HighlightMarkup(tildeFilePath, nameMatches, 4, false, true) : tildeFilePath; long bytes; DateTime?created; DateTime?modified; builder.Append (SourceTools.StatisticsMarkup (page, tildeFilePath, markupText, onlyPublic, true, true, statistics, download, null, out bytes, out created, out modified)); // markup for highlighted content if (matchContent) { builder.Append(HTML_Tools.open_pre); builder.Append (StringTools.HighlightMarkup (content, contentMatches, 4, true, showAllLines)); builder.Append(HTML_Tools.shut_pre); builder.Append("\n"); } return(builder.ToString()); }
/// <summary> /// Return the HTML string to list consecutive lines in the file. /// /// The returned string has all required HTML to plug into a page. /// </summary> /// <param name="server">The server to convert to real file paths</param> /// <param name="tildeFilePath">The tilde file path</param> /// <param name="StartLine">The start line for the list</param> /// <param name="MaxLines">The maximum number of lines to list</param> /// <param name="showLineNumbers">If true, show line numbers</param> public static string ListLines (HttpServerUtility server, string tildeFilePath, long StartLine, long MaxLines, bool showLineNumbers) { StringBuilder builder = new StringBuilder(); string filePath = null; FileInfo info = null; if (TildeFilePathExistsAndIsText(server, tildeFilePath, ref filePath, ref info)) { if (StartLine < 1) { StartLine = 1; } if (MaxLines < 1) { MaxLines = 1; } long LineNumber = 1; using (StreamReader reader = new StreamReader(filePath)) { // Skip lines up to StartLine while ((LineNumber < StartLine) && !reader.EndOfStream) { string foobar = reader.ReadLine(); LineNumber++; } if (reader.EndOfStream) { NoLinesErrorMessage(builder); } else { builder.Append("<pre>"); long FinishLine = StartLine + MaxLines - 1; while ((LineNumber <= FinishLine) && !reader.EndOfStream) { string line = reader.ReadLine(); string result = StringTools.HighlightMarkupForOneLine (line, null, 4, showLineNumbers, LineNumber); builder.Append(result); builder.Append("\n"); LineNumber++; } builder.Append("</pre>\n"); } } } else { TildeFilePathErrorMessage(builder); } return(builder.ToString()); }
/* * The main method of this IHttpHandler. */ public void ProcessRequest(HttpContext context) { string url = context.Request.Url.OriginalString; string embeddedUrl = GetEmbeddedParameter(url, "url=", true); HttpWebResponse response = null; if (!StringTools.IsTrivial(embeddedUrl)) { response = GetResponse(embeddedUrl); } if (response == null) { ProcessRequestError(context, embeddedUrl, ""); return; } int status = (int)response.StatusCode; context.Response.StatusCode = status; if ((status < 200) || (status > 299)) { ProcessRequestError(context, embeddedUrl, "Status = " + status); } string host = response.Headers.Get("Host"); if (StringTools.IsTrivial(host)) { try { Uri uri = new Uri(embeddedUrl); host = uri.Host; } catch { } } if (!StringTools.IsTrivial(host)) { context.Response.AppendHeader("Host", host); } try { using (Stream stream = response.GetResponseStream()) { using (StreamReader reader = new StreamReader(stream)) { string content = reader.ReadToEnd(); if (!StringTools.IsTrivial(content)) { if (usePreTag(url)) { context.Response.ContentType = "text/html"; content = HTML_Tools.FeedbackData(content); } else if (useXml(url)) { context.Response.ContentType = "text/xml"; } else { context.Response.ContentType = "text/plain"; } context.Response.Write(content); } else { context.Response.ContentType = "text/plain"; context.Response.Write(""); } } } } catch { ProcessRequestError(context, embeddedUrl, "Error in reading Url content"); } }
/// <summary> /// Constructs a DateTime using input formatted as in the /// method ToYMDHMS or using the special strings "now" /// and "today". Input is case insensitive. /// /// Allows the string "now" to return DateTime.Now. /// /// Allows the string "today" to return the first moment /// of today, that is, DateTime.Now adjusted so that the /// hours, minutes, seconds, and milliseconds are 0. /// /// Further allows "today-N" where N is a positive integer /// string value. This will yield N days before the first /// moment of today. /// /// Aside from the special strings, the input should /// consist only of digits, hyphens, and underscores just /// as in ToYMDHMS. Parsing stops and uses what has been /// read so far if the input fails to match the pattern /// expected. Unread fields use the following defaults: /// /// year = DateTime.Now.Year /// month = 1 /// day = 1 /// hour = 0 /// minute = 0 /// second = 0 /// millisecond = 0 /// /// In particular, FromYMDHMS("") returns the first moment /// of the current year. /// /// Input fields are forced to satisfy the following rules: /// /// 1 LE year /// 1 LE month LE 12 /// 1 LE day LE 31 /// 0 LE hour LE 23 /// 0 LE minute LE 59 /// 0 LE second LE 59 /// 0 LE millisecond LE 999 /// /// The symbol LE is used for "less than or equal" because /// this comment is XML and does not allow the real symbol /// for "less than". /// /// Finally, for months that do not allow 31 days, the day /// is forced downward into the correct range. /// </summary> public static DateTime FromYMDHMS(string YMDHMS) { DateTime Now = DateTime.Now; int year = Now.Year; int month = 1; int day = 1; int hour = 0; int minute = 0; int second = 0; int millisecond = 0; if (StringTools.IsTrivial(YMDHMS)) { goto returnStatement; } YMDHMS = YMDHMS.ToLower(); if (YMDHMS == "now") { return(DateTime.Now); } int length = YMDHMS.Length; int position = 0; char c; char hyphen = '-'; char underscore = '_'; if (length >= 5) { string chunk = YMDHMS.Substring(0, 5); if (chunk == "today") { month = Now.Month; day = Now.Day; DateTime Today = new DateTime(year, month, day, 0, 0, 0, 0); if (length == 5) { return(Today); } position = 5; c = YMDHMS[position]; if (c == hyphen) { position++; } else { return(Today); } int delta = GetNextInt(YMDHMS, length, ref position, 0, int.MaxValue); return(Today.AddDays(-delta)); } } // handle year year = GetNextInt(YMDHMS, length, ref position, 1, int.MaxValue); if (position >= length) { goto returnStatement; } c = YMDHMS[position]; if (c == hyphen) { position++; } else { goto returnStatement; } // handle month month = GetNextInt(YMDHMS, length, ref position, 1, 12); if (position >= length) { goto returnStatement; } c = YMDHMS[position]; if (c == hyphen) { position++; } else { goto returnStatement; } // handle day day = GetNextInt(YMDHMS, length, ref position, 1, 31); if (position >= length) { goto returnStatement; } c = YMDHMS[position]; if (c == underscore) { position++; } else { goto returnStatement; } // handle hour hour = GetNextInt(YMDHMS, length, ref position, 0, 23); if (position >= length) { goto returnStatement; } c = YMDHMS[position]; if (c == hyphen) { position++; } else { goto returnStatement; } // handle minute minute = GetNextInt(YMDHMS, length, ref position, 0, 59); if (position >= length) { goto returnStatement; } c = YMDHMS[position]; if (c == hyphen) { position++; } else { goto returnStatement; } // handle second second = GetNextInt(YMDHMS, length, ref position, 0, 59); if (position >= length) { goto returnStatement; } c = YMDHMS[position]; if (c == underscore) { position++; } else { goto returnStatement; } // handle millisecond millisecond = GetNextInt(YMDHMS, length, ref position, 0, 999); returnStatement: DateTime datetime = DateTime.Now; while (true) { try { datetime = new DateTime(year, month, day, hour, minute, second, millisecond); break; } catch { day--; } if (day < 1) { datetime = DateTime.Now; break; } } return(datetime); }
/// <summary> /// Returns a link to the file view utility for the file with /// the given tilde path. /// /// Returns an empty string if an error occurs. /// </summary> /// <param name="context">Web site HttpContext object</param> /// <param name="tildeFilePath">A file tilde path</param> public static string MakeFileViewLinkMarkup (HttpContext context, string tildeFilePath) { try { if (context == null) { return(""); } if (StringTools.IsTrivial(tildeFilePath)) { return(""); } if (!tildeFilePath.StartsWith(SourceTools.tildeStart)) { return(""); } string filename = HttpContextTools.GetFileName(tildeFilePath); string fileviewPath = HttpContextTools. MakeMergedPath(context, fileviewTildePath); StringBuilder builder = new StringBuilder(); builder.Append(openFileViewMarkup); // Download button builder.Append(Download1); builder.Append(tildeFilePath); builder.Append(Download2); // FileView link builder.Append(HTML_Tools.open_span); builder.Append(HTML_Tools.open_anchor); builder.Append(fileviewPath); builder.Append("?"); builder.Append(tildeFilePath); builder.Append(HTML_Tools.mid_anchor_blank); builder.Append(HTML_Tools.open_code); builder.Append(filename); builder.Append(HTML_Tools.shut_code); builder.Append(HTML_Tools.shut_anchor); builder.Append(HTML_Tools.shut_span); // Data for the file string filePath = context.Server.MapPath(tildeFilePath); FileInfo info = new FileInfo(filePath); // bytes long bytes = info.Length; builder.Append(HTML_Tools.open_span); builder.Append(bytes.ToString()); builder.Append(HTML_Tools.shut_span); // most recent date and time DateTime mostrecent = info.MostRecentTime(); builder.Append(HTML_Tools.open_span); builder.Append(mostrecent.ToYMD()); builder.Append(HTML_Tools.shut_span); builder.Append(HTML_Tools.open_span); builder.Append(mostrecent.ToHMS()); builder.Append(HTML_Tools.shut_span); builder.Append(shutFileViewMarkup); return(builder.ToString()); } catch (Exception) { return(""); } }
/// <summary> /// Returns the markup for links to the list of /// subdirectories of the web directory of the context. /// /// Removes subdirectories that begin with "~/app_". /// /// After each subdirectory name in a link, inserts a /// slash and then a reference to the given filename. /// /// The filename may be: /// /// * Empty, so a default servable file will be used. /// /// * A pseudo filename handled by an IHttpHandler. /// /// * Some other filename known to be present in all /// subdirectories. /// /// * Null, which is treated as empty. /// /// If there are no subdirectories, then then the empty /// string will be returned as the markup. /// /// The optional comment heads the list of subdirectory /// names. If omitted, a default comment is constructed. /// </summary> /// <param name="context">Web site HttpContext object</param> /// <param name="filename">The target file name</param> /// <param name="comment">Optional comment to head list</param> /// <param name="onlyPublic">If true restrict to public subdirectories</param> public static string MakeSubdirectoryLinkMarkup (HttpContext context, string filename, string comment, bool onlyPublic) { if (context == null) { return(""); } if (filename == null) { filename = ""; } string tildeDirectoryPath = HttpContextTools.GetTildeDirectoryPath(context); List <string> subnames = HttpContextTools.MakeSubdirectoryList(context, onlyPublic); // Remove names that would lead to paths // that begin with "~/app_". List <string> remove = new List <string>(); foreach (string name in subnames) { string subpath = tildeDirectoryPath + name + "/"; if (!subpath.ToLower().StartsWith("~/app_")) { continue; } remove.Add(name); } foreach (string name in remove) { subnames.Remove(name); } int count = subnames.Count; if (count == 0) { return(""); } StringBuilder builder = new StringBuilder(); builder.Append(HTML_Tools.open_p); if (StringTools.IsTrivial(comment)) { builder.Append("Subdirectories of "); builder.Append(tildeDirectoryPath); builder.Append(" ["); builder.Append(count); builder.Append("]:"); } else { builder.Append(comment); } builder.Append(HTML_Tools.shut_p); foreach (string name in subnames) { string subpath = tildeDirectoryPath + name + "/"; string directorylink = MakeDirectoryLink(context, subpath, filename); builder.Append(directorylink); } return(builder.ToString()); }
/// <summary> /// Returns the markup for the list of files /// that reside in the context web directory /// and that match the given file type. /// /// Each file name will link to the file viewer. /// /// The filetype should take one of seven values: /// 1: Text files /// 2: Image files /// 3: Viewable files, that is, text or image files /// 4: Non-viewable files /// 5: Text files plus non-viewable files /// 6: Image files plus non-viewable files /// 7: All files /// /// If no files match the filetype then the empty /// string will be returned as the markup. /// /// The optional comment heads the list of file names. /// If omitted, a default comment is provided. /// </summary> /// <param name="context">Web site HttpContext object</param> /// <param name="fileType">The filetype mask</param> /// <param name="comment">Optional comment to head list</param> /// <param name="extras">If true show extras</param> public static string MakeFileListMarkup (HttpContext context, int fileType, string comment) { if (context == null) { return(""); } fileType &= FileTools.ALL; if (fileType == 0) { return(""); } List <string> filelist = HttpContextTools.MakeFileList(context, fileType); int count = filelist.Count; if (count == 0) { return(""); } string tildeDirectoryPath = HttpContextTools.GetTildeDirectoryPath(context); StringBuilder builder = new StringBuilder(); builder.Append(HTML_Tools.open_p); if (StringTools.IsTrivial(comment)) { switch (fileType) { case 1: builder.Append("Text files in "); break; case 2: builder.Append("Image files in "); break; case 3: builder.Append("Viewable files in "); break; case 4: builder.Append("Non-viewable files in "); break; case 5: builder.Append("Text and non-viewable files in "); break; case 6: builder.Append("Image and non-viewable files in "); break; case 7: builder.Append("All files in "); break; default: break; } builder.Append(tildeDirectoryPath); builder.Append(" ["); builder.Append(count); builder.Append("]:"); } else { builder.Append(comment); } builder.Append(HTML_Tools.shut_p); foreach (string filename in filelist) { string tildeFilePath = tildeDirectoryPath + filename; string filelink = MakeFileViewLinkMarkup(context, tildeFilePath); builder.Append(filelink); } return(builder.ToString()); }