Sourcecode - ExampleInserter

Download ExampleInserter.cs

////////////////////////////////////////////////
////            Example inserter            ////
////  Version 1.0.1               31.07.04  ////
////          www.danielgrunwald.de         ////
////////////////////////////////////////////////

using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Text.RegularExpressions;
using System.Xml;

/*
 * If you implement any missing feature or find some bug, please write an e-mail to
 * daniel@danielgrunwald.de
 */

public class MainClass
{
	static ArrayList examples = new ArrayList();
	public static int ruleCount = 0;
	public static int matchCount = 0;
	
	public static void Main()
	{
		int totalStart = Environment.TickCount;
		int start;
		const string basePath = "./";
		start = Environment.TickCount;
		//Console.WriteLine("Reading examples...");
		GetExamples(new DirectoryInfo(basePath + "doc/examples"));
		Console.WriteLine("Got {0} examples in {1} ms.", examples.Count, Environment.TickCount - start);
		start = Environment.TickCount;
		//Console.WriteLine("Reading xml files...");
		GetXMLs(new DirectoryInfo(basePath + "bin"));
		//Console.WriteLine("Got {0} xml documentation files in {1} ms.", xmlDocs.Count, Environment.TickCount - start);
		//start = Environment.TickCount;
		//Console.WriteLine("Applying {0} rules...", ruleCount);
		foreach (Example e in examples) {
			foreach (XmlDoc doc in xmlDocs) {
				e.ApplyTo(doc.Members);
			}
		}
		Console.WriteLine("Got {0} matches using {2} rules in {3} xml files in {1} ms.", matchCount,
		                  Environment.TickCount - start, ruleCount, xmlDocs.Count);
		start = Environment.TickCount;
		//Console.WriteLine("Saving xml files...");
		foreach (XmlDoc doc in xmlDocs) {
			doc.Save();
		}
		//Console.WriteLine("Files saved in {0} ms.", Environment.TickCount - start);
		//Console.WriteLine("Finished in total {0} ms.", Environment.TickCount - totalStart);
	}
	
	#region GetExamples
	static void GetExample(FileInfo file)
	{
		try {
			StreamReader r = file.OpenText();
			try {
				examples.Add(new Example(r));
			} finally {
				r.Close();
			}
		} catch (Exception ex) {
			Console.WriteLine("Error reading example {0}:", file.Name);
			Console.WriteLine(ex.Message);
		}
	}
	
	static void GetExamples(DirectoryInfo dir)
	{
		foreach (FileInfo file in dir.GetFiles("*.cs")) {
			GetExample(file);
		}
		foreach (DirectoryInfo subdir in dir.GetDirectories()) {
			if (subdir.Name.StartsWith("."))
				continue;
			if (subdir.Name == "bin" || subdir.Name == "obj")
				continue;
			GetExamples(subdir);
		}
	}
	#endregion
	
	#region GetXMLs
	static ArrayList xmlDocs = new ArrayList();
	
	static void GetXML(FileInfo file)
	{
		XmlDocument xml = new XmlDocument();
		xml.Load(file.FullName);
		XmlElement root = xml.DocumentElement;
		if (root.Name != "doc")
			return;
		XmlElement members = root["members"];
		if (members == null)
			return;
		xmlDocs.Add(new XmlDoc(file, xml, members));
	}
	
	static void GetXMLs(DirectoryInfo dir)
	{
		foreach (FileInfo file in dir.GetFiles("*.xml")) {
			try {
				GetXML(file);
			} catch (Exception ex) {
				Console.WriteLine(ex.ToString());
				Console.Write("Press enter to continue...");
				Console.ReadLine();
			}
		}
		foreach (DirectoryInfo subdir in dir.GetDirectories()) {
			if (subdir.Name.StartsWith("."))
				continue;
			GetXMLs(subdir);
		}
	}
	#endregion
}

#region Example
class Example
{
	ArrayList applyTo = new ArrayList();
	string content;
	int targetCount = 0;
	
	public void ApplyTo(XmlElement members)
	{
		foreach (object o in applyTo) {
			if (o is Regex) {
				Apply(o as Regex, members);
			} else if (o is String) {
				Apply(o as String, members);
			} else {
				throw new Exception("Unknown object in applyTo-array: " + o.ToString());
			}
		}
	}
	
	void Apply(Regex r, XmlElement members)
	{
		foreach (XmlElement e in members) {
			string name = e.GetAttribute("name");
			if (r.IsMatch(name)) {
				Apply(e);
			}
		}
	}
	
	void Apply(String s, XmlElement members)
	{
		foreach (XmlElement e in members) {
			string name = e.GetAttribute("name");
			if (name.Substring(2).ToLower() == s) {
				Apply(e);
			}
		}
	}
	
	void Apply(XmlElement member)
	{
		targetCount++;
		MainClass.matchCount++;
		XmlElement example = member["example"];
		if (example == null) {
			example = member.OwnerDocument.CreateElement("example");
			member.AppendChild(example);
		} else {
			example.AppendChild(member.OwnerDocument.CreateElement("br"));
		}
		example.InnerXml += this.content;
	}
	
	public Example(StreamReader r)
	{
		StringBuilder b = new StringBuilder();
		string line;
		int linenr = 0;
		bool doc = true;
		while ((line = r.ReadLine()) != null) {
			linenr++;
			try {
				string trimmed = line.Trim();
				if (trimmed.StartsWith("//**")) {
					trimmed = trimmed.Substring(4).TrimStart();
					if (trimmed.StartsWith("~ "))
						applyTo.Add(new Regex("^.." + trimmed.Substring(2).Trim() + "$", RegexOptions.IgnoreCase));
					else
						applyTo.Add(trimmed.ToLower());
					MainClass.ruleCount++;
				} else if (trimmed == "////") {
					// ignore
				} else if (trimmed.StartsWith("////")) {
					if (!doc)
						b.Append("</code>\r\n");
					doc = true;
					b.Append(trimmed.Substring(4).TrimStart());
					b.Append("\r\n");
					doc = true;
				} else {
					if (doc)
						b.Append("<code>\r\n");
					b.Append(ToXML(line));
					b.Append("\r\n");
					doc = false;
				}
			} catch (Exception ex) {
				throw new Exception("Error in line " + linenr.ToString() + ":\r\n" + ex.Message);
			}
		}
		if (!doc)
			b.Append("</code>\r\n");
		if (applyTo.Count == 0)
			throw new Exception("No apply-To line (//**) found.");
		content = b.ToString();
	}
	
	static string ToXML(string text)
	{
		return text.Replace("&", "&amp;").Replace("\"", "&quot;").Replace("<", "&lt;").Replace(">", "&gt;");
	}
}
#endregion

#region XmlDoc
class XmlDoc
{
	FileInfo file;
	XmlDocument doc;
	public readonly XmlElement Members;
	
	public XmlDoc(FileInfo file, XmlDocument doc, XmlElement members)
	{
		this.file = file;
		this.doc = doc;
		this.Members = members;
	}
	
	public void Save()
	{
		doc.Save(file.FullName);
	}
}
#endregion