示例#1
0
        private Token CheckItalic(LexerContext ctx)
        {
            string lookahead = this.PeekChar(Italic.Length);

            if (lookahead == Italic)
            {
                return new Token {
                           Type = TokenType.Italic, Value = ctx.Peek ? lookahead : this.ConsumeChar(Italic.Length)
                }
            }
            ;


            lookahead = this.PeekChar(Italic2.Length);

            if (lookahead == Italic2)
            {
                return new Token {
                           Type = TokenType.Italic, Value = ctx.Peek ? lookahead : this.ConsumeChar(Italic2.Length)
                }
            }
            ;

            return(null);
        }
示例#2
0
        private Token CheckCodeBlockLang(LexerContext ctx)
        {
            string lookahead = this.PeekChar();
            Token  last      = this.Output.LastOrDefault();

            if (last == null || last.Type != TokenType.CodeBlock || lookahead == null || lookahead == "\n")
            {
                return(null);
            }

            lookahead = "";
            int    q   = 1;
            string tmp = null;

            while ((tmp = this.PeekChar(q)) != lookahead && !tmp.EndsWith("\n"))
            {
                lookahead = tmp;
                q++;
            }

            if (!ctx.Peek)
            {
                this.ConsumeChar(q - 1);
            }

            return(new Token()
            {
                Type = TokenType.CodeBlockLang, Value = lookahead
            });
        }
示例#3
0
        private Token CheckCodeBlock(LexerContext ctx)
        {
            if (!this.IsValidBlockStart())
            {
                return(null);
            }

            string lookahead = this.PeekChar(Codeblock.Length);

            if (lookahead != Codeblock)
            {
                return(null);
            }


            // Check for more backticks to see if it is a header
            string str = this.PeekChar(Codeblock.Length + 1);

            if (str.Length == Codeblock.Length + 1 && str.Last() == Codeblock[0])
            {
                return(null);
            }

            return(new Token {
                Type = TokenType.CodeBlock, Value = ctx.Peek ? lookahead : this.ConsumeChar(Codeblock.Length)
            });
        }
示例#4
0
        private Token CheckLabeledListItem(LexerContext ctx)
        {
            if (!this.IsValidBlockStart())
            {
                return(null);
            }

            string lookahead = this.PeekChar(3);

            if (lookahead != null && char.IsLetter(lookahead[0]) && (lookahead.EndsWith(". ") || lookahead.EndsWith(") ")))
            {
                string originalValue = lookahead;
                lookahead = "- ";

                if (!ctx.Peek)
                {
                    this.ConsumeChar(3);
                }

                return(new Token {
                    Type = TokenType.ListItem, Value = lookahead, OriginalValue = originalValue
                });
            }
            return(null);
        }
示例#5
0
        private Token CheckDmlCodeBlock(LexerContext ctx)
        {
            if (!this.IsValidBlockStart())
            {
                return(null);
            }

            string lookahead = this.PeekChar(DmlCodeblock.Length);

            if (lookahead != DmlCodeblock)
            {
                return(null);
            }

            string str = this.PeekChar(DmlCodeblock.Length + 1);

            if (str.Length == DmlCodeblock.Length + 1 && str.Last() == DmlCodeblock[0])
            {
                return(null);
            }

            return(new Token {
                Type = TokenType.CodeBlock, Value = ctx.Peek ? lookahead : this.ConsumeChar(DmlCodeblock.Length)
            });
        }
示例#6
0
        private Token CheckEscapeBlock(LexerContext ctx)
        {
            string lookahead = this.PeekChar(2);

            if (lookahead == EscapeBlock && !this.LastIs(TokenType.Escape))
            {
                return new Token {
                           Type = TokenType.EscapeBlock, Value = ctx.Peek ? lookahead : this.ConsumeChar(2)
                }
            }
            ;

            return(null);
        }
示例#7
0
        private Token CheckColon(LexerContext ctx)
        {
            string lookahead = this.PeekChar(Colon.Length);

            if (lookahead == Colon)
            {
                return new Token {
                           Type = TokenType.Colon, Value = ctx.Peek ? lookahead : this.ConsumeChar(Colon.Length)
                }
            }
            ;

            return(null);
        }
示例#8
0
        private Token CheckReference(LexerContext ctx)
        {
            string lookahead = this.PeekChar();

            if (this.IsValidBlockStart() && lookahead == Reference)
            {
                return new Token {
                           Type = TokenType.Reference, Value = ctx.Peek ? lookahead : this.ConsumeChar()
                }
            }
            ;

            return(null);
        }
示例#9
0
        private Token CheckListItem(LexerContext ctx)
        {
            string lookahead = this.PeekChar(2);

            if (this.IsValidBlockStart() && lookahead.Length == 2 && Lists.Contains(lookahead[0].ToString()) && lookahead[1] == ' ')
            {
                return new Token {
                           Type = TokenType.ListItem, Value = ctx.Peek ? lookahead : this.ConsumeChar(2)
                }
            }
            ;

            return(null);
        }
