Here is another option (the syntax formatter is mine, implement your own according to your syntax):
private void ReplaceTokensWithControl(Run run)
{
var text = run.Text;
bool inToken = false;
var startIndex = 0;
var endIndex = 0;
for (var i = 0; i < text.Length; i++)
{
if (Char.IsWhiteSpace(text[i]) | SyntaxFormatter.TextControlSpecialTokens.Contains(text[i]))
{
if (i > 0 && !(Char.IsWhiteSpace(text[i - 1]) | SyntaxFormatter.TextControlSpecialTokens.Contains(text[i - 1])))
{
endIndex = i - 1;
string token = text.Substring(startIndex, endIndex - startIndex + 1);
string tokenContext = text.Substring(0, startIndex);
if (SyntaxFormatter.IsTextControlToken(token, tokenContext))
{
var textBefore = run.Text.Substring(0, startIndex);
var runBefore = new Run(textBefore);
run.ContentStart.Paragraph.Inlines.InsertBefore(run, runBefore);
Run runAfter = null;
if (endIndex + 1 < run.Text.Length)
{
var textAfter = run.Text.Substring(endIndex + 1, run.Text.Length - (endIndex + 1));
runAfter = new Run(textAfter);
run.ContentStart.Paragraph.Inlines.InsertAfter(runBefore, runAfter);
}
runBefore.ContentStart
.Paragraph
.Inlines
.InsertAfter(runBefore,new InlineUIContainer(SyntaxFormatter.GetTokenTextControl(text, tokenContext)));
run.ContentStart.Paragraph.Inlines.Remove(run);
if (runAfter != null)
ReplaceTokensWithControl(runAfter);
return;
}
}
}
else
{
if (!inToken)
{
inToken = true;
startIndex = i;
}
}
}