示例#1
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (context.IsInParagraph)
            {
                return(null);
            }
            if (Code != Regexes.Block.Code)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(CodeMatcher);

            if (match?.Length > 0)
            {
                var sourceInfo = context.Consume(match.Length);
                var capStr     = Regexes.Lexers.LeadingWhiteSpaces.Replace(sourceInfo.Markdown, string.Empty);
                if (parser.Options.Pedantic)
                {
                    return(new MarkdownCodeBlockToken(this, parser.Context, capStr, null, sourceInfo));
                }
                else
                {
                    return(new MarkdownCodeBlockToken(this, parser.Context, Regexes.Lexers.TailingEmptyLine.Replace(capStr, string.Empty), null, sourceInfo));
                }
            }
            return(null);
        }
示例#2
0
        public IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (YamlHeader != YamlHeaderRegex)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(YamlHeaderMatcher);

            if (match?.Length > 0)
            {
                // ---
                // a: b
                // ---
                var value = match["yaml"].GetValue();
                try
                {
                    using (StringReader reader = new StringReader(value))
                    {
                        var result = YamlUtility.Deserialize <Dictionary <string, object> >(reader);
                        if (result == null)
                        {
                            return(null);
                        }
                    }
                }
                catch (Exception)
                {
                    Logger.LogInfo("Invalid yaml header.", file: context.File, line: context.LineNumber.ToString());
                    return(null);
                }
                var sourceInfo = context.Consume(match.Length);
                return(new DfmYamlHeaderBlockToken(this, parser.Context, value, sourceInfo));
            }
            return(null);
        }
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (Heading != Regexes.Block.Heading || parser.Options.LegacyMode)
            {
                return(OldMatch(parser, context));
            }
            var match = context.Match(HeadingMatcher);

            if (match?.Length > 0)
            {
                var sourceInfo = context.Consume(match.Length);
                return(new TwoPhaseBlockToken(
                           this,
                           parser.Context,
                           sourceInfo,
                           (p, t) => new MarkdownHeadingBlockToken(
                               t.Rule,
                               t.Context,
                               p.TokenizeInline(t.SourceInfo.Copy(match["text"].GetValue())),
                               Regex.Replace(match["text"].GetValue().ToLower(), @"[^\p{L}\p{N}\- ]+", "").Replace(' ', '-'),
                               match["level"].Count,
                               t.SourceInfo)));
            }
            return(null);
        }
示例#4
0
        public IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (Include != _incRegex)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(IncludeMatcher);

            if (match?.Length > 0)
            {
                var sourceInfo = context.Consume(match.Length);

                // [!include[name](path "title")]
                var path  = match["path"].GetValue();
                var name  = match["name"].GetValue();
                var title = match.GetGroup("title")?.GetValue() ?? string.Empty;

                return(new DfmIncludeBlockToken(
                           this,
                           parser.Context,
                           StringHelper.UnescapeMarkdown(path),
                           StringHelper.UnescapeMarkdown(name),
                           StringHelper.UnescapeMarkdown(title),
                           sourceInfo));
            }
            return(null);
        }
示例#5
0
        public override IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (parser.Options.LegacyMode)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(DfmFencesMatcher);

            if (match?.Length > 0)
            {
                var sourceInfo = context.Consume(match.Length);

                // [!code-lang[name](href "optionalTitle")]
                var name  = StringHelper.UnescapeMarkdown(match["name"].GetValue());
                var href  = StringHelper.UnescapeMarkdown(match["href"].GetValue());
                var lang  = match.GetGroup("lang")?.GetValue() ?? string.Empty;
                var title = StringHelper.UnescapeMarkdown(match.GetGroup("title")?.GetValue() ?? string.Empty);
                var queryStringAndFragment = UriUtility.GetQueryStringAndFragment(href);
                var path            = UriUtility.GetPath(href);
                var pathQueryOption =
                    !string.IsNullOrEmpty(queryStringAndFragment) ?
                    ParsePathQueryString(queryStringAndFragment.Remove(1), queryStringAndFragment.Substring(1)) :
                    null;
                return(new DfmFencesBlockToken(this, parser.Context, name, path, sourceInfo, lang, title, pathQueryOption));
            }
            return(null);
        }
示例#6
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = context.Match(_sdnsMatcher);

            return(match?.Length > 0 ? new SDNSBlockToken(
                       this,
                       parser.Context,
                       context.Consume(match.Length),
                       match.GetGroup("text").Value.GetValue()) : null);
        }