示例#10
0
        private Token CheckEscape(LexerContext ctx)
        {
            string lookahead = this.PeekChar();

            if (lookahead == Escape)
            {
                return new Token {
                           Type = TokenType.Escape, Value = ctx.Peek ? lookahead : this.ConsumeChar()
                }
            }
            ;

            return(null);
        }
示例#11
0
        private Token CheckTodoListItem(LexerContext ctx)
        {
            string lookahead = this.PeekChar(4);

            if (this.IsValidBlockStart() && (lookahead == "[ ] " || lookahead == "[x] " || lookahead == "[X] "))
            {
                return new Token {
                           Type = TokenType.ListItem, Value = ctx.Peek ? lookahead : ConsumeChar(4)
                }
            }
            ;

            return(null);
        }
示例#12
0
        private Token CheckStrikethrough(LexerContext ctx)
        {
            string lookahead = this.PeekChar(Strikethrough.Length);

            if (lookahead == Strikethrough)
            {
                return new Token {
                           Type = TokenType.Strikethrough, Value = ctx.Peek ? lookahead : this.ConsumeChar(Strikethrough.Length)
                }
            }
            ;

            return(null);
        }
示例#13
0
        private Token CheckUnderlined(LexerContext ctx)
        {
            string lookahead = this.PeekChar(Underline.Length);

            if (lookahead == Underline)
            {
                return new Token {
                           Type = TokenType.Underlined, Value = ctx.Peek ? lookahead : this.ConsumeChar(Underline.Length)
                }
            }
            ;

            return(null);
        }
示例#14
0
        private Token CheckHeader(LexerContext ctx)
        {
            string lookahead = this.PeekChar(1);

            if (!Headers.Contains(lookahead))
            {
                return(null);
            }

            if (!this.IsValidBlockStart())
            {
                return(null);
            }

            if (this.Output.Count == 0)
            {
                return(null);
            }

            // If previous line is just a newline, it is not a header
            if (this.Output.Count >= 2 && this.Output.Last().Type == TokenType.NewLine && this.Output[this.Output.Count - 2].Type == TokenType.NewLine)
            {
                return(null);
            }

            string tokenval = "";
            string tmp;

            while ((tmp = this.PeekChar()) == lookahead || tmp == " ")
            {
                tokenval += this.ConsumeChar();
            }

            if ((tmp == NewLine || this.IsEndOfInput()) && tokenval.Length >= 4)
            {
                if (ctx.Peek)
                {
                    this.Pointer -= tokenval.Length;
                }

                return(new Token {
                    Type = TokenType.HeaderStart, Value = tokenval
                });
            }

            this.Pointer -= tokenval.Length;

            return(null);
        }
示例#15
0
        private Token CheckPreformatted(LexerContext ctx)
        {
            Token last = this.Output.LastOrDefault();

            if (last != null && last.Type == TokenType.Indentation && this.CheckListItem(new LexerContext()
            {
                Peek = true
            }) == null)
            {
                return new Token {
                           Type = TokenType.Preformatted, Value = ""
                }
            }
            ;

            return(null);
        }
示例#16
0
        private Token CheckIndentation(LexerContext ctx)
        {
            bool isValidBlockStart = this.IsValidBlockStart();

            // Check tab
            string lookahead = this.PeekChar();

            if (isValidBlockStart && lookahead == Indent)
            {
                if (!ctx.Peek)
                {
                    this.ConsumeChar();
                }

                return(new Token {
                    Type = TokenType.Indentation, Value = "    "
                });
            }

            // Check at least 4 white spaces
            lookahead = PeekChar(4);

            // If lookahead is null or it does not contain at least 4 chars, it is not a pre node
            if (lookahead == null || lookahead.Length < 4)
            {
                return(null);
            }

            // Cannot start a pre node if it is not a valid block start
            if (!isValidBlockStart)
            {
                return(null);
            }

            // If all chars are white space and are not new lines, it is an indent token
            if (lookahead.All(c => char.IsWhiteSpace(c) && c != '\n'))
            {
                return new Token {
                           Type = TokenType.Indentation, Value = ctx.Peek ? lookahead : this.ConsumeChar(4)
                }
            }
            ;

            return(null);
        }
示例#17
0
        private Token CheckThematicBreak(LexerContext ctx)
        {
            if (!this.IsValidBlockStart())
            {
                return(null);
            }

            string lookahead = this.PeekChar(ThematicBreak.Length);

            if (lookahead == ThematicBreak)
            {
                return new Token {
                           Type = TokenType.ThematicBreak, Value = ctx.Peek ? lookahead : this.ConsumeChar(ThematicBreak.Length)
                }
            }
            ;

            return(null);
        }
