From 124a92f7436c5a9f8cbabacd5878c67074e49b2f Mon Sep 17 00:00:00 2001 From: Andrei Fangli Date: Sat, 30 May 2020 16:11:47 +0300 Subject: [PATCH] #9 Refactored to generic Token --- Mup/Creole/CreoleScanner.cs | 42 ++++----- Mup/Creole/CreoleToken.cs | 12 --- Mup/Creole/CreoleTokenRange.cs | 89 ------------------- .../CreoleCodeBlockElementProcessor.cs | 5 +- .../CreoleElementProcessor.cs | 13 +-- .../CreoleHeadingElementProcessor.cs | 3 +- .../CreoleHorizontalRuleElementProcessor.cs | 3 +- .../CreoleListElementProcessor.cs | 3 +- .../CreoleParagraphElementProcessor.cs | 3 +- .../CreolePluginElementProcessor.cs | 3 +- .../CreoleTableElementProcessor.cs | 3 +- .../RichText/CreoleCodeElementProcessor.cs | 5 +- .../CreoleEmphasisElementProcessor.cs | 5 +- .../CreoleHyperlinkElementProcessor.cs | 5 +- .../RichText/CreoleImageElementProcessor.cs | 5 +- .../CreoleInlineHyperlinkProcessor.cs | 5 +- .../CreoleLineBreakElementProcessor.cs | 5 +- .../RichText/CreolePluginElementProcessor.cs | 5 +- .../CreoleRichTextElementProcessor.cs | 15 ++-- .../RichText/CreoleRichTextProcessor.cs | 37 ++++---- .../RichText/CreoleStrongElementProcessor.cs | 5 +- .../RichText/CreoleStyleElementProcessor.cs | 5 +- .../RichText/CreoleUrlElementProcessor.cs | 5 +- Mup/CreoleParser.cs | 7 +- Mup/Scanner/TokenRange.cs | 48 ++++++++++ .../TokenRangeHelper.cs} | 6 +- 26 files changed, 155 insertions(+), 187 deletions(-) delete mode 100644 Mup/Creole/CreoleToken.cs delete mode 100644 Mup/Creole/CreoleTokenRange.cs create mode 100644 Mup/Scanner/TokenRange.cs rename Mup/{Creole/CreoleTokenRangeHelper.cs => Scanner/TokenRangeHelper.cs} (63%) diff --git a/Mup/Creole/CreoleScanner.cs b/Mup/Creole/CreoleScanner.cs index 18bfac7..32a9051 100644 --- a/Mup/Creole/CreoleScanner.cs +++ b/Mup/Creole/CreoleScanner.cs @@ -19,9 +19,9 @@ internal class CreoleScanner : CharacterScanner private readonly StringBuilder _textBuilder = new StringBuilder(); - private List _tokens; + private List> _tokens; - internal IReadOnlyList Result { get; private set; } + internal IReadOnlyList> Result { get; private set; } protected override void Reset() { @@ -31,7 +31,7 @@ protected override void Reset() _tokenCode = Text; _lineFeedCount = 0; _textBuilder.Length = 0; - _tokens = new List(); + _tokens = new List>(); } protected override void Process(char character) @@ -58,74 +58,74 @@ private void _ProcessCharacter(char character) case '*': _AddToken(); - _tokens.Add(new CreoleToken(Asterisk, "*", Line, Column)); + _tokens.Add(new Token(Asterisk, "*", Line, Column)); break; case '/': _AddToken(); - _tokens.Add(new CreoleToken(Slash, "/", Line, Column)); + _tokens.Add(new Token(Slash, "/", Line, Column)); break; case '\\': _AddToken(); - _tokens.Add(new CreoleToken(BackSlash, "\\", Line, Column)); + _tokens.Add(new Token(BackSlash, "\\", Line, Column)); break; case '[': _AddToken(); - _tokens.Add(new CreoleToken(BracketOpen, "[", Line, Column)); + _tokens.Add(new Token(BracketOpen, "[", Line, Column)); break; case ']': _AddToken(); - _tokens.Add(new CreoleToken(BracketClose, "]", Line, Column)); + _tokens.Add(new Token(BracketClose, "]", Line, Column)); break; case '{': _AddToken(); - _tokens.Add(new CreoleToken(BraceOpen, "{", Line, Column)); + _tokens.Add(new Token(BraceOpen, "{", Line, Column)); break; case '}': _AddToken(); - _tokens.Add(new CreoleToken(BraceClose, "}", Line, Column)); + _tokens.Add(new Token(BraceClose, "}", Line, Column)); break; case '<': _AddToken(); - _tokens.Add(new CreoleToken(AngleOpen, "<", Line, Column)); + _tokens.Add(new Token(AngleOpen, "<", Line, Column)); break; case '>': _AddToken(); - _tokens.Add(new CreoleToken(AngleClose, ">", Line, Column)); + _tokens.Add(new Token(AngleClose, ">", Line, Column)); break; case '=': _AddToken(); - _tokens.Add(new CreoleToken(Equal, "=", Line, Column)); + _tokens.Add(new Token(Equal, "=", Line, Column)); break; case '-': _AddToken(); - _tokens.Add(new CreoleToken(Dash, "-", Line, Column)); + _tokens.Add(new Token(Dash, "-", Line, Column)); break; case '#': _AddToken(); - _tokens.Add(new CreoleToken(Hash, "#", Line, Column)); + _tokens.Add(new Token(Hash, "#", Line, Column)); break; case '|': _AddToken(); - _tokens.Add(new CreoleToken(Pipe, "|", Line, Column)); + _tokens.Add(new Token(Pipe, "|", Line, Column)); break; default: if (IsPunctuation(character)) { _AddToken(); - _tokens.Add(new CreoleToken(Punctuation, character.ToString(), Line, Column)); + _tokens.Add(new Token(Punctuation, character.ToString(), Line, Column)); } else { @@ -150,7 +150,7 @@ private void _ProcessEscapedCharacter(char character) { _AddToken(); - _tokens.Add(new CreoleToken(Tilde, _escapeCahracterString, Line, Column)); + _tokens.Add(new Token(Tilde, _escapeCahracterString, Line, Column)); _tokenCode = Text; _textBuilder.Append(character); @@ -159,7 +159,7 @@ private void _ProcessEscapedCharacter(char character) { _AddToken(); - _tokens.Add(new CreoleToken(Text, _escapeCahracterString, Line, Column)); + _tokens.Add(new Token(Text, _escapeCahracterString, Line, Column)); _tokenCode = Text; } @@ -215,11 +215,11 @@ private void _AddToken() _lineFeedCount = 0; } - _tokens.Add(new CreoleToken(_tokenCode, _textBuilder.ToString(), Line, Column)); + _tokens.Add(new Token(_tokenCode, _textBuilder.ToString(), Line, Column)); _textBuilder.Length = 0; } else if (_isEscaped) - _tokens.Add(new CreoleToken(Text, _escapeCahracterString, Line, Column)); + _tokens.Add(new Token(Text, _escapeCahracterString, Line, Column)); } } } \ No newline at end of file diff --git a/Mup/Creole/CreoleToken.cs b/Mup/Creole/CreoleToken.cs deleted file mode 100644 index 0a84a2c..0000000 --- a/Mup/Creole/CreoleToken.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Mup.Scanner; - -namespace Mup.Creole -{ - internal class CreoleToken : Token - { - internal CreoleToken(CreoleTokenCode code, string text, int line, int column) - : base(code, text, line, column) - { - } - } -} \ No newline at end of file diff --git a/Mup/Creole/CreoleTokenRange.cs b/Mup/Creole/CreoleTokenRange.cs deleted file mode 100644 index 3e66d85..0000000 --- a/Mup/Creole/CreoleTokenRange.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Mup.Creole -{ - internal class CreoleTokenRange : IEnumerable - { - private readonly IReadOnlyList _tokens; - private readonly int _startIndex; - private readonly int _count; - - internal CreoleTokenRange(IReadOnlyList tokens) - { - if (tokens == null) - throw new ArgumentNullException(nameof(tokens)); - - _tokens = tokens; - _startIndex = 0; - _count = _tokens.Count; - } - - internal CreoleTokenRange(IReadOnlyList tokens, int rangeStartIndex, int rangeLength) - { - if (tokens == null) - throw new ArgumentNullException(nameof(tokens)); - if (rangeStartIndex < 0 || rangeStartIndex > tokens.Count) - throw new ArgumentOutOfRangeException(nameof(rangeLength), "Start index must less than the length of the source collection and greater than zero."); - if (tokens.Count < rangeStartIndex + rangeLength) - throw new ArgumentOutOfRangeException(nameof(rangeLength), "The sum of the range start and length must be less or equal to the source collection length."); - - _tokens = tokens; - _startIndex = rangeStartIndex; - _count = rangeLength; - } - - internal int Count - => _count; - - internal CreoleTokenRange SubRange(int startIndex, int length) - => new CreoleTokenRange(_tokens, (_startIndex + startIndex), length); - - public IEnumerator GetEnumerator() - => new CreoleTokenRangeEnumerator(this); - - IEnumerator IEnumerable.GetEnumerator() - => GetEnumerator(); - - private class CreoleTokenRangeEnumerator : IEnumerator - { - private readonly CreoleTokenRange _creoleTokenRange; - private int _index = -1; - - internal CreoleTokenRangeEnumerator(CreoleTokenRange creoleTokenRange) - { - _creoleTokenRange = creoleTokenRange; - } - - public CreoleToken Current - { - get - { - if (_index < 0 || _index > _creoleTokenRange._count) - throw new InvalidOperationException("The last call to MoveNext() method must return true for this property to be accessible."); - - return _creoleTokenRange._tokens[_creoleTokenRange._startIndex + _index]; - } - } - - object IEnumerator.Current - => Current; - - public bool MoveNext() - { - _index++; - return (_index < _creoleTokenRange._count); - } - - public void Reset() - { - _index = -1; - } - - void IDisposable.Dispose() - { - } - } - } -} \ No newline at end of file diff --git a/Mup/Creole/ElementProcessors/CreoleCodeBlockElementProcessor.cs b/Mup/Creole/ElementProcessors/CreoleCodeBlockElementProcessor.cs index 4a2018a..8a7c436 100644 --- a/Mup/Creole/ElementProcessors/CreoleCodeBlockElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/CreoleCodeBlockElementProcessor.cs @@ -1,4 +1,5 @@ using Mup.Creole.Elements; +using Mup.Scanner; using System.Text; using static Mup.Creole.CreoleTokenCode; @@ -25,7 +26,7 @@ private enum State : byte private bool _isAtBeginningOfLine = true; - internal CreoleCodeBlockElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + internal CreoleCodeBlockElementProcessor(CreoleParserContext context, TokenRange tokens) : base(context, tokens) { } @@ -114,7 +115,7 @@ private CreoleElement _GetCodeBlockElement() return new CreolePreformattedBlockElement(codeBlockText); } - private string _GetCodeBlockTextFrom(CreoleTokenRange tokens) + private string _GetCodeBlockTextFrom(TokenRange tokens) { var builder = new StringBuilder(); diff --git a/Mup/Creole/ElementProcessors/CreoleElementProcessor.cs b/Mup/Creole/ElementProcessors/CreoleElementProcessor.cs index 17160a4..668ceff 100644 --- a/Mup/Creole/ElementProcessors/CreoleElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/CreoleElementProcessor.cs @@ -1,5 +1,6 @@ using Mup.Creole.ElementProcessors.RichText; using Mup.Creole.Elements; +using Mup.Scanner; using System; using System.Collections.Generic; using static Mup.Creole.CreoleTokenCode; @@ -9,17 +10,17 @@ namespace Mup.Creole.ElementProcessors internal abstract class CreoleElementProcessor : IDisposable { private static readonly IEnumerable _emptyCreoleElements = new CreoleElement[0]; - private readonly CreoleTokenRange _tokens; + private readonly TokenRange _tokens; private int _index = 0; private bool _isOnNewLine = true; private int _elementStartIndex = 0; private int _elementEndIndex = 0; - private readonly IEnumerator _token; + private readonly IEnumerator> _token; private bool _tokenHasValue; private CreoleElementInfo _result = null; private bool _isCompleted = false; - protected CreoleElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + protected CreoleElementProcessor(CreoleParserContext context, TokenRange tokens) { Context = context; _tokens = tokens; @@ -83,7 +84,7 @@ internal bool MoveNext() protected CreoleParserContext Context { get; } - protected CreoleToken Token + protected Token Token => _token.Current; protected int Index @@ -119,7 +120,7 @@ protected string GetPlainText() => GetPlainText(_elementStartIndex, _elementEndIndex); protected string GetPlainText(int startIndex, int endIndex) - => CreoleTokenRangeHelper.GetPlainText(GetTokens(startIndex, endIndex)); + => TokenRangeHelper.GetPlainText(GetTokens(startIndex, endIndex)); protected IEnumerable GetRichText() => GetRichText(_elementStartIndex, _elementEndIndex); @@ -134,7 +135,7 @@ protected IEnumerable GetRichText(int startIndex, int endIndex) return richTextProcessor.Process(tokens); } - protected CreoleTokenRange GetTokens(int startIndex, int endIndex) + protected TokenRange GetTokens(int startIndex, int endIndex) { if (startIndex < _elementStartIndex) throw new ArgumentException("Content cannot begin before the element starts.", nameof(startIndex)); diff --git a/Mup/Creole/ElementProcessors/CreoleHeadingElementProcessor.cs b/Mup/Creole/ElementProcessors/CreoleHeadingElementProcessor.cs index 3a561e5..d1e46f2 100644 --- a/Mup/Creole/ElementProcessors/CreoleHeadingElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/CreoleHeadingElementProcessor.cs @@ -1,4 +1,5 @@ using Mup.Creole.Elements; +using Mup.Scanner; using static Mup.Creole.CreoleTokenCode; namespace Mup.Creole.ElementProcessors @@ -20,7 +21,7 @@ private enum State : byte private State _state = State.NotInHeading; private byte _equalTokensCount = 0; - internal CreoleHeadingElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + internal CreoleHeadingElementProcessor(CreoleParserContext context, TokenRange tokens) : base(context, tokens) { } diff --git a/Mup/Creole/ElementProcessors/CreoleHorizontalRuleElementProcessor.cs b/Mup/Creole/ElementProcessors/CreoleHorizontalRuleElementProcessor.cs index 327250b..639dc57 100644 --- a/Mup/Creole/ElementProcessors/CreoleHorizontalRuleElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/CreoleHorizontalRuleElementProcessor.cs @@ -1,4 +1,5 @@ using Mup.Creole.Elements; +using Mup.Scanner; using static Mup.Creole.CreoleTokenCode; namespace Mup.Creole.ElementProcessors @@ -16,7 +17,7 @@ private enum State : byte private int dashCount = 0; private State _state = State.NotInHorizontalRule; - internal CreoleHorizontalRuleElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + internal CreoleHorizontalRuleElementProcessor(CreoleParserContext context, TokenRange tokens) : base(context, tokens) { } diff --git a/Mup/Creole/ElementProcessors/CreoleListElementProcessor.cs b/Mup/Creole/ElementProcessors/CreoleListElementProcessor.cs index a3433a3..15acbfd 100644 --- a/Mup/Creole/ElementProcessors/CreoleListElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/CreoleListElementProcessor.cs @@ -1,4 +1,5 @@ using Mup.Creole.Elements; +using Mup.Scanner; using System.Collections.Generic; using static Mup.Creole.CreoleTokenCode; @@ -25,7 +26,7 @@ private enum State private int _listItemLevel; private Stack _listInfos = new Stack(); - public CreoleListElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + public CreoleListElementProcessor(CreoleParserContext context, TokenRange tokens) : base(context, tokens) { } diff --git a/Mup/Creole/ElementProcessors/CreoleParagraphElementProcessor.cs b/Mup/Creole/ElementProcessors/CreoleParagraphElementProcessor.cs index 6810b66..597da7e 100644 --- a/Mup/Creole/ElementProcessors/CreoleParagraphElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/CreoleParagraphElementProcessor.cs @@ -1,4 +1,5 @@ using Mup.Creole.Elements; +using Mup.Scanner; using static Mup.Creole.CreoleTokenCode; namespace Mup.Creole.ElementProcessors @@ -14,7 +15,7 @@ private enum State : byte private State _state = State.NotInParagraph; - internal CreoleParagraphElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + internal CreoleParagraphElementProcessor(CreoleParserContext context, TokenRange tokens) : base(context, tokens) { } diff --git a/Mup/Creole/ElementProcessors/CreolePluginElementProcessor.cs b/Mup/Creole/ElementProcessors/CreolePluginElementProcessor.cs index 9b59853..7c4106b 100644 --- a/Mup/Creole/ElementProcessors/CreolePluginElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/CreolePluginElementProcessor.cs @@ -1,4 +1,5 @@ using Mup.Creole.Elements; +using Mup.Scanner; using static Mup.Creole.CreoleTokenCode; namespace Mup.Creole.ElementProcessors @@ -22,7 +23,7 @@ private enum State : byte private int _contentEndIndexOddEndingIndex = 0; private State _state = State.NotInPlugin; - internal CreolePluginElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + internal CreolePluginElementProcessor(CreoleParserContext context, TokenRange tokens) : base(context, tokens) { } diff --git a/Mup/Creole/ElementProcessors/CreoleTableElementProcessor.cs b/Mup/Creole/ElementProcessors/CreoleTableElementProcessor.cs index 4c4ef6e..45dd5e5 100644 --- a/Mup/Creole/ElementProcessors/CreoleTableElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/CreoleTableElementProcessor.cs @@ -1,4 +1,5 @@ using Mup.Creole.Elements; +using Mup.Scanner; using System.Collections.Generic; using static Mup.Creole.CreoleTokenCode; @@ -23,7 +24,7 @@ private enum State : byte private List _rows; private List _cells; - internal CreoleTableElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + internal CreoleTableElementProcessor(CreoleParserContext context, TokenRange tokens) : base(context, tokens) { } diff --git a/Mup/Creole/ElementProcessors/RichText/CreoleCodeElementProcessor.cs b/Mup/Creole/ElementProcessors/RichText/CreoleCodeElementProcessor.cs index bf167c8..a446838 100644 --- a/Mup/Creole/ElementProcessors/RichText/CreoleCodeElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/RichText/CreoleCodeElementProcessor.cs @@ -1,3 +1,4 @@ +using Mup.Scanner; using static Mup.Creole.CreoleTokenCode; namespace Mup.Creole.ElementProcessors.RichText @@ -19,12 +20,12 @@ private enum State : byte private int _elementEndIndex; private State _state = State.NoElement; - internal CreoleCodeElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + internal CreoleCodeElementProcessor(CreoleParserContext context, TokenRange tokens) : base(context, tokens) { } - internal CreoleCodeElementProcessor(CreoleParserContext context, CreoleTokenRange tokens, CreoleRichTextElementProcessor baseElementProcessor) + internal CreoleCodeElementProcessor(CreoleParserContext context, TokenRange tokens, CreoleRichTextElementProcessor baseElementProcessor) : base(context, tokens, baseElementProcessor) { } diff --git a/Mup/Creole/ElementProcessors/RichText/CreoleEmphasisElementProcessor.cs b/Mup/Creole/ElementProcessors/RichText/CreoleEmphasisElementProcessor.cs index 13c1f53..1234e52 100644 --- a/Mup/Creole/ElementProcessors/RichText/CreoleEmphasisElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/RichText/CreoleEmphasisElementProcessor.cs @@ -1,3 +1,4 @@ +using Mup.Scanner; using System.Collections.Generic; using static Mup.Creole.CreoleTokenCode; @@ -5,12 +6,12 @@ namespace Mup.Creole.ElementProcessors.RichText { internal class CreoleEmphasisElementProcessor : CreoleStyleElementProcessor { - internal CreoleEmphasisElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + internal CreoleEmphasisElementProcessor(CreoleParserContext context, TokenRange tokens) : base(context, tokens) { } - internal CreoleEmphasisElementProcessor(CreoleParserContext context, CreoleTokenRange tokens, IEnumerable baseElements) + internal CreoleEmphasisElementProcessor(CreoleParserContext context, TokenRange tokens, IEnumerable baseElements) : base(context, tokens, baseElements) { } diff --git a/Mup/Creole/ElementProcessors/RichText/CreoleHyperlinkElementProcessor.cs b/Mup/Creole/ElementProcessors/RichText/CreoleHyperlinkElementProcessor.cs index b640f12..5edf7bc 100644 --- a/Mup/Creole/ElementProcessors/RichText/CreoleHyperlinkElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/RichText/CreoleHyperlinkElementProcessor.cs @@ -1,15 +1,16 @@ +using Mup.Scanner; using static Mup.Creole.CreoleTokenCode; namespace Mup.Creole.ElementProcessors.RichText { internal class CreoleHyperlinkElementProcessor : CreoleUrlElementProcessor { - internal CreoleHyperlinkElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + internal CreoleHyperlinkElementProcessor(CreoleParserContext context, TokenRange tokens) : base(context, tokens) { } - internal CreoleHyperlinkElementProcessor(CreoleParserContext context, CreoleTokenRange tokens, CreoleRichTextElementProcessor baseElementProcessor) + internal CreoleHyperlinkElementProcessor(CreoleParserContext context, TokenRange tokens, CreoleRichTextElementProcessor baseElementProcessor) : base(context, tokens, baseElementProcessor) { } diff --git a/Mup/Creole/ElementProcessors/RichText/CreoleImageElementProcessor.cs b/Mup/Creole/ElementProcessors/RichText/CreoleImageElementProcessor.cs index 838d7d4..2284ec2 100644 --- a/Mup/Creole/ElementProcessors/RichText/CreoleImageElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/RichText/CreoleImageElementProcessor.cs @@ -1,15 +1,16 @@ +using Mup.Scanner; using static Mup.Creole.CreoleTokenCode; namespace Mup.Creole.ElementProcessors.RichText { internal class CreoleImageElementProcessor : CreoleUrlElementProcessor { - internal CreoleImageElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + internal CreoleImageElementProcessor(CreoleParserContext context, TokenRange tokens) : base(context, tokens) { } - internal CreoleImageElementProcessor(CreoleParserContext context, CreoleTokenRange tokens, CreoleRichTextElementProcessor baseElementProcessor) + internal CreoleImageElementProcessor(CreoleParserContext context, TokenRange tokens, CreoleRichTextElementProcessor baseElementProcessor) : base(context, tokens, baseElementProcessor) { } diff --git a/Mup/Creole/ElementProcessors/RichText/CreoleInlineHyperlinkProcessor.cs b/Mup/Creole/ElementProcessors/RichText/CreoleInlineHyperlinkProcessor.cs index 7e915d5..7b73c17 100644 --- a/Mup/Creole/ElementProcessors/RichText/CreoleInlineHyperlinkProcessor.cs +++ b/Mup/Creole/ElementProcessors/RichText/CreoleInlineHyperlinkProcessor.cs @@ -1,3 +1,4 @@ +using Mup.Scanner; using System; using static Mup.Creole.CreoleTokenCode; @@ -24,12 +25,12 @@ private enum State : byte private bool _isEscaped; private State _state = State.NoElement; - internal CreoleInlineHyperlinkProcessor(CreoleParserContext context, CreoleTokenRange tokens) + internal CreoleInlineHyperlinkProcessor(CreoleParserContext context, TokenRange tokens) : base(context, tokens) { } - internal CreoleInlineHyperlinkProcessor(CreoleParserContext context, CreoleTokenRange tokens, CreoleRichTextElementProcessor baseElementProcessor) + internal CreoleInlineHyperlinkProcessor(CreoleParserContext context, TokenRange tokens, CreoleRichTextElementProcessor baseElementProcessor) : base(context, tokens, baseElementProcessor) { } diff --git a/Mup/Creole/ElementProcessors/RichText/CreoleLineBreakElementProcessor.cs b/Mup/Creole/ElementProcessors/RichText/CreoleLineBreakElementProcessor.cs index 33080a5..a397af3 100644 --- a/Mup/Creole/ElementProcessors/RichText/CreoleLineBreakElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/RichText/CreoleLineBreakElementProcessor.cs @@ -1,3 +1,4 @@ +using Mup.Scanner; using static Mup.Creole.CreoleTokenCode; namespace Mup.Creole.ElementProcessors.RichText @@ -13,12 +14,12 @@ private enum State : byte private int _elementStartIndex; private State _state = State.NoElement; - internal CreoleLineBreakElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + internal CreoleLineBreakElementProcessor(CreoleParserContext context, TokenRange tokens) : base(context, tokens) { } - internal CreoleLineBreakElementProcessor(CreoleParserContext context, CreoleTokenRange tokens, CreoleRichTextElementProcessor baseElementProcessor) + internal CreoleLineBreakElementProcessor(CreoleParserContext context, TokenRange tokens, CreoleRichTextElementProcessor baseElementProcessor) : base(context, tokens, baseElementProcessor) { } diff --git a/Mup/Creole/ElementProcessors/RichText/CreolePluginElementProcessor.cs b/Mup/Creole/ElementProcessors/RichText/CreolePluginElementProcessor.cs index a2e83f0..cab339d 100644 --- a/Mup/Creole/ElementProcessors/RichText/CreolePluginElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/RichText/CreolePluginElementProcessor.cs @@ -1,3 +1,4 @@ +using Mup.Scanner; using static Mup.Creole.CreoleTokenCode; namespace Mup.Creole.ElementProcessors.RichText @@ -17,12 +18,12 @@ private enum State : byte private int _elementEndIndex; private State _state = State.NoElement; - internal CreolePluginElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + internal CreolePluginElementProcessor(CreoleParserContext context, TokenRange tokens) : base(context, tokens) { } - internal CreolePluginElementProcessor(CreoleParserContext context, CreoleTokenRange tokens, CreoleRichTextElementProcessor baseElementProcessor) + internal CreolePluginElementProcessor(CreoleParserContext context, TokenRange tokens, CreoleRichTextElementProcessor baseElementProcessor) : base(context, tokens, baseElementProcessor) { } diff --git a/Mup/Creole/ElementProcessors/RichText/CreoleRichTextElementProcessor.cs b/Mup/Creole/ElementProcessors/RichText/CreoleRichTextElementProcessor.cs index 054fcbb..e53b4ee 100644 --- a/Mup/Creole/ElementProcessors/RichText/CreoleRichTextElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/RichText/CreoleRichTextElementProcessor.cs @@ -1,3 +1,4 @@ +using Mup.Scanner; using System; using System.Collections.Generic; @@ -5,29 +6,29 @@ namespace Mup.Creole.ElementProcessors.RichText { internal abstract class CreoleRichTextElementProcessor : IDisposable { - private readonly CreoleTokenRange _tokens; + private readonly TokenRange _tokens; private int _index; private int _startIndex = 0; private CreoleRichTextElementData _result = null; private ICreoleRichTextElementDataIterator _element; - private IEnumerator _token; + private IEnumerator> _token; - internal CreoleRichTextElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + internal CreoleRichTextElementProcessor(CreoleParserContext context, TokenRange tokens) : this(context, tokens, elementIterator: null) { } - internal CreoleRichTextElementProcessor(CreoleParserContext context, CreoleTokenRange tokens, CreoleRichTextElementProcessor elementProcessor) + internal CreoleRichTextElementProcessor(CreoleParserContext context, TokenRange tokens, CreoleRichTextElementProcessor elementProcessor) : this(context, tokens, (elementProcessor != null ? new CreoleRichTextElementProcessorIteratorAdapter(elementProcessor) : null)) { } - internal CreoleRichTextElementProcessor(CreoleParserContext context, CreoleTokenRange tokens, IEnumerable elements) + internal CreoleRichTextElementProcessor(CreoleParserContext context, TokenRange tokens, IEnumerable elements) : this(context, tokens, (elements != null ? new CreoleRichTextElementDataCollectionAdapter(elements) : null)) { } - private CreoleRichTextElementProcessor(CreoleParserContext context, CreoleTokenRange tokens, ICreoleRichTextElementDataIterator elementIterator) + private CreoleRichTextElementProcessor(CreoleParserContext context, TokenRange tokens, ICreoleRichTextElementDataIterator elementIterator) { _tokens = tokens; Context = context; @@ -105,7 +106,7 @@ internal CreoleRichTextElementData Current protected CreoleParserContext Context { get; } - protected CreoleToken Token + protected Token Token => _token.Current; protected int Index diff --git a/Mup/Creole/ElementProcessors/RichText/CreoleRichTextProcessor.cs b/Mup/Creole/ElementProcessors/RichText/CreoleRichTextProcessor.cs index f037167..d03302b 100644 --- a/Mup/Creole/ElementProcessors/RichText/CreoleRichTextProcessor.cs +++ b/Mup/Creole/ElementProcessors/RichText/CreoleRichTextProcessor.cs @@ -1,4 +1,5 @@ using Mup.Creole.Elements; +using Mup.Scanner; using System; using System.Collections.Generic; @@ -6,7 +7,7 @@ namespace Mup.Creole.ElementProcessors.RichText { internal class CreoleRichTextProcessor { - private delegate CreoleStyleElementProcessor CreoleStyleElementProcessorFactory(CreoleParserContext context, CreoleTokenRange tokens, IEnumerable baseElementsData); + private delegate CreoleStyleElementProcessor CreoleStyleElementProcessorFactory(CreoleParserContext context, TokenRange tokens, IEnumerable baseElementsData); private static readonly IDictionary _styleElementFactories = new Dictionary { { CreoleRichTextElementType.Emphasis, (context, tokens, baseElementsData) => new CreoleEmphasisElementProcessor(context, tokens, baseElementsData) }, @@ -21,7 +22,7 @@ internal CreoleRichTextProcessor(CreoleParserContext context) _context = context; } - internal IEnumerable Process(CreoleTokenRange tokens) + internal IEnumerable Process(TokenRange tokens) { var baseElementsData = new List(); using (var baseElementProcessor = _GetBaseElementProcessor(_context, tokens)) @@ -36,7 +37,7 @@ internal IEnumerable Process(CreoleTokenRange tokens) return _GetCreoleElements(tokens, elementsData); } - private CreoleRichTextElementProcessor _GetBaseElementProcessor(CreoleParserContext contenxt, CreoleTokenRange tokens) + private CreoleRichTextElementProcessor _GetBaseElementProcessor(CreoleParserContext contenxt, TokenRange tokens) => new CreoleLineBreakElementProcessor( _context, tokens, @@ -61,7 +62,7 @@ private CreoleRichTextElementProcessor _GetBaseElementProcessor(CreoleParserCont ) ); - private CreoleRichTextElementProcessor _GetHyperlinkBaseElementProcessor(CreoleParserContext contenxt, CreoleTokenRange tokens) + private CreoleRichTextElementProcessor _GetHyperlinkBaseElementProcessor(CreoleParserContext contenxt, TokenRange tokens) => new CreoleLineBreakElementProcessor( _context, tokens, @@ -74,20 +75,20 @@ private CreoleRichTextElementProcessor _GetHyperlinkBaseElementProcessor(CreoleP ) ); - private IEnumerable _GetCreoleElements(CreoleTokenRange tokens, IEnumerable elementsData) + private IEnumerable _GetCreoleElements(TokenRange tokens, IEnumerable elementsData) => _GetCreoleElements(tokens, _GetRootNodesFrom(tokens, elementsData)); - private IEnumerable _GetCreoleElements(CreoleTokenRange tokens, IEnumerable nodesData) + private IEnumerable _GetCreoleElements(TokenRange tokens, IEnumerable nodesData) => _GetCreoleElements(tokens, 0, tokens.Count, nodesData); - private IEnumerable _GetCreoleElements(CreoleTokenRange tokens, int startIndex, int endIndex, IEnumerable nodesData) + private IEnumerable _GetCreoleElements(TokenRange tokens, int startIndex, int endIndex, IEnumerable nodesData) { var elements = new List(); var subRangeStartIndex = startIndex; foreach (var nodeData in nodesData) { if (subRangeStartIndex < nodeData.StartIndex) - elements.Add(new CreoleTextElement(CreoleTokenRangeHelper.GetPlainText(tokens.SubRange(subRangeStartIndex, (nodeData.StartIndex - subRangeStartIndex))))); + elements.Add(new CreoleTextElement(TokenRangeHelper.GetPlainText(tokens.SubRange(subRangeStartIndex, (nodeData.StartIndex - subRangeStartIndex))))); elements.Add(_GetCreoleElementFrom(tokens, nodeData)); subRangeStartIndex = nodeData.EndIndex; @@ -95,13 +96,13 @@ private IEnumerable _GetCreoleElements(CreoleTokenRange tokens, i if (subRangeStartIndex < endIndex) { var subRange = tokens.SubRange(subRangeStartIndex, (endIndex - subRangeStartIndex)); - elements.Add(new CreoleTextElement(CreoleTokenRangeHelper.GetPlainText(subRange))); + elements.Add(new CreoleTextElement(TokenRangeHelper.GetPlainText(subRange))); } return elements; } - private IEnumerable _GetRootNodesFrom(CreoleTokenRange tokens, IEnumerable elementsData) + private IEnumerable _GetRootNodesFrom(TokenRange tokens, IEnumerable elementsData) { var rootNodes = new List(); var visitedElementTypes = new List(10); @@ -146,7 +147,7 @@ private CreoleRichTextElementNodeData _AddIndexOffset(int offset, CreoleRichText nodeData.ChildNodes ); - private IEnumerable _GetHyperlinkContentElementNodesData(CreoleTokenRange tokens, IEnumerable excludedElementTypes) + private IEnumerable _GetHyperlinkContentElementNodesData(TokenRange tokens, IEnumerable excludedElementTypes) { var baseElementsData = new List(); using (var baseElementProcessor = _GetHyperlinkBaseElementProcessor(_context, tokens)) @@ -168,7 +169,7 @@ private IEnumerable _GetHyperlinkContentElementNo return _GetRootNodesFrom(tokens, elementsData); } - private CreoleElement _GetCreoleElementFrom(CreoleTokenRange tokens, CreoleRichTextElementNodeData nodeData) + private CreoleElement _GetCreoleElementFrom(TokenRange tokens, CreoleRichTextElementNodeData nodeData) { CreoleElement result = null; @@ -236,20 +237,20 @@ private CreoleElement _GetCreoleElementFrom(CreoleTokenRange tokens, CreoleRichT return result; } - private string _GetUrlFrom(CreoleTokenRange tokens, CreoleRichTextElementNodeData richTextElementData) + private string _GetUrlFrom(TokenRange tokens, CreoleRichTextElementNodeData richTextElementData) { var urlStartIndex = richTextElementData.UrlStartIndex; var urlEndIdnex = richTextElementData.UrlEndIndex; var urlRange = tokens.SubRange(urlStartIndex, (urlEndIdnex - urlStartIndex)); - return CreoleTokenRangeHelper.GetPlainText(urlRange); + return TokenRangeHelper.GetPlainText(urlRange); } - private string _GetContentFrom(CreoleTokenRange tokens, CreoleRichTextElementNodeData richTextElementData) + private string _GetContentFrom(TokenRange tokens, CreoleRichTextElementNodeData richTextElementData) { var contentStartIndex = richTextElementData.ContentStartIndex; var contentEndIdnex = richTextElementData.ContentEndIndex; var contentRange = tokens.SubRange(contentStartIndex, (contentEndIdnex - contentStartIndex)); - return CreoleTokenRangeHelper.GetPlainText(contentRange); + return TokenRangeHelper.GetPlainText(contentRange); } private static bool _Contains(CreoleRichTextElementData parent, CreoleRichTextElementData child) @@ -258,10 +259,10 @@ private static bool _Contains(CreoleRichTextElementData parent, CreoleRichTextEl private static bool _Contains(CreoleRichTextElementNodeData parent, CreoleRichTextElementNodeData child) => (parent.ContentStartIndex <= child.StartIndex && child.EndIndex <= parent.ContentEndIndex); - private IElementDataIterator _GetStyleElementIterator(CreoleParserContext context, CreoleTokenRange tokens, IEnumerable baseElementsData) + private IElementDataIterator _GetStyleElementIterator(CreoleParserContext context, TokenRange tokens, IEnumerable baseElementsData) => _GetStyleElementIterator(context, tokens, baseElementsData, null); - private IElementDataIterator _GetStyleElementIterator(CreoleParserContext context, CreoleTokenRange tokens, IEnumerable baseElementsData, IEnumerable excludedElementTypes) + private IElementDataIterator _GetStyleElementIterator(CreoleParserContext context, TokenRange tokens, IEnumerable baseElementsData, IEnumerable excludedElementTypes) { var processors = new List(); if (excludedElementTypes == null) diff --git a/Mup/Creole/ElementProcessors/RichText/CreoleStrongElementProcessor.cs b/Mup/Creole/ElementProcessors/RichText/CreoleStrongElementProcessor.cs index ce8ac7f..4def300 100644 --- a/Mup/Creole/ElementProcessors/RichText/CreoleStrongElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/RichText/CreoleStrongElementProcessor.cs @@ -1,3 +1,4 @@ +using Mup.Scanner; using System.Collections.Generic; using static Mup.Creole.CreoleTokenCode; @@ -5,12 +6,12 @@ namespace Mup.Creole.ElementProcessors.RichText { internal class CreoleStrongElementProcessor : CreoleStyleElementProcessor { - internal CreoleStrongElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + internal CreoleStrongElementProcessor(CreoleParserContext context, TokenRange tokens) : base(context, tokens) { } - internal CreoleStrongElementProcessor(CreoleParserContext context, CreoleTokenRange tokens, IEnumerable baseElements) + internal CreoleStrongElementProcessor(CreoleParserContext context, TokenRange tokens, IEnumerable baseElements) : base(context, tokens, baseElements) { } diff --git a/Mup/Creole/ElementProcessors/RichText/CreoleStyleElementProcessor.cs b/Mup/Creole/ElementProcessors/RichText/CreoleStyleElementProcessor.cs index 37c99bd..ec61f51 100644 --- a/Mup/Creole/ElementProcessors/RichText/CreoleStyleElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/RichText/CreoleStyleElementProcessor.cs @@ -1,3 +1,4 @@ +using Mup.Scanner; using System.Collections.Generic; namespace Mup.Creole.ElementProcessors.RichText @@ -17,12 +18,12 @@ private enum State : byte private int _elementEndIndex; private State _state = State.NoElement; - internal CreoleStyleElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + internal CreoleStyleElementProcessor(CreoleParserContext context, TokenRange tokens) : base(context, tokens) { } - internal CreoleStyleElementProcessor(CreoleParserContext context, CreoleTokenRange tokens, IEnumerable baseElements) + internal CreoleStyleElementProcessor(CreoleParserContext context, TokenRange tokens, IEnumerable baseElements) : base(context, tokens, baseElements) { } diff --git a/Mup/Creole/ElementProcessors/RichText/CreoleUrlElementProcessor.cs b/Mup/Creole/ElementProcessors/RichText/CreoleUrlElementProcessor.cs index 9582496..1b5f0ad 100644 --- a/Mup/Creole/ElementProcessors/RichText/CreoleUrlElementProcessor.cs +++ b/Mup/Creole/ElementProcessors/RichText/CreoleUrlElementProcessor.cs @@ -1,3 +1,4 @@ +using Mup.Scanner; using static Mup.Creole.CreoleTokenCode; namespace Mup.Creole.ElementProcessors.RichText @@ -23,12 +24,12 @@ private enum State : byte private int _contentEndIndex; private State _state = State.NoElement; - protected CreoleUrlElementProcessor(CreoleParserContext context, CreoleTokenRange tokens) + protected CreoleUrlElementProcessor(CreoleParserContext context, TokenRange tokens) : base(context, tokens) { } - protected CreoleUrlElementProcessor(CreoleParserContext context, CreoleTokenRange tokens, CreoleRichTextElementProcessor baseElementProcessor) + protected CreoleUrlElementProcessor(CreoleParserContext context, TokenRange tokens, CreoleRichTextElementProcessor baseElementProcessor) : base(context, tokens, baseElementProcessor) { } diff --git a/Mup/CreoleParser.cs b/Mup/CreoleParser.cs index a6bd561..2e1e00d 100644 --- a/Mup/CreoleParser.cs +++ b/Mup/CreoleParser.cs @@ -1,6 +1,7 @@ using Mup.Creole; using Mup.Creole.ElementProcessors; using Mup.Creole.Elements; +using Mup.Scanner; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -13,7 +14,7 @@ public class CreoleParser : IMarkupParser { private const int _defaultBufferSize = 1024; - private delegate CreoleElementProcessor CreoleElementProcessorFactory(CreoleParserContext context, CreoleTokenRange tokens); + private delegate CreoleElementProcessor CreoleElementProcessorFactory(CreoleParserContext context, TokenRange tokens); private static readonly ReadOnlyCollection _creoleElementProcessorFactories = new ReadOnlyCollection( @@ -77,10 +78,10 @@ public IParseTree Parse(TextReader reader, int bufferSize) return parseTree; } - private IParseTree _Parse(IReadOnlyList tokens) + private IParseTree _Parse(IReadOnlyList> tokens) { var context = new CreoleParserContext(Options.InlineHyperlinkProtocols); - var tokenRange = new CreoleTokenRange(tokens); + var tokenRange = new TokenRange(tokens); var elementInfos = new LinkedList(); diff --git a/Mup/Scanner/TokenRange.cs b/Mup/Scanner/TokenRange.cs new file mode 100644 index 0000000..77bfce0 --- /dev/null +++ b/Mup/Scanner/TokenRange.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Mup.Scanner +{ + internal class TokenRange : IReadOnlyList> + { + private readonly IReadOnlyList> _tokens; + private readonly int _startIndex; + + public TokenRange(IReadOnlyList> tokens) + : this(tokens, 0, tokens.Count) + { + } + + public TokenRange(IReadOnlyList> tokens, int rangeStartIndex, int rangeLength) + { + if (tokens == null) + throw new ArgumentNullException(nameof(tokens)); + if (rangeStartIndex < 0 || rangeStartIndex > tokens.Count) + throw new ArgumentOutOfRangeException(nameof(rangeLength), "Start index must less than the length of the source collection and greater than zero."); + if (tokens.Count < rangeStartIndex + rangeLength) + throw new ArgumentOutOfRangeException(nameof(rangeLength), "The sum of the range start and length must be less or equal to the source collection length."); + + _tokens = tokens; + _startIndex = rangeStartIndex; + Count = rangeLength; + } + + public TokenRange SubRange(int startIndex, int length) + => new TokenRange(_tokens, _startIndex + startIndex, length); + + public int Count { get; } + + public Token this[int index] + => _tokens[_startIndex + index]; + + public IEnumerator> GetEnumerator() + { + for (var index = 0; index < Count; index++) + yield return _tokens[_startIndex + index]; + } + + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); + } +} \ No newline at end of file diff --git a/Mup/Creole/CreoleTokenRangeHelper.cs b/Mup/Scanner/TokenRangeHelper.cs similarity index 63% rename from Mup/Creole/CreoleTokenRangeHelper.cs rename to Mup/Scanner/TokenRangeHelper.cs index e6de89c..0201004 100644 --- a/Mup/Creole/CreoleTokenRangeHelper.cs +++ b/Mup/Scanner/TokenRangeHelper.cs @@ -1,10 +1,10 @@ using System.Text; -namespace Mup.Creole +namespace Mup.Scanner { - internal static class CreoleTokenRangeHelper + internal static class TokenRangeHelper { - internal static string GetPlainText(CreoleTokenRange tokens) + internal static string GetPlainText(TokenRange tokens) { var stringBuilder = new StringBuilder(); foreach (var token in tokens)