Skip to content

Commit

Permalink
Merge pull request #2 from Toine-db/cleanup_and_more_support
Browse files Browse the repository at this point in the history
Support code blocks, html blocks and reference definitions
  • Loading branch information
Toine-db authored Nov 2, 2024
2 parents 9109b18 + 74d7141 commit 69058ee
Show file tree
Hide file tree
Showing 12 changed files with 357 additions and 59 deletions.
31 changes: 31 additions & 0 deletions src/MarkdownParser/IViewSupplier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ namespace MarkdownParser
{
public interface IViewSupplier<T>
{
/// <summary>
/// get a textual line break
/// </summary>
/// <returns></returns>
string GetTextualLineBreak();

/// <summary>
/// a default text view
/// </summary>
Expand Down Expand Up @@ -72,5 +78,30 @@ public interface IViewSupplier<T>
/// <param name="placeholderName">placeholder string</param>
/// <returns></returns>
T GetPlaceholder(string placeholderName);

/// <summary>
/// a view that shows fenced code (found in MD blocks starting with ```cs )
/// </summary>
/// <returns></returns>
T GetFencedCodeBlock(string content, string codeInfo);

/// <summary>
/// a view that shows indented code (found in MD lines starting with at least 4 spaces)
/// </summary>
/// <returns></returns>
T GetIndentedCodeBlock(string content);

/// <summary>
/// a view that shows html content
/// </summary>
/// <returns></returns>
T GetHtmlBlock(string content);

/// <summary>
/// a view that shows reference definitions ([link]s usually at the end of the document)
/// </summary>
/// <param name="markdownReferenceDefinitions">collection of Reference Definitions</param>
/// <returns></returns>
T GetReferenceDefinitions(IEnumerable<MarkdownReferenceDefinition> markdownReferenceDefinitions);
}
}
30 changes: 0 additions & 30 deletions src/MarkdownParser/ListBulletFormatter.cs

This file was deleted.

6 changes: 6 additions & 0 deletions src/MarkdownParser/MarkdownParser.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,10 @@
<None Include="..\..\README.md" Pack="true" PackagePath="\"/>
</ItemGroup>

<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
<_Parameter1>MarkdownParser.Test</_Parameter1>
</AssemblyAttribute>
</ItemGroup>

</Project>
10 changes: 10 additions & 0 deletions src/MarkdownParser/MarkdownReferenceDefinition.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
}
17 changes: 10 additions & 7 deletions src/MarkdownParser/ViewFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ public ViewFormatter(IViewSupplier<T> viewSupplier)
public List<T> Format(Block markdownBlock)
{
WriteBlockToView(markdownBlock, _writer);
_writer.StartAndFinalizeReferenceDefinitions();

return _writer.Flush();
}

public List<T> FormatSingleBlock(Block markdownBlock)
{
WriteBlockToView(markdownBlock, _writer, false);

return _writer.Flush();
}

Expand All @@ -36,6 +39,7 @@ private void WriteBlockToView(Block block, ViewWriter<T> writer, bool continueWi
switch (block.Tag)
{
case BlockTag.Document:
_writer.RegisterReferenceDefinitions(block.Document.ReferenceMap);
WriteBlockToView(block.FirstChild, writer);
break;
case BlockTag.Paragraph:
Expand Down Expand Up @@ -69,17 +73,16 @@ private void WriteBlockToView(Block block, ViewWriter<T> 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
//writer.StartBlock(BlockTag.Paragraph, block.StringContent.ToString());
//WriteBlockToView(block.FirstChild, writer);
//writer.FinalizeParagraphBlock();
writer.StartAndFinalizeHtmlBlock(block.StringContent);
break;
case BlockTag.ReferenceDefinition:
// not supported
// ignore, handled at the end of document by _writer.StartAndFinalizeReferenceDefinitions()
break;
default:
throw new CommonMarkException("Block type " + block.Tag + " is not supported.", block);
Expand Down Expand Up @@ -114,7 +117,7 @@ private void WriteInlineToView(Inline inline, ViewWriter<T> writer)
break;
case InlineTag.SoftBreak:
case InlineTag.LineBreak:
writer.AddText(Environment.NewLine);
writer.AddText(writer.GetTextualLineBreak());
break;
case InlineTag.Placeholder:
writer.StartAndFinalizePlaceholderBlock(inline.TargetUrl);
Expand Down
123 changes: 101 additions & 22 deletions src/MarkdownParser/ViewWriter.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using CommonMark.Syntax;

Expand All @@ -10,8 +10,14 @@ public class ViewWriter<T>
{
private IViewSupplier<T> ViewSupplier { get; }
private List<T> WrittenViews { get; set; } = new List<T>();

private Stack<ViewWriterCache<T>> Workbench { get; } = new Stack<ViewWriterCache<T>>();
private Dictionary<string, Reference> _referenceDefinitions;

public ViewWriter(IViewSupplier<T> viewSupplier)
{
ViewSupplier = viewSupplier;
}

private ViewWriterCache<T> GetWorkbenchItem()
{
if (Workbench.Count == 0)
Expand All @@ -22,11 +28,6 @@ private ViewWriterCache<T> GetWorkbenchItem()
return Workbench.Peek();
}

public ViewWriter(IViewSupplier<T> viewSupplier)
{
ViewSupplier = viewSupplier;
}

public List<T> Flush()
{
var collectedViews = WrittenViews;
Expand All @@ -35,6 +36,11 @@ public List<T> Flush()
return collectedViews;
}

public void RegisterReferenceDefinitions(Dictionary<string, Reference> referenceDefinitions)
{
_referenceDefinitions = referenceDefinitions;
}

public void StartBlock(BlockTag blockType, string content = "")
{
Workbench.Push(new ViewWriterCache<T> { ComponentType = blockType });
Expand All @@ -57,8 +63,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)
{
Expand Down Expand Up @@ -94,7 +101,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;
Expand All @@ -107,8 +113,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);
}
Expand Down Expand Up @@ -155,18 +162,19 @@ 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)
{
views.Add(view);
}
}

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);
}
Expand All @@ -182,10 +190,62 @@ public void StartAndFinalizeImageBlock(string targetUrl, string subscription, st
StoreView(imageView);
}

public void StartAndFinalizeFencedCodeBlock(StringContent content, string blockInfo)
{
var parsedContent = StringContentToStringWithLineBreaks(content);

var blockView = ViewSupplier.GetFencedCodeBlock(parsedContent, blockInfo);
StoreView(blockView);
}

public void StartAndFinalizeIndentedCodeBlock(StringContent content)
{
var parsedContent = StringContentToStringWithLineBreaks(content);

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 StartAndFinalizeReferenceDefinitions()
{
if (_referenceDefinitions == null || _referenceDefinitions.Count == 0)
{
return;
}

var markdownReferenceDefinition = new List<MarkdownReferenceDefinition>();
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 seperator = ViewSupplier.GetThematicBreak();
StoreView(seperator);
var separator = ViewSupplier.GetThematicBreak();
StoreView(separator);
}

public void StartAndFinalizePlaceholderBlock(string placeholderName)
Expand All @@ -194,16 +254,23 @@ public void StartAndFinalizePlaceholderBlock(string placeholderName)
StoreView(placeholderView);
}

public string GetTextualLineBreak()
{
return ViewSupplier.GetTextualLineBreak();
}

private T StackViews(List<T> 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;
}
Expand All @@ -226,6 +293,18 @@ private void StoreView(T view)
WrittenViews.Add(view);
}
}

private string StringContentToStringWithLineBreaks(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;
}
}
}
6 changes: 6 additions & 0 deletions test/MarkdownParser.Test/MarkdownParser.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,26 @@
<None Remove="Resources\Examples\Combined\basic-example.md" />
<None Remove="Resources\Examples\Combined\full-example.md" />
<None Remove="Resources\Examples\Combined\minimal-example.md" />
<None Remove="Resources\Examples\Sections\codeblocks.md" />
<None Remove="Resources\Examples\Sections\headers.md" />
<None Remove="Resources\Examples\Sections\htmlblocks.md" />
<None Remove="Resources\Examples\Sections\list.md" />
<None Remove="Resources\Examples\Sections\nestedlist.md" />
<None Remove="Resources\Examples\Sections\paragraphs.md" />
<None Remove="Resources\Examples\Sections\referencedefinitions.md" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="Resources\Examples\Combined\basic-example.md" />
<EmbeddedResource Include="Resources\Examples\Combined\full-example.md" />
<EmbeddedResource Include="Resources\Examples\Combined\minimal-example.md" />
<EmbeddedResource Include="Resources\Examples\Sections\codeblocks.md" />
<EmbeddedResource Include="Resources\Examples\Sections\headers.md" />
<EmbeddedResource Include="Resources\Examples\Sections\htmlblocks.md" />
<EmbeddedResource Include="Resources\Examples\Sections\list.md" />
<EmbeddedResource Include="Resources\Examples\Sections\nestedlist.md" />
<EmbeddedResource Include="Resources\Examples\Sections\paragraphs.md" />
<EmbeddedResource Include="Resources\Examples\Sections\referencedefinitions.md" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading

0 comments on commit 69058ee

Please sign in to comment.