diff --git a/Cyjb.Markdown/ParseBlock/BlockParser.cs b/Cyjb.Markdown/ParseBlock/BlockParser.cs index 7856aa0..7c40f67 100644 --- a/Cyjb.Markdown/ParseBlock/BlockParser.cs +++ b/Cyjb.Markdown/ParseBlock/BlockParser.cs @@ -130,7 +130,7 @@ public BlockParser(TextReader text, ParseOptions? options) public Document Parse() { Token token; - BlockText line = new(this, locator); + BlockText line = new(locator); while (true) { // 清除行的旧数据。 @@ -254,7 +254,7 @@ private void ParseLine(BlockText line) { foreach (IBlockFactory factory in factories) { - currentInlineProcessors.AddRange(factory.TryStart(line, processor)); + currentInlineProcessors.AddRange(factory.TryStart(this, line, processor)); if (currentInlineProcessors.Count > 0) { break; @@ -264,7 +264,7 @@ private void ParseLine(BlockText line) // 尝试检查缩进代码块 if (currentInlineProcessors.Count == 0) { - currentInlineProcessors.AddRange(IndentedCodeBlockProcessor.TryStart(line)); + currentInlineProcessors.AddRange(IndentedCodeBlockProcessor.TryStart(this, line)); } if (currentInlineProcessors.Count == 0) { diff --git a/Cyjb.Markdown/ParseBlock/BlockText.cs b/Cyjb.Markdown/ParseBlock/BlockText.cs index 6cc42aa..a38d93f 100644 --- a/Cyjb.Markdown/ParseBlock/BlockText.cs +++ b/Cyjb.Markdown/ParseBlock/BlockText.cs @@ -5,7 +5,7 @@ namespace Cyjb.Markdown.ParseBlock; /// -/// 行的信息。 +/// 块的文本。 /// internal sealed class BlockText { @@ -23,10 +23,6 @@ internal sealed class BlockText /// private readonly LineLocator locator; /// - /// 块解析器。 - /// - private readonly BlockParser parser; - /// /// 行的起始位置。 /// private int start = -1; @@ -66,11 +62,9 @@ internal sealed class BlockText /// /// 使用指定的行定位器初始化 类的新实例。 /// - /// 块解析器。 /// 行定位器。 - internal BlockText(BlockParser parser, LineLocator locator) + internal BlockText(LineLocator locator) { - this.parser = parser; this.locator = locator; } @@ -111,10 +105,6 @@ public int Indent /// 获取行的结束位置。 /// public int End => end; - /// - /// 获取解析的选项。 - /// - public ParseOptions Options => parser.Options; /// /// 获取当前行的文本。 @@ -177,11 +167,6 @@ public MappedText Text } } - /// - /// 获取当前激活的节点处理器。 - /// - public BlockProcessor ActivatedProcessor => parser.ActivatedProcessor; - /// /// 获取行是否是空的。 /// diff --git a/Cyjb.Markdown/ParseBlock/Processors/ATXHeadingProcessor.cs b/Cyjb.Markdown/ParseBlock/Processors/ATXHeadingProcessor.cs index 839224f..0d4599e 100644 --- a/Cyjb.Markdown/ParseBlock/Processors/ATXHeadingProcessor.cs +++ b/Cyjb.Markdown/ParseBlock/Processors/ATXHeadingProcessor.cs @@ -88,10 +88,11 @@ private sealed class BlockFactory : IBlockFactory /// /// 尝试开始当前块的解析。 /// + /// 块级语法分析器。 /// 要检查的行。 /// 当前匹配到的块处理器。 /// 如果能够开始当前块的解析,则返回解析器序列。否则返回空序列。 - public IEnumerable TryStart(BlockText line, BlockProcessor matchedProcessor) + public IEnumerable TryStart(BlockParser parser, BlockText line, BlockProcessor matchedProcessor) { if (line.IsCodeIndent) { diff --git a/Cyjb.Markdown/ParseBlock/Processors/BlockquoteProcessor.cs b/Cyjb.Markdown/ParseBlock/Processors/BlockquoteProcessor.cs index e117e70..04acd9d 100644 --- a/Cyjb.Markdown/ParseBlock/Processors/BlockquoteProcessor.cs +++ b/Cyjb.Markdown/ParseBlock/Processors/BlockquoteProcessor.cs @@ -104,10 +104,11 @@ private sealed class BlockFactory : IBlockFactory /// /// 尝试开始当前块的解析。 /// + /// 块级语法分析器。 /// 要检查的行。 /// 当前匹配到的块处理器。 /// 如果能够开始当前块的解析,则返回解析器序列。否则返回空序列。 - public IEnumerable TryStart(BlockText line, BlockProcessor matchedProcessor) + public IEnumerable TryStart(BlockParser parser, BlockText line, BlockProcessor matchedProcessor) { int start = line.Peek().Span.Start; if (CheckQuoteStart(line)) diff --git a/Cyjb.Markdown/ParseBlock/Processors/CustomContainerProcessor.cs b/Cyjb.Markdown/ParseBlock/Processors/CustomContainerProcessor.cs index 3accbb5..ff488b1 100644 --- a/Cyjb.Markdown/ParseBlock/Processors/CustomContainerProcessor.cs +++ b/Cyjb.Markdown/ParseBlock/Processors/CustomContainerProcessor.cs @@ -108,16 +108,17 @@ private sealed class BlockFactory : IBlockFactory /// /// 尝试开始当前块的解析。 /// + /// 块级语法分析器。 /// 要检查的行。 /// 当前匹配到的块处理器。 /// 如果能够开始当前块的解析,则返回解析器序列。否则返回空序列。 - public IEnumerable TryStart(BlockText line, BlockProcessor matchedProcessor) + public IEnumerable TryStart(BlockParser parser, BlockText line, BlockProcessor matchedProcessor) { if (line.IsCodeIndent) { yield break; } - MarkdownUtil.ParseFenceStart(line, out int start, out int _, + MarkdownUtil.ParseFenceStart(parser, line, out int start, out int _, out char _, out int fenceLength, out string? info, out HtmlAttributeList? attrs); yield return new CustomContainerProcessor(start, fenceLength, info, attrs); } diff --git a/Cyjb.Markdown/ParseBlock/Processors/FencedCodeBlockProcessor.cs b/Cyjb.Markdown/ParseBlock/Processors/FencedCodeBlockProcessor.cs index 267a263..4ae4341 100644 --- a/Cyjb.Markdown/ParseBlock/Processors/FencedCodeBlockProcessor.cs +++ b/Cyjb.Markdown/ParseBlock/Processors/FencedCodeBlockProcessor.cs @@ -114,16 +114,17 @@ private sealed class BlockFactory : IBlockFactory /// /// 尝试开始当前块的解析。 /// + /// 块级语法分析器。 /// 要检查的行。 /// 当前匹配到的块处理器。 /// 如果能够开始当前块的解析,则返回解析器序列。否则返回空序列。 - public IEnumerable TryStart(BlockText line, BlockProcessor matchedProcessor) + public IEnumerable TryStart(BlockParser parser, BlockText line, BlockProcessor matchedProcessor) { if (line.IsCodeIndent) { yield break; } - MarkdownUtil.ParseFenceStart(line, out int start, out int indent, + MarkdownUtil.ParseFenceStart(parser, line, out int start, out int indent, out char fenceChar, out int fenceLength, out string? info, out HtmlAttributeList? attrs); yield return new FencedCodeBlockProcessor(start, fenceChar, fenceLength, indent, info, attrs); } diff --git a/Cyjb.Markdown/ParseBlock/Processors/FootnoteProcessor.cs b/Cyjb.Markdown/ParseBlock/Processors/FootnoteProcessor.cs index 6997dba..070c1f6 100644 --- a/Cyjb.Markdown/ParseBlock/Processors/FootnoteProcessor.cs +++ b/Cyjb.Markdown/ParseBlock/Processors/FootnoteProcessor.cs @@ -105,10 +105,11 @@ private sealed class BlockFactory : IBlockFactory /// /// 尝试开始当前块的解析。 /// + /// 块级语法分析器。 /// 要检查的行。 /// 当前匹配到的块处理器。 /// 如果能够开始当前块的解析,则返回解析器序列。否则返回空序列。 - public IEnumerable TryStart(BlockText line, BlockProcessor matchedProcessor) + public IEnumerable TryStart(BlockParser parser, BlockText line, BlockProcessor matchedProcessor) { if (line.IsCodeIndent) { diff --git a/Cyjb.Markdown/ParseBlock/Processors/HtmlBlockProcessor.cs b/Cyjb.Markdown/ParseBlock/Processors/HtmlBlockProcessor.cs index 5ec0e36..e8c6b42 100644 --- a/Cyjb.Markdown/ParseBlock/Processors/HtmlBlockProcessor.cs +++ b/Cyjb.Markdown/ParseBlock/Processors/HtmlBlockProcessor.cs @@ -98,18 +98,19 @@ private sealed class BlockFactory : IBlockFactory /// /// 尝试开始当前块的解析。 /// + /// 块级语法分析器。 /// 要检查的行。 /// 当前匹配到的块处理器。 /// 如果能够开始当前块的解析,则返回解析器序列。否则返回空序列。 - public IEnumerable TryStart(BlockText line, BlockProcessor matchedProcessor) + public IEnumerable TryStart(BlockParser parser, BlockText line, BlockProcessor matchedProcessor) { if (line.IsCodeIndent) { yield break; } HtmlInfo info = (HtmlInfo)line.Peek().Value!; - if (!info.CanInterruptParagraph && (line.ActivatedProcessor.Kind == MarkdownKind.Paragraph || - line.ActivatedProcessor.CanLazyContinuation)) + if (!info.CanInterruptParagraph && (parser.ActivatedProcessor.Kind == MarkdownKind.Paragraph || + parser.ActivatedProcessor.CanLazyContinuation)) { // 不中断段落。 yield break; diff --git a/Cyjb.Markdown/ParseBlock/Processors/IBlockFactory.cs b/Cyjb.Markdown/ParseBlock/Processors/IBlockFactory.cs index 9d4c18a..8841b2e 100644 --- a/Cyjb.Markdown/ParseBlock/Processors/IBlockFactory.cs +++ b/Cyjb.Markdown/ParseBlock/Processors/IBlockFactory.cs @@ -8,8 +8,9 @@ internal interface IBlockFactory /// /// 尝试开始当前块的解析。 /// + /// 块级语法分析器。 /// 要检查的行。 /// 当前匹配到的块处理器。 /// 如果能够开始当前块的解析,则返回解析器序列。否则返回空序列。 - IEnumerable TryStart(BlockText line, BlockProcessor matchedProcessor); + IEnumerable TryStart(BlockParser parser, BlockText line, BlockProcessor matchedProcessor); } diff --git a/Cyjb.Markdown/ParseBlock/Processors/IndentedCodeBlockProcessor.cs b/Cyjb.Markdown/ParseBlock/Processors/IndentedCodeBlockProcessor.cs index 573a50e..f8a8d02 100644 --- a/Cyjb.Markdown/ParseBlock/Processors/IndentedCodeBlockProcessor.cs +++ b/Cyjb.Markdown/ParseBlock/Processors/IndentedCodeBlockProcessor.cs @@ -13,13 +13,14 @@ internal class IndentedCodeBlockProcessor : BlockProcessor /// /// 尝试开始新的缩进代码块处理器。 /// + /// 块级语法分析器。 /// 要检查的行。 /// 新的块处理器数组,若未能成功解析,则返回空数组。 - public static IEnumerable TryStart(BlockText line) + public static IEnumerable TryStart(BlockParser parser, BlockText line) { // 缩进代码块不会中断段落。 if (line.IsCodeIndent && !line.IsBlank() && - line.ActivatedProcessor.Kind != MarkdownKind.Paragraph) + parser.ActivatedProcessor.Kind != MarkdownKind.Paragraph) { // 代码块的起始位置包含缩进位置。 int start = line.Start; diff --git a/Cyjb.Markdown/ParseBlock/Processors/ListItemProcessor.cs b/Cyjb.Markdown/ParseBlock/Processors/ListItemProcessor.cs index da30ecd..c9851ed 100644 --- a/Cyjb.Markdown/ParseBlock/Processors/ListItemProcessor.cs +++ b/Cyjb.Markdown/ParseBlock/Processors/ListItemProcessor.cs @@ -75,7 +75,7 @@ public override BlockContinue TryContinue(BlockText line) { if (line.IsBlank()) { - if (item.Children.Count == 0 && line.ActivatedProcessor.Kind == MarkdownKind.ListItem) + if (item.Children.Count == 0 && parent.Parser.ActivatedProcessor.Kind == MarkdownKind.ListItem) { // 列表项最多可以包含一个起始空行,因此空列表项后的空行会闭合当前项。 return BlockContinue.None; @@ -83,7 +83,7 @@ public override BlockContinue TryContinue(BlockText line) else { // 记录已包含空行。 - MarkdownKind kind = line.ActivatedProcessor.Kind; + MarkdownKind kind = parent.Parser.ActivatedProcessor.Kind; hadBlankLine = kind == MarkdownKind.Paragraph || kind == MarkdownKind.ListItem; line.SkipIndent(); return BlockContinue.Continue; diff --git a/Cyjb.Markdown/ParseBlock/Processors/ListProcessor.cs b/Cyjb.Markdown/ParseBlock/Processors/ListProcessor.cs index 75f1822..cdaf3e0 100644 --- a/Cyjb.Markdown/ParseBlock/Processors/ListProcessor.cs +++ b/Cyjb.Markdown/ParseBlock/Processors/ListProcessor.cs @@ -48,14 +48,21 @@ internal sealed class ListProcessor : BlockProcessor /// /// 使用列表的标记字符和节点初始化 类的新实例。 /// + /// 块级语法分析器。 /// 列表的标记字符。 /// 列表节点。 - private ListProcessor(char marker, List list) : base(MarkdownKind.List) + private ListProcessor(BlockParser parser, char marker, List list) : base(MarkdownKind.List) { + Parser = parser; this.marker = marker; this.list = list; } + /// + /// 获取关联到的块级语法分析器。 + /// + public BlockParser Parser { get; } + /// /// 获取是否是容器节点。 /// @@ -172,10 +179,11 @@ private sealed class BlockFactory : IBlockFactory /// /// 尝试开始当前块的解析。 /// + /// 块级语法分析器。 /// 要检查的行。 /// 当前匹配到的块处理器。 /// 如果能够开始当前块的解析,则返回解析器序列。否则返回空序列。 - public IEnumerable TryStart(BlockText line, BlockProcessor matchedProcessor) + public IEnumerable TryStart(BlockParser parser, BlockText line, BlockProcessor matchedProcessor) { if (line.IsCodeIndent) { @@ -227,12 +235,12 @@ public IEnumerable TryStart(BlockText line, BlockProcessor match { Start = start }; - listProcessor = new ListProcessor(token.Text[^1], list); + listProcessor = new ListProcessor(parser, token.Text[^1], list); yield return listProcessor; } ListItemProcessor itemProcessor = new(listProcessor, itemStart, contentIndent); // 检查任务列表项。 - if (line.Options.UseTaskListItem) + if (parser.Options.UseTaskListItem) { itemProcessor.Checked = CheckTaskListItem(line); } diff --git a/Cyjb.Markdown/ParseBlock/Processors/MathBlockProcessor.cs b/Cyjb.Markdown/ParseBlock/Processors/MathBlockProcessor.cs index 87b1e02..4065114 100644 --- a/Cyjb.Markdown/ParseBlock/Processors/MathBlockProcessor.cs +++ b/Cyjb.Markdown/ParseBlock/Processors/MathBlockProcessor.cs @@ -107,16 +107,17 @@ private sealed class BlockFactory : IBlockFactory /// /// 尝试开始当前块的解析。 /// + /// 块级语法分析器。 /// 要检查的行。 /// 当前匹配到的块处理器。 /// 如果能够开始当前块的解析,则返回解析器序列。否则返回空序列。 - public IEnumerable TryStart(BlockText line, BlockProcessor matchedProcessor) + public IEnumerable TryStart(BlockParser parser, BlockText line, BlockProcessor matchedProcessor) { if (line.IsCodeIndent) { yield break; } - MarkdownUtil.ParseFenceStart(line, out int start, out int indent, + MarkdownUtil.ParseFenceStart(parser, line, out int start, out int indent, out char _, out int fenceLength, out string? info, out HtmlAttributeList? attrs); yield return new MathBlockProcessor(start, fenceLength, indent, info, attrs); } diff --git a/Cyjb.Markdown/ParseBlock/Processors/SetextHeadingProcessor.cs b/Cyjb.Markdown/ParseBlock/Processors/SetextHeadingProcessor.cs index f5b6e94..047951f 100644 --- a/Cyjb.Markdown/ParseBlock/Processors/SetextHeadingProcessor.cs +++ b/Cyjb.Markdown/ParseBlock/Processors/SetextHeadingProcessor.cs @@ -91,10 +91,11 @@ private sealed class BlockFactory : IBlockFactory /// /// 尝试开始当前块的解析。 /// + /// 块级语法分析器。 /// 要检查的行。 /// 当前匹配到的块处理器。 /// 如果能够开始当前块的解析,则返回解析器序列。否则返回空序列。 - public IEnumerable TryStart(BlockText line, BlockProcessor matchedProcessor) + public IEnumerable TryStart(BlockParser parser, BlockText line, BlockProcessor matchedProcessor) { // 要求 Setext 标签之前是段落,而且包含有效内容。 IList? lines; @@ -110,7 +111,7 @@ public IEnumerable TryStart(BlockText line, BlockProcessor match lines[^1].TrimEnd(); HtmlAttributeList? attrs = null; // 尝试解析属性。 - if (line.Options.UseHeaderAttributes) + if (parser.Options.UseHeaderAttributes) { attrs = ParseAttributes(lines); // 移除尾行后的空白。 diff --git a/Cyjb.Markdown/ParseBlock/Processors/TableProcessor.cs b/Cyjb.Markdown/ParseBlock/Processors/TableProcessor.cs index 7907a1b..6e725f1 100644 --- a/Cyjb.Markdown/ParseBlock/Processors/TableProcessor.cs +++ b/Cyjb.Markdown/ParseBlock/Processors/TableProcessor.cs @@ -230,10 +230,11 @@ private sealed class BlockFactory : IBlockFactory /// /// 尝试开始当前块的解析。 /// + /// 块级语法分析器。 /// 要检查的行。 /// 当前匹配到的块处理器。 /// 如果能够开始当前块的解析,则返回解析器序列。否则返回空序列。 - public IEnumerable TryStart(BlockText line, BlockProcessor matchedProcessor) + public IEnumerable TryStart(BlockParser parser, BlockText line, BlockProcessor matchedProcessor) { // 要求分割行之前是段落,而且包含且只包含一行。 IList? lines; diff --git a/Cyjb.Markdown/ParseBlock/Processors/ThematicBreakProcessor.cs b/Cyjb.Markdown/ParseBlock/Processors/ThematicBreakProcessor.cs index 5784d55..74418a7 100644 --- a/Cyjb.Markdown/ParseBlock/Processors/ThematicBreakProcessor.cs +++ b/Cyjb.Markdown/ParseBlock/Processors/ThematicBreakProcessor.cs @@ -56,10 +56,11 @@ private sealed class BlockFactory : IBlockFactory /// /// 尝试开始当前块的解析。 /// + /// 块级语法分析器。 /// 要检查的行。 /// 当前匹配到的块处理器。 /// 如果能够开始当前块的解析,则返回处理器序列。否则返回空序列。 - public IEnumerable TryStart(BlockText line, BlockProcessor matchedProcessor) + public IEnumerable TryStart(BlockParser parser, BlockText line, BlockProcessor matchedProcessor) { if (line.IsCodeIndent) { diff --git a/Cyjb.Markdown/Utils/MarkdownUtil.Fence.cs b/Cyjb.Markdown/Utils/MarkdownUtil.Fence.cs index daf0ae1..a0373cd 100644 --- a/Cyjb.Markdown/Utils/MarkdownUtil.Fence.cs +++ b/Cyjb.Markdown/Utils/MarkdownUtil.Fence.cs @@ -29,6 +29,7 @@ public static int GetFenceLength(ReadOnlySpan text) /// /// 解析分隔符的起始。 /// + /// 块级语法分析器。 /// 要解析的行信息。 /// 分隔符的起始索引。 /// 分隔符的缩进。 @@ -36,7 +37,7 @@ public static int GetFenceLength(ReadOnlySpan text) /// 分隔符的长度。 /// 分隔符的信息。 /// 分隔符的属性。 - public static void ParseFenceStart(BlockText line, out int start, out int indent, + public static void ParseFenceStart(BlockParser parser, BlockText line, out int start, out int indent, out char fenceChar, out int fenceLength, out string? info, out HtmlAttributeList? attrs) { @@ -59,7 +60,7 @@ public static void ParseFenceStart(BlockText line, out int start, out int indent info = null; } attrs = token.Value as HtmlAttributeList; - attrs?.AddPrefix(line.Options.AttributesPrefix); + attrs?.AddPrefix(parser.Options.AttributesPrefix); } else {