コード例 #1
0
        public override IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = RefLink.Match(context.CurrentMarkdown);
            if (match.Length == 0)
            {
                return null;
            }

            var linkStr = match.NotEmpty(2, 1).ReplaceRegex(Regexes.Lexers.WhiteSpaces, " ");

            LinkObj link;
            parser.Links.TryGetValue(linkStr.ToLower(), out link);

            if (string.IsNullOrEmpty(link?.Href))
            {
                var sourceInfo = context.Consume(1);
                var text = match.Value.Remove(1);
                return new MarkdownTextToken(this, parser.Context, text, sourceInfo);
            }
            else
            {
                var sourceInfo = context.Consume(match.Length);
                return GenerateToken(parser, link.Href, link.Title, match.Groups[1].Value, match.Value[0] == '!', sourceInfo, MarkdownLinkType.RefLink, linkStr);
            }
        }
コード例 #2
0
ファイル: GfmUrlInlineRule.cs プロジェクト: dotnet/docfx
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if ((bool)parser.Context.Variables[MarkdownInlineContext.IsInLink])
            {
                return null;
            }
            var match = Url.Match(context.CurrentMarkdown);
            if (match.Length == 0)
            {
                return null;
            }
            var text = StringHelper.Escape(match.Groups[1].Value);
            if (!Uri.IsWellFormedUriString(text, UriKind.RelativeOrAbsolute))
            {
                return null;
            }

            var sourceInfo = context.Consume(match.Length);
            return new MarkdownLinkInlineToken(
                this,
                parser.Context,
                text,
                null,
                ImmutableArray.Create<IMarkdownToken>(
                    new MarkdownRawToken(this, parser.Context, sourceInfo.Copy(match.Groups[1].Value))),
                sourceInfo,
                MarkdownLinkType.UrlLink,
                null);
        }
コード例 #3
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = AutoLink.Match(context.CurrentMarkdown);
            if (match.Length == 0)
            {
                return null;
            }
            var sourceInfo = context.Consume(match.Length);

            StringBuffer text;
            StringBuffer href;
            if (match.Groups[2].Value == "@")
            {
                text = match.Groups[1].Value[6] == ':'
                  ? Mangle(parser.Options.Mangle, match.Groups[1].Value.Substring(7))
                  : Mangle(parser.Options.Mangle, match.Groups[1].Value);
                href = Mangle(parser.Options.Mangle, "mailto:") + text;
            }
            else
            {
                text = StringHelper.Escape(match.Groups[1].Value);
                href = match.Groups[1].Value;
            }

            return new MarkdownLinkInlineToken(
                this, 
                parser.Context, 
                href, 
                null, 
                ImmutableArray.Create<IMarkdownToken>(
                    new MarkdownRawToken(this, parser.Context, sourceInfo.Copy(text))),
                sourceInfo,
                MarkdownLinkType.AutoLink,
                null);
        }
コード例 #4
0
        public IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = YamlHeader.Match(context.CurrentMarkdown);
            if (match.Length == 0)
            {
                return null;
            }

            // ---
            // a: b
            // ---
            var value = match.Groups[1].Value;
            try
            {
                using (StringReader reader = new StringReader(value))
                {
                    var result = YamlUtility.Deserialize<Dictionary<string, object>>(reader);
                    if (result == null)
                    {
                        return null;
                    }
                }
            }
            catch (Exception)
            {
                return null;
            }
            var sourceInfo = context.Consume(match.Length);
            return new DfmYamlHeaderBlockToken(this, parser.Context, value, sourceInfo);
        }
コード例 #5
0
 public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
 {
     var match = EscapedText.Match(context.CurrentMarkdown);
     if (match.Length == 0)
     {
         return null;
     }
     var sourceInfo = context.Consume(match.Length);
     return new MarkdownTextToken(this, parser.Context, StringHelper.Escape(match.Groups[1].Value), sourceInfo);
 }
コード例 #6
0
ファイル: GfmFencesBlockRule.cs プロジェクト: dotnet/docfx
 public IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
 {
     var match = Fences.Match(context.CurrentMarkdown);
     if (match.Length == 0)
     {
         return null;
     }
     var sourceInfo = context.Consume(match.Length);
     return new MarkdownCodeBlockToken(this, parser.Context, match.Groups[3].Value, match.Groups[2].Value, sourceInfo);
 }
コード例 #7
0
ファイル: MarkdownBrInlineRule.cs プロジェクト: dotnet/docfx
 public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
 {
     var match = Br.Match(context.CurrentMarkdown);
     if (match.Length == 0)
     {
         return null;
     }
     var sourceInfo = context.Consume(match.Length);
     return new MarkdownBrInlineToken(this, parser.Context, sourceInfo);
 }
