예제 #1
0
파일: Chef.cs 프로젝트: petedavis/ScottPlot
        /// <summary>
        /// Use a combination of file reading and reflection to get fields and source code for all recipes
        /// </summary>
        public List <(string id, string title, string description, string source)> GetRecipeSources(string sourcePath)
        {
            sourcePath = Path.GetFullPath(sourcePath);
            if (!File.Exists(Path.Combine(sourcePath, "IRecipe.cs")))
            {
                throw new ArgumentException("IRecipe.cs can not be found in the given source colder");
            }

            var sources = new List <(string id, string title, string description, string source)>();

            string[] projectCsFiles = Directory.GetFiles(sourcePath, "*.cs", SearchOption.AllDirectories);
            foreach (string csFilePath in projectCsFiles)
            {
                string sourceCode = File.ReadAllText(csFilePath);

                // ensure the source code is not from this file
                if (Path.GetFileName(csFilePath) == "Chef.cs")
                {
                    continue;
                }

                // ensure the start of the recipe is in the file
                string recipeStart = ": IRecipe";
                if (!sourceCode.Contains(recipeStart))
                {
                    continue;
                }

                // isolate individual recipes from files with multiple recipes
                string[] sourceCodeByClass = sourceCode.Split(
                    separator: new string[] { recipeStart },
                    options: StringSplitOptions.RemoveEmptyEntries)
                                             .Skip(1)
                                             .ToArray();

                foreach (string singleClassSourceCode in sourceCodeByClass)
                {
                    // ensure functions are at the correct indentation level
                    int    executionMethodCount = Regex.Matches(singleClassSourceCode, ExecutionMethod).Count;
                    string indentedMethod       = "\n        " + ExecutionMethod;
                    int    indentedMethodCount  = Regex.Matches(singleClassSourceCode, indentedMethod).Count;
                    if (executionMethodCount != indentedMethodCount)
                    {
                        throw new InvalidOperationException($"recipe structure error in: {csFilePath}");
                    }

                    // read the file's source code for primary recipe components
                    string  id     = GetRecipeID(singleClassSourceCode);
                    IRecipe recipe = Locate.GetRecipe(id);
                    string  source = $"var plt = new ScottPlot.Plot({Width}, {Height});\n\n" +
                                     GetRecipeSource(singleClassSourceCode, csFilePath) + "\n\n" +
                                     $"plt.SaveFig(\"{id}{Ext}\");";

                    sources.Add((recipe.ID, recipe.Title, recipe.Description, source));
                }
            }

            return(sources);
        }
예제 #2
0
        /// <summary>
        /// Use a combination of file reading and reflection to get fields and source code for all recipes
        /// </summary>
        public static RecipeSource[] GetRecipeSources(string sourcePath, int width, int height)
        {
            sourcePath = Path.GetFullPath(sourcePath);
            if (!File.Exists(Path.Combine(sourcePath, "IRecipe.cs")))
            {
                throw new ArgumentException($"IRecipe.cs not be found in: {sourcePath}");
            }

            List <RecipeSource> sources = new();

            string[] projectCsFiles = Directory.GetFiles(sourcePath, "*.cs", SearchOption.AllDirectories);
            foreach (string csFilePath in projectCsFiles)
            {
                string sourceCode = File.ReadAllText(csFilePath);

                // ensure the source code is not from this file
                if (Path.GetFileName(csFilePath) == "Chef.cs")
                {
                    continue;
                }

                // ensure the start of the recipe is in the file
                string recipeStart = ": IRecipe";
                if (!sourceCode.Contains(recipeStart))
                {
                    continue;
                }

                // isolate individual recipes from files with multiple recipes
                string[] sourceCodeByClass = sourceCode.Split(
                    separator: new string[] { recipeStart },
                    options: StringSplitOptions.RemoveEmptyEntries)
                                             .Skip(1)
                                             .ToArray();

                foreach (string singleClassSourceCode in sourceCodeByClass)
                {
                    // ensure functions are at the correct indentation level
                    int    executionMethodCount = Regex.Matches(singleClassSourceCode, ExecutionMethod).Count;
                    string indentedMethod       = "\n        " + ExecutionMethod;
                    int    indentedMethodCount  = Regex.Matches(singleClassSourceCode, indentedMethod).Count;
                    if (executionMethodCount != indentedMethodCount)
                    {
                        throw new InvalidOperationException($"Source code parsing error in: {csFilePath}\n\n" +
                                                            "This is typically caused by an error in indentation and whitespace before '{ExecutionMethod}'.\n\n" +
                                                            "Ensure cookbook classes are standalone classes not encased by another class.");
                    }

                    // read the file's source code for primary recipe components
                    string id = GetRecipeID(singleClassSourceCode);
                    if (string.IsNullOrWhiteSpace(id))
                    {
                        continue;
                    }

                    IRecipe recipe = Locate.GetRecipe(id);
                    string  source = $"var plt = new ScottPlot.Plot({width}, {height});\n\n" +
                                     GetRecipeSource(singleClassSourceCode, csFilePath) + "\n\n" +
                                     $"plt.SaveFig(\"{id}.png\");";

                    sources.Add(new RecipeSource(recipe, source));
                }
            }

            return(sources.ToArray());
        }