-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Also adds helper methods to the pipeline builder
- Loading branch information
Showing
4 changed files
with
313 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
## Parser Pipelines | ||
|
||
The parser pipelines defines which inline and block parsers will be run across the input generating tags from their output. | ||
|
||
You may want to add custom tags to your output or remove existing ones if you don't want to use that functionality. | ||
|
||
We provide no method of building a parser pipeline yourself since we wanted to provide helpers so that users could easily fall into the best patterns. | ||
|
||
With this in mind you build parser pipelines using the `Parser Pipline Builder` which has some helper methods for replacing or adding parsers before or after other parsers. | ||
|
||
```c# | ||
var builder = new ParserPipelineBuilder(); | ||
builder.Replace<InterpolationTagParser>(new MyCustomParser()); | ||
// OR | ||
builder.Remove<InterpolationTagParser>(); | ||
// OR | ||
builder.AddAfter<InterpolationTagParser>(new MyCustomParser()); | ||
builder.AddBefore<InterpolationTagParser>(new MyCustomParser()); | ||
var pipeline = builder.Build(); | ||
``` | ||
|
||
These methods will work regardless of the type of parser you provide it and will correctly adapt the underlying parser listings. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
using Stubble.Core.Builders; | ||
using Stubble.Core.Imported; | ||
using Stubble.Core.Parser; | ||
using Stubble.Core.Parser.Interfaces; | ||
using Stubble.Core.Parser.TokenParsers; | ||
using Stubble.Core.Tokens; | ||
using Xunit; | ||
|
||
namespace Stubble.Core.Tests | ||
{ | ||
public class ParserPipelineBuilderTest | ||
{ | ||
[Fact] | ||
public void It_Should_Be_Able_To_Remove_InlineParsers() | ||
{ | ||
var builder = new ParserPipelineBuilder(); | ||
builder.Remove<InterpolationTagParser>(); | ||
var pipeline = builder.Build(); | ||
|
||
Assert.DoesNotContain(pipeline.InlineParsers, p => p is InterpolationTagParser); | ||
} | ||
|
||
[Fact] | ||
public void It_Should_Be_Able_To_Remove_BlockParsers() | ||
{ | ||
var builder = new ParserPipelineBuilder(); | ||
builder.Remove<SectionTagParser>(); | ||
var pipeline = builder.Build(); | ||
|
||
Assert.DoesNotContain(pipeline.BlockParsers, p => p is SectionTagParser); | ||
} | ||
|
||
[Fact] | ||
public void It_Should_Be_Able_To_Replace_InlineParsers() | ||
{ | ||
var builder = new ParserPipelineBuilder(); | ||
builder.Replace<InterpolationTagParser>(new MyCustomInlineParser()); | ||
var pipeline = builder.Build(); | ||
|
||
Assert.DoesNotContain(pipeline.InlineParsers, p => p is InterpolationTagParser); | ||
} | ||
|
||
[Fact] | ||
public void It_Should_Be_Able_To_Replace_BlockParsers() | ||
{ | ||
var builder = new ParserPipelineBuilder(); | ||
builder.Replace<SectionTagParser>(new MyCustomBlockParser()); | ||
var pipeline = builder.Build(); | ||
|
||
Assert.DoesNotContain(pipeline.BlockParsers, p => p is SectionTagParser); | ||
} | ||
|
||
[Fact] | ||
public void It_Should_Be_Able_To_AddAfter_InlineParsers() | ||
{ | ||
var builder = new ParserPipelineBuilder(); | ||
builder.AddAfter<InterpolationTagParser>(new MyCustomInlineParser()); | ||
var pipeline = builder.Build(); | ||
|
||
Assert.Contains(pipeline.InlineParsers, p => p is InterpolationTagParser); | ||
Assert.Contains(pipeline.InlineParsers, p => p is MyCustomInlineParser); | ||
|
||
var interpolationIndex = pipeline.InlineParsers.FindIndex(p => p is InterpolationTagParser); | ||
var customIndex = pipeline.InlineParsers.FindIndex(p => p is MyCustomInlineParser); | ||
Assert.True(customIndex > interpolationIndex); | ||
} | ||
|
||
[Fact] | ||
public void It_Should_Be_Able_To_AddAfter_BlockParsers() | ||
{ | ||
var builder = new ParserPipelineBuilder(); | ||
builder.AddAfter<SectionTagParser>(new MyCustomBlockParser()); | ||
var pipeline = builder.Build(); | ||
|
||
Assert.Contains(pipeline.BlockParsers, p => p is SectionTagParser); | ||
Assert.Contains(pipeline.BlockParsers, p => p is MyCustomBlockParser); | ||
|
||
var sectionIndex = pipeline.BlockParsers.FindIndex(p => p is SectionTagParser); | ||
var customIndex = pipeline.BlockParsers.FindIndex(p => p is MyCustomBlockParser); | ||
Assert.True(customIndex > sectionIndex); | ||
} | ||
|
||
[Fact] | ||
public void It_Should_Be_Able_To_AddBefore_InlineParsers() | ||
{ | ||
var builder = new ParserPipelineBuilder(); | ||
builder.AddBefore<InterpolationTagParser>(new MyCustomInlineParser()); | ||
var pipeline = builder.Build(); | ||
|
||
Assert.Contains(pipeline.InlineParsers, p => p is InterpolationTagParser); | ||
Assert.Contains(pipeline.InlineParsers, p => p is MyCustomInlineParser); | ||
|
||
var interpolationIndex = pipeline.InlineParsers.FindIndex(p => p is InterpolationTagParser); | ||
var customIndex = pipeline.InlineParsers.FindIndex(p => p is MyCustomInlineParser); | ||
Assert.True(customIndex < interpolationIndex); | ||
} | ||
|
||
[Fact] | ||
public void It_Should_Be_Able_To_AddBefore_BlockParsers() | ||
{ | ||
var builder = new ParserPipelineBuilder(); | ||
builder.AddBefore<SectionTagParser>(new MyCustomBlockParser()); | ||
var pipeline = builder.Build(); | ||
|
||
Assert.Contains(pipeline.BlockParsers, p => p is SectionTagParser); | ||
Assert.Contains(pipeline.BlockParsers, p => p is MyCustomBlockParser); | ||
|
||
var sectionIndex = pipeline.BlockParsers.FindIndex(p => p is SectionTagParser); | ||
var customIndex = pipeline.BlockParsers.FindIndex(p => p is MyCustomBlockParser); | ||
Assert.True(customIndex < sectionIndex); | ||
} | ||
|
||
private class MyCustomInlineParser : InlineParser | ||
{ | ||
public override bool Match(Processor processor, ref StringSlice slice) | ||
{ | ||
throw new System.NotImplementedException(); | ||
} | ||
} | ||
|
||
private class MyCustomBlockParser : BlockParser | ||
{ | ||
public override void EndBlock(Processor processor, BlockToken token, BlockCloseToken closeToken, StringSlice content) | ||
{ | ||
throw new System.NotImplementedException(); | ||
} | ||
|
||
public override bool TryClose(Processor processor, ref StringSlice slice, BlockToken token) | ||
{ | ||
throw new System.NotImplementedException(); | ||
} | ||
|
||
public override ParserState TryOpenBlock(Processor processor, ref StringSlice slice) | ||
{ | ||
throw new System.NotImplementedException(); | ||
} | ||
} | ||
} | ||
} |