Compare commits
2 Commits
codeHighli
...
next-prev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a1f34d81c | ||
|
|
e539263aa4 |
@@ -15,16 +15,9 @@ namespace TerribleDev.Blog.Web.Factories
|
||||
.Aggregate(
|
||||
ImmutableDictionary.Create<string, ImmutableList<IPost>>(),
|
||||
(accum, item) => {
|
||||
foreach(var tag in item.tags.Select(i => i.ToLower()))
|
||||
foreach(var tag in item.tags.Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => i.ToLower()))
|
||||
{
|
||||
if(accum.TryGetValue(tag, out var list))
|
||||
{
|
||||
accum = accum.SetItem(tag, list.Add(item));
|
||||
}
|
||||
else
|
||||
{
|
||||
accum = accum.Add(tag, ImmutableList.Create<IPost>(item));
|
||||
}
|
||||
accum = accum.TryGetValue(tag, out var list) ? accum.SetItem(tag, list.Add(item)) : accum.Add(tag, ImmutableList.Create(item));
|
||||
}
|
||||
return accum;
|
||||
}).ToImmutableSortedDictionary();
|
||||
@@ -46,6 +39,7 @@ namespace TerribleDev.Blog.Web.Factories
|
||||
return accum.SetItem(highestPage, current.Add(item));
|
||||
}).ToImmutableDictionary();
|
||||
var syndicationPosts = posts.Select(i => i.ToSyndicationItem()).ToImmutableList();
|
||||
var postsToPosition = posts.Select((item, index) => (item, index)).ToImmutableDictionary(i => i.item, i => i.index);
|
||||
return new PostCache()
|
||||
{
|
||||
PostsAsLists = posts,
|
||||
|
||||
@@ -11,13 +11,11 @@ using TerribleDev.Blog.Web.MarkExtension.TerribleDev.Blog.Web.ExternalLinkParser
|
||||
using TerribleDev.Blog.Web.MarkExtension;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using System.Diagnostics;
|
||||
using TerribleDev.Blog.Web.Factories;
|
||||
|
||||
namespace TerribleDev.Blog.Web
|
||||
{
|
||||
public class BlogFactory
|
||||
{
|
||||
private HighlightFactory highlightFactory = new HighlightFactory();
|
||||
public List<IPost> GetAllPosts(string domain)
|
||||
{
|
||||
// why didn't I use f# I'd have a pipe operator by now
|
||||
@@ -49,19 +47,16 @@ namespace TerribleDev.Blog.Web
|
||||
var markdownText = string.Join("", splitFile.Skip(1));
|
||||
var postSettings = ParseYaml(ymlRaw);
|
||||
var resolvedUrl = !string.IsNullOrWhiteSpace(postSettings.permalink) ? postSettings.permalink : fileName.Split('.')[0].Replace(' ', '-').WithoutSpecialCharacters();
|
||||
var codeBlocks = new List<string>();
|
||||
List<string> postImages = new List<string>();
|
||||
var pipeline = new MarkdownPipelineBuilder()
|
||||
.Use(new AbsoluteLinkConverter(resolvedUrl, domain))
|
||||
.Use<ImageRecorder>(new ImageRecorder(ref postImages))
|
||||
.Use<TargetLinkExtension>()
|
||||
.Use<PictureInline>()
|
||||
.Use(new CodeRecorder(ref codeBlocks))
|
||||
.UseMediaLinks()
|
||||
.UseEmojiAndSmiley()
|
||||
.Build();
|
||||
var postContent = Markdown.ToHtml(markdownText, pipeline);
|
||||
var postContentHighlighted = highlightFactory.Highlight(postContent);
|
||||
var postContentPlain = String.Join("", Markdown.ToPlainText(markdownText, pipeline).Split("<!-- more -->"));
|
||||
|
||||
var summary = postContent.Split("<!-- more -->")[0];
|
||||
@@ -78,8 +73,7 @@ namespace TerribleDev.Blog.Web
|
||||
SummaryPlain = postSummaryPlain,
|
||||
SummaryPlainShort = (postContentPlain.Length <= 147 ? postContentPlain : postContentPlain.Substring(0, 146)) + "...",
|
||||
ContentPlain = postContentPlain,
|
||||
Images = postImages.Distinct().ToList(),
|
||||
CodeBlockLangs = codeBlocks
|
||||
Images = postImages.Distinct().ToList()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace TerribleDev.Blog.Web.Factories
|
||||
{
|
||||
public class HighlightFactory
|
||||
{
|
||||
private Regex codeFenceLang = new Regex("(?=<code class=\"language-(.*?)\">(.*?)(?=</code>))", RegexOptions.Compiled | RegexOptions.Singleline);
|
||||
public string Highlight(string input)
|
||||
{
|
||||
return codeFenceLang.Replace(input, m => {
|
||||
return m.ToString();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace TerribleDev.Blog.Web.Factories.Processors
|
||||
{
|
||||
public class JavaScriptProcessor
|
||||
{
|
||||
private Regex keywordRegex = new Regex(@"\b(in|of|if|for|while|finally|var|new|function|do|return|void|else|break|catch|instanceof|with|throw|case|default|try|this|switch|continue|typeof|delete|let|yield|const|export|super|debugger|as|async|await|static|import|from|as|)(?=[^\w])", RegexOptions.Compiled | RegexOptions.Multiline);
|
||||
private Regex literalRegex = new Regex(@"\b(true|false|null|undefined|NaN|Infinity)(?=[^\w])", RegexOptions.Compiled | RegexOptions.Multiline);
|
||||
private Regex[] quoteMarkRegexes = new Regex[]{ new Regex("(.*?)", RegexOptions.Compiled | RegexOptions.Multiline), new Regex(@"'(.*?)'", RegexOptions.Compiled | RegexOptions.Multiline)};
|
||||
public string Process(string input)
|
||||
{
|
||||
return input;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Markdig;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Renderers.Html;
|
||||
using Markdig.Syntax;
|
||||
|
||||
namespace TerribleDev.Blog.Web.MarkExtension
|
||||
{
|
||||
public class CodeRecorder : IMarkdownExtension
|
||||
{
|
||||
public CodeRecorder(ref List<string> codeLanguages)
|
||||
{
|
||||
CodeLanguages = codeLanguages;
|
||||
}
|
||||
|
||||
public List<string> CodeLanguages { get; }
|
||||
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
}
|
||||
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
{
|
||||
var inlineRenderer = htmlRenderer.ObjectRenderers.FindExact<CodeBlockRenderer>();
|
||||
if (inlineRenderer != null)
|
||||
{
|
||||
inlineRenderer.TryWriters.Add(TryWriter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryWriter(HtmlRenderer renderer, CodeBlock block)
|
||||
{
|
||||
var fencedBlock = block as FencedCodeBlock;
|
||||
if(fencedBlock == null || fencedBlock.Info == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
CodeLanguages.Add(fencedBlock.Info ?? "");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,5 @@ namespace TerribleDev.Blog.Web.Models
|
||||
string SummaryPlainShort { get; set; }
|
||||
IList<string> tags { get; set; }
|
||||
IList<string> Images { get; set;}
|
||||
IList<string> CodeBlockLangs { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace TerribleDev.Blog.Web.Models
|
||||
public string SummaryPlainShort { get; set; }
|
||||
public IList<string> tags { get; set; }
|
||||
public IList<string> Images { get; set;}
|
||||
public IList<string> CodeBlockLangs { get; set; }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace TerribleDev.Blog.Web.Models
|
||||
public ImmutableDictionary<string, IPost> UrlToPost { get; set; }
|
||||
public ImmutableDictionary<int, ImmutableList<IPost>> PostsByPage { get; set; }
|
||||
public ImmutableList<SyndicationItem> PostsAsSyndication { get; set; }
|
||||
|
||||
public ImmutableDictionary<IPost, int> PostToPosition { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
<UserSecretsId>9a1f51b6-f4d9-4df7-a0af-e345176e9927</UserSecretsId>
|
||||
<ApplicationInsightsResourceId>/subscriptions/088a81c7-d703-41c9-a1d0-476bce11df60/resourcegroups/WebResourceGroup/providers/microsoft.insights/components/tparnellblognew</ApplicationInsightsResourceId>
|
||||
<ApplicationInsightsAnnotationResourceId>/subscriptions/088a81c7-d703-41c9-a1d0-476bce11df60/resourcegroups/WebResourceGroup/providers/microsoft.insights/components/tparnellblognew</ApplicationInsightsAnnotationResourceId>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -31,13 +31,4 @@
|
||||
<meta name="twitter:image" content="@(Model.Images[0])">
|
||||
}
|
||||
<meta property="og:image" content="https://www.gravatar.com/avatar/333e3cea32cd17ff2007d131df336061?s=640" />
|
||||
@if(Model.CodeBlockLangs.Count > 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
@section Scripts
|
||||
{
|
||||
@if(Model.CodeBlockLangs.Count > 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
@using Newtonsoft.Json
|
||||
@model IPost
|
||||
@model IPost
|
||||
|
||||
<article itemprop="blogPost">
|
||||
<h1 itemprop="headline" class="headline">@Model.Title</h1>
|
||||
@@ -16,12 +15,4 @@
|
||||
</div>
|
||||
}
|
||||
|
||||
<environment names="Development">
|
||||
<pre>
|
||||
<code>
|
||||
@JsonConvert.SerializeObject(Model, Formatting.Indented)
|
||||
</code>
|
||||
</pre>
|
||||
</environment>
|
||||
|
||||
</article>
|
||||
@@ -36,12 +36,12 @@
|
||||
@RenderBody()
|
||||
</div>
|
||||
</main>
|
||||
@RenderSection("Scripts", required: false)
|
||||
<environment names="Development">
|
||||
<script asp-append-version="true" src="~/js/swi.js" async></script>
|
||||
</environment>
|
||||
<environment names="Production">
|
||||
<script asp-append-version="true" src="~/js/site.min.js" async></script>
|
||||
</environment>
|
||||
@RenderSection("Scripts", required: false)
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
.hljs,
|
||||
.hljs-subst {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.hljs-comment {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-attribute,
|
||||
.hljs-selector-tag,
|
||||
.hljs-meta-keyword,
|
||||
.hljs-doctag,
|
||||
.hljs-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
/* User color: hue: 0 */
|
||||
|
||||
.hljs-type,
|
||||
.hljs-string,
|
||||
.hljs-number,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-quote,
|
||||
.hljs-template-tag,
|
||||
.hljs-deletion {
|
||||
color: #880000;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #880000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-symbol,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-link,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #BC6060;
|
||||
}
|
||||
|
||||
|
||||
/* Language color: hue: 90; */
|
||||
|
||||
.hljs-literal {
|
||||
color: #78A960;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-bullet,
|
||||
.hljs-code,
|
||||
.hljs-addition {
|
||||
color: #397300;
|
||||
}
|
||||
|
||||
|
||||
/* Meta color: hue: 200 */
|
||||
|
||||
.hljs-meta {
|
||||
color: #1f7199;
|
||||
}
|
||||
|
||||
.hljs-meta-string {
|
||||
color: #4d99bf;
|
||||
}
|
||||
|
||||
|
||||
/* Misc effects */
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
Reference in New Issue
Block a user