public void TestInclusion_InlineLevel() { // 1. Prepare data var root = @" Inline [!include[ref1](ref1.md ""This is root"")] Inline [!include[ref3](ref3.md ""This is root"")] "; var ref1 = @"[!include[ref2](ref2.md ""This is root"")]"; var ref2 = @"## Inline inclusion do not parse header [!include[root](root.md ""This is root"")]"; var ref3 = @"**Hello**"; File.WriteAllText("root.md", root); File.WriteAllText("ref1.md", ref1); File.WriteAllText("ref2.md", ref2); File.WriteAllText("ref3.md", ref3); var marked = DocfxFlavoredMarked.Markup(root, "root.md"); Assert.Equal("<p>Inline <!-- BEGIN INCLUDE: Include content from "ref1.md" --><!-- BEGIN INCLUDE: Include content from "ref2.md" -->## Inline inclusion do not parse header <!-- BEGIN ERROR INCLUDE: Unable to resolve [!include[root](root.md "This is root")]: Circular dependency found in "ref2.md" -->[!include[root](root.md \"This is root\")]<!--END ERROR INCLUDE --><!--END INCLUDE --><!--END INCLUDE -->\nInline <!-- BEGIN INCLUDE: Include content from "ref3.md" --><strong>Hello</strong><!--END INCLUDE --></p>\n", marked); }
public void CodeSnippetTagsShouldMatchCaseInsensitive() { //arange var content = @"// <tag1> line1 // <tag2> line2 // </tag2> line3 // </TAG1> // <unmatched> "; File.WriteAllText("Program.cs", content.Replace("\r\n", "\n")); // act var marked = DocfxFlavoredMarked.Markup("[!code[tag1](Program.cs#Tag1)]", "Program.cs"); // assert var expected = "<pre><code name=\"tag1\">line1\nline2\nline3\n</code></pre>"; Assert.Equal(expected.Replace("\r\n", "\n"), marked); }
public void TestRendererCreator() { var p = new TestDfmRendererPartProvider(); var renderer = CustomizedRendererCreator.CreateRenderer( new DfmRenderer(), new[] { p }, null); var engine = DocfxFlavoredMarked .CreateBuilder(".") .CreateDfmEngine(renderer); var result = engine.Markup(@"```cs public void TestRendererCreator() ``` ```cs-x public void TestRendererCreator() ```", "a.md"); Assert.Equal(@"<pre><code class=""lang-cs"">public void TestRendererCreator() </code></pre><pre class=""x""><code class=""lang-cs"">public void TestRendererCreator() </code></pre>".Replace("\r\n", "\n"), result); (renderer as IDisposable).Dispose(); Assert.True(p.CodeRendererPartInstance.Disposed); }
public DfmService( DfmServiceProvider provider, string baseDir, string templateDir, ICompositionContainer container, ImmutableDictionary <string, string> tokens, IReadOnlyList <string> fallbackFolders, IReadOnlyDictionary <string, object> parameters) { var options = DocfxFlavoredMarked.CreateDefaultOptions(); options.LegacyMode = provider.LegacyMode; options.ShouldFixId = provider.ShouldFixId; options.ShouldExportSourceInfo = true; options.XHtml = true; Builder = new DfmEngineBuilder( options, baseDir, templateDir, fallbackFolders, container) { TokenTreeValidator = MarkdownTokenTreeValidatorFactory.Combine(provider.TokenTreeValidator) }; _tokens = tokens; Renderer = CustomizedRendererCreator.CreateRenderer( new DfmRenderer { Tokens = _tokens }, provider.DfmRendererPartProviders, parameters); foreach (var c in provider.DfmEngineCustomizers) { c.Customize(Builder, parameters); } _incrementalContextHash = ComputeIncrementalContextHash(baseDir, templateDir, provider.TokenTreeValidator, parameters); }
public MarkdigMarkdownRenderer(Stack <IMarkdownToken> processedBlockTokens, string basePath, bool useLegacyMode = true, MigrationRule rule = MigrationRule.All) { var option = DocfxFlavoredMarked.CreateDefaultOptions(); option.LegacyMode = useLegacyMode; var builder = new DfmEngineBuilder(option); var render = new DfmRenderer(); _dfmEngine = builder.CreateDfmEngine(render); _dfmHtmlRender = new DfmHtmlRender(useLegacyMode); _rule = rule; var parameter = new MarkdownServiceParameters { BasePath = basePath, Extensions = new Dictionary <string, object> { { "EnableSourceInfo", false } } }; _service = new MarkdigMarkdownService(parameter); _processedBlockTokens = processedBlockTokens; }
public void TestDfmFencesBlockLevel() { var root = @" [!code-FakeREST[REST](api.json)] [!Code-FakeREST-i[REST-i](api.json ""This is root"")] [!CODE[No Language](api.json)] [!code-js[empty](api.json)] "; var apiJsonContent = @" { ""method"": ""GET"", ""resourceFormat"": ""https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End"", ""requestUrl"": ""https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End"", ""requestHeaders"": { ""Accept"": ""application/json"" } }"; File.WriteAllText("api.json", apiJsonContent.Replace("\r\n", "\n")); var marked = DocfxFlavoredMarked.Markup(root, "api.json"); Assert.Equal("<pre><code class=\"lang-FakeREST\" name=\"REST\">\n{\n "method": "GET",\n "resourceFormat": "https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End",\n "requestUrl": "https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End",\n "requestHeaders": {\n "Accept": "application/json"\n }\n}\n</code></pre><pre><code class=\"lang-FakeREST-i\" name=\"REST-i\" title=\"This is root\">\n{\n "method": "GET",\n "resourceFormat": "https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End",\n "requestUrl": "https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End",\n "requestHeaders": {\n "Accept": "application/json"\n }\n}\n</code></pre><pre><code name=\"No Language\">\n{\n "method": "GET",\n "resourceFormat": "https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End",\n "requestUrl": "https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End",\n "requestHeaders": {\n "Accept": "application/json"\n }\n}\n</code></pre><pre><code class=\"lang-js\" name=\"empty\">\n{\n "method": "GET",\n "resourceFormat": "https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End",\n "requestUrl": "https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End",\n "requestHeaders": {\n "Accept": "application/json"\n }\n}\n</code></pre>", marked); }
public void TestSectionNoteInBlockQuote(string source, string expected) { var markedContent = DocfxFlavoredMarked.Markup(source); Assert.Equal(expected.Replace("\r\n", "\n"), markedContent); }
public void TestBlockLevelInclusionWithSameFile() { // -r // |- r.md // |- a // | |- a.md // |- b // | |- token.md // |- c // |- d // |- d.md // |- img // | |- img.jpg var r = @" [!include[](a/a.md)] [!include[](c/d/d.md)] "; var a = @" [!include[](../b/token.md)]"; var token = @" ![](../img/img.jpg) [](#anchor) [a](../a/a.md) [](invalid.md) [d](../c/d/d.md#anchor) "; var d = @" [!include[](../../b/token.md)]"; WriteToFile("r/r.md", r); WriteToFile("r/a/a.md", a); WriteToFile("r/b/token.md", token); WriteToFile("r/c/d/d.md", d); var dependency = new HashSet <string>(); var marked = DocfxFlavoredMarked.Markup(a, "r/a/a.md", dependency: dependency); var expected = @"<!-- BEGIN INCLUDE: Include content from "r/b/token.md" --><p><img src=""~/r/img/img.jpg"" alt=""""> <a href=""#anchor""></a> <a href=""~/r/a/a.md"">a</a> <a href=""~/r/b/invalid.md""></a> <a href=""~/r/c/d/d.md#anchor"">d</a></p> <!--END INCLUDE -->".Replace("\r\n", "\n"); Assert.Equal(expected, marked); Assert.Equal( new[] { "../b/token.md" }, dependency.OrderBy(x => x)); dependency.Clear(); marked = DocfxFlavoredMarked.Markup(d, "r/c/d/d.md", dependency: dependency); Assert.Equal(expected, marked); Assert.Equal( new[] { "../../b/token.md" }, dependency.OrderBy(x => x)); dependency.Clear(); marked = DocfxFlavoredMarked.Markup(r, "r/r.md", dependency: dependency); Assert.Equal($@"<!-- BEGIN INCLUDE: Include content from "r/a/a.md" -->{expected}<!--END INCLUDE --><!-- BEGIN INCLUDE: Include content from "r/c/d/d.md" -->{expected}<!--END INCLUDE -->", marked); Assert.Equal( new[] { "a/a.md", "b/token.md", "c/d/d.md" }, dependency.OrderBy(x => x)); }
public void TestFallback_InclusionWithCodeFences() { // -root_folder (this is also docset folder) // |- root.md // |- a_folder // |- a.md // |- code_folder // |- sample1.cs // -fallback_folder // |- a_folder // |- code_in_a.cs // |- code_folder // |- sample2.cs // 1. Prepare data var root = @"markdown root.md main content start. mardown a content in root.md content start [!include[a](a_folder/a.md ""This is a.md"")] mardown a content in root.md content end sample 1 code in root.md content start [!CODE-cs[this is sample 1 code](code_folder/sample1.cs)] sample 1 code in root.md content end sample 2 code in root.md content start [!CODE-cs[this is sample 2 code](code_folder/sample2.cs)] sample 2 code in root.md content end markdown root.md main content end."; var a = @"markdown a.md main content start. code_in_a code in a.md content start [!CODE-cs[this is code_in_a code](code_in_a.cs)] code_in_a in a.md content end markdown a.md a.md content end."; var code_in_a = @"namespace code_in_a{}"; var sample1 = @"namespace sample1{}"; var sample2 = @"namespace sample2{}"; var uniqueFolderName = Path.GetRandomFileName(); WriteToFile($"{uniqueFolderName}/root_folder/root.md", root); WriteToFile($"{uniqueFolderName}/root_folder/a_folder/a.md", a); WriteToFile($"{uniqueFolderName}/root_folder/code_folder/sample1.cs", sample1); WriteToFile($"{uniqueFolderName}/fallback_folder/a_folder/code_in_a.cs", code_in_a); WriteToFile($"{uniqueFolderName}/fallback_folder/code_folder/sample2.cs", sample2); try { EnvironmentContext.SetBaseDirectory($"{uniqueFolderName}/root_folder"); var fallbackFolders = new List <string> { { Path.Combine(Directory.GetCurrentDirectory(), $"{uniqueFolderName}/fallback_folder") } }; // Verify root.md markup result var rootDependency = new HashSet <string>(); var rootMarked = DocfxFlavoredMarked.Markup(Path.Combine(Directory.GetCurrentDirectory(), $"{uniqueFolderName}/root_folder"), root, fallbackFolders, "root.md", dependency: rootDependency); Assert.Equal(@"<p>markdown root.md main content start.</p> <p>mardown a content in root.md content start</p> <p>markdown a.md main content start.</p> <p>code_in_a code in a.md content start</p> <pre><code class=""lang-cs"" name=""this is code_in_a code"">namespace code_in_a{} </code></pre><p>code_in_a in a.md content end</p> <p>markdown a.md a.md content end.</p> <p>mardown a content in root.md content end</p> <p>sample 1 code in root.md content start</p> <pre><code class=""lang-cs"" name=""this is sample 1 code"">namespace sample1{} </code></pre><p>sample 1 code in root.md content end</p> <p>sample 2 code in root.md content start</p> <pre><code class=""lang-cs"" name=""this is sample 2 code"">namespace sample2{} </code></pre><p>sample 2 code in root.md content end</p> <p>markdown root.md main content end.</p> ".Replace("\r\n", "\n"), rootMarked); Assert.Equal( new[] { "../fallback_folder/a_folder/code_in_a.cs", "../fallback_folder/code_folder/sample2.cs", "a_folder/a.md", "a_folder/code_in_a.cs", "code_folder/sample1.cs", "code_folder/sample2.cs" }, rootDependency.OrderBy(x => x)); // Verify a.md markup result var aDependency = new HashSet <string>(); var aMarked = DocfxFlavoredMarked.Markup(Path.Combine(Directory.GetCurrentDirectory(), $"{uniqueFolderName}/root_folder"), a, fallbackFolders, "a_folder/a.md", dependency: aDependency); Assert.Equal(@"<p>markdown a.md main content start.</p> <p>code_in_a code in a.md content start</p> <pre><code class=""lang-cs"" name=""this is code_in_a code"">namespace code_in_a{} </code></pre><p>code_in_a in a.md content end</p> <p>markdown a.md a.md content end.</p> ".Replace("\r\n", "\n"), aMarked); Assert.Equal( new[] { "../../fallback_folder/a_folder/code_in_a.cs", "code_in_a.cs" }, aDependency.OrderBy(x => x)); } finally { EnvironmentContext.Clean(); } }
public void TestRendererCreator() { var content = @"namespace ConsoleApplication1 { // <namespace> using System; using System.Collections.Generic; using System.IO; // </namespace> // <snippetprogram> class Program { static void Main(string[] args) { string s = ""\ntest""; int i = 100; } } // </snippetprogram> #region Helper internal static class Helper { #region Foo public static void Foo() { } #endregion Foo } #endregion }"; File.WriteAllText("Program.csdocfx", content.Replace("\r\n", "\n")); var p = new TestDfmRendererPartProvider(); var renderer = CustomizedRendererCreator.CreateRenderer( new DfmRenderer(), new[] { p }, null); var engine = DocfxFlavoredMarked .CreateBuilder(".") .CreateDfmEngine(renderer); var result = engine.Markup(@"```cs public void TestRendererCreator() ``` ```cs-x public void TestRendererCreator() ``` [!code-csdocfx[Main](Program.csdocfx#namespace ""This is root"")] [!code-cs-xyz[](Program.csdocfx#Foo)]", "a.md"); Assert.Equal(@"<pre><code class=""lang-cs"">public void TestRendererCreator() </code></pre><pre class=""x""><code class=""lang-cs"">public void TestRendererCreator() </code></pre><pre><code class=""lang-csdocfx"" name=""Main"" title=""This is root"">using System; using System.Collections.Generic; using System.IO; </code></pre><pre><code class=""lang-cs-xyz"">public static void Foo() { } </code></pre>".Replace("\r\n", "\n"), result); (renderer as IDisposable).Dispose(); Assert.True(p.CodeRendererPartInstance.Disposed); if (File.Exists("Program.csdocfx")) { File.Delete("Program.csdocfx"); } }
public DfmService(string baseDir) { _builder = DocfxFlavoredMarked.CreateBuilder(baseDir); }
public void TestSectionCornerCase(string source, string expected) { var content = DocfxFlavoredMarked.Markup(source); Assert.Equal(expected, content); }
public void TestDfmInGeneral(string source, string expected) { Assert.Equal(expected.Replace("\r\n", "\n"), DocfxFlavoredMarked.Markup(source)); }
public MarkupResult MarkupCore(string markdown, FileAndType ft) { var html = DocfxFlavoredMarked.Markup(markdown, Path.Combine(ft.BaseDir, ft.File)); var doc = new HtmlDocument(); doc.LoadHtml(html); var result = new MarkupResult(); var node = doc.DocumentNode.SelectSingleNode("//yamlheader"); if (node != null) { using (var sr = new StringReader(StringHelper.HtmlDecode(node.InnerHtml))) { result.YamlHeader = YamlUtility.Deserialize <Dictionary <string, object> >(sr).ToImmutableDictionary(); } node.Remove(); } var linkToFiles = new HashSet <string>(); foreach (var link in from n in doc.DocumentNode.Descendants() where !string.Equals(n.Name, "xref", StringComparison.OrdinalIgnoreCase) from attr in n.Attributes where string.Equals(attr.Name, "src", StringComparison.OrdinalIgnoreCase) || string.Equals(attr.Name, "href", StringComparison.OrdinalIgnoreCase) where !string.IsNullOrWhiteSpace(attr.Value) select attr) { string linkFile; string anchor = null; if (PathUtility.IsRelativePath(link.Value)) { var index = link.Value.IndexOf('#'); if (index == -1) { linkFile = link.Value; } else if (index == 0) { continue; } else { linkFile = link.Value.Remove(index); anchor = link.Value.Substring(index); } var path = (RelativePath)ft.File + (RelativePath)linkFile; if (path.ParentDirectoryCount > 0) { Logger.LogError($"Cannot refer path: \"{path}\" out of project.", file: ft.File); throw new DocumentException($"Cannot refer path \"{path}\" out of project in file \"{ft.File}\"."); } var file = path.GetPathFromWorkingFolder(); link.Value = file + anchor; linkToFiles.Add(HttpUtility.UrlDecode(file)); } } result.LinkToFiles = linkToFiles.ToImmutableArray(); result.LinkToUids = (from n in doc.DocumentNode.Descendants() where string.Equals(n.Name, "xref", StringComparison.OrdinalIgnoreCase) from attr in n.Attributes where string.Equals(attr.Name, "href", StringComparison.OrdinalIgnoreCase) where !string.IsNullOrWhiteSpace(attr.Value) select attr.Value).ToImmutableHashSet(); using (var sw = new StringWriter()) { doc.Save(sw); result.Html = sw.ToString(); } return(result); }
private void Init(string phaseName) { Listener = new TestLoggerListener(phaseName); Logger.RegisterListener(Listener); DocfxFlavoredMarked.ClearBuilder(); }
public void TestDfmFencesInlineLevel() { var root = @" | Code in table | Header1 | ----------------- | ---------------------------- | [!code-FakeREST[REST](api.json)] | [!Code-FakeREST-i[REST-i](api.json ""This is root"")] | [!CODE[No Language](api.json)] | [!code-js[empty](api.json)] "; var apiJsonContent = @" { ""method"": ""GET"", ""resourceFormat"": ""https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End"", ""requestUrl"": ""https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End"", ""requestHeaders"": { ""Accept"": ""application/json"" } }"; File.WriteAllText("api.json", apiJsonContent.Replace("\r\n", "\n")); var dependency = new HashSet <string>(); var marked = DocfxFlavoredMarked.Markup(root, "api.json", dependency: dependency); const string expected = @"<table> <thead> <tr> <th>Code in table</th> <th>Header1</th> </tr> </thead> <tbody> <tr> <td><pre><code class=""lang-FakeREST"" name=""REST""> { "method": "GET", "resourceFormat": "https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End", "requestUrl": "https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End", "requestHeaders": { "Accept": "application/json" } } </code></pre></td> <td><pre><code class=""lang-FakeREST-i"" name=""REST-i"" title=""This is root""> { "method": "GET", "resourceFormat": "https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End", "requestUrl": "https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End", "requestHeaders": { "Accept": "application/json" } } </code></pre></td> </tr> <tr> <td><pre><code name=""No Language""> { "method": "GET", "resourceFormat": "https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End", "requestUrl": "https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End", "requestHeaders": { "Accept": "application/json" } } </code></pre></td> <td><pre><code class=""lang-js"" name=""empty""> { "method": "GET", "resourceFormat": "https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End", "requestUrl": "https://outlook.office.com/api/v1.0/me/events?$select=Subject,Organizer,Start,End", "requestHeaders": { "Accept": "application/json" } } </code></pre></td> </tr> </tbody> </table> "; Assert.Equal(expected.Replace("\r\n", "\n"), marked); Assert.Equal( new[] { "api.json" }, dependency.OrderBy(x => x)); }
public DfmJsonTokenTreeService(string baseDir, IMarkdownTokenTreeValidator tokenTreeValidator) { _builder = DocfxFlavoredMarked.CreateBuilder(baseDir); _builder.TokenTreeValidator = tokenTreeValidator; }
private void CleanUp() { Logger.UnregisterAllListeners(); Listener = null; DocfxFlavoredMarked.ClearBuilder(); }
public void TestTabGroup_DifferentTabIdSet() { var listener = TestLoggerListener.CreateLoggerListenerWithPhaseEqualFilter("test!!!!"); var options = DocfxFlavoredMarked.CreateDefaultOptions(); options.ShouldExportSourceInfo = true; var groupId = "aupEkulau5"; string actual; try { Logger.RegisterListener(listener); using (new LoggerPhaseScope("test!!!!")) { actual = DocfxFlavoredMarked.Markup(null, null, options, @"# [title-a](#tab/a) content-a # [title-b](#tab/b) content-b - - - # [title-a](#tab/a) content-a # [title-c](#tab/c) content-c - - -", "test.md"); } } finally { Logger.UnregisterListener(listener); } var expected = $@"<div class=""tabGroup"" id=""tabgroup_{groupId}"" sourceFile=""test.md"" sourceStartLineNumber=""1"" sourceEndLineNumber=""5""> <ul role=""tablist""> <li role=""presentation""> <a href=""#tabpanel_{groupId}_a"" role=""tab"" aria-controls=""tabpanel_{groupId}_a"" data-tab=""a"" tabindex=""0"" aria-selected=""true"" sourceFile=""test.md"" sourceStartLineNumber=""1"" sourceEndLineNumber=""1"">title-a</a> </li> <li role=""presentation""> <a href=""#tabpanel_{groupId}_b"" role=""tab"" aria-controls=""tabpanel_{groupId}_b"" data-tab=""b"" tabindex=""-1"" sourceFile=""test.md"" sourceStartLineNumber=""3"" sourceEndLineNumber=""3"">title-b</a> </li> </ul> <section id=""tabpanel_{groupId}_a"" role=""tabpanel"" data-tab=""a""> <p sourceFile=""test.md"" sourceStartLineNumber=""2"" sourceEndLineNumber=""2"">content-a</p> </section> <section id=""tabpanel_{groupId}_b"" role=""tabpanel"" data-tab=""b"" aria-hidden=""true"" hidden=""hidden""> <p sourceFile=""test.md"" sourceStartLineNumber=""4"" sourceEndLineNumber=""4"">content-b</p> </section> </div> <div class=""tabGroup"" id=""tabgroup_{groupId}-1"" sourceFile=""test.md"" sourceStartLineNumber=""6"" sourceEndLineNumber=""10""> <ul role=""tablist""> <li role=""presentation""> <a href=""#tabpanel_{groupId}-1_a"" role=""tab"" aria-controls=""tabpanel_{groupId}-1_a"" data-tab=""a"" tabindex=""0"" aria-selected=""true"" sourceFile=""test.md"" sourceStartLineNumber=""6"" sourceEndLineNumber=""6"">title-a</a> </li> <li role=""presentation""> <a href=""#tabpanel_{groupId}-1_c"" role=""tab"" aria-controls=""tabpanel_{groupId}-1_c"" data-tab=""c"" tabindex=""-1"" sourceFile=""test.md"" sourceStartLineNumber=""8"" sourceEndLineNumber=""8"">title-c</a> </li> </ul> <section id=""tabpanel_{groupId}-1_a"" role=""tabpanel"" data-tab=""a""> <p sourceFile=""test.md"" sourceStartLineNumber=""7"" sourceEndLineNumber=""7"">content-a</p> </section> <section id=""tabpanel_{groupId}-1_c"" role=""tabpanel"" data-tab=""c"" aria-hidden=""true"" hidden=""hidden""> <p sourceFile=""test.md"" sourceStartLineNumber=""9"" sourceEndLineNumber=""9"">content-c</p> </section> </div> "; Assert.Equal(expected.Replace("\r\n", "\n"), actual); Assert.Equal(new[] { WarningCodes.Markdown.DifferentTabIdSet }, from item in listener.Items select item.Code); }
public void TestSectionWithTextFollowed(string source) { var markedContent = DocfxFlavoredMarked.Markup(source); Assert.Equal("<div class=\"All\" id=\"All\"><p>Followed text\nWe should support that.</p>\n</div>\n", markedContent); }
public void TestSectionBlockLevelRecursive(string source) { var markedContent = DocfxFlavoredMarked.Markup(source); Assert.Equal("<div class=\"All\" id=\"All\"><p>this is out all</p>\n<div class=\"A\" id=\"A\"><p>this is A</p>\n</div>\n<div class=\"B\" id=\"B\"><p>this is B</p>\n</div>\n</div>\n", markedContent); }
public HostService(string baseDir, IEnumerable <FileModel> models) { _engine = DocfxFlavoredMarked.CreateBuilder(baseDir); LoadCore(models); }
public void TestSectionNoteMixture(string source) { var content = DocfxFlavoredMarked.Markup(source); Assert.Equal("<blockquote><p>this is blockquote</p>\n<p>this line is also in the before blockquote</p>\n</blockquote>\n<div class=\"NOTE\"><h5>NOTE</h5><p>This is note text</p>\n</div>\n<div class=\"WARNING\"><h5>WARNING</h5><p>This is warning text</p>\n</div>\n<div class=\"a\" id=\"diva\"><p>this is div with class a and id diva\ntext also in div</p>\n</div>\n<div class=\"b\" cause=\"divb\"><p>this is div with class b and cause divb</p>\n</div>\n<div class=\"IMPORTANT\"><h5>IMPORTANT</h5><p>This is imoprtant text follow div</p>\n</div>\n", content); }
public DfmService(string baseDir, ImmutableDictionary <string, string> tokens) { _builder = DocfxFlavoredMarked.CreateBuilder(baseDir); _tokens = tokens; }
public void TestBlockLevelInclusion() { // -r // |- root.md // |- empty.md // |- a // | |- refc.md // |- b // | |- linkAndRefRoot.md // | |- a.md // | |- img // | | |- img.jpg // |- c // | |- c.md // |- link // |- link2.md // |- md // |- c.md var root = @" [!include[linkAndRefRoot](b/linkAndRefRoot.md)] [!include[refc](a/refc.md ""This is root"")] [!include[refc_using_cache](a/refc.md)] [!include[empty](empty.md)] [!include[external](http://microsoft.com/a.md)]"; var linkAndRefRoot = @" Paragraph1 [link](a.md) [!include[link2](../link/link2.md)] ![Image](img/img.jpg) [!include[root](../root.md)]"; var link2 = @"[link](md/c.md)"; var refc = @"[!include[c](../c/c.md ""This is root"")]"; var c = @"**Hello**"; WriteToFile("r/root.md", root); WriteToFile("r/a/refc.md", refc); WriteToFile("r/b/linkAndRefRoot.md", linkAndRefRoot); WriteToFile("r/link/link2.md", link2); WriteToFile("r/c/c.md", c); WriteToFile("r/empty.md", string.Empty); var dependency = new HashSet <string>(); var marked = DocfxFlavoredMarked.Markup(root, "r/root.md", dependency: dependency); Assert.Equal(@"<!-- BEGIN INCLUDE: Include content from "r/b/linkAndRefRoot.md" --><p>Paragraph1 <a href=""~/r/b/a.md"">link</a> <!-- BEGIN INCLUDE: Include content from "r/link/link2.md" --><a href=""~/r/link/md/c.md"">link</a><!--END INCLUDE --> <img src=""~/r/b/img/img.jpg"" alt=""Image""> <!-- BEGIN ERROR INCLUDE: Unable to resolve [!include[root](../root.md)]: Circular dependency found in "r/b/linkAndRefRoot.md" -->[!include[root](../root.md)]<!--END ERROR INCLUDE --></p> <!--END INCLUDE --><!-- BEGIN INCLUDE: Include content from "r/a/refc.md" --><!-- BEGIN INCLUDE: Include content from "r/c/c.md" --><p><strong>Hello</strong></p> <!--END INCLUDE --><!--END INCLUDE --><!-- BEGIN INCLUDE: Include content from "r/a/refc.md" --><!-- BEGIN INCLUDE: Include content from "r/c/c.md" --><p><strong>Hello</strong></p> <!--END INCLUDE --><!--END INCLUDE --><!-- BEGIN INCLUDE: Include content from "r/empty.md" --><!--END INCLUDE --><!-- BEGIN ERROR INCLUDE: Absolute path "http://microsoft.com/a.md" is not supported. -->[!include[external](http://microsoft.com/a.md)]<!--END ERROR INCLUDE -->".Replace("\r\n", "\n"), marked); Assert.Equal( new[] { "a/refc.md", "b/linkAndRefRoot.md", "c/c.md", "empty.md", "link/link2.md", "root.md", }, dependency.OrderBy(x => x)); }
public void TestReadMarkdownAsOverwrite() { var content = @"--- uid: Test remarks: Hello --- This is unit test!"; content = Regex.Replace(content, "\r?\n", "\r\n"); var html = DocfxFlavoredMarked.Markup(content); var baseDir = Directory.GetCurrentDirectory(); var fileName = "ut_ReadMarkdownAsOverwrite.md"; var fullPath = Path.Combine(baseDir, fileName); File.WriteAllText(fullPath, content); var host = new HostService(null, Enumerable.Empty <FileModel>()) { MarkdownService = new DfmServiceProvider().CreateMarkdownService(new MarkdownServiceParameters { BasePath = string.Empty }) }; var ft = new FileAndType(baseDir, fileName, DocumentType.Overwrite, null); var results = MarkdownReader.ReadMarkdownAsOverwrite(host, ft).ToList(); Assert.NotNull(results); Assert.Equal(1, results.Count); Assert.Equal("Test", results[0].Uid); Assert.Equal("Hello", results[0].Metadata["remarks"]); Assert.Equal("<p>This is unit test!</p>\n", results[0].Conceptual); File.Delete(fileName); // Test conceptual content between two yamlheader content = @"--- uid: Test1 remarks: Hello --- This is unit test! --- uid: Test2 --- "; content = Regex.Replace(content, "\r?\n", "\r\n"); html = DocfxFlavoredMarked.Markup(content); File.WriteAllText(fileName, content); results = MarkdownReader.ReadMarkdownAsOverwrite(host, ft).ToList(); Assert.NotNull(results); Assert.Equal(2, results.Count); Assert.Equal("Test1", results[0].Uid); Assert.Equal("Test2", results[1].Uid); Assert.Equal("Hello", results[0].Metadata["remarks"]); Assert.Equal("<p>This is unit test!</p>\n", results[0].Conceptual); Assert.Equal(string.Empty, results[1].Conceptual); File.Delete(fileName); //invalid yamlheader is not supported content = @"--- uid: Test1 remarks: Hello --- This is unit test! --- uid: Test2 --- "; content = Regex.Replace(content, "\r?\n", "\r\n"); html = DocfxFlavoredMarked.Markup(content); File.WriteAllText(fileName, content); results = MarkdownReader.ReadMarkdownAsOverwrite(host, ft).ToList(); Assert.NotNull(results); Assert.Equal(1, results.Count); Assert.Equal("Test1", results[0].Uid); Assert.Equal("Hello", results[0].Metadata["remarks"]); Assert.Equal("<h2 id=\"this-is-unit-test-\">This is unit test!</h2>\n<h2 id=\"uid-test2\">uid: Test2</h2>\n", results[0].Conceptual); File.Delete(fileName); // Test conceptual content with extra empty line between two yamlheader content = @"--- uid: Test1 remarks: Hello --- This is unit test! --- uid: Test2 --- "; content = Regex.Replace(content, "\r?\n", "\r\n"); html = DocfxFlavoredMarked.Markup(content); File.WriteAllText(fileName, content); results = MarkdownReader.ReadMarkdownAsOverwrite(host, ft).ToList(); Assert.NotNull(results); Assert.Equal(2, results.Count); Assert.Equal("Test1", results[0].Uid); Assert.Equal("Test2", results[1].Uid); Assert.Equal("Hello", results[0].Metadata["remarks"]); Assert.Equal("<p>This is unit test!</p>\n", results[0].Conceptual); Assert.Equal(string.Empty, results[1].Conceptual); File.Delete(fileName); // Test different line ending content = "---\nuid: Test\nremarks: Hello\n---\nThis is unit test!\n"; html = DocfxFlavoredMarked.Markup(content); File.WriteAllText(fileName, content); results = MarkdownReader.ReadMarkdownAsOverwrite(host, ft).ToList(); Assert.NotNull(results); Assert.Equal(1, results.Count); Assert.Equal("Test", results[0].Uid); Assert.Equal("Hello", results[0].Metadata["remarks"]); Assert.Equal("<p>This is unit test!</p>\n", results[0].Conceptual); File.Delete(fileName); }
public DfmJsonTokenTreeService(string baseDir, ImmutableDictionary <string, string> tokens, IMarkdownTokenTreeValidator tokenTreeValidator) { _builder = DocfxFlavoredMarked.CreateBuilder(baseDir); _builder.TokenTreeValidator = tokenTreeValidator; _tokens = tokens; }
public void TestFallback_Inclusion_random_name() { // -root_folder (this is also docset folder) // |- root.md // |- a_folder // | |- a.md // |- token_folder // | |- token1.md // -fallback_folder // |- token_folder // |- token2.md // 1. Prepare data var uniqueFolderName = Path.GetRandomFileName(); var root = $@"1markdown root.md main content start. [!include[a](a_folder_{uniqueFolderName}/a_{uniqueFolderName}.md ""This is a.md"")] markdown root.md main content end."; var a = $@"1markdown a.md main content start. [!include[token1](../token_folder_{uniqueFolderName}/token1_{uniqueFolderName}.md ""This is token1.md"")] [!include[token1](../token_folder_{uniqueFolderName}/token2_{uniqueFolderName}.md ""This is token2.md"")] markdown a.md main content end."; var token1 = $@"1markdown token1.md content start. [!include[token2](token2_{uniqueFolderName}.md ""This is token2.md"")] markdown token1.md content end."; var token2 = @"**1markdown token2.md main content**"; WriteToFile($"{uniqueFolderName}/root_folder_{uniqueFolderName}/root_{uniqueFolderName}.md", root); WriteToFile($"{uniqueFolderName}/root_folder_{uniqueFolderName}/a_folder_{uniqueFolderName}/a_{uniqueFolderName}.md", a); WriteToFile($"{uniqueFolderName}/root_folder_{uniqueFolderName}/token_folder_{uniqueFolderName}/token1_{uniqueFolderName}.md", token1); WriteToFile($"{uniqueFolderName}/fallback_folder_{uniqueFolderName}/token_folder_{uniqueFolderName}/token2_{uniqueFolderName}.md", token2); try { EnvironmentContext.SetBaseDirectory($"{uniqueFolderName}/root_folder_{uniqueFolderName}"); var fallbackFolders = new List <string> { { Path.Combine(Directory.GetCurrentDirectory(), $"{uniqueFolderName}/fallback_folder_{uniqueFolderName}") } }; var dependency = new HashSet <string>(); var marked = DocfxFlavoredMarked.Markup(Path.Combine(Directory.GetCurrentDirectory(), $"{uniqueFolderName}/root_folder_{uniqueFolderName}"), root, fallbackFolders, $"root_{uniqueFolderName}.md", dependency: dependency); Assert.Equal($@"<p>1markdown root.md main content start.</p> <p>1markdown a.md main content start.</p> <p>1markdown token1.md content start.</p> <p><strong>1markdown token2.md main content</strong></p> <p>markdown token1.md content end.</p> <p><strong>1markdown token2.md main content</strong></p> <p>markdown a.md main content end.</p> <p>markdown root.md main content end.</p> ".Replace("\r\n", "\n"), marked); Assert.Equal( new[] { $"../fallback_folder_{uniqueFolderName}/token_folder_{uniqueFolderName}/token2_{uniqueFolderName}.md", $"a_folder_{uniqueFolderName}/a_{uniqueFolderName}.md", $"token_folder_{uniqueFolderName}/token1_{uniqueFolderName}.md", $"token_folder_{uniqueFolderName}/token2_{uniqueFolderName}.md" }, dependency.OrderBy(x => x)); } finally { EnvironmentContext.Clean(); } }
public void TestReadMarkdownAsOverwrite() { var content = @"--- uid: Test remarks: Hello --- This is unit test!"; content = Regex.Replace(content, "\r?\n", "\r\n"); var html = DocfxFlavoredMarked.Markup(content); var baseDir = Directory.GetCurrentDirectory(); var fileName = "ut_ReadMarkdownAsOverwrite.md"; var fullPath = Path.Combine(baseDir, fileName); File.WriteAllText(fullPath, content); var host = new HostService(null, Enumerable.Empty <FileModel>()) { MarkdownService = new DfmServiceProvider().CreateMarkdownService(new MarkdownServiceParameters { BasePath = string.Empty }), SourceFiles = ImmutableDictionary.Create <string, FileAndType>() }; var ft = new FileAndType(baseDir, fileName, DocumentType.Overwrite); var results = MarkdownReader.ReadMarkdownAsOverwrite(host, ft).ToList(); Assert.NotNull(results); Assert.Equal(1, results.Count); Assert.Equal("Test", results[0].Uid); Assert.Equal("Hello", results[0].Metadata["remarks"]); Assert.Equal("<p sourcefile=\"ut_ReadMarkdownAsOverwrite.md\" sourcestartlinenumber=\"6\" sourceendlinenumber=\"6\">This is unit test!</p>\n", results[0].Conceptual); File.Delete(fileName); // Test conceptual content between two yamlheader content = @"--- uid: Test1 remarks: Hello --- This is unit test! --- uid: Test2 --- "; content = Regex.Replace(content, "\r?\n", "\r\n"); html = DocfxFlavoredMarked.Markup(content); File.WriteAllText(fileName, content); results = MarkdownReader.ReadMarkdownAsOverwrite(host, ft).ToList(); Assert.NotNull(results); Assert.Equal(2, results.Count); Assert.Equal("Test1", results[0].Uid); Assert.Equal("Test2", results[1].Uid); Assert.Equal("Hello", results[0].Metadata["remarks"]); Assert.Equal("<p sourcefile=\"ut_ReadMarkdownAsOverwrite.md\" sourcestartlinenumber=\"5\" sourceendlinenumber=\"5\">This is unit test!</p>\n", results[0].Conceptual); Assert.Equal(string.Empty, results[1].Conceptual); File.Delete(fileName); //invalid yamlheader is not supported content = @"--- uid: Test1 remarks: Hello --- This is unit test! --- uid: Test2 --- "; content = Regex.Replace(content, "\r?\n", "\r\n"); html = DocfxFlavoredMarked.Markup(content); File.WriteAllText(fileName, content); results = MarkdownReader.ReadMarkdownAsOverwrite(host, ft).ToList(); Assert.NotNull(results); Assert.Equal(1, results.Count); Assert.Equal("Test1", results[0].Uid); Assert.Equal("Hello", results[0].Metadata["remarks"]); Assert.Equal("<h2 id=\"this-is-unit-test\" sourcefile=\"ut_ReadMarkdownAsOverwrite.md\" sourcestartlinenumber=\"5\" sourceendlinenumber=\"6\">This is unit test!</h2>\n<h2 id=\"uid-test2\" sourcefile=\"ut_ReadMarkdownAsOverwrite.md\" sourcestartlinenumber=\"7\" sourceendlinenumber=\"8\">uid: Test2</h2>\n", results[0].Conceptual); File.Delete(fileName); // Test conceptual content with extra empty line between two yamlheader content = @"--- uid: Test1 remarks: Hello --- This is unit test! --- uid: Test2 --- "; content = Regex.Replace(content, "\r?\n", "\r\n"); html = DocfxFlavoredMarked.Markup(content); File.WriteAllText(fileName, content); results = MarkdownReader.ReadMarkdownAsOverwrite(host, ft).ToList(); Assert.NotNull(results); Assert.Equal(2, results.Count); Assert.Equal("Test1", results[0].Uid); Assert.Equal("Test2", results[1].Uid); Assert.Equal("Hello", results[0].Metadata["remarks"]); Assert.Equal("<p sourcefile=\"ut_ReadMarkdownAsOverwrite.md\" sourcestartlinenumber=\"7\" sourceendlinenumber=\"7\">This is unit test!</p>\n", results[0].Conceptual); Assert.Equal(string.Empty, results[1].Conceptual); File.Delete(fileName); // Test different line ending content = "---\nuid: Test\nremarks: Hello\n---\nThis is unit test!\n"; html = DocfxFlavoredMarked.Markup(content); File.WriteAllText(fileName, content); results = MarkdownReader.ReadMarkdownAsOverwrite(host, ft).ToList(); Assert.NotNull(results); Assert.Equal(1, results.Count); Assert.Equal("Test", results[0].Uid); Assert.Equal("Hello", results[0].Metadata["remarks"]); Assert.Equal("<p sourcefile=\"ut_ReadMarkdownAsOverwrite.md\" sourcestartlinenumber=\"5\" sourceendlinenumber=\"5\">This is unit test!</p>\n", results[0].Conceptual); File.Delete(fileName); // Test link to files and Uids in overwrite document content = @"--- uid: Test remarks: Hello --- @NotExistUid [Not exist link](link.md) This is unit test!"; content = Regex.Replace(content, "\r?\n", "\r\n"); html = DocfxFlavoredMarked.Markup(content); File.WriteAllText(fileName, content); results = MarkdownReader.ReadMarkdownAsOverwrite(host, ft).ToList(); Assert.NotNull(results); Assert.Equal(1, results.Count); Assert.Equal("Test", results[0].Uid); Assert.Equal("Hello", results[0].Metadata["remarks"]); Assert.Equal(1, results[0].LinkToFiles.Count); Assert.Equal("~/link.md", results[0].LinkToFiles.ElementAt(0)); Assert.Equal(1, results[0].LinkToUids.Count); Assert.Equal("NotExistUid", results[0].LinkToUids.ElementAt(0)); Assert.Equal(@"<p sourcefile=""ut_ReadMarkdownAsOverwrite.md"" sourcestartlinenumber=""5"" sourceendlinenumber=""5""><xref href=""NotExistUid"" data-throw-if-not-resolved=""False"" data-raw-source=""@NotExistUid"" sourcefile=""ut_ReadMarkdownAsOverwrite.md"" sourcestartlinenumber=""5"" sourceendlinenumber=""5""></xref></p> <p sourcefile=""ut_ReadMarkdownAsOverwrite.md"" sourcestartlinenumber=""7"" sourceendlinenumber=""7""><a href=""link.md"" data-raw-source=""[Not exist link](link.md)"" sourcefile=""ut_ReadMarkdownAsOverwrite.md"" sourcestartlinenumber=""7"" sourceendlinenumber=""7"">Not exist link</a></p> <p sourcefile=""ut_ReadMarkdownAsOverwrite.md"" sourcestartlinenumber=""9"" sourceendlinenumber=""9"">This is unit test!</p> ".Replace("\r\n", "\n"), results[0].Conceptual); File.Delete(fileName); }
public void Parse(string source, string expected) { Assert.Equal(expected, DocfxFlavoredMarked.Markup(source)); }