From 341d39e53d4114badf51044fa6972796b9d3ca48 Mon Sep 17 00:00:00 2001 From: Scott W Harden Date: Fri, 11 Nov 2022 00:23:23 -0500 Subject: [PATCH] SP5 Cookbook: recipe source code reader --- .../ScottPlot5 Cookbook/Cookbook.cs | 17 ++-- .../HtmlPages/HtmlFrontPage.cs | 2 +- .../ScottPlot5 Cookbook/RecipeSource.cs | 15 +++ .../ScottPlot Cookbook.csproj | 1 - .../ScottPlot5 Cookbook/SourceReading.cs | 93 +++++++++++++++++++ src/ScottPlot5/ScottPlot5/ScottPlot.csproj | 2 +- 6 files changed, 119 insertions(+), 11 deletions(-) create mode 100644 src/ScottPlot5/ScottPlot5 Cookbook/RecipeSource.cs create mode 100644 src/ScottPlot5/ScottPlot5 Cookbook/SourceReading.cs diff --git a/src/ScottPlot5/ScottPlot5 Cookbook/Cookbook.cs b/src/ScottPlot5/ScottPlot5 Cookbook/Cookbook.cs index 1219ff6b61..0c17ca2673 100644 --- a/src/ScottPlot5/ScottPlot5 Cookbook/Cookbook.cs +++ b/src/ScottPlot5/ScottPlot5 Cookbook/Cookbook.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using NUnit.Framework.Internal.Execution; +using System.Reflection; namespace ScottPlotCookbook; @@ -8,19 +9,19 @@ namespace ScottPlotCookbook; /// public static class Cookbook { - public static readonly string OutputFolder = GetCookbookFolder(); + public static readonly string OutputFolder = Path.Combine(GetRepoFolder(), "dev/www/cookbook/5.0"); - private static string GetCookbookFolder() - { - string defaultFolder = Path.GetFullPath(TestContext.CurrentContext.TestDirectory); - string cookbookOutputSubFolder = "dev/www/cookbook/5.0"; + public static readonly string RecipeSourceFolder = Path.Combine(GetRepoFolder(), "src/ScottPlot5/ScottPlot5 Cookbook/Recipes"); + private static string GetRepoFolder() + { + string defaultFolder = Path.GetFullPath(TestContext.CurrentContext.TestDirectory); ; string? repoFolder = defaultFolder; while (repoFolder is not null) { if (File.Exists(Path.Combine(repoFolder, "LICENSE"))) { - return Path.Combine(repoFolder, cookbookOutputSubFolder); + return repoFolder; } else { @@ -28,7 +29,7 @@ private static string GetCookbookFolder() } } - return Path.Combine(defaultFolder, cookbookOutputSubFolder); + throw new InvalidOperationException($"repository folder not found in any folder above {defaultFolder}"); } internal static List GetChapters() => Enum.GetValues().ToList(); diff --git a/src/ScottPlot5/ScottPlot5 Cookbook/HtmlPages/HtmlFrontPage.cs b/src/ScottPlot5/ScottPlot5 Cookbook/HtmlPages/HtmlFrontPage.cs index 61a385a9c2..2005dcd66d 100644 --- a/src/ScottPlot5/ScottPlot5 Cookbook/HtmlPages/HtmlFrontPage.cs +++ b/src/ScottPlot5/ScottPlot5 Cookbook/HtmlPages/HtmlFrontPage.cs @@ -23,7 +23,7 @@ public void Generate() { if (!chapter.Pages.Any()) continue; - SB.AppendLine($"

{chapter.ToString()}

"); + SB.AppendLine($"

{chapter.Name}

