/// <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 override void Document(List <AutoDocumentation.ITag> tags, int headingLevel, int indent) { // add a heading. if (!(tags.Last() is AutoDocumentation.Heading)) { tags.Add(new AutoDocumentation.NewPage()); } tags.Add(new AutoDocumentation.Heading(Name, headingLevel)); // write any memo children. foreach (IModel child in Apsim.Children(this, typeof(Memo))) { child.Document(tags, headingLevel + 1, indent); } int pageNumber = 1; int i = 0; List <IModel> children = Apsim.Children(this, typeof(Graph.Graph)); while (i < children.Count) { GraphPage page = new GraphPage(); page.name = Name + pageNumber; for (int j = i; j < i + 6 && j < children.Count; j++) { page.graphs.Add(children[j] as Graph.Graph); } tags.Add(page); i += 6; pageNumber++; } // write any folder children. foreach (IModel child in Apsim.Children(this, typeof(Folder))) { child.Document(tags, headingLevel + 1, indent); } }
/// <summary> /// Parse a string into documentation tags /// </summary> /// <param name="stringToParse">The string to parse</param> /// <param name="model">The associated model where the string came from</param> /// <param name="tags">The list of tags to add to</param> /// <param name="headingLevel">The current heading level</param> /// <param name="indent">The current indent level</param> /// <param name="documentAllChildren">Ensure all children are documented?</param> public static void ParseTextForTags(string stringToParse, IModel model, List <ITag> tags, int headingLevel, int indent, bool documentAllChildren) { List <IModel> childrenDocumented = new List <Core.IModel>(); int numSpacesStartOfLine = -1; string paragraphSoFar = string.Empty; if (stringToParse.StartsWith("\r\n")) { stringToParse = stringToParse.Remove(0, 2); } StringReader reader = new StringReader(stringToParse); string line = reader.ReadLine(); int targetHeadingLevel = headingLevel; while (line != null) { line = line.Trim(); // Adjust heading levels. if (line.StartsWith("#")) { int currentHeadingLevel = line.Count(c => c == '#'); targetHeadingLevel = headingLevel + currentHeadingLevel - 1; // assumes models start numbering headings at 1 '#' character string hashString = new string('#', targetHeadingLevel); line = hashString + line.Replace("#", "") + hashString; } if (line != string.Empty) { { if (numSpacesStartOfLine == -1) { int preLineLength = line.Length; line = line.TrimStart(); numSpacesStartOfLine = preLineLength - line.Length - 1; } else { line = line.Remove(0, numSpacesStartOfLine); } } } // Remove expression macros and replace with values. line = RemoveMacros(model, line); string heading; int thisHeadingLevel; if (GetHeadingFromLine(line, out heading, out thisHeadingLevel)) { StoreParagraphSoFarIntoTags(tags, indent, ref paragraphSoFar); tags.Add(new Heading(heading, thisHeadingLevel)); } else if (line.StartsWith("[Document ")) { StoreParagraphSoFarIntoTags(tags, indent, ref paragraphSoFar); // Find child string childName = line.Replace("[Document ", "").Replace("]", ""); IModel child = Apsim.Get(model, childName) as IModel; if (child == null) { paragraphSoFar += "<b>Unknown child name: " + childName + " </b>\r\n"; } else { DocumentModel(child, tags, targetHeadingLevel + 1, indent); childrenDocumented.Add(child); } } else if (line.StartsWith("[DocumentType ")) { StoreParagraphSoFarIntoTags(tags, indent, ref paragraphSoFar); // Find children string childTypeName = line.Replace("[DocumentType ", "").Replace("]", ""); Type childType = ReflectionUtilities.GetTypeFromUnqualifiedName(childTypeName); foreach (IModel child in Apsim.Children(model, childType)) { DocumentModel(child, tags, targetHeadingLevel + 1, indent); childrenDocumented.Add(child); } } else if (line == "[DocumentView]") { tags.Add(new ModelView(model)); } else { paragraphSoFar += " " + line + "\r\n"; } line = reader.ReadLine(); } StoreParagraphSoFarIntoTags(tags, indent, ref paragraphSoFar); if (documentAllChildren) { // write children. foreach (IModel child in Apsim.Children(model, typeof(IModel))) { if (!childrenDocumented.Contains(child)) { DocumentModel(child, tags, headingLevel + 1, indent, documentAllChildren); } } } }
/// <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 override 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 Apsim.Children(this, typeof(Memo))) { memo.Document(tags, headingLevel, indent); } if (Apsim.Children(this, typeof(Experiment)).Count > 0) { // 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 Apsim.Children(this, typeof(Experiment))) { IModel Factors = Apsim.Child(child, typeof(Factors)); string Design = ""; foreach (IModel factor in Apsim.Children(Factors, typeof(Factor))) { if (Design != "") { Design += " x "; } Design += factor.Name; } Design += " (" + (child as Experiment).GetSimulationNames().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 <IModel> children = Apsim.Children(this, typeof(Graph.Graph)); 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.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.Graph) && !(model is Memo)) { model.Document(tags, headingLevel + 1, indent); } } } else { foreach (IModel model in Children) { model.Document(tags, headingLevel + 1, indent); } } } }
/// <summary>Writes the description of a class to the tags.</summary> /// <param name="model">The model to get documentation for.</param> /// <param name="tags">The tags to add to.</param> /// <param name="headingLevel">The heading level to use.</param> /// <param name="indent">The indentation level.</param> /// <param name="documentAllChildren">Document all children?</param> /// <param name="withHeading">Put a heading in for this model?</param> public static void DocumentModel(IModel model, List <ITag> tags, int headingLevel, int indent, bool documentAllChildren = false, bool withHeading = false) { if (doc == null) { string fileName = Path.ChangeExtension(Assembly.GetExecutingAssembly().Location, ".xml"); doc = new XmlDocument(); doc.Load(fileName); } if (withHeading) { tags.Add(new AutoDocumentation.Heading(model.Name, headingLevel)); } List <IModel> childrenDocumented = new List <Core.IModel>(); string nameToFindInSummary = "members/T:" + model.GetType().FullName.Replace("+", ".") + "/summary"; XmlNode summaryNode = XmlUtilities.Find(doc.DocumentElement, nameToFindInSummary); if (summaryNode != null) { int numSpacesStartOfLine = -1; string paragraphSoFar = string.Empty; string st = summaryNode.InnerXml; if (st.StartsWith("\r\n")) { st = st.Remove(0, 2); } StringReader reader = new StringReader(st); string line = reader.ReadLine(); int targetHeadingLevel = headingLevel; while (line != null) { line = line.Trim(); // Adjust heading levels. if (line.StartsWith("#")) { int currentHeadingLevel = line.Count(c => c == '#') / 2; targetHeadingLevel = headingLevel + currentHeadingLevel - 1; string hashString = new string('#', targetHeadingLevel); line = hashString + line.Replace("#", "") + hashString; } if (line != string.Empty) { { if (numSpacesStartOfLine == -1) { int preLineLength = line.Length; line = line.TrimStart(); numSpacesStartOfLine = preLineLength - line.Length - 1; } else { line = line.Remove(0, numSpacesStartOfLine); } } } string heading; int thisHeadingLevel; if (GetHeadingFromLine(line, out heading, out thisHeadingLevel)) { StoreParagraphSoFarIntoTags(tags, indent, ref paragraphSoFar); tags.Add(new Heading(heading, thisHeadingLevel)); } else if (line.StartsWith("[Document ")) { StoreParagraphSoFarIntoTags(tags, indent, ref paragraphSoFar); // Find child string childName = line.Replace("[Document ", "").Replace("]", ""); IModel child = Apsim.Get(model, childName) as IModel; if (child == null) { paragraphSoFar += "<b>Unknown child name: " + childName + " </b>\r\n"; } else { child.Document(tags, targetHeadingLevel + 1, indent); childrenDocumented.Add(child); } } else { paragraphSoFar += " " + line + "\r\n"; } line = reader.ReadLine(); } StoreParagraphSoFarIntoTags(tags, indent, ref paragraphSoFar); } if (documentAllChildren) { // write children. foreach (IModel child in Apsim.Children(model, typeof(IModel))) { if (!childrenDocumented.Contains(child)) { child.Document(tags, headingLevel + 1, indent); } } } }