コード例 #8
0
ファイル: GfmDelInlineRule.cs プロジェクト: dotnet/docfx
 public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
 {
     var match = Del.Match(context.CurrentMarkdown);
     if (match.Length == 0)
     {
         return null;
     }
     var sourceInfo = context.Consume(match.Length);
     return new GfmDelInlineToken(this, parser.Context, parser.Tokenize(sourceInfo.Copy(match.Groups[1].Value)), sourceInfo);
 }
コード例 #9
0
ファイル: MarkdownEmInlineRule.cs プロジェクト: dotnet/docfx
 public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
 {
     var match = Em.Match(context.CurrentMarkdown);
     if (match.Length == 0)
     {
         return null;
     }
     var sourceInfo = context.Consume(match.Length);
     return new MarkdownEmInlineToken(this, parser.Context, parser.Tokenize(sourceInfo.Copy(match.NotEmpty(2, 1))), sourceInfo);
 }
コード例 #10
0
ファイル: GfmStrongEmInlineRule.cs プロジェクト: dotnet/docfx
 public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
 {
     var match = StrongEm.Match(context.CurrentMarkdown);
     if (match.Length == 0)
     {
         return null;
     }
     if (match.Groups[1].Length > 0)
     {
         var sourceInfo = context.Consume(match.Groups[1].Length);
         return new MarkdownTextToken(this, parser.Context, match.Groups[1].Value, sourceInfo);
     }
     else
     {
         var sourceInfo = context.Consume(match.Length);
         return new MarkdownStrongInlineToken(
             this,
             parser.Context,
             GetContent(parser, match, sourceInfo),
             sourceInfo);
     }
 }
コード例 #11
0
ファイル: AzureNoteBlockRule.cs プロジェクト: dotnet/docfx
 public virtual IMarkdownToken TryMatch(IMarkdownParser engine, IMarkdownParsingContext context)
 {
     if (!engine.Context.Variables.ContainsKey(MarkdownBlockContext.IsBlockQuote) || !(bool)engine.Context.Variables[MarkdownBlockContext.IsBlockQuote])
     {
         return null;
     }
     var match = AzureNoteRegex.Match(context.CurrentMarkdown);
     if (match.Length == 0)
     {
         return null;
     }
     var sourceInfo = context.Consume(match.Groups["rawmarkdown"].Length);
     return new AzureNoteBlockToken(this, engine.Context, match.Groups["notetype"].Value, match.Groups["rawmarkdown"].Value, sourceInfo);
 }
コード例 #12
0
 public override IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
 {
     var match = Link.Match(context.CurrentMarkdown);
     if (match.Length == 0)
     {
         return null;
     }
     if (IsEscape(match.Groups[1].Value) || IsEscape(match.Groups[2].Value))
     {
         return null;
     }
     var sourceInfo = context.Consume(match.Length);
     return GenerateToken(parser, match.Groups[2].Value, match.Groups[4].Value, match.Groups[1].Value, match.Value[0] == '!', sourceInfo, MarkdownLinkType.NormalLink, null);
 }
コード例 #13
0
        public IMarkdownToken TryMatch(IMarkdownParser engine, IMarkdownParsingContext context)
        {
            var match = AzureMigrationVideoRegex.Match(context.CurrentMarkdown);
            if (match.Length == 0)
            {
                return null;
            }
            var sourceInfo = context.Consume(match.Length);

            // Sample: [AZURE.VIDEO video-id-string]. Get video id here
            var videoId = match.Groups[1].Value;

            return new AzureVideoBlockToken(this, engine.Context, videoId, sourceInfo);
        }
コード例 #14
0
ファイル: DfmSectionBlockRule.cs プロジェクト: dotnet/docfx
 public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
 {
     if (!parser.Context.Variables.ContainsKey(MarkdownBlockContext.IsBlockQuote) || !(bool)parser.Context.Variables[MarkdownBlockContext.IsBlockQuote])
     {
         return null;
     }
     var match = _sectionRegex.Match(context.CurrentMarkdown);
     if (match.Length == 0)
     {
         return null;
     }
     var sourceInfo = context.Consume(match.Groups["rawmarkdown"].Length);
     var attributes = ExtractAttibutes(match.Groups["attributes"].Value);
     return new DfmSectionBlockToken(this, parser.Context, attributes, sourceInfo);
 }
コード例 #15
0
 public IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
 {
     var match = XrefAutoLinkRegexWithQuote.Match(context.CurrentMarkdown);
     if (match.Length == 0)
     {
         match = XrefAutoLinkRegex.Match(context.CurrentMarkdown);
         if (match.Length == 0)
         {
             return null;
         }
     }
     var sourceInfo = context.Consume(match.Length);
     var content = match.Groups[2].Value;
     return new DfmXrefInlineToken(this, parser.Context, content, ImmutableArray<IMarkdownToken>.Empty, null, true, sourceInfo);
 }
コード例 #16
0
ファイル: MarkdownDefBlockRule.cs プロジェクト: dotnet/docfx
 public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
 {
     var match = Def.Match(context.CurrentMarkdown);
     if (match.Length == 0)
     {
         return null;
     }
     var sourceInfo = context.Consume(match.Length);
     parser.Links[match.Groups[1].Value.ToLower()] = new LinkObj
     {
         Href = match.Groups[2].Value,
         Title = match.Groups[3].Value
     };
     return new MarkdownIgnoreToken(this, parser.Context, sourceInfo);
 }
コード例 #17
0
 public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
 {
     var match = Blockquote.Match(context.CurrentMarkdown);
     if (match.Length == 0)
     {
         return null;
     }
     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);
 }
コード例 #18
0
ファイル: DfmFencesBlockRule.cs プロジェクト: dotnet/docfx
        public override IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = _dfmFencesRegex.Match(context.CurrentMarkdown);
            if (match.Length == 0)
            {
                return null;
            }
            var sourceInfo = context.Consume(match.Length);

            // [!code-REST-i[name](path "optionalTitle")]
            var name = match.Groups["name"].Value;
            var path = match.Groups["path"].Value;
            var lang = match.Groups["lang"]?.Value;
            var title = match.Groups["title"]?.Value;
            var pathQueryOption = ParsePathQueryString(match.Groups["option"]?.Value, match.Groups["optionValue"]?.Value);

            return new DfmFencesBlockToken(this, parser.Context, name, path, sourceInfo, lang, title, pathQueryOption);
        }
コード例 #19
0
        public IMarkdownToken TryMatch(IMarkdownParser engine, IMarkdownParsingContext context)
        {
            var match = AzureIncludeRegex.Match(context.CurrentMarkdown);
            if (match.Length == 0)
            {
                return null;
            }
            var sourceInfo = context.Consume(match.Length);

            // [!azure.include[title](path "optionalTitle")]
            // 1. Get include file path 
            var path = match.Groups[2].Value;

            // 2. Get title
            var value = match.Groups[1].Value;
            var title = match.Groups[4].Value;

            if (!TypeForwardedToPathUtility.IsRelativePath(path))
            {
                Logger.LogWarning($"Azure inline include path {path} is not a relative path, can't expand it");
                return new MarkdownTextToken(this, engine.Context, match.Value, sourceInfo);
            }

            // 3. Apply inline rules to the included content
            object currentFilePath;
            if (!engine.Context.Variables.TryGetValue("path", out currentFilePath))
            {
                Logger.LogWarning($"Can't get path for the file that ref azure inline include file, return MarkdownTextToken. Raw: {match.Value}");
                return new MarkdownTextToken(this, engine.Context, match.Value, sourceInfo);
            }

            var includeFilePath = TypeForwardedToPathUtility.NormalizePath(Path.Combine(Path.GetDirectoryName(currentFilePath.ToString()), path));
            if (!File.Exists(includeFilePath))
            {
                Logger.LogWarning($"Can't get include file path {includeFilePath} in the file {currentFilePath}, return MarkdownTextToken. Raw: {match.Value}");
                return new MarkdownTextToken(this, engine.Context, match.Value, sourceInfo);
            }

            return new TwoPhaseBlockToken(this, engine.Context, sourceInfo, (p, t) =>
            {
                var inlineTokens = p.Tokenize(SourceInfo.Create(MarkdownEngine.Normalize(File.ReadAllText(includeFilePath)), includeFilePath));
                return new AzureIncludeInlineToken(t.Rule, t.Context, path, value, title, inlineTokens, match.Groups[0].Value, t.SourceInfo);
            });
        }
コード例 #20
0
ファイル: MarkdownHtmlBlockRule.cs プロジェクト: dotnet/docfx
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = Html.Match(context.CurrentMarkdown);
            if (match.Length == 0)
            {
                return null;
            }
            var sourceInfo = context.Consume(match.Length);

            bool isPre = parser.Options.Sanitizer == null &&
                (match.Groups[1].Value == "pre" || match.Groups[1].Value == "script" || match.Groups[1].Value == "style");
            if (parser.Options.Sanitize)
            {
                return new TwoPhaseBlockToken(
                    this,
                    parser.Context,
                    sourceInfo,
                    (p, t) => new MarkdownParagraphBlockToken(
                        t.Rule,
                        t.Context,
                        p.TokenizeInline(t.SourceInfo.Copy(match.Value)),
                        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));
            }
        }
コード例 #21
0
        public IMarkdownToken TryMatch(IMarkdownParser engine, IMarkdownParsingContext context)
        {
            var match = AzureIncludeRegex.Match(context.CurrentMarkdown);
            if (match.Length == 0)
            {
                return null;
            }
            var sourceInfo = context.Consume(match.Length);

            // [!azure.include[title](path "optionalTitle")]
            // 1. Get include file path 
            var path = match.Groups[2].Value;

            // 2. Get title
            var name = match.Groups[1].Value;
            var title = match.Groups[4].Value;

            return new AzureMigrationIncludeBlockToken(this, engine.Context, name, path, title, sourceInfo);
        }
コード例 #22
0
        public IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = XrefShortcutRegexWithQuote.Match(context.CurrentMarkdown);
            if (match.Length == 0)
            {
                match = XrefShortcutRegex.Match(context.CurrentMarkdown);
                if (match.Length == 0)
                {
                    return null;
                }
            }

            var sourceInfo = context.Consume(match.Length);

            // @String=>cap[2]=String, @'string'=>cap[2]=string
            // For cross-reference, add ~/ prefix
            var content = match.Groups[2].Value;
            return new DfmXrefInlineToken(this, parser.Context, content, ImmutableArray<IMarkdownToken>.Empty, null, false, sourceInfo);
        }
コード例 #23
0
ファイル: DfmIncludeBlockRule.cs プロジェクト: dotnet/docfx
        public IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = Include.Match(context.CurrentMarkdown);
            if (match.Length == 0)
            {
                return null;
            }
            var sourceInfo = context.Consume(match.Length);

            // [!include[title](path "optionalTitle")]
            // 1. Get include file path 
            var path = match.Groups[2].Value;

            // 2. Get title
            var value = match.Groups[1].Value;
            var title = match.Groups[4].Value;

            return new DfmIncludeBlockToken(this, parser.Context, path, value, title, match.Groups[0].Value, sourceInfo);
        }
コード例 #24
0
 public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
 {
     var match = Heading.Match(context.CurrentMarkdown);
     if (match.Length == 0)
     {
         return null;
     }
     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.Groups[2].Value)),
             Regex.Replace(match.Groups[2].Value.ToLower(), @"[^\p{L}\p{N}\- ]+", "").Replace(' ', '-'),
             match.Groups[1].Value.Length,
             t.SourceInfo));
 }
コード例 #25
0
        public IMarkdownToken TryMatch(IMarkdownParser engine, IMarkdownParsingContext context)
        {
            var match = AzureIncludeRegex.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }
            var sourceInfo = context.Consume(match.Length);

            // [!azure.include[title](path "optionalTitle")]
            // 1. Get include file path
            var path = match.Groups[2].Value;

            // 2. Get title
            var name  = match.Groups[1].Value;
            var title = match.Groups[4].Value;

            return(new AzureMigrationIncludeInlineToken(this, engine.Context, name, path, title, sourceInfo));
        }
コード例 #26
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (Def != Regexes.Block.Def || parser.Options.LegacyMode)
            {
                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);
        }
コード例 #27
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);
        }
コード例 #28
0
        public IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = Include.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }
            var sourceInfo = context.Consume(match.Length);

            // [!include[title](path "optionalTitle")]
            // 1. Get include file path
            var path = match.Groups[2].Value;

            // 2. Get title
            var value = match.Groups[1].Value;
            var title = match.Groups[4].Value;

            return(new DfmIncludeBlockToken(this, parser.Context, path, value, title, match.Groups[0].Value, sourceInfo));
        }
コード例 #29
0
        private IMarkdownToken TryMatchOld(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = Code.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }
            var sourceInfo = context.Consume(match.Length);
            var capStr     = Regexes.Lexers.LeadingWhiteSpaces.Replace(match.Value, 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));
            }
        }
コード例 #30
0
        public IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = AzureIncludeRegex.Match(context.CurrentMarkdown);
            if (match.Length == 0)
            {
                return null;
            }
            var sourceInfo = context.Consume(match.Length);

            // [!azure.include[title](path "optionalTitle")]
            // 1. Get include file path 
            var path = match.Groups[2].Value;

            // 2. Get title
            var value = match.Groups[1].Value;
            var title = match.Groups[4].Value;

            if (!PathUtility.IsRelativePath(path))
            {
                Logger.LogWarning($"Azure inline include path {path} is not a relative path, can't expand it");
                return new MarkdownTextToken(this, parser.Context, match.Value, sourceInfo);
            }

            object currentFilePath;
            if (!parser.Context.Variables.TryGetValue("path", out currentFilePath))
            {
                Logger.LogWarning($"Can't get path for the file that ref azure block include file, return MarkdownTextToken. Raw: {match.Value}");
                return new MarkdownTextToken(this, parser.Context, match.Value, sourceInfo);
            }

            var includeFilePath = PathUtility.NormalizePath(Path.Combine(Path.GetDirectoryName(currentFilePath.ToString()), path));
            if (!File.Exists(includeFilePath))
            {
                Logger.LogWarning($"Can't get include file path {includeFilePath} in the file {currentFilePath}, return MarkdownTextToken. Raw: {match.Value}");
                return new MarkdownTextToken(this, parser.Context, match.Value, sourceInfo);
            }

            var blockTokens = parser.Tokenize(SourceInfo.Create(MarkdownEngine.Normalize(File.ReadAllText(includeFilePath)), includeFilePath));
            blockTokens = TokenHelper.CreateParagraghs(parser, this, blockTokens, true, sourceInfo);
            return new AzureIncludeBlockToken(this, parser.Context, path, value, title, blockTokens, match.Groups[0].Value, sourceInfo);
        }
コード例 #31
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (MarkdownInlineContext.GetIsInLink(parser.Context))
            {
                return(null);
            }
            var match = AutoLink.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }
            var sourceInfo = context.Consume(match.Length);

            StringBuffer text;
            StringBuffer href;

            if (match.Groups[2].Value == "@")
            {
                text = match.Groups[1].Value[6] == ':'
                  ? Mangle(parser.Options.Mangle, match.Groups[1].Value.Substring(7))
                  : Mangle(parser.Options.Mangle, match.Groups[1].Value);
                href = Mangle(parser.Options.Mangle, "mailto:") + text;
            }
            else
            {
                text = StringHelper.Escape(match.Groups[1].Value);
                href = match.Groups[1].Value;
            }

            return(new MarkdownLinkInlineToken(
                       this,
                       parser.Context,
                       href,
                       null,
                       ImmutableArray.Create <IMarkdownToken>(
                           new MarkdownRawToken(this, parser.Context, sourceInfo.Copy(text))),
                       sourceInfo,
                       MarkdownLinkType.AutoLink,
                       null));
        }
コード例 #32
0
ファイル: MarkdownTagInlineRule.cs プロジェクト: dotnet/docfx
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = Tag.Match(context.CurrentMarkdown);
            if (match.Length == 0)
            {
                return null;
            }
            var sourceInfo = context.Consume(match.Length);

            var c = parser.Context;
            var inLink = (bool)c.Variables[MarkdownInlineContext.IsInLink];
            if (!inLink && Regexes.Lexers.StartHtmlLink.IsMatch(match.Value))
            {
                parser.SwitchContext(MarkdownInlineContext.IsInLink, true);
            }
            else if (inLink && Regexes.Lexers.EndHtmlLink.IsMatch(match.Value))
            {
                parser.SwitchContext(MarkdownInlineContext.IsInLink, false);
            }
            return new MarkdownTagInlineToken(this, parser.Context, sourceInfo);
        }
コード例 #33
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);
                }
コード例 #34
0
        public IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = XrefShortcutRegexWithQuote.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                match = XrefShortcutRegex.Match(context.CurrentMarkdown);
                if (match.Length == 0)
                {
                    return(null);
                }
            }

            var sourceInfo = context.Consume(match.Length);

            // @String=>cap[2]=String, @'string'=>cap[2]=string
            // For cross-reference, add ~/ prefix
            var content = match.Groups[2].Value;

            return(new DfmXrefInlineToken(this, parser.Context, content, ImmutableArray <IMarkdownToken> .Empty, null, false, sourceInfo));
        }
コード例 #35
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (!(bool)parser.Context.Variables[MarkdownBlockContext.IsTop])
            {
                return(null);
            }
            var match = Def.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }
            var sourceInfo = context.Consume(match.Length);

            parser.Links[match.Groups[1].Value.ToLower()] = new LinkObj
            {
                Href  = match.Groups[2].Value,
                Title = match.Groups[3].Value
            };
            return(new MarkdownIgnoreToken(this, parser.Context, sourceInfo));
        }
コード例 #36
0
        public IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (MarkdownInlineContext.GetIsInLink(parser.Context))
            {
                return(null);
            }
            var match = XrefAutoLinkRegexWithQuote.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                match = XrefAutoLinkRegex.Match(context.CurrentMarkdown);
                if (match.Length == 0)
                {
                    return(null);
                }
            }
            var sourceInfo = context.Consume(match.Length);
            var content    = match.Groups[2].Value;

            return(new DfmXrefInlineToken(this, parser.Context, content, ImmutableArray <IMarkdownToken> .Empty, null, true, sourceInfo));
        }
コード例 #37
0
        public override IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = Blockquote.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }
            var sourceInfo  = context.Consume(match.Length);
            var c           = parser.SwitchContext(MarkdownBlockContext.IsBlockQuote, true);
            var capStr      = LeadingBlockquote.Replace(sourceInfo.Markdown, string.Empty);
            var blockTokens = parser.Tokenize(sourceInfo.Copy(capStr));

            blockTokens = TokenHelper.CreateParagraghs(parser, this, blockTokens, true, sourceInfo);
            parser.SwitchContext(c);
            return(new MarkdownBlockquoteBlockToken(
                       this,
                       parser.Context,
                       blockTokens,
                       sourceInfo));
        }
コード例 #38
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = HtmlComment.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }
            var sourceInfo = context.Consume(match.Length);

            return(new MarkdownHtmlBlockToken(
                       this,
                       parser.Context,
                       new InlineContent(
                           ImmutableArray.Create <IMarkdownToken>(
                               new MarkdownRawToken(
                                   this,
                                   parser.Context,
                                   sourceInfo))),
                       sourceInfo));
        }
コード例 #39
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);
        }
コード例 #40
0
        private IMarkdownToken OldMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = Heading.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }
            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.Groups[2].Value)),
                           Regex.Replace(match.Groups[2].Value.ToLower(), @"[^\p{L}\p{N}\- ]+", "").Replace(' ', '-'),
                           match.Groups[1].Value.Length,
                           t.SourceInfo)));
        }
コード例 #41
0
ファイル: MarkdownDefBlockRule.cs プロジェクト: zyj0021/docfx
        public virtual IMarkdownToken TryMatchOld(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (!parser.Context.Variables.ContainsKey(MarkdownBlockContext.IsTop) ||
                false.Equals(parser.Context.Variables[MarkdownBlockContext.IsTop]))
            {
                return(null);
            }
            var match = Def.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }
            var sourceInfo = context.Consume(match.Length);

            parser.Links[match.Groups[1].Value.ToLower()] = new LinkObj
            {
                Href  = StringHelper.LegacyUnescapeMarkdown(match.Groups[2].Value),
                Title = StringHelper.LegacyUnescapeMarkdown(match.Groups[3].Value),
            };
            return(new MarkdownIgnoreToken(this, parser.Context, sourceInfo));
        }
コード例 #42
0
        private IMarkdownToken TryMatchOld(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = YamlHeader.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }

            // ---
            // a: b
            // ---
            var value = match.Groups[1].Value;

            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));
        }
コード例 #43
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = Blockquote.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }
            var sourceInfo = context.Consume(match.Length);

            return(new TwoPhaseBlockToken(
                       this,
                       parser.Context,
                       sourceInfo,
                       (p, t) =>
            {
                var capStr = LeadingBlockquote.Replace(t.SourceInfo.Markdown, string.Empty);
                var blockTokens = p.Tokenize(t.SourceInfo.Copy(capStr));
                blockTokens = TokenHelper.ParseInlineToken(p, t.Rule, blockTokens, true, t.SourceInfo);
                return new MarkdownBlockquoteBlockToken(t.Rule, t.Context, blockTokens, t.SourceInfo);
            }));
        }
コード例 #44
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);
        }
コード例 #45
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = LHeading.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }
            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.Groups[1].Value)),
                           Regex.Replace(match.Groups[1].Value.ToLower(), @"[^\w]+", "-"),
                           match.Groups[2].Value == "=" ? 1 : 2,
                           t.SourceInfo)));
        }
コード例 #46
0
ファイル: DfmFencesBlockRule.cs プロジェクト: zyj0021/docfx
        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);
                return(new DfmFencesBlockToken(this, parser.Context, name, path, sourceInfo, lang, title, queryStringAndFragment));
            }
            return(null);
        }
コード例 #47
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser engine, IMarkdownParsingContext context)
        {
            var match = AzureHtmlMetadataRegex.Match(context.CurrentMarkdown);
            if (match.Length == 0)
            {
                return null;
            }

            var sourceInfo = context.Consume(match.Length);
            object currentFilePath;
            if (!engine.Context.Variables.TryGetValue("path", out currentFilePath))
            {
                Logger.LogWarning($"Can't get path for setting azure ms.assetid. Won't set it.");
                currentFilePath = string.Empty;
            }

            var metadata = GetAttributesFromHtmlContent(match.Value);
            if (metadata == null)
            {
                return new MarkdownTextToken(this, engine.Context, match.Value, sourceInfo);
            }
            return new AzureHtmlMetadataBlockToken(this, engine.Context, metadata.Properties, metadata.Tags, sourceInfo);
        }
コード例 #48
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = Tag.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }
            var sourceInfo = context.Consume(match.Length);

            var c      = parser.Context;
            var inLink = (bool)c.Variables[MarkdownInlineContext.IsInLink];

            if (!inLink && Regexes.Lexers.StartHtmlLink.IsMatch(match.Value))
            {
                parser.SwitchContext(MarkdownInlineContext.IsInLink, true);
            }
            else if (inLink && Regexes.Lexers.EndHtmlLink.IsMatch(match.Value))
            {
                parser.SwitchContext(MarkdownInlineContext.IsInLink, false);
            }
            return(new MarkdownTagInlineToken(this, parser.Context, sourceInfo));
        }
コード例 #49
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = NpTable.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }
            var sourceInfo = context.Consume(match.Length);
            var header     = match.Groups[1].Value.ReplaceRegex(Regexes.Lexers.UselessTableHeader, string.Empty).SplitRegex(Regexes.Lexers.TableSplitter);
            var align      = ParseAligns(match.Groups[2].Value.ReplaceRegex(Regexes.Lexers.UselessTableAlign, string.Empty).SplitRegex(Regexes.Lexers.TableSplitter));
            var cells      = match.Groups[3].Value.ReplaceRegex(Regexes.Lexers.EndWithNewLine, string.Empty).Split('\n').Select(x => new string[] { x }).ToArray();

            for (int i = 0; i < cells.Length; i++)
            {
                cells[i] = cells[i][0].SplitRegex(Regexes.Lexers.TableSplitter);
            }
            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)));
        }
コード例 #50
0
ファイル: GfmEmojiInlineRule.cs プロジェクト: dotnet/docfx
 public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
 {
     var match = Emoji.Match(context.CurrentMarkdown);
     if (match.Length == 0)
     {
         return null;
     }
     var shortCode = match.Groups[1].Value;
     var text = GetEmoji(shortCode);
     if (text == null)
     {
         return null;
     }
     else
     {
         var sourceInfo = context.Consume(match.Length);
         return new GfmEmojiInlineToken(
             this,
             parser.Context,
             shortCode,
             text,
             sourceInfo);
     }
 }
コード例 #51
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);
        }
コード例 #52
0
        public override IMarkdownToken TryMatch(IMarkdownParser engine, IMarkdownParsingContext context)
        {
            var match = Blockquote.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }
            var sourceInfo = context.Consume(match.Length);

            return(new TwoPhaseBlockToken(
                       this,
                       engine.Context,
                       sourceInfo,
                       (p, t) =>
            {
                var capStr = LeadingBlockquote.Replace(t.SourceInfo.Markdown, string.Empty);
                var c = p.SwitchContext(MarkdownBlockContext.IsBlockQuote, true);
                var tokens = p.Tokenize(t.SourceInfo.Copy(capStr));
                tokens = TokenHelper.ParseInlineToken(p, t.Rule, tokens, true, t.SourceInfo);
                p.SwitchContext(c);
                return new AzureBlockquoteBlockToken(this, t.Context, tokens, t.SourceInfo);
            }));
        }
コード例 #53
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 = 1;
            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);
                    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, start, sourceInfo));
            }
            return(null);
        }
コード例 #54
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (context.IsInParagraph)
            {
                return(null);
            }
            if (Html != Regexes.Block.Html || parser.Options.LegacyMode)
            {
                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) =>
                    {
                        InlineContent ic;
                        if (isPre)
                        {
                            ic = new InlineContent(
                                ImmutableArray.Create <IMarkdownToken>(
                                    new MarkdownRawToken(
                                        this,
                                        parser.Context,
                                        t.SourceInfo)));
                        }
                        else
                        {
                            var c = new MarkdownInlineContext(
                                ImmutableList.Create <IMarkdownRule>(
                                    new MarkdownPreElementInlineRule(),
                                    new MarkdownTagInlineRule(),
                                    new MarkdownTextInlineRule()));
                            p.SwitchContext(c);
                            ic = new InlineContent(p.Tokenize(t.SourceInfo));
                            p.SwitchContext(t.Context);
                        }
                        return new MarkdownHtmlBlockToken(
                            t.Rule,
                            t.Context,
                            ic,
                            t.SourceInfo);
                    }));
                }
            }
            return(null);
        }
コード例 #55
0
        public override IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            // NOTE: This copies the logic from MarkdownLinkInlineRule, but does not match if there are no links to replace.
            // This isn't perfect, but at least it ensures we only match the one [Changes]() link it is intended to match
            // and replaces multiple environment variables if they exist.

            // The when the Consume() method below is called, there doesn't appear to be any way to make the cursor backtrack,
            // and the scan is only performed once. This is why we have to resort to this. Not sure if there is a better way to make
            // nested tokens than this, but it doesn't seem like there is.

            var match = Link.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }
            if (MarkdownInlineContext.GetIsInLink(parser.Context) && match.Value[0] != '!')
            {
                return(null);
            }
            if (IsEscape(match.Groups[1].Value) || IsEscape(match.Groups[2].Value))
            {
                return(null);
            }

            var text  = match.Groups[1].Value;
            var title = match.Groups[4].Value;
            var href  = match.Groups[2].Value;

            var textMatch  = EnvVarRegex.Match(text);
            var titleMatch = EnvVarRegex.Match(title);
            var hrefMatch  = EnvVarRegex.Match(href);

            // Don't match unless we have a match for our EnvVar pattern in any part of the link
            if (!textMatch.Success && !titleMatch.Success && !hrefMatch.Success)
            {
                return(null);
            }

            StringBuilder scratch = null;

            if (textMatch.Success || titleMatch.Success || hrefMatch.Success)
            {
                scratch = new StringBuilder();
            }

            if (textMatch.Success)
            {
                text = EnvironmentVariableUtil.ReplaceEnvironmentVariables(text, textMatch, scratch);
            }
            if (titleMatch.Success)
            {
                title = EnvironmentVariableUtil.ReplaceEnvironmentVariables(title, titleMatch, scratch);
            }
            if (hrefMatch.Success)
            {
                href = EnvironmentVariableUtil.ReplaceEnvironmentVariables(href, hrefMatch, scratch);
            }

            var sourceInfo = context.Consume(match.Length);

            return(GenerateToken(parser, href, title, text, match.Value[0] == '!', sourceInfo, MarkdownLinkType.NormalLink, null));
        }
コード例 #56
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = Table.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                return(null);
            }
            var header = match.Groups[1].Value.ReplaceRegex(Regexes.Lexers.UselessTableHeader, string.Empty).SplitRegex(Regexes.Lexers.TableSplitter);
            var align  = ParseAligns(match.Groups[2].Value.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.Groups[3].Value.ReplaceRegex(Regexes.Lexers.UselessGfmTableCell, string.Empty).Split('\n').Select(x => x).ToArray();
            var cells = new string[rows.Length][];

            for (int i = 0; i < rows.Length; i++)
            {
                var columns = rows[i]
                              .ReplaceRegex(Regexes.Lexers.EmptyGfmTableCell, string.Empty)
                              .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)));
        }
コード例 #57
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = NpTable.Match(context.CurrentMarkdown);
            if (match.Length == 0)
            {
                return null;
            }
            var header = match.Groups[1].Value.ReplaceRegex(Regexes.Lexers.UselessTableHeader, string.Empty).SplitRegex(Regexes.Lexers.TableSplitter);
            var align = ParseAligns(match.Groups[2].Value.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 = (from row in match.Groups[3].Value.ReplaceRegex(Regexes.Lexers.EndWithNewLine, string.Empty).Split('\n')
                        select row.ReplaceRegex(Regexes.Lexers.UselessTableRow, string.Empty)).ToList();
            var cells = new string[rows.Count][];
            for (int i = 0; i < rows.Count; i++)
            {
                var columns = rows[i]
                  .ReplaceRegex(Regexes.Lexers.EmptyGfmTableCell, string.Empty)
                  .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));
        }
コード例 #58
0
ファイル: MarkdownListBlockRule.cs プロジェクト: runt18/docfx
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = OrderList.Match(context.CurrentMarkdown);

            if (match.Length == 0)
            {
                match = UnorderList.Match(context.CurrentMarkdown);
                if (match.Length == 0)
                {
                    return(null);
                }
            }
            var sourceInfo = context.Consume(match.Length);

            var bull = match.Groups[2].Value;

            var cap = match.Groups[0].Value.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;
                    c = 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(), bull.Length > 1, sourceInfo));
        }
コード例 #59
0
ファイル: MarkdownListBlockRule.cs プロジェクト: dotnet/docfx
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            var match = OrderList.Match(context.CurrentMarkdown);
            if (match.Length == 0)
            {
                match = UnorderList.Match(context.CurrentMarkdown);
                if (match.Length == 0)
                {
                    return null;
                }
            }
            var sourceInfo = context.Consume(match.Length);

            var bull = match.Groups[2].Value;

            var cap = match.Groups[0].Value.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;
                    c = 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(), bull.Length > 1, sourceInfo);
        }
コード例 #60
0
        public virtual IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
        {
            if (NpTable != Regexes.Block.Tables.NpTable)
            {
                return(TryMatchOld(parser, context));
            }
            var match = context.Match(NpTableMatcher);

            if (match?.Length > 0)
            {
                var header = match["header"].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 = (from row in match["body"].GetValue().ReplaceRegex(Regexes.Lexers.EndWithNewLine, string.Empty).Split('\n')
                            select row.ReplaceRegex(Regexes.Lexers.UselessTableRow, string.Empty)).ToList();
                var cells = new string[rows.Count][];
                for (int i = 0; i < rows.Count; 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);
        }