Files
ZelWiki/ZelWiki.Engine.Implementation/PostProcessingFunctionHandler.cs
2025-02-23 18:47:21 +08:00

169 lines
6.0 KiB
C#

using System.Text;
using ZelWiki.Engine.Function;
using ZelWiki.Engine.Implementation.Utility;
using ZelWiki.Engine.Library;
using ZelWiki.Engine.Library.Interfaces;
using ZelWiki.Models;
namespace ZelWiki.Engine.Implementation
{
/// <summary>
/// 处理后处理函数调用.
/// </summary>
public class PostProcessingFunctionHandler : IPostProcessingFunctionHandler
{
private static FunctionPrototypeCollection? _collection;
public FunctionPrototypeCollection Prototypes
{
get
{
if (_collection == null)
{
_collection =
new FunctionPrototypeCollection(FunctionPrototypeCollection.WikiFunctionType.Standard);
#region
_collection.Add("##Tags: <string>{styleName(Flat,List)}='List'");
_collection.Add("##TagCloud: <string>[pageTag] | <integer>{Top}='1000'");
_collection.Add("##SearchCloud: <string>[searchPhrase] | <integer>{Top}='1000'");
_collection.Add("##TOC:<bool>{alphabetized}='false'");
#endregion
}
return _collection;
}
}
/// <summary>
/// 当匹配到合适的原型时,调用它来处理函数调用。
/// </summary>
/// <param name="state"></param>
/// <param name="function"></param>
/// <param name="scopeBody"></param>
/// <returns></returns>
public HandlerResult Handle(IZelEngineState state, FunctionCall function, string? scopeBody = null)
{
switch (function.Name.ToLower())
{
case "tags": //##tags
{
var styleName = function.Parameters.Get<string>("styleName").ToLower();
var html = new StringBuilder();
if (styleName == "list")
{
html.Append("<ul>");
foreach (var tag in state.Tags)
{
html.Append($"<li><a href=\"{GlobalConfiguration.BasePath}/Tag/Browse/{tag}\">{tag}</a>");
}
html.Append("</ul>");
}
else if (styleName == "flat")
{
foreach (var tag in state.Tags)
{
if (html.Length > 0) html.Append(" | ");
html.Append($"<a href=\"{GlobalConfiguration.BasePath}/Tag/Browse/{tag}\">{tag}</a>");
}
}
return new HandlerResult(html.ToString());
}
case "tagcloud":
{
var top = function.Parameters.Get<int>("Top");
string seedTag = function.Parameters.Get<string>("pageTag");
string html = TagCloud.Build(seedTag, top);
return new HandlerResult(html);
}
case "searchcloud":
{
var top = function.Parameters.Get<int>("Top");
var tokens = function.Parameters.Get<string>("searchPhrase")
.Split(" ", StringSplitOptions.RemoveEmptyEntries).ToList();
string html = SearchCloud.Build(tokens, top);
return new HandlerResult(html);
}
case "toc":
{
var alphabetized = function.Parameters.Get<bool>("alphabetized");
var html = new StringBuilder();
var tags = (from t in state.TableOfContents
orderby t.StartingPosition
select t).ToList();
var unordered = new List<TableOfContentsTag>();
var ordered = new List<TableOfContentsTag>();
if (alphabetized)
{
var level = tags.FirstOrDefault()?.Level ?? 0;
foreach (var tag in tags)
{
if (level != tag.Level)
{
ordered.AddRange(unordered.OrderBy(o => o.Text));
unordered.Clear();
level = tag.Level;
}
unordered.Add(tag);
}
ordered.AddRange(unordered.OrderBy(o => o.Text));
unordered.Clear();
tags = ordered.ToList();
}
var currentLevel = 0;
foreach (var tag in tags)
{
if (tag.Level > currentLevel)
{
while (currentLevel < tag.Level)
{
html.Append("<ul>");
currentLevel++;
}
}
else if (tag.Level < currentLevel)
{
while (currentLevel > tag.Level)
{
html.Append("</ul>");
currentLevel--;
}
}
html.Append("<li><a href=\"#" + tag.HrefTag + "\">" + tag.Text + "</a></li>");
}
while (currentLevel > 0)
{
html.Append("</ul>");
currentLevel--;
}
return new HandlerResult(html.ToString());
}
}
return new HandlerResult() { Instructions = [Constants.HandlerResultInstruction.Skip] };
}
}
}