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); } }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); } }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }); }
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)); } }
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); }
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); }
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); }
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)); }
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)); }
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); }
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); }
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)); }
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)); } }
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); }
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)); }
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); }
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); }
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)); }
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)); }
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)); }
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)); }
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)); }
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); }
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))); }
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)); }
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)); }
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); })); }
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); }
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))); }
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); }
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); }
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)); }
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))); }
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); } }
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); }
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); })); }
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); }
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); }
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)); }
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))); }
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)); }
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)); }
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); }
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); }