Compare commits
2 Commits
backup-nav
...
codeHighli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
728ef5b30d | ||
|
|
f51abe4339 |
@@ -11,11 +11,13 @@ 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
|
||||
@@ -47,16 +49,19 @@ 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];
|
||||
@@ -73,7 +78,8 @@ namespace TerribleDev.Blog.Web
|
||||
SummaryPlain = postSummaryPlain,
|
||||
SummaryPlainShort = (postContentPlain.Length <= 147 ? postContentPlain : postContentPlain.Substring(0, 146)) + "...",
|
||||
ContentPlain = postContentPlain,
|
||||
Images = postImages.Distinct().ToList()
|
||||
Images = postImages.Distinct().ToList(),
|
||||
CodeBlockLangs = codeBlocks
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
15
src/TerribleDev.Blog.Web/Factories/HighlightFactory.cs
Normal file
15
src/TerribleDev.Blog.Web/Factories/HighlightFactory.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
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();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
47
src/TerribleDev.Blog.Web/MarkExtension/CodeRecorder.cs
Normal file
47
src/TerribleDev.Blog.Web/MarkExtension/CodeRecorder.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
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,5 +19,6 @@ 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,5 +18,6 @@ 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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,4 +31,13 @@
|
||||
<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,4 +1,5 @@
|
||||
@model IPost
|
||||
@using Newtonsoft.Json
|
||||
@model IPost
|
||||
|
||||
<article itemprop="blogPost">
|
||||
<h1 itemprop="headline" class="headline">@Model.Title</h1>
|
||||
@@ -15,4 +16,12 @@
|
||||
</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>
|
||||
|
||||
83
src/TerribleDev.Blog.Web/wwwroot/css/langHi.css
Normal file
83
src/TerribleDev.Blog.Web/wwwroot/css/langHi.css
Normal file
@@ -0,0 +1,83 @@
|
||||
.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