Skip to content

Commit bf52da6

Browse files
authored
Merge pull request #10 from Toine-db/placeholders_inline
Placeholder moved to inline textblocks
2 parents fa3b914 + 9d6d74d commit bf52da6

17 files changed

Lines changed: 140 additions & 62 deletions

src/MarkdownParser/IViewSupplier.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,6 @@ public interface IViewSupplier<T>
7373
/// <returns></returns>
7474
T CreateThematicBreak();
7575

76-
/// <summary>
77-
/// a placeholder for views or other objects
78-
/// </summary>
79-
/// <param name="placeholderName">placeholder string</param>
80-
/// <returns></returns>
81-
T CreatePlaceholder(string placeholderName);
82-
8376
/// <summary>
8477
/// a view that shows fenced code (found in MD blocks starting with ```cs )
8578
/// </summary>

src/MarkdownParser/Models/Segments/Indicators/SegmentIndicator.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public enum SegmentIndicator
88
Strikethrough,
99
Code,
1010
Link,
11-
LineBreak
11+
LineBreak,
12+
Placeholder
1213
}
1314
}

src/MarkdownParser/Models/Segments/LinkSegment.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ public class LinkSegment : IndicatorSegment
77
public string Url { get; }
88
public string Title { get; }
99

10-
public LinkSegment(SegmentIndicator indicator, SegmentIndicatorPosition indicatorPosition, string url, string title)
11-
: base(indicator, indicatorPosition)
10+
public LinkSegment(SegmentIndicatorPosition indicatorPosition, string url, string title)
11+
: base(SegmentIndicator.Link, indicatorPosition)
1212
{
1313
Url = url;
1414
Title = title;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using MarkdownParser.Models.Segments.Indicators;
2+
3+
namespace MarkdownParser.Models.Segments
4+
{
5+
public class PlaceholderSegment : IndicatorSegment
6+
{
7+
public string Url { get; }
8+
public string Title { get; }
9+
10+
public PlaceholderSegment(string url, string title)
11+
: base(SegmentIndicator.Placeholder, SegmentIndicatorPosition.Start)
12+
{
13+
Url = url;
14+
Title = title;
15+
HasLiteralContent = !string.IsNullOrWhiteSpace(Title)
16+
&& !string.IsNullOrWhiteSpace(Url);
17+
}
18+
19+
public override string ToString()
20+
{
21+
return Title ?? Url ?? string.Empty;
22+
}
23+
}
24+
}

src/MarkdownParser/Writer/ViewFormatter.cs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,20 @@ public List<T> FormatSingleBlock(Block markdownBlock)
2828
return _writer.Flush();
2929
}
3030

