Files
markdig/src/Textamina.Markdig/Syntax/FencedCodeBlock.cs

93 lines
2.8 KiB
C#
Raw Normal View History

2016-02-10 00:54:08 +09:00
2016-02-10 20:30:38 +09:00
using Textamina.Markdig.Parsing;
namespace Textamina.Markdig.Syntax
2016-02-10 00:54:08 +09:00
{
/// <summary>
/// Repressents a fenced code block.
/// </summary>
/// <remarks>
/// Related to CommonMark spec: 4.5 Fenced code blocks
/// </remarks>
public class FencedCodeBlock : BlockLeaf
{
public static readonly BlockParser Parser = new ParserInternal();
2016-02-10 00:54:08 +09:00
private int fencedCharCount;
2016-02-10 00:54:08 +09:00
private char fencedChar;
private bool hasFencedEnd;
private class ParserInternal : BlockParser
2016-02-10 00:54:08 +09:00
{
public override MatchLineResult Match(ref StringLiner liner, ref Block block)
2016-02-10 00:54:08 +09:00
{
2016-02-10 20:30:38 +09:00
liner.SkipLeadingSpaces3();
var fenced = block as FencedCodeBlock;
if (fenced != null)
2016-02-10 00:54:08 +09:00
{
var c = liner.Current;
int count = fenced.fencedCharCount;
var matchChar = fenced.fencedChar;
2016-02-10 00:54:08 +09:00
while (!liner.IsEol)
{
if (c != matchChar || count < 0)
{
if (count > 0)
{
break;
}
fenced.hasFencedEnd = true;
return MatchLineResult.Last;
2016-02-10 00:54:08 +09:00
}
c = liner.NextChar();
count--;
}
// TODO: It is unclear how to handle this correctly
// Break only if Eof
return MatchLineResult.Continue;
2016-02-10 00:54:08 +09:00
}
else
{
var c = liner.Current;
int count = 0;
var matchChar = (char)0;
while (!liner.IsEol)
{
if (count == 0 && (c == '`' || c == '~'))
2016-02-10 00:54:08 +09:00
{
matchChar = c;
}
else if (c != matchChar)
{
if (count < 3)
{
break;
}
// Store the number of matched string into the context
block = new FencedCodeBlock()
{
fencedChar = matchChar,
fencedCharCount = count
};
return MatchLineResult.Continue;
2016-02-10 00:54:08 +09:00
}
c = liner.NextChar();
count++;
}
return MatchLineResult.None;
2016-02-10 00:54:08 +09:00
}
}
}
}
}