📄 formatter.cs
字号:
}
return res;
}
private static string ExtractBullets(string value) {
string res = "";
for(int i = 0; i < value.Length; i++) {
if(value[i] == '*' || value[i] == '#') res += value[i];
else break;
}
return res;
}
private static string BuildToc(List<HPosition> hPos) {
StringBuilder sb = new StringBuilder();
hPos.Sort(new HPositionComparer());
sb.Append(@"<div id=""TocContainer"">");
sb.Append(@"<p class=""small"">");
sb.Append(tocTitlePlaceHolder);
sb.Append("</p>");
sb.Append(@"<div id=""Toc"">");
sb.Append("<p><br />");
for(int i = 0; i < hPos.Count; i++) {
//Debug.WriteLine(i.ToString() + " " + hPos[i].Index.ToString() + ": " + hPos[i].Level);
switch(hPos[i].Level) {
case 1:
break;
case 2:
sb.Append(" ");
break;
case 3:
sb.Append(" ");
break;
case 4:
sb.Append(" ");
break;
}
if(hPos[i].Level == 1) sb.Append("<b>");
if(hPos[i].Level == 4) sb.Append("<small>");
sb.Append(@"<a href=""#");
sb.Append(BuildHAnchor(hPos[i].Text));
sb.Append(@""">");
sb.Append(hPos[i].Text);
sb.Append("</a>");
if(hPos[i].Level == 4) sb.Append("</small>");
if(hPos[i].Level == 1) sb.Append("</b>");
sb.Append("<br />");
}
sb.Append("</p>");
sb.Append("</div>");
sb.Append("</div>");
return sb.ToString();
}
private static string BuildHAnchor(string h) {
StringBuilder sb = new StringBuilder(h);
sb.Replace(" ", "_");
sb.Replace(".", "");
sb.Replace(",", "");
sb.Replace("\"", "");
sb.Replace("/", "");
sb.Replace("\\", "");
sb.Replace("'", "");
sb.Replace("(", "");
sb.Replace(")", "");
sb.Replace("[", "");
sb.Replace("]", "");
sb.Replace("{", "");
sb.Replace("}", "");
sb.Replace("<", "");
sb.Replace(">", "");
sb.Replace("#", "");
sb.Replace("\n", "");
sb.Replace("?", "");
sb.Replace("&", "");
sb.Replace("0", "A");
sb.Replace("1", "B");
sb.Replace("2", "C");
sb.Replace("3", "D");
sb.Replace("4", "E");
sb.Replace("5", "F");
sb.Replace("6", "G");
sb.Replace("7", "H");
sb.Replace("8", "I");
sb.Replace("9", "J");
return sb.ToString();
}
private static string EscapeUrl(string url) {
return url.Replace("&", "&");
}
private static string BuildTable(string table) {
// Proceed line-by-line, ignoring the first and last one
string[] lines = table.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
if(lines.Length < 3) {
return "<b>FORMATTER ERROR (Malformed Table)</b>";
}
StringBuilder sb = new StringBuilder();
sb.Append("<table");
if(lines[0].Length > 2) {
sb.Append(" ");
sb.Append(lines[0].Substring(3));
}
sb.Append(">");
int count = 1;
if(lines[1].Length >= 3 && lines[1].Trim().StartsWith("|+")) {
// Table caption
sb.Append("<caption>");
sb.Append(lines[1].Substring(3));
sb.Append("</caption>");
count++;
}
if(!lines[count].StartsWith("|-")) sb.Append("<tr>");
string item;
for(int i = count; i < lines.Length - 1; i++) {
if(lines[i].Trim().StartsWith("|-")) {
// New line
if(i != count) sb.Append("</tr>");
sb.Append("<tr");
if(lines[i].Length > 2) {
sb.Append(" ");
sb.Append(lines[i].Substring(3));
}
sb.Append(">");
}
else if(lines[i].Trim().StartsWith("|")) {
// Cell
if(lines[i].Length < 3) continue;
item = lines[i].Substring(2);
if(item.IndexOf(" || ") != -1) {
sb.Append("<td>");
sb.Append(item.Replace(" || ", "</td><td>"));
sb.Append("</td>");
}
else if(item.IndexOf(" | ") != -1) {
sb.Append("<td ");
sb.Append(item.Substring(0, item.IndexOf(" | ")));
sb.Append(">");
sb.Append(item.Substring(item.IndexOf(" | ") + 3));
sb.Append("</td>");
}
else {
sb.Append("<td>");
sb.Append(item);
sb.Append("</td>");
}
}
else if(lines[i].Trim().StartsWith("!")) {
// Header
if(lines[i].Length < 3) continue;
item = lines[i].Substring(2);
if(item.IndexOf(" !! ") != -1) {
sb.Append("<th>");
sb.Append(item.Replace(" !! ", "</th><th>"));
sb.Append("</th>");
}
else if(item.IndexOf(" ! ") != -1) {
sb.Append("<th ");
sb.Append(item.Substring(0, item.IndexOf(" ! ")));
sb.Append(">");
sb.Append(item.Substring(item.IndexOf(" ! ") + 3));
sb.Append("</th>");
}
else {
sb.Append("<th>");
sb.Append(item);
sb.Append("</th>");
}
}
}
if(sb.ToString().EndsWith("<tr>")) {
sb.Remove(sb.Length - 4 - 1, 4);
sb.Append("</table>");
}
else {
sb.Append("</tr></table>");
}
sb.Replace("<tr></tr>", "");
return sb.ToString();
}
private static string BuildIndent(string indent) {
int colons = 0;
indent = indent.Trim();
while(colons < indent.Length && indent[colons] == ':') colons++;
indent = indent.Substring(colons).Trim();
return @"<div style=""margin: 0px; padding: 0px; padding-left: " + ((int)(colons * 15)).ToString() + @"px"">" + indent + "</div>";
}
private static string BuildCloud() {
StringBuilder sb = new StringBuilder();
// Total categorized Pages (uncategorized Pages don't count)
int tot = Pages.Instance.AllPages.Count - Pages.Instance.GetUncategorizedPages().Length;
for(int i = 0; i < Pages.Instance.AllCategories.Count; i++) {
if(Pages.Instance.AllCategories[i].Pages.Length > 0) {
sb.Append(@"<a href=""AllPages.aspx?Cat=");
sb.Append(Tools.UrlEncode(Pages.Instance.AllCategories[i].Name));
sb.Append(@""" style=""font-size: ");
sb.Append(ComputeSize((float)Pages.Instance.AllCategories[i].Pages.Length / (float)tot * 100F).ToString());
sb.Append(@"px;"">");
sb.Append(Pages.Instance.AllCategories[i].Name);
sb.Append("</a>");
}
if(i != Pages.Instance.AllCategories.Count - 1) sb.Append(" ");
}
return sb.ToString();
}
private static int ComputeSize(float percentage) {
// Interpolates min and max size on a line, so that if:
// - percentage = 0 -> size = minSize
// - percentage = 100 -> size = maxSize
// - intermediate values are calculated
float minSize = 8, maxSize = 26;
//return (int)((maxSize - minSize) / 100F * (float)percentage + minSize); // Linear interpolation
return (int)(maxSize - (maxSize - minSize) * Math.Exp(-percentage / 25)); // Exponential interpolation
}
private static void ComputeNoWiki(string text, ref List<int> noWikiBegin, ref List<int> noWikiEnd) {
Match match;
noWikiBegin.Clear();
noWikiEnd.Clear();
match = noWiki.Match(text);
while(match.Success) {
noWikiBegin.Add(match.Index);
noWikiEnd.Add(match.Index + match.Length);
match = noWiki.Match(text, match.Index + match.Length);
}
}
private static bool IsNoWikied(int index, List<int> noWikiBegin, List<int> noWikiEnd, out int end) {
for(int i = 0; i < noWikiBegin.Count; i++) {
if(index > noWikiBegin[i] && index < noWikiEnd[i]) {
end = noWikiEnd[i];
return true;
}
}
end = 0;
return false;
}
/// <summary>
/// Performs the internal Phase 3 of the Formatting pipeline.
/// </summary>
/// <param name="raw">The raw data.</param>
/// <param name="current">The current PageInfo, if any.</param>
/// <returns>The formatted content.</returns>
public static string FormatPhase3(string raw, PageInfo current) {
StringBuilder sb = new StringBuilder();
StringBuilder dummy;
sb.Append(raw);
dummy = new StringBuilder("<b>");
dummy.Append(Exchanger.ResourceExchanger.GetResource("TableOfContents"));
dummy.Append(@"</b><span id=""ExpandTocSpan""> [<a href=""#"" onclick=""javascript:if(document.getElementById('Toc').style['display']=='none') document.getElementById('Toc').style['display']=''; else document.getElementById('Toc').style['display']='none'; return false;"">");
dummy.Append(Exchanger.ResourceExchanger.GetResource("HideShow"));
dummy.Append("</a>]</span>");
sb.Replace(tocTitlePlaceHolder, dummy.ToString());
sb.Replace(editSectionPlaceHolder, Exchanger.ResourceExchanger.GetResource("Edit"));
Match match;
string shift = "";
if(HttpContext.Current.Request.Cookies[Settings.CultureCookieName] != null) shift = HttpContext.Current.Request.Cookies[Settings.CultureCookieName]["T"];
match = sign.Match(sb.ToString());
while(match.Success) {
sb.Remove(match.Index, match.Length);
string txt = match.Value.Substring(3, match.Length - 6);
int idx = txt.LastIndexOf(",");
string[] fields = new string[] { txt.Substring(0, idx), txt.Substring(idx + 1) };
dummy = new StringBuilder();
dummy.Append(@"<span class=""signature""><a href=""Message.aspx?Username=");
dummy.Append(Tools.UrlEncode(fields[0]));
dummy.Append(@""">");
dummy.Append(fields[0]);
dummy.Append("</a>, ");
dummy.Append(Tools.AlignWithPreferences(DateTime.Parse(fields[1]), shift).ToString(Settings.DateTimeFormat));
dummy.Append("</span>");
sb.Insert(match.Index, dummy.ToString());
match = sign.Match(sb.ToString());
}
match = username.Match(sb.ToString());
while(match.Success) {
sb.Remove(match.Index, match.Length);
if(SessionFacade.LoginKey != null) sb.Insert(match.Index, SessionFacade.Username);
match = username.Match(sb.ToString());
}
return sb.ToString();
}
}
/// <summary>
/// Represents a Header.
/// </summary>
public class HPosition {
private int index;
private string text;
private int level;
private int id;
/// <summary>
/// Initializes a new instance of the <b>HPosition</b> class.
/// </summary>
/// <param name="index">The Index.</param>
/// <param name="text">The Text.</param>
/// <param name="level">The Header level.</param>
/// <param name="id">The Unique ID of the Header (0-based counter).</param>
public HPosition(int index, string text, int level, int id) {
this.index = index;
this.text = text;
this.level = level;
this.id = id;
}
/// <summary>
/// Gets or sets the Index.
/// </summary>
public int Index {
get { return index; }
set { index = value; }
}
/// <summary>
/// Gets or sets the Text.
/// </summary>
public string Text {
get { return text; }
set { text = value; }
}
/// <summary>
/// Gets or sets the Level.
/// </summary>
public int Level {
get { return level; }
set { level = value; }
}
/// <summary>
/// Gets or sets the ID (0-based counter).
/// </summary>
public int ID {
get { return id; }
set { id = value; }
}
}
/// <summary>
/// Compares HPosition objects.
/// </summary>
public class HPositionComparer : IComparer<HPosition> {
public int Compare(HPosition x, HPosition y) {
return x.Index.CompareTo(y.Index);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -