using Textamina.Markdig.Parsing; namespace Textamina.Markdig.Syntax { /// /// Repressents a fenced code block. /// /// /// Related to CommonMark spec: 4.5 Fenced code blocks /// public class FencedCodeBlock : BlockLeaf { public static readonly BlockMatcher DefaultMatcher = new MatcherInternal(); public FencedCodeBlock() : base(DefaultMatcher) { } private class MatcherInternal : BlockMatcher { public override MatchLineState Match(ref StringLiner liner, MatchLineState matchLineState, ref object matchContext) { liner.SkipLeadingSpaces3(); if (matchLineState == MatchLineState.Continue) { var match = (MatchContext) matchContext; var c = liner.Current; int count = match.Count; var matchChar = match.FencedChar; while (!liner.IsEol) { if (c != matchChar || count < 0) { if (count > 0) { break; } return MatchLineState.Break; } c = liner.NextChar(); count--; } // TODO: It is unclear how to handle this correctly return MatchLineState.BreakAndKeepOnlyIfEof; } else { var c = liner.Current; int count = 0; var matchChar = (char)0; while (!liner.IsEol) { if (count == 0 && (c == '-' || c == '_' || c == '*')) { matchChar = c; } else if (c != matchChar) { if (count < 3) { break; } // Store the number of matched string into the context matchContext = new MatchContext(matchChar, count); return MatchLineState.Continue; } c = liner.NextChar(); count++; } return MatchLineState.Discard; } } public override Block New() { return new FencedCodeBlock(); } private class MatchContext { public MatchContext(char fencedChar, int count) { FencedChar = fencedChar; Count = count; } public char FencedChar; public int Count; } } } }