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 { /// /// Handles post-processing function calls. /// public class PostProcessingFunctionHandler : IPostProcessingFunctionHandler { private static FunctionPrototypeCollection? _collection; public FunctionPrototypeCollection Prototypes { get { if (_collection == null) { _collection = new FunctionPrototypeCollection(FunctionPrototypeCollection.WikiFunctionType.Standard); #region Prototypes. _collection.Add("##Tags: {styleName(Flat,List)}='List'"); _collection.Add("##TagCloud: [pageTag] | {Top}='1000'"); _collection.Add("##SearchCloud: [searchPhrase] | {Top}='1000'"); _collection.Add("##TOC:{alphabetized}='false'"); #endregion } return _collection; } } /// /// Called to handle function calls when proper prototypes are matched. /// /// Reference to the wiki state object /// The parsed function call and all its parameters and their values. /// This is not a scope function, this should always be null public HandlerResult Handle(IZelEngineState state, FunctionCall function, string? scopeBody = null) { switch (function.Name.ToLower()) { //------------------------------------------------------------------------------------------------------------------------------ //Displays a tag link list. case "tags": //##tags { string styleName = function.Parameters.Get("styleName").ToLower(); var html = new StringBuilder(); if (styleName == "list") { html.Append("
    "); foreach (var tag in state.Tags) { html.Append($"
  • {tag}"); } html.Append("
"); } else if (styleName == "flat") { foreach (var tag in state.Tags) { if (html.Length > 0) html.Append(" | "); html.Append($"{tag}"); } } return new HandlerResult(html.ToString()); } //------------------------------------------------------------------------------------------------------------------------------ case "tagcloud": { var top = function.Parameters.Get("Top"); string seedTag = function.Parameters.Get("pageTag"); string html = TagCloud.Build(seedTag, top); return new HandlerResult(html); } //------------------------------------------------------------------------------------------------------------------------------ case "searchcloud": { var top = function.Parameters.Get("Top"); var tokens = function.Parameters.Get("searchPhrase").Split(" ", StringSplitOptions.RemoveEmptyEntries).ToList(); string html = SearchCloud.Build(tokens, top); return new HandlerResult(html); } //------------------------------------------------------------------------------------------------------------------------------ //Displays a table of contents for the page based on the header tags. case "toc": { bool alphabetized = function.Parameters.Get("alphabetized"); var html = new StringBuilder(); var tags = (from t in state.TableOfContents orderby t.StartingPosition select t).ToList(); var unordered = new List(); var ordered = new List(); if (alphabetized) { int 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(); } int currentLevel = 0; foreach (var tag in tags) { if (tag.Level > currentLevel) { while (currentLevel < tag.Level) { html.Append("
    "); currentLevel++; } } else if (tag.Level < currentLevel) { while (currentLevel > tag.Level) { html.Append("
"); currentLevel--; } } html.Append("
  • " + tag.Text + "
  • "); } while (currentLevel > 0) { html.Append(""); currentLevel--; } return new HandlerResult(html.ToString()); } } return new HandlerResult() { Instructions = [Constants.HandlerResultInstruction.Skip] }; } } }