示例#7
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (context.IsInParagraph)
            {
                return(null);
            }
            if (Html != Regexes.Block.Html)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(HtmlMatcher);

            if (match?.Length > 0)
            {
                var sourceInfo = context.Consume(match.Length);

                var  elementName = match.GetGroup("element")?.GetValue();
                bool isPre       = parser.Options.Sanitizer == null &&
                                   ("pre".Equals(elementName, StringComparison.OrdinalIgnoreCase) || "script".Equals(elementName, StringComparison.OrdinalIgnoreCase) || "style".Equals(elementName, StringComparison.OrdinalIgnoreCase));
                if (parser.Options.Sanitize)
                {
                    return(new TwoPhaseBlockToken(
                               this,
                               parser.Context,
                               sourceInfo,
                               (p, t) => new MarkdownParagraphBlockToken(
                                   t.Rule,
                                   t.Context,
                                   p.TokenizeInline(t.SourceInfo),
                                   t.SourceInfo)));
                }
                else
                {
                    return(new TwoPhaseBlockToken(
                               this,
                               parser.Context,
                               sourceInfo,
                               (p, t) => new MarkdownHtmlBlockToken(
                                   t.Rule,
                                   t.Context,
                                   isPre ?
                                   new InlineContent(
                                       ImmutableArray.Create <IMarkdownToken>(
                                           new MarkdownRawToken(
                                               this,
                                               parser.Context,
                                               t.SourceInfo)))
                            :
                                   p.TokenizeInline(t.SourceInfo),
                                   t.SourceInfo)));
                }
            }
            return(null);
        }
示例#8
0
        public IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = context.Match(_FencesMatcher);

            if (match?.Length > 0)
            {
                var sourceInfo = context.Consume(match.Length);
                return(new MarkdownCodeBlockToken(this, parser.Context, match["code"].GetValue(), match["lang"].GetValue(), sourceInfo));
            }
            return(null);
        }
示例#9
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (Newline != Regexes.Block.Newline)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(NewLineMatcher);

            if (match?.Length > 0)
            {
                return(new MarkdownNewLineBlockToken(this, parser.Context, context.Consume(match.Length)));
            }
            return(null);
        }
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (parser.Options.LegacyMode)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(BrMatcher);

            if (match?.Length > 0)
            {
                var sourceInfo = context.Consume(match.Length);
                return(new MarkdownBrInlineToken(this, parser.Context, sourceInfo));
            }
            return(null);
        }
示例#11
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (Text != Regexes.Block.Text)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(TextMatcher);

            if (match?.Length > 0)
            {
                var sourceInfo = context.Consume(match.Length);
                return(new MarkdownTextToken(this, parser.Context, sourceInfo.Markdown, sourceInfo));
            }
            return(null);
        }
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (PreElement != Regexes.Block.PreElement || parser.Options.LegacyMode)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(PreElementMatcher);

            if (match?.Length > 0)
            {
                var sourceInfo = context.Consume(match.Length);
                return(new MarkdownRawToken(this, parser.Context, sourceInfo));
            }
            return(null);
        }
示例#13
0
        public IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = context.Match(_FencesMatcher);

            if (match?.Length > 0)
            {
                var sourceInfo = context.Consume(match.Length);
                var code       = match["code"].GetValue();
                if (match["spaces"].Count > 0)
                {
                    code = Regex.Replace(code, "^ {1," + match["spaces"].Count.ToString() + "}", string.Empty, RegexOptions.Multiline);
                }
                return(new MarkdownCodeBlockToken(this, parser.Context, code, match["lang"].GetValue(), sourceInfo));
            }
            return(null);
        }
示例#14
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (!parser.Context.Variables.ContainsKey(MarkdownBlockContext.IsBlockQuote) || !(bool)parser.Context.Variables[MarkdownBlockContext.IsBlockQuote])
            {
                return(null);
            }
            if (DfmNoteRegex != _dfmNoteRegex || parser.Options.LegacyMode)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(NoteMatcher);

            if (match?.Length > 0)
            {
                var sourceInfo = context.Consume(match.Length);
                return(new DfmNoteBlockToken(this, parser.Context, match["notetype"].GetValue(), sourceInfo.Markdown, sourceInfo));
            }
            return(null);
        }
示例#15
0
        public IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (!parser.Context.Variables.ContainsKey(MarkdownBlockContext.IsBlockQuote) || !(bool)parser.Context.Variables[MarkdownBlockContext.IsBlockQuote])
            {
                return(null);
            }
            if (VideoRegex != _videoRegex || parser.Options.LegacyMode)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(VideoMatcher);

            if (match?.Length > 0)
            {
                var sourceInfo = context.Consume(match.Length);
                return(new DfmVideoBlockToken(this, parser.Context, StringHelper.UnescapeMarkdown(match["link"].GetValue()), sourceInfo));
            }
            return(null);
        }