"); chapter.Pages.ForEach(x => AddPage(x)); } diff --git a/src/ScottPlot5/ScottPlot5 Cookbook/RecipeSource.cs b/src/ScottPlot5/ScottPlot5 Cookbook/RecipeSource.cs new file mode 100644 index 0000000000..044ae2b6af --- /dev/null +++ b/src/ScottPlot5/ScottPlot5 Cookbook/RecipeSource.cs @@ -0,0 +1,15 @@ +namespace ScottPlotCookbook; + +internal struct RecipeSource +{ + public string PageName { get; set; } + public string RecipeName { get; set; } + public string SourceCode { get; set; } + + public RecipeSource(string page, string recipe, string source) + { + PageName = page; + RecipeName = recipe; + SourceCode = source; + } +} diff --git a/src/ScottPlot5/ScottPlot5 Cookbook/ScottPlot Cookbook.csproj b/src/ScottPlot5/ScottPlot5 Cookbook/ScottPlot Cookbook.csproj index 7c2f7b9216..11dfd91f77 100644 --- a/src/ScottPlot5/ScottPlot5 Cookbook/ScottPlot Cookbook.csproj +++ b/src/ScottPlot5/ScottPlot5 Cookbook/ScottPlot Cookbook.csproj @@ -5,7 +5,6 @@ enable enable ScottPlotCookbook - true false diff --git a/src/ScottPlot5/ScottPlot5 Cookbook/SourceReading.cs b/src/ScottPlot5/ScottPlot5 Cookbook/SourceReading.cs new file mode 100644 index 0000000000..9ca66a5606 --- /dev/null +++ b/src/ScottPlot5/ScottPlot5 Cookbook/SourceReading.cs @@ -0,0 +1,93 @@ +using FluentAssertions; +using System.Text; + +namespace ScottPlotCookbook; + +internal static class SourceReading +{ + public static List GetRecipeSourceFilePaths() + { + List paths = new(); + + if (!Directory.Exists(Cookbook.RecipeSourceFolder)) + throw new DirectoryNotFoundException(Cookbook.RecipeSourceFolder); + + paths.AddRange(Directory.GetFiles(Cookbook.RecipeSourceFolder, "*.cs")); + + foreach (string subFolder in Directory.GetDirectories(Cookbook.RecipeSourceFolder)) + { + + paths.AddRange(Directory.GetFiles(subFolder, "*.cs")); + } + + if (!paths.Any()) + throw new InvalidOperationException("no source files found"); + + return paths; + } + + public static List GetRecipeSources() + { + List sources = new(); + + string recipeStartSignal = " {"; + string recipeOverSignal = " }"; + + foreach (string path in GetRecipeSourceFilePaths()) + { + string[] rawLines = File.ReadAllLines(path); + string pageNameSafe = string.Empty; + string recipeNameSafe = string.Empty; + StringBuilder sourceBeingExtended = new(); + bool InRecipe = false; + + foreach (string line in rawLines) + { + if (line.StartsWith(" PageName = ")) + { + pageNameSafe = UrlTools.UrlSafe(line.Split('"')[1]); + continue; + } + + if (line.StartsWith(" public override string Name =")) + { + recipeNameSafe = UrlTools.UrlSafe(line.Split('"')[1]); + continue; + } + + if (!InRecipe && line.StartsWith(recipeStartSignal)) + { + InRecipe = true; + continue; + } + + if (InRecipe && line.StartsWith(recipeOverSignal)) + { + string source = string.Join(Environment.NewLine, sourceBeingExtended); + sources.Add(new RecipeSource(pageNameSafe, recipeNameSafe, source)); + InRecipe = false; + sourceBeingExtended.Clear(); + continue; + } + + bool lineIsWhitespace = line.Trim().Length == 0; + if (InRecipe) + sourceBeingExtended.AppendLine(lineIsWhitespace ? "" : line.Substring(8)); + } + } + + return sources; + } + + [Test] + public static void Test_Recipe_Sources_Found() + { + List sources = GetRecipeSources(); + + sources.Should().NotBeEmpty(); + sources.Should().HaveCount(Cookbook.GetRecipes().Count); + + foreach (RecipeSource source in sources) + TestContext.WriteLine($"{source.PageName}/{source.RecipeName} ({source.SourceCode.Length} characters)"); + } +} diff --git a/src/ScottPlot5/ScottPlot5/ScottPlot.csproj b/src/ScottPlot5/ScottPlot5/ScottPlot.csproj index c2e6f0c2a9..b9e18165d9 100644 --- a/src/ScottPlot5/ScottPlot5/ScottPlot.csproj +++ b/src/ScottPlot5/ScottPlot5/ScottPlot.csproj @@ -5,7 +5,7 @@ disable enable latest - 5.1.0-beta + 5.0.0-beta false