public override BlockState TryOpen()

in src/Elastic.Markdown/Myst/Comments/CommentBlockParser.cs [56:151]


	public override BlockState TryOpen(BlockProcessor processor)
	{
		// If we are in a CodeIndent, early exit
		if (processor.IsCodeIndent)
			return BlockState.None;

		var column = processor.Column;
		var line = processor.Line;
		var sourcePosition = line.Start;
		var c = line.CurrentChar;
		var matchingChar = c;

		Debug.Assert(MaxLeadingCount > 0);
		var leadingCount = 0;
		while (c != '\0' && leadingCount <= MaxLeadingCount)
		{
			if (c != matchingChar)
				break;
			c = processor.NextChar();
			leadingCount++;
		}

		// A space is required after leading %
		if (leadingCount > 0 && leadingCount <= MaxLeadingCount && (c.IsSpaceOrTab() || c == '\0'))
		{
			if (processor.TrackTrivia && c.IsSpaceOrTab())
				_ = processor.NextChar();

			// Move to the content
			var headingBlock = new CommentBlock(this)
			{
				CommentChar = matchingChar,
				Level = leadingCount,
				Column = column,
				Span = { Start = sourcePosition },
			};

			if (processor.TrackTrivia)
			{
				headingBlock.TriviaBefore = processor.UseTrivia(sourcePosition - 1);

				var linesBefore = processor.LinesBefore;
				processor.LinesBefore = null;
				headingBlock.LinesBefore = linesBefore;
				headingBlock.NewLine = processor.Line.NewLine;
			}
			else
				processor.GoToColumn(column + leadingCount + 1);

			processor.NewBlocks.Push(headingBlock);

			// The optional closing sequence of #s must be preceded by a space and may be followed by spaces only.
			var endState = 0;
			var countClosingTags = 0;
			for (var i = processor.Line.End;
				 i >= processor.Line.Start - 1;
				 i--) // Go up to Start - 1 in order to match the space after the first ###
			{
				c = processor.Line.Text[i];
				if (endState == 0)
				{
					if (c.IsSpaceOrTab())
						continue;
					endState = 1;
				}

				if (endState == 1)
				{
					if (c == matchingChar)
					{
						countClosingTags++;
						continue;
					}

					if (countClosingTags > 0)
					{
						if (c.IsSpaceOrTab())
							processor.Line.End = i - 1;
					}

					break;
				}
			}

			// Set up the source end position of this element
			headingBlock.Span.End = processor.Line.End;

			// We expect a single line, so don't continue
			return BlockState.Break;
		}

		// Else we don't have an header
		processor.Line.Start = sourcePosition;
		processor.Column = column;
		return BlockState.None;
	}