diff --git a/Figgle.Generator.AcceptanceTests/Figgle.Generator.AcceptanceTests.csproj b/Figgle.Generator.AcceptanceTests/Figgle.Generator.AcceptanceTests.csproj new file mode 100644 index 0000000..89dcf82 --- /dev/null +++ b/Figgle.Generator.AcceptanceTests/Figgle.Generator.AcceptanceTests.csproj @@ -0,0 +1,41 @@ + + + + + + + net7.0 + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + + + + + + diff --git a/Figgle.Generator.AcceptanceTests/FiggleSourceGeneratorAcceptanceTests.cs b/Figgle.Generator.AcceptanceTests/FiggleSourceGeneratorAcceptanceTests.cs new file mode 100644 index 0000000..bf7e337 --- /dev/null +++ b/Figgle.Generator.AcceptanceTests/FiggleSourceGeneratorAcceptanceTests.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System; +using Xunit; + +namespace Figgle.Generator.AcceptanceTests; + +[GenerateFiggleText("HelloWorld", "My External Font", "Hello World!")] +public partial class FiggleSourceGeneratorAcceptanceTests +{ + [Fact] + public void HelloWorldTextWithExternalFontIsSourceGenerated_RenderedTextMatches() + { + string expectedText = """ + ██╗ ██╗███████╗██╗ ██╗ ██████╗ ██╗ ██╗ ██████╗ ██████╗ ██╗ ██████╗ ██╗ + ██║ ██║██╔════╝██║ ██║ ██╔═══██╗ ██║ ██║██╔═══██╗██╔══██╗██║ ██╔══██╗██║ + ███████║█████╗ ██║ ██║ ██║ ██║ ██║ █╗ ██║██║ ██║██████╔╝██║ ██║ ██║██║ + ██╔══██║██╔══╝ ██║ ██║ ██║ ██║ ██║███╗██║██║ ██║██╔══██╗██║ ██║ ██║╚═╝ + ██║ ██║███████╗███████╗███████╗╚██████╔╝ ╚███╔███╔╝╚██████╔╝██║ ██║███████╗██████╔╝██╗ + ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝ ╚═════╝ ╚══╝╚══╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═════╝ ╚═╝ + """; + + Assert.Equal(expectedText, HelloWorld.Trim(), NewlineIgnoreComparer.Instance); + } + + private sealed class NewlineIgnoreComparer : IEqualityComparer + { + public static NewlineIgnoreComparer Instance { get; } = new(); + + public bool Equals(string? x, string? y) + { + return StringComparer.Ordinal.Equals(Normalize(x), Normalize(y)); + } + + public int GetHashCode(string obj) + { + return StringComparer.Ordinal.GetHashCode(Normalize(obj)); + } + + [return: NotNullIfNotNull("s")] + private static string? Normalize(string? s) => s?.Replace("\r", ""); + } +} diff --git a/Figgle.Generator.Tests/Figgle.Generator.Tests.csproj b/Figgle.Generator.Tests/Figgle.Generator.Tests.csproj index b1ed8a7..c8a7477 100644 --- a/Figgle.Generator.Tests/Figgle.Generator.Tests.csproj +++ b/Figgle.Generator.Tests/Figgle.Generator.Tests.csproj @@ -25,6 +25,7 @@ PreserveNewest + FiggleSourceGeneratorTests_ExternalFonts.cs diff --git a/Figgle.Generator.Tests/FiggleSourceGeneratorTests.cs b/Figgle.Generator.Tests/FiggleSourceGeneratorTests.cs index b815981..8ae956d 100644 --- a/Figgle.Generator.Tests/FiggleSourceGeneratorTests.cs +++ b/Figgle.Generator.Tests/FiggleSourceGeneratorTests.cs @@ -9,13 +9,14 @@ using System.Threading; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Text; using Xunit; using Xunit.Sdk; namespace Figgle.Generator.Tests; -public class FiggleSourceGeneratorTests +public partial class FiggleSourceGeneratorTests { private readonly ImmutableArray _references; @@ -614,64 +615,22 @@ internal partial class Inner Assert.Equal("Unable to generate Figgle text for nested type 'Inner'. Generation is only supported for non-nested types.", diagnostic.GetMessage()); } - [Theory] - [InlineData("ANSI Shadow")] - [InlineData("ansi shadow")] - public void ExternalFontInAdditionalFiles_RendersText(string fontName) - { - string source = - $$""" - namespace Test.Namespace - { - [GenerateFiggleText("Member", "{{fontName}}", "Figgle")] - internal partial class DemoUsage - { - } - } - """; - string expected = - """ - // Copyright Drew Noakes. Licensed under the Apache-2.0 license. See the LICENSE file for more details. - - // - // This code was generated by Figgle.Generator. - // - // Changes to this file may cause incorrect behavior and will be lost if - // the code is regenerated. - // - - namespace Test.Namespace - { - partial class DemoUsage - { - public static string Member { get; } = @"███████╗██╗ ██████╗ ██████╗ ██╗ ███████╗ - ██╔════╝██║██╔════╝ ██╔════╝ ██║ ██╔════╝ - █████╗ ██║██║ ███╗██║ ███╗██║ █████╗ - ██╔══╝ ██║██║ ██║██║ ██║██║ ██╔══╝ - ██║ ██║╚██████╔╝╚██████╔╝███████╗███████╗ - ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝╚══════╝ - - "; - } - } - """; - - using var fontStream = File.OpenRead("ANSI Shadow.flf"); - var additionalFonts = ImmutableArray.Create(new ExternalFontAdditionalText("ANSI Shadow.flf", fontStream)); - ValidateOutput(source, additionalFonts, expected); - } - private void ValidateOutput(string source, params string[] outputs) { - ValidateOutput(source, ImmutableArray.Empty, outputs); + ValidateOutput( + source, + ImmutableArray.Empty, + optionsProvider: null, + outputs); } private void ValidateOutput( string source, ImmutableArray additionalFonts, + TestAnalyzerConfigOptionsProvider? optionsProvider, params string[] outputs) { - var (compilation, diagnostics) = RunGenerator(source, additionalFonts); + var (compilation, diagnostics) = RunGenerator(source, additionalFonts, optionsProvider); ValidateNoErrors(diagnostics); @@ -683,23 +642,23 @@ private void ValidateOutput( private (Compilation Compilation, ImmutableArray Diagnostics) RunGenerator( string source, - ImmutableArray? optionalAdditionalFonts = null) + ImmutableArray? additionalFonts = null, + TestAnalyzerConfigOptionsProvider? optionsProvider = null) { - var additionalFonts = optionalAdditionalFonts - ?? ImmutableArray.Empty; - var syntaxTree = CSharpSyntaxTree.ParseText(source); var compilation = CSharpCompilation.Create( "testAssembly", - new SyntaxTree[] { syntaxTree }, + [syntaxTree], _references, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); ISourceGenerator generator = new FiggleSourceGenerator(); - var driver = CSharpGeneratorDriver.Create(generator) - .AddAdditionalTexts(additionalFonts.As()); + var driver = CSharpGeneratorDriver.Create( + [generator], + additionalTexts: additionalFonts, + optionsProvider: optionsProvider); driver.RunGeneratorsAndUpdateCompilation( compilation, @@ -722,24 +681,6 @@ private static void ValidateNoErrors(ImmutableArray diagnostics) } } - private sealed class ExternalFontAdditionalText : AdditionalText - { - private readonly SourceText _sourceText; - - public ExternalFontAdditionalText(string path, Stream externalFont) - { - Path = path; - _sourceText = SourceText.From(externalFont); - } - - public override string Path { get; } - - public override SourceText? GetText(CancellationToken cancellationToken = default) - { - return _sourceText; - } - } - private sealed class NewlineIgnoreComparer : IEqualityComparer { public static NewlineIgnoreComparer Instance { get; } = new(); diff --git a/Figgle.Generator.Tests/FiggleSourceGeneratorTests_ExternalFonts.cs b/Figgle.Generator.Tests/FiggleSourceGeneratorTests_ExternalFonts.cs new file mode 100644 index 0000000..c12e694 --- /dev/null +++ b/Figgle.Generator.Tests/FiggleSourceGeneratorTests_ExternalFonts.cs @@ -0,0 +1,162 @@ +// Copyright Drew Noakes. Licensed under the Apache-2.0 license. See the LICENSE file for more details. + +using System.IO; +using System.Threading; +using Microsoft.CodeAnalysis.Text; +using Microsoft.CodeAnalysis; +using Xunit; +using System.Collections.Immutable; + +namespace Figgle.Generator.Tests; + +public partial class FiggleSourceGeneratorTests +{ + private const string ExternalFontFileName = "ANSI Shadow.flf"; + + [Theory] + [InlineData("ANSI Shadow")] + [InlineData("ansi shadow")] + public void ExternalFontInAdditionalFiles_RendersText(string fontName) + { + string source = + $$""" + namespace Test.Namespace + { + [GenerateFiggleText("Member", "{{fontName}}", "Figgle")] + internal partial class DemoUsage + { + } + } + """; + string expected = + """ + // Copyright Drew Noakes. Licensed under the Apache-2.0 license. See the LICENSE file for more details. + + // + // This code was generated by Figgle.Generator. + // + // Changes to this file may cause incorrect behavior and will be lost if + // the code is regenerated. + // + + namespace Test.Namespace + { + partial class DemoUsage + { + public static string Member { get; } = @"███████╗██╗ ██████╗ ██████╗ ██╗ ███████╗ + ██╔════╝██║██╔════╝ ██╔════╝ ██║ ██╔════╝ + █████╗ ██║██║ ███╗██║ ███╗██║ █████╗ + ██╔══╝ ██║██║ ██║██║ ██║██║ ██╔══╝ + ██║ ██║╚██████╔╝╚██████╔╝███████╗███████╗ + ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝╚══════╝ + + "; + } + } + """; + + var additionalFont = ExternalFontAdditionalText.Create(ExternalFontFileName); + + ValidateOutput( + source, + ImmutableArray.Create(additionalFont), + optionsProvider: null, + expected); + } + + [Theory] + [InlineData("MyCustomFontName", "MyCustomFontName")] + [InlineData("myCustomFontname", "MyCustomFontName")] + public void ExternalFontInAdditionalFilesWithExplicitFontNameProperty_RendersText( + string generateFiggleFontName, + string externalFontNamePropertyValue) + { + string source = + $$""" + namespace Test.Namespace + { + [GenerateFiggleText("Member", "{{generateFiggleFontName}}", "Figgle")] + internal partial class DemoUsage + { + } + } + """; + string expected = + """ + // Copyright Drew Noakes. Licensed under the Apache-2.0 license. See the LICENSE file for more details. + + // + // This code was generated by Figgle.Generator. + // + // Changes to this file may cause incorrect behavior and will be lost if + // the code is regenerated. + // + + namespace Test.Namespace + { + partial class DemoUsage + { + public static string Member { get; } = @"███████╗██╗ ██████╗ ██████╗ ██╗ ███████╗ + ██╔════╝██║██╔════╝ ██╔════╝ ██║ ██╔════╝ + █████╗ ██║██║ ███╗██║ ███╗██║ █████╗ + ██╔══╝ ██║██║ ██║██║ ██║██║ ██╔══╝ + ██║ ██║╚██████╔╝╚██████╔╝███████╗███████╗ + ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝╚══════╝ + + "; + } + } + """; + + var additionalFont = ExternalFontAdditionalText.Create(ExternalFontFileName); + + var optionsProvider = CreateOptionsProvider( + ExternalFontFileName, + externalFontNamePropertyValue); + + ValidateOutput( + source, + ImmutableArray.Create(additionalFont), + optionsProvider, + expected); + + static TestAnalyzerConfigOptionsProvider CreateOptionsProvider( + string fontFileName, + string fontNameProperty) + { + var additionalFontOption = new TestAnalyzerConfigOptionsBuilder() + .AddOption("build_metadata.AdditionalFiles.FontName", fontNameProperty) + .Build(); + + return new TestAnalyzerConfigOptionsProvider( + getAdditionalFileOptions: f => f.Path == fontFileName + ? additionalFontOption + : null); + } + } + + private sealed class ExternalFontAdditionalText : AdditionalText + { + private readonly SourceText _sourceText; + + public static ExternalFontAdditionalText Create(string externalFontPath) + { + using var fontStream = File.OpenRead(externalFontPath); + + return new ExternalFontAdditionalText(externalFontPath, fontStream); + } + + public ExternalFontAdditionalText(string path, Stream externalFont) + { + Path = path; + _sourceText = SourceText.From(externalFont); + } + + public override string Path { get; } + + public override SourceText? GetText(CancellationToken cancellationToken = default) + { + return _sourceText; + } + } +} diff --git a/Figgle.Generator.Tests/TestAnalyzerConfigOptions.cs b/Figgle.Generator.Tests/TestAnalyzerConfigOptions.cs new file mode 100644 index 0000000..c1ede5d --- /dev/null +++ b/Figgle.Generator.Tests/TestAnalyzerConfigOptions.cs @@ -0,0 +1,31 @@ +// Copyright Drew Noakes. Licensed under the Apache-2.0 license. See the LICENSE file for more details. + +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; + +namespace Figgle.Generator.Tests; + +internal sealed class TestAnalyzerConfigOptions : AnalyzerConfigOptions +{ + public static readonly TestAnalyzerConfigOptions Empty + = new(ImmutableDictionary.Empty); + + private readonly ImmutableDictionary _options; + + public TestAnalyzerConfigOptions( + ImmutableDictionary options) + { + _options = options; + } + + public override IEnumerable Keys => _options.Keys; + + public override bool TryGetValue( + string key, + [NotNullWhen(true)] out string? value) + { + return _options.TryGetValue(key, out value); + } +} diff --git a/Figgle.Generator.Tests/TestAnalyzerConfigOptionsBuilder.cs b/Figgle.Generator.Tests/TestAnalyzerConfigOptionsBuilder.cs new file mode 100644 index 0000000..e61bc02 --- /dev/null +++ b/Figgle.Generator.Tests/TestAnalyzerConfigOptionsBuilder.cs @@ -0,0 +1,25 @@ +// Copyright Drew Noakes. Licensed under the Apache-2.0 license. See the LICENSE file for more details. + +using System.Collections.Immutable; + +namespace Figgle.Generator.Tests; + +internal sealed class TestAnalyzerConfigOptionsBuilder +{ + private readonly ImmutableDictionary.Builder _optionsBuilder + = ImmutableDictionary.CreateBuilder(); + + public TestAnalyzerConfigOptionsBuilder AddOption( + string key, + string value) + { + _optionsBuilder.Add(key, value); + return this; + } + + public TestAnalyzerConfigOptions Build() + { + return new TestAnalyzerConfigOptions( + _optionsBuilder.ToImmutable()); + } +} diff --git a/Figgle.Generator.Tests/TestAnalyzerConfigOptionsProvider.cs b/Figgle.Generator.Tests/TestAnalyzerConfigOptionsProvider.cs new file mode 100644 index 0000000..330028f --- /dev/null +++ b/Figgle.Generator.Tests/TestAnalyzerConfigOptionsProvider.cs @@ -0,0 +1,43 @@ +// Copyright Drew Noakes. Licensed under the Apache-2.0 license. See the LICENSE file for more details. + +using System; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis; + +namespace Figgle.Generator.Tests; + +internal sealed class TestAnalyzerConfigOptionsProvider + : AnalyzerConfigOptionsProvider +{ + private readonly Func _getSyntaxTreeOptions; + private readonly Func _getAdditionalFileOptions; + + public TestAnalyzerConfigOptionsProvider( + AnalyzerConfigOptions? globalOptions = null, + Func? getSyntaxTreeOptions = null, + Func? getAdditionalFileOptions = null) + { + GlobalOptions = globalOptions + ?? TestAnalyzerConfigOptions.Empty; + + _getSyntaxTreeOptions = getSyntaxTreeOptions + ?? (_ => TestAnalyzerConfigOptions.Empty); + + _getAdditionalFileOptions = getAdditionalFileOptions + ?? (_ => TestAnalyzerConfigOptions.Empty); + } + + public override AnalyzerConfigOptions GlobalOptions { get; } + + public override AnalyzerConfigOptions GetOptions(SyntaxTree tree) + { + return _getSyntaxTreeOptions(tree) + ?? TestAnalyzerConfigOptions.Empty; + } + + public override AnalyzerConfigOptions GetOptions(AdditionalText textFile) + { + return _getAdditionalFileOptions(textFile) + ?? TestAnalyzerConfigOptions.Empty; + } +} diff --git a/Figgle.Generator/Figgle.Generator.csproj b/Figgle.Generator/Figgle.Generator.csproj index 0d558a4..9acf6c3 100644 --- a/Figgle.Generator/Figgle.Generator.csproj +++ b/Figgle.Generator/Figgle.Generator.csproj @@ -33,6 +33,10 @@ + + + + diff --git a/Figgle.Generator/FiggleSourceGenerator.cs b/Figgle.Generator/FiggleSourceGenerator.cs index ea66473..45cedda 100644 --- a/Figgle.Generator/FiggleSourceGenerator.cs +++ b/Figgle.Generator/FiggleSourceGenerator.cs @@ -140,7 +140,7 @@ partial class {{type.Class}} foreach (var item in data.Items) { var font = FiggleFonts.TryGetByName(item.FontName) - ?? TryParseFromAdditionalFiles(context.AdditionalFiles, item.FontName); + ?? TryParseFromAdditionalFiles(context, item.FontName); if (font is null) { @@ -188,14 +188,10 @@ partial class {{type.Class}} } private static FiggleFont? TryParseFromAdditionalFiles( - ImmutableArray additionalFiles, + GeneratorExecutionContext context, string fontName) { - var matchingAdditionalFile = additionalFiles - .FirstOrDefault(f => string.Equals( - Path.GetFileName(f.Path), - $"{fontName}.flf", - StringComparison.OrdinalIgnoreCase)); + var matchingAdditionalFile = GetMatchingExternalFontFile(context, fontName); if (matchingAdditionalFile is null) { @@ -211,11 +207,53 @@ partial class {{type.Class}} var textEncoding = text.Encoding ?? Encoding.UTF8; using var stream = new MemoryStream(textEncoding.GetBytes(text.ToString())); return FiggleFontParser.Parse(stream); + + static AdditionalText? GetMatchingExternalFontFile( + GeneratorExecutionContext context, + string fontName) + { + // If additional file has an explicit font name property defined, prefer that first. + // Otherwise, fall back to matching the filename. + var matchingFile = context.AdditionalFiles + .FirstOrDefault(f => FontNamePropertyMatchesFontName(context, f, fontName)); + + if (matchingFile is not null) + { + return matchingFile; + } + + return context.AdditionalFiles.FirstOrDefault(f => FileNameMatchesFontName(f, fontName)); + + static bool FontNamePropertyMatchesFontName( + GeneratorExecutionContext context, + AdditionalText fontFile, + string fontName) + { + // a "build_metadata" prefix is added by msbuild for CompilerVisibleItemMetadata + context.AnalyzerConfigOptions.GetOptions(fontFile).TryGetValue( + "build_metadata.AdditionalFiles.FontName", + out var fontNameProperty); + + if (fontNameProperty is null) + { + return false; + } + + return fontNameProperty.Equals(fontName, StringComparison.OrdinalIgnoreCase); + } + + static bool FileNameMatchesFontName(AdditionalText fontFile, string fontName) + { + return Path.GetFileName(fontFile.Path).Equals( + $"{fontName}.flf", + StringComparison.OrdinalIgnoreCase); + } + } } - private record TypeItems(List Items, HashSet SeenMemberNames); + private sealed record TypeItems(List Items, HashSet SeenMemberNames); - private record RenderItem(string MemberName, Location MemberNameLocation, string FontName, Location FontNameLocation, string SourceText); + private sealed record RenderItem(string MemberName, Location MemberNameLocation, string FontName, Location FontNameLocation, string SourceText); private sealed class Receiver : ISyntaxContextReceiver { diff --git a/Figgle.Generator/build/Figgle.Generator.props b/Figgle.Generator/build/Figgle.Generator.props new file mode 100644 index 0000000..ff0faf2 --- /dev/null +++ b/Figgle.Generator/build/Figgle.Generator.props @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Figgle.sln b/Figgle.sln index a3cb00b..96c36fa 100644 --- a/Figgle.sln +++ b/Figgle.sln @@ -294,6 +294,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Figgle.Generator", "Figgle. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Figgle.Generator.Tests", "Figgle.Generator.Tests\Figgle.Generator.Tests.csproj", "{8695E5C8-7027-409C-8B19-439731AD5335}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Figgle.Generator.AcceptanceTests", "Figgle.Generator.AcceptanceTests\Figgle.Generator.AcceptanceTests.csproj", "{E9177B5C-626B-44E6-87B4-2D712FB52DC9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -364,6 +366,18 @@ Global {8695E5C8-7027-409C-8B19-439731AD5335}.Release|x64.Build.0 = Release|Any CPU {8695E5C8-7027-409C-8B19-439731AD5335}.Release|x86.ActiveCfg = Release|Any CPU {8695E5C8-7027-409C-8B19-439731AD5335}.Release|x86.Build.0 = Release|Any CPU + {E9177B5C-626B-44E6-87B4-2D712FB52DC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E9177B5C-626B-44E6-87B4-2D712FB52DC9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E9177B5C-626B-44E6-87B4-2D712FB52DC9}.Debug|x64.ActiveCfg = Debug|Any CPU + {E9177B5C-626B-44E6-87B4-2D712FB52DC9}.Debug|x64.Build.0 = Debug|Any CPU + {E9177B5C-626B-44E6-87B4-2D712FB52DC9}.Debug|x86.ActiveCfg = Debug|Any CPU + {E9177B5C-626B-44E6-87B4-2D712FB52DC9}.Debug|x86.Build.0 = Debug|Any CPU + {E9177B5C-626B-44E6-87B4-2D712FB52DC9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E9177B5C-626B-44E6-87B4-2D712FB52DC9}.Release|Any CPU.Build.0 = Release|Any CPU + {E9177B5C-626B-44E6-87B4-2D712FB52DC9}.Release|x64.ActiveCfg = Release|Any CPU + {E9177B5C-626B-44E6-87B4-2D712FB52DC9}.Release|x64.Build.0 = Release|Any CPU + {E9177B5C-626B-44E6-87B4-2D712FB52DC9}.Release|x86.ActiveCfg = Release|Any CPU + {E9177B5C-626B-44E6-87B4-2D712FB52DC9}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/README.md b/README.md index 77b0143..0c06efa 100644 --- a/README.md +++ b/README.md @@ -151,10 +151,22 @@ If you want to use an external font, include the external font file as an additi ``` -Then specify the font name in the attribute: +Then specify the font's file name (excluding the extension) as the font name in the attribute: ```c# [GenerateFiggleText("HelloWorldString", "myfont", "Hello world")] ``` -Note the font name specified in the attribute is case-insensitive so `MyFont` works too. +Alternatively, you can specify a custom font name using the `FontName` item metadata: + +```xml + + + +``` + +```C# +[GenerateFiggleText("HelloWorldString", "MyCustomFontName", "Hello world")] +``` + +Note the font name specified in the `GenerateFiggleText` attribute is case-insensitive so `mycustomfontname` works too. diff --git a/appveyor.yml b/appveyor.yml index 971bb68..3b53b49 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,6 +14,8 @@ test: only: - Figgle.Tests.dll - Figgle.Generator.Tests.dll + - Figgle.Generator.AcceptanceTests.dll test_script: - dotnet test .\Figgle.Tests\Figgle.Tests.csproj --no-build - dotnet test .\Figgle.Generator.Tests\Figgle.Generator.Tests.csproj --no-build + - dotnet test .\Figgle.Generator.AcceptanceTests\Figgle.Generator.AcceptanceTests.csproj --no-build