示例#18
0
        private Token CheckBlockquote(LexerContext ctx)
        {
            if (!this.IsValidBlockStart())
            {
                return(null);
            }

            string lookahead = this.PeekChar();

            if (lookahead != Blockquote)
            {
                return(null);
            }

            int    q   = 1;
            string tmp = null;

            lookahead = "";
            do
            {
                if (this.IsEndOfInput(q))
                {
                    break;
                }

                tmp = this.PeekChar(q);

                if (tmp[q - 1] == Blockquote[0])
                {
                    q++;
                    lookahead = tmp;
                    continue;
                }

                break;
            } while (true);

            return(new Token {
                Type = TokenType.Blockquote,
                Value = ctx.Peek ? lookahead : this.ConsumeChar(Math.Max(1, q - 1))
            });
        }
示例#19
0
        private Token CheckBold(LexerContext ctx)
        {
            string lookahead = this.PeekChar();

            if (lookahead == BoldOpen)
            {
                return new Token {
                           Type = TokenType.BoldOpen, Value = ctx.Peek ? lookahead : this.ConsumeChar()
                }
            }
            ;

            if (lookahead == BoldClose)
            {
                return new Token {
                           Type = TokenType.BoldClose, Value = ctx.Peek ? lookahead : this.ConsumeChar()
                }
            }
            ;

            return(null);
        }
示例#20
0
        private Token CheckNumberedListItem(LexerContext ctx)
        {
            if (!this.IsValidBlockStart())
            {
                return(null);
            }

            int    i         = 1;
            string lookahead = "";

            while ((lookahead = this.PeekChar(i)).Length > 0 && !this.IsEndOfInput(i) && lookahead.All(c => char.IsDigit(c)))
            {
                i++;
            }

            string tmp = this.PeekChar(++i); // The NOT digit that broke the previos while plus the needed space

            if (tmp == lookahead)            // End of file
            {
                return(null);
            }

            if (tmp.EndsWith(". ") || tmp.EndsWith(") "))
            {
                lookahead = "# ";

                if (!ctx.Peek)
                {
                    this.ConsumeChar(i);
                }

                return(new Token {
                    Type = TokenType.ListItem, Value = lookahead, OriginalValue = tmp
                });
            }

            return(null);
        }
示例#21
0
        private Token CheckNewline(LexerContext ctx)
        {
            var lookahead = this.PeekChar(DoubleNewLine.Length);

            if (lookahead == DoubleNewLine)
            {
                return new Token {
                           Type = TokenType.DoubleNewLine, Value = ctx.Peek ? lookahead : this.ConsumeChar(DoubleNewLine.Length)
                }
            }
            ;

            lookahead = this.PeekChar();

            if (lookahead == NewLine)
            {
                return(new Token {
                    Type = TokenType.NewLine, Value = ctx.Peek ? lookahead : this.ConsumeChar()
                });
            }

            return(null);
        }
示例#22
0
        private Token CheckImage(LexerContext ctx)
        {
            string lookahead    = this.PeekChar(ImgOpen.Length);
            bool   lastIsEscape = this.LastIs(TokenType.Escape);

            if (lookahead == ImgOpen && !lastIsEscape)
            {
                return new Token {
                           Type = TokenType.ImageStart, Value = ctx.Peek ? lookahead : this.ConsumeChar(ImgOpen.Length)
                }
            }
            ;

            if (lookahead == ImgClose && !lastIsEscape)
            {
                return new Token {
                           Type = TokenType.ImageEnd, Value = ctx.Peek ? lookahead : this.ConsumeChar(ImgClose.Length)
                }
            }
            ;

            return(null);
        }
示例#23
0
        private Token NextMarkupToken(LexerContext ctx)
        {
            if (this.PeekChar() == null)
            {
                return(null);
            }

            return(this.CheckNewline(ctx)
                   // Block
                   ?? this.CheckIndentation(ctx)
                   ?? this.CheckThematicBreak(ctx)
                   ?? this.CheckListItem(ctx)
                   ?? this.CheckTodoListItem(ctx)
                   ?? this.CheckNumberedListItem(ctx)
                   ?? this.CheckLabeledListItem(ctx)
                   ?? this.CheckPreformatted(ctx)
                   ?? this.CheckBlockquote(ctx)
                   ?? this.CheckHeader(ctx)
                   ?? this.CheckCodeBlock(ctx)
                   ?? this.CheckDmlCodeBlock(ctx)
                   ?? this.CheckCodeBlockLang(ctx)
                   ?? this.CheckEscapeBlock(ctx)
                   ?? this.CheckReference(ctx)
                   // Inline elements
                   ?? this.CheckLt(ctx)
                   ?? this.CheckEscape(ctx)
                   ?? this.CheckColon(ctx)
                   ?? this.CheckPipe(ctx)
                   ?? this.CheckLink(ctx)
                   ?? this.CheckImage(ctx)
                   ?? this.CheckBold(ctx)
                   ?? this.CheckInlineCode(ctx)
                   ?? this.CheckItalic(ctx)
                   ?? this.CheckUnderlined(ctx)
                   ?? this.CheckStrikethrough(ctx));
        }