diff --git a/README.md b/README.md index 3a170bc4b..1d23118da 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# RSCG - 261 Examples of Roslyn Source Code Generators / 16 created by Microsoft / +# RSCG - 262 Examples of Roslyn Source Code Generators / 16 created by Microsoft / -The RSCG_Examples repository is a comprehensive documentation system that automatically processes and showcases 261 Roslyn Source Code Generator (RSCG) examples. The system transforms individual RSCG projects into structured documentation with code examples and cross-referenced content with a searchable website and code example exports. +The RSCG_Examples repository is a comprehensive documentation system that automatically processes and showcases 262 Roslyn Source Code Generator (RSCG) examples. The system transforms individual RSCG projects into structured documentation with code examples and cross-referenced content with a searchable website and code example exports. This system serves as both a learning resource for .NET developers interested in source generators and an automated pipeline for maintaining up-to-date documentation about the RSCG ecosystem -## Latest Update : 2026-04-03 => 03 April 2026 +## Latest Update : 2026-04-04 => 04 April 2026 If you want to see examples with code, please click ***[List V2](https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG)*** @@ -24,8 +24,30 @@ If you want to be notified each time I add a new RSCG example , please click htt ## Content -Those are the 261 Roslyn Source Code Generators that I have tested you can see and download source code example. +Those are the 262 Roslyn Source Code Generators that I have tested you can see and download source code example. ( including 16 from Microsoft ) +### 262. [SvgIconGenerator](https://ignatandrei.github.io/RSCG_Examples/v2/docs/SvgIconGenerator) , in the [FilesToCode](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#filestocode) category + +Generated on : 2026-04-04 => 04 April 2026 + +
+ Expand + + + +Author: Matt Schneeberger + +SVG icon source generator + +Nuget: [https://www.nuget.org/packages/SvgIconGenerator/](https://www.nuget.org/packages/SvgIconGenerator/) + + +Link: [https://ignatandrei.github.io/RSCG_Examples/v2/docs/SvgIconGenerator](https://ignatandrei.github.io/RSCG_Examples/v2/docs/SvgIconGenerator) + +Source: [https://github.com/helluvamatt/SvgIconGenerator](https://github.com/helluvamatt/SvgIconGenerator) + +
+ ### 261. [NLog.Extensions.ThisClass](https://ignatandrei.github.io/RSCG_Examples/v2/docs/NLog.Extensions.ThisClass) , in the [EnhancementClass](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#enhancementclass) category Generated on : 2026-04-03 => 03 April 2026 diff --git a/later.md b/later.md index a001d5de3..eaf631906 100644 --- a/later.md +++ b/later.md @@ -1,6 +1,6 @@ # Just later -## Latest Update : 2026-04-03 => 03 April 2026 +## Latest Update : 2026-04-04 => 04 April 2026 diff --git a/v2/.tours/SvgIconGenerator.tour b/v2/.tours/SvgIconGenerator.tour new file mode 100644 index 000000000..583095333 --- /dev/null +++ b/v2/.tours/SvgIconGenerator.tour @@ -0,0 +1,48 @@ + +{ + "$schema": "https://aka.ms/codetour-schema", + "title": "SvgIconGenerator", + "steps": + [ + { + "file": "rscg_examples/SvgIconGenerator/src/DemoSvg/DemoSvg.csproj", + "description": "First, we add Nuget [SvgIconGenerator](https://www.nuget.org/packages/SvgIconGenerator/) in csproj ", + "pattern": "SvgIconGenerator" + } + + ,{ + "file": "rscg_examples/SvgIconGenerator/src/DemoSvg/Icons.cs", + "description": "File Icons.cs ", + "pattern": "this is the code" + } + + ,{ + "file": "rscg_examples/SvgIconGenerator/src/DemoSvg/Program.cs", + "description": "File Program.cs \r\n>> dotnet run --project rscg_examples/SvgIconGenerator/src/DemoSvg/DemoSvg.csproj ", + "pattern": "this is the code" + } + + + ,{ + "file": "rscg_examples/SvgIconGenerator/src/DemoSvg/obj/GX/SvgIconGenerator/SvgIconGenerator.IconGenerator/MyIcons.g.cs", + "description": "Generated File 3 from 3 : MyIcons.g.cs ", + "line": 1 + } + + ,{ + "file": "rscg_examples/SvgIconGenerator/src/DemoSvg/obj/GX/SvgIconGenerator/SvgIconGenerator.IconGenerator/IconDto.g.cs", + "description": "Generated File 2 from 3 : IconDto.g.cs ", + "line": 1 + } + + ,{ + "file": "rscg_examples/SvgIconGenerator/src/DemoSvg/obj/GX/SvgIconGenerator/SvgIconGenerator.IconGenerator/GenerateIconsAttribute.g.cs", + "description": "Generated File 1 from 3 : GenerateIconsAttribute.g.cs ", + "line": 1 + } + + ], + + "ref": "main" + +} \ No newline at end of file diff --git a/v2/Generator/all.csv b/v2/Generator/all.csv index 7bc80a70a..e6a073ec1 100644 --- a/v2/Generator/all.csv +++ b/v2/Generator/all.csv @@ -260,3 +260,4 @@ Nr,Key,Source,Category 259,TypedPaths, https://github.com/AlexChim1231/TypedPaths/,FilesToCode 260,AssemblyMetadata, https://github.com/BenjaminAbt/AssemblyMetadata,EnhancementProject 261,NLog.Extensions.ThisClass, https://github.com/trympet/ThisClass,EnhancementClass +262,SvgIconGenerator, https://github.com/helluvamatt/SvgIconGenerator,FilesToCode diff --git a/v2/RSCGExamplesData/GeneratorDataRec.json b/v2/RSCGExamplesData/GeneratorDataRec.json index 638e29f32..1bec4774e 100644 --- a/v2/RSCGExamplesData/GeneratorDataRec.json +++ b/v2/RSCGExamplesData/GeneratorDataRec.json @@ -1582,5 +1582,11 @@ "Category": 5, "dtStart": "2026-04-03T00:00:00", "show": true + }, + { + "ID":"SvgIconGenerator", + "Category": 8, + "dtStart": "2026-04-04T00:00:00", + "show": true } ] \ No newline at end of file diff --git a/v2/book/examples/SvgIconGenerator.html b/v2/book/examples/SvgIconGenerator.html new file mode 100644 index 000000000..93150ef19 --- /dev/null +++ b/v2/book/examples/SvgIconGenerator.html @@ -0,0 +1,69 @@ + +

RSCG nr 262 : SvgIconGenerator

+ +

Info

+Nuget : https://www.nuget.org/packages/SvgIconGenerator/ + +

You can find more details at : https://github.com/helluvamatt/SvgIconGenerator

+ +

Author :Matt Schneeberger

+ +

Source: https://github.com/helluvamatt/SvgIconGenerator

+ +

About

+ +Generating classes from SVG icons to be used in C# projects. + +

+ How to use +

+

+ Add reference to the SvgIconGenerator in the csproj +

+ + +

This was for me the starting code

+ +
+ I have coded the file Program.cs +
+ +
+ +
+ I have coded the file Icons.cs +
+ +
+

And here are the generated files

+ +
+ The file generated is GenerateIconsAttribute.g.cs +
+ + +
+ The file generated is IconDto.g.cs +
+ + +
+ The file generated is MyIcons.g.cs +
+ + +

+ You can download the code and this page as pdf from + + https://ignatandrei.github.io/RSCG_Examples/v2/docs/SvgIconGenerator + +

+ + +

+ You can see the whole list at + + https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG + +

+ diff --git a/v2/book/list.html b/v2/book/list.html index bfbf15c41..6b4724355 100644 --- a/v2/book/list.html +++ b/v2/book/list.html @@ -17,7 +17,7 @@

-This is the list of 261 RSCG with examples => +This is the list of 262 RSCG with examples =>

@@ -1070,6 +1070,10 @@

+ + + +
261 NLog.Extensions.ThisClass
262SvgIconGenerator
diff --git a/v2/book/pandocHTML.yaml b/v2/book/pandocHTML.yaml index d2288014b..86142a65b 100644 --- a/v2/book/pandocHTML.yaml +++ b/v2/book/pandocHTML.yaml @@ -275,6 +275,7 @@ input-files: - examples/TypedPaths.html - examples/AssemblyMetadata.html - examples/NLog.Extensions.ThisClass.html +- examples/SvgIconGenerator.html # or you may use input-file: with a single value # defaults: diff --git a/v2/rscg_examples/SvgIconGenerator/description.json b/v2/rscg_examples/SvgIconGenerator/description.json new file mode 100644 index 000000000..f07c41a91 --- /dev/null +++ b/v2/rscg_examples/SvgIconGenerator/description.json @@ -0,0 +1,22 @@ +{ + "generator":{ + "name":"SvgIconGenerator", + "nuget":[ + "https://www.nuget.org/packages/SvgIconGenerator/" + ], + "link":"https://github.com/helluvamatt/SvgIconGenerator", + "author":"Matt Schneeberger", + "source":"https://github.com/helluvamatt/SvgIconGenerator" + }, + "data":{ + "goodFor":["Generating classes from SVG icons to be used in C# projects."], + "csprojDemo":"DemoSvg.csproj", + "csFiles":["Program.cs","Icons.cs"], + "excludeDirectoryGenerated":[""], + "includeAdditionalFiles":[""] + }, + "links":{ + "blog":"", + "video":"" + } +} \ No newline at end of file diff --git a/v2/rscg_examples/SvgIconGenerator/nuget.txt b/v2/rscg_examples/SvgIconGenerator/nuget.txt new file mode 100644 index 000000000..b127df7be --- /dev/null +++ b/v2/rscg_examples/SvgIconGenerator/nuget.txt @@ -0,0 +1 @@ +SVG icon source generator \ No newline at end of file diff --git a/v2/rscg_examples/SvgIconGenerator/readme.txt b/v2/rscg_examples/SvgIconGenerator/readme.txt new file mode 100644 index 000000000..c0c9373bb --- /dev/null +++ b/v2/rscg_examples/SvgIconGenerator/readme.txt @@ -0,0 +1,262 @@ +# SVG Icon Generator + +A C# source generator that automatically creates strongly-typed icon properties from SVG files. + +## Installation + +Install the NuGet package in your project: + +```bash +dotnet add package SvgIconGenerator +``` + +## Usage + +### 1. Organize Your SVG Files + +Place your SVG icon files in a folder within your project (e.g., `Icons/`): + +``` +YourProject/ +├── Icons/ +│ ├── user-circle.svg +│ ├── home.svg +│ └── settings.svg +└── Program.cs +``` + +### 2. Add SVG Files as AdditionalFiles + +In your `.csproj` file, add the SVG files as `AdditionalFiles`: + +```xml + + + +``` + +**Important**: Adding files as `AdditionalFiles` ensures that changes to SVG files trigger regeneration during incremental compilation. + +### 3. Create an Icon Class + +Create a `static partial` class and decorate it with the `[GenerateIcons]` attribute: + +```csharp +[GenerateIcons] +internal static partial class MyIcons; +``` + +You can optionally specify a glob pattern to filter which SVG files to include: + +```csharp +// Include all SVG files from AdditionalFiles +[GenerateIcons] +internal static partial class AllIcons; + +// Filter by glob pattern +[GenerateIcons("Icons/*.svg")] +internal static partial class MyIcons; +``` + +### 4. Access Generated Icons + +The source generator will create properties for each SVG file. Property names are automatically converted from kebab-case to PascalCase: + +```csharp +// user-circle.svg becomes UserCircle +IconDto icon = MyIcons.UserCircle; + +Console.WriteLine($"Icon name: {icon.Name}"); +Console.WriteLine($"ViewBox: {icon.DefaultAttributes["viewBox"]}"); +Console.WriteLine($"SVG content: {icon.InnerContent}"); +``` + +### 5. Render Icons + +The `IconDto` contains everything needed to render the icon: + +```csharp +public static string RenderIcon(IconDto icon, Dictionary? customAttributes = null) +{ + // Merge default attributes with custom overrides + var attributes = new Dictionary(icon.DefaultAttributes); + if (customAttributes != null) + { + foreach (var kvp in customAttributes) + { + attributes[kvp.Key] = kvp.Value; + } + } + + // Build attribute string + var attrString = string.Join(" ", attributes.Select(kvp => $"{kvp.Key}=\"{kvp.Value}\"")); + + // Return complete SVG + return $"{icon.InnerContent}"; +} + +// Use it +string svg = RenderIcon(MyIcons.UserCircle, new Dictionary +{ + ["class"] = "icon", + ["width"] = "24", + ["height"] = "24" +}); +``` + +## Using with Popular Icon Libraries + +You can use this generator with popular icon libraries installed via NPM, such as Bootstrap Icons, Lucide, Heroicons, or Feather Icons. + +### Example: Lucide Icons + +1. Install Lucide icons via NPM: + +```bash +npm install lucide-static +``` + +2. Add the icons as `AdditionalFiles` in your `.csproj`: + +```xml + + + +``` + +3. Create the icon class with optional glob pattern filter: + +```csharp +[GenerateIcons("node_modules/lucide-static/icons/*.svg")] +internal static partial class LucideIcons; +``` + +4. Access any Lucide icon: + +```csharp +IconDto icon = LucideIcons.UserCircle; +IconDto icon2 = LucideIcons.ShoppingCart; +IconDto icon3 = LucideIcons.AlertTriangle; +``` + +### Example: Bootstrap Icons + +```bash +npm install bootstrap-icons +``` + +```xml + + + +``` + +```csharp +[GenerateIcons("node_modules/bootstrap-icons/icons/*.svg")] +internal static partial class BootstrapIcons; +``` + +### Example: Heroicons + +```bash +npm install heroicons +``` + +```xml + + + + +``` + +```csharp +// Outline style icons +[GenerateIcons("node_modules/heroicons/24/outline/*.svg")] +internal static partial class HeroiconsOutline; + +// Solid style icons +[GenerateIcons("node_modules/heroicons/24/solid/*.svg")] +internal static partial class HeroiconsSolid; +``` + +### Multiple Icon Sets + +You can create multiple icon classes in the same project to organize different icon sets: + +```xml + + + + + +``` + +```csharp +[GenerateIcons("node_modules/lucide-static/icons/*.svg")] +internal static partial class LucideIcons; + +[GenerateIcons("Icons/custom/*.svg")] +internal static partial class CustomIcons; + +[GenerateIcons("Icons/logos/*.svg")] +internal static partial class LogoIcons; +``` + +## How It Works + +1. The source generator reads SVG files from `AdditionalFiles` in your project +2. Files are optionally filtered by glob pattern (if specified in the attribute) +3. For each SVG file, it: + - Extracts the root element's attributes (excluding `xmlns` and `class`) + - Captures the inner SVG content + - Converts the filename to PascalCase for the property name +4. Generates a partial class with `IconDto` properties for each icon +5. **Incremental compilation**: Changes to SVG files automatically trigger regeneration + +## IconDto Structure + +The generated `IconDto` record contains: + +- **Name** (`string`): The original kebab-case filename without extension +- **DefaultAttributes** (`IReadOnlyDictionary`): SVG root attributes like `viewBox`, `fill`, `stroke`, etc. +- **InnerContent** (`string`): The inner HTML content (paths, circles, etc.) + +## Example SVG Input + +Given an SVG file `Icons/user-circle.svg`: + +```xml + + + + + +``` + +The generator creates: + +```csharp +/// +/// Icon: user-circle +/// +public static readonly IconDto UserCircle = new IconDto( + "user-circle", + new global::System.Collections.Generic.Dictionary { + { "width", "24" }, + { "height", "24" }, + { "viewBox", "0 0 24 24" }, + { "fill", "none" }, + { "stroke", "currentColor" }, + { "stroke-width", "2" }, + }, + ""); +``` + +## Requirements + +- .NET Standard 2.0 or higher +- C# 9.0 or higher (for record types) + +## License + +See the repository for license information. diff --git a/v2/rscg_examples/SvgIconGenerator/src/DemoSvg.slnx b/v2/rscg_examples/SvgIconGenerator/src/DemoSvg.slnx new file mode 100644 index 000000000..df1472f61 --- /dev/null +++ b/v2/rscg_examples/SvgIconGenerator/src/DemoSvg.slnx @@ -0,0 +1,3 @@ + + + diff --git a/v2/rscg_examples/SvgIconGenerator/src/DemoSvg/DemoSvg.csproj b/v2/rscg_examples/SvgIconGenerator/src/DemoSvg/DemoSvg.csproj new file mode 100644 index 000000000..930c8e0fb --- /dev/null +++ b/v2/rscg_examples/SvgIconGenerator/src/DemoSvg/DemoSvg.csproj @@ -0,0 +1,22 @@ + + + + Exe + net10.0 + enable + enable + + + + + + + + + + + + true + $(BaseIntermediateOutputPath)\GX + + diff --git a/v2/rscg_examples/SvgIconGenerator/src/DemoSvg/Icons.cs b/v2/rscg_examples/SvgIconGenerator/src/DemoSvg/Icons.cs new file mode 100644 index 000000000..d39d23d40 --- /dev/null +++ b/v2/rscg_examples/SvgIconGenerator/src/DemoSvg/Icons.cs @@ -0,0 +1,9 @@ +using System; +using System.Collections.Generic; +using System.Text; +using SvgIconGenerator; +namespace DemoSvg; + +[GenerateIcons()] +internal static partial class MyIcons; + diff --git a/v2/rscg_examples/SvgIconGenerator/src/DemoSvg/Icons/Circle.svg b/v2/rscg_examples/SvgIconGenerator/src/DemoSvg/Icons/Circle.svg new file mode 100644 index 000000000..892e02681 --- /dev/null +++ b/v2/rscg_examples/SvgIconGenerator/src/DemoSvg/Icons/Circle.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/v2/rscg_examples/SvgIconGenerator/src/DemoSvg/Icons/Rect.svg b/v2/rscg_examples/SvgIconGenerator/src/DemoSvg/Icons/Rect.svg new file mode 100644 index 000000000..7a3402cf5 --- /dev/null +++ b/v2/rscg_examples/SvgIconGenerator/src/DemoSvg/Icons/Rect.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/v2/rscg_examples/SvgIconGenerator/src/DemoSvg/Program.cs b/v2/rscg_examples/SvgIconGenerator/src/DemoSvg/Program.cs new file mode 100644 index 000000000..71c7c9749 --- /dev/null +++ b/v2/rscg_examples/SvgIconGenerator/src/DemoSvg/Program.cs @@ -0,0 +1,5 @@ +using DemoSvg; + +Console.WriteLine(MyIcons.Circle.Name); + +Console.WriteLine(MyIcons.Rect.InnerContent); diff --git a/v2/rscg_examples/SvgIconGenerator/video.json b/v2/rscg_examples/SvgIconGenerator/video.json new file mode 100644 index 000000000..a78ebc639 --- /dev/null +++ b/v2/rscg_examples/SvgIconGenerator/video.json @@ -0,0 +1,39 @@ +{ + "scriptName": "SvgIconGenerator", + "steps": +[ + {"typeStep":"exec","arg":"clipchamp.exe launch"}, + {"typeStep":"text","arg": "Welcome to Roslyn Examples"}, + {"typeStep":"text","arg":"If you want to see more examples , see List Of RSCG"}, + {"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG"}, + {"typeStep":"text","arg": "My name is Andrei Ignat and I am deeply fond of Roslyn Source Code Generator. "}, + +{"typeStep":"text","arg": "Today I will present SvgIconGenerator . Generating classes from SVG icons to be used in C# projects. ."}, +{"typeStep":"browser","arg":"https://www.nuget.org/packages/SvgIconGenerator/"}, +{"typeStep":"text","arg": "The whole example is here"}, +{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/SvgIconGenerator"}, +{"typeStep":"text","arg": "You can download the code from here"}, +{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/SvgIconGenerator#download-example-net--c-"}, +{"typeStep":"text","arg":"Here is the code downloaded "}, +{"typeStep":"exec","arg":"explorer.exe /select,D:\\gth\\RSCG_Examples\\v2\\Generator.sln"}, +{"typeStep":"text","arg": "So , let's start the project with Visual Studio Code "}, +{"typeStep":"stepvscode","arg": "-n D:\\gth\\RSCG_Examples\\v2"}, + +{"typeStep":"text","arg": "To use it ,you will put the Nuget SvgIconGenerator into the csproj "}, + +{"typeStep":"stepvscode","arg": "-r -g D:\\gth\\RSCG_Examples\\v2\\rscg_examples\\SvgIconGenerator\\src\\DemoSvg\\DemoSvg.csproj"}, + +{"typeStep":"text","arg": "And now I will show you an example of using SvgIconGenerator"}, + +{"typeStep":"hide","arg": "now execute the tour in VSCode"}, +{"typeStep":"tour", "arg": "src/.tours/"}, +{"typeStep":"text","arg":" And I will execute the project"}, +{"typeStep":"showproj", "arg":"DemoSvg.csproj"}, +{"typeStep":"text","arg":" This concludes the project"}, +{"typeStep":"waitseconds","arg":"30"}, +{"typeStep":"text","arg": "Remember, you can download the code from here"}, +{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/SvgIconGenerator#download-example-net--c-", +SpeakTest=" "}, +{"typeStep":"waitseconds","arg":"30"}, +] +} diff --git a/v2/rscg_examples_site/docs/Authors/Matt_Schneeberger.md b/v2/rscg_examples_site/docs/Authors/Matt_Schneeberger.md new file mode 100644 index 000000000..c3ac53f47 --- /dev/null +++ b/v2/rscg_examples_site/docs/Authors/Matt_Schneeberger.md @@ -0,0 +1,7 @@ +# Author : Matt Schneeberger + +Number RSCG: 1 + + + 1 [SvgIconGenerator](/docs/SvgIconGenerator) [![Nuget](https://img.shields.io/nuget/dt/SvgIconGenerator?label=SvgIconGenerator)](https://www.nuget.org/packages/SvgIconGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/helluvamatt/SvgIconGenerator?style=social) 2026-04-04 + diff --git a/v2/rscg_examples_site/docs/Categories/FilesToCode.md b/v2/rscg_examples_site/docs/Categories/FilesToCode.md index 8d104ca86..c2de06927 100644 --- a/v2/rscg_examples_site/docs/Categories/FilesToCode.md +++ b/v2/rscg_examples_site/docs/Categories/FilesToCode.md @@ -1,6 +1,6 @@

FilesToCode

-Number RSCG: 18 +Number RSCG: 19 1 [Chorn.EmbeddedResourceAccessGenerator](/docs/Chorn.EmbeddedResourceAccessGenerator) [![Nuget](https://img.shields.io/nuget/dt/Chorn.EmbeddedResourceAccessGenerator?label=Chorn.EmbeddedResourceAccessGenerator)](https://www.nuget.org/packages/Chorn.EmbeddedResourceAccessGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/ChristophHornung/EmbeddedResourceGenerator?style=social) 2024-01-21 @@ -30,11 +30,13 @@ Number RSCG: 18 14 [Strings.ResourceGenerator](/docs/Strings.ResourceGenerator) [![Nuget](https://img.shields.io/nuget/dt/Strings.ResourceGenerator?label=Strings.ResourceGenerator)](https://www.nuget.org/packages/Strings.ResourceGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/biggik/Strings.ResourceGenerator?style=social) 2025-07-06 - 15 [ThisAssembly_Resources](/docs/ThisAssembly_Resources) [![Nuget](https://img.shields.io/nuget/dt/ThisAssembly.Resources?label=ThisAssembly.Resources)](https://www.nuget.org/packages/ThisAssembly.Resources/) ![GitHub Repo stars](https://img.shields.io/github/stars/devlooped/ThisAssembly?style=social) 2023-09-16 + 15 [SvgIconGenerator](/docs/SvgIconGenerator) [![Nuget](https://img.shields.io/nuget/dt/SvgIconGenerator?label=SvgIconGenerator)](https://www.nuget.org/packages/SvgIconGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/helluvamatt/SvgIconGenerator?style=social) 2026-04-04 - 16 [ThisAssembly.Strings](/docs/ThisAssembly.Strings) [![Nuget](https://img.shields.io/nuget/dt/ThisAssembly.Strings?label=ThisAssembly.Strings)](https://www.nuget.org/packages/ThisAssembly.Strings/) ![GitHub Repo stars](https://img.shields.io/github/stars/devlooped/ThisAssembly?style=social) 2024-07-21 + 16 [ThisAssembly_Resources](/docs/ThisAssembly_Resources) [![Nuget](https://img.shields.io/nuget/dt/ThisAssembly.Resources?label=ThisAssembly.Resources)](https://www.nuget.org/packages/ThisAssembly.Resources/) ![GitHub Repo stars](https://img.shields.io/github/stars/devlooped/ThisAssembly?style=social) 2023-09-16 - 17 [TypedPaths](/docs/TypedPaths) [![Nuget](https://img.shields.io/nuget/dt/TypedPaths.Generator?label=TypedPaths.Generator)](https://www.nuget.org/packages/TypedPaths.Generator/) ![GitHub Repo stars](https://img.shields.io/github/stars/AlexChim1231/TypedPaths?style=social) 2026-04-01 + 17 [ThisAssembly.Strings](/docs/ThisAssembly.Strings) [![Nuget](https://img.shields.io/nuget/dt/ThisAssembly.Strings?label=ThisAssembly.Strings)](https://www.nuget.org/packages/ThisAssembly.Strings/) ![GitHub Repo stars](https://img.shields.io/github/stars/devlooped/ThisAssembly?style=social) 2024-07-21 - 18 [Weave](/docs/Weave) [![Nuget](https://img.shields.io/nuget/dt/Weave?label=Weave)](https://www.nuget.org/packages/Weave/) ![GitHub Repo stars](https://img.shields.io/github/stars/otac0n/Weave?style=social) 2024-01-27 + 18 [TypedPaths](/docs/TypedPaths) [![Nuget](https://img.shields.io/nuget/dt/TypedPaths.Generator?label=TypedPaths.Generator)](https://www.nuget.org/packages/TypedPaths.Generator/) ![GitHub Repo stars](https://img.shields.io/github/stars/AlexChim1231/TypedPaths?style=social) 2026-04-01 + + 19 [Weave](/docs/Weave) [![Nuget](https://img.shields.io/nuget/dt/Weave?label=Weave)](https://www.nuget.org/packages/Weave/) ![GitHub Repo stars](https://img.shields.io/github/stars/otac0n/Weave?style=social) 2024-01-27 \ No newline at end of file diff --git a/v2/rscg_examples_site/docs/Categories/_PrimitiveFilesToCode.mdx b/v2/rscg_examples_site/docs/Categories/_PrimitiveFilesToCode.mdx index 9090622be..7d64a4ef5 100644 --- a/v2/rscg_examples_site/docs/Categories/_PrimitiveFilesToCode.mdx +++ b/v2/rscg_examples_site/docs/Categories/_PrimitiveFilesToCode.mdx @@ -28,13 +28,15 @@ 14 [Strings.ResourceGenerator](/docs/Strings.ResourceGenerator) [![Nuget](https://img.shields.io/nuget/dt/Strings.ResourceGenerator?label=Strings.ResourceGenerator)](https://www.nuget.org/packages/Strings.ResourceGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/biggik/Strings.ResourceGenerator?style=social) 2025-07-06 - 15 [ThisAssembly_Resources](/docs/ThisAssembly_Resources) [![Nuget](https://img.shields.io/nuget/dt/ThisAssembly.Resources?label=ThisAssembly.Resources)](https://www.nuget.org/packages/ThisAssembly.Resources/) ![GitHub Repo stars](https://img.shields.io/github/stars/devlooped/ThisAssembly?style=social) 2023-09-16 + 15 [SvgIconGenerator](/docs/SvgIconGenerator) [![Nuget](https://img.shields.io/nuget/dt/SvgIconGenerator?label=SvgIconGenerator)](https://www.nuget.org/packages/SvgIconGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/helluvamatt/SvgIconGenerator?style=social) 2026-04-04 - 16 [ThisAssembly.Strings](/docs/ThisAssembly.Strings) [![Nuget](https://img.shields.io/nuget/dt/ThisAssembly.Strings?label=ThisAssembly.Strings)](https://www.nuget.org/packages/ThisAssembly.Strings/) ![GitHub Repo stars](https://img.shields.io/github/stars/devlooped/ThisAssembly?style=social) 2024-07-21 + 16 [ThisAssembly_Resources](/docs/ThisAssembly_Resources) [![Nuget](https://img.shields.io/nuget/dt/ThisAssembly.Resources?label=ThisAssembly.Resources)](https://www.nuget.org/packages/ThisAssembly.Resources/) ![GitHub Repo stars](https://img.shields.io/github/stars/devlooped/ThisAssembly?style=social) 2023-09-16 - 17 [TypedPaths](/docs/TypedPaths) [![Nuget](https://img.shields.io/nuget/dt/TypedPaths.Generator?label=TypedPaths.Generator)](https://www.nuget.org/packages/TypedPaths.Generator/) ![GitHub Repo stars](https://img.shields.io/github/stars/AlexChim1231/TypedPaths?style=social) 2026-04-01 + 17 [ThisAssembly.Strings](/docs/ThisAssembly.Strings) [![Nuget](https://img.shields.io/nuget/dt/ThisAssembly.Strings?label=ThisAssembly.Strings)](https://www.nuget.org/packages/ThisAssembly.Strings/) ![GitHub Repo stars](https://img.shields.io/github/stars/devlooped/ThisAssembly?style=social) 2024-07-21 - 18 [Weave](/docs/Weave) [![Nuget](https://img.shields.io/nuget/dt/Weave?label=Weave)](https://www.nuget.org/packages/Weave/) ![GitHub Repo stars](https://img.shields.io/github/stars/otac0n/Weave?style=social) 2024-01-27 + 18 [TypedPaths](/docs/TypedPaths) [![Nuget](https://img.shields.io/nuget/dt/TypedPaths.Generator?label=TypedPaths.Generator)](https://www.nuget.org/packages/TypedPaths.Generator/) ![GitHub Repo stars](https://img.shields.io/github/stars/AlexChim1231/TypedPaths?style=social) 2026-04-01 + + 19 [Weave](/docs/Weave) [![Nuget](https://img.shields.io/nuget/dt/Weave?label=Weave)](https://www.nuget.org/packages/Weave/) ![GitHub Repo stars](https://img.shields.io/github/stars/otac0n/Weave?style=social) 2024-01-27 ### See category diff --git a/v2/rscg_examples_site/docs/RSCG-Examples/SvgIconGenerator.md b/v2/rscg_examples_site/docs/RSCG-Examples/SvgIconGenerator.md new file mode 100644 index 000000000..6b1e4d698 --- /dev/null +++ b/v2/rscg_examples_site/docs/RSCG-Examples/SvgIconGenerator.md @@ -0,0 +1,535 @@ +--- +sidebar_position: 2620 +title: 262 - SvgIconGenerator +description: Generating classes from SVG icons to be used in C# projects. +slug: /SvgIconGenerator +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import TOCInline from '@theme/TOCInline'; +import SameCategory from '../Categories/_PrimitiveFilesToCode.mdx'; + +# SvgIconGenerator by Matt Schneeberger + + + + +## NuGet / site data +[![Nuget](https://img.shields.io/nuget/dt/SvgIconGenerator?label=SvgIconGenerator)](https://www.nuget.org/packages/SvgIconGenerator/) +[![GitHub last commit](https://img.shields.io/github/last-commit/helluvamatt/SvgIconGenerator?label=updated)](https://github.com/helluvamatt/SvgIconGenerator) +![GitHub Repo stars](https://img.shields.io/github/stars/helluvamatt/SvgIconGenerator?style=social) + +## Details + +### Info +:::info + +Name: **SvgIconGenerator** + +SVG icon source generator + +Author: Matt Schneeberger + +NuGet: +*https://www.nuget.org/packages/SvgIconGenerator/* + + +You can find more details at https://github.com/helluvamatt/SvgIconGenerator + +Source: https://github.com/helluvamatt/SvgIconGenerator + +::: + +### Author +:::note +Matt Schneeberger +![Alt text](https://github.com/helluvamatt.png) +::: + +## Original Readme +:::note + +### SVG Icon Generator + +A C# source generator that automatically creates strongly-typed icon properties from SVG files. + +###### Installation + +Install the NuGet package in your project: + +```bash +dotnet add package SvgIconGenerator +``` + +###### Usage + +######### 1. Organize Your SVG Files + +Place your SVG icon files in a folder within your project (e.g., `Icons/`): + +``` +YourProject/ +├── Icons/ +│ ├── user-circle.svg +│ ├── home.svg +│ └── settings.svg +└── Program.cs +``` + +######### 2. Add SVG Files as AdditionalFiles + +In your `.csproj` file, add the SVG files as `AdditionalFiles`: + +```xml + + + +``` + +**Important**: Adding files as `AdditionalFiles` ensures that changes to SVG files trigger regeneration during incremental compilation. + +######### 3. Create an Icon Class + +Create a `static partial` class and decorate it with the `[GenerateIcons]` attribute: + +```csharp +[GenerateIcons] +internal static partial class MyIcons; +``` + +You can optionally specify a glob pattern to filter which SVG files to include: + +```csharp +// Include all SVG files from AdditionalFiles +[GenerateIcons] +internal static partial class AllIcons; + +// Filter by glob pattern +[GenerateIcons("Icons/*.svg")] +internal static partial class MyIcons; +``` + +######### 4. Access Generated Icons + +The source generator will create properties for each SVG file. Property names are automatically converted from kebab-case to PascalCase: + +```csharp +// user-circle.svg becomes UserCircle +IconDto icon = MyIcons.UserCircle; + +Console.WriteLine($"Icon name: {icon.Name}"); +Console.WriteLine($"ViewBox: {icon.DefaultAttributes["viewBox"]}"); +Console.WriteLine($"SVG content: {icon.InnerContent}"); +``` + +######### 5. Render Icons + +The `IconDto` contains everything needed to render the icon: + +```csharp +public static string RenderIcon(IconDto icon, Dictionary? customAttributes = null) +{ + // Merge default attributes with custom overrides + var attributes = new Dictionary(icon.DefaultAttributes); + if (customAttributes != null) + { + foreach (var kvp in customAttributes) + { + attributes[kvp.Key] = kvp.Value; + } + } + + // Build attribute string + var attrString = string.Join(" ", attributes.Select(kvp => $"{kvp.Key}=\"{kvp.Value}\"")); + + // Return complete SVG + return $"{icon.InnerContent}"; +} + +// Use it +string svg = RenderIcon(MyIcons.UserCircle, new Dictionary +{ + ["class"] = "icon", + ["width"] = "24", + ["height"] = "24" +}); +``` + +###### Using with Popular Icon Libraries + +You can use this generator with popular icon libraries installed via NPM, such as Bootstrap Icons, Lucide, Heroicons, or Feather Icons. + +######### Example: Lucide Icons + +1. Install Lucide icons via NPM: + +```bash +npm install lucide-static +``` + +2. Add the icons as `AdditionalFiles` in your `.csproj`: + +```xml + + + +``` + +3. Create the icon class with optional glob pattern filter: + +```csharp +[GenerateIcons("node_modules/lucide-static/icons/*.svg")] +internal static partial class LucideIcons; +``` + +4. Access any Lucide icon: + +```csharp +IconDto icon = LucideIcons.UserCircle; +IconDto icon2 = LucideIcons.ShoppingCart; +IconDto icon3 = LucideIcons.AlertTriangle; +``` + +######### Example: Bootstrap Icons + +```bash +npm install bootstrap-icons +``` + +```xml + + + +``` + +```csharp +[GenerateIcons("node_modules/bootstrap-icons/icons/*.svg")] +internal static partial class BootstrapIcons; +``` + +######### Example: Heroicons + +```bash +npm install heroicons +``` + +```xml + + + + +``` + +```csharp +// Outline style icons +[GenerateIcons("node_modules/heroicons/24/outline/*.svg")] +internal static partial class HeroiconsOutline; + +// Solid style icons +[GenerateIcons("node_modules/heroicons/24/solid/*.svg")] +internal static partial class HeroiconsSolid; +``` + +######### Multiple Icon Sets + +You can create multiple icon classes in the same project to organize different icon sets: + +```xml + + + + + +``` + +```csharp +[GenerateIcons("node_modules/lucide-static/icons/*.svg")] +internal static partial class LucideIcons; + +[GenerateIcons("Icons/custom/*.svg")] +internal static partial class CustomIcons; + +[GenerateIcons("Icons/logos/*.svg")] +internal static partial class LogoIcons; +``` + +###### How It Works + +1. The source generator reads SVG files from `AdditionalFiles` in your project +2. Files are optionally filtered by glob pattern (if specified in the attribute) +3. For each SVG file, it: + - Extracts the root element's attributes (excluding `xmlns` and `class`) + - Captures the inner SVG content + - Converts the filename to PascalCase for the property name +4. Generates a partial class with `IconDto` properties for each icon +5. **Incremental compilation**: Changes to SVG files automatically trigger regeneration + +###### IconDto Structure + +The generated `IconDto` record contains: + +- **Name** (`string`): The original kebab-case filename without extension +- **DefaultAttributes** (`IReadOnlyDictionary`): SVG root attributes like `viewBox`, `fill`, `stroke`, etc. +- **InnerContent** (`string`): The inner HTML content (paths, circles, etc.) + +###### Example SVG Input + +Given an SVG file `Icons/user-circle.svg`: + +```xml + + + + + +``` + +The generator creates: + +```csharp +/// +/// Icon: user-circle +/// +public static readonly IconDto UserCircle = new IconDto( + "user-circle", + new global::System.Collections.Generic.Dictionary { + \{ "width", "24" }, + \{ "height", "24" }, + \{ "viewBox", "0 0 24 24" }, + \{ "fill", "none" }, + \{ "stroke", "currentColor" }, + \{ "stroke-width", "2" }, + }, + ""); +``` + +###### Requirements + +- .NET Standard 2.0 or higher +- C# 9.0 or higher (for record types) + +###### License + +See the repository for license information. + + +::: + +### About +:::note + +Generating classes from SVG icons to be used in C# projects. + + +::: + +## How to use + +### Example (source csproj, source files) + + + + + +This is the CSharp Project that references **SvgIconGenerator** +```xml showLineNumbers {11} + + + + Exe + net10.0 + enable + enable + + + + + + + + + + + + true + $(BaseIntermediateOutputPath)\GX + + + +``` + + + + + + This is the use of **SvgIconGenerator** in *Program.cs* + +```csharp showLineNumbers +using DemoSvg; + +Console.WriteLine(MyIcons.Circle.Name); + +Console.WriteLine(MyIcons.Rect.InnerContent); + +``` + + + + + This is the use of **SvgIconGenerator** in *Icons.cs* + +```csharp showLineNumbers +using System; +using System.Collections.Generic; +using System.Text; +using SvgIconGenerator; +namespace DemoSvg; + +[GenerateIcons()] +internal static partial class MyIcons; + + +``` + + + + +### Generated Files + +Those are taken from $(BaseIntermediateOutputPath)\GX + + + + +```csharp showLineNumbers +namespace SvgIconGenerator +{ + /// + /// Marks a static partial class for icon generation. + /// The source generator will scan AdditionalFiles for SVG files matching the specified glob pattern + /// and generate static readonly IconDto properties for each icon found. + /// + /// + /// SVG files must be added to the project as AdditionalFiles in the .csproj file: + /// + /// <ItemGroup> + /// <AdditionalFiles Include="icons/**/*.svg" /> + /// </ItemGroup> + /// + /// + [global::System.AttributeUsage(global::System.AttributeTargets.Class, Inherited = false, AllowMultiple = false)] + internal sealed class GenerateIconsAttribute : global::System.Attribute + { + /// + /// Initializes a new instance of the class. + /// + public GenerateIconsAttribute() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// Optional glob pattern to filter SVG files from AdditionalFiles. + /// If not specified, all SVG files in AdditionalFiles will be included. + /// Supports * (wildcard) and ** (recursive) patterns. + /// Example: "node_modules/lucide-static/icons/*.svg" + /// + public GenerateIconsAttribute(string globPattern) + { + } + } +} + +``` + + + + +```csharp showLineNumbers +namespace SvgIconGenerator +{ + /// + /// Represents an icon with its SVG metadata and content. + /// This type is generated by the IconGenerator source generator. + /// + /// The kebab-case name of the icon (e.g., "circle-user-round"). + /// The default attributes from the SVG root element (excluding xmlns). Common attributes include: width, height, viewBox, fill, stroke, stroke-width, stroke-linecap, stroke-linejoin. + /// The inner HTML content of the SVG element (paths, circles, lines, etc.). + public sealed record IconDto(string Name, global::System.Collections.Generic.IReadOnlyDictionary DefaultAttributes, string InnerContent); +} + +``` + + + + +```csharp showLineNumbers +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace DemoSvg +{ + partial class MyIcons + { + /// + /// Icon: Circle + /// + public static readonly global::SvgIconGenerator.IconDto Circle = new global::SvgIconGenerator.IconDto( + "Circle", + new global::System.Collections.Generic.Dictionary { + \{ "height", "100" }, + \{ "width", "100" }, + }, + ""); + + /// + /// Icon: Rect + /// + public static readonly global::SvgIconGenerator.IconDto Rect = new global::SvgIconGenerator.IconDto( + "Rect", + new global::System.Collections.Generic.Dictionary { + \{ "width", "300" }, + \{ "height", "130" }, + }, + ""); + + } +} + +``` + + + + +## Useful + +### Download Example (.NET C#) + +:::tip + +[Download Example project SvgIconGenerator ](/sources/SvgIconGenerator.zip) + +::: + + +### Share SvgIconGenerator + + + +https://ignatandrei.github.io/RSCG_Examples/v2/docs/SvgIconGenerator + + + diff --git a/v2/rscg_examples_site/docs/RSCG-Examples/index.md b/v2/rscg_examples_site/docs/RSCG-Examples/index.md index 051075d11..5378a3dfc 100644 --- a/v2/rscg_examples_site/docs/RSCG-Examples/index.md +++ b/v2/rscg_examples_site/docs/RSCG-Examples/index.md @@ -1,7 +1,7 @@ --- sidebar_position: 30 -title: 261 RSCG list by category -description: 261 RSCG list by category +title: 262 RSCG list by category +description: 262 RSCG list by category slug: /rscg-examples --- @@ -889,7 +889,7 @@ import DocCardList from '@theme/DocCardList'; ## FilesToCode
- Expand FilesToCode =>examples:18 + Expand FilesToCode =>examples:19 @@ -980,6 +980,11 @@ import DocCardList from '@theme/DocCardList'; [TypedPaths](/docs/TypedPaths) + + + +[SvgIconGenerator](/docs/SvgIconGenerator) +
@@ -1964,6 +1969,8 @@ flowchart LR; FilesToCode--> TypedPaths((TypedPaths)) + FilesToCode--> SvgIconGenerator((SvgIconGenerator)) + FunctionalProgramming--> dunet((dunet)) FunctionalProgramming--> PartiallyApplied((PartiallyApplied)) diff --git a/v2/rscg_examples_site/docs/about.md b/v2/rscg_examples_site/docs/about.md index 72578e2ab..293579178 100644 --- a/v2/rscg_examples_site/docs/about.md +++ b/v2/rscg_examples_site/docs/about.md @@ -6,7 +6,7 @@ title: About ## Content You will find here code examples -of 261 Roslyn Source Code Generator (RSCG) +of 262 Roslyn Source Code Generator (RSCG) that can be useful for you. That means, you will write more elegant and concise code - even if the generators code is not always nice to look. ## Are those examples ready for production? diff --git a/v2/rscg_examples_site/docs/indexRSCG.md b/v2/rscg_examples_site/docs/indexRSCG.md index 90f67eddc..b5edfdc63 100644 --- a/v2/rscg_examples_site/docs/indexRSCG.md +++ b/v2/rscg_examples_site/docs/indexRSCG.md @@ -7,9 +7,9 @@ slug: /List-of-RSCG import useBaseUrl from '@docusaurus/useBaseUrl'; -## 261 RSCG with examples in descending chronological order +## 262 RSCG with examples in descending chronological order -This is the list of 261 ( 16 from Microsoft) RSCG with examples +This is the list of 262 ( 16 from Microsoft) RSCG with examples [See by category](/docs/rscg-examples) [See as json](/exports/RSCG.json) [See as Excel](/exports/RSCG.xlsx) @@ -20,6 +20,7 @@ This is the list of 261 ( 16 from Microsoft) RSCG with examples | No | Name | Date | Category | | --------- | ----- | ---- | -------- | +|262| [SvgIconGenerator by Matt Schneeberger ](/docs/SvgIconGenerator)|2026-04-04 => 04 April 2026 | [FilesToCode](/docs/Categories/FilesToCode) | |261| [NLog.Extensions.ThisClass by Trym Pet ](/docs/NLog.Extensions.ThisClass)|2026-04-03 => 03 April 2026 | [EnhancementClass](/docs/Categories/EnhancementClass) | |260| [AssemblyMetadata by Benjamin Abt ](/docs/AssemblyMetadata)|2026-04-02 => 02 April 2026 | [EnhancementProject](/docs/Categories/EnhancementProject) | |259| [TypedPaths by Alex Chim ](/docs/TypedPaths)|2026-04-01 => 01 April 2026 | [FilesToCode](/docs/Categories/FilesToCode) | diff --git a/v2/rscg_examples_site/src/components/HomepageFeatures/index.js b/v2/rscg_examples_site/src/components/HomepageFeatures/index.js index dedc9f52a..eb1550485 100644 --- a/v2/rscg_examples_site/src/components/HomepageFeatures/index.js +++ b/v2/rscg_examples_site/src/components/HomepageFeatures/index.js @@ -4,7 +4,7 @@ import styles from './styles.module.css'; const FeatureList = [ { -title: '261 Examples (16 from MSFT)', +title: '262 Examples (16 from MSFT)', Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, description: ( <> diff --git a/v2/rscg_examples_site/static/exports/RSCG.json b/v2/rscg_examples_site/static/exports/RSCG.json index 02d691647..3a92941ac 100644 --- a/v2/rscg_examples_site/static/exports/RSCG.json +++ b/v2/rscg_examples_site/static/exports/RSCG.json @@ -2089,6 +2089,14 @@ "Source": "https://github.com/trympet/ThisClass", "Category": "EnhancementClass", "AddedOn": "2026-04-03T00:00:00" + }, + { + "Name": "SvgIconGenerator", + "Link": "https://ignatandrei.github.io/RSCG_Examples/v2/docs/SvgIconGenerator", + "NuGet": "https://www.nuget.org/packages/SvgIconGenerator/", + "Source": "https://github.com/helluvamatt/SvgIconGenerator", + "Category": "FilesToCode", + "AddedOn": "2026-04-04T00:00:00" } ] } \ No newline at end of file diff --git a/v2/rscg_examples_site/static/exports/RSCG.xlsx b/v2/rscg_examples_site/static/exports/RSCG.xlsx index ed06ba81c..2fb3ee4ed 100644 Binary files a/v2/rscg_examples_site/static/exports/RSCG.xlsx and b/v2/rscg_examples_site/static/exports/RSCG.xlsx differ diff --git a/v2/rscg_examples_site/static/sources/SvgIconGenerator.zip b/v2/rscg_examples_site/static/sources/SvgIconGenerator.zip new file mode 100644 index 000000000..d4889a6b7 Binary files /dev/null and b/v2/rscg_examples_site/static/sources/SvgIconGenerator.zip differ