示例#16
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (Def != Regexes.Block.Def)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(DefMatcher);

            if (match?.Length > 0)
            {
                var sourceInfo = context.Consume(match.Length);
                parser.Links[match["key"].GetValue().ToLower()] = new LinkObj
                {
                    Href  = match["href"].GetValue(),
                    Title = match.GetGroup("title")?.GetValue() ?? string.Empty,
                };
                return(new MarkdownIgnoreToken(this, parser.Context, sourceInfo));
            }
            return(null);
        }
示例#17
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (!parser.Context.Variables.ContainsKey(MarkdownBlockContext.IsBlockQuote) || !(bool)parser.Context.Variables[MarkdownBlockContext.IsBlockQuote])
            {
                return(null);
            }
            if (parser.Options.LegacyMode)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(_SectionMatcher);

            if (match?.Length > 0)
            {
                var sourceInfo = context.Consume(match.Length);
                var attributes = ExtractAttibutes(match.GetGroup("attributes")?.GetValue() ?? string.Empty);
                return(new DfmSectionBlockToken(this, parser.Context, attributes, sourceInfo));
            }
            return(null);
        }
示例#18
0
                public IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
                {
                    var match = context.Match(HeadingMatcher);

                    if (match?.Length > 0)
                    {
                        var sourceInfo = context.Consume(match.Length);
                        return(new TwoPhaseBlockToken(
                                   this,
                                   parser.Context,
                                   sourceInfo,
                                   (p, t) => new MarkdownHeadingBlockToken(
                                       t.Rule,
                                       t.Context,
                                       p.TokenizeInline(t.SourceInfo.Copy(match["text"].GetValue())),
                                       match["id"].GetValue(),
                                       match["level"].Count,
                                       t.SourceInfo)));
                    }
                    return(null);
                }
示例#19
0
        public IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (YamlHeader != YamlHeaderRegex || parser.Options.LegacyMode)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(YamlHeaderMatcher);

            if (match?.Length > 0)
            {
                // ---
                // a: b
                // ---
                var value = match["yaml"].GetValue();
                try
                {
                    using (StringReader reader = new StringReader(value))
                    {
                        var result = YamlUtility.Deserialize <Dictionary <string, object> >(reader);
                        if (result == null)
                        {
                            return(null);
                        }
                    }
                }
                catch (YamlException invalidYamlHeaderException)
                {
                    LogMessage(invalidYamlHeaderException, context);
                    return(null);
                }
                catch (Exception)
                {
                    LogMessage(context);
                    return(null);
                }
                var sourceInfo = context.Consume(match.Length);
                return(new DfmYamlHeaderBlockToken(this, parser.Context, value, sourceInfo));
            }
            return(null);
        }
示例#20
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (Blockquote != Regexes.Block.Blockquote)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(BlockquoteMatcher);

            if (match?.Length > 0)
            {
                var sourceInfo  = context.Consume(match.Length);
                var capStr      = LeadingBlockquote.Replace(sourceInfo.Markdown, string.Empty);
                var blockTokens = parser.Tokenize(sourceInfo.Copy(capStr));
                blockTokens = TokenHelper.CreateParagraghs(parser, this, blockTokens, true, sourceInfo);
                return(new MarkdownBlockquoteBlockToken(
                           this,
                           parser.Context,
                           blockTokens,
                           sourceInfo));
            }
            return(null);
        }
示例#21
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (HtmlComment != Regexes.Block.Gfm.HtmlComment)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(HtmlCommentMatcher);

            if (match?.Length > 0)
            {
                var sourceInfo = context.Consume(match.Length);
                return(new MarkdownHtmlBlockToken(
                           this,
                           parser.Context,
                           new InlineContent(
                               ImmutableArray.Create <IMarkdownToken>(
                                   new MarkdownRawToken(
                                       this,
                                       parser.Context,
                                       sourceInfo))),
                           sourceInfo));
            }
            return(null);
        }
