diff --git a/Extensions/RenderContentHtml.cs b/Extensions/RenderContentHtml.cs new file mode 100644 index 0000000..18056fc --- /dev/null +++ b/Extensions/RenderContentHtml.cs @@ -0,0 +1,72 @@ +namespace QuestReader.Extensions; + +using System.Web; +using QuestReader.Models; +using QuestReader.Models.ParsedContent; + +public static class RenderContentHtmlExtension +{ + public static string RenderContentHtml(this ContentNode node, TemplateModel model) + { + return node switch + { + RootNode rootNode => string.Join("", rootNode.Nodes.Select(n => n.RenderContentHtml(model))), + TextNode textNode => textNode.Text, + NewlineNode => "
\n", + ReferenceNode refNode => refNode.RenderReferenceHtml(model), + ContainerNode container => container.RenderContailerHtml(model), + _ => throw new NotImplementedException(), + }; + } + + + static string RenderContailerHtml(this ContainerNode node, TemplateModel model) + { + var tag = node switch + { + QuoteNode => "span", + BoldNode => "strong", + ItalicsNode => "em", + StrikeoutNode => "s", + UnderlineNode => "span", + SpoilerNode => "span", + ExternalLinkNode => "a", + null => throw new NullReferenceException("Node is null, something is ver wrong"), + _ => throw new NotImplementedException($"Rendering not implemented for {node.GetType().Name}"), + }; + + string? extra = node switch + { + QuoteNode quote => " class=\"text-quote\"", + UnderlineNode => " class=\"text-underline\"", + SpoilerNode => " class=\"text-spoiler\"", + ExternalLinkNode externalLink => $" href=\"{HttpUtility.HtmlAttributeEncode(externalLink.Destination)}\"", + _ => null, + }; + var content = string.Join("", node.Nodes.Select(n => n.RenderContentHtml(model))); + + // The spaces around this are absolutely stopgap and will NOT work for something like "abso-fucking-lutely" + // HTML is... frustrating + // Note for future implementation: don't trim, just collapse to single space + // Search regex "[^>\s;]<[^>]>". And yes there /are/ hits. Fuck! + return $" <{tag}{extra}>{content} "; + } + + static string RenderReferenceHtml(this ReferenceNode node, TemplateModel model) + { + var type = node.ReferenceType switch + { + ReferenceType.QuestActive => "quest", + ReferenceType.QuestArchive => "quest-archived", + ReferenceType.QuestDiscussion => "discussion", + _ => throw new NotImplementedException(), + }; + + var included = model.Metadata.Threads.Any(t => t == node.ThreadId) && model.Posts.Any(p => p.Id == node.PostId); + var href = ""; + if (included) + href = $"href=\"#post-{node.PostId}\" "; + + return $">>{node.PostId}"; + } +} \ No newline at end of file