31+
private Dictionary<string, Reference> ReferenceMap;
32+
3133
private void WriteBlockToView(Block block, ViewWriter<T> writer, bool continueWithNextSibling = true)
3234
{
33-
if (block == null)
35+
var tag = block?.Tag;
36+
if (tag == null)
3437
{
3538
return;
3639
}
3740

38-
switch (block.Tag)
41+
switch (tag)
3942
{
4043
case BlockTag.Document:
44+
ReferenceMap = block.Document.ReferenceMap;
4145
_writer.RegisterReferenceDefinitions(block.Document.ReferenceMap);
4246
WriteBlockToView(block.FirstChild, writer);
4347
break;
@@ -81,7 +85,8 @@ private void WriteBlockToView(Block block, ViewWriter<T> writer, bool continueWi
8185
writer.StartAndFinalizeHtmlBlock(block.StringContent);
8286
break;
8387
case BlockTag.ReferenceDefinition:
84-
// ignore this tag, because it's handled before so the data can be used during the formatting
88+
// ignore this tag, because it's handled at 'BlockTag.Document' with 'RegisterReferenceDefinitions'
89+
// this way the data is available in time to be used during the formatting
8590
break;
8691
default:
8792
throw new CommonMarkException("Block type " + block.Tag + " is not supported.", block);
@@ -95,12 +100,13 @@ private void WriteBlockToView(Block block, ViewWriter<T> writer, bool continueWi
95100

96101
private void WriteInlineToView(Inline inline, ViewWriter<T> writer)
97102
{
98-
if (inline == null)
103+
var tag = inline?.Tag;
104+
if (tag == null)
99105
{
100106
return;
101107
}
102108

103-
switch (inline.Tag)
109+
switch (tag)
104110
{
105111
case InlineTag.Code:
106112
writer.AddEmphasis(inline, inline.SourcePosition, inline.SourceLength);
@@ -111,7 +117,7 @@ private void WriteInlineToView(Inline inline, ViewWriter<T> writer)
111117
writer.AddText(inline.LiteralContent, inline.SourcePosition);
112118
break;
113119
case InlineTag.Link:
114-
writer.AddLink(inline, inline.SourcePosition, inline.SourceLength, inline.TargetUrl, inline.LiteralContent); // check if this works at links
120+
writer.AddLink(inline.SourcePosition, inline.SourceLength, inline.TargetUrl, inline.LiteralContent); // check if this works at links
115121
WriteInlineToView(inline.FirstChild, writer);
116122
break;
117123
case InlineTag.Image:
@@ -122,7 +128,7 @@ private void WriteInlineToView(Inline inline, ViewWriter<T> writer)
122128
writer.AddEmphasis(inline, inline.SourcePosition, inline.SourceLength);
123129
break;
124130
case InlineTag.Placeholder:
125-
writer.StartAndFinalizePlaceholderBlock(inline.TargetUrl);
131+
writer.AddPlaceholder(inline.SourcePosition, inline.SourceLength, inline.TargetUrl, inline.FirstChild.LiteralContent);
126132
break;
127133
case InlineTag.Strikethrough:
128134
case InlineTag.Emphasis:

src/MarkdownParser/Writer/ViewWriter.cs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -231,11 +231,16 @@ public void AddText(string content, int firstCharacterPosition)
231231
GetWorkbenchItem().Add(content, firstCharacterPosition);
232232
}
233233

234-
public void AddLink(Inline inline, int firstCharacterPosition, int length, string url, string urlTitle)
234+
public void AddLink(int firstCharacterPosition, int length, string url, string urlTitle)
235235
{
236236
GetWorkbenchItem().AddLink(firstCharacterPosition, length, url, urlTitle);
237237
}
238238

239+
public void AddPlaceholder(int firstCharacterPosition, int length, string url, string title)
240+
{
241+
GetWorkbenchItem().AddPlaceholder(firstCharacterPosition, length, url, title);
242+
}
243+
239244
public void AddEmphasis(Inline inline, int firstCharacterPosition, int length)
240245
{
241246
SegmentIndicator indicator;
@@ -308,13 +313,7 @@ public void StartAndFinalizeThematicBreak()
308313
var separator = ViewSupplier.CreateThematicBreak();
309314
StoreView(separator);
310315
}
311-
312-
public void StartAndFinalizePlaceholderBlock(string placeholderName)
313-
{
314-
var placeholderView = ViewSupplier.CreatePlaceholder(placeholderName);
315-
StoreView(placeholderView);
316-
}
317-
316+
318317
private BlockType[] GetAncestorsTreeFromWorkbench(BlockType currentBlockType)
319318
{
320319
var blockTypeTree = new List<BlockType>();

src/MarkdownParser/Writer/ViewWriterCache.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,15 @@ public void AddLink(int firstCharacterPosition, int length, string url, string u
4848

4949
_pendingSegmentIndicators.Add((SegmentIndicator.Link, firstCharacterPosition + length - 1));
5050

51-
var segmentIndicator = new LinkSegment(SegmentIndicator.Link, SegmentIndicatorPosition.Start, url, urlTitle);
51+
var segmentIndicator = new LinkSegment(SegmentIndicatorPosition.Start, url, urlTitle);
52+
_valuesStack.Push((segmentIndicator, _defaultT));
53+
}
54+
55+
public void AddPlaceholder(int firstCharacterPosition, int length, string url, string title)
56+
{
57+
FinalizeSegmentIndicator(firstCharacterPosition);
58+
59+
var segmentIndicator = new PlaceholderSegment(url, title);
5260
_valuesStack.Push((segmentIndicator, _defaultT));
5361
}
5462

@@ -129,7 +137,7 @@ private void FinalizeSegmentIndicator(int toWritePosition)
129137
switch (pendingIndicator.SegmentIndicator)
130138
{
131139
case SegmentIndicator.Link:
132-
segmentIndicator = new LinkSegment(pendingIndicator.SegmentIndicator, SegmentIndicatorPosition.End, string.Empty, string.Empty);
140+
segmentIndicator = new LinkSegment(SegmentIndicatorPosition.End, string.Empty, string.Empty);
133141
break;
134142
default:
135143
segmentIndicator = new IndicatorSegment(pendingIndicator.SegmentIndicator, SegmentIndicatorPosition.End);

test/MarkdownParser.Test/MarkdownParser.Test.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
<EmbeddedResource Include="Resources\Examples\Sections\paragraphs.md" />
4141
<EmbeddedResource Include="Resources\Examples\Sections\referencedefinitions.md" />
4242
<EmbeddedResource Include="Resources\Examples\TextEmphasis\basic-links.md" />
43+
<EmbeddedResource Include="Resources\Examples\TextEmphasis\basic-placeholders.md" />
4344
<EmbeddedResource Include="Resources\Examples\TextEmphasis\basic-text.md" />
4445
</ItemGroup>
4546

test/MarkdownParser.Test/MarkdownParserBlockSegmentsSpecs.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,66 @@ public void When_parsing_text_with_links_it_should_output_ordered_segments()
136136
textBlock1!.TextSegments[6].As<IndicatorSegment>().Indicator.Should().Be(SegmentIndicator.Link);
137137
textBlock1!.TextSegments[6].As<IndicatorSegment>().IndicatorPosition.Should().Be(SegmentIndicatorPosition.End);
138138
}
139+
140+
[TestMethod]
141+
public void When_parsing_text_with_placeholders_it_should_output_ordered_segments()
142+
{
143+
//-----------------------------------------------------------------------------------------------------------
144+
// Arrange
145+
//-----------------------------------------------------------------------------------------------------------
146+
var markdown = FileReader.ReadFile("TextEmphasis.basic-placeholders.md");
147+
148+
var componentSupplier = new PassThroughComponentSupplier();
149+
var parser = new MarkdownParser<object>(componentSupplier);
150+
151+
//-----------------------------------------------------------------------------------------------------------
152+
// Act
153+
//-----------------------------------------------------------------------------------------------------------
154+
var parseResult = parser.Parse(markdown);
155+
156+
//-----------------------------------------------------------------------------------------------------------
157+
// Assert
158+
//-----------------------------------------------------------------------------------------------------------
159+
parseResult.Count.Should().Be(3);
160+
161+
parseResult[0].Should().BeOfType<TextBlock>();
162+
var textBlock0 = parseResult[0] as TextBlock;
163+
textBlock0!.TextSegments.Length.Should().Be(3);
164+
textBlock0!.TextSegments[0].As<TextSegment>().Text.Should().Be("Use ");
165+
textBlock0!.TextSegments[1].As<IndicatorSegment>().Indicator.Should().Be(SegmentIndicator.Placeholder);
166+
textBlock0!.TextSegments[1].As<IndicatorSegment>().IndicatorPosition.Should().Be(SegmentIndicatorPosition.Start);
167+
textBlock0!.TextSegments[1].As<PlaceholderSegment>().Title.Should().Be("placeholder x");
168+
textBlock0!.TextSegments[1].As<PlaceholderSegment>().Url.Should().Be("placeholder x");
169+
textBlock0!.TextSegments[1].As<PlaceholderSegment>().ToString().Should().Be("placeholder x");
170+
textBlock0!.TextSegments[2].As<TextSegment>().Text.Should().Be(" within sentence.");
171+
172+
parseResult[1].Should().BeOfType<TextBlock>();
173+
var textBlock1 = parseResult[1] as TextBlock;
174+
textBlock1!.TextSegments.Length.Should().Be(10);
175+
textBlock1!.TextSegments[0].As<TextSegment>().Text.Should().Be("Paragraphs ");
176+
textBlock1!.TextSegments[1].As<IndicatorSegment>().Indicator.Should().Be(SegmentIndicator.Strong);
177+
textBlock1!.TextSegments[1].As<IndicatorSegment>().IndicatorPosition.Should().Be(SegmentIndicatorPosition.Start);
178+
textBlock1!.TextSegments[2].As<TextSegment>().Text.Should().Be("are ");
179+
textBlock1!.TextSegments[3].As<IndicatorSegment>().Indicator.Should().Be(SegmentIndicator.Italic);
180+
textBlock1!.TextSegments[3].As<IndicatorSegment>().IndicatorPosition.Should().Be(SegmentIndicatorPosition.Start);
181+
textBlock1!.TextSegments[4].As<TextSegment>().Text.Should().Be("separated ");
182+
textBlock1!.TextSegments[5].As<IndicatorSegment>().Indicator.Should().Be(SegmentIndicator.Placeholder);
183+
textBlock1!.TextSegments[5].As<PlaceholderSegment>().Title.Should().Be("placeholder y");
184+
textBlock1!.TextSegments[5].As<PlaceholderSegment>().Url.Should().Be("placeholder y");
185+
textBlock1!.TextSegments[5].As<PlaceholderSegment>().ToString().Should().Be("placeholder y");
186+
textBlock1!.TextSegments[6].As<IndicatorSegment>().Indicator.Should().Be(SegmentIndicator.Italic);
187+
textBlock1!.TextSegments[6].As<IndicatorSegment>().IndicatorPosition.Should().Be(SegmentIndicatorPosition.End);
188+
textBlock1!.TextSegments[7].As<TextSegment>().Text.Should().Be(" by");
189+
textBlock1!.TextSegments[8].As<IndicatorSegment>().Indicator.Should().Be(SegmentIndicator.Strong);
190+
textBlock1!.TextSegments[8].As<IndicatorSegment>().IndicatorPosition.Should().Be(SegmentIndicatorPosition.End);
191+
textBlock1!.TextSegments[9].As<TextSegment>().Text.Should().Be(" a blank line.");
192+
193+
parseResult[2].Should().BeOfType<TextBlock>();
194+
var textBlock2 = parseResult[2] as TextBlock;
195+
textBlock2!.TextSegments.Length.Should().Be(1);
196+
textBlock2!.TextSegments[0].As<IndicatorSegment>().Indicator.Should().Be(SegmentIndicator.Placeholder);
197+
textBlock2!.TextSegments[0].As<PlaceholderSegment>().Title.Should().Be("placeholder z");
198+
textBlock2!.TextSegments[0].As<PlaceholderSegment>().Url.Should().Be("placeholder z");
199+
textBlock2!.TextSegments[0].As<PlaceholderSegment>().ToString().Should().Be("placeholder z");
200+
}
139201
}

test/MarkdownParser.Test/MarkdownParserBlocksSpecs.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ public void When_parsing_reference_definitions_it_should_output_correct_ancestor
260260
// Assert
261261
//-----------------------------------------------------------------------------------------------------------
262262
parseResult.Count.Should().Be(1);
263-
parseResult[0].Should().StartWith($"stackview>:+textview:[]{BlockType.Paragraph}");
263+
parseResult[0].Should().StartWith($"textview:[]{BlockType.Paragraph}:Aliquet in luctus in porttitor non quam donec.");
264264
}
265265

266266
[TestMethod]

0 commit comments

Comments
 (0)