示例#22
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (OrderList != Regexes.Block.OrderList ||
                UnorderList != Regexes.Block.UnorderList)
            {
                return(TryMatchOld(parser, context));
            }
            var  match = context.Match(OrderListMatcher);
            int  start;
            bool ordered;

            if (match == null)
            {
                match   = context.Match(UnorderListMatcher);
                ordered = false;
            }
            else
            {
                start   = int.Parse(match["start"].GetValue());
                ordered = true;
            }
            if (match?.Length > 0)
            {
                var sourceInfo = context.Consume(match.Length);
                var cap        = sourceInfo.Markdown.Match(Item);
                var next       = false;
                var l          = cap.Length;
                int i          = 0;
                var tokens     = new List <IMarkdownToken>();
                var lineOffset = 0;
                var lines      = 0;
                for (; i < l; i++)
                {
                    var item = cap[i];
                    lines = CountLine(item);
                    // Remove the list item's bullet
                    // so it is seen as the next token.
                    var space = item.Length;
                    item = item.ReplaceRegex(Regexes.Lexers.LeadingBullet, string.Empty);

                    // Outdent whatever the
                    // list item contains. Hacky.
                    if (item.IndexOf("\n ") > -1)
                    {
                        space -= item.Length;
                        item   = !parser.Options.Pedantic
                          ? Regex.Replace(item, "^ {1," + space + "}", "", RegexOptions.Multiline)
                          : Regex.Replace(item, @"^ {1,4}", "", RegexOptions.Multiline);
                    }

                    // Determine whether item is loose or not.
                    // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
                    // for discount behavior.
                    var loose = next || Regex.IsMatch(item, @"\n\n(?!\s*$)");
                    if (i != l - 1 && item.Length != 0)
                    {
                        next = item[item.Length - 1] == '\n';
                        if (!loose)
                        {
                            loose = next;
                        }
                    }

                    var c = parser.SwitchContext(MarkdownBlockContext.IsTop, false);
                    if (!loose)
                    {
                        var bc = (MarkdownBlockContext)parser.Context;
                        parser.SwitchContext(
                            bc.SetRules(
                                ImmutableList.Create <IMarkdownRule>(
                                    this,
                                    new MarkdownNewLineBlockRule(),
                                    new MarkdownTextBlockRule())));
                    }
                    var itemSourceInfo = sourceInfo.Copy(item, lineOffset);
                    var blockTokens    = parser.Tokenize(itemSourceInfo);
                    parser.SwitchContext(c);
                    blockTokens = TokenHelper.CreateParagraghs(parser, this, blockTokens, loose, itemSourceInfo);
                    tokens.Add(new MarkdownListItemBlockToken(this, parser.Context, blockTokens, loose, itemSourceInfo));
                    lineOffset += lines;
                }

                return(new MarkdownListBlockToken(this, parser.Context, tokens.ToImmutableArray(), ordered, sourceInfo));
            }
            return(null);
        }
示例#23
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (Table != Regexes.Block.Tables.Table || parser.Options.LegacyMode)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(TableMatcher);

            if (match?.Length > 0)
            {
                var header = match["head"].GetValue().ReplaceRegex(Regexes.Lexers.UselessTableHeader, string.Empty).SplitRegex(Regexes.Lexers.TableSplitter);
                var align  = ParseAligns(match["align"].GetValue().ReplaceRegex(Regexes.Lexers.UselessTableAlign, string.Empty).SplitRegex(Regexes.Lexers.TableSplitter));
                if (header.Length > align.Length)
                {
                    return(null);
                }
                var sourceInfo = context.Consume(match.Length);

                var rows  = match["body"].GetValue().ReplaceRegex(Regexes.Lexers.UselessGfmTableCell, string.Empty).Split('\n');
                var cells = new string[rows.Length][];
                for (int i = 0; i < rows.Length; i++)
                {
                    var columns = rows[i].SplitRegex(Regexes.Lexers.TableSplitter);
                    if (columns.Length == header.Length)
                    {
                        cells[i] = columns;
                    }
                    else if (columns.Length < header.Length)
                    {
                        cells[i] = new string[header.Length];
                        for (int j = 0; j < columns.Length; j++)
                        {
                            cells[i][j] = columns[j];
                        }
                        for (int j = columns.Length; j < cells[i].Length; j++)
                        {
                            cells[i][j] = string.Empty;
                        }
                    }
                    else // columns.Length > header.Length
                    {
                        cells[i] = new string[header.Length];
                        for (int j = 0; j < header.Length; j++)
                        {
                            cells[i][j] = columns[j];
                        }
                    }
                }

                return(new TwoPhaseBlockToken(
                           this,
                           parser.Context,
                           sourceInfo,
                           (p, t) => new MarkdownTableBlockToken(
                               t.Rule,
                               t.Context,
                               (from text in header
                                let si = t.SourceInfo.Copy(text)
                                         select new MarkdownTableItemBlockToken(t.Rule, t.Context, p.TokenizeInline(si), si)).ToImmutableArray(),
                               align.ToImmutableArray(),
                               cells.Select(
                                   (row, index) =>
                                   (from col in row
                                    let si = t.SourceInfo.Copy(col, index + 2)
                                             select new MarkdownTableItemBlockToken(t.Rule, t.Context, p.TokenizeInline(si), si)).ToImmutableArray()
                                   ).ToImmutableArray(),
                               t.SourceInfo)));
            }
            return(null);
        }