From 5b6f1db2838ea0c14545e81b80a7096d82ae2985 Mon Sep 17 00:00:00 2001
From: Toinedb
Date: Fri, 1 Nov 2024 18:08:29 +0100
Subject: [PATCH 1/3] code block options
---
src/MarkdownParser/IViewSupplier.cs | 18 ++++
src/MarkdownParser/ListBulletFormatter.cs | 30 -------
src/MarkdownParser/MarkdownParser.csproj | 6 ++
src/MarkdownParser/ViewFormatter.cs | 13 ++-
src/MarkdownParser/ViewWriter.cs | 82 ++++++++++++++-----
.../MarkdownParser.Test.csproj | 6 ++
.../MarkdownParserSectionsSpecs.cs | 33 ++++++++
.../Mocks/StringComponentSupplier.cs | 15 ++++
.../Resources/Examples/Sections/codeblocks.md | 8 ++
9 files changed, 155 insertions(+), 56 deletions(-)
delete mode 100644 src/MarkdownParser/ListBulletFormatter.cs
create mode 100644 test/MarkdownParser.Test/Resources/Examples/Sections/codeblocks.md
diff --git a/src/MarkdownParser/IViewSupplier.cs b/src/MarkdownParser/IViewSupplier.cs
index 2c7e231..1eff70f 100644
--- a/src/MarkdownParser/IViewSupplier.cs
+++ b/src/MarkdownParser/IViewSupplier.cs
@@ -72,5 +72,23 @@ public interface IViewSupplier
/// placeholder string
///
T GetPlaceholder(string placeholderName);
+
+ ///
+ /// a view that shows fenced code found in MD blocks starting with ```cs
+ ///
+ ///
+ T GetFencedCodeBlock(string content, string codeInfo);
+
+ ///
+ /// a view that shows indented code found in MD lines starting with at least 4 spaces
+ ///
+ ///
+ T GetIndentedCodeBlock(string content);
+
+ ///
+ /// get a textual line break
+ ///
+ ///
+ string GetTextualLineBreak();
}
}
diff --git a/src/MarkdownParser/ListBulletFormatter.cs b/src/MarkdownParser/ListBulletFormatter.cs
deleted file mode 100644
index 6a96d6a..0000000
--- a/src/MarkdownParser/ListBulletFormatter.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System;
-using System.Globalization;
-
-namespace MarkdownParser
-{
- public static class ListBulletFormatter
- {
- public static string GetListItemBullet(bool isOrderedList, int sequenceNumber, int listLevel, string listItemBulletOddCharacter, string listItemBulletEvenCharacter)
- {
- // 'listlevel' even or odd (list start at level 1 == odd)
- var isListOddLeveled = (listLevel % 2) != 0;
-
- if (!isOrderedList)
- {
- return (isListOddLeveled)
- ? listItemBulletOddCharacter
- : listItemBulletEvenCharacter;
- }
-
- const int aCharacterPosition = 97; // character 'a' position in ASCI table
- var sequenceNumberCharacterPosition = -1 + aCharacterPosition + sequenceNumber;
-
- var bullet = (isListOddLeveled)
- ? sequenceNumber.ToString()
- : Convert.ToChar(sequenceNumberCharacterPosition, CultureInfo.InvariantCulture).ToString();
-
- return $"{bullet}.";
- }
- }
-}
diff --git a/src/MarkdownParser/MarkdownParser.csproj b/src/MarkdownParser/MarkdownParser.csproj
index dc60480..5e485e8 100644
--- a/src/MarkdownParser/MarkdownParser.csproj
+++ b/src/MarkdownParser/MarkdownParser.csproj
@@ -49,4 +49,10 @@
+
+
+ <_Parameter1>MarkdownParser.Test
+
+
+
diff --git a/src/MarkdownParser/ViewFormatter.cs b/src/MarkdownParser/ViewFormatter.cs
index af12363..11ae746 100644
--- a/src/MarkdownParser/ViewFormatter.cs
+++ b/src/MarkdownParser/ViewFormatter.cs
@@ -69,17 +69,22 @@ private void WriteBlockToView(Block block, ViewWriter writer, bool continueWi
writer.StartAndFinalizeThematicBreak();
break;
case BlockTag.FencedCode:
+ writer.StartAndFinalizeFencedCodeBlock(block.StringContent, block.FencedCodeData.Info);
+ break;
case BlockTag.IndentedCode:
- // not supported
+ writer.StartAndFinalizeIndentedCodeBlock(block.StringContent);
break;
case BlockTag.HtmlBlock:
- // TODO.....if needed
+ // TODO
+ var currentBlock3 = block;
+ break;
//writer.StartBlock(BlockTag.Paragraph, block.StringContent.ToString());
//WriteBlockToView(block.FirstChild, writer);
//writer.FinalizeParagraphBlock();
break;
case BlockTag.ReferenceDefinition:
- // not supported
+ // TODO
+ var currentBlock4 = block;
break;
default:
throw new CommonMarkException("Block type " + block.Tag + " is not supported.", block);
@@ -114,7 +119,7 @@ private void WriteInlineToView(Inline inline, ViewWriter writer)
break;
case InlineTag.SoftBreak:
case InlineTag.LineBreak:
- writer.AddText(Environment.NewLine);
+ writer.AddText(writer.GetTextualLineBreak());
break;
case InlineTag.Placeholder:
writer.StartAndFinalizePlaceholderBlock(inline.TargetUrl);
diff --git a/src/MarkdownParser/ViewWriter.cs b/src/MarkdownParser/ViewWriter.cs
index 6eb147d..2f3d6a4 100644
--- a/src/MarkdownParser/ViewWriter.cs
+++ b/src/MarkdownParser/ViewWriter.cs
@@ -1,7 +1,8 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Diagnostics;
+using System.IO;
using System.Linq;
+using System.Text;
using CommonMark.Syntax;
namespace MarkdownParser
@@ -10,8 +11,13 @@ public class ViewWriter
{
private IViewSupplier ViewSupplier { get; }
private List WrittenViews { get; set; } = new List();
-
private Stack> Workbench { get; } = new Stack>();
+
+ public ViewWriter(IViewSupplier viewSupplier)
+ {
+ ViewSupplier = viewSupplier;
+ }
+
private ViewWriterCache GetWorkbenchItem()
{
if (Workbench.Count == 0)
@@ -22,11 +28,6 @@ private ViewWriterCache GetWorkbenchItem()
return Workbench.Peek();
}
- public ViewWriter(IViewSupplier viewSupplier)
- {
- ViewSupplier = viewSupplier;
- }
-
public List Flush()
{
var collectedViews = WrittenViews;
@@ -57,8 +58,9 @@ public void FinalizeParagraphBlock()
foreach (var itemsCacheTuple in itemsCache)
{
- var view = !string.IsNullOrEmpty(itemsCacheTuple.Item1) ?
- ViewSupplier.GetTextView(itemsCacheTuple.Item1) : itemsCacheTuple.Item2;
+ var view = !string.IsNullOrEmpty(itemsCacheTuple.Item1)
+ ? ViewSupplier.GetTextView(itemsCacheTuple.Item1)
+ : itemsCacheTuple.Item2;
if (view != null)
{
@@ -94,7 +96,6 @@ public void FinalizeHeaderBlock(int headerLevel)
var wbi = GetWorkbenchItem();
if (wbi.ComponentType != BlockTag.AtxHeading
&& wbi.ComponentType != BlockTag.SetextHeading)
-
{
Debug.WriteLine($"Finalizing Header can not finalize {wbi.ComponentType}");
return;
@@ -107,8 +108,9 @@ public void FinalizeHeaderBlock(int headerLevel)
foreach (var itemsCacheTuple in itemsCache)
{
- var view = !string.IsNullOrEmpty(itemsCacheTuple.Item1) ?
- ViewSupplier.GetHeaderView(itemsCacheTuple.Item1, headerLevel) : itemsCacheTuple.Item2;
+ var view = !string.IsNullOrEmpty(itemsCacheTuple.Item1)
+ ? ViewSupplier.GetHeaderView(itemsCacheTuple.Item1, headerLevel)
+ : itemsCacheTuple.Item2;
views.Add(view);
}
@@ -155,8 +157,9 @@ public void FinalizeListItemBlock(ListData listData)
foreach (var itemsCacheTuple in itemsCache)
{
- var view = !string.IsNullOrEmpty(itemsCacheTuple.Item1) ?
- ViewSupplier.GetTextView(itemsCacheTuple.Item1) : itemsCacheTuple.Item2;
+ var view = !string.IsNullOrEmpty(itemsCacheTuple.Item1)
+ ? ViewSupplier.GetTextView(itemsCacheTuple.Item1)
+ : itemsCacheTuple.Item2;
if (view != null)
{
@@ -164,9 +167,9 @@ public void FinalizeListItemBlock(ListData listData)
}
}
- var flattendView = StackViews(views);
+ var flattenedView = StackViews(views);
- var listItemView = ViewSupplier.GetListItemView(flattendView, isOrderedList, sequenceNumber, depthLevel);
+ var listItemView = ViewSupplier.GetListItemView(flattenedView, isOrderedList, sequenceNumber, depthLevel);
StoreView(listItemView);
}
@@ -182,10 +185,26 @@ public void StartAndFinalizeImageBlock(string targetUrl, string subscription, st
StoreView(imageView);
}
+ public void StartAndFinalizeFencedCodeBlock(StringContent content, string blockInfo)
+ {
+ var parsedContent = ParseStringContentToString(content);
+
+ var codeBlock = ViewSupplier.GetFencedCodeBlock(parsedContent, blockInfo);
+ StoreView(codeBlock);
+ }
+
+ public void StartAndFinalizeIndentedCodeBlock(StringContent content)
+ {
+ var parsedContent = ParseStringContentToString(content);
+
+ var codeBlock = ViewSupplier.GetIndentedCodeBlock(parsedContent);
+ StoreView(codeBlock);
+ }
+
public void StartAndFinalizeThematicBreak()
{
- var seperator = ViewSupplier.GetThematicBreak();
- StoreView(seperator);
+ var separator = ViewSupplier.GetThematicBreak();
+ StoreView(separator);
}
public void StartAndFinalizePlaceholderBlock(string placeholderName)
@@ -194,16 +213,23 @@ public void StartAndFinalizePlaceholderBlock(string placeholderName)
StoreView(placeholderView);
}
+ public string GetTextualLineBreak()
+ {
+ return ViewSupplier.GetTextualLineBreak();
+ }
+
private T StackViews(List views)
{
- if (views == null || views.Count == 0)
+ if (views == null
+ || views.Count == 0)
{
return default(T);
}
// multiple views combine a single stack layout
- var viewToStore = views.Count == 1 ?
- views[0] : ViewSupplier.GetStackLayoutView(views);
+ var viewToStore = views.Count == 1
+ ? views[0]
+ : ViewSupplier.GetStackLayoutView(views);
return viewToStore;
}
@@ -226,6 +252,18 @@ private void StoreView(T view)
WrittenViews.Add(view);
}
}
+
+ private string ParseStringContentToString(StringContent content)
+ {
+ var stringWriter = new StringWriter();
+ content.WriteTo(stringWriter);
+ var contentLines = stringWriter.ToString();
+
+ contentLines = contentLines.Replace("\r", "");
+ contentLines = contentLines.TrimEnd('\n');
+ contentLines = contentLines.Replace("\n", GetTextualLineBreak());
+ return contentLines;
+ }
}
}
diff --git a/test/MarkdownParser.Test/MarkdownParser.Test.csproj b/test/MarkdownParser.Test/MarkdownParser.Test.csproj
index f93842d..9637277 100644
--- a/test/MarkdownParser.Test/MarkdownParser.Test.csproj
+++ b/test/MarkdownParser.Test/MarkdownParser.Test.csproj
@@ -13,20 +13,26 @@
+
+
+
+
+
+
diff --git a/test/MarkdownParser.Test/MarkdownParserSectionsSpecs.cs b/test/MarkdownParser.Test/MarkdownParserSectionsSpecs.cs
index 5617526..d66bdc5 100644
--- a/test/MarkdownParser.Test/MarkdownParserSectionsSpecs.cs
+++ b/test/MarkdownParser.Test/MarkdownParserSectionsSpecs.cs
@@ -98,4 +98,37 @@ public void When_parsing_nested_list_it_should_output_nesting_by_level()
splittedViews[12].Should().Be("_False.2.1_textview");
splittedViews[13].Should().Be("item2-3(mockComponentSupplier);
+
+ //-----------------------------------------------------------------------------------------------------------
+ // Act
+ //-----------------------------------------------------------------------------------------------------------
+ var parseResult = parser.Parse(markdown);
+
+ //-----------------------------------------------------------------------------------------------------------
+ // Assert
+ //-----------------------------------------------------------------------------------------------------------
+ parseResult.Count.Should().Be(2);
+
+ var view0Parts = parseResult[0].Split('|');
+ view0Parts[0].Should().Be("fencedcodeview>");
+ view0Parts[1].Should().Be("(cs)");
+ view0Parts[2].Should().Be("var myNumber = 1;\r\nmyNumber++;");
+ view0Parts[3].Should().Be("");
+ view1Parts[1].Should().Be("the first line for IndentedCode code block\r\nthe second line for IndentedCode code block\r\nthe third line for IndentedCode code block");
+ view1Parts[2].Should().Be("|({codeInfo})|{content}||{content}|
Date: Sat, 2 Nov 2024 14:26:33 +0100
Subject: [PATCH 2/3] html support
---
src/MarkdownParser/IViewSupplier.cs | 14 +++-
src/MarkdownParser/ViewFormatter.cs | 7 +-
src/MarkdownParser/ViewWriter.cs | 23 ++++--
.../MarkdownParserSectionsSpecs.cs | 75 ++++++++++++++++---
.../Mocks/StringComponentSupplier.cs | 5 ++
.../Resources/Examples/Sections/htmlblocks.md | 14 ++++
6 files changed, 110 insertions(+), 28 deletions(-)
create mode 100644 test/MarkdownParser.Test/Resources/Examples/Sections/htmlblocks.md
diff --git a/src/MarkdownParser/IViewSupplier.cs b/src/MarkdownParser/IViewSupplier.cs
index 1eff70f..c68b5c9 100644
--- a/src/MarkdownParser/IViewSupplier.cs
+++ b/src/MarkdownParser/IViewSupplier.cs
@@ -4,6 +4,12 @@ namespace MarkdownParser
{
public interface IViewSupplier
{
+ ///
+ /// get a textual line break
+ ///
+ ///
+ string GetTextualLineBreak();
+
///
/// a default text view
///
@@ -74,21 +80,21 @@ public interface IViewSupplier
T GetPlaceholder(string placeholderName);
///
- /// a view that shows fenced code found in MD blocks starting with ```cs
+ /// a view that shows fenced code (found in MD blocks starting with ```cs )
///
///
T GetFencedCodeBlock(string content, string codeInfo);
///
- /// a view that shows indented code found in MD lines starting with at least 4 spaces
+ /// a view that shows indented code (found in MD lines starting with at least 4 spaces)
///
///
T GetIndentedCodeBlock(string content);
///
- /// get a textual line break
+ /// a view that shows html content
///
///
- string GetTextualLineBreak();
+ T GetHtmlBlock(string content);
}
}
diff --git a/src/MarkdownParser/ViewFormatter.cs b/src/MarkdownParser/ViewFormatter.cs
index 11ae746..a1d67d4 100644
--- a/src/MarkdownParser/ViewFormatter.cs
+++ b/src/MarkdownParser/ViewFormatter.cs
@@ -75,12 +75,7 @@ private void WriteBlockToView(Block block, ViewWriter writer, bool continueWi
writer.StartAndFinalizeIndentedCodeBlock(block.StringContent);
break;
case BlockTag.HtmlBlock:
- // TODO
- var currentBlock3 = block;
- break;
- //writer.StartBlock(BlockTag.Paragraph, block.StringContent.ToString());
- //WriteBlockToView(block.FirstChild, writer);
- //writer.FinalizeParagraphBlock();
+ writer.StartAndFinalizeHtmlBlock(block.StringContent);
break;
case BlockTag.ReferenceDefinition:
// TODO
diff --git a/src/MarkdownParser/ViewWriter.cs b/src/MarkdownParser/ViewWriter.cs
index 2f3d6a4..78134f2 100644
--- a/src/MarkdownParser/ViewWriter.cs
+++ b/src/MarkdownParser/ViewWriter.cs
@@ -2,7 +2,6 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
-using System.Text;
using CommonMark.Syntax;
namespace MarkdownParser
@@ -187,18 +186,26 @@ public void StartAndFinalizeImageBlock(string targetUrl, string subscription, st
public void StartAndFinalizeFencedCodeBlock(StringContent content, string blockInfo)
{
- var parsedContent = ParseStringContentToString(content);
+ var parsedContent = StringContentToStringWithLineBreaks(content);
- var codeBlock = ViewSupplier.GetFencedCodeBlock(parsedContent, blockInfo);
- StoreView(codeBlock);
+ var blockView = ViewSupplier.GetFencedCodeBlock(parsedContent, blockInfo);
+ StoreView(blockView);
}
public void StartAndFinalizeIndentedCodeBlock(StringContent content)
{
- var parsedContent = ParseStringContentToString(content);
+ var parsedContent = StringContentToStringWithLineBreaks(content);
- var codeBlock = ViewSupplier.GetIndentedCodeBlock(parsedContent);
- StoreView(codeBlock);
+ var blockView = ViewSupplier.GetIndentedCodeBlock(parsedContent);
+ StoreView(blockView);
+ }
+
+ public void StartAndFinalizeHtmlBlock(StringContent content)
+ {
+ var parsedContent = StringContentToStringWithLineBreaks(content);
+
+ var blockView = ViewSupplier.GetHtmlBlock(parsedContent);
+ StoreView(blockView);
}
public void StartAndFinalizeThematicBreak()
@@ -253,7 +260,7 @@ private void StoreView(T view)
}
}
- private string ParseStringContentToString(StringContent content)
+ private string StringContentToStringWithLineBreaks(StringContent content)
{
var stringWriter = new StringWriter();
content.WriteTo(stringWriter);
diff --git a/test/MarkdownParser.Test/MarkdownParserSectionsSpecs.cs b/test/MarkdownParser.Test/MarkdownParserSectionsSpecs.cs
index d66bdc5..a9022e4 100644
--- a/test/MarkdownParser.Test/MarkdownParserSectionsSpecs.cs
+++ b/test/MarkdownParser.Test/MarkdownParserSectionsSpecs.cs
@@ -120,15 +120,70 @@ public void When_parsing_codeblocks_it_should_output_code_views()
//-----------------------------------------------------------------------------------------------------------
parseResult.Count.Should().Be(2);
- var view0Parts = parseResult[0].Split('|');
- view0Parts[0].Should().Be("fencedcodeview>");
- view0Parts[1].Should().Be("(cs)");
- view0Parts[2].Should().Be("var myNumber = 1;\r\nmyNumber++;");
- view0Parts[3].Should().Be("");
- view1Parts[1].Should().Be("the first line for IndentedCode code block\r\nthe second line for IndentedCode code block\r\nthe third line for IndentedCode code block");
- view1Parts[2].Should().Be("");
+ codeViewComponentsGroup0[1].Should().Be("(cs)");
+ codeViewComponentsGroup0[2].Should().Be("var myNumber = 1;\r\nmyNumber++;");
+ codeViewComponentsGroup0[3].Should().Be("");
+ codeViewComponentsGroup1[1].Should().Be("the first line for IndentedCode code block\r\nthe second line for IndentedCode code block\r\nthe third line for IndentedCode code block");
+ codeViewComponentsGroup1[2].Should().Be("(mockComponentSupplier);
+
+ var newLineIndicator = mockComponentSupplier.GetTextualLineBreak();
+
+ //-----------------------------------------------------------------------------------------------------------
+ // Act
+ //-----------------------------------------------------------------------------------------------------------
+ var parseResult = parser.Parse(markdown);
+
+ //-----------------------------------------------------------------------------------------------------------
+ // Assert
+ //-----------------------------------------------------------------------------------------------------------
+ parseResult.Count.Should().Be(2);
+
+ var htmlViewComponentsGroup0 = parseResult[0].Split('|');
+ htmlViewComponentsGroup0.Length.Should().Be(3);
+ htmlViewComponentsGroup0.First().Should().Be("htmlview>");
+ htmlViewComponentsGroup0.Last().Should().Be("First text in block
");
+ firstHtmlViewContentGroup[1].Trim().Should().Be("");
+ firstHtmlViewContentGroup[2].Trim().Should().Be("
Header
");
+ firstHtmlViewContentGroup[3].Trim().Should().Be("
Same block but nested element
");
+ firstHtmlViewContentGroup[4].Trim().Should().Be("
");
+
+ var htmlViewComponentsGroup1 = parseResult[1].Split('|');
+ htmlViewComponentsGroup1.Length.Should().Be(3);
+ htmlViewComponentsGroup1.First().Should().Be("htmlview>");
+ htmlViewComponentsGroup1.Last().Should().Be("");
+ secondHtmlViewContentGroup[1].Trim().Should().Be("");
+ secondHtmlViewContentGroup[6].Trim().Should().Be("Lorem Ipsum...
");
+ secondHtmlViewContentGroup[7].Trim().Should().Be("");
}
}
diff --git a/test/MarkdownParser.Test/Mocks/StringComponentSupplier.cs b/test/MarkdownParser.Test/Mocks/StringComponentSupplier.cs
index 41dad75..254fb8c 100644
--- a/test/MarkdownParser.Test/Mocks/StringComponentSupplier.cs
+++ b/test/MarkdownParser.Test/Mocks/StringComponentSupplier.cs
@@ -62,6 +62,11 @@ public string GetIndentedCodeBlock(string content)
return $"indentedview>|{content}||{content}|First text in block
+
+
Header
+
Same block but nested element
+
+
+
+
+ Lorem Ipsum...
+
\ No newline at end of file
From 74d714140e730673df6babe112a98b3ddfcb27b5 Mon Sep 17 00:00:00 2001
From: Toinedb
Date: Sat, 2 Nov 2024 16:36:03 +0100
Subject: [PATCH 3/3] suport reference definitions
---
src/MarkdownParser/IViewSupplier.cs | 7 ++++
.../MarkdownReferenceDefinition.cs | 10 +++++
src/MarkdownParser/ViewFormatter.cs | 7 +++-
src/MarkdownParser/ViewWriter.cs | 34 ++++++++++++++++
.../MarkdownParserSectionsSpecs.cs | 40 +++++++++++++++++++
.../Mocks/StringComponentSupplier.cs | 16 ++++++++
.../Examples/Sections/referencedefinitions.md | 7 ++++
7 files changed, 119 insertions(+), 2 deletions(-)
create mode 100644 src/MarkdownParser/MarkdownReferenceDefinition.cs
create mode 100644 test/MarkdownParser.Test/Resources/Examples/Sections/referencedefinitions.md
diff --git a/src/MarkdownParser/IViewSupplier.cs b/src/MarkdownParser/IViewSupplier.cs
index c68b5c9..522bb28 100644
--- a/src/MarkdownParser/IViewSupplier.cs
+++ b/src/MarkdownParser/IViewSupplier.cs
@@ -96,5 +96,12 @@ public interface IViewSupplier
///
///
T GetHtmlBlock(string content);
+
+ ///
+ /// a view that shows reference definitions ([link]s usually at the end of the document)
+ ///
+ /// collection of Reference Definitions
+ ///
+ T GetReferenceDefinitions(IEnumerable markdownReferenceDefinitions);
}
}
diff --git a/src/MarkdownParser/MarkdownReferenceDefinition.cs b/src/MarkdownParser/MarkdownReferenceDefinition.cs
new file mode 100644
index 0000000..5ab3892
--- /dev/null
+++ b/src/MarkdownParser/MarkdownReferenceDefinition.cs
@@ -0,0 +1,10 @@
+namespace MarkdownParser
+{
+ public class MarkdownReferenceDefinition
+ {
+ public string Label { get; set; }
+ public string Url { get; set; }
+ public string Title { get; set; }
+ public bool IsPlaceholder { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/MarkdownParser/ViewFormatter.cs b/src/MarkdownParser/ViewFormatter.cs
index a1d67d4..851e480 100644
--- a/src/MarkdownParser/ViewFormatter.cs
+++ b/src/MarkdownParser/ViewFormatter.cs
@@ -17,12 +17,15 @@ public ViewFormatter(IViewSupplier viewSupplier)
public List Format(Block markdownBlock)
{
WriteBlockToView(markdownBlock, _writer);
+ _writer.StartAndFinalizeReferenceDefinitions();
+
return _writer.Flush();
}
public List FormatSingleBlock(Block markdownBlock)
{
WriteBlockToView(markdownBlock, _writer, false);
+
return _writer.Flush();
}
@@ -36,6 +39,7 @@ private void WriteBlockToView(Block block, ViewWriter writer, bool continueWi
switch (block.Tag)
{
case BlockTag.Document:
+ _writer.RegisterReferenceDefinitions(block.Document.ReferenceMap);
WriteBlockToView(block.FirstChild, writer);
break;
case BlockTag.Paragraph:
@@ -78,8 +82,7 @@ private void WriteBlockToView(Block block, ViewWriter writer, bool continueWi
writer.StartAndFinalizeHtmlBlock(block.StringContent);
break;
case BlockTag.ReferenceDefinition:
- // TODO
- var currentBlock4 = block;
+ // ignore, handled at the end of document by _writer.StartAndFinalizeReferenceDefinitions()
break;
default:
throw new CommonMarkException("Block type " + block.Tag + " is not supported.", block);
diff --git a/src/MarkdownParser/ViewWriter.cs b/src/MarkdownParser/ViewWriter.cs
index 78134f2..2578803 100644
--- a/src/MarkdownParser/ViewWriter.cs
+++ b/src/MarkdownParser/ViewWriter.cs
@@ -11,6 +11,7 @@ public class ViewWriter
private IViewSupplier ViewSupplier { get; }
private List WrittenViews { get; set; } = new List();
private Stack> Workbench { get; } = new Stack>();
+ private Dictionary _referenceDefinitions;
public ViewWriter(IViewSupplier viewSupplier)
{
@@ -35,6 +36,11 @@ public List Flush()
return collectedViews;
}
+ public void RegisterReferenceDefinitions(Dictionary referenceDefinitions)
+ {
+ _referenceDefinitions = referenceDefinitions;
+ }
+
public void StartBlock(BlockTag blockType, string content = "")
{
Workbench.Push(new ViewWriterCache { ComponentType = blockType });
@@ -208,6 +214,34 @@ public void StartAndFinalizeHtmlBlock(StringContent content)
StoreView(blockView);
}
+ public void StartAndFinalizeReferenceDefinitions()
+ {
+ if (_referenceDefinitions == null || _referenceDefinitions.Count == 0)
+ {
+ return;
+ }
+
+ var markdownReferenceDefinition = new List();
+ foreach (var referenceDefinition in _referenceDefinitions)
+ {
+ if (referenceDefinition.Value == null)
+ {
+ continue;
+ }
+
+ markdownReferenceDefinition.Add(new MarkdownReferenceDefinition()
+ {
+ IsPlaceholder = referenceDefinition.Value.IsPlaceholder,
+ Label = referenceDefinition.Value.Label,
+ Title = referenceDefinition.Value.Title,
+ Url = referenceDefinition.Value.Url
+ });
+ }
+
+ var view = ViewSupplier.GetReferenceDefinitions(markdownReferenceDefinition);
+ StoreView(view);
+ }
+
public void StartAndFinalizeThematicBreak()
{
var separator = ViewSupplier.GetThematicBreak();
diff --git a/test/MarkdownParser.Test/MarkdownParserSectionsSpecs.cs b/test/MarkdownParser.Test/MarkdownParserSectionsSpecs.cs
index a9022e4..8500dba 100644
--- a/test/MarkdownParser.Test/MarkdownParserSectionsSpecs.cs
+++ b/test/MarkdownParser.Test/MarkdownParserSectionsSpecs.cs
@@ -186,4 +186,44 @@ public void When_parsing_htmlblocks_it_should_output_html_views()
secondHtmlViewContentGroup[6].Trim().Should().Be("Lorem Ipsum...
");
secondHtmlViewContentGroup[7].Trim().Should().Be("");
}
+
+ [TestMethod]
+ public void When_parsing_reference_definitions_it_should_output_specific_views()
+ {
+ //-----------------------------------------------------------------------------------------------------------
+ // Arrange
+ //-----------------------------------------------------------------------------------------------------------
+ var markdown = FileReader.ReadFile("Sections.referencedefinitions.md");
+
+ var mockComponentSupplier = new StringComponentSupplier();
+ var parser = new MarkdownParser(mockComponentSupplier);
+
+ //-----------------------------------------------------------------------------------------------------------
+ // Act
+ //-----------------------------------------------------------------------------------------------------------
+ var parseResult = parser.Parse(markdown);
+
+ //-----------------------------------------------------------------------------------------------------------
+ // Assert
+ //-----------------------------------------------------------------------------------------------------------
+ parseResult.Count.Should().Be(2);
+ parseResult[0].Should().StartWith("stackview>:+textview");
+
+ var referenceDefinitionsViewGroup = parseResult[1].Split('|');
+ referenceDefinitionsViewGroup.Length.Should().Be(4);
+ referenceDefinitionsViewGroup.First().Should().Be("referencedefinitions>");
+ referenceDefinitionsViewGroup.Last().Should().Be("|{content}| markdownReferenceDefinitions)
+ {
+ var content = "referencedefinitions>";
+ foreach (var markdownReferenceDefinition in markdownReferenceDefinitions)
+ {
+ content += $"|{markdownReferenceDefinition.IsPlaceholder}";
+ content += $"*{markdownReferenceDefinition.Label}";
+ content += $"*{markdownReferenceDefinition.Title}";
+ content += $"*{markdownReferenceDefinition.Url}";
+ }
+
+ content += "|