/// <summary>Documents the specified model.</summary> /// <param name="modelNameToDocument">The model name to document.</param> /// <param name="tags">The auto doc tags.</param> /// <param name="headingLevel">The starting heading level.</param> public void DocumentModel(string modelNameToDocument, List <AutoDocumentation.ITag> tags, int headingLevel) { Simulation simulation = Apsim.Find(this, typeof(Simulation)) as Simulation; if (simulation != null) { // Find the model of the right name. IModel modelToDocument = Apsim.Find(simulation, modelNameToDocument); // If not found then find a model of the specified type. if (modelToDocument == null) { modelToDocument = Apsim.Get(simulation, "[" + modelNameToDocument + "]") as IModel; } // If the simulation has the same name as the model we want to document, dig a bit deeper if (modelToDocument == simulation) { modelToDocument = Apsim.ChildrenRecursivelyVisible(simulation).FirstOrDefault(m => m.Name.Equals(modelNameToDocument, StringComparison.OrdinalIgnoreCase)); } // If still not found throw an error. if (modelToDocument != null) { // Get the path of the model (relative to parentSimulation) to document so that // when replacements happen below we will point to the replacement model not the // one passed into this method. string pathOfSimulation = Apsim.FullPath(simulation) + "."; string pathOfModelToDocument = Apsim.FullPath(modelToDocument).Replace(pathOfSimulation, ""); // Clone the simulation SimulationDescription simDescription = new SimulationDescription(simulation); Simulation clonedSimulation = simDescription.ToSimulation(); // Now use the path to get the model we want to document. modelToDocument = Apsim.Get(clonedSimulation, pathOfModelToDocument) as IModel; if (modelToDocument == null) { throw new Exception("Cannot find model to document: " + modelNameToDocument); } // resolve all links in cloned simulation. Links.Resolve(clonedSimulation, true); modelToDocument.IncludeInDocumentation = true; foreach (IModel child in Apsim.ChildrenRecursively(modelToDocument)) { child.IncludeInDocumentation = true; } // Document the model. AutoDocumentation.DocumentModel(modelToDocument, tags, headingLevel, 0, documentAllChildren: true); // Unresolve links. Links.Unresolve(clonedSimulation, true); } } }
/// <summary> /// Document the mathematical function. /// </summary> /// <param name="function">The IModel function.</param> /// <param name="op">The operator</param> /// <param name="tags">The tags to add to.</param> /// <param name="headingLevel">The level (e.g. H2) of the headings.</param> /// <param name="indent">The level of indentation 1, 2, 3 etc.</param> private static List <IModel> DocumentMathFunction(IModel function, char op, List <AutoDocumentation.ITag> tags, int headingLevel, int indent) { // create a string to display 'child1 - child2 - child3...' string msg = string.Empty; List <IModel> childrenToDocument = new List <IModel>(); foreach (IModel child in function.FindAllChildren <IFunction>()) { if (msg != string.Empty) { msg += " " + op + " "; } if (!AddChildToMsg(child, ref msg)) { childrenToDocument.Add(child); } } tags.Add(new AutoDocumentation.Paragraph("<i>" + function.Name + " = " + msg + "</i>", indent)); // write children if (childrenToDocument.Count > 0) { tags.Add(new AutoDocumentation.Paragraph("Where:", indent)); foreach (IModel child in childrenToDocument) { AutoDocumentation.DocumentModel(child, tags, headingLevel + 1, indent + 1); } } return(childrenToDocument); }
/// <summary>Documents the specified model.</summary> /// <param name="modelNameToDocument">The model name to document.</param> /// <param name="tags">The auto doc tags.</param> /// <param name="headingLevel">The starting heading level.</param> public void DocumentModel(string modelNameToDocument, List <AutoDocumentation.ITag> tags, int headingLevel) { Simulation simulation = this.FindInScope <Simulation>(); if (simulation != null) { // Find the model of the right name. IModel modelToDocument = simulation.FindInScope(modelNameToDocument); // If not found then find a model of the specified type. if (modelToDocument == null) { modelToDocument = simulation.FindByPath("[" + modelNameToDocument + "]")?.Value as IModel; } // If the simulation has the same name as the model we want to document, dig a bit deeper if (modelToDocument == simulation) { modelToDocument = simulation.FindAllDescendants().Where(m => !m.IsHidden).ToList().FirstOrDefault(m => m.Name.Equals(modelNameToDocument, StringComparison.OrdinalIgnoreCase)); } // If still not found throw an error. if (modelToDocument != null) { // Get the path of the model (relative to parentSimulation) to document so that // when replacements happen below we will point to the replacement model not the // one passed into this method. string pathOfSimulation = simulation.FullPath + "."; string pathOfModelToDocument = modelToDocument.FullPath.Replace(pathOfSimulation, ""); // Clone the simulation SimulationDescription simDescription = new SimulationDescription(simulation); Simulation clonedSimulation = simDescription.ToSimulation(); // Prepare the simulation for running - this perform misc cleanup tasks such // as removing disabled models, standardising the soil, resolving links, etc. clonedSimulation.Prepare(); FindInScope <IDataStore>().Writer.Stop(); // Now use the path to get the model we want to document. modelToDocument = clonedSimulation.FindByPath(pathOfModelToDocument)?.Value as IModel; if (modelToDocument == null) { throw new Exception("Cannot find model to document: " + modelNameToDocument); } // resolve all links in cloned simulation. Links.Resolve(clonedSimulation, true); // Document the model. AutoDocumentation.DocumentModel(modelToDocument, tags, headingLevel, 0, documentAllChildren: true); // Unresolve links. Links.Unresolve(clonedSimulation, true); } } }
/// <summary>Writes documentation for this function by adding to the list of documentation tags.</summary> /// <param name="tags">The list of tags to add to.</param> /// <param name="headingLevel">The level (e.g. H2) of the headings.</param> /// <param name="indent">The level of indentation 1, 2, 3 etc.</param> public virtual void Document(List <AutoDocumentation.ITag> tags, int headingLevel, int indent) { if (IncludeInDocumentation) { // document children foreach (IModel child in Children) { AutoDocumentation.DocumentModel(child, tags, headingLevel + 1, indent); } } }
/// <summary>Writes documentation for this function by adding to the list of documentation tags.</summary> /// <param name="tags">The list of tags to add to.</param> /// <param name="headingLevel">The level (e.g. H2) of the headings.</param> /// <param name="indent">The level of indentation 1, 2, 3 etc.</param> public virtual void Document(List <AutoDocumentation.ITag> tags, int headingLevel, int indent) { if (IncludeInDocumentation) { // add a heading. tags.Add(new AutoDocumentation.Heading(Name, headingLevel)); // write description of this class. AutoDocumentation.DocumentModel(this, tags, headingLevel, indent, true); //foreach (IModel model in Children) // model.Document(tags, headingLevel+1, indent); } }
/// <summary>Writes documentation for this function by adding to the list of documentation tags.</summary> /// <param name="tags">The list of tags to add to.</param> /// <param name="headingLevel">The level (e.g. H2) of the headings.</param> /// <param name="indent">The level of indentation 1, 2, 3 etc.</param> public virtual void Document(List <AutoDocumentation.ITag> tags, int headingLevel, int indent) { // add a heading. tags.Add(new AutoDocumentation.Heading(Name, headingLevel)); // write description of this class. AutoDocumentation.GetClassDescription(this, tags, indent); // write children. foreach (IModel child in Apsim.Children(this, typeof(IModel))) { child.Document(tags, headingLevel + 1, indent); } }
/// <summary>Creates the table.</summary> /// <param name="section">The section.</param> /// <param name="tableObj">The table to convert to html.</param> /// <param name="workingDirectory">The working directory.</param> private void CreateTable(Section section, AutoDocumentation.Table tableObj, string workingDirectory) { // Create a 2 column, 1 row table. Image in first cell, X/Y data in second cell. Table table = section.AddTable(); table.Style = "Table"; table.Rows.LeftIndent = "1cm"; foreach (List<string> column in tableObj.data) { Column column1 = table.AddColumn(); column1.Width = "1.4cm"; column1.Format.Alignment = ParagraphAlignment.Right; } for (int rowIndex = 0; rowIndex < tableObj.data[0].Count; rowIndex++) { Row row = table.AddRow(); for (int columnIndex = 0; columnIndex < tableObj.data.Count; columnIndex++) { string cellText = tableObj.data[columnIndex][rowIndex]; row.Cells[columnIndex].AddParagraph(cellText); } } }
/// <summary>Creates the graph.</summary> /// <param name="writer">The writer.</param> /// <param name="graphAndTable">The graph and table to convert to html.</param> /// <param name="workingDirectory">The working directory.</param> private void CreateGraphPDF(Section section, AutoDocumentation.GraphAndTable graphAndTable, string workingDirectory) { // Create a 2 column, 1 row table. Image in first cell, X/Y data in second cell. Table table = section.AddTable(); table.Style = "GraphAndTable"; table.Rows.LeftIndent = graphAndTable.indent + "cm"; Column column1 = table.AddColumn(); column1.Width = "8cm"; //column1.Format.Alignment = ParagraphAlignment.Right; Column column2 = table.AddColumn(); column2.Width = "8cm"; //column2.Format.Alignment = ParagraphAlignment.Right; Row row = table.AddRow(); // Ensure graphs directory exists. string graphDirectory = Path.Combine(workingDirectory, "Graphs"); Directory.CreateDirectory(graphDirectory); // Determine the name of the .png file to write. string PNGFileName = Path.Combine(graphDirectory, graphAndTable.xyPairs.Parent.Parent.Name + graphAndTable.xyPairs.Parent.Name + ".png"); // Setup graph. GraphView graph = new GraphView(); graph.Clear(); // Create a line series. graph.DrawLineAndMarkers("", graphAndTable.xyPairs.X, graphAndTable.xyPairs.Y, Models.Graph.Axis.AxisType.Bottom, Models.Graph.Axis.AxisType.Left, System.Drawing.Color.Blue, Models.Graph.LineType.Solid, Models.Graph.MarkerType.None, Models.Graph.LineThicknessType.Normal, Models.Graph.MarkerSizeType.Normal, true); // Format the axes. graph.FormatAxis(Models.Graph.Axis.AxisType.Bottom, graphAndTable.xName, false, double.NaN, double.NaN, double.NaN); graph.FormatAxis(Models.Graph.Axis.AxisType.Left, graphAndTable.yName, false, double.NaN, double.NaN, double.NaN); graph.BackColor = System.Drawing.Color.White; graph.FontSize = 10; graph.Refresh(); // Export graph to bitmap file. Bitmap image = new Bitmap(400, 250); graph.Export(image, false); image.Save(PNGFileName, System.Drawing.Imaging.ImageFormat.Png); MigraDoc.DocumentObjectModel.Shapes.Image image1 = row.Cells[0].AddImage(PNGFileName); // Add x/y data. Paragraph xyParagraph = row.Cells[1].AddParagraph(); xyParagraph.Style = "xyStyle"; AddFixedWidthText(xyParagraph, "X", 10); AddFixedWidthText(xyParagraph, "Y", 10); xyParagraph.AddLineBreak(); for (int i = 0; i < graphAndTable.xyPairs.X.Length; i++) { AddFixedWidthText(xyParagraph, graphAndTable.xyPairs.X[i].ToString(), 10); AddFixedWidthText(xyParagraph, graphAndTable.xyPairs.Y[i].ToString(), 10); xyParagraph.AddLineBreak(); } // Add an empty paragraph for spacing. Paragraph spacing = section.AddParagraph(); }
/// <summary>Adds a formatted paragraph to section.</summary> /// <param name="section">The section.</param> /// <param name="paragraph">The paragraph.</param> private void AddFormattedParagraphToSection(Section section, AutoDocumentation.Paragraph paragraph) { MarkdownDeep.Markdown markDown = new MarkdownDeep.Markdown(); markDown.ExtraMode = true; string html = markDown.Transform(paragraph.text); string imageDirectory = Path.GetDirectoryName(ExplorerPresenter.ApsimXFile.FileName); HtmlToMigraDoc.Convert(html, section, imageDirectory); Paragraph para = section.LastParagraph; para.Format.LeftIndent = Unit.FromCentimeter(paragraph.indent); if (paragraph.bookmarkName != null) para.AddBookmark(paragraph.bookmarkName); if (paragraph.handingIndent) { para.Format.LeftIndent = "1cm"; para.Format.FirstLineIndent = "-1cm"; } }
/// <summary>Writes documentation for this function by adding to the list of documentation tags.</summary> /// <param name="tags">The list of tags to add to.</param> /// <param name="headingLevel">The level (e.g. H2) of the headings.</param> /// <param name="indent">The level of indentation 1, 2, 3 etc.</param> public void Document(List <AutoDocumentation.ITag> tags, int headingLevel, int indent) { if (IncludeInDocumentation) { // add a heading. tags.Add(new AutoDocumentation.Heading(Name, headingLevel)); if (ShowPageOfGraphs) { foreach (Memo memo in FindAllChildren <Memo>()) { memo.Document(tags, headingLevel, indent); } if (FindAllChildren <Experiment>().Any()) { // Write Phase Table tags.Add(new AutoDocumentation.Paragraph("**List of experiments.**", indent)); DataTable tableData = new DataTable(); tableData.Columns.Add("Experiment Name", typeof(string)); tableData.Columns.Add("Design (Number of Treatments)", typeof(string)); foreach (IModel child in FindAllChildren <Experiment>()) { IModel Factors = child.FindChild <Factors>(); string Design = ""; foreach (Factor factor in Factors.FindAllChildren <Factor>()) { if (Design != "") { Design += " x "; } Design += factor.Name; } var simulationNames = (child as Experiment).GenerateSimulationDescriptions().Select(s => s.Name); Design += " (" + simulationNames.ToArray().Length + ")"; DataRow row = tableData.NewRow(); row[0] = child.Name; row[1] = Design; tableData.Rows.Add(row); } tags.Add(new AutoDocumentation.Table(tableData, indent)); } int pageNumber = 1; int i = 0; List <Graph> children = FindAllChildren <Graph>().ToList(); while (i < children.Count) { GraphPage page = new GraphPage(); page.name = Name + pageNumber; for (int j = i; j < i + 6 && j < children.Count; j++) { if (children[j].IncludeInDocumentation) { page.graphs.Add(children[j] as Graph); } } if (page.graphs.Count > 0) { tags.Add(page); } i += 6; pageNumber++; } // Document everything else other than graphs foreach (IModel model in Children) { if (!(model is Graph) && !(model is Memo)) { AutoDocumentation.DocumentModel(model, tags, headingLevel + 1, indent); } } } else { foreach (IModel model in Children) { AutoDocumentation.DocumentModel(model, tags, headingLevel + 1, indent); } } } }