private static XInline ParseInlineString(string str)
{
var inlines = new List<XInline>();
bool formattedInlineMatch;
int searchStartIndex = 0;
do
{
formattedInlineMatch = false;
const string boldDelimiter = "**";
const string italicDelimiter = "*";
var boldStart = str.IndexOf(boldDelimiter, searchStartIndex, StringComparison.Ordinal);
var italicStart = str.IndexOf(italicDelimiter, searchStartIndex, StringComparison.Ordinal);
var newLineStart = str.IndexOf("\n", searchStartIndex, StringComparison.Ordinal);
searchStartIndex = 0;
// Fix escaped characters
while (italicStart > 0 && str[italicStart - 1] == '\\')
{
// Make sure backslash is not escaped
if (italicStart > 1 && str[italicStart - 2] == '\\')
{
// We are good to fix italicStart
var startIndex = italicStart + 1;
str = str.Remove(italicStart - 1, 1);
if (startIndex >= str.Length)
{
italicStart = -1;
break;
}
// Remove escape character for *
italicStart = str.IndexOf(italicDelimiter, startIndex, StringComparison.Ordinal);
}
else
{
str = str.Remove(italicStart - 1, 1);
boldStart = str.IndexOf(boldDelimiter, italicStart, StringComparison.Ordinal);
newLineStart = str.IndexOf("\n", italicStart, StringComparison.Ordinal);
italicStart = str.IndexOf(italicDelimiter, italicStart, StringComparison.Ordinal);
break;
}
}
if (newLineStart != -1 &&
(newLineStart < boldStart || boldStart == -1) &&
(newLineStart < italicStart || italicStart == -1))
{
if (newLineStart == 0)
{
inlines.Add(new XLineBreak());
str = str.Substring(1);
}
else
{
inlines.Add(new XRun(str.Substring(0, newLineStart)));
str = str.Substring(newLineStart + 1);
inlines.Add(new XLineBreak());
}
formattedInlineMatch = true;
}
else if (boldStart != -1 && boldStart <= italicStart)
{
try
{
str = ParseNextInline(str, boldDelimiter, boldStart, inlines, s => new XBold(s));
}
catch (ArgumentOutOfRangeException)
{
searchStartIndex = boldStart + 1;
}
formattedInlineMatch = true;
}
else if (italicStart != -1)
{
try
{
str = ParseNextInline(str, italicDelimiter, italicStart, inlines, s => new XItalic(s));
}
catch (ArgumentOutOfRangeException)
{
searchStartIndex = italicStart + 1;
}
formattedInlineMatch = true;
}
} while (formattedInlineMatch);
if (!string.IsNullOrEmpty(str))
inlines.Add(new XRun(str));
if (inlines.Count == 1)
return inlines[0];
return new XSpan(inlines.ToArray());
}