private bool TestForParagraph() { // both paragraphs and footer are separated from previous paragraphs and the header using a blank line. // If there is at least 1 blank line followed by a non-blank line, // the line could be either the first line of the next paragraph of the first footer. // To determine if we reached the end of the body, test if the next line is // When 'IgnoreDuplicateBlankLines' is set, skip all consecutive blank lines // otherwise, expect only a single blank line if (m_Mode.HasFlag(ParserMode.IgnoreDuplicateBlankLines)) { return (TestTokens(LineTokenKind.Blank, out var blanklineCount) && // check for at least one blank line TestToken(LineTokenKind.Line, blanklineCount) && // check if blank lines are followed by a non-blank line(look ahead the number of blank lines matched) !FooterParser.IsFooter(Peek(blanklineCount))); // check if the line is the start of a footer } else { return (TestToken(LineTokenKind.Blank) && TestToken(LineTokenKind.Line, 1) && !FooterParser.IsFooter(Peek(1))); } }
private IReadOnlyList <CommitMessageFooter> ParseFooters() { // Footers are separated by the message body using a blank line. // There must be at least one blank line, // if the 'IgnoreDuplicateBlankLines' option is set, // multiple consecutive blank lines are treated the same as a single blank line. if (m_Mode.HasFlag(ParserMode.IgnoreDuplicateBlankLines)) { MatchTokens(LineTokenKind.Blank, 1); } else { MatchToken(LineTokenKind.Blank); } var footers = new List <CommitMessageFooter>(); // 'IgnoreTrailingBlankLines' is set, there might not be a parse-able footer present in the message // an we will only encounter blank lines, so it is not an error, if no non-blank line is found. // However if 'IgnoreTrailingBlankLines' is *not* set, there must be a at lease one footer after the blank line if (m_Mode.HasFlag(ParserMode.IgnoreTrailingBlankLines)) { while (TestAndMatchToken(LineTokenKind.Line, out var currentLine)) { footers.Add(FooterParser.Parse(currentLine)); // ignore blank lines between footers when option is set if (m_Mode.HasFlag(ParserMode.AllowBlankLinesBetweenFooters)) { MatchTokens(LineTokenKind.Blank, 0); } } } else if (!TestToken(LineTokenKind.Eof)) { do { var currentLine = MatchToken(LineTokenKind.Line); footers.Add(FooterParser.Parse(currentLine)); // ignore blank lines between footers when option is set if (m_Mode.HasFlag(ParserMode.AllowBlankLinesBetweenFooters)) { MatchTokens(LineTokenKind.Blank, 0); } } while (TestToken(LineTokenKind.Line)); } return(footers); }