using System.Text; using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Mvc.Rendering; using AsciiDocNet; using Yavsc.Models.Blog; using System.Linq.Expressions; namespace Yavsc.Helpers { public static class AsciiDocHelpers { static void ToHtml(this IElement elt, IHtmlContentBuilder contentbuilder) { switch (elt.GetType().FullName) { case "AsciiDocNet.Paragraph": Paragraph p = (Paragraph)elt; contentbuilder.AppendHtmlLine("

"); foreach (var pitem in p) { pitem.ToHtml(contentbuilder); } contentbuilder.AppendHtmlLine("

"); break; case "AsciiDocNet.SectionTitle": SectionTitle stitle = (SectionTitle)elt; contentbuilder.AppendHtmlLine($""); foreach (var titem in stitle) { titem.ToHtml(contentbuilder); } contentbuilder.AppendHtmlLine(""); break; case "AsciiDocNet.UnorderedList": UnorderedList ul = (UnorderedList)elt; contentbuilder.AppendHtmlLine(""); break; case "AsciiDocNet.Source": Source source = (Source)elt; // TODO syntact hilighting and fun js modules contentbuilder.AppendHtmlLine("
");
                    contentbuilder.Append(source.Text);
                    contentbuilder.AppendHtmlLine("
"); break; default: string unsupportedType = elt.GetType().FullName; throw new InvalidProgramException(unsupportedType); } } public static string GetValidHRef(this Link link) { if (link.Href.StartsWith("link:\\")) return link.Href.Substring(7); if (link.Href.StartsWith("link:")) return link.Href.Substring(5); return link.Href; } static void ToHtml(this IInlineElement elt, IHtmlContentBuilder sb) { switch (elt.GetType().FullName) { case "AsciiDocNet.Link": Link link = (Link)elt; Uri uri; if (Uri.TryCreate(link.Href, UriKind.RelativeOrAbsolute , out uri)) { if (string.IsNullOrEmpty(link.Text)) { link.Text = $"{uri.Host}({uri.LocalPath})"; } } sb.AppendFormat("{1} ", link.GetValidHRef(), link.Text); break; case "AsciiDocNet.TextLiteral": var tl = elt as TextLiteral; if (tl.Attributes.Anchor!=null) { sb.AppendFormat("{1} ", tl.Attributes.Anchor.Id, tl.Attributes.Anchor.XRefLabel); } sb.Append(tl.Text); break; case "AsciiDocNet.Emphasis": sb.AppendHtml(""); AsciiDocNet.Emphasis em = (Emphasis)elt; sb.Append(em.Text); sb.AppendHtml(""); break; case "AsciiDocNet.Strong": sb.AppendHtml(""); AsciiDocNet.Strong str = (Strong)elt; foreach (var stritem in str) { stritem.ToHtml(sb); } sb.AppendHtml(""); break; case "AsciiDocNet.InternalAnchor": InternalAnchor a = (InternalAnchor) elt; sb.AppendFormat("{1} ", a.Id, a.XRefLabel); break; default: string unsupportedType = elt.GetType().FullName; throw new InvalidProgramException(unsupportedType); } } public static IHtmlContent ToHtml(this Document doc, int doclevel = 4) { var contentbuilder = new HtmlContentBuilder(); if (doc.Title != null) { if (!string.IsNullOrWhiteSpace(doc.Title.Title)) { contentbuilder.AppendHtmlLine($"{doc.Title.Title}"); if (!string.IsNullOrWhiteSpace(doc.Title.Subtitle)) { contentbuilder.AppendHtmlLine($"{doc.Title.Title}
"); } } } foreach (var item in doc) { item.ToHtml(contentbuilder); } return contentbuilder; } public static IHtmlContent AsciiDocFor(this IHtmlHelper html, Expression> expression) { string ascii = html.ValueFor(expression, "{0}"); if (string.IsNullOrWhiteSpace(ascii)) return new HtmlString(string.Empty); Document document = Document.Parse(ascii); var htmlDoc = document.ToHtml(); var span = new TagBuilder("p") { TagRenderMode = TagRenderMode.SelfClosing }; span.InnerHtml.AppendHtml(htmlDoc); return span.RenderBody(); } public static string AsciiDoc(IHtmlHelper htmlHelper, string text) { return AsciiDoc(htmlHelper, text, null); } private static string AsciiDoc(IHtmlHelper htmlHelper, string text, object htmlAttributes) { // Create tag builder var builder = new TagBuilder("div"); var document = Document.Parse(text); // builder.InnerHtml = . // Add attributes builder.MergeAttribute("class", "ascii"); builder.MergeAttributes(new RouteValueDictionary(htmlAttributes)); // Render tag return builder.ToString(); } } }