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