diff --git a/src/Spectre.Console/Internal/Text/Markup/MarkupTokenizer.cs b/src/Spectre.Console/Internal/Text/Markup/MarkupTokenizer.cs index 38de6e9c9..8f4106b5b 100644 --- a/src/Spectre.Console/Internal/Text/Markup/MarkupTokenizer.cs +++ b/src/Spectre.Console/Internal/Text/Markup/MarkupTokenizer.cs @@ -122,34 +122,55 @@ private bool ReadMarkup() var encounteredClosing = false; while (!_reader.Eof) { + var currentStylePartCanContainMarkup = + builder.ToString() + .Split(' ') + .Last() + .StartsWith("link=", StringComparison.OrdinalIgnoreCase); current = _reader.Peek(); - if (current == ']' && !encounteredOpening) + if (currentStylePartCanContainMarkup) { - if (encounteredClosing) + switch (current) { - builder.Append(_reader.Read()); - encounteredClosing = false; - continue; + case ']' when !encounteredOpening: + if (encounteredClosing) + { + builder.Append(_reader.Read()); + encounteredClosing = false; + continue; + } + + _reader.Read(); + encounteredClosing = true; + continue; + + case '[' when !encounteredClosing: + if (encounteredOpening) + { + builder.Append(_reader.Read()); + encounteredOpening = false; + continue; + } + + _reader.Read(); + encounteredOpening = true; + continue; } - - _reader.Read(); - encounteredClosing = true; - continue; } - - if (current == '[' && !encounteredClosing) + else { - if (encounteredOpening) + switch (current) { - builder.Append(_reader.Read()); - encounteredOpening = false; - continue; + case ']': + _reader.Read(); + encounteredClosing = true; + break; + case '[': + _reader.Read(); + encounteredOpening = true; + break; } - - _reader.Read(); - encounteredOpening = true; - continue; } if (encounteredClosing) diff --git a/test/Spectre.Console.Tests/Unit/AnsiConsoleTests.Markup.cs b/test/Spectre.Console.Tests/Unit/AnsiConsoleTests.Markup.cs index c00bde333..01bbfa6ce 100644 --- a/test/Spectre.Console.Tests/Unit/AnsiConsoleTests.Markup.cs +++ b/test/Spectre.Console.Tests/Unit/AnsiConsoleTests.Markup.cs @@ -154,5 +154,25 @@ public void Should_Not_Get_Confused_When_Mixing_Escaped_And_Unescaped() // Then console.Output.ShouldBe("[grey][white]"); } + + [Theory] + [InlineData("[white][[[/][white]]][/]", "[]")] + [InlineData("[white][[[/]", "[")] + [InlineData("[white]]][/]", "]")] + [InlineData("[black on white link=https://www.gooole.com/q=]]]Search for a bracket[/]", "Search for a bracket")] + [InlineData("[link=https://www.gooole.com/q=]] black on white]Search for a bracket[/]", "Search for a bracket")] + [InlineData("[link]https://www.gooole.com/q=]][/]", "https://www.gooole.com/q=]")] + public void Should_Not_Fail_As_In_GH1024(string markup, string expected) + { + // Given + var console = new TestConsole(); + console.EmitAnsiSequences = false; + + // When + console.Markup(markup); + + // Then + console.Output.ShouldBe(expected); + } } }