Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup and more support #2

Merged
merged 3 commits into from
Nov 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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