Skip to content

SadConsole string parser: Overview

SadConsole includes a string processing system that lets you easily apply styles and effects to strings without writing code. For example, you can use the string parser to change the foreground or background of text in the string. You can also create your own commands.

The string parser generates a ColoredString object, which represents each character in the string with an associated foreground color, background color, mirrored setting, and effect.

To learn more about the parser syntax, see String parser syntax.

The parser instance and commands are available in the SadConsole.StringParser namespace. The following table describes the objects in that namespace:

ClassDescription
IParserAn interface that contains the Parse method that transforms a string into a ColoredString.
DefaultSadConsole’s built-in parser that supports the parser commands.
ParseCommandBaseThe base class for a SadConsole parser command.
ParseCommandBlinkApplies an effect to a glyph.
ParseCommandClearEffectRemoves an effect from a glyph.
ParseCommandDecoratorSets a decorator on a glyph.
ParseCommandGradientApplies a gradient of colors across multiple glyphs.
ParseCommandMirrorSets the mirror setting on a glyph.
ParseCommandRecolorChanges the foreground or background color of a glyph.
ParseCommandSetGlyphChanges the character of a glyph.
ParseCommandStacksHolds the active commands applied across the glyphs in a string.
ParseCommandUndoRemoves the previous command from the stack of commands.

For more information about how to use the commands, see String parser syntax.

The Default parser is available through the ColoredString.Parser property.

Three parts of SadConsole can parse a string to generate a ColoredString object:

  • ColoredString.Parser

    This property is configured to use the built-in parser. The rest of SadConsole uses it to parse strings. You can use it directly to parse a string.

    ColoredString.Parser.Parse("Normal [c:r f:Blue][c:r b:Yellow]and colored");

    To learn more about the parser syntax, see String parser syntax.

  • The Print methods on surfaces.

    If the UsePrintProcessor property of the surface is set to true, the string printed is first passed through the string parser.

    The UsePrintProcessor property is set to false by default.

    Even if UsePrintProcessor is set to false, you can still print parsed strings by using the Print(ISurface, int, int, ColoredString) overload, which takes a ColoredString instance. First, use ColoredString.Parser to parse the string and generate the ColoredString instance, then call the Print method.

  • The Print methods on cursors.

    If the UseStringParser property of a cursor is set to true, the string printed is first passed through the string parser before the cursor starts printing characters.

    The UseStringParser property is set to false by default.

    Even if UseStringParser is set to false, you can still print parsed strings by using the Print(ColoredString) overload, which takes a ColoredString instance. First, use ColoredString.Parser to parse the string and generate the ColoredString instance, then call the Print method.

SadConsole’s default parser supports a find-and-replace system when parsing a string. “Variable” names are added to a dictionary in the parser and associated with a delegate that returns a string. Instead of a simple find-and-replace system where a named string is replaced with a string value, the delegates are invoked to generate a string. This means you get to run code to calculate values and generate the replacement string.

Variables are marked in the parsed string with $$name where name is the name of the variable-value you want to place into the string.

The following code adds two variables to the parser, first_name and last_name. The delegates assigned to the variables return a name when the variable is found in the string.

var castedParser = (SadConsole.StringParser.Default)SadConsole.ColoredString.Parser;
castedParser.Variables["first_name"] = () => "John";
castedParser.Variables["last_name"] = () => "Smith";
castedParser.Parse("The player's name is $$first_name $$last_name.");
// Creates the following colored string text:
// The player's name is John Smith.

The string parser looks for command triggers in the string it’s parsing, but it only knows to look for the built-in commands. You can extend the parsing logic to look for triggers of your own commands. The extended parser logic runs first, and if no command is returned, the built-in system processes the command trigger. With this logic, you can provide your own commands with new triggers or override the existing triggers with new commands.

The following code attaches a delegate named CustomParseCommand to the parser’s CustomProcessor property:

((Default)ColoredString.Parser).CustomProcessor = CustomParseCommand;

The magic keyword trigger is [c:name where name is the command name. The command name is sent to the command parser. The parameters, which is the rest of the command string until ] is encountered, are passed as the parameters of the command.

The following example is the parser extension registered in the preceding code. The logic checks for the command name t or retext, and if found, returns that command. If the name doesn’t match, null is returned, which lets the parser check the built-in commands.

private ParseCommandBase? CustomParseCommand(string command, string parameters, ColoredGlyphBase[] glyphString,
ICellSurface? surface, ParseCommandStacks? commandStacks)
{
return command switch
{
"retext" => new ParseCommandRetext(parameters),
"t" => new ParseCommandRetext(parameters),
_ => null,
};
}

With the parser method declared, you can create a new command type based on the ParseCommandBase type. This type has one important method, Build. The Build method takes in a colored glyph instance and transforms it according to the command. The command must set the CommandType property to the aspect of the glyph the command manipulates; otherwise, it won’t be processed when parsing the string. There are six different types of valid commands:

TypeDescription
ForegroundCommand is added to the foreground stack of commands.
BackgroundCommand is added to the background stack of commands.
GlyphCommand is added to the glyph stack of commands.
SpriteEffectCommand is added to the SpriteEffect (mirror) stack of commands.
EffectCommand is added to the cell effect stack of commands.
PureCommandCommand isn’t added to the list of active commands, and its Build method is never called. It’s only created once during creation and can manipulate things. The Undo command behaves like this.

The following code example demonstrates the t command declared in the preceding code example. The command changes the glyphs in the string to a specific glyph. The command’s parameters expect a character and an optional count of how many glyphs to change: [c:t glyph_index[:count]]

private class ParseCommandRetext : ParseCommandBase
{
public int Counter;
public char Glyph;
public ParseCommandRetext(string parameters)
{
string[] parts = parameters.Split(new char[] { ':' }, 2);
// Count and glyph type provided
if (parts.Length == 2)
Counter = int.Parse(parts[1]);
else
Counter = -1;
// Get character
Glyph = parts[0][0];
// No exceptions, set the type
CommandType = CommandTypes.Glyph;
}
public override void Build(ref ColoredGlyphAndEffect glyphState, ColoredGlyphAndEffect[] glyphString, int surfaceIndex, ICellSurface surface, ref int stringIndex, System.ReadOnlySpan<char> processedString, ParseCommandStacks commandStack)
{
glyphState.Glyph = Glyph;
if (Counter != -1)
{
Counter--;
if (Counter == 0)
commandStack.RemoveSafe(this);
}
}
}

The command can be triggered by adding the syntax to a string that’s parsed:

The text after the command [c:t Z]is changed to 'Z'.

Which outputs the following text:

The text after the command ZZZZZZZZZZZZZZZZZZ