private static void AppendMarkdown(StringBuilder sb, CodeInfo cinfo, Assembly asm) { Console.WriteLine("Generating C# documentation."); Type astro = asm.GetType("CosineKitty.Astronomy"); // Document all public constants in the Astronomy class. FieldInfo[] constants = astro.GetFields(BindingFlags.Public | BindingFlags.Static) .Where(f => f.IsLiteral && !f.IsInitOnly) .OrderBy(f => f.Name.ToUpperInvariant()) .ToArray(); AppendSectionHeader(sb, "Constants"); foreach (FieldInfo c in constants) { AppendConstantMarkdown(sb, cinfo, c); } // All the member functions in the Astronomy class go in the "functions" section. AppendSectionHeader(sb, "Functions"); MethodInfo[] funcs = astro.GetMethods() .Where(m => m.IsPublic && m.IsStatic) .OrderBy(m => m.Name.ToUpperInvariant()) .ToArray(); foreach (MethodInfo f in funcs) { AppendFunctionMarkdown(sb, cinfo, f); } // The classes other than "Astronomy" are listed one by one in the "classes" section. sb.AppendLine("---"); sb.AppendLine(); AppendSectionHeader(sb, "Types"); Type[] typeList = asm.GetExportedTypes() .Where(c => c.Name != "Astronomy") .OrderBy(c => c.Name.ToUpperInvariant()) .ToArray(); foreach (Type c in typeList) { AppendTypeMarkdown(sb, cinfo, c); } }
private static void AppendConstantMarkdown(StringBuilder sb, CodeInfo cinfo, FieldInfo f) { CodeItem item = cinfo.FindField(f); if (item == null) { return; } string fieldType; switch (f.FieldType.Name) { case "Double": fieldType = "double"; break; default: throw new Exception($"Do not know how to generate markdown for constant type: {f.FieldType.Name}"); } string parentClassName = f.DeclaringType.Name; sb.AppendFormat("<a name=\"{0}.{1}\"></a>", parentClassName, f.Name); sb.AppendLine(); sb.AppendFormat("### `const {0} {1}.{2} = {3};`", fieldType, parentClassName, f.Name, f.GetValue(null)); sb.AppendLine(); sb.AppendLine(); if (!string.IsNullOrWhiteSpace(item.Summary)) { sb.AppendLine("**" + item.Summary + "**"); sb.AppendLine(); } if (!string.IsNullOrWhiteSpace(item.Remarks)) { sb.AppendLine(item.Remarks); sb.AppendLine(); } sb.AppendLine(); sb.AppendLine("---"); sb.AppendLine(); }
private static void AppendTypeMarkdown(StringBuilder sb, CodeInfo cinfo, Type type) { string kind; if (type.IsClass) { kind = "class"; } else if (type.IsEnum) { kind = "enum"; } else { kind = "struct"; } CodeItem typeItem = cinfo.FindType(type); // Header sb.AppendLine("<a name=\"" + type.Name + "\"></a>"); sb.AppendLine("## `" + kind + " " + type.Name + "`"); sb.AppendLine(); if (!string.IsNullOrWhiteSpace(typeItem.Summary)) { sb.AppendLine("**" + typeItem.Summary + "**"); sb.AppendLine(); } if (!string.IsNullOrWhiteSpace(typeItem.Remarks)) { sb.AppendLine(typeItem.Remarks); sb.AppendLine(); } if (type.IsEnum) { // Dump enum values. FieldInfo[] fields = type.GetFields().Where(f => f.IsLiteral).ToArray(); if (fields.Length > 0) { sb.AppendLine("| Value | Description |"); sb.AppendLine("| --- | --- |"); foreach (FieldInfo f in fields) { AppendEnumValueMarkdown(sb, cinfo, f); } sb.AppendLine(); } } else { // Dump struct/class fields. FieldInfo[] fields = type.GetFields(); if (fields.Length > 0) { sb.AppendLine("| Type | Name | Description |"); sb.AppendLine("| --- | --- | --- |"); foreach (FieldInfo f in fields) { if (f.DeclaringType == type) { AppendMemberVariableMarkdown(sb, cinfo, f); } } sb.AppendLine(); } } // Member functions MethodInfo[] funcs = type.GetMethods() .Where(m => m.IsPublic && m.DeclaringType == type) .OrderBy(m => m.Name.ToUpperInvariant()) .ToArray(); if (funcs.Length > 0) { sb.AppendLine("### member functions"); sb.AppendLine(); foreach (MethodInfo f in funcs) { AppendFunctionMarkdown(sb, cinfo, f); } } sb.AppendLine("---"); sb.AppendLine(); }