using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using NAnt.Core;
using NAnt.Core.Attributes;
using NAnt.Core.Types;
namespace ASPCommenter
{
///
/// NAnt task to extract XML comments from ASP files
///
[TaskName("getcomment")]
public class ExtractCommentTask : Task
{
private FileSet m_fileset = new FileSet();
private FileInfo m_output;
private string m_basedir = @"\";
private Encoding m_enc = Encoding.GetEncoding(1252);
///
/// Get or set the file to extract comment from
///
[BuildElement("fileset", Required=true)]
public FileSet Fileset
{
get
{
return m_fileset;
}
}
///
/// Get or set the output XML file to write comments to
///
[TaskAttribute("output", Required=true)]
public FileInfo Output
{
get
{
return m_output;
}
set
{
m_output = value;
}
}
///
/// The base directory where the code is localted. Relative to the project base
/// directory.
///
[TaskAttribute("basedir")]
public FileInfo BaseDirectory
{
get
{
return m_output;
}
set
{
m_output = value;
}
}
protected override void ExecuteTask()
{
ExtractComment();
}
public void ExtractComment()
{
XmlTextWriter writer = new XmlTextWriter(m_output.FullName, m_enc);
Log(Level.Info, "Extracting comments");
writer.WriteStartDocument();
writer.WriteStartElement("doc");
foreach(string file in m_fileset.FileNames)
{
ExtractComment(file, ref writer);
}
writer.WriteEndDocument();
writer.Close();
}
public void ExtractComment(string file, ref XmlTextWriter writer)
{
Regex rxComment = new Regex("(''').*\n");
Regex rxLine = new Regex(".*\n");
Regex rxDeclaration = new Regex("(sub|function).*[a-z].*\n");
MatchCollection matches;
StreamReader reader = new StreamReader(file, m_enc);
string content;
string comment = "";
string declaration;
string nextLine;
string relativeFile = file.Replace(Project.BaseDirectory + m_basedir, "");
Log(Level.Info, "\tFrom {0}", relativeFile, m_output.FullName);
content = reader.ReadToEnd();
reader.Close();
matches = rxComment.Matches(content);
writer.WriteStartElement("file");
writer.WriteAttributeString("path", relativeFile);
foreach(Match m in matches)
{
comment += m.Value.Substring(4, m.Length - 4);
nextLine = rxLine.Match(content, m.Index + m.Length).Value;
if (rxDeclaration.IsMatch(nextLine))
{
declaration = rxDeclaration.Match(nextLine).Value;
declaration = declaration.Remove(declaration.Length - 2, 2);
try
{
CheckXml(comment);
writer.WriteStartElement("member");
writer.WriteAttributeString("signature", declaration);
writer.WriteRaw(comment);
writer.WriteEndElement();
}
catch (XmlException ex)
{
Log(Level.Error, "\t\tInvalid XML in {0} comments : {1}", declaration, ex.Message);
}
comment = "";
declaration = "";
}
}
writer.WriteEndElement();
}
private void CheckXml(string xml)
{
XmlValidatingReader vr = new XmlValidatingReader(xml, XmlNodeType.Element, null);
while(vr.Read()) {}
vr.Close();
}
}
}