diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3f072af..bd1fd97 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,7 @@ Improvements
- Allow comparing Keybind and Combination based on the amount of modifiers they have
- Allow using multiple textures in a StaticSpriteBatch
- Added GenericInput support for Buttons.None
+- Improved the way terminating formatting codes work by introducing SimpleEndCode
Removals
- Marked AStar.InfiniteCost as obsolete
diff --git a/Demos/TextFormattingDemo.cs b/Demos/TextFormattingDemo.cs
index 3cd0b8f..152d4ab 100644
--- a/Demos/TextFormattingDemo.cs
+++ b/Demos/TextFormattingDemo.cs
@@ -12,7 +12,7 @@ namespace Demos {
private const string Text =
"MLEM's text formatting system allows for various formatting codes to be applied in the middle of a string. Here's a demonstration of some of them.\n\n" +
- "You can write in bold, italics, with an underline, strikethrough, or with a drop shadow whose color and offset you can modify in each application of the code.\n\n" +
+ "You can write in bold, italics, with an underline, strikethrough, with a drop shadow whose color and offset you can modify in each application of the code, or with various types of combined formatting codes.\n\n" +
"You can apply custom colors to text, including all default MonoGame colors and inline custom colors.\n\n" +
"You can also use animations like a wobbly one, as well as create custom ones using the Code class.\n\n" +
"You can also display icons in your text!\n\n" +
diff --git a/MLEM/Formatting/Codes/Code.cs b/MLEM/Formatting/Codes/Code.cs
index 1ffdc05..2ca18ce 100644
--- a/MLEM/Formatting/Codes/Code.cs
+++ b/MLEM/Formatting/Codes/Code.cs
@@ -39,13 +39,25 @@ namespace MLEM.Formatting.Codes {
///
/// Returns whether this formatting code should end when the passed formatting code starts.
/// If this method returns true, a new is started at its position.
+ /// This is the opposite version of .
///
- /// The code that is started here
- /// If this code should end
+ /// The code that is started here.
+ /// If this code should end here.
public virtual bool EndsHere(Code other) {
return other.GetType() == this.GetType();
}
+ ///
+ /// Returns whether the should end when this formatting code starts.
+ /// If this method returns true, a new is started at this code's position.
+ /// This is the opposite version of .
+ ///
+ /// The code that could end here.
+ /// Whether the code should end here.
+ public virtual bool EndsOther(Code other) {
+ return false;
+ }
+
///
public virtual Color? GetColor(Color defaultPick) {
return null;
diff --git a/MLEM/Formatting/Codes/FontCode.cs b/MLEM/Formatting/Codes/FontCode.cs
index 9db6ae2..52e96c1 100644
--- a/MLEM/Formatting/Codes/FontCode.cs
+++ b/MLEM/Formatting/Codes/FontCode.cs
@@ -18,10 +18,5 @@ namespace MLEM.Formatting.Codes {
return this.font?.Invoke(defaultPick);
}
- ///
- public override bool EndsHere(Code other) {
- return other is FontCode;
- }
-
}
}
diff --git a/MLEM/Formatting/Codes/ResetFormattingCode.cs b/MLEM/Formatting/Codes/ResetFormattingCode.cs
deleted file mode 100644
index 761ebf6..0000000
--- a/MLEM/Formatting/Codes/ResetFormattingCode.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System.Text.RegularExpressions;
-
-namespace MLEM.Formatting.Codes {
- ///
- public class ResetFormattingCode : Code {
-
- ///
- public ResetFormattingCode(Match match, Regex regex) : base(match, regex) {}
-
- ///
- public override bool EndsHere(Code other) {
- return true;
- }
-
- }
-}
diff --git a/MLEM/Formatting/Codes/ShadowCode.cs b/MLEM/Formatting/Codes/ShadowCode.cs
index 86878ba..942bf1a 100644
--- a/MLEM/Formatting/Codes/ShadowCode.cs
+++ b/MLEM/Formatting/Codes/ShadowCode.cs
@@ -24,10 +24,5 @@ namespace MLEM.Formatting.Codes {
return false;
}
- ///
- public override bool EndsHere(Code other) {
- return other is ShadowCode || other is ResetFormattingCode;
- }
-
}
}
diff --git a/MLEM/Formatting/Codes/SimpleEndCode.cs b/MLEM/Formatting/Codes/SimpleEndCode.cs
new file mode 100644
index 0000000..0c3aa38
--- /dev/null
+++ b/MLEM/Formatting/Codes/SimpleEndCode.cs
@@ -0,0 +1,20 @@
+using System.Text.RegularExpressions;
+
+namespace MLEM.Formatting.Codes {
+ ///
+ public class SimpleEndCode : Code {
+
+ private readonly Regex codeToEnd;
+
+ ///
+ public SimpleEndCode(Match match, Regex regex, string codeNameToEnd) : base(match, regex) {
+ this.codeToEnd = new Regex($"<{codeNameToEnd}.*>");
+ }
+
+ ///
+ public override bool EndsOther(Code other) {
+ return this.codeToEnd.IsMatch(other.Regex.ToString());
+ }
+
+ }
+}
diff --git a/MLEM/Formatting/Codes/UnderlineCode.cs b/MLEM/Formatting/Codes/UnderlineCode.cs
index 90aecf7..4d20a54 100644
--- a/MLEM/Formatting/Codes/UnderlineCode.cs
+++ b/MLEM/Formatting/Codes/UnderlineCode.cs
@@ -29,10 +29,5 @@ namespace MLEM.Formatting.Codes {
return false;
}
- ///
- public override bool EndsHere(Code other) {
- return other is UnderlineCode || other is ResetFormattingCode;
- }
-
}
}
diff --git a/MLEM/Formatting/TextFormatter.cs b/MLEM/Formatting/TextFormatter.cs
index 8fed25e..67b4562 100644
--- a/MLEM/Formatting/TextFormatter.cs
+++ b/MLEM/Formatting/TextFormatter.cs
@@ -40,8 +40,6 @@ namespace MLEM.Formatting {
new Vector2(float.TryParse(m.Groups[2].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var offset) ? offset : 2)));
this.Codes.Add(new Regex(""), (f, m, r) => new UnderlineCode(m, r, 1 / 16F, 0.85F));
this.Codes.Add(new Regex(""), (f, m, r) => new UnderlineCode(m, r, 1 / 16F, 0.55F));
- this.Codes.Add(new Regex("(s|u|st|l)>"), (f, m, r) => new ResetFormattingCode(m, r));
- this.Codes.Add(new Regex("(b|i|f)>"), (f, m, r) => new FontCode(m, r, null));
// color codes
foreach (var c in typeof(Color).GetProperties()) {
@@ -51,13 +49,14 @@ namespace MLEM.Formatting {
}
}
this.Codes.Add(new Regex(@""), (f, m, r) => new ColorCode(m, r, ColorHelper.FromHexString(m.Groups[1].Value)));
- this.Codes.Add(new Regex(""), (f, m, r) => new ColorCode(m, r, null));
// animation codes
this.Codes.Add(new Regex(@""), (f, m, r) => new WobblyCode(m, r,
float.TryParse(m.Groups[1].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var mod) ? mod : 5,
float.TryParse(m.Groups[2].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var heightMod) ? heightMod : 1 / 8F));
- this.Codes.Add(new Regex(""), (f, m, r) => new AnimatedCode(m, r));
+
+ // control codes
+ this.Codes.Add(new Regex(@"(\w+)>"), (f, m, r) => new SimpleEndCode(m, r, m.Groups[1].Value));
// macros
this.Macros.Add(new Regex("~"), (f, m, r) => GenericFont.Nbsp.ToCachedString());
@@ -101,7 +100,7 @@ namespace MLEM.Formatting {
index += strippedRet.Length;
// remove all codes that are incompatible with the next one and apply it
- codes.RemoveAll(c => c.EndsHere(next));
+ codes.RemoveAll(c => c.EndsHere(next) || next.EndsOther(c));
codes.Add(next);
}
return new TokenizedString(font, alignment, s, TextFormatter.StripFormatting(font, s, tokens.SelectMany(t => t.AppliedCodes)), tokens.ToArray());