using AscDocCsharp, and fixing the tag helper
This commit is contained in:
parent
694300b150
commit
e5fa31c9cb
12 changed files with 53 additions and 284 deletions
|
|
@ -4,7 +4,8 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="IdentityModel.OidcClient" Version="6.0.0" />
|
||||
<PackageVersion Include="AsciiDocNet" Version="1.0.0" />
|
||||
<PackageVersion Include="AsciiDocSharp" Version="0.2.0" />
|
||||
<PackageVersion Include="AsciiDocSharp.Converters.Html" Version="0.2.0" />
|
||||
<PackageVersion Include="bootstrap" Version="5.3.7" />
|
||||
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
|
||||
<PackageVersion Include="Google.Apis.Calendar.v3" Version="1.69.0.3746" />
|
||||
|
|
|
|||
|
|
@ -204,7 +204,6 @@ namespace Yavsc.Models
|
|||
return base.SaveChanges();
|
||||
}
|
||||
|
||||
|
||||
public async Task<int> SaveChangesAsync(string userId, CancellationToken ctoken = default(CancellationToken))
|
||||
{
|
||||
AddTimestamps(userId);
|
||||
|
|
|
|||
|
|
@ -343,7 +343,8 @@ public static class HostingExtensions
|
|||
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
// to fix Home/Error app.UseDeveloperExceptionPage();
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,238 +0,0 @@
|
|||
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using AsciiDocNet;
|
||||
|
||||
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.AppendHtml(source.Text);
|
||||
contentbuilder.AppendHtmlLine("</code></pre>");
|
||||
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.Monospace":
|
||||
sb.AppendHtml("<code>");
|
||||
Monospace mono = (Monospace)elt;
|
||||
AllItemsToHtml(sb, mono);
|
||||
break;
|
||||
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("<a href=\"{0}\">{1}</a> ", link.GetValidHRef(), link.Text);
|
||||
break;
|
||||
|
||||
case "AsciiDocNet.TextLiteral":
|
||||
RenderLitteral(elt, sb);
|
||||
break;
|
||||
|
||||
case "AsciiDocNet.Emphasis":
|
||||
sb.AppendHtml("<i>");
|
||||
AsciiDocNet.Emphasis em = (Emphasis)elt;
|
||||
sb.AppendHtml(em.Text);
|
||||
sb.AppendHtml("</i>");
|
||||
break;
|
||||
|
||||
case "AsciiDocNet.Strong":
|
||||
sb.AppendHtml("<b>");
|
||||
Strong str = (Strong)elt;
|
||||
AllItemsToHtml(sb, str);
|
||||
sb.AppendHtml("</b>");
|
||||
break;
|
||||
case "AsciiDocNet.InternalAnchor":
|
||||
InternalAnchor a = (InternalAnchor)elt;
|
||||
sb.AppendFormat("<a name=\"{0}\">{1}</a> ", a.Id, a.XRefLabel);
|
||||
break;
|
||||
case "AsciiDocNet.Subscript":
|
||||
sb.AppendHtml("<sup>");
|
||||
Subscript sub = (Subscript)elt;
|
||||
RenderLitteral(sub, sb);
|
||||
sb.AppendHtml("</sup>");
|
||||
break;
|
||||
case "AsciiDocNet.Superscript":
|
||||
sb.AppendHtml("<sup>");
|
||||
Superscript sup = (Superscript)elt;
|
||||
RenderLitteral(sup, sb);
|
||||
sb.AppendHtml("</sup>");
|
||||
break;
|
||||
case "AsciiDocNet.Mark":
|
||||
sb.AppendHtml("<em>");
|
||||
|
||||
Mark mark = (Mark)elt;
|
||||
if (mark.DoubleDelimited)
|
||||
{
|
||||
sb.AppendHtml("<b>");
|
||||
RenderLitteral(mark, sb);
|
||||
sb.AppendHtml("</b>");
|
||||
}
|
||||
else
|
||||
RenderLitteral(mark, sb);
|
||||
sb.AppendHtml("</em>");
|
||||
break;
|
||||
|
||||
default:
|
||||
string unsupportedType = elt.GetType().FullName;
|
||||
if (elt is InlineContainer inlineContainer)
|
||||
{
|
||||
sb.AppendHtml($"<span title=\"E NOT SUPPORTED : {unsupportedType}\">");
|
||||
AllItemsToHtml(sb, inlineContainer);
|
||||
sb.AppendHtml("</span>");
|
||||
}
|
||||
else if (elt is IInlineElement inlineElement)
|
||||
{
|
||||
sb.AppendHtml($"<span title=\"E NOT SUPPORTED : {unsupportedType}\">");
|
||||
RenderLitteral(inlineElement, sb);
|
||||
sb.AppendHtml("</span>");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidProgramException(unsupportedType);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void AllItemsToHtml(IHtmlContentBuilder sb, InlineContainer mono)
|
||||
{
|
||||
foreach (var item in mono)
|
||||
{
|
||||
item.ToHtml(sb);
|
||||
}
|
||||
sb.AppendHtml("</code>");
|
||||
}
|
||||
|
||||
private static void RenderLitteral(IInlineElement elt, IHtmlContentBuilder sb)
|
||||
{
|
||||
var tl = elt as TextLiteral;
|
||||
if (tl?.Attributes.Anchor != null)
|
||||
{
|
||||
sb.AppendHtmlLine($"<a name=\"{tl.Attributes.Anchor.Id}\">{tl.Attributes.Anchor.XRefLabel}</a> ");
|
||||
}
|
||||
if (tl != null) sb.AppendHtml(tl.Text);
|
||||
}
|
||||
|
||||
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}");
|
||||
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<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();
|
||||
} */
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
using System.Text.Encodings.Web;
|
||||
using AsciiDocNet;
|
||||
using System.Web;
|
||||
using AsciiDocSharp;
|
||||
using AsciiDocSharp.Converters.Html;
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
|
||||
|
|
@ -9,10 +11,11 @@ namespace Yavsc.Helpers
|
|||
{
|
||||
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
|
||||
await base.ProcessAsync(context, output);
|
||||
|
||||
//await base.ProcessAsync(context, output);
|
||||
var content = await output.GetChildContentAsync();
|
||||
string text = content.GetContent();
|
||||
string text = HttpUtility.HtmlDecode(content.GetContent());
|
||||
|
||||
if (string.IsNullOrWhiteSpace(text)) return;
|
||||
|
||||
try
|
||||
|
|
@ -31,12 +34,14 @@ namespace Yavsc.Helpers
|
|||
}
|
||||
}
|
||||
}
|
||||
Document document = Document.Parse(text);
|
||||
var html = document.ToHtml(2);
|
||||
using var stringWriter = new StringWriter();
|
||||
html.WriteTo(stringWriter, HtmlEncoder.Default);
|
||||
var processedHere = stringWriter.ToString();
|
||||
output.Content.AppendHtml(processedHere);
|
||||
var processor = new AsciiDocProcessor();
|
||||
var htmlConverter = new HtmlDocumentConverter();
|
||||
|
||||
var document = processor.ParseFromText(text);
|
||||
var htmlResult = processor.ConvertDocument(document, htmlConverter);
|
||||
|
||||
|
||||
output.Content.AppendHtml(htmlResult);
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
@model BlogPostEditViewModel
|
||||
@model BlogPostCreateViewModel
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Blog post edition";
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@
|
|||
<h2 title="Titre du post" class="blogtitle" id="titleview" >@Model.Title</h2>
|
||||
|
||||
|
||||
<div title="Contenu du post" id="contentview">@Model.Content</div>
|
||||
<div title="Contenu du post" id="contentview"><asciidoc>@Model.Content</asciidoc></div>
|
||||
|
||||
<hr>
|
||||
<form asp-action="Edit">
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@
|
|||
<PackageReference Include="System.Security.Cryptography.Pkcs" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Antiforgery" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" />
|
||||
<PackageReference Include="AsciiDocNet" />
|
||||
<PackageReference Include="AsciiDocSharp" />
|
||||
<PackageReference Include="AsciiDocSharp.Converters.Html" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" />
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
div.carousel-inner > div.item > div.carousel-caption-s {
|
||||
margin: .5em;
|
||||
background-color: #11415f4a;
|
||||
background-color: #11415faa;
|
||||
color: #ffffc8;
|
||||
font-weight: bold;
|
||||
padding: .5em; }
|
||||
|
|
@ -76,7 +76,7 @@ a.close {
|
|||
|
||||
div.carousel-inner > div.item > div.carousel-caption-s {
|
||||
margin: .5em;
|
||||
background-color: #11415f4a;
|
||||
background-color: #11415faa;
|
||||
color: #ffffc8;
|
||||
font-weight: bold;
|
||||
padding: .5em; }
|
||||
|
|
@ -92,14 +92,15 @@ input[type='checkbox'] {
|
|||
|
||||
.container {
|
||||
background-color: #000000;
|
||||
color: #f5f7db;
|
||||
padding: .5em;
|
||||
margin: .5em; }
|
||||
color: #ffffffab;
|
||||
padding: 0;
|
||||
margin: 0; }
|
||||
|
||||
.post {
|
||||
background-color: #290505;
|
||||
color: #fff4ca;
|
||||
padding: .7em;
|
||||
color: #c4fbff;
|
||||
padding: .3em;
|
||||
margin: .3em;
|
||||
border-radius: 2em;
|
||||
border: solid #b29e9e 2pt; }
|
||||
.post .photo {
|
||||
|
|
@ -116,7 +117,7 @@ input[type='checkbox'] {
|
|||
|
||||
body {
|
||||
font: 1rem/1.5 var(--font-family-sans-serif);
|
||||
color: #f5f7db;
|
||||
color: #ffffffab;
|
||||
background-color: #000000; }
|
||||
|
||||
.card {
|
||||
|
|
|
|||
8
src/Yavsc/wwwroot/css/site.min.css
vendored
8
src/Yavsc/wwwroot/css/site.min.css
vendored
|
|
@ -1,10 +1,10 @@
|
|||
.grants-page.card{margin-top:20px;border-bottom:1px solid#fd8134;}.grants-page.card.card-title{font-size:120%;font-weight:bold;}.grants-page.card.card-title img{width:100px;height:100px;}.grants-page.card label{font-weight:bold;}.navbar-dark.navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");}
|
||||
div.carousel-inner>div.item>div.carousel-caption-s{margin:.5em;background-color:#11415f4a;color:#ffffc8;font-weight:bold;padding:.5em;}
|
||||
div.carousel-inner>div.item>div.carousel-caption-s{margin:.5em;background-color:#11415faa;color:#ffffc8;font-weight:bold;padding:.5em;}
|
||||
img.blogphoto{max-width:100%;max-height:100%;}
|
||||
input[type='checkbox']{appearance:auto;min-width:1em;min-height:1em;}.container{background-color:#000000;color:#fff;padding:.5em;margin:.5em;}.post{background-color:#290505;color:#d1d1d1;padding:2.3em;border-radius:2em;border:solid#5d7f0ca4 2pt;}.actiongroup{float:right;margin:.5em;}.float-left{float:left;margin:.5em;}
|
||||
a{color:var(--blue);}
|
||||
a.close{cursor:pointer;}.grants-page.card{margin-top:20px;border-bottom:1px solid lightgray;}.grants-page.card.card-title{font-size:120%;font-weight:bold;}.grants-page.card.card-title img{width:100px;height:100px;}.grants-page.card label{font-weight:bold;}.navbar-dark.navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");}
|
||||
div.carousel-inner>div.item>div.carousel-caption-s{margin:.5em;background-color:#11415f4a;color:#ffffc8;font-weight:bold;padding:.5em;}
|
||||
div.carousel-inner>div.item>div.carousel-caption-s{margin:.5em;background-color:#11415faa;color:#ffffc8;font-weight:bold;padding:.5em;}
|
||||
img.blogphoto{max-width:100%;max-height:100%;}
|
||||
input[type='checkbox']{appearance:auto;min-width:1em;min-height:1em;}.container{background-color:#000000;color:#f5f7db;padding:.5em;margin:.5em;}.post{background-color:#290505;color:#fff4ca;padding:.7em;border-radius:2em;border:solid#b29e9e 2pt;}.post.photo{max-height:100%;max-width:100%;}.actiongroup{float:right;margin:.5em;}.float-left{float:left;margin:.5em;}
|
||||
body{font:1rem/1.5 var(--font-family-sans-serif);color:#f5f7db;background-color:#000000;}.card{max-height:20em;max-width:30em;display:inline-table;}.card.card-photo{border:solid 1px#ffffffd4;max-height:15em;max-width:30em;}.card.index-post-title{display:inline;}
|
||||
input[type='checkbox']{appearance:auto;min-width:1em;min-height:1em;}.container{background-color:#000000;color:#ffffffab;padding:0;margin:0;}.post{background-color:#290505;color:#c4fbff;padding:.3em;margin:.3em;border-radius:2em;border:solid#b29e9e 2pt;}.post.photo{max-height:100%;max-width:100%;}.actiongroup{float:right;margin:.5em;}.float-left{float:left;margin:.5em;}
|
||||
body{font:1rem/1.5 var(--font-family-sans-serif);color:#ffffffab;background-color:#000000;}.card{max-height:20em;max-width:30em;display:inline-table;}.card.card-photo{border:solid 1px#ffffffd4;max-height:15em;max-width:30em;}.card.index-post-title{display:inline;}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
$color: #f5f7db;
|
||||
$color: #ffffffab;
|
||||
$background-color: #000000;
|
||||
$post-color: #fff4ca;
|
||||
$post-color: #c4fbff;
|
||||
$post-background-color: #290505;
|
||||
$post-border-color: rgb(178, 158, 158);
|
||||
$card-border-color: rgb(253, 129, 52);
|
||||
$card-photo-border-color: #ffffffd4;
|
||||
$carousel-color: rgb(255, 255, 200);
|
||||
$carousel-background-color: #11415f4a;
|
||||
$carousel-background-color: #11415faa;
|
||||
$primary: #00c40d;
|
||||
$danger: #dc0505d5;
|
||||
|
||||
|
|
@ -135,14 +135,15 @@ input[type='checkbox'] {
|
|||
.container {
|
||||
background-color: $background-color;
|
||||
color: $color;
|
||||
padding: .5em;
|
||||
margin: .5em;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.post {
|
||||
background-color: $post-background-color;
|
||||
color: $post-color;
|
||||
padding: .7em;
|
||||
padding: .3em;
|
||||
margin: .3em;
|
||||
border-radius: 2em;
|
||||
border: solid $post-border-color 2pt;
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,14 @@ namespace isnd.tests
|
|||
using (var migrationScope = app.Services.CreateScope())
|
||||
{
|
||||
var db = migrationScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||
await db.Database.MigrateAsync();
|
||||
db.Database.EnsureDeleted();
|
||||
db.Database.EnsureCreated();
|
||||
db.Database.Migrate();
|
||||
TestingUserName = "Tester";
|
||||
TestingUserPassword = "test";
|
||||
TestClientId = "testClientId";
|
||||
TestingUser = await db.Users.FirstOrDefaultAsync(u => u.UserName == TestingUserName);
|
||||
EnsureUser(TestingUserName, TestingUserPassword);
|
||||
}
|
||||
await app.ConfigurePipeline();
|
||||
app.UseSession();
|
||||
|
|
@ -112,17 +119,8 @@ namespace isnd.tests
|
|||
}
|
||||
SiteSettings = app.Services.GetRequiredService<IOptions<SiteSettings>>().Value;
|
||||
|
||||
using IServiceScope scope = app.Services.CreateScope();
|
||||
ApplicationDbContext dbContext =
|
||||
scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||
//dbContext.Database.EnsureCreated();
|
||||
dbContext.Database.Migrate();
|
||||
|
||||
TestingUserName = "Tester";
|
||||
TestingUserPassword = "test";
|
||||
TestClientId = "testClientId";
|
||||
TestingUser = await dbContext.Users.FirstOrDefaultAsync(u => u.UserName == TestingUserName);
|
||||
EnsureUser(TestingUserName, TestingUserPassword);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue