private ImmutableArray<IMarkdownToken> GetContent(IMarkdownParser parser, Match match, SourceInfo sourceInfo) { var emContent = new MarkdownEmInlineToken( this, parser.Context, parser.Tokenize(sourceInfo.Copy(match.Groups[2].Value)), sourceInfo.Copy("*" + match.Groups[1].Value + "*")); if (match.Groups[2].Length > 0) { return parser.Tokenize(sourceInfo.Copy(match.Groups[3].Value)).Insert(0, emContent); } else { return ImmutableArray.Create<IMarkdownToken>(emContent); } }
private ImmutableArray <IMarkdownToken> GetContent(IMarkdownParser parser, Match match) { var emContent = new MarkdownEmInlineToken( this, parser.Context, parser.Tokenize(match.Groups[2].Value), "*" + match.Groups[1].Value + "*"); if (match.Groups[2].Length > 0) { return(parser.Tokenize(match.Groups[3].Value).Insert(0, emContent)); } else { return(ImmutableArray.Create <IMarkdownToken>(emContent)); } }
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 engine, ref string source) { var match = Strong.Match(source); if (match.Length == 0) { return null; } source = source.Substring(match.Length); return new MarkdownStrongInlineToken(this, engine.Context, engine.Tokenize(match.NotEmpty(2, 1)), match.Value); }
public virtual IMarkdownToken TryMatch(IMarkdownParser engine, ref string source) { var match = Del.Match(source); if (match.Length == 0) { return null; } source = source.Substring(match.Length); return new GfmDelInlineToken(this, engine.Context, engine.Tokenize(match.Groups[1].Value), match.Value); }
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 = 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)); }
protected virtual IMarkdownToken GenerateToken(IMarkdownParser parser, string href, string title, string text, bool isImage, SourceInfo sourceInfo, MarkdownLinkType linkType, string refId) { var escapedHref = Regexes.Helper.MarkdownEscape.Replace(href, m => m.Groups[1].Value); if (isImage) { return new MarkdownImageInlineToken(this, parser.Context, escapedHref, title, text, sourceInfo, linkType, refId); } else { return new MarkdownLinkInlineToken(this, parser.Context, escapedHref, title, parser.Tokenize(sourceInfo.Copy(text)), sourceInfo, linkType, refId); } }
public virtual IMarkdownToken TryMatch(IMarkdownParser parser, ref string source) { var match = Em.Match(source); if (match.Length == 0) { return(null); } source = source.Substring(match.Length); return(new MarkdownEmInlineToken(this, parser.Context, parser.Tokenize(match.NotEmpty(2, 1)), match.Value)); }
protected virtual IMarkdownToken GenerateToken(IMarkdownParser engine, string href, string title, string text, bool isImage, string rawMarkdown) { var escapedHref = StringHelper.Escape(href); var escapedTitle = !string.IsNullOrEmpty(title) ? StringHelper.Escape(title) : null; if (isImage) { return new MarkdownImageInlineToken(this, engine.Context, escapedHref, escapedTitle, text, rawMarkdown); } else { return new MarkdownLinkInlineToken(this, engine.Context, escapedHref, escapedTitle, engine.Tokenize(text), rawMarkdown); } }
public virtual IMarkdownToken TryMatch(IMarkdownParser engine, ref string source) { var match = Blockquote.Match(source); if (match.Length == 0) { return null; } source = source.Substring(match.Length); var capStr = LeadingBlockquote.Replace(match.Value, string.Empty); var blockTokens = engine.Tokenize(capStr); blockTokens = TokenHelper.ParseInlineToken(engine, this, blockTokens, true); return new MarkdownBlockquoteBlockToken(this, engine.Context, blockTokens, match.Value); }
public override IMarkdownToken TryMatch(IMarkdownParser engine, ref string source) { var match = Blockquote.Match(source); if (match.Length == 0) { return null; } source = source.Substring(match.Length); var capStr = LeadingBlockquote.Replace(match.Value, string.Empty); var c = engine.SwitchContext(MarkdownBlockContext.IsBlockQuote, true); var tokens = engine.Tokenize(capStr); engine.SwitchContext(c); return new AzureBlockquoteBlockToken(this, engine.Context, tokens, match.Value); }
public virtual IMarkdownToken TryMatch(IMarkdownParser engine, ref string source) { var match = Blockquote.Match(source); if (match.Length == 0) { return(null); } source = source.Substring(match.Length); var capStr = LeadingBlockquote.Replace(match.Value, string.Empty); var blockTokens = engine.Tokenize(capStr); blockTokens = TokenHelper.ParseInlineToken(engine, this, blockTokens, true); return(new MarkdownBlockquoteBlockToken(this, engine.Context, blockTokens, match.Value)); }
public IMarkdownToken TryMatch(IMarkdownParser engine, ref string source) { var match = XrefLinkRegex.Match(source); if (match.Length == 0) { return(null); } source = source.Substring(match.Length); var name = match.Groups[1].Value; var xref = match.Groups[2].Value; var title = match.Groups[4].Value; return(new DfmXrefInlineToken(this, engine.Context, xref, engine.Tokenize(name), title, true, match.Value)); }
public override IMarkdownToken TryMatch(IMarkdownParser engine, ref string source) { var match = Blockquote.Match(source); if (match.Length == 0) { return(null); } source = source.Substring(match.Length); var capStr = LeadingBlockquote.Replace(match.Value, string.Empty); var c = engine.SwitchContext(MarkdownBlockContext.IsBlockQuote, true); var tokens = engine.Tokenize(capStr); engine.SwitchContext(c); return(new AzureBlockquoteBlockToken(this, engine.Context, tokens, match.Value)); }
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); var capStr = LeadingBlockquote.Replace(match.Value, string.Empty); var c = engine.SwitchContext(MarkdownBlockContext.IsBlockQuote, true); var tokens = engine.Tokenize(sourceInfo.Copy(capStr)); engine.SwitchContext(c); return(new AzureBlockquoteBlockToken(this, engine.Context, tokens, 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 static InlineContent TokenizeInline(this IMarkdownParser parser, SourceInfo sourceInfo) { if (parser == null) { throw new ArgumentNullException(nameof(parser)); } if (!(parser.Context is MarkdownBlockContext context)) { throw new InvalidOperationException($"{nameof(parser)}.{nameof(parser.Context)}(type:{parser.Context.GetType().FullName}) is invalid."); } var c = parser.SwitchContext(context.GetInlineContext()); var tokens = parser.Tokenize(sourceInfo); parser.SwitchContext(c); return(new InlineContent(tokens)); }
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 (!TypeForwardedToPathUtility.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 = 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, 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) { 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 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 (!TypeForwardedToPathUtility.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 = 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, 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 (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, ref string source) { var match = Regexes.Block.List.Match(source); if (match.Length == 0) { return null; } source = source.Substring(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>(); for (; i < l; i++) { var item = cap[i]; // 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 the next list item belongs here. // Backpedal if it does not belong in this list. if (parser.Options.SmartLists && i != l - 1) { var b = Bullet.Apply(cap[i + 1])[0]; // !!!!!!!!!!! if (bull != b && !(bull.Length > 1 && b.Length > 1)) { source = string.Join("\n", cap.Skip(i + 1)) + source; i = l - 1; } } // 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 blockTokens = parser.Tokenize(item); blockTokens = TokenHelper.ParseInlineToken(parser, this, blockTokens, loose); tokens.Add(new MarkdownListItemBlockToken(this, parser.Context, blockTokens, loose, item)); parser.SwitchContext(c); } return new MarkdownListBlockToken(this, parser.Context, tokens.ToImmutableArray(), bull.Length > 1, match.Value); }
protected virtual IMarkdownToken GenerateToken(IMarkdownParser parser, string href, string title, string text, bool isImage, SourceInfo sourceInfo, MarkdownLinkType linkType, string refId) { var escapedHref = Regexes.Helper.MarkdownEscape.Replace(href, m => m.Groups[1].Value); if (isImage) { return(new MarkdownImageInlineToken(this, parser.Context, escapedHref, title, text, sourceInfo, linkType, refId)); } else { return(new MarkdownLinkInlineToken(this, parser.Context, escapedHref, title, parser.Tokenize(sourceInfo.Copy(text)), sourceInfo, linkType, refId)); } }
protected virtual IMarkdownToken GenerateToken(IMarkdownParser engine, string href, string title, string text, bool isImage, string rawMarkdown) { var escapedHref = StringHelper.Escape(href); var escapedTitle = !string.IsNullOrEmpty(title) ? StringHelper.Escape(title) : null; if (isImage) { return(new MarkdownImageInlineToken(this, engine.Context, escapedHref, escapedTitle, text, rawMarkdown)); } else { return(new MarkdownLinkInlineToken(this, engine.Context, escapedHref, escapedTitle, engine.Tokenize(text), rawMarkdown)); } }
protected virtual IMarkdownToken GenerateToken(IMarkdownParser parser, string href, string title, string text, bool isImage, SourceInfo sourceInfo, MarkdownLinkType linkType, string refId) { var escapedHref = StringHelper.UnescapeMarkdown(href); var c = parser.SwitchContext(MarkdownInlineContext.IsInLink, BoxedTrue); IMarkdownToken result; if (isImage) { result = new MarkdownImageInlineToken(this, parser.Context, escapedHref, title, text, sourceInfo, linkType, refId); } else { result = new MarkdownLinkInlineToken(this, parser.Context, escapedHref, title, parser.Tokenize(sourceInfo.Copy(text)), sourceInfo, linkType, refId); } parser.SwitchContext(c); return(result); }
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) { 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, ref string source) { var match = Regexes.Block.List.Match(source); if (match.Length == 0) { return(null); } source = source.Substring(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>(); for (; i < l; i++) { var item = cap[i]; // 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 the next list item belongs here. // Backpedal if it does not belong in this list. if (parser.Options.SmartLists && i != l - 1) { var b = Bullet.Apply(cap[i + 1])[0]; // !!!!!!!!!!! if (bull != b && !(bull.Length > 1 && b.Length > 1)) { source = string.Join("\n", cap.Skip(i + 1)) + source; i = l - 1; } } // 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 blockTokens = parser.Tokenize(item); blockTokens = TokenHelper.ParseInlineToken(parser, this, blockTokens, loose); tokens.Add(new MarkdownListItemBlockToken(this, parser.Context, blockTokens, loose, item)); parser.SwitchContext(c); } return(new MarkdownListBlockToken(this, parser.Context, tokens.ToImmutableArray(), bull.Length > 1, match.Value)); }
protected virtual IMarkdownToken GenerateToken(IMarkdownParser parser, string href, string title, string text, bool isImage, SourceInfo sourceInfo) { var escapedHref = StringHelper.Escape(href); var escapedTitle = !string.IsNullOrEmpty(title) ? StringHelper.Escape(title) : null; if (isImage) { return(new MarkdownImageInlineToken(this, parser.Context, escapedHref, escapedTitle, text, sourceInfo)); } else { return(new MarkdownLinkInlineToken(this, parser.Context, escapedHref, escapedTitle, parser.Tokenize(sourceInfo.Copy(text)), sourceInfo)); } }