diff --git a/src/Yavsc/Helpers/Tags/MarkDownTagHelper.cs b/src/Yavsc/Helpers/Tags/MarkDownTagHelper.cs index cb00a72e..623ed6d4 100644 --- a/src/Yavsc/Helpers/Tags/MarkDownTagHelper.cs +++ b/src/Yavsc/Helpers/Tags/MarkDownTagHelper.cs @@ -1,11 +1,10 @@ +using System.Text.RegularExpressions; using System.Threading.Tasks; +using MarkdownDeep; using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Razor.TagHelpers; -using CommonMark; -using CommonMark.Syntax; -using System.IO; namespace Yavsc.TagHelpers { @@ -33,6 +32,45 @@ namespace Yavsc.TagHelpers [HtmlAttributeName(MarkdownContentAttributeName)] public string MarkdownContent { get; set; } + static Regex rxExtractLanguage = new Regex("^({{(.+)}}[\r\n])", RegexOptions.Compiled); + private static string FormatCodePrettyPrint(MarkdownDeep.Markdown m, string code) + { + // Try to extract the language from the first line + var match = rxExtractLanguage.Match(code); + string language = null; + + if (match.Success) + { + // Save the language + var g = (Group)match.Groups[2]; + language = g.ToString(); + + // Remove the first line + code = code.Substring(match.Groups[1].Length); + } + + // If not specified, look for a link definition called "default_syntax" and + // grab the language from its title + if (language == null) + { + var d = m.GetLinkDefinition("default_syntax"); + if (d != null) + language = d.title; + } + + // Common replacements + if (language == "C#") + language = "csharp"; + if (language == "C++") + language = "cpp"; + + // Wrap code in pre/code tags and add PrettyPrint attributes if necessary + if (string.IsNullOrEmpty(language)) + return string.Format("
{0}
\n", code); + else + return string.Format("
{1}
\n", + language.ToLowerInvariant(), code); + } /// @@ -41,28 +79,28 @@ namespace Yavsc.TagHelpers /// The Markdown that should be transformed. /// The url Base Location. /// The HTML representation of the supplied Markdown. - public string Markdown(string commonMark, string urlBaseLocation = "") + public string Markdown(string text, string urlBaseLocation = "") { // Transform the supplied text (Markdown) into HTML. - string actual; - var settings = CommonMarkSettings.Default.Clone(); - settings.OutputFormat = OutputFormat.Html; - settings.AdditionalFeatures |= CommonMarkAdditionalFeatures.StrikethroughTilde; - - Block document; + var markdownTransformer = GetMarkdownTransformer(); + markdownTransformer.UrlBaseLocation = urlBaseLocation; + string html = markdownTransformer.Transform(text); + // Wrap the html in an MvcHtmlString otherwise it'll be HtmlEncoded and displayed to the user as HTML :( + return html; + } - // Act - using (var reader = new StringReader(commonMark)) - using (var writer = new StringWriter()) - { - var prologue = CommonMarkConverter.ProcessPrologue(reader, settings); - document = CommonMarkConverter.ProcessStage1(reader, settings, prologue); - CommonMarkConverter.ProcessStage2(document, settings); - CommonMarkConverter.ProcessStage3(document, writer, settings); - actual = writer.ToString(); - } - return actual; + internal Markdown GetMarkdownTransformer() + { + var markdownTransformer = new Markdown(); + markdownTransformer.ExtraMode = true; + markdownTransformer.NoFollowLinks = true; + markdownTransformer.SafeMode = false; + markdownTransformer.FormatCodeBlock = FormatCodePrettyPrint; + markdownTransformer.ExtractHeadBlocks = true; + markdownTransformer.UserBreaks = true; + return markdownTransformer; } + public ModelExpression Content { get; set; } public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) diff --git a/src/Yavsc/project.json b/src/Yavsc/project.json index c764957f..a16a3030 100644 --- a/src/Yavsc/project.json +++ b/src/Yavsc/project.json @@ -75,7 +75,7 @@ "defaultNamespace": "Yavsc" }, "dependencies": { - "ya.CommonMark.NET": "0.11.0", + "MarkdownDeep-av.NET": "1.5.26", "EntityFramework.Commands": "7.0.0-rc1-final", "EntityFramework.Core": "7.0.0-rc1-final", "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final",