diff --git a/examples/Figlet/Figlet.csproj b/examples/Figlet/Figlet.csproj new file mode 100644 index 0000000..de0a616 --- /dev/null +++ b/examples/Figlet/Figlet.csproj @@ -0,0 +1,15 @@ + + + + Exe + net5.0 + false + Figlet + Demonstrates how to render FIGlet text. + + + + + + + diff --git a/examples/Figlet/Program.cs b/examples/Figlet/Program.cs new file mode 100644 index 0000000..0310a7b --- /dev/null +++ b/examples/Figlet/Program.cs @@ -0,0 +1,14 @@ +using Spectre.Console; + +namespace EmojiExample +{ + public static class Program + { + public static void Main(string[] args) + { + AnsiConsole.Render(new FigletText("Left aligned").LeftAligned().Color(Color.Red)); + AnsiConsole.Render(new FigletText("Centered").Centered().Color(Color.Green)); + AnsiConsole.Render(new FigletText("Right aligned").RightAligned().Color(Color.Blue)); + } + } +} diff --git a/src/Spectre.Console.Tests/Data/starwars.flf b/src/Spectre.Console.Tests/Data/starwars.flf new file mode 100644 index 0000000..6ea55f0 --- /dev/null +++ b/src/Spectre.Console.Tests/Data/starwars.flf @@ -0,0 +1,719 @@ +flf2a$ 7 6 22 15 4 +starwars.flf by Ryan Youck (youck@cs.uregina.ca) Dec 25/1994 +I am not responsible for use of this font +Based on Big.flf by Glenn Chappell + +$ $@ +$ $@ +$ $@ +$ $@ +$ $@ +$ $@ +$ $@@ + __ $@ +| |$@ +| |$@ +| |$@ +|__|$@ +(__)$@ + $@@ + _ _ @ +( | )@ + V V @ + $ @ + $ @ + $ @ + @@ + _ _ @ + _| || |_$@ +|_ __ _|@ + _| || |_ @ +|_ __ _|@ + |_||_| $@ + @@ + __,--,_.@ + / |@ + | (----`@ + \ \ $@ +.----) | $@ +|_ __/ $@ + '--' $@@ + _ ___$ @ + / \ / /$ @ +( o ) / / $ @ + \_/ / / _$ @ + / / / \ @ + / / ( o )@ + /__/ \_/ @@ + @ + ___ @ + ( _ ) $@ + / _ \/\@ +| (_> <@ + \___/\/@ + $@@ + __ @ +(_ )@ + |/ @ + $ @ + $ @ + $ @ + @@ + ___@ + / /@ +| |$@ +| |$@ +| |$@ +| |$@ + \__\@@ +___ @ +\ \ @ + | |@ + | |@ + | |@ + | |@ +/__/ @@ + _ @ + /\| |/\ @ + \ ` ' /$@ +|_ _|@ + / , . \$@ + \/|_|\/ @ + @@ + @ + _ @ + _| |_$@ +|_ _|@ + |_| $@ + $ @ + @@ + @ + @ + $ @ + $ @ + __ @ +(_ )@ + |/ @@ + @ + @ + ______ @ +|______|@ + $ @ + $ @ + @@ + @ + @ + @ + $ @ + __ @ +(__)@ + @@ + ___@ + / /@ + / / @ + / /$ @ + / /$ @ +/__/$ @ + @@ + ___ $@ + / _ \ $@ +| | | |$@ +| | | |$@ +| |_| |$@ + \___/ $@ + $@@ + __ $@ +/_ |$@ + | |$@ + | |$@ + | |$@ + |_|$@ + $@@ + ___ $@ +|__ \ $@ + $) |$@ + / / $@ + / /_ $@ +|____|$@ + $@@ + ____ $@ +|___ \ $@ + __) |$@ + |__ < $@ + ___) |$@ +|____/ $@ + $@@ + _ _ $@ +| || | $@ +| || |_ $@ +|__ _|$@ + | | $@ + |_| $@ + $@@ + _____ $@ +| ____|$@ +| |__ $@ +|___ \ $@ + ___) |$@ +|____/ $@ + $@@ + __ $@ + / / $@ + / /_ $@ +| '_ \ $@ +| (_) |$@ + \___/ $@ + $@@ + ______ $@ +|____ |$@ + $/ / $@ + / / $@ + / / $@ + /_/ $@ + $@@ + ___ $@ + / _ \ $@ +| (_) |$@ + > _ < $@ +| (_) |$@ + \___/ $@ + $@@ + ___ $@ + / _ \ $@ +| (_) |$@ + \__, |$@ + / / $@ + /_/ $@ + $@@ + @ + _ @ +(_)@ + $ @ + _ @ +(_)@ + @@ + @ + _ @ +(_)@ + $ @ + _ @ +( )@ +|/ @@ + ___@ + / /@ + / /$@ +< <$ @ + \ \$@ + \__\@ + @@ + @ + ______ @ +|______|@ + ______ @ +|______|@ + @ + @@ +___ @ +\ \$ @ + \ \ @ + > >@ + / / @ +/__/$ @ + @@ + ______ $@ +| \ $@ +`----) |$@ + / / $@ + |__| $@ + __ $@ + (__) $@@ + ____ @ + / __ \ @ + / / _` |@ +| | (_| |@ + \ \__,_|@ + \____/ @ + @@ + ___ $ @ + / \ $ @ + / ^ \$ @ + / /_\ \$ @ + / _____ \$ @ +/__/ \__\$@ + $@@ +.______ $@ +| _ \ $@ +| |_) |$@ +| _ < $@ +| |_) |$@ +|______/ $@ + $@@ + ______$@ + / |@ +| ,----'@ +| | $@ +| `----.@ + \______|@ + $@@ + _______ $@ +| \$@ +| .--. |@ +| | | |@ +| '--' |@ +|_______/$@ + $@@ + _______ @ +| ____|@ +| |__ $@ +| __| $@ +| |____ @ +|_______|@ + @@ + _______ @ +| ____|@ +| |__ $@ +| __| $@ +| | $ @ +|__| @ + @@ + _______ @ + / _____|@ +| | __ $@ +| | |_ |$@ +| |__| |$@ + \______|$@ + $@@ + __ __ $@ +| | | |$@ +| |__| |$@ +| __ |$@ +| | | |$@ +|__| |__|$@ + $@@ + __ $@ +| |$@ +| |$@ +| |$@ +| |$@ +|__|$@ + $@@ + __ $@ + | |$@ + | |$@ +.--. | |$@ +| `--' |$@ + \______/ $@ + $@@ + __ ___$@ +| |/ /$@ +| ' / $@ +| < $@ +| . \ $@ +|__|\__\$@ + $@@ + __ $@ +| | $@ +| | $@ +| | $@ +| `----.@ +|_______|@ + $@@ +.___ ___.$@ +| \/ |$@ +| \ / |$@ +| |\/| |$@ +| | | |$@ +|__| |__|$@ + $@@ +.__ __.$@ +| \ | |$@ +| \| |$@ +| . ` |$@ +| |\ |$@ +|__| \__|$@ + $@@ + ______ $@ + / __ \ $@ +| | | |$@ +| | | |$@ +| `--' |$@ + \______/ $@ + $@@ +.______ $@ +| _ \ $@ +| |_) |$@ +| ___/ $@ +| | $ @ +| _| $ @ + $ @@ + ______ $ @ + / __ \ $ @ +| | | | $ @ +| | | | $ @ +| `--' '--. @ + \_____\_____\@ + $ @@ +.______ $ @ +| _ \ $ @ +| |_) | $ @ +| / $ @ +| |\ \----.@ +| _| `._____|@ + $@@ + _______.@ + / |@ + | (----`@ + \ \ $@ +.----) | $@ +|_______/ $@ + $@@ +.___________.@ +| |@ +`---| |----`@ + | | $ @ + | | $ @ + |__| $ @ + $ @@ + __ __ $@ +| | | |$@ +| | | |$@ +| | | |$@ +| `--' |$@ + \______/ $@ + $@@ +____ ____$@ +\ \ / /$@ + \ \/ /$ @ + \ /$ @ + \ /$ @ + \__/$ @ + $ @@ +____ __ ____$@ +\ \ / \ / /$@ + \ \/ \/ /$ @ + \ /$ @ + \ /\ /$ @ + \__/ \__/$ @ + $ @@ +___ ___$@ +\ \ / /$@ + \ V / $@ + > < $@ + / . \ $@ +/__/ \__\$@ + $@@ +____ ____$@ +\ \ / /$@ + \ \/ /$ @ + \_ _/$ @ + | |$ @ + |__|$ @ + $ @@ + ________ $@ +| / $@ +`---/ / $@ + / / $@ + / /----.@ + /________|@ + $@@ + ____ @ +| |@ +| |-`@ +| | $@ +| | $@ +| |-.@ +|____|@@ +___ @ +\ \ $ @ + \ \$ @ + \ \$ @ + \ \$@ + \__\@ + @@ + ____ @ +| |@ +`-| |@ + | |@ + | |@ +.-| |@ +|____|@@ + ___ @ + / \ @ +/--^--\@ + $@ + $@ + $@ + $@@ + @ + @ + @ + $ @ + $ @ + ______ @ +|______|@@ + __ @ +( _)@ + \| @ + $ @ + $ @ + $ @ + @@ + ___ $ @ + / \ $ @ + / ^ \$ @ + / /_\ \$ @ + / _____ \$ @ +/__/ \__\$@ + $@@ +.______ $@ +| _ \ $@ +| |_) |$@ +| _ < $@ +| |_) |$@ +|______/ $@ + $@@ + ______$@ + / |@ +| ,----'@ +| | $@ +| `----.@ + \______|@ + $@@ + _______ $@ +| \$@ +| .--. |@ +| | | |@ +| '--' |@ +|_______/$@ + $@@ + _______ @ +| ____|@ +| |__ $@ +| __| $@ +| |____ @ +|_______|@ + @@ + _______ @ +| ____|@ +| |__ $@ +| __| $@ +| | $ @ +|__| @ + @@ + _______ @ + / _____|@ +| | __ $@ +| | |_ |$@ +| |__| |$@ + \______|$@ + $@@ + __ __ $@ +| | | |$@ +| |__| |$@ +| __ |$@ +| | | |$@ +|__| |__|$@ + $@@ + __ $@ +| |$@ +| |$@ +| |$@ +| |$@ +|__|$@ + $@@ + __ $@ + | |$@ + | |$@ +.--. | |$@ +| `--' |$@ + \______/ $@ + $@@ + __ ___$@ +| |/ /$@ +| ' / $@ +| < $@ +| . \ $@ +|__|\__\$@ + $@@ + __ $@ +| | $@ +| | $@ +| | $@ +| `----.@ +|_______|@ + $@@ +.___ ___.$@ +| \/ |$@ +| \ / |$@ +| |\/| |$@ +| | | |$@ +|__| |__|$@ + $@@ +.__ __.$@ +| \ | |$@ +| \| |$@ +| . ` |$@ +| |\ |$@ +|__| \__|$@ + $@@ + ______ $@ + / __ \ $@ +| | | |$@ +| | | |$@ +| `--' |$@ + \______/ $@ + $@@ +.______ $@ +| _ \ $@ +| |_) |$@ +| ___/ $@ +| | $ @ +| _| $ @ + $ @@ + ______ $ @ + / __ \ $ @ +| | | | $ @ +| | | | $ @ +| `--' '--. @ + \_____\_____\@ + $ @@ +.______ $ @ +| _ \ $ @ +| |_) | $ @ +| / $ @ +| |\ \----.@ +| _| `._____|@ + $@@ + _______.@ + / |@ + | (----`@ + \ \ $@ +.----) | $@ +|_______/ $@ + $@@ +.___________.@ +| |@ +`---| |----`@ + | | $ @ + | | $ @ + |__| $ @ + $ @@ + __ __ $@ +| | | |$@ +| | | |$@ +| | | |$@ +| `--' |$@ + \______/ $@ + $@@ +____ ____$@ +\ \ / /$@ + \ \/ /$ @ + \ /$ @ + \ /$ @ + \__/$ @ + $ @@ +____ __ ____$@ +\ \ / \ / /$@ + \ \/ \/ /$ @ + \ /$ @ + \ /\ /$ @ + \__/ \__/$ @ + $ @@ +___ ___$@ +\ \ / /$@ + \ V / $@ + > < $@ + / . \ $@ +/__/ \__\$@ + $@@ +____ ____$@ +\ \ / /$@ + \ \/ /$ @ + \_ _/$ @ + | |$ @ + |__|$ @ + $ @@ + ________ $@ +| / $@ +`---/ / $@ + / / $@ + / /----.@ + /________|@ + $@@ + ___@ + / /@ + | |$@ +/ /$ @ +\ \$ @ + | |$@ + \__\@@ + __ $@ +| |$@ +| |$@ +| |$@ +| |$@ +| |$@ +|__|$@@ +___ @ +\ \$ @ + | | @ + \ \@ + / /@ + | | @ +/__/$ @@ + __ _ @ + / \/ |@ +|_/\__/ @ + $ @ + $ @ + $ @ + @@ + _ _ @ + (_)_(_) @ + / \ @ + / _ \ @ + / ___ \ @ +/_/ \_\@ + @@ + _ _ @ +(_)_(_)@ + / _ \ @ +| | | |@ +| |_| |@ + \___/ @ + @@ + _ _ @ +(_) (_)@ +| | | |@ +| | | |@ +| |_| |@ + \___/ @ + @@ + _ _ @ +(_) (_)@ + __ _ @ + / _` |@ +| (_| |@ + \__,_|@ + @@ + _ _ @ +(_) (_)@ + ___ @ + / _ \ @ +| (_) |@ + \___/ @ + @@ + _ _ @ +(_) (_)@ + _ _ @ +| | | |@ +| |_| |@ + \__,_|@ + @@ + ___ @ + / _ \ @ +| | ) |@ +| |< < @ +| | ) |@ +| ||_/ @ +|_| @@ diff --git a/src/Spectre.Console.Tests/EmbeddedResourceDataAttribute.cs b/src/Spectre.Console.Tests/EmbeddedResourceDataAttribute.cs new file mode 100644 index 0000000..4951b87 --- /dev/null +++ b/src/Spectre.Console.Tests/EmbeddedResourceDataAttribute.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Xunit.Sdk; + +namespace Spectre.Console.Tests +{ + public sealed class EmbeddedResourceDataAttribute : DataAttribute + { + private readonly string _args; + + public EmbeddedResourceDataAttribute(string args) + { + _args = args ?? throw new ArgumentNullException(nameof(args)); + } + + public override IEnumerable GetData(MethodInfo testMethod) + { + var result = new object[1]; + result[0] = ReadManifestData(_args); + return new[] { result }; + } + + public static string ReadManifestData(string resourceName) + { + if (resourceName is null) + { + throw new ArgumentNullException(nameof(resourceName)); + } + + using (var stream = ResourceReader.LoadResourceStream(resourceName)) + { + if (stream == null) + { + throw new InvalidOperationException("Could not load manifest resource stream."); + } + + using (var reader = new StreamReader(stream)) + { + return reader.ReadToEnd().NormalizeLineEndings(); + } + } + } + } +} diff --git a/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Load_Font_From_Stream.verified.txt b/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Load_Font_From_Stream.verified.txt new file mode 100644 index 0000000..76aff34 --- /dev/null +++ b/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Load_Font_From_Stream.verified.txt @@ -0,0 +1,7 @@ +.______ ___ .___________..______ __ __ ___ ____ __ ____ ___ _______. __ __ _______ .______ _______ +| _ \ / \ | || _ \ | | | |/ / \ \ / \ / / / \ / | | | | | | ____|| _ \ | ____| +| |_) | / ^ \ `---| |----`| |_) | | | | ' / \ \/ \/ / / ^ \ | (----` | |__| | | |__ | |_) | | |__ +| ___/ / /_\ \ | | | / | | | < \ / / /_\ \ \ \ | __ | | __| | / | __| +| | / _____ \ | | | |\ \----.| | | . \ \ /\ / / _____ \ .----) | | | | | | |____ | |\ \----.| |____ +| _| /__/ \__\ |__| | _| `._____||__| |__|\__\ \__/ \__/ /__/ \__\ |_______/ |__| |__| |_______|| _| `._____||_______| + diff --git a/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Render_Centered_Text_Correctly.verified.txt b/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Render_Centered_Text_Correctly.verified.txt new file mode 100644 index 0000000..af87b25 --- /dev/null +++ b/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Render_Centered_Text_Correctly.verified.txt @@ -0,0 +1,6 @@ + ____ _ ____ _ + / ___| _ __ ___ ___ | |_ _ __ ___ / ___| ___ _ __ ___ ___ | | ___ + \___ \ | '_ \ / _ \ / __| | __| | '__| / _ \ | | / _ \ | '_ \ / __| / _ \ | | / _ \ + ___) | | |_) | | __/ | (__ | |_ | | | __/ _ | |___ | (_) | | | | | \__ \ | (_) | | | | __/ + |____/ | .__/ \___| \___| \__| |_| \___| (_) \____| \___/ |_| |_| |___/ \___/ |_| \___| + |_| diff --git a/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Render_Left_Aligned_Text_Correctly.verified.txt b/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Render_Left_Aligned_Text_Correctly.verified.txt new file mode 100644 index 0000000..702c786 --- /dev/null +++ b/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Render_Left_Aligned_Text_Correctly.verified.txt @@ -0,0 +1,6 @@ + ____ _ ____ _ + / ___| _ __ ___ ___ | |_ _ __ ___ / ___| ___ _ __ ___ ___ | | ___ + \___ \ | '_ \ / _ \ / __| | __| | '__| / _ \ | | / _ \ | '_ \ / __| / _ \ | | / _ \ + ___) | | |_) | | __/ | (__ | |_ | | | __/ _ | |___ | (_) | | | | | \__ \ | (_) | | | | __/ + |____/ | .__/ \___| \___| \__| |_| \___| (_) \____| \___/ |_| |_| |___/ \___/ |_| \___| + |_| diff --git a/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Render_Right_Aligned_Text_Correctly.verified.txt b/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Render_Right_Aligned_Text_Correctly.verified.txt new file mode 100644 index 0000000..1fa505f --- /dev/null +++ b/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Render_Right_Aligned_Text_Correctly.verified.txt @@ -0,0 +1,6 @@ + ____ _ ____ _ + / ___| _ __ ___ ___ | |_ _ __ ___ / ___| ___ _ __ ___ ___ | | ___ + \___ \ | '_ \ / _ \ / __| | __| | '__| / _ \ | | / _ \ | '_ \ / __| / _ \ | | / _ \ + ___) | | |_) | | __/ | (__ | |_ | | | __/ _ | |___ | (_) | | | | | \__ \ | (_) | | | | __/ + |____/ | .__/ \___| \___| \__| |_| \___| (_) \____| \___/ |_| |_| |___/ \___/ |_| \___| + |_| diff --git a/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Render_Text_Correctly.verified.txt b/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Render_Text_Correctly.verified.txt new file mode 100644 index 0000000..3e81383 --- /dev/null +++ b/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Render_Text_Correctly.verified.txt @@ -0,0 +1,12 @@ + ____ _ _ _ + | _ \ __ _ | |_ _ __ (_) | | __ __ __ __ _ ___ + | |_) | / _` | | __| | '__| | | | |/ / \ \ /\ / / / _` | / __| + | __/ | (_| | | |_ | | | | | < \ V V / | (_| | \__ \ + |_| \__,_| \__| |_| |_| |_|\_\ \_/\_/ \__,_| |___/ + + _ + | |__ ___ _ __ ___ + | '_ \ / _ \ | '__| / _ \ + | | | | | __/ | | | __/ + |_| |_| \___| |_| \___| + diff --git a/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Render_Wrapped_Text_Correctly.verified.txt b/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Render_Wrapped_Text_Correctly.verified.txt new file mode 100644 index 0000000..7fa6180 --- /dev/null +++ b/src/Spectre.Console.Tests/Expectations/FigletTests.Should_Render_Wrapped_Text_Correctly.verified.txt @@ -0,0 +1,12 @@ + ____ _ ____ + / ___| _ __ ___ ___ | |_ _ __ ___ / ___| ___ + \___ \ | '_ \ / _ \ / __| | __| | '__| / _ \ | | / _ \ + ___) | | |_) | | __/ | (__ | |_ | | | __/ _ | |___ | (_) | + |____/ | .__/ \___| \___| \__| |_| \___| (_) \____| \___/ + |_| + _ + _ __ ___ ___ | | ___ + | '_ \ / __| / _ \ | | / _ \ + | | | | \__ \ | (_) | | | | __/ + |_| |_| |___/ \___/ |_| \___| + diff --git a/src/Spectre.Console.Tests/Spectre.Console.Tests.csproj b/src/Spectre.Console.Tests/Spectre.Console.Tests.csproj index c731be4..3a1b0c5 100644 --- a/src/Spectre.Console.Tests/Spectre.Console.Tests.csproj +++ b/src/Spectre.Console.Tests/Spectre.Console.Tests.csproj @@ -5,6 +5,14 @@ false + + + + + + + + diff --git a/src/Spectre.Console.Tests/Tools/ResourceReader.cs b/src/Spectre.Console.Tests/Tools/ResourceReader.cs new file mode 100644 index 0000000..9a09c72 --- /dev/null +++ b/src/Spectre.Console.Tests/Tools/ResourceReader.cs @@ -0,0 +1,21 @@ +using System; +using System.IO; + +namespace Spectre.Console.Tests +{ + public static class ResourceReader + { + public static Stream LoadResourceStream(string resourceName) + { + if (resourceName is null) + { + throw new ArgumentNullException(nameof(resourceName)); + } + + var assembly = typeof(EmbeddedResourceDataAttribute).Assembly; + resourceName = resourceName.Replace("/", ".", StringComparison.Ordinal); + + return assembly.GetManifestResourceStream(resourceName); + } + } +} diff --git a/src/Spectre.Console.Tests/Unit/FigletTests.cs b/src/Spectre.Console.Tests/Unit/FigletTests.cs new file mode 100644 index 0000000..d756b78 --- /dev/null +++ b/src/Spectre.Console.Tests/Unit/FigletTests.cs @@ -0,0 +1,98 @@ +using System.Threading.Tasks; +using VerifyXunit; +using Xunit; + +namespace Spectre.Console.Tests.Unit +{ + [UsesVerify] + public sealed class FigletTests + { + [Fact] + public async Task Should_Load_Font_From_Stream() + { + // Given + var console = new PlainConsole(width: 180); + var font = FigletFont.Load(ResourceReader.LoadResourceStream("Spectre.Console.Tests/Data/starwars.flf")); + var text = new FigletText(font, "Patrik was here"); + + // When + console.Render(text); + + // Then + await Verifier.Verify(console.Output); + } + + [Fact] + public async Task Should_Render_Text_Correctly() + { + // Given + var console = new PlainConsole(width: 70); + var text = new FigletText(FigletFont.Default, "Patrik was here"); + + // When + console.Render(text); + + // Then + await Verifier.Verify(console.Output); + } + + [Fact] + public async Task Should_Render_Wrapped_Text_Correctly() + { + // Given + var console = new PlainConsole(width: 70); + var text = new FigletText(FigletFont.Default, "Spectre.Console"); + + // When + console.Render(text); + + // Then + await Verifier.Verify(console.Output); + } + + [Fact] + public async Task Should_Render_Left_Aligned_Text_Correctly() + { + // Given + var console = new PlainConsole(width: 120); + var text = new FigletText(FigletFont.Default, "Spectre.Console") + .Alignment(Justify.Left); + + // When + console.Render(text); + + // Then + await Verifier.Verify(console.Output); + } + + [Fact] + public async Task Should_Render_Centered_Text_Correctly() + { + // Given + var console = new PlainConsole(width: 120); + var text = new FigletText(FigletFont.Default, "Spectre.Console") + .Alignment(Justify.Center); + + // When + console.Render(text); + + // Then + await Verifier.Verify(console.Output); + } + + [Fact] + public async Task Should_Render_Right_Aligned_Text_Correctly() + { + // Given + var console = new PlainConsole(width: 120); + var text = new FigletText(FigletFont.Default, "Spectre.Console") + .Alignment(Justify.Right); + + // When + console.Render(text); + + // Then + await Verifier.Verify(console.Output); + } + } +} diff --git a/src/Spectre.Console.Tests/TestConfig.cs b/src/Spectre.Console.Tests/VerifyConfiguration.cs similarity index 92% rename from src/Spectre.Console.Tests/TestConfig.cs rename to src/Spectre.Console.Tests/VerifyConfiguration.cs index 1ca1730..2f5dcf7 100644 --- a/src/Spectre.Console.Tests/TestConfig.cs +++ b/src/Spectre.Console.Tests/VerifyConfiguration.cs @@ -3,7 +3,7 @@ using System.Runtime.CompilerServices; namespace Spectre.Console.Tests { - public static class TestConfig + public static class VerifyConfiguration { [ModuleInitializer] public static void Init() diff --git a/src/Spectre.Console.sln b/src/Spectre.Console.sln index f24e9e8..c9a4ba3 100644 --- a/src/Spectre.Console.sln +++ b/src/Spectre.Console.sln @@ -52,6 +52,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cursor", "..\examples\Curso EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Prompt", "..\examples\Prompt\Prompt.csproj", "{6351C70F-F368-46DB-BAED-9B87CCD69353}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Figlet", "..\examples\Figlet\Figlet.csproj", "{45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -254,6 +256,18 @@ Global {6351C70F-F368-46DB-BAED-9B87CCD69353}.Release|x64.Build.0 = Release|Any CPU {6351C70F-F368-46DB-BAED-9B87CCD69353}.Release|x86.ActiveCfg = Release|Any CPU {6351C70F-F368-46DB-BAED-9B87CCD69353}.Release|x86.Build.0 = Release|Any CPU + {45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Debug|x64.ActiveCfg = Debug|Any CPU + {45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Debug|x64.Build.0 = Debug|Any CPU + {45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Debug|x86.ActiveCfg = Debug|Any CPU + {45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Debug|x86.Build.0 = Debug|Any CPU + {45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Release|Any CPU.Build.0 = Release|Any CPU + {45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Release|x64.ActiveCfg = Release|Any CPU + {45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Release|x64.Build.0 = Release|Any CPU + {45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Release|x86.ActiveCfg = Release|Any CPU + {45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -274,6 +288,7 @@ Global {8622A261-02C6-40CA-9797-E3F01ED87D6B} = {F0575243-121F-4DEE-9F6B-246E26DC0844} {75C608C3-ABB4-4168-A229-7F8250B946D1} = {F0575243-121F-4DEE-9F6B-246E26DC0844} {6351C70F-F368-46DB-BAED-9B87CCD69353} = {F0575243-121F-4DEE-9F6B-246E26DC0844} + {45BF6302-6553-4E52-BF0F-B10D1AA9A6D1} = {F0575243-121F-4DEE-9F6B-246E26DC0844} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5729B071-67A0-48FB-8B1B-275E6822086C} diff --git a/src/Spectre.Console/Extensions/FigletTextExtensions.cs b/src/Spectre.Console/Extensions/FigletTextExtensions.cs new file mode 100644 index 0000000..7457653 --- /dev/null +++ b/src/Spectre.Console/Extensions/FigletTextExtensions.cs @@ -0,0 +1,27 @@ +using System; + +namespace Spectre.Console +{ + /// + /// Contains extension methods for . + /// + public static class FigletTextExtensions + { + /// + /// Sets the color of the FIGlet text. + /// + /// The text. + /// The color. + /// The same instance so that multiple calls can be chained. + public static FigletText Color(this FigletText text, Color? color) + { + if (text is null) + { + throw new ArgumentNullException(nameof(text)); + } + + text.Color = color ?? Console.Color.Default; + return text; + } + } +} diff --git a/src/Spectre.Console/Figlet/FigletCharacter.cs b/src/Spectre.Console/Figlet/FigletCharacter.cs new file mode 100644 index 0000000..36e6c0f --- /dev/null +++ b/src/Spectre.Console/Figlet/FigletCharacter.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Spectre.Console +{ + internal sealed class FigletCharacter + { + public int Code { get; } + public int Width { get; } + public int Height { get; } + public IReadOnlyList Lines { get; } + + public FigletCharacter(int code, IEnumerable lines) + { + Code = code; + Lines = new List(lines ?? throw new ArgumentNullException(nameof(lines))); + + var min = Lines.Min(x => x.Length); + var max = Lines.Max(x => x.Length); + if (min != max) + { + throw new InvalidOperationException($"Figlet character #{code} has varying width"); + } + + Width = max; + Height = Lines.Count; + } + } +} diff --git a/src/Spectre.Console/Figlet/FigletFont.cs b/src/Spectre.Console/Figlet/FigletFont.cs new file mode 100644 index 0000000..bb86cd9 --- /dev/null +++ b/src/Spectre.Console/Figlet/FigletFont.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Spectre.Console.Internal; + +namespace Spectre.Console +{ + /// + /// Represents a FIGlet font. + /// + public sealed class FigletFont + { + private readonly Dictionary _characters; + private static readonly Lazy _standard; + + /// + /// Gets the number of characters in the font. + /// + public int Count => _characters.Count; + + /// + /// Gets the height of the font. + /// + public int Height { get; } + + /// + /// Gets the font's baseline. + /// + public int Baseline { get; } + + /// + /// Gets the font's maximum width. + /// + public int MaxWidth { get; } + + /// + /// Gets the default FIGlet font. + /// + public static FigletFont Default => _standard.Value; + + static FigletFont() + { + _standard = new Lazy(() => Parse(ResourceReader.ReadManifestData("Spectre.Console/Figlet/Fonts/Standard.flf"))); + } + + internal FigletFont(IEnumerable characters, FigletHeader header) + { + _characters = new Dictionary(); + + foreach (var character in characters) + { + if (_characters.ContainsKey(character.Code)) + { + throw new InvalidOperationException("Character already exist"); + } + + _characters[character.Code] = character; + } + + Height = header.Height; + Baseline = header.Baseline; + MaxWidth = header.MaxLength; + } + + /// + /// Loads a FIGlet font from the specified stream. + /// + /// The stream to load the FIGlet font from. + /// The loaded FIGlet font. + public static FigletFont Load(Stream stream) + { + using (var reader = new StreamReader(stream)) + { + return Parse(reader.ReadToEnd()); + } + } + + /// + /// Loads a FIGlet font from disk. + /// + /// The path of the FIGlet font to load. + /// The loaded FIGlet font. + public static FigletFont Load(string path) + { + return Parse(File.ReadAllText(path)); + } + + /// + /// Parses a FIGlet font from the specified . + /// + /// The FIGlet font source. + /// The parsed FIGlet font. + public static FigletFont Parse(string source) + { + return FigletFontParser.Parse(source); + } + + internal int GetWidth(string text) + { + var width = 0; + foreach (var character in text) + { + width += GetCharacter(character)?.Width ?? 0; + } + + return width; + } + + internal FigletCharacter? GetCharacter(char character) + { + _characters.TryGetValue(character, out var result); + return result; + } + + internal IEnumerable GetCharacters(string text) + { + if (text is null) + { + throw new ArgumentNullException(nameof(text)); + } + + var result = new List(); + foreach (var character in text) + { + if (_characters.TryGetValue(character, out var figletCharacter)) + { + result.Add(figletCharacter); + } + } + + return result; + } + } +} diff --git a/src/Spectre.Console/Figlet/FigletFontParser.cs b/src/Spectre.Console/Figlet/FigletFontParser.cs new file mode 100644 index 0000000..5da556d --- /dev/null +++ b/src/Spectre.Console/Figlet/FigletFontParser.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; + +namespace Spectre.Console +{ + internal static class FigletFontParser + { + public static FigletFont Parse(string source) + { + var lines = source.SplitLines(); + var header = ParseHeader(lines.FirstOrDefault()); + + var characters = new List(); + + var index = 32; + var indexOverridden = false; + var hasOverriddenIndex = false; + var buffer = new List(); + + foreach (var line in lines.Skip(header.CommentLines + 1)) + { + if (!line.EndsWith("@", StringComparison.Ordinal)) + { + var words = line.SplitWords(); + if (words.Length > 0 && TryParseIndex(words[0], out var newIndex)) + { + index = newIndex; + indexOverridden = true; + hasOverriddenIndex = true; + continue; + } + + continue; + } + + if (hasOverriddenIndex && !indexOverridden) + { + throw new InvalidOperationException("Unknown index for FIGlet character"); + } + + buffer.Add(line.Replace('$', ' ').ReplaceExact("@", string.Empty)); + + if (line.EndsWith("@@", StringComparison.Ordinal)) + { + characters.Add(new FigletCharacter(index, buffer)); + buffer.Clear(); + + if (!hasOverriddenIndex) + { + index++; + } + + // Reset the flag so we know if we're trying to parse + // a character that wasn't prefixed with an ASCII index. + indexOverridden = false; + } + } + + return new FigletFont(characters, header); + } + + private static bool TryParseIndex(string index, out int result) + { + var style = NumberStyles.Integer; + if (index.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) + { + // TODO: ReplaceExact should not be used + index = index.ReplaceExact("0x", string.Empty).ReplaceExact("0x", string.Empty); + style = NumberStyles.HexNumber; + } + + return int.TryParse(index, style, CultureInfo.InvariantCulture, out result); + } + + private static FigletHeader ParseHeader(string text) + { + if (string.IsNullOrWhiteSpace(text)) + { + throw new InvalidOperationException("Invalid Figlet font"); + } + + var parts = text.SplitWords(StringSplitOptions.RemoveEmptyEntries); + if (parts.Length < 6) + { + throw new InvalidOperationException("Invalid Figlet font header"); + } + + if (!IsValidSignature(parts[0])) + { + throw new InvalidOperationException("Invalid Figlet font header signature"); + } + + return new FigletHeader + { + Hardblank = parts[0][5], + Height = int.Parse(parts[1], CultureInfo.InvariantCulture), + Baseline = int.Parse(parts[2], CultureInfo.InvariantCulture), + MaxLength = int.Parse(parts[3], CultureInfo.InvariantCulture), + OldLayout = int.Parse(parts[4], CultureInfo.InvariantCulture), + CommentLines = int.Parse(parts[5], CultureInfo.InvariantCulture), + }; + } + + private static bool IsValidSignature(string signature) + { + return signature.Length == 6 + && signature[0] == 'f' && signature[1] == 'l' + && signature[2] == 'f' && signature[3] == '2' + && signature[4] == 'a'; + } + } +} diff --git a/src/Spectre.Console/Figlet/FigletHeader.cs b/src/Spectre.Console/Figlet/FigletHeader.cs new file mode 100644 index 0000000..416b1d2 --- /dev/null +++ b/src/Spectre.Console/Figlet/FigletHeader.cs @@ -0,0 +1,12 @@ +namespace Spectre.Console +{ + internal sealed class FigletHeader + { + public char Hardblank { get; set; } + public int Height { get; set; } + public int Baseline { get; set; } + public int MaxLength { get; set; } + public int OldLayout { get; set; } + public int CommentLines { get; set; } + } +} diff --git a/src/Spectre.Console/Figlet/FigletText.cs b/src/Spectre.Console/Figlet/FigletText.cs new file mode 100644 index 0000000..2e0c493 --- /dev/null +++ b/src/Spectre.Console/Figlet/FigletText.cs @@ -0,0 +1,151 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Spectre.Console.Rendering; + +namespace Spectre.Console +{ + /// + /// Represents text rendered with a FIGlet font. + /// + public sealed class FigletText : Renderable, IAlignable + { + private readonly FigletFont _font; + private readonly string _text; + + /// + /// Gets or sets the color of the text. + /// + public Color? Color { get; set; } + + /// + public Justify? Alignment { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// The text. + public FigletText(string text) + : this(FigletFont.Default, text) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The FIGlet font to use. + /// The text. + public FigletText(FigletFont font, string text) + { + _font = font ?? throw new ArgumentNullException(nameof(font)); + _text = text ?? throw new ArgumentNullException(nameof(text)); + } + + /// + protected override IEnumerable Render(RenderContext context, int maxWidth) + { + var style = new Style(Color ?? Console.Color.Default); + var alignment = Alignment ?? Justify.Left; + + foreach (var row in GetRows(maxWidth)) + { + for (var index = 0; index < _font.Height; index++) + { + var line = new Segment(string.Concat(row.Select(x => x.Lines[index])), style); + + var lineWidth = line.CellCount(context); + if (alignment == Justify.Left) + { + yield return line; + + if (lineWidth < maxWidth) + { + yield return new Segment(new string(' ', maxWidth - lineWidth)); + } + } + else if (alignment == Justify.Center) + { + var left = (maxWidth - lineWidth) / 2; + var right = left + ((maxWidth - lineWidth) % 2); + + yield return new Segment(new string(' ', left)); + yield return line; + yield return new Segment(new string(' ', right)); + } + else if (alignment == Justify.Right) + { + if (lineWidth < maxWidth) + { + yield return new Segment(new string(' ', maxWidth - lineWidth)); + } + + yield return line; + } + + yield return Segment.LineBreak; + } + } + } + + private List> GetRows(int maxWidth) + { + var result = new List>(); + var words = _text.SplitWords(StringSplitOptions.None); + + var totalWidth = 0; + var line = new List(); + + foreach (var word in words) + { + // Does the whole word fit? + var width = _font.GetWidth(word); + if (width + totalWidth < maxWidth) + { + // Add it to the line + line.AddRange(_font.GetCharacters(word)); + totalWidth += width; + } + else + { + // Does it fit on it's own line? + if (width < maxWidth) + { + // Flush the line + result.Add(line); + line = new List(); + totalWidth = 0; + + line.AddRange(_font.GetCharacters(word)); + totalWidth += width; + } + else + { + // We need to split it up. + var queue = new Queue(_font.GetCharacters(word)); + while (queue.Count > 0) + { + var current = queue.Dequeue(); + if (totalWidth + current.Width > maxWidth) + { + // Flush the line + result.Add(line); + line = new List(); + totalWidth = 0; + } + + line.Add(current); + totalWidth += current.Width; + } + } + } + } + + if (line.Count > 0) + { + result.Add(line); + } + + return result; + } + } +} diff --git a/src/Spectre.Console/Figlet/Fonts/Standard.flf b/src/Spectre.Console/Figlet/Fonts/Standard.flf new file mode 100644 index 0000000..8bfcca7 --- /dev/null +++ b/src/Spectre.Console/Figlet/Fonts/Standard.flf @@ -0,0 +1,2227 @@ +flf2a$ 6 5 16 15 11 0 24463 +Standard by Glenn Chappell & Ian Chai 3/93 -- based on Frank's .sig +Includes ISO Latin-1 +figlet release 2.1 -- 12 Aug 1994 +Modified for figlet 2.2 by John Cowan + to add Latin-{2,3,4,5} support (Unicode U+0100-017F). +Permission is hereby given to modify this font, as long as the +modifier's name is placed on a comment line. + +Modified by Paul Burton 12/96 to include new parameter +supported by FIGlet and FIGWin. May also be slightly modified for better use +of new full-width/kern/smush alternatives, but default output is NOT changed. + $@ + $@ + $@ + $@ + $@ + $@@ + _ @ + | |@ + | |@ + |_|@ + (_)@ + @@ + _ _ @ + ( | )@ + V V @ + $ @ + $ @ + @@ + _ _ @ + _| || |_ @ + |_ .. _|@ + |_ _|@ + |_||_| @ + @@ + _ @ + | | @ + / __)@ + \__ \@ + ( /@ + |_| @@ + _ __@ + (_)/ /@ + / / @ + / /_ @ + /_/(_)@ + @@ + ___ @ + ( _ ) @ + / _ \/\@ + | (_> <@ + \___/\/@ + @@ + _ @ + ( )@ + |/ @ + $ @ + $ @ + @@ + __@ + / /@ + | | @ + | | @ + | | @ + \_\@@ + __ @ + \ \ @ + | |@ + | |@ + | |@ + /_/ @@ + @ + __/\__@ + \ /@ + /_ _\@ + \/ @ + @@ + @ + _ @ + _| |_ @ + |_ _|@ + |_| @ + @@ + @ + @ + @ + _ @ + ( )@ + |/ @@ + @ + @ + _____ @ + |_____|@ + $ @ + @@ + @ + @ + @ + _ @ + (_)@ + @@ + __@ + / /@ + / / @ + / / @ + /_/ @ + @@ + ___ @ + / _ \ @ + | | | |@ + | |_| |@ + \___/ @ + @@ + _ @ + / |@ + | |@ + | |@ + |_|@ + @@ + ____ @ + |___ \ @ + __) |@ + / __/ @ + |_____|@ + @@ + _____ @ + |___ / @ + |_ \ @ + ___) |@ + |____/ @ + @@ + _ _ @ + | || | @ + | || |_ @ + |__ _|@ + |_| @ + @@ + ____ @ + | ___| @ + |___ \ @ + ___) |@ + |____/ @ + @@ + __ @ + / /_ @ + | '_ \ @ + | (_) |@ + \___/ @ + @@ + _____ @ + |___ |@ + / / @ + / / @ + /_/ @ + @@ + ___ @ + ( _ ) @ + / _ \ @ + | (_) |@ + \___/ @ + @@ + ___ @ + / _ \ @ + | (_) |@ + \__, |@ + /_/ @ + @@ + @ + _ @ + (_)@ + _ @ + (_)@ + @@ + @ + _ @ + (_)@ + _ @ + ( )@ + |/ @@ + __@ + / /@ + / / @ + \ \ @ + \_\@ + @@ + @ + _____ @ + |_____|@ + |_____|@ + $ @ + @@ + __ @ + \ \ @ + \ \@ + / /@ + /_/ @ + @@ + ___ @ + |__ \@ + / /@ + |_| @ + (_) @ + @@ + ____ @ + / __ \ @ + / / _` |@ + | | (_| |@ + \ \__,_|@ + \____/ @@ + _ @ + / \ @ + / _ \ @ + / ___ \ @ + /_/ \_\@ + @@ + ____ @ + | __ ) @ + | _ \ @ + | |_) |@ + |____/ @ + @@ + ____ @ + / ___|@ + | | @ + | |___ @ + \____|@ + @@ + ____ @ + | _ \ @ + | | | |@ + | |_| |@ + |____/ @ + @@ + _____ @ + | ____|@ + | _| @ + | |___ @ + |_____|@ + @@ + _____ @ + | ___|@ + | |_ @ + | _| @ + |_| @ + @@ + ____ @ + / ___|@ + | | _ @ + | |_| |@ + \____|@ + @@ + _ _ @ + | | | |@ + | |_| |@ + | _ |@ + |_| |_|@ + @@ + ___ @ + |_ _|@ + | | @ + | | @ + |___|@ + @@ + _ @ + | |@ + _ | |@ + | |_| |@ + \___/ @ + @@ + _ __@ + | |/ /@ + | ' / @ + | . \ @ + |_|\_\@ + @@ + _ @ + | | @ + | | @ + | |___ @ + |_____|@ + @@ + __ __ @ + | \/ |@ + | |\/| |@ + | | | |@ + |_| |_|@ + @@ + _ _ @ + | \ | |@ + | \| |@ + | |\ |@ + |_| \_|@ + @@ + ___ @ + / _ \ @ + | | | |@ + | |_| |@ + \___/ @ + @@ + ____ @ + | _ \ @ + | |_) |@ + | __/ @ + |_| @ + @@ + ___ @ + / _ \ @ + | | | |@ + | |_| |@ + \__\_\@ + @@ + ____ @ + | _ \ @ + | |_) |@ + | _ < @ + |_| \_\@ + @@ + ____ @ + / ___| @ + \___ \ @ + ___) |@ + |____/ @ + @@ + _____ @ + |_ _|@ + | | @ + | | @ + |_| @ + @@ + _ _ @ + | | | |@ + | | | |@ + | |_| |@ + \___/ @ + @@ + __ __@ + \ \ / /@ + \ \ / / @ + \ V / @ + \_/ @ + @@ + __ __@ + \ \ / /@ + \ \ /\ / / @ + \ V V / @ + \_/\_/ @ + @@ + __ __@ + \ \/ /@ + \ / @ + / \ @ + /_/\_\@ + @@ + __ __@ + \ \ / /@ + \ V / @ + | | @ + |_| @ + @@ + _____@ + |__ /@ + / / @ + / /_ @ + /____|@ + @@ + __ @ + | _|@ + | | @ + | | @ + | | @ + |__|@@ + __ @ + \ \ @ + \ \ @ + \ \ @ + \_\@ + @@ + __ @ + |_ |@ + | |@ + | |@ + | |@ + |__|@@ + /\ @ + |/\|@ + $ @ + $ @ + $ @ + @@ + @ + @ + @ + @ + _____ @ + |_____|@@ + _ @ + ( )@ + \|@ + $ @ + $ @ + @@ + @ + __ _ @ + / _` |@ + | (_| |@ + \__,_|@ + @@ + _ @ + | |__ @ + | '_ \ @ + | |_) |@ + |_.__/ @ + @@ + @ + ___ @ + / __|@ + | (__ @ + \___|@ + @@ + _ @ + __| |@ + / _` |@ + | (_| |@ + \__,_|@ + @@ + @ + ___ @ + / _ \@ + | __/@ + \___|@ + @@ + __ @ + / _|@ + | |_ @ + | _|@ + |_| @ + @@ + @ + __ _ @ + / _` |@ + | (_| |@ + \__, |@ + |___/ @@ + _ @ + | |__ @ + | '_ \ @ + | | | |@ + |_| |_|@ + @@ + _ @ + (_)@ + | |@ + | |@ + |_|@ + @@ + _ @ + (_)@ + | |@ + | |@ + _/ |@ + |__/ @@ + _ @ + | | __@ + | |/ /@ + | < @ + |_|\_\@ + @@ + _ @ + | |@ + | |@ + | |@ + |_|@ + @@ + @ + _ __ ___ @ + | '_ ` _ \ @ + | | | | | |@ + |_| |_| |_|@ + @@ + @ + _ __ @ + | '_ \ @ + | | | |@ + |_| |_|@ + @@ + @ + ___ @ + / _ \ @ + | (_) |@ + \___/ @ + @@ + @ + _ __ @ + | '_ \ @ + | |_) |@ + | .__/ @ + |_| @@ + @ + __ _ @ + / _` |@ + | (_| |@ + \__, |@ + |_|@@ + @ + _ __ @ + | '__|@ + | | @ + |_| @ + @@ + @ + ___ @ + / __|@ + \__ \@ + |___/@ + @@ + _ @ + | |_ @ + | __|@ + | |_ @ + \__|@ + @@ + @ + _ _ @ + | | | |@ + | |_| |@ + \__,_|@ + @@ + @ + __ __@ + \ \ / /@ + \ V / @ + \_/ @ + @@ + @ + __ __@ + \ \ /\ / /@ + \ V V / @ + \_/\_/ @ + @@ + @ + __ __@ + \ \/ /@ + > < @ + /_/\_\@ + @@ + @ + _ _ @ + | | | |@ + | |_| |@ + \__, |@ + |___/ @@ + @ + ____@ + |_ /@ + / / @ + /___|@ + @@ + __@ + / /@ + | | @ + < < @ + | | @ + \_\@@ + _ @ + | |@ + | |@ + | |@ + | |@ + |_|@@ + __ @ + \ \ @ + | | @ + > >@ + | | @ + /_/ @@ + /\/|@ + |/\/ @ + $ @ + $ @ + $ @ + @@ + _ _ @ + (_)_(_)@ + /_\ @ + / _ \ @ + /_/ \_\@ + @@ + _ _ @ + (_)_(_)@ + / _ \ @ + | |_| |@ + \___/ @ + @@ + _ _ @ + (_) (_)@ + | | | |@ + | |_| |@ + \___/ @ + @@ + _ _ @ + (_)_(_)@ + / _` |@ + | (_| |@ + \__,_|@ + @@ + _ _ @ + (_)_(_)@ + / _ \ @ + | (_) |@ + \___/ @ + @@ + _ _ @ + (_) (_)@ + | | | |@ + | |_| |@ + \__,_|@ + @@ + ___ @ + / _ \@ + | |/ /@ + | |\ \@ + | ||_/@ + |_| @@ +160 NO-BREAK SPACE + $@ + $@ + $@ + $@ + $@ + $@@ +161 INVERTED EXCLAMATION MARK + _ @ + (_)@ + | |@ + | |@ + |_|@ + @@ +162 CENT SIGN + _ @ + | | @ + / __)@ + | (__ @ + \ )@ + |_| @@ +163 POUND SIGN + ___ @ + / ,_\ @ + _| |_ @ + | |___ @ + (_,____|@ + @@ +164 CURRENCY SIGN + /\___/\@ + \ _ /@ + | (_) |@ + / ___ \@ + \/ \/@ + @@ +165 YEN SIGN + __ __ @ + \ V / @ + |__ __|@ + |__ __|@ + |_| @ + @@ +166 BROKEN BAR + _ @ + | |@ + |_|@ + _ @ + | |@ + |_|@@ +167 SECTION SIGN + __ @ + _/ _)@ + / \ \ @ + \ \\ \@ + \ \_/@ + (__/ @@ +168 DIAERESIS + _ _ @ + (_) (_)@ + $ $ @ + $ $ @ + $ $ @ + @@ +169 COPYRIGHT SIGN + _____ @ + / ___ \ @ + / / __| \ @ + | | (__ |@ + \ \___| / @ + \_____/ @@ +170 FEMININE ORDINAL INDICATOR + __ _ @ + / _` |@ + \__,_|@ + |____|@ + $ @ + @@ +171 LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + ____@ + / / /@ + / / / @ + \ \ \ @ + \_\_\@ + @@ +172 NOT SIGN + @ + _____ @ + |___ |@ + |_|@ + $ @ + @@ +173 SOFT HYPHEN + @ + @ + ____ @ + |____|@ + $ @ + @@ +174 REGISTERED SIGN + _____ @ + / ___ \ @ + / | _ \ \ @ + | | / |@ + \ |_|_\ / @ + \_____/ @@ +175 MACRON + _____ @ + |_____|@ + $ @ + $ @ + $ @ + @@ +176 DEGREE SIGN + __ @ + / \ @ + | () |@ + \__/ @ + $ @ + @@ +177 PLUS-MINUS SIGN + _ @ + _| |_ @ + |_ _|@ + _|_|_ @ + |_____|@ + @@ +178 SUPERSCRIPT TWO + ___ @ + |_ )@ + / / @ + /___|@ + $ @ + @@ +179 SUPERSCRIPT THREE + ____@ + |__ /@ + |_ \@ + |___/@ + $ @ + @@ +180 ACUTE ACCENT + __@ + /_/@ + $ @ + $ @ + $ @ + @@ +181 MICRO SIGN + @ + _ _ @ + | | | |@ + | |_| |@ + | ._,_|@ + |_| @@ +182 PILCROW SIGN + _____ @ + / |@ + | (| | |@ + \__ | |@ + |_|_|@ + @@ +183 MIDDLE DOT + @ + _ @ + (_)@ + $ @ + $ @ + @@ +184 CEDILLA + @ + @ + @ + @ + _ @ + )_)@@ +185 SUPERSCRIPT ONE + _ @ + / |@ + | |@ + |_|@ + $ @ + @@ +186 MASCULINE ORDINAL INDICATOR + ___ @ + / _ \@ + \___/@ + |___|@ + $ @ + @@ +187 RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + ____ @ + \ \ \ @ + \ \ \@ + / / /@ + /_/_/ @ + @@ +188 VULGAR FRACTION ONE QUARTER + _ __ @ + / | / / _ @ + | |/ / | | @ + |_/ /|_ _|@ + /_/ |_| @ + @@ +189 VULGAR FRACTION ONE HALF + _ __ @ + / | / /__ @ + | |/ /_ )@ + |_/ / / / @ + /_/ /___|@ + @@ +190 VULGAR FRACTION THREE QUARTERS + ____ __ @ + |__ / / / _ @ + |_ \/ / | | @ + |___/ /|_ _|@ + /_/ |_| @ + @@ +191 INVERTED QUESTION MARK + _ @ + (_) @ + | | @ + / /_ @ + \___|@ + @@ +192 LATIN CAPITAL LETTER A WITH GRAVE + __ @ + \_\ @ + /_\ @ + / _ \ @ + /_/ \_\@ + @@ +193 LATIN CAPITAL LETTER A WITH ACUTE + __ @ + /_/ @ + /_\ @ + / _ \ @ + /_/ \_\@ + @@ +194 LATIN CAPITAL LETTER A WITH CIRCUMFLEX + //\ @ + |/_\| @ + /_\ @ + / _ \ @ + /_/ \_\@ + @@ +195 LATIN CAPITAL LETTER A WITH TILDE + /\/| @ + |/\/ @ + /_\ @ + / _ \ @ + /_/ \_\@ + @@ +196 LATIN CAPITAL LETTER A WITH DIAERESIS + _ _ @ + (_)_(_)@ + /_\ @ + / _ \ @ + /_/ \_\@ + @@ +197 LATIN CAPITAL LETTER A WITH RING ABOVE + _ @ + (o) @ + /_\ @ + / _ \ @ + /_/ \_\@ + @@ +198 LATIN CAPITAL LETTER AE + ______ @ + / ____|@ + / _ _| @ + / __ |___ @ + /_/ |_____|@ + @@ +199 LATIN CAPITAL LETTER C WITH CEDILLA + ____ @ + / ___|@ + | | @ + | |___ @ + \____|@ + )_) @@ +200 LATIN CAPITAL LETTER E WITH GRAVE + __ @ + _\_\_ @ + | ____|@ + | _|_ @ + |_____|@ + @@ +201 LATIN CAPITAL LETTER E WITH ACUTE + __ @ + _/_/_ @ + | ____|@ + | _|_ @ + |_____|@ + @@ +202 LATIN CAPITAL LETTER E WITH CIRCUMFLEX + //\ @ + |/_\| @ + | ____|@ + | _|_ @ + |_____|@ + @@ +203 LATIN CAPITAL LETTER E WITH DIAERESIS + _ _ @ + (_)_(_)@ + | ____|@ + | _|_ @ + |_____|@ + @@ +204 LATIN CAPITAL LETTER I WITH GRAVE + __ @ + \_\ @ + |_ _|@ + | | @ + |___|@ + @@ +205 LATIN CAPITAL LETTER I WITH ACUTE + __ @ + /_/ @ + |_ _|@ + | | @ + |___|@ + @@ +206 LATIN CAPITAL LETTER I WITH CIRCUMFLEX + //\ @ + |/_\|@ + |_ _|@ + | | @ + |___|@ + @@ +207 LATIN CAPITAL LETTER I WITH DIAERESIS + _ _ @ + (_)_(_)@ + |_ _| @ + | | @ + |___| @ + @@ +208 LATIN CAPITAL LETTER ETH + ____ @ + | _ \ @ + _| |_| |@ + |__ __| |@ + |____/ @ + @@ +209 LATIN CAPITAL LETTER N WITH TILDE + /\/|@ + |/\/ @ + | \| |@ + | .` |@ + |_|\_|@ + @@ +210 LATIN CAPITAL LETTER O WITH GRAVE + __ @ + \_\ @ + / _ \ @ + | |_| |@ + \___/ @ + @@ +211 LATIN CAPITAL LETTER O WITH ACUTE + __ @ + /_/ @ + / _ \ @ + | |_| |@ + \___/ @ + @@ +212 LATIN CAPITAL LETTER O WITH CIRCUMFLEX + //\ @ + |/_\| @ + / _ \ @ + | |_| |@ + \___/ @ + @@ +213 LATIN CAPITAL LETTER O WITH TILDE + /\/| @ + |/\/ @ + / _ \ @ + | |_| |@ + \___/ @ + @@ +214 LATIN CAPITAL LETTER O WITH DIAERESIS + _ _ @ + (_)_(_)@ + / _ \ @ + | |_| |@ + \___/ @ + @@ +215 MULTIPLICATION SIGN + @ + @ + /\/\@ + > <@ + \/\/@ + @@ +216 LATIN CAPITAL LETTER O WITH STROKE + ____ @ + / _// @ + | |// |@ + | //| |@ + //__/ @ + @@ +217 LATIN CAPITAL LETTER U WITH GRAVE + __ @ + _\_\_ @ + | | | |@ + | |_| |@ + \___/ @ + @@ +218 LATIN CAPITAL LETTER U WITH ACUTE + __ @ + _/_/_ @ + | | | |@ + | |_| |@ + \___/ @ + @@ +219 LATIN CAPITAL LETTER U WITH CIRCUMFLEX + //\ @ + |/ \| @ + | | | |@ + | |_| |@ + \___/ @ + @@ +220 LATIN CAPITAL LETTER U WITH DIAERESIS + _ _ @ + (_) (_)@ + | | | |@ + | |_| |@ + \___/ @ + @@ +221 LATIN CAPITAL LETTER Y WITH ACUTE + __ @ + __/_/__@ + \ \ / /@ + \ V / @ + |_| @ + @@ +222 LATIN CAPITAL LETTER THORN + _ @ + | |___ @ + | __ \@ + | ___/@ + |_| @ + @@ +223 LATIN SMALL LETTER SHARP S + ___ @ + / _ \@ + | |/ /@ + | |\ \@ + | ||_/@ + |_| @@ +224 LATIN SMALL LETTER A WITH GRAVE + __ @ + \_\_ @ + / _` |@ + | (_| |@ + \__,_|@ + @@ +225 LATIN SMALL LETTER A WITH ACUTE + __ @ + /_/_ @ + / _` |@ + | (_| |@ + \__,_|@ + @@ +226 LATIN SMALL LETTER A WITH CIRCUMFLEX + //\ @ + |/_\| @ + / _` |@ + | (_| |@ + \__,_|@ + @@ +227 LATIN SMALL LETTER A WITH TILDE + /\/| @ + |/\/_ @ + / _` |@ + | (_| |@ + \__,_|@ + @@ +228 LATIN SMALL LETTER A WITH DIAERESIS + _ _ @ + (_)_(_)@ + / _` |@ + | (_| |@ + \__,_|@ + @@ +229 LATIN SMALL LETTER A WITH RING ABOVE + __ @ + (()) @ + / _ '|@ + | (_| |@ + \__,_|@ + @@ +230 LATIN SMALL LETTER AE + @ + __ ____ @ + / _` _ \@ + | (_| __/@ + \__,____|@ + @@ +231 LATIN SMALL LETTER C WITH CEDILLA + @ + ___ @ + / __|@ + | (__ @ + \___|@ + )_) @@ +232 LATIN SMALL LETTER E WITH GRAVE + __ @ + \_\ @ + / _ \@ + | __/@ + \___|@ + @@ +233 LATIN SMALL LETTER E WITH ACUTE + __ @ + /_/ @ + / _ \@ + | __/@ + \___|@ + @@ +234 LATIN SMALL LETTER E WITH CIRCUMFLEX + //\ @ + |/_\|@ + / _ \@ + | __/@ + \___|@ + @@ +235 LATIN SMALL LETTER E WITH DIAERESIS + _ _ @ + (_)_(_)@ + / _ \ @ + | __/ @ + \___| @ + @@ +236 LATIN SMALL LETTER I WITH GRAVE + __ @ + \_\@ + | |@ + | |@ + |_|@ + @@ +237 LATIN SMALL LETTER I WITH ACUTE + __@ + /_/@ + | |@ + | |@ + |_|@ + @@ +238 LATIN SMALL LETTER I WITH CIRCUMFLEX + //\ @ + |/_\|@ + | | @ + | | @ + |_| @ + @@ +239 LATIN SMALL LETTER I WITH DIAERESIS + _ _ @ + (_)_(_)@ + | | @ + | | @ + |_| @ + @@ +240 LATIN SMALL LETTER ETH + /\/\ @ + > < @ + _\/\ |@ + / __` |@ + \____/ @ + @@ +241 LATIN SMALL LETTER N WITH TILDE + /\/| @ + |/\/ @ + | '_ \ @ + | | | |@ + |_| |_|@ + @@ +242 LATIN SMALL LETTER O WITH GRAVE + __ @ + \_\ @ + / _ \ @ + | (_) |@ + \___/ @ + @@ +243 LATIN SMALL LETTER O WITH ACUTE + __ @ + /_/ @ + / _ \ @ + | (_) |@ + \___/ @ + @@ +244 LATIN SMALL LETTER O WITH CIRCUMFLEX + //\ @ + |/_\| @ + / _ \ @ + | (_) |@ + \___/ @ + @@ +245 LATIN SMALL LETTER O WITH TILDE + /\/| @ + |/\/ @ + / _ \ @ + | (_) |@ + \___/ @ + @@ +246 LATIN SMALL LETTER O WITH DIAERESIS + _ _ @ + (_)_(_)@ + / _ \ @ + | (_) |@ + \___/ @ + @@ +247 DIVISION SIGN + @ + _ @ + _(_)_ @ + |_____|@ + (_) @ + @@ +248 LATIN SMALL LETTER O WITH STROKE + @ + ____ @ + / _//\ @ + | (//) |@ + \//__/ @ + @@ +249 LATIN SMALL LETTER U WITH GRAVE + __ @ + _\_\_ @ + | | | |@ + | |_| |@ + \__,_|@ + @@ +250 LATIN SMALL LETTER U WITH ACUTE + __ @ + _/_/_ @ + | | | |@ + | |_| |@ + \__,_|@ + @@ +251 LATIN SMALL LETTER U WITH CIRCUMFLEX + //\ @ + |/ \| @ + | | | |@ + | |_| |@ + \__,_|@ + @@ +252 LATIN SMALL LETTER U WITH DIAERESIS + _ _ @ + (_) (_)@ + | | | |@ + | |_| |@ + \__,_|@ + @@ +253 LATIN SMALL LETTER Y WITH ACUTE + __ @ + _/_/_ @ + | | | |@ + | |_| |@ + \__, |@ + |___/ @@ +254 LATIN SMALL LETTER THORN + _ @ + | |__ @ + | '_ \ @ + | |_) |@ + | .__/ @ + |_| @@ +255 LATIN SMALL LETTER Y WITH DIAERESIS + _ _ @ + (_) (_)@ + | | | |@ + | |_| |@ + \__, |@ + |___/ @@ +0x0100 LATIN CAPITAL LETTER A WITH MACRON + ____ @ + /___/ @ + /_\ @ + / _ \ @ + /_/ \_\@ + @@ +0x0101 LATIN SMALL LETTER A WITH MACRON + ___ @ + /_ _/@ + / _` |@ + | (_| |@ + \__,_|@ + @@ +0x0102 LATIN CAPITAL LETTER A WITH BREVE + _ _ @ + \\_// @ + /_\ @ + / _ \ @ + /_/ \_\@ + @@ +0x0103 LATIN SMALL LETTER A WITH BREVE + \_/ @ + ___ @ + / _` |@ + | (_| |@ + \__,_|@ + @@ +0x0104 LATIN CAPITAL LETTER A WITH OGONEK + @ + _ @ + /_\ @ + / _ \ @ + /_/ \_\@ + (_(@@ +0x0105 LATIN SMALL LETTER A WITH OGONEK + @ + __ _ @ + / _` |@ + | (_| |@ + \__,_|@ + (_(@@ +0x0106 LATIN CAPITAL LETTER C WITH ACUTE + __ @ + _/_/ @ + / ___|@ + | |___ @ + \____|@ + @@ +0x0107 LATIN SMALL LETTER C WITH ACUTE + __ @ + /__/@ + / __|@ + | (__ @ + \___|@ + @@ +0x0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX + /\ @ + _//\\@ + / ___|@ + | |___ @ + \____|@ + @@ +0x0109 LATIN SMALL LETTER C WITH CIRCUMFLEX + /\ @ + /_\ @ + / __|@ + | (__ @ + \___|@ + @@ +0x010A LATIN CAPITAL LETTER C WITH DOT ABOVE + [] @ + ____ @ + / ___|@ + | |___ @ + \____|@ + @@ +0x010B LATIN SMALL LETTER C WITH DOT ABOVE + [] @ + ___ @ + / __|@ + | (__ @ + \___|@ + @@ +0x010C LATIN CAPITAL LETTER C WITH CARON + \\// @ + _\/_ @ + / ___|@ + | |___ @ + \____|@ + @@ +0x010D LATIN SMALL LETTER C WITH CARON + \\//@ + _\/ @ + / __|@ + | (__ @ + \___|@ + @@ +0x010E LATIN CAPITAL LETTER D WITH CARON + \\// @ + __\/ @ + | _ \ @ + | |_| |@ + |____/ @ + @@ +0x010F LATIN SMALL LETTER D WITH CARON + \/ _ @ + __| |@ + / _` |@ + | (_| |@ + \__,_|@ + @@ +0x0110 LATIN CAPITAL LETTER D WITH STROKE + ____ @ + |_ __ \ @ + /| |/ | |@ + /|_|/_| |@ + |_____/ @ + @@ +0x0111 LATIN SMALL LETTER D WITH STROKE + ---|@ + __| |@ + / _` |@ + | (_| |@ + \__,_|@ + @@ +0x0112 LATIN CAPITAL LETTER E WITH MACRON + ____ @ + /___/ @ + | ____|@ + | _|_ @ + |_____|@ + @@ +0x0113 LATIN SMALL LETTER E WITH MACRON + ____@ + /_ _/@ + / _ \ @ + | __/ @ + \___| @ + @@ +0x0114 LATIN CAPITAL LETTER E WITH BREVE + _ _ @ + \\_// @ + | ____|@ + | _|_ @ + |_____|@ + @@ +0x0115 LATIN SMALL LETTER E WITH BREVE + \\ //@ + -- @ + / _ \ @ + | __/ @ + \___| @ + @@ +0x0116 LATIN CAPITAL LETTER E WITH DOT ABOVE + [] @ + _____ @ + | ____|@ + | _|_ @ + |_____|@ + @@ +0x0117 LATIN SMALL LETTER E WITH DOT ABOVE + [] @ + __ @ + / _ \@ + | __/@ + \___|@ + @@ +0x0118 LATIN CAPITAL LETTER E WITH OGONEK + @ + _____ @ + | ____|@ + | _|_ @ + |_____|@ + (__(@@ +0x0119 LATIN SMALL LETTER E WITH OGONEK + @ + ___ @ + / _ \@ + | __/@ + \___|@ + (_(@@ +0x011A LATIN CAPITAL LETTER E WITH CARON + \\// @ + __\/_ @ + | ____|@ + | _|_ @ + |_____|@ + @@ +0x011B LATIN SMALL LETTER E WITH CARON + \\//@ + \/ @ + / _ \@ + | __/@ + \___|@ + @@ +0x011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX + _/\_ @ + / ___|@ + | | _ @ + | |_| |@ + \____|@ + @@ +0x011D LATIN SMALL LETTER G WITH CIRCUMFLEX + /\ @ + _/_ \@ + / _` |@ + | (_| |@ + \__, |@ + |___/ @@ +0x011E LATIN CAPITAL LETTER G WITH BREVE + _\/_ @ + / ___|@ + | | _ @ + | |_| |@ + \____|@ + @@ +0x011F LATIN SMALL LETTER G WITH BREVE + \___/ @ + __ _ @ + / _` |@ + | (_| |@ + \__, |@ + |___/ @@ +0x0120 LATIN CAPITAL LETTER G WITH DOT ABOVE + _[]_ @ + / ___|@ + | | _ @ + | |_| |@ + \____|@ + @@ +0x0121 LATIN SMALL LETTER G WITH DOT ABOVE + [] @ + __ _ @ + / _` |@ + | (_| |@ + \__, |@ + |___/ @@ +0x0122 LATIN CAPITAL LETTER G WITH CEDILLA + ____ @ + / ___|@ + | | _ @ + | |_| |@ + \____|@ + )__) @@ +0x0123 LATIN SMALL LETTER G WITH CEDILLA + @ + __ _ @ + / _` |@ + | (_| |@ + \__, |@ + |_))))@@ +0x0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX + _/ \_ @ + | / \ |@ + | |_| |@ + | _ |@ + |_| |_|@ + @@ +0x0125 LATIN SMALL LETTER H WITH CIRCUMFLEX + _ /\ @ + | |//\ @ + | '_ \ @ + | | | |@ + |_| |_|@ + @@ +0x0126 LATIN CAPITAL LETTER H WITH STROKE + _ _ @ + | |=| |@ + | |_| |@ + | _ |@ + |_| |_|@ + @@ +0x0127 LATIN SMALL LETTER H WITH STROKE + _ @ + |=|__ @ + | '_ \ @ + | | | |@ + |_| |_|@ + @@ +0x0128 LATIN CAPITAL LETTER I WITH TILDE + /\//@ + |_ _|@ + | | @ + | | @ + |___|@ + @@ +0x0129 LATIN SMALL LETTER I WITH TILDE + @ + /\/@ + | |@ + | |@ + |_|@ + @@ +0x012A LATIN CAPITAL LETTER I WITH MACRON + /___/@ + |_ _|@ + | | @ + | | @ + |___|@ + @@ +0x012B LATIN SMALL LETTER I WITH MACRON + ____@ + /___/@ + | | @ + | | @ + |_| @ + @@ +0x012C LATIN CAPITAL LETTER I WITH BREVE + \__/@ + |_ _|@ + | | @ + | | @ + |___|@ + @@ +0x012D LATIN SMALL LETTER I WITH BREVE + @ + \_/@ + | |@ + | |@ + |_|@ + @@ +0x012E LATIN CAPITAL LETTER I WITH OGONEK + ___ @ + |_ _|@ + | | @ + | | @ + |___|@ + (__(@@ +0x012F LATIN SMALL LETTER I WITH OGONEK + _ @ + (_) @ + | | @ + | | @ + |_|_@ + (_(@@ +0x0130 LATIN CAPITAL LETTER I WITH DOT ABOVE + _[] @ + |_ _|@ + | | @ + | | @ + |___|@ + @@ +0x0131 LATIN SMALL LETTER DOTLESS I + @ + _ @ + | |@ + | |@ + |_|@ + @@ +0x0132 LATIN CAPITAL LIGATURE IJ + ___ _ @ + |_ _|| |@ + | | | |@ + | |_| |@ + |__|__/ @ + @@ +0x0133 LATIN SMALL LIGATURE IJ + _ _ @ + (_) (_)@ + | | | |@ + | | | |@ + |_|_/ |@ + |__/ @@ +0x0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX + /\ @ + /_\|@ + _ | | @ + | |_| | @ + \___/ @ + @@ +0x0135 LATIN SMALL LETTER J WITH CIRCUMFLEX + /\@ + /_\@ + | |@ + | |@ + _/ |@ + |__/ @@ +0x0136 LATIN CAPITAL LETTER K WITH CEDILLA + _ _ @ + | |/ / @ + | ' / @ + | . \ @ + |_|\_\ @ + )__)@@ +0x0137 LATIN SMALL LETTER K WITH CEDILLA + _ @ + | | __@ + | |/ /@ + | < @ + |_|\_\@ + )_)@@ +0x0138 LATIN SMALL LETTER KRA + @ + _ __ @ + | |/ \@ + | < @ + |_|\_\@ + @@ +0x0139 LATIN CAPITAL LETTER L WITH ACUTE + _ //@ + | | // @ + | | @ + | |___ @ + |_____|@ + @@ +0x013A LATIN SMALL LETTER L WITH ACUTE + //@ + | |@ + | |@ + | |@ + |_|@ + @@ +0x013B LATIN CAPITAL LETTER L WITH CEDILLA + _ @ + | | @ + | | @ + | |___ @ + |_____|@ + )__)@@ +0x013C LATIN SMALL LETTER L WITH CEDILLA + _ @ + | | @ + | | @ + | | @ + |_| @ + )_)@@ +0x013D LATIN CAPITAL LETTER L WITH CARON + _ \\//@ + | | \/ @ + | | @ + | |___ @ + |_____|@ + @@ +0x013E LATIN SMALL LETTER L WITH CARON + _ \\//@ + | | \/ @ + | | @ + | | @ + |_| @ + @@ +0x013F LATIN CAPITAL LETTER L WITH MIDDLE DOT + _ @ + | | @ + | | [] @ + | |___ @ + |_____|@ + @@ +0x0140 LATIN SMALL LETTER L WITH MIDDLE DOT + _ @ + | | @ + | | []@ + | | @ + |_| @ + @@ +0x0141 LATIN CAPITAL LETTER L WITH STROKE + __ @ + | // @ + |//| @ + // |__ @ + |_____|@ + @@ +0x0142 LATIN SMALL LETTER L WITH STROKE + _ @ + | |@ + |//@ + //|@ + |_|@ + @@ +0x0143 LATIN CAPITAL LETTER N WITH ACUTE + _/ /_ @ + | \ | |@ + | \| |@ + | |\ |@ + |_| \_|@ + @@ +0x0144 LATIN SMALL LETTER N WITH ACUTE + _ @ + _ /_/ @ + | '_ \ @ + | | | |@ + |_| |_|@ + @@ +0x0145 LATIN CAPITAL LETTER N WITH CEDILLA + _ _ @ + | \ | |@ + | \| |@ + | |\ |@ + |_| \_|@ + )_) @@ +0x0146 LATIN SMALL LETTER N WITH CEDILLA + @ + _ __ @ + | '_ \ @ + | | | |@ + |_| |_|@ + )_) @@ +0x0147 LATIN CAPITAL LETTER N WITH CARON + _\/ _ @ + | \ | |@ + | \| |@ + | |\ |@ + |_| \_|@ + @@ +0x0148 LATIN SMALL LETTER N WITH CARON + \\// @ + _\/_ @ + | '_ \ @ + | | | |@ + |_| |_|@ + @@ +0x0149 LATIN SMALL LETTER N PRECEDED BY APOSTROPHE + @ + _ __ @ + ( )| '_\ @ + |/| | | |@ + |_| |_|@ + @@ +0x014A LATIN CAPITAL LETTER ENG + _ _ @ + | \ | |@ + | \| |@ + | |\ |@ + |_| \ |@ + )_)@@ +0x014B LATIN SMALL LETTER ENG + _ __ @ + | '_ \ @ + | | | |@ + |_| | |@ + | |@ + |__ @@ +0x014C LATIN CAPITAL LETTER O WITH MACRON + ____ @ + /_ _/ @ + / _ \ @ + | (_) |@ + \___/ @ + @@ +0x014D LATIN SMALL LETTER O WITH MACRON + ____ @ + /_ _/ @ + / _ \ @ + | (_) |@ + \___/ @ + @@ +0x014E LATIN CAPITAL LETTER O WITH BREVE + \ / @ + _-_ @ + / _ \ @ + | |_| |@ + \___/ @ + @@ +0x014F LATIN SMALL LETTER O WITH BREVE + \ / @ + _-_ @ + / _ \ @ + | |_| |@ + \___/ @ + @@ +0x0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + ___ @ + /_/_/@ + / _ \ @ + | |_| |@ + \___/ @ + @@ +0x0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE + ___ @ + /_/_/@ + / _ \ @ + | |_| |@ + \___/ @ + @@ +0x0152 LATIN CAPITAL LIGATURE OE + ___ ___ @ + / _ \| __|@ + | | | | | @ + | |_| | |__@ + \___/|____@ + @@ +0x0153 LATIN SMALL LIGATURE OE + @ + ___ ___ @ + / _ \ / _ \@ + | (_) | __/@ + \___/ \___|@ + @@ +0x0154 LATIN CAPITAL LETTER R WITH ACUTE + _/_/ @ + | _ \ @ + | |_) |@ + | _ < @ + |_| \_\@ + @@ +0x0155 LATIN SMALL LETTER R WITH ACUTE + __@ + _ /_/@ + | '__|@ + | | @ + |_| @ + @@ +0x0156 LATIN CAPITAL LETTER R WITH CEDILLA + ____ @ + | _ \ @ + | |_) |@ + | _ < @ + |_| \_\@ + )_) @@ +0x0157 LATIN SMALL LETTER R WITH CEDILLA + @ + _ __ @ + | '__|@ + | | @ + |_| @ + )_) @@ +0x0158 LATIN CAPITAL LETTER R WITH CARON + _\_/ @ + | _ \ @ + | |_) |@ + | _ < @ + |_| \_\@ + @@ +0x0159 LATIN SMALL LETTER R WITH CARON + \\// @ + _\/_ @ + | '__|@ + | | @ + |_| @ + @@ +0x015A LATIN CAPITAL LETTER S WITH ACUTE + _/_/ @ + / ___| @ + \___ \ @ + ___) |@ + |____/ @ + @@ +0x015B LATIN SMALL LETTER S WITH ACUTE + __@ + _/_/@ + / __|@ + \__ \@ + |___/@ + @@ +0x015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX + _/\_ @ + / ___| @ + \___ \ @ + ___) |@ + |____/ @ + @@ +0x015D LATIN SMALL LETTER S WITH CIRCUMFLEX + @ + /_\_@ + / __|@ + \__ \@ + |___/@ + @@ +0x015E LATIN CAPITAL LETTER S WITH CEDILLA + ____ @ + / ___| @ + \___ \ @ + ___) |@ + |____/ @ + )__)@@ +0x015F LATIN SMALL LETTER S WITH CEDILLA + @ + ___ @ + / __|@ + \__ \@ + |___/@ + )_)@@ +0x0160 LATIN CAPITAL LETTER S WITH CARON + _\_/ @ + / ___| @ + \___ \ @ + ___) |@ + |____/ @ + @@ +0x0161 LATIN SMALL LETTER S WITH CARON + \\//@ + _\/ @ + / __|@ + \__ \@ + |___/@ + @@ +0x0162 LATIN CAPITAL LETTER T WITH CEDILLA + _____ @ + |_ _|@ + | | @ + | | @ + |_| @ + )__)@@ +0x0163 LATIN SMALL LETTER T WITH CEDILLA + _ @ + | |_ @ + | __|@ + | |_ @ + \__|@ + )_)@@ +0x0164 LATIN CAPITAL LETTER T WITH CARON + _____ @ + |_ _|@ + | | @ + | | @ + |_| @ + @@ +0x0165 LATIN SMALL LETTER T WITH CARON + \/ @ + | |_ @ + | __|@ + | |_ @ + \__|@ + @@ +0x0166 LATIN CAPITAL LETTER T WITH STROKE + _____ @ + |_ _|@ + | | @ + -|-|- @ + |_| @ + @@ +0x0167 LATIN SMALL LETTER T WITH STROKE + _ @ + | |_ @ + | __|@ + |-|_ @ + \__|@ + @@ +0x0168 LATIN CAPITAL LETTER U WITH TILDE + @ + _/\/_ @ + | | | |@ + | |_| |@ + \___/ @ + @@ +0x0169 LATIN SMALL LETTER U WITH TILDE + @ + _/\/_ @ + | | | |@ + | |_| |@ + \__,_|@ + @@ +0x016A LATIN CAPITAL LETTER U WITH MACRON + ____ @ + /__ _/@ + | | | |@ + | |_| |@ + \___/ @ + @@ +0x016B LATIN SMALL LETTER U WITH MACRON + ____ @ + / _ /@ + | | | |@ + | |_| |@ + \__,_|@ + @@ +0x016C LATIN CAPITAL LETTER U WITH BREVE + @ + \_/_ @ + | | | |@ + | |_| |@ + \____|@ + @@ +0x016D LATIN SMALL LETTER U WITH BREVE + @ + \_/_ @ + | | | |@ + | |_| |@ + \__,_|@ + @@ +0x016E LATIN CAPITAL LETTER U WITH RING ABOVE + O @ + __ _ @ + | | | |@ + | |_| |@ + \___/ @ + @@ +0x016F LATIN SMALL LETTER U WITH RING ABOVE + O @ + __ __ @ + | | | |@ + | |_| |@ + \__,_|@ + @@ +0x0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + -- --@ + /_//_/@ + | | | |@ + | |_| |@ + \___/ @ + @@ +0x0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE + ____@ + _/_/_/@ + | | | |@ + | |_| |@ + \__,_|@ + @@ +0x0172 LATIN CAPITAL LETTER U WITH OGONEK + _ _ @ + | | | |@ + | | | |@ + | |_| |@ + \___/ @ + (__(@@ +0x0173 LATIN SMALL LETTER U WITH OGONEK + @ + _ _ @ + | | | |@ + | |_| |@ + \__,_|@ + (_(@@ +0x0174 LATIN CAPITAL LETTER W WITH CIRCUMFLEX + __ /\ __@ + \ \ //\\/ /@ + \ \ /\ / / @ + \ V V / @ + \_/\_/ @ + @@ +0x0175 LATIN SMALL LETTER W WITH CIRCUMFLEX + /\ @ + __ //\\__@ + \ \ /\ / /@ + \ V V / @ + \_/\_/ @ + @@ +0x0176 LATIN CAPITAL LETTER Y WITH CIRCUMFLEX + /\ @ + __//\\ @ + \ \ / /@ + \ V / @ + |_| @ + @@ +0x0177 LATIN SMALL LETTER Y WITH CIRCUMFLEX + /\ @ + //\\ @ + | | | |@ + | |_| |@ + \__, |@ + |___/ @@ +0x0178 LATIN CAPITAL LETTER Y WITH DIAERESIS + [] []@ + __ _@ + \ \ / /@ + \ V / @ + |_| @ + @@ +0x0179 LATIN CAPITAL LETTER Z WITH ACUTE + __/_/@ + |__ /@ + / / @ + / /_ @ + /____|@ + @@ +0x017A LATIN SMALL LETTER Z WITH ACUTE + _ @ + _/_/@ + |_ /@ + / / @ + /___|@ + @@ +0x017B LATIN CAPITAL LETTER Z WITH DOT ABOVE + __[]_@ + |__ /@ + / / @ + / /_ @ + /____|@ + @@ +0x017C LATIN SMALL LETTER Z WITH DOT ABOVE + [] @ + ____@ + |_ /@ + / / @ + /___|@ + @@ +0x017D LATIN CAPITAL LETTER Z WITH CARON + _\_/_@ + |__ /@ + / / @ + / /_ @ + /____|@ + @@ +0x017E LATIN SMALL LETTER Z WITH CARON + \\//@ + _\/_@ + |_ /@ + / / @ + /___|@ + @@ +0x017F LATIN SMALL LETTER LONG S + __ @ + / _|@ + |-| | @ + |-| | @ + |_| @ + @@ +0x02C7 CARON + \\//@ + \/ @ + $@ + $@ + $@ + $@@ +0x02D8 BREVE + \\_//@ + \_/ @ + $@ + $@ + $@ + $@@ +0x02D9 DOT ABOVE + []@ + $@ + $@ + $@ + $@ + $@@ +0x02DB OGONEK + $@ + $@ + $@ + $@ + $@ + )_) @@ +0x02DD DOUBLE ACUTE ACCENT + _ _ @ + /_/_/@ + $@ + $@ + $@ + $@@ \ No newline at end of file diff --git a/src/Spectre.Console/Internal/ResourceReader.cs b/src/Spectre.Console/Internal/ResourceReader.cs new file mode 100644 index 0000000..908707b --- /dev/null +++ b/src/Spectre.Console/Internal/ResourceReader.cs @@ -0,0 +1,32 @@ +using System; +using System.IO; + +namespace Spectre.Console.Internal +{ + internal static class ResourceReader + { + public static string ReadManifestData(string resourceName) + { + if (resourceName is null) + { + throw new ArgumentNullException(nameof(resourceName)); + } + + var assembly = typeof(ResourceReader).Assembly; + resourceName = resourceName.ReplaceExact("/", "."); + + using (var stream = assembly.GetManifestResourceStream(resourceName)) + { + if (stream == null) + { + throw new InvalidOperationException("Could not load manifest resource stream."); + } + + using (var reader = new StreamReader(stream)) + { + return reader.ReadToEnd().NormalizeLineEndings(); + } + } + } + } +} diff --git a/src/Spectre.Console/Spectre.Console.csproj b/src/Spectre.Console/Spectre.Console.csproj index e2aa4d9..7a3d999 100644 --- a/src/Spectre.Console/Spectre.Console.csproj +++ b/src/Spectre.Console/Spectre.Console.csproj @@ -5,8 +5,13 @@ enable + + + + + @@ -20,20 +25,6 @@ - - - BoxBorder.cs - - - TableBorder.cs - - - AnsiConsoleExtensions.cs - - - AnsiConsoleExtensions.cs - - 3.0.0 False