asciidoc tag

dotnet-7.0
Paul Schneider 1 year ago
parent 921a16d471
commit 16b7d97c75
6 changed files with 218 additions and 125 deletions

@ -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();
}
}
}

@ -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());
}
}
}

@ -1,53 +1,8 @@
using System;
using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Yavsc.Models.Drawing; 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 namespace Yavsc.Helpers
{ {
public static class HtmlHelpers public static class HtmlHelpers
{ {
public static HtmlString Color(this Color c) public static HtmlString Color(this Color c)
@ -61,6 +16,5 @@ namespace Yavsc.Helpers
var isSecure = request.Headers[Constants.SshHeaderKey] == "on"; var isSecure = request.Headers[Constants.SshHeaderKey] == "on";
return (isSecure ? "https" : "http") + $"://{host}/{url}"; return (isSecure ? "https" : "http") + $"://{host}/{url}";
} }
} }
} }

@ -1,17 +1,19 @@
@{ @{
ViewData["Title"] = @SR["About"]+" "+@SiteSettings.Value.Title; ViewData["Title"] = SR["About"] + " " + SiteSettings.Value.Title;
} }
<h1>@ViewData["Title"]</h1> <h1>@ViewData["Title"]</h1>
<environment names="Development">
**Version de Development** **Version de Development**
<markdown>
## L'objectif <asciidoc>
= À propos de Yavsc
== L'objectif
Cette application est construite pour mettre en relation des artistes Cette application est construite pour mettre en relation des artistes
du domaine musical avec leur public. du domaine musical avec leur public.
## Le fonctionnement == Le fonctionnement
Les utilisateurs du site sont soit artiste, soit client, soit administrateur. ils ont tous droit à leur blog. Les utilisateurs du site sont soit artiste, soit client, soit administrateur. ils ont tous droit à leur blog.
Pour les artistes, c'est un moyen de promouvoir leur activité. Pour les artistes, c'est un moyen de promouvoir leur activité.
@ -53,7 +55,7 @@ Une fois sa prestation associée exécutée, les paiements relatifs sont effectu
Pour un contrat exécuté et non honoré par le client, le processus de poursuite en recouvrement est engagé, sinon, le contrat est archivé, Pour un contrat exécuté et non honoré par le client, le processus de poursuite en recouvrement est engagé, sinon, le contrat est archivé,
des attestations de paiement sont disponibles pour l'artiste et la facture est marquée payée, puis repostée au client. des attestations de paiement sont disponibles pour l'artiste et la facture est marquée payée, puis repostée au client.
### Pour l'artiste === Pour l'artiste
L'artiste choisit plusieurs paramètres qui vont faire son profil : L'artiste choisit plusieurs paramètres qui vont faire son profil :
@ -66,7 +68,7 @@ L'artiste choisit plusieurs paramètres qui vont faire son profil :
* Des paramètres supplémentaires en fonctions de son type d'activité par exemple, pour * Des paramètres supplémentaires en fonctions de son type d'activité par exemple, pour
les ensembles, leur taille, le cas échéant, leur répertoire ou des indications sur le style de leur musique) les ensembles, leur taille, le cas échéant, leur répertoire ou des indications sur le style de leur musique)
### Pour le client === Pour le client
Il choisit un lieu et une date pour déclarer un événement avenir Il choisit un lieu et une date pour déclarer un événement avenir
(il peut bien-sûr en programmer autant qu'il le veut). (il peut bien-sûr en programmer autant qu'il le veut).
@ -76,7 +78,7 @@ sur la base d'un de ses projets événementiel, la négociation d'un contrat de
Il a accès à la connaissance des journées connues comme libres des artistes par le système. Il a accès à la connaissance des journées connues comme libres des artistes par le système.
## La confidentialité == La confidentialité
À aucun moment, aucune adresse postale, aucune adresse e-mail ni aucun numéro de téléphone À aucun moment, aucune adresse postale, aucune adresse e-mail ni aucun numéro de téléphone
ne sont transmis ni aux clients, ni aux artistes. Seul le système a accès à ces informations. ne sont transmis ni aux clients, ni aux artistes. Seul le système a accès à ces informations.
@ -87,77 +89,7 @@ qui désactive immédiatement les publications associées à leurs informations,
et programme la suppression complète de ces dites informations dans les quinze jours et programme la suppression complète de ces dites informations dans les quinze jours
à compter de la demande, sauf demande contradictoire. à compter de la demande, sauf demande contradictoire.
L'opération est annulable, jusqu'à deux semaines après sa programmation. L'opération est annulable, jusqu'à deux semaines après sa programmation.
</asciidoc>
</markdown>
</environment>
<environment names="Lua,Development">
<markdown>
C'est mon site pérso, une configuration de _Yavsc_ (encore une autre très petite entreprise).
* [README](https://github.com/pazof/yavsc/blob/vnext/README.md)
* [license: GNU GPL v3](https://github.com/pazof/yavsc/blob/vnext/LICENSE)
Autres installations:
</markdown>
<markdown>
* [Yavsc](http://yavsc.pschneider.fr)
</markdown>
</environment>
<environment names="Yavsc,Development">
<markdown>
Yet Another Very Small Company ...
* [README](https://github.com/pazof/yavsc/blob/vnext/README.md)
* [license: GNU FPL v3](https://github.com/pazof/yavsc/blob/vnext/LICENSE)
</markdown>
</environment>
<environment names="YavscPre,Development">
<markdown>
## Yet Another Very Small Company :
* [README](https://github.com/pazof/yavsc/blob/vnext/README.md)
* [license: GNU FPL v3](https://github.com/pazof/yavsc/blob/vnext/LICENSE)
En production:
* [Lua](https://lua.pschneider.fr)
* [Yavsc](https://yavsc.pschneider.fr)
</markdown>
</environment>
<environment names="coiffure,Development">
<markdown>
Vous êtes sur le site de commande en coiffure à domicile de Soraya Boudjouraf,
un as de la coiffure, qui oeuvre en région parisienne.
En validant un formulaire de commande ici, c'est à elle que vous notifiez votre demande.
Vous pouvez ![lui laisser votre numéro de téléphone](/HairCutCommand/HairCut?activityCode=Brush&performerId=1bd841ab-c305-4971-940d-7ddca818310c)
et/ou des détails sur votre demande,
elle vous rappelera.</markdown>
</environment>
<environment names="Development">
<markdown>
## Ceci est un site de développement.
Cette présente ressource ne concerne que le développement du logiciel qui la met en oeuvre.
Elle est éphémère, et pratiquement en permanence force de codes 500.
Veuillez excuser l'équipe de développement pour vous avoir fait part de cette adresse et pour la gêne occasionnnée.
La "pré-production" affiche les sites suivants:
* [Yavsc](https://yavsc.pschneider.fr)
* [Lua](https://lua.pschneider.fr)
</markdown>
</environment>
<p> <p>
@Model @Model
</p> </p>

@ -103,3 +103,34 @@
} }
</style> </style>
} }
<asciidoc>
= Hello, AsciiDoc!
Doc Writer <doc@example.com>
An introduction to http://asciidoc.org[AsciiDoc].
== First Section
* item 1
* item 2
[source,asciidoc]
----
= Hello, AsciiDoc!
Doc Writer <doc@example.com>
An introduction to http://asciidoc.org[AsciiDoc].
== First Section
* item 1
* item 2
[source,ruby]
puts "Hello, World!"
----
----
</asciidoc>

@ -31,6 +31,7 @@
@using PayPal.PayPalAPIInterfaceService.Model; @using PayPal.PayPalAPIInterfaceService.Model;
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Yavsc @addTagHelper *, Yavsc
@inject IAuthorizationService AuthorizationService @inject IAuthorizationService AuthorizationService
@inject Microsoft.AspNetCore.Mvc.Localization.IHtmlLocalizer<Yavsc.Startup> SR @inject Microsoft.AspNetCore.Mvc.Localization.IHtmlLocalizer<Yavsc.Startup> SR
@inject Microsoft.Extensions.Options.IOptions<SiteSettings> SiteSettings @inject Microsoft.Extensions.Options.IOptions<SiteSettings> SiteSettings

Loading…