[Mono-docs-list] DocStatus tool

John Luke jluke@cfl.rr.com
11 Jun 2003 14:44:35 -0400


--=-Qfj0wEK8FUUzhIHT/7IP
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hello,

I have created a small tool to generate the status of our documentation
(mostly for Gtk#, but it works for ECMA also).  It currently consists of
DocStatus.cs which generates an xml file, and DocStatus.aspx that reads
the xml file.

To try it you will need a mono compiled since Duncan's IHasXmlNode patch
the other day. Here is a usage example:
mono DocStatus.exe gtk-sharp/doc/en Gtk#

where gtk-sharp/doc/en is the starting directory and Gtk# is the "Name"
used for the xml filename. Then put DocStatus.aspx and Gtk#DocStatus.xml
into your xsp directory.

Here are some of the current limitations:
- the documented / not documented decision is not great
- perhaps one large xml file for all the docs would be better instead of
how it's done now
- the aspx page is not very pretty

Any suggestions or comments would be appreciated.  Especially by Miguel
and Ben on fitting it in to the new website.

Thanks,
John Luke

--=-Qfj0wEK8FUUzhIHT/7IP
Content-Disposition: attachment; filename=DocStatus.cs
Content-Type: text/x-csharp; name=DocStatus.cs; charset=UTF-8
Content-Transfer-Encoding: 7bit

// author: John Luke  <jluke@cfl.rr.com>

using System;
using System.IO;
using System.Xml;
using System.Xml.XPath;

namespace DocStatus
{
	public class DocStatus
	{
		decimal membersAll;
		decimal membersDone;
		decimal classDone;
		decimal TotalDone;
		decimal TotalAll;
		decimal GrandTotalDone;
		decimal GrandTotalAll;
		XmlTextWriter writer;
		
		static void Main (string[] args)
		{
			string StartDir;
			string Name;
			
			if (args.Length == 2)
			{
				StartDir = args[0];
				Name = args[1];
			}
			else
			{
				Console.WriteLine ("Usage: mono DocStatus.exe StartDirectory Name");
				return;
			}
			
			new DocStatus (StartDir, Name);
		}
		
		DocStatus (string StartDir, string Name)
		{
			string outfile = Name + "DocStatus.xml";
			writer = new XmlTextWriter (outfile, System.Text.Encoding.UTF8);
			writer.Formatting = Formatting.Indented;
			writer.WriteStartDocument ();
			writer.WriteStartElement(null,"DocStatus", null);
			writer.WriteStartAttribute (null, "name", null);
				writer.WriteRaw (Name);
			writer.WriteEndAttribute ();
			
			DirectoryInfo di = new DirectoryInfo (StartDir);
			DirectoryInfo[] directories = di.GetDirectories ();
			
			foreach (DirectoryInfo directory in directories)
			{
				string d = directory.Name;
				string dirpath = Path.Combine (StartDir, d);
				
				if (d != "CVS")
				{
					writer.WriteStartElement(null, "Namespace", null);
					writer.WriteStartAttribute (null, "name", null);
						writer.WriteRaw (d);
					writer.WriteEndAttribute ();
					WriteNamespaceStats (dirpath);
					writer.WriteEndElement ();
				}
			}
			
			int GrandPercent = (int) ((GrandTotalDone / GrandTotalAll) * 100);
			
			writer.WriteStartElement(null, "Total", null);
				writer.WriteStartAttribute (null, "All", null);
					writer.WriteRaw (GrandTotalAll.ToString());
				writer.WriteEndAttribute ();
				writer.WriteStartAttribute (null, "Done", null);
					writer.WriteRaw (GrandTotalDone.ToString());
				writer.WriteEndAttribute ();
				writer.WriteStartAttribute (null, "Percent", null);
					writer.WriteRaw (GrandPercent.ToString());
				writer.WriteEndAttribute ();
			writer.WriteEndElement ();
			
			writer.WriteEndElement ();
			writer.WriteEndDocument ();
			writer.Flush ();
			writer.Close ();
		}
		
		void WriteNamespaceStats (string directory)
		{
			TotalDone = 0;
			TotalAll = 0;
			
			DirectoryInfo di = new DirectoryInfo (directory);
			FileInfo[] files = di.GetFiles ();
			
			foreach (FileInfo file in files)
			{
				string f = file.Name;
				string filepath = Path.Combine (directory, f);
				if (Path.GetExtension (filepath) == ".xml")
				{
					WriteClassStats (filepath);
				}
			}
			
			try
			{
				int percent = (int) ((TotalDone / TotalAll) * 100);
			
			writer.WriteStartElement (null, "Total", null);
				writer.WriteStartAttribute (null, "All", null);
					writer.WriteRaw (TotalAll.ToString());
				writer.WriteEndAttribute ();
				writer.WriteStartAttribute (null, "Done", null);
					writer.WriteRaw (TotalDone.ToString());
				writer.WriteEndAttribute ();
				writer.WriteStartAttribute (null, "Percent", null);
					writer.WriteRaw (percent.ToString());
				writer.WriteEndAttribute ();
			writer.WriteEndElement ();
			
			GrandTotalDone += TotalDone;
			GrandTotalAll += TotalAll;
			}
			catch (Exception e)
			{
				Console.WriteLine (e.Message, TotalDone, TotalAll);
			}
		}
		
		void WriteClassStats (string file)
		{
			membersAll = 0;
			membersDone = 0;
			classDone = 0;
			XPathDocument doc;
			XPathNavigator xpn;
			
			doc = new XPathDocument(file);
			xpn = doc.CreateNavigator();
					
			XPathNodeIterator xniSummary = xpn.Select ("/Type/Docs/summary");
            XPathNodeIterator xniRemarks = xpn.Select ("/Type/Docs/remarks");
            xniSummary.MoveNext ();
            xniRemarks.MoveNext ();
			
			if (xniSummary.Current.Value != "To be added" &&
                    xniSummary.Current.Value != "To be added")
			{
				classDone = 1;
			}
			
			XPathNodeIterator xniCount = xpn.Select("/Type/Members/Member");
			membersAll = xniCount.Count;
			
			XPathNodeIterator NameNode = xpn.Select ("/Type/Members/Member/MemberSignature/@Value");
			XPathNodeIterator summaryNodes = xpn.Select ("/Type/Members/Member/Docs/summary");
			XPathNodeIterator remarkNodes = xpn.Select ("/Type/Members/Member/Docs/remarks");
			
			for (int i = 0; i < xniCount.Count; i++)
			{
				NameNode.MoveNext ();
				summaryNodes.MoveNext ();
				remarkNodes.MoveNext ();
				
				if (summaryNodes.Current.Value != "To be added" &&
					remarkNodes.Current.Value != "To be added")
				{
					membersDone += 1;
				}
			}
			
			membersDone += classDone;
			membersAll += 1;
			
			string fname = Path.GetFileName (file);
			int percent = (int) ((membersDone / membersAll) * 100);
			
			writer.WriteStartElement (null, "Class", null);
			writer.WriteStartAttribute (null, "name", null);
				writer.WriteRaw (fname);
			writer.WriteEndAttribute ();
				writer.WriteStartAttribute (null, "All", null);
					writer.WriteRaw (membersAll.ToString ());
				writer.WriteEndAttribute ();
				writer.WriteStartAttribute (null, "Done", null);
					writer.WriteRaw (membersDone.ToString ());
				writer.WriteEndAttribute ();
				writer.WriteStartAttribute (null, "Percent", null);
					writer.WriteRaw (percent.ToString ());
				writer.WriteEndAttribute ();
			writer.WriteEndElement ();
			
			TotalDone += membersDone;
			TotalAll += membersAll;
		}
	}
}

--=-Qfj0wEK8FUUzhIHT/7IP
Content-Disposition: attachment; filename=DocStatus.aspx
Content-Type: text/plain; name=DocStatus.aspx; charset=UTF-8
Content-Transfer-Encoding: 7bit

<%@ Page Language="C#" %>
<%@ Import namespace="System.Xml" %>
<%@ Import namespace="System.Xml.XPath" %>
<html>
<head>
<style type="text/css">
<!--

.Normal
{
    font-family: Verdana, Helvetica, sans-serif;
    font-size: 11px;
    font-weight: normal;
    line-height: 12px;    
}

.Bold
{
    font-family: Verdana, Helvetica, sans-serif;
    font-size: 11px;
    font-weight: bold;
}
//-->
</style>
</head>

<script runat="server">
	void Page_Load(Object sender, EventArgs e)
	{
		string[] Names = GetNamespaceList ("Gtk#DocStatus.xml");
		
		if (!IsPostBack)
		{
			foreach (string name in Names)
			{
				optionsList.Add (name);
			}
		
			list.DataSource = optionsList;
			list.DataBind();
		}
	}
	
	string[] GetNamespaceList (string file)
	{
		XPathDocument doc;
		XPathNavigator xpn;
		XPathNodeIterator xni;
		
		doc = new XPathDocument(file);
		xpn = doc.CreateNavigator();
		xni = xpn.Select ("/DocStatus/Namespace/@name");
		
		string[] Names = new string [xni.Count];
		for (int i = 0; i < xni.Count; i++)
		{
			xni.MoveNext ();
			Names[i] = xni.Current.Value;
		}
		
		return Names;
	}
	
	void GetSelection (string selected)
	{
		XPathDocument doc = new XPathDocument ("Gtk#DocStatus.xml");
		XPathNavigator xpn = doc.CreateNavigator ();
		string xpe = "/DocStatus/Namespace[@name='" + selected + "']/Total";
		XPathNodeIterator xni = xpn.Select (xpe);

		xni.MoveNext ();
		XmlNode node = ((IHasXmlNode) xni.Current).GetNode ();
		XmlAttributeCollection attr = node.Attributes;
		string totalAll = attr["All"].Value;
		string totalDone = attr["Done"].Value;
		string totalPercent = attr["Percent"].Value;
		
		lblAll.Text = "Total members: " + totalAll;
		lblDone.Text = "Documented members: " + totalDone;
		lblPercent.Text = "Percent done: " + totalPercent + "%";
		lblSelection.Text = selected;
		
		GetDatagrid (selected);
	}
	
	void Click (object o, EventArgs e) 
	{
		 GetSelection (list.SelectedItem.Text);
	}
	
	public class Datum 
	{
		private string className;
		private string classDone;
		private string classAll;
		private string classPercent;

		public Datum (string className, string classDone, string classAll, string classPercent)
		{
			this.className = className;
			this.classDone = classDone;
			this.classAll = classAll;
			this.classPercent = classPercent;
		}

		public string Class 
		{
			get { return className; }
		}

		public string Done 
		{
			get { return classDone; }
		}

		public string All 
		{
			get { return classAll; }
		}
		
		public string Percent 
		{
			get { return classPercent; }
		}
	}
	
	void GetDatagrid (string selected)
	{
		XPathDocument doc = new XPathDocument ("Gtk#DocStatus.xml");
		XPathNavigator xpn = doc.CreateNavigator ();
		
		string Nodes = "/DocStatus/Namespace[@name='" + selected + "']/Class";
		XPathNodeIterator xni = xpn.Select (Nodes);
		
		ArrayList list = new ArrayList ();
		for (int i = 0; i < xni.Count; i++)
		{
			xni.MoveNext ();
			XmlNode node = ((IHasXmlNode) xni.Current).GetNode ();
			XmlAttributeCollection attr = node.Attributes;
			string dName = attr["name"].Value;
			string dDone = attr["Done"].Value;
			string dAll = attr["All"].Value;
			string dPercent = attr["Percent"].Value + "%";
			
			list.Add (new Datum (dName, dDone, dAll, dPercent));
		}
		
		dg.DataSource = list;
		dg.DataBind ();
	}
</script>

<title>DocStatus</title>
</head>
<h3>DocStatus page</h3>
<body>

<form runat="server">
	<object id="optionsList" runat="server" class="System.Collections.ArrayList" />
		<asp:DropDownList id="list" runat="server"/>	 
		<br><br>
		<asp:Button id="btn" Text="Submit" OnClick="Click" runat="server"/>
		<hr>
		<asp:Label id="lblDone" runat="server"/><br />
		<asp:Label id="lblAll" runat="server"/><br />
		<asp:Label id="lblPercent" runat="server"/>
		<hr>
	<h4><asp:Label id="lblSelection" runat="server"/></h4>
	<asp:datagrid id="dg" border="1" AutoGenerateColumns="false" EnableViewState="false" runat="server">
	    <Columns>
		<asp:BoundColumn HeaderText="Class" DataField="Class" ItemStyle-CssClass="Normal" HeaderStyle-Cssclass="Bold" />
		<asp:BoundColumn HeaderText="Done" DataField="Done" ItemStyle-CssClass="Normal" HeaderStyle-Cssclass="Bold"/>
		<asp:BoundColumn HeaderText="All" DataField="All" ItemStyle-CssClass="Normal" HeaderStyle-Cssclass="Bold"/>
	    <asp:BoundColumn HeaderText="Percent" DataField="Percent" ItemStyle-CssClass="Normal" HeaderStyle-Cssclass="Bold"/>
		</Columns>
	</asp:datagrid>
	</form>
</body>
</html>

--=-Qfj0wEK8FUUzhIHT/7IP--