Class
Sealed
public sealed class ChangelogParser : BlockParser
Namespace: Moka.Docs.Parsing.Markdown
Parses
::: changelog blocks. Collects all inner lines as raw text so the renderer can parse version entries, types, categories, and items.Inheritance
Inherits from: BlockParser
Constructors
| Name | Description |
|---|---|
ChangelogParser() |
Methods
| Name | Description |
|---|---|
TryContinue(BlockProcessor processor, Block block) override |
|
TryOpen(BlockProcessor processor) override |
Type Relationships
classDiagram
style ChangelogParser fill:#f9f,stroke:#333,stroke-width:2px
ChangelogParser --|> BlockParser : inherits
View Source
#endregion
#region Parser
/// <summary>
/// Parses <c>::: changelog</c> blocks. Collects all inner lines as raw text
/// so the renderer can parse version entries, types, categories, and items.
/// </summary>
public sealed class ChangelogParser : BlockParser
{
public ChangelogParser()
{
OpeningCharacters = [':'];
}
/// <inheritdoc/>
public override BlockState TryOpen(BlockProcessor processor)
{
if (processor.IsCodeIndent)
{
return BlockState.None;
}
StringSlice line = processor.Line;
int start = line.Start;
if (line.CurrentChar != ':')
{
return BlockState.None;
}
int colons = MarkdigHelpers.CountAndSkipChar(ref line, ':');
if (colons < 3)
{
return BlockState.None;
}
line.TrimStart();
string remaining = line.ToString().Trim();
if (!string.Equals(remaining, "changelog", StringComparison.OrdinalIgnoreCase))
{
return BlockState.None;
}
var block = new ChangelogBlock(this)
{
Span = new SourceSpan(start, line.End),
Column = processor.Column
};
processor.NewBlocks.Push(block);
return BlockState.ContinueDiscard;
}
/// <inheritdoc/>
public override BlockState TryContinue(BlockProcessor processor, Block block)
{
if (block is not ChangelogBlock changelogBlock)
{
return BlockState.None;
}
StringSlice line = processor.Line;
// Check for closing :::
if (line.CurrentChar == ':')
{
StringSlice saved = line;
int colons = MarkdigHelpers.CountAndSkipChar(ref line, ':');
if (colons >= 3)
{
string after = line.ToString().Trim();
if (string.IsNullOrEmpty(after))
{
block.UpdateSpanEnd(line.End);
return BlockState.BreakDiscard;
}
}
processor.Line = saved;
}
// Collect the raw line
changelogBlock.RawLines.Add(processor.Line.ToString());
return BlockState.ContinueDiscard;
}
}