public void TwitterUserNameSpan() { var builder = new StringBuilder(); builder.AppendLine("some random text here and a twitter user name @pekkath plus more text"); "Given markdown parser with UserNameSpanFactory" .Given(() => { var parser = new MarkdownParser(); var paragraphBuilder = parser.Builders.OfType<ParagraphBuilder>().Single(); paragraphBuilder.InlineParser.Builders.Insert(0, new UserNameBuilder()); GivenMarkdownParser(parser); GivenTheMarkdown(builder.ToString()); }); "When markdown is parsed" .When(()=>WhenTheMarkdownIsParsed()); "Then count of document children should be 1" .Then(() => ThenDocumentChildrenShouldHaveCount(1)); "And child at index 0 should be a paragraph with UserName span" .And(() => ThenDocumentChildAtIndexShould<Paragraph>(0, paragraph => { var userName = paragraph.Spans.OfType<UserName>().Single(); userName.ToString().ShouldBeEquivalentTo("@pekkath"); })); }
private static void CreateCommentModelsMap() { Mapper.CreateMap<Comment, CommentViewModel>() .ForMember(d => d.CommentId, o => o.MapFrom(s => s.Id)) .ForMember(d => d.CommentUserName, o => o.MapFrom(s => s.User.Name)) .ForMember(d => d.CommentUserDisplayName, o => o.MapFrom(s => s.User.DisplayName)) .ForMember(d => d.CommentUserIconUrl, o => o.MapFrom(s => s.User.IconUrl ?? GlobalSettings.NoImageUserIconUrl)) .ForMember(d => d.CommentCreatedDateTime, o => o.MapFrom(s => s.CreatedDateTime)) .ForMember(d => d.CommentLastModifiedDateTime, o => o.MapFrom(s => s.LastModifiedDateTime)) .AfterMap((s, d) => { using (var parser = new MarkdownParser()) { d.CommentHtmlBody = parser.Transform(s.Body); } }); Mapper.CreateMap<Comment, CommentEditModel>() .ForMember(d => d.CommentId, o => o.MapFrom(s => s.Id)) .ForMember(d => d.CommentBody, o => o.MapFrom(s => s.Body)) .AfterMap((s, d) => { using (var parser = new MarkdownParser()) { d.CommentHtmlBody = parser.Transform(s.Body); } }); Mapper.CreateMap<CommentEditModel, Comment>() .ForMember(d => d.Id, o => o.MapFrom(s => s.CommentId)) .ForMember(d => d.Body, o => o.MapFrom(s => s.CommentBody)); }
public void Test() { using (var parser = new MarkdownParser()) { var html = parser.Transform("H1\n=="); } }
public void GistBlock() { var builder = new StringBuilder(); builder.AppendLine("https://gist.github.com/pekkah/8304465"); "Given markdown parser with GistFactory" .Given(() => { var parser = new MarkdownParser(); parser.Builders.Insert(0, new GistBuilder()); GivenMarkdownParser(parser); GivenTheMarkdown(builder.ToString()); }); "When markdown is parsed" .When(()=>WhenTheMarkdownIsParsed()); "Then count of document children should be 1" .Then(() => ThenDocumentChildrenShouldHaveCount(1)); "And child at index 0 should be Gist with gist id and user name" .And(() => ThenDocumentChildAtIndexShould<GistBlock>(0, gist => { gist.UserName.ToString().ShouldBeEquivalentTo("pekkah"); gist.GistId.ToString().ShouldBeEquivalentTo("8304465"); })); }
public void HeadingTest(string markdown, string expected) { using (var parser = new MarkdownParser()) { var html = parser.Transform(markdown); Assert.AreEqual(expected, html); } }
public void StripTest(string markdown, string expected) { using (var parser = new MarkdownParser()) { var stripText = parser.Strip(markdown); Assert.AreEqual(expected, stripText); } }
private static void CreateItemModelsMap() { const string askTitlePrefix = @"質問: "; Mapper.CreateMap<Item, ItemIndexModel>() .ForMember(d => d.AuthorName, o => o.MapFrom(s => s.Author.Name)) .ForMember(d => d.AuthorDisplayName, o => o.MapFrom(s => s.Author.DisplayName)) .ForMember(d => d.AuthorIconUrl, o => o.MapFrom(s => s.Author.IconUrl ?? GlobalSettings.NoImageUserIconUrl)) .ForMember(d => d.EditorName, o => o.MapFrom(s => s.Editor.Name)) .ForMember(d => d.EditorDisplayName, o => o.MapFrom(s => s.Editor.DisplayName)) .ForMember(d => d.EditorIconUrl, o => o.MapFrom(s => s.Editor.IconUrl ?? GlobalSettings.NoImageUserIconUrl)) .ForMember(d => d.Title, o => o.Ignore()) .AfterMap((s, d) => { d.Title = ((s.Type == ItemType.Ask) ? askTitlePrefix : "") + s.Title; }); Mapper.CreateMap<Item, ItemViewModel>() .ForMember(d => d.AuthorName, o => o.MapFrom(s => s.Author.Name)) .ForMember(d => d.AuthorDisplayName, o => o.MapFrom(s => s.Author.DisplayName)) .ForMember(d => d.AuthorIconUrl, o => o.MapFrom(s => s.Author.IconUrl ?? GlobalSettings.NoImageUserIconUrl)) .ForMember(d => d.EditorName, o => o.MapFrom(s => s.Editor.Name)) .ForMember(d => d.EditorDisplayName, o => o.MapFrom(s => s.Editor.DisplayName)) .ForMember(d => d.EditorIconUrl, o => o.MapFrom(s => s.Editor.IconUrl ?? GlobalSettings.NoImageUserIconUrl)) .AfterMap((s, d) => { d.DisplayTitle = ((s.Type == ItemType.Ask) ? askTitlePrefix : "") + s.Title; using (var parser = new MarkdownParser()) { d.HtmlBody = parser.Transform(s.Body); } }); Mapper.CreateMap<ItemRevision, ItemRevisionDetailModel>() .ForMember(d => d.AuthorName, o => o.MapFrom(s => s.Author.Name)) .ForMember(d => d.AuthorDisplayName, o => o.MapFrom(s => s.Author.DisplayName)) .ForMember(d => d.AuthorIconUrl, o => o.MapFrom(s => s.Author.IconUrl ?? GlobalSettings.NoImageUserIconUrl)) .ForMember(d => d.EditorName, o => o.MapFrom(s => s.Editor.Name)) .ForMember(d => d.EditorDisplayName, o => o.MapFrom(s => s.Editor.DisplayName)) .ForMember(d => d.EditorIconUrl, o => o.MapFrom(s => s.Editor.IconUrl ?? GlobalSettings.NoImageUserIconUrl)) .ForMember(d => d.Comment, o => o.Ignore()) .AfterMap((s, d) => { if (s.IsFirst && string.IsNullOrWhiteSpace(s.Comment)) { d.Comment = "投稿"; return; } d.Comment = string.IsNullOrWhiteSpace(s.Comment) ? "(コメントなし)" : s.Comment; }); Mapper.CreateMap<Item, ItemEditCollaboratorsModel>() .ForMember(d => d.AuthorName, o => o.MapFrom(s => s.Author.Name)) .ForMember(d => d.AuthorDisplayName, o => o.MapFrom(s => s.Author.DisplayName)) .ForMember(d => d.AuthorIconUrl, o => o.MapFrom(s => s.Author.IconUrl ?? GlobalSettings.NoImageUserIconUrl)) .ForMember(d => d.Collaborators, o => o.MapFrom(s => Mapper.Map<IEnumerable<CollaboratorEditModel>>(s.Collaborators))); }
public UtilsAdminApi() : base("/api/admin/utils") { this.RequiresHttpsOrXProto(); this.RequiresAuthentication(); this.RequiresClaims(new[] {SystemRoles.Administrators}); Post["/slugs"] = parameters => { var slugDto = this.Bind<SlugDto>(); if (string.IsNullOrWhiteSpace(slugDto.Text)) { return global::System.Net.HttpStatusCode.BadRequest; } string slug = Snail.ToSlug(slugDto.Text); return new {Slug = slug}; }; Post["/markdown/render"] = parameters => { string content = Request.Body.ReadAsString(); if (string.IsNullOrEmpty(content)) return global::System.Net.HttpStatusCode.BadRequest; var parser = new MarkdownParser(); var htmlRenderer = new MarkdownHtmlRenderer(); string html = string.Empty; try { Document document = parser.Parse(content); html = htmlRenderer.Render(document); } catch (ParsingException x) { html = string.Format( "Markdown parsing error at {0} as block type {1}", x.Position, x.BuilderType); } catch (RenderingException renderingException) { html = string.Format( "Markdown rendering error with block {0} using {1} renderer", renderingException.Block, renderingException.Renderer); } return Response.AsText(html, "text/html"); }; }
public ItemIndexModel(Item item) { if (item == null) throw new ArgumentNullException("item"); Id = item.Id; IsPublic = item.IsPublic; Type = item.Type.ToString().ToLower(); Author = item.Author.Name; Title = item.Title; Tags = item.ItemTags.Select(x => x.Name).ToArray(); Revision = item.RevisionNo; Created = item.CreatedDateTime; Modified = item.LastModifiedDateTime; using (var parser = new MarkdownParser()) { Body = parser.Strip(item.Body); } }
public void UsePreprocessors() { /* given */ var builder = new StringBuilder(); builder.AppendLine("paragraph is just text"); builder.AppendLine("that can continue for"); builder.AppendLine("multiple lines"); string markdown = builder.ToString(); var preprocessor = Substitute.For<IPreprocessor>(); var parser = new MarkdownParser(); parser.Pre.Insert(0, preprocessor); /* when */ parser.Parse(markdown); /* then */ preprocessor.Received().Process(Arg.Is(markdown)); }
public void Paragraph() { /* given */ var builder = new StringBuilder(); builder.AppendLine("paragraph is just text"); builder.AppendLine("that can continue for"); builder.AppendLine("multiple lines"); string markdown = builder.ToString(); var parser = new MarkdownParser(); /* when */ Document result = parser.Parse(markdown); /* then */ result.Blocks.Should().ContainSingle(block => block.GetType() == typeof (Paragraph)); var paragraph = result.Blocks.Single() as Paragraph; paragraph.Start.ShouldBeEquivalentTo(0); paragraph.Spans.Should().HaveCount(5); }
public void MultipleParagraphs() { /* given */ var builder = new StringBuilder(); builder.AppendLine("paragraph is just text"); builder.AppendLine("that can continue for"); builder.AppendLine(); builder.AppendLine("second paragraph"); builder.AppendLine("multiple lines"); string markdown = builder.ToString(); var parser = new MarkdownParser(); /* when */ Document result = parser.Parse(markdown); /* then */ result.Blocks.Should().HaveCount(2); result.Blocks.Should().ContainItemsAssignableTo<Paragraph>(); }
public void ParseEscapingSameWayAsGithub() { MarkdownParser markdownParser = new MarkdownParser(); DocumentNode documentNode = MarkdownStringToDocumentNode(@" \< \\< \\\< \\\\< \\\\\< \\\\[ \ \\ \\\ \\\\ ( ) [ ] \( \) \[ \\[ \] \` \* \\* \\\* \_ \\_ \\\_ "); ParagraphNode paragraphNode = this.AssertNodeType <ParagraphNode>( documentNode.Children.ElementAtOrDefault(0), MarkdownNodeType.Paragraph); // NOTE: to update this example, create a gist on github to check out how it's parsed. Assert.Equal(@"< \< \< \\< \\< \\[ \ \ \\ \\ ( ) [ ] ( ) [ \[ ] ` * \* \* _ \_ \_", paragraphNode.Spans.First().Text); }
private string GetAutoWrappingForMarkdown(string[] lines) { // this is an implementation of https://github.com/PowerShell/platyPS/issues/93 // algorithm: identify chunks that represent lists // Every entry in a list should be preserved as is and 1 EOL between them // Every entry not in a list should be split with GetAutoWrappingForNonListLine // delimiters between lists and non-lists are 2 EOLs. var newLines = new List <string>(); for (int i = 0; i < lines.Length; i++) { if (MarkdownParser.HasListPrefix(lines[i])) { if (i > 0 && !MarkdownParser.HasListPrefix(lines[i - 1])) { // we are in a list and it just started newLines.Add(Environment.NewLine + lines[i]); } else { newLines.Add(lines[i]); } } else { if (i > 0) { // we are just finished a list newLines.Add(Environment.NewLine + GetAutoWrappingForNonListLine(lines[i])); } else { newLines.Add(GetAutoWrappingForNonListLine(lines[i])); } } } return(string.Join(Environment.NewLine, newLines)); }
public async Task<ActionResult> Save(DraftEditModel model) { model.EntryMode = EntryMode.SaveDraft; TryValidateModel(model); if (!ModelState.IsValid) { using (var parser = new MarkdownParser()) { model.Html = parser.Transform(model.Body); return View("Edit", model); } } var draft = await _draftDbCommand.FindAsync(model.Id) ?? Draft.NewDraft(LogonUser, model.ItemType); Mapper.Map(model, draft); draft.LastModifiedDateTime = DateTime.Now; await _draftDbCommand.SaveAsync(draft); return RedirectToAction("Index", "Draft"); }
/// <summary> /// Converts a markdown string into Html. /// </summary> /// <param name="mdString"></param> /// <param name="mdPath"></param> /// <returns>Returns converted markdown as html</returns> internal string ParseToHtml(string mdString, string mdPath) { if (string.IsNullOrWhiteSpace(mdString)) { return(string.Empty); } using (var writer = new StringWriter()) { // Remove scripts from user content for security reasons. var renderer = new HtmlRenderer(writer); pipeline.Setup(renderer); var document = MarkdownParser.Parse(mdString, pipeline); ConvertRelativeLocalImagePathsToAbsolute(mdPath, document); renderer.Render(document); return(writer.ToString()); } }
private static void CreateItemModelsMap() { const string askTitlePrefix = @"質問: "; Mapper.CreateMap <Item, ItemIndexModel>() .ForMember(d => d.AuthorName, o => o.MapFrom(s => s.Author.Name)) .ForMember(d => d.AuthorDisplayName, o => o.MapFrom(s => s.Author.DisplayName)) .ForMember(d => d.AuthorIconUrl, o => o.MapFrom(s => s.Author.IconUrl ?? GlobalSettings.NoImageUserIconUrl)) .ForMember(d => d.Title, o => o.Ignore()) .AfterMap((s, d) => { d.Title = ((s.Type == ItemType.Ask) ? askTitlePrefix : "") + s.Title; }); Mapper.CreateMap <Item, ItemViewModel>() .ForMember(d => d.AuthorName, o => o.MapFrom(s => s.Author.Name)) .ForMember(d => d.AuthorDisplayName, o => o.MapFrom(s => s.Author.DisplayName)) .ForMember(d => d.AuthorIconUrl, o => o.MapFrom(s => s.Author.IconUrl ?? GlobalSettings.NoImageUserIconUrl)) .AfterMap((s, d) => { d.DisplayTitle = ((s.Type == ItemType.Ask) ? askTitlePrefix : "") + s.Title; using (var parser = new MarkdownParser()) { d.HtmlBody = parser.Transform(s.Body); } }); Mapper.CreateMap <ItemRevision, ItemRevisionDetailModel>() .ForMember(d => d.Comment, o => o.Ignore()) .AfterMap((s, d) => { if (s.IsFirst && string.IsNullOrWhiteSpace(s.Comment)) { d.Comment = "投稿"; return; } d.Comment = string.IsNullOrWhiteSpace(s.Comment) ? "(コメントなし)" : s.Comment; }); }
public ItemIndexModel(Item item) { if (item == null) { throw new ArgumentNullException("item"); } Id = item.Id; IsPublic = item.IsPublic; Type = item.Type.ToString().ToLower(); Author = item.Author.Name; Title = item.Title; Tags = item.ItemTags.Select(x => x.Name).ToArray(); Revision = item.RevisionNo; Created = item.CreatedDateTime; Modified = item.LastModifiedDateTime; using (var parser = new MarkdownParser()) { Body = parser.Strip(item.Body); } }
public void TestGetChangelogBy() { IMarkdownParser markdownParser = new MarkdownParser(); Milestone milestone = new MilestoneBuilder { Title = "v1.2.3", ClosedAt = DateTimeOffset.ParseExact("01.11.1993", "dd.MM.yyyy", CultureInfo.InvariantCulture), }.Build(); MilestoneObject milestoneObject = new MilestoneObject(milestone, new PullRequest[] { }); Dictionary <string, IList <string> > entries = new Dictionary <string, IList <string> > { { "added", new[] { "first added entry", "second added entry", } }, { "changed", new[] { "first changed entry", "second changed entry", } }, }; VersionEntry versionEntry = new VersionEntry(milestoneObject, entries); string expected = "## v1.2.3 (1993-11-01)\n\n### added\n\n* first added entry\n* second added entry\n\n### changed\n\n* first changed entry\n* second changed entry"; string result = markdownParser.GetChangelogBy(versionEntry); AreEqual(expected, result); }
private static string ToHtml(string markdown, MarkdownPipeline pipeline) { string markdownPreProcessed = MarkdownPreProcessors.Process(markdown); MarkdownPipeline GetPipeline() { var selfPipeline = pipeline.Extensions.Find <SelfPipelineExtension>(); return(selfPipeline is not null?selfPipeline.CreatePipelineFromInput(markdownPreProcessed) : pipeline); } pipeline = GetPipeline(); var document = MarkdownParser.Parse(markdownPreProcessed, pipeline); using var rentedRenderer = pipeline.RentCustomHtmlRenderer(); CustomHtmlRenderer renderer = rentedRenderer.Instance; renderer.Render(document); renderer.Writer.Flush(); return(HtmlPostProcessors.Process(renderer.Writer.ToString() ?? string.Empty)); }
public void TestGetChangelogEntries(string fileName, string[] expectedAddedEntries, string[] expectedChangedEntries, string[] expectedDeprecatedEntries, string[] expectedFixedEntries, string[] expectedRemovedEntries, string[] expectedSecurityEntries) { IMarkdownParser markdownParser = new MarkdownParser(); string markdownText = File.ReadAllText($"./Assets/{fileName}"); IDictionary <string, IList <string> > result = markdownParser.GetChangelogEntries(markdownText); AreEqual(6, result.Keys.Count); ExpectEquivalentEntries(result, "added", expectedAddedEntries); ExpectEquivalentEntries(result, "changed", expectedChangedEntries); ExpectEquivalentEntries(result, "deprecated", expectedDeprecatedEntries); ExpectEquivalentEntries(result, "fixed", expectedFixedEntries); ExpectEquivalentEntries(result, "removed", expectedRemovedEntries); ExpectEquivalentEntries(result, "security", expectedSecurityEntries); }
public void TestBlockquote() { var text = @"> ⚠️ When `component=""img""`, CardMedia relies on `object-fit` for centering the image. It's not supported by IE 11. ## UI Controls Supplemental actions within the card are explicitly called out using icons, text, and UI controls, typically placed at the bottom of the card. Here's an example of a media control card. "; var options = new Options(); var renderer = new MarkdownRenderer(); options.Renderer = renderer; var parser = new MarkdownParser(options); var tokensResult = Lexer.Lex(text, options); parser.Parse(tokensResult); }
public async Task <string> GetHtml(string localGetImgRelativeURI) { var httpClient = new HttpClient(); string mdBody = await httpClient.GetStringAsync(_rawSourceMDUrl).ConfigureAwait(false); var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build(); var document = MarkdownParser.Parse(mdBody, pipeline); var htmlRenderer = new HtmlRenderer(new StringWriter()); // Old approach for building local images url. // Removed because it does not manage explicit <img> tag inside MD files // //htmlRenderer.BaseUrl = new Uri(_rawBaseSourceUrl); //if (localGetImgRelativeURI != null) //{ // htmlRenderer.LinkRewriter = (oldlink) => // { // if (oldlink.StartsWith(_rawBaseSourceUrl)) // { // return localGetImgRelativeURI + Convert.ToBase64String(Encoding.UTF8.GetBytes(oldlink.Replace(_rawBaseSourceUrl, ""))); // } // else // { // return oldlink; // } // }; //} pipeline.Setup(htmlRenderer); htmlRenderer.Render(document); htmlRenderer.Writer.Flush(); string htmlBody = htmlRenderer.Writer.ToString(); htmlBody = await SetImgUrls(htmlBody, localGetImgRelativeURI); return(htmlBody); }
public void TransformMultilineDescription() { var parser = new MarkdownParser(); var doc = parser.ParseString(@" # Get-Foo ## Synopsis This is Synopsis, but it doesn't matter in this test ## DESCRIPTION Hello, I'm a multiline description. And this is my last line. "); MamlCommand mamlCommand = (new ModelTransformer()).NodeModelToMamlModel(doc).First(); string[] description = mamlCommand.Description.Split('\n').Select(x => x.Trim()).ToArray(); Assert.Equal(3, description.Length); Assert.Equal("Hello,", description[0]); Assert.Equal("I'm a multiline description.", description[1]); Assert.Equal("And this is my last line.", description[2]); }
public async Task <ActionResult> Save(DraftEditModel model) { model.EntryMode = EntryMode.SaveDraft; TryValidateModel(model); if (!ModelState.IsValid) { using (var parser = new MarkdownParser()) { model.Html = parser.Transform(model.Body); return(View("Edit", model)); } } var draft = await _draftDbCommand.FindAsync(model.Id) ?? Draft.NewDraft(LogonUser, model.ItemType); Mapper.Map(model, draft); draft.LastModifiedDateTime = DateTime.Now; await _draftDbCommand.SaveAsync(draft); return(RedirectToAction("Index", "Draft")); }
/// <summary> /// we only parse simple key-value pairs here /// </summary> /// <param name="yamlSnippet"></param> /// <returns></returns> private Dictionary <string, string> ParseYamlKeyValuePairs(CodeBlockNode yamlSnippet) { Dictionary <string, string> result; try { result = MarkdownParser.ParseYamlKeyValuePairs(yamlSnippet.Text); } catch (ArgumentException) { throw new HelpSchemaException(yamlSnippet.SourceExtent, "Invalid yaml: expected simple key-value pairs"); } foreach (var pair in result) { if (!IsKnownKey(pair.Key)) { throw new HelpSchemaException(yamlSnippet.SourceExtent, "Invalid yaml: unknown key " + pair.Key); } } return(result); }
/// <summary> /// Converts a Markdown string to HTML and output to the specified writer. /// </summary> /// <param name="markdown">A Markdown text.</param> /// <param name="writer">The destination <see cref="TextWriter"/> that will receive the result of the conversion.</param> /// <param name="pipeline">The pipeline used for the conversion.</param> /// <param name="context">A parser context used for the parsing.</param> /// <returns>The Markdown document that has been parsed</returns> /// <exception cref="ArgumentNullException">if reader or writer variable are null</exception> public static MarkdownDocument ToHtml(string markdown, TextWriter writer, MarkdownPipeline?pipeline = null, MarkdownParserContext?context = null) { if (markdown is null) { ThrowHelper.ArgumentNullException_markdown(); } if (writer is null) { ThrowHelper.ArgumentNullException_writer(); } pipeline = GetPipeline(pipeline, markdown); var document = MarkdownParser.Parse(markdown, pipeline, context); using var rentedRenderer = pipeline.RentHtmlRenderer(writer); HtmlRenderer renderer = rentedRenderer.Instance; renderer.Render(document); writer.Flush(); return(document); }
public void ProducesSyntaxInTheRightOrder() { var parser = new MarkdownParser(); const string docFormatString = @" # Get-Foo ## PARAMETERS ### SecondSetParam [String] ```powershell [Parameter(ParameterSetName = 'Set 2')] ``` ### FirstSetParam [String] ```powershell [Parameter(ParameterSetName = 'Set 1')] ``` "; var doc = parser.ParseString(docFormatString); MamlCommand mamlCommand = (new ModelTransformer()).NodeModelToMamlModel(doc).First(); Assert.Equal(mamlCommand.Name, "Get-Foo"); Assert.Equal(2, mamlCommand.Syntax.Count); var syntax1 = mamlCommand.Syntax[0]; var syntax2 = mamlCommand.Syntax[1]; Assert.Equal(syntax1.Parameters.Count, 1); Assert.Equal(syntax2.Parameters.Count, 1); Assert.Equal(syntax1.Parameters[0].Name, "FirstSetParam"); Assert.Equal(syntax2.Parameters[0].Name, "SecondSetParam"); }
public void ProducesSyntaxForTwoSets() { var parser = new MarkdownParser(); const string docFormatString = @" # Get-Foo ## PARAMETERS ### TypeName [String] ```powershell [Parameter(Mandatory = $true, ParameterSetName = 'Set 1')] [Parameter(ParameterSetName = 'Set 2')] ``` "; var doc = parser.ParseString(docFormatString); MamlCommand mamlCommand = (new ModelTransformer()).NodeModelToMamlModel(doc).First(); Assert.Equal(mamlCommand.Name, "Get-Foo"); Assert.Equal(2, mamlCommand.Syntax.Count); var syntax1 = mamlCommand.Syntax[0]; var syntax2 = mamlCommand.Syntax[1]; Assert.Equal(syntax1.Parameters.Count, 1); Assert.Equal(syntax2.Parameters.Count, 1); Assert.Equal(syntax1.Parameters[0].Name, "TypeName"); Assert.Equal(syntax2.Parameters[0].Name, "TypeName"); Assert.Equal(syntax1.Parameters[0].Type, "String"); Assert.Equal(syntax2.Parameters[0].Type, "String"); Assert.Equal(syntax1.Parameters[0].Required, false); Assert.Equal(syntax2.Parameters[0].Required, true); }
public async Task <IActionResult> PreviewArticle(Guid id) { var htmlSanitizer = new HtmlSanitizer(); //HTML Sanitizer var userEntity = await _userManager //Get logged in user's db entry .GetUserAsync(User); var articleInfo = _dbContext.Articles //Get all articles .FirstOrDefault(a => a.Id == id && //That match the Id in the route a.AuthorId == userEntity.Id); //and is submited by current user if (articleInfo == null) //if null return not found { return(NotFound()); } var articleText = await _fileRepository //Read article file from disk .GetArticle(articleInfo.ArticlePath); articleText = MarkdownParser //parse markdown .Parse(articleText) .ToString(); articleText = htmlSanitizer //sanitize .SanitizeDocument(articleText); return(View(articleText)); //return View of Article Dto }
/// <summary> /// Display a published article /// </summary> /// <param name="id">id of article</param> /// <returns>View of article</returns> public async Task <IActionResult> Article(Guid id) { var htmlSanitizer = new HtmlSanitizer(); //HTML sanitizer var articleEntity = _dbContext.Articles //Get article .FirstOrDefault(a => a.Id == id); if (articleEntity == null) //if null return NotFound { return(NotFound()); } else if (articleEntity.Status != Status.Published) //If not published return NotFound { return(NotFound()); } var articleDto = //Map to Dto Mapper.Map <GetArticleDto>(articleEntity); var articleText = await _fileRepository //Load article file .GetArticle(articleEntity.ArticlePath); articleText = MarkdownParser.Parse(articleText).ToString(); //Parse MarkDown articleDto.ArticleText = htmlSanitizer //Sanatize and add to DTO .SanitizeDocument(articleText); return(View(articleDto)); //return view of DTO }
/// <summary> /// performs a rough benchmark of the Markdown engine using small, medium, and large input samples /// please DO NOT MODIFY the input samples or the benchmark itself as this will invalidate previous /// benchmark runs! /// </summary> static void Benchmark(string text, int iterations) { var m = new MarkdownParser(); var sw = new Stopwatch(); sw.Start(); for (int i = 0; i < iterations; i++) { m.Transform(text); } sw.Stop(); Console.WriteLine("input string length: " + text.Length); Console.Write(iterations + " iteration" + (iterations == 1 ? "" : "s") + " in " + sw.ElapsedMilliseconds + " ms"); if (iterations == 1) { Console.WriteLine(); } else { Console.WriteLine(" (" + Convert.ToDouble(sw.ElapsedMilliseconds) / Convert.ToDouble(iterations) + " ms per iteration)"); } }
public SongController(SongService service, SongQueries queries, SongListQueries songListQueries, MarkdownParser markdownParser) { this.service = service; this.queries = queries; this.songListQueries = songListQueries; this.markdownParser = markdownParser; }
public void ParagraphWithImage() { /* given */ var contentBuilder = new StringBuilder(); contentBuilder.Append("And images ![alt](http://image.jpg)"); var parser = new MarkdownParser(); /* when */ var result = parser.Parse(contentBuilder.ToString()); /* then */ result.Blocks.Should().HaveCount(1); var paragaph = (Paragraph) result.Blocks.Single(); paragaph.Spans.Should().HaveCount(2); paragaph.Spans.OfType<TextSpan>().Single().ToString().ShouldBeEquivalentTo("And images "); var image = paragaph.Spans.OfType<ImageSpan>().Single(); image.Title.ToString().ShouldBeEquivalentTo("alt"); image.Url.ToString().ShouldBeEquivalentTo("http://image.jpg"); }
public void Headings() { /* given */ var builder = new StringBuilder(); builder.AppendLine("# Heading 1"); builder.AppendLine("## Heading 2"); builder.AppendLine("### Heading 3"); builder.AppendLine("#### Heading 4"); builder.AppendLine("##### Heading 5"); builder.AppendLine("###### Heading 6"); string markdown = builder.ToString(); var parser = new MarkdownParser(); /* when */ Document result = parser.Parse(markdown); /* then */ for (int i = 0; i < result.Blocks.Count(); i++) { string expected = string.Format("Heading {0}", i + 1); var heading = result.Blocks.ElementAt(i) as Heading; heading.Level.ShouldBeEquivalentTo(i + 1); heading.ToString().ShouldBeEquivalentTo(expected); } }
private DocumentNode ParseString(string markdown) { var parser = new MarkdownParser(); return(parser.ParseString(new string[] { markdown })); }
public ArtistController(ArtistService service, ArtistQueries queries, MarkdownParser markdownParser) { this.service = service; this.queries = queries; this.markdownParser = markdownParser; }
public UserController(UserService service, UserQueries data, ArtistService artistService, ArtistQueries artistQueries, OtherService otherService, IRepository repository, UserMessageQueries messageQueries, IPRuleManager ipRuleManager, VdbConfigManager config, MarkdownParser markdownParser) { Service = service; Data = data; this.artistQueries = artistQueries; this.artistService = artistService; this.repository = repository; this.otherService = otherService; this.messageQueries = messageQueries; this.ipRuleManager = ipRuleManager; this.config = config; this.markdownParser = markdownParser; }
public ContentResult ConvertToHtml(string markdown) { using (var parser = new MarkdownParser()) { return new ContentResult { Content = parser.Transform(markdown), ContentEncoding = Encoding.UTF8, ContentType = "text/html" }; } }
public void SimpleMultipleParagraphs() { /* given */ var builder = new StringBuilder(); builder.AppendLine("p1"); builder.AppendLine(); builder.AppendLine("p2"); string markdown = builder.ToString(); var parser = new MarkdownParser(); /* when */ Document result = parser.Parse(markdown); /* then */ result.Blocks.Should().HaveCount(2); result.Blocks.Should().ContainItemsAssignableTo<Paragraph>(); }
public void LinkDefinitions() { /* given */ var builder = new StringBuilder(); builder.AppendLine("[key 1]: url-1"); builder.AppendLine("[key 2]: url-2"); builder.AppendLine("[key 3]: url-3"); string markdown = builder.ToString(); var parser = new MarkdownParser(); /* when */ Document result = parser.Parse(markdown); /* then */ var list = result.Blocks.Single() as LinkDefinitionList; for (int i = 0; i < list.Definitions.Count(); i++) { string expectedKey = string.Format("key {0}", i + 1); string expectedUrl = string.Format("url-{0}", i + 1); LinkDefinition definition = list.Definitions.ElementAt(i); definition.Key.ToString().ShouldBeEquivalentTo(expectedKey); definition.Url.ToString().ShouldBeEquivalentTo(expectedUrl); } }
public static SaveResult SaveAs(DocumentModel document, string style) { Logger.GetInstance().Debug("SaveAs() >>"); try { var saveDialog = new SaveFileDialog { CreatePrompt = true, OverwritePrompt = true, Title = "Save a PMD file", Filter = "Project Markdown File | *.pmd" }; var result = saveDialog.ShowDialog(); if (result != null) { if (result == true) { var tempFolder = FolderPaths.TempFolderPath + "\\" + saveDialog.SafeFileName + "_temp"; if (Directory.Exists(tempFolder)) { Directory.Delete(tempFolder, true); } var parentFolder = Directory.CreateDirectory(tempFolder).FullName; var mp = new MarkdownParser(); // Generate HTML var html = mp.Parse(document.Markdown, style); var markdownFileName = saveDialog.SafeFileName + ".md"; var markdownFilePath = parentFolder + "\\" + markdownFileName; var htmlFileName = saveDialog.SafeFileName + ".html"; var htmlFilePath = parentFolder + "\\" + htmlFileName; var xmlFileName = saveDialog.SafeFileName + ".xml"; var metadataFilePath = parentFolder + "\\" + xmlFileName; // Generate MD file using (var sw = new StreamWriter(markdownFilePath)) { sw.Write(document.Markdown); } // Generate HTML file using (var sw = new StreamWriter(htmlFilePath)) { sw.Write(html); } document.FilePath = saveDialog.FileName; // Generate XML file document.Metadata.FileName = saveDialog.SafeFileName; document.Metadata.IsNew = false; var gxs = new GenericXmlSerializer <DocumentMetadata>(); gxs.Serialize(document.Metadata, metadataFilePath); // Generate the package if (File.Exists(document.FilePath)) { File.Delete(document.FilePath); } ZipFile.CreateFromDirectory(parentFolder, saveDialog.FileName); // Update the view var saveResult = new SaveResult { FileName = saveDialog.SafeFileName, Source = htmlFilePath.ToUri(), TempFile = tempFolder }; Logger.GetInstance().Debug("<< SaveAs()"); return(saveResult); } } Logger.GetInstance().Debug("<< SaveAs()"); return(null); } catch (Exception e) { throw e; } }
public void CodeblocsWithSyntaxIdentifierAndParagraphBetween() { /* given */ var builder = new StringBuilder(); builder.AppendLine("```cs"); builder.AppendLine("public int X = 1;"); builder.AppendLine("```"); builder.AppendLine("Some text here to separate the two"); builder.AppendLine("```js"); builder.AppendLine("public int X = 1;"); builder.AppendLine("```"); string markdown = builder.ToString(); var parser = new MarkdownParser(); /* when */ Document result = parser.Parse(markdown); /* then */ result.Blocks.Count().ShouldBeEquivalentTo(3); result.Blocks.ElementAt(0).As<Codeblock>().Syntax.ToString().ShouldBeEquivalentTo("cs"); result.Blocks.ElementAt(1).As<Paragraph>().ToString().ShouldBeEquivalentTo("\nSome text here to separate the two\n"); result.Blocks.ElementAt(2).As<Codeblock>().Syntax.ToString().ShouldBeEquivalentTo("js"); }
private static void CreateDraftModelsMap() { const string unTitled = "タイトル未設定"; Mapper.CreateMap<Draft, DraftIndexModel>() .ForMember(d => d.Title, o => o.Ignore()) .AfterMap((s, d) => { if (string.IsNullOrWhiteSpace(s.Title)) { d.Title = unTitled; d.UnTitled = true; } else { d.Title = s.Title; d.UnTitled = false; } }); Mapper.CreateMap<Draft, DraftPreviewModel>() .ForMember(d => d.Title, o => o.Ignore()) .AfterMap((s, d) => { if (string.IsNullOrWhiteSpace(s.Title)) { d.Title = unTitled; d.UnTitled = true; } else { d.Title = s.Title; d.UnTitled = false; } using (var parser = new MarkdownParser()) { d.Html = parser.Transform(s.Body); } }); Mapper.CreateMap<Draft, DraftEditModel>() .ForMember(d => d.ItemType, o => o.MapFrom(s => s.Type)) .AfterMap((s, d) => { if (s.IsContributed) { d.ItemIsPrivate = !s.ItemIsPublic; } else { d.ItemIsPrivate = false; } using (var parser = new MarkdownParser()) { d.Html = parser.Transform(s.Body); } var isFirst = true; foreach (var tag in s.ItemTags) { if (!isFirst) d.TagInlineString += " "; d.TagInlineString += tag.Name; if (tag.Version != null) d.TagInlineString += string.Format("[{0}]", tag.Version); isFirst = false; } }); Mapper.CreateMap<DraftEditModel, Draft>() .ForMember(d => d.Type, o => o.MapFrom(s => s.ItemType)) .ForMember(d => d.ItemIsPublic, o => o.MapFrom(s => !s.ItemIsPrivate)) .ForMember(d => d.CurrentRevisionNo, o => o.Ignore()) .AfterMap((s, d) => { d.ItemTags.Clear(); foreach (var tag in s.CreateTagCollectionFromInlineText()) { d.ItemTags.Add(tag); } }); }
public void SetextHeadings() { /* given */ var builder = new StringBuilder(); builder.AppendLine("Setext 1"); builder.AppendLine("========"); builder.AppendLine("Setext 2"); builder.AppendLine("--------"); string markdown = builder.ToString(); var parser = new MarkdownParser(); /* when */ Document result = parser.Parse(markdown); /* then */ result.Blocks.Should().HaveCount(2); var headingOne = result.Blocks.First() as Heading; headingOne.Level.ShouldBeEquivalentTo(1); headingOne.ToString().ShouldBeEquivalentTo("Setext 1"); var headingTwo = result.Blocks.Last() as Heading; headingTwo.Level.ShouldBeEquivalentTo(2); headingTwo.ToString().ShouldBeEquivalentTo("Setext 2"); }
protected override async Task <IEnumerable <IDocument> > ExecuteInputAsync(IDocument input, IExecutionContext context) { context.LogDebug( "Processing Markdown {0} for {1}", string.IsNullOrEmpty(_sourceKey) ? string.Empty : ("in" + _sourceKey), input.ToSafeDisplayString()); string content; if (string.IsNullOrEmpty(_sourceKey)) { content = await input.GetContentStringAsync(); } else if (input.ContainsKey(_sourceKey)) { content = input.GetString(_sourceKey) ?? string.Empty; } else { // Don't do anything if the key doesn't exist return(input.Yield()); } MarkdownPipeline pipeline = CreateMarkdownPipeline(); string result; using (StringWriter writer = new StringWriter()) { HtmlRenderer htmlRenderer = new HtmlRenderer(writer); pipeline.Setup(htmlRenderer); if (_prependLinkRoot && context.Settings.ContainsKey(Keys.LinkRoot)) { htmlRenderer.LinkRewriter = (link) => { if (string.IsNullOrEmpty(link)) { return(link); } if (link[0] == '/') { // root-based url, must be rewritten by prepending the LinkRoot setting value // ex: '/virtual/directory' + '/relative/abs/link.html' => '/virtual/directory/relative/abs/link.html' link = context.Settings[Keys.LinkRoot] + link; } return(link); }; } MarkdownDocument document = MarkdownParser.Parse(content, pipeline); htmlRenderer.Render(document); writer.Flush(); result = writer.ToString(); } if (_escapeAt) { result = EscapeAtRegex.Replace(result, "@"); result = result.Replace("\\@", "@"); } return(string.IsNullOrEmpty(_sourceKey) ? input.Clone(await context.GetContentProviderAsync(result)).Yield() : input .Clone(new MetadataItems { { string.IsNullOrEmpty(_destinationKey) ? _sourceKey : _destinationKey, result } }) .Yield()); }
public TagController(TagQueries queries, IEntryLinkFactory entryLinkFactory, IEnumTranslations enumTranslations, MarkdownParser markdownParser, IEntryImagePersisterOld entryThumbPersister) { this.queries = queries; this.entryLinkFactory = entryLinkFactory; this.enumTranslations = enumTranslations; this.markdownParser = markdownParser; this.entryThumbPersister = entryThumbPersister; }
public void ThrowParseErrorOnBuilderFailure() { /* given */ var contentBuilder = new StringBuilder(); contentBuilder.Append("1234567890"); const int expectedPosition = 5; var parser = new MarkdownParser(); parser.Builders.Insert( 0, new ExceptionAtPositionBuilder(expectedPosition)); /* when */ var exception = Assert.Throws<ParsingException>(() => { parser.Parse(contentBuilder.ToString()); }); exception.Position.ShouldBeEquivalentTo(expectedPosition); exception.BuilderType.ShouldBeEquivalentTo(typeof (ExceptionAtPositionBuilder)); exception.InnerException.Should().BeOfType<ArgumentNullException>(); exception.Content.ToString().ShouldBeEquivalentTo("67890"); }
public async Task<ActionResult> Publish(DraftEditModel model) { ModelState.Clear(); model.EntryMode = EntryMode.PublishItem; TryValidateModel(model); if (!ModelState.IsValid) { using (var parser = new MarkdownParser()) { model.Html = parser.Transform(model.Body); return View("Edit", model); } } var draft = await _draftDbCommand.FindAsync(model.Id, LogonUser) ?? Draft.NewDraft(LogonUser, model.ItemType); Mapper.Map(model, draft); var item = draft.ToItem(); item.PublishSince = model.PublishSince; item.PublishUntil = model.PublishUntil; await _itemDbCommand.SaveAsync(item); await _draftDbCommand.DeleteAsync(draft.Id, LogonUser); return RedirectToAction("Index", "Item"); }
public void Codeblock() { /* given */ var builder = new StringBuilder(); builder.AppendLine("```"); builder.AppendLine("public int X = 1;"); builder.AppendLine("```"); string markdown = builder.ToString(); var parser = new MarkdownParser(); /* when */ Document result = parser.Parse(markdown); /* then */ result.Blocks.Should().HaveCount(1); result.Blocks.Should().ContainSingle(block => block.GetType() == typeof (Codeblock)); }
private static BlogPostDto ToDto(BlogPost blogPost) { string html = string.Empty; if (!string.IsNullOrWhiteSpace(blogPost.Content)) { var md = new MarkdownParser(); var renderer = new MarkdownHtmlRenderer(); try { Document document = md.Parse(blogPost.Content); html = renderer.Render(document); } catch (ParsingException x) { html = string.Format( "Markdown parsing error at {0} as block type {1}", x.Position, x.BuilderType); } catch (RenderingException renderingException) { html = string.Format( "Markdown rendering error with block {0} using {1} renderer", renderingException.Block, renderingException.Renderer); } } return new BlogPostDto { Content = html, Author = blogPost.Author, Created = blogPost.Created, PublishedOn = blogPost.PublishedOn, Title = blogPost.Title, Slug = blogPost.Slug, Id = Id.WithoutCollection(blogPost.Id), Tags = blogPost.Tags ?? new Collection<string>() }; }
public void EmptyLine() { /* given */ var builder = new StringBuilder(); builder.AppendLine("paragraph is just text"); builder.AppendLine("that can continue for"); builder.AppendLine(); builder.AppendLine("second paragraph"); builder.AppendLine("multiple lines"); string markdown = builder.ToString(); var parser = new MarkdownParser(false); /* when */ Document result = parser.Parse(markdown); /* then */ result.Blocks.Should().HaveCount(3); var firstParagraph = result.Blocks.First() as Paragraph; firstParagraph.ToString().ShouldBeEquivalentTo("paragraph is just text\nthat can continue for\n"); var emptyLine = result.Blocks.ElementAt(1) as EmptyLine; emptyLine.Should().NotBeNull(); var secondParagraph = result.Blocks.Last() as Paragraph; secondParagraph.ToString().ShouldBeEquivalentTo("second paragraph\nmultiple lines\n"); }
public void GetNextSpanElement_NoSpanElementDecetected(string markdown) { parser = new MarkdownParser(markdown, spanElements); parser.ParseNextTag(); parser.ParseNextTag().SpanElement.Should().BeNull(); }
public void MultipleParagraphsWithNewLines() { /* given */ var builder = new StringBuilder(); builder.Append( "Paragraphs should be separated by one empty line. Paragraph text is part of one \nparagraph as long as there's no empty lines.\n\nThis is a second paragraph which starts from new line and there's one empty line\nabove it."); var markdown = builder.ToString(); var parser = new MarkdownParser(); /* when */ Document result = parser.Parse(markdown); /* then */ result.Blocks.Should().HaveCount(2); result.Blocks.Should().ContainItemsAssignableTo<Paragraph>(); }
private DocumentNode ParseStringPreserveFormat(string markdown) { var parser = new MarkdownParser(); return(parser.ParseString(new string[] { markdown }, ParserMode.FormattingPreserve, null)); }
public void OrdederedList() { /* given */ var builder = new StringBuilder(); builder.AppendLine("1. item 1"); builder.AppendLine("2. item 2"); builder.AppendLine("3. item 3"); string markdown = builder.ToString(); var parser = new MarkdownParser(); /* when */ Document result = parser.Parse(markdown); /* then */ var list = result.Blocks.Single() as List; list.IsOrdered.ShouldBeEquivalentTo(true); for (int i = 0; i < list.Items.Count(); i++) { string expected = string.Format("item {0}", i + 1); Item item = list.Items.ElementAt(i); item.ToString().ShouldBeEquivalentTo(expected); } }
private string FormatMarkdown(string markdown) => FormatMarkdown(MarkdownParser.ParseMinimal(markdown));
public void CodeblocskWithSyntaxIdentifier() { /* given */ var builder = new StringBuilder(); builder.AppendLine("```cs"); builder.AppendLine("public int X = 1;"); builder.AppendLine("```"); builder.AppendLine("```js"); builder.AppendLine("int X = 1;"); builder.AppendLine("```"); string markdown = builder.ToString(); var parser = new MarkdownParser(); /* when */ Document result = parser.Parse(markdown); /* then */ result.Blocks.Count().ShouldBeEquivalentTo(2); result.Blocks.Cast<Codeblock>().First().Syntax.ToString().ShouldBeEquivalentTo("cs"); result.Blocks.Cast<Codeblock>().Last().Syntax.ToString().ShouldBeEquivalentTo("js"); }
private static MarkdownDocument LoadDocument(string fileName) { var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build(); return(MarkdownParser.Parse(File.ReadAllText(fileName), pipeline)); }
public void Empty() { /* given */ var contentBuilder = new StringBuilder(); var parser = new MarkdownParser(); /* when */ var result = parser.Parse(contentBuilder.ToString()); /* then */ result.Blocks.Should().HaveCount(0); }