asciidoc tag

This commit is contained in:
Paul Schneider 2023-04-08 01:10:36 +01:00
commit ec6424803b
6 changed files with 218 additions and 125 deletions

View file

@ -0,0 +1,155 @@
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("<p>");
foreach (var pitem in p)
{
pitem.ToHtml(contentbuilder);
}
contentbuilder.AppendHtmlLine("</p>");
break;
case "AsciiDocNet.SectionTitle":
SectionTitle stitle = (SectionTitle) elt;
contentbuilder.AppendHtmlLine($"<h{stitle.Level}>");
foreach (var titem in stitle)
{
titem.ToHtml(contentbuilder);
}
contentbuilder.AppendHtmlLine("</h>");
break;
case "AsciiDocNet.UnorderedList":
UnorderedList ul = (UnorderedList) elt;
contentbuilder.AppendHtmlLine("<ul>");
foreach (var li in ul.Items)
{
contentbuilder.AppendHtmlLine("<li>");
foreach (var lii in li)
{
lii.ToHtml(contentbuilder);
}
contentbuilder.AppendHtmlLine("</li>");
}
contentbuilder.AppendHtmlLine("</ul>");
break;
case "AsciiDocNet.Source":
Source source = (Source) elt ;
// TODO syntact hilighting and fun js modules
contentbuilder.AppendHtmlLine("<pre><code>");
contentbuilder.Append(source.Text);
contentbuilder.AppendHtmlLine("</code></pre>");
break;
default:
string unsupportedType = elt.GetType().FullName;
throw new InvalidProgramException(unsupportedType);
}
}
static void ToHtml(this IInlineElement elt, IHtmlContentBuilder sb)
{
switch (elt.GetType().FullName)
{
case "AsciiDocNet.Link":
Link link = (Link) elt;
sb.AppendFormat("<a href=\"{0}\">{1}</a> ",link.Href, link.Text);
break;
case "AsciiDocNet.TextLiteral":
sb.Append(elt.ToString());
break;
case "AsciiDocNet.Emphasis":
sb.AppendHtml("<i>");
AsciiDocNet.Emphasis em = (Emphasis) elt;
sb.Append(em.Text);
sb.AppendHtml("</i>");
break;
case "AsciiDocNet.Strong":
sb.AppendHtml("<b>");
AsciiDocNet.Strong str = (Strong) elt;
foreach (var stritem in str)
{
stritem.ToHtml(sb);
}
sb.AppendHtml("</b>");
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($"<h{doclevel}>{doc.Title.Title}</h{doclevel}>");
if (!string.IsNullOrWhiteSpace(doc.Title.Subtitle))
{
contentbuilder.AppendHtmlLine($"<i>{doc.Title.Title}</i><br/>");
}
}
}
foreach (var item in doc)
{
item.ToHtml(contentbuilder);
}
return contentbuilder;
}
public static IHtmlContent AsciiDocFor<TModel>(this IHtmlHelper<TModel> html,
Expression<Func<TModel, string>> expression)
{
string ascii = html.ValueFor<string>(expression, "{0}");
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<BlogPost> htmlHelper, string text)
{
return AsciiDoc(htmlHelper, text, null);
}
private static string AsciiDoc(IHtmlHelper<BlogPost> 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();
}
}
}

View file

@ -0,0 +1,20 @@
using System.Text.Encodings.Web;
using AsciiDocNet;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace Yavsc.Helpers
{
public class AsciidocTagHelper : TagHelper
{
public override async Task ProcessAsync (TagHelperContext context, TagHelperOutput output)
{
var content = await output.GetChildContentAsync();
Document document = Document.Parse(content.GetContent());
var html = document.ToHtml(4);
using var stringWriter = new StringWriter();
html.WriteTo(stringWriter, HtmlEncoder.Default);
output.Content.AppendHtml(stringWriter.ToString());
}
}
}

View file

@ -1,53 +1,8 @@
using System;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Yavsc.Models.Drawing;
using AsciiDocNet;
using Yavsc.Models.Blog;
using System.Linq.Expressions;
public static class AsciiDocHelpers
{
public static IHtmlContent AsciiDocFor<TModel> (this IHtmlHelper<TModel> html,
Expression<Func<TModel, string>> expression)
{
var span = new TagBuilder("p"){ TagRenderMode = TagRenderMode.SelfClosing };
span.InnerHtml.Append (
html.ValueFor<string>(expression, "{0}"));
return span.RenderBody();
}
public static string AsciiDoc(IHtmlHelper<BlogPost> htmlHelper, string text)
{
return AsciiDoc(htmlHelper, text, null);
}
private static string AsciiDoc(IHtmlHelper<BlogPost> 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();
}
}
namespace Yavsc.Helpers
{
public static class HtmlHelpers
{
public static HtmlString Color(this Color c)
@ -61,6 +16,5 @@ namespace Yavsc.Helpers
var isSecure = request.Headers[Constants.SshHeaderKey] == "on";
return (isSecure ? "https" : "http") + $"://{host}/{url}";
}
}
}