fad71374d0
Former-commit-id: a536d4f20e27294d8bbc2184d75f3a22364f7ba1
213 lines
7.8 KiB
C#
213 lines
7.8 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Xml;
|
|
|
|
using Monodoc;
|
|
using Mono.Options;
|
|
|
|
namespace Mono.Documentation {
|
|
public class MDocToMSXDocConverter : MDocCommand {
|
|
|
|
public override void Run (IEnumerable<string> args)
|
|
{
|
|
string file = null;
|
|
var p = new OptionSet () {
|
|
{ "o|out=",
|
|
"The XML {FILE} to generate.\n" +
|
|
"If not specified, will create a set of files in the curent directory " +
|
|
"based on the //AssemblyInfo/AssemblyName values within the documentation.\n" +
|
|
"Use '-' to write to standard output.",
|
|
v => file = v },
|
|
};
|
|
List<string> directories = Parse (p, args, "export-slashdoc",
|
|
"[OPTIONS]+ DIRECTORIES",
|
|
"Export mdoc(5) documentation within DIRECTORIES into \n" +
|
|
"Microsoft XML Documentation format files.");
|
|
if (directories == null)
|
|
return;
|
|
Run (file, directories);
|
|
}
|
|
|
|
public static void Run (string file, IEnumerable<string> dirs)
|
|
{
|
|
Dictionary<string, XmlElement> outputfiles = new Dictionary<string, XmlElement> ();
|
|
|
|
XmlDocument nsSummaries = new XmlDocument();
|
|
nsSummaries.LoadXml("<namespaces/>");
|
|
|
|
foreach (string dir in dirs)
|
|
Process (dir, outputfiles, nsSummaries, file == null);
|
|
|
|
if (outputfiles.Count > 0 && file != null) {
|
|
List<string> files = new List<string> (outputfiles.Keys);
|
|
files.Sort ();
|
|
XmlDocument d = new XmlDocument ();
|
|
d.AppendChild (d.CreateElement ("doc"));
|
|
d.FirstChild.AppendChild (
|
|
d.ImportNode (outputfiles [files [0]].SelectSingleNode ("/doc/assembly"), true));
|
|
XmlElement members = d.CreateElement ("members");
|
|
d.FirstChild.AppendChild (members);
|
|
foreach (string f in files) {
|
|
XmlElement from = (XmlElement) outputfiles [f];
|
|
foreach (XmlNode n in from.SelectNodes ("/doc/members/*"))
|
|
members.AppendChild (d.ImportNode (n, true));
|
|
}
|
|
using (TextWriter tw = file == "-" ? Console.Out : new StreamWriter (file))
|
|
WriteXml (d.DocumentElement, tw);
|
|
return;
|
|
}
|
|
|
|
// Write out each of the assembly documents
|
|
foreach (string assemblyName in outputfiles.Keys) {
|
|
XmlElement members = (XmlElement)outputfiles[assemblyName];
|
|
Console.WriteLine(assemblyName + ".xml");
|
|
using(StreamWriter sw = new StreamWriter(assemblyName + ".xml")) {
|
|
WriteXml(members.OwnerDocument.DocumentElement, sw);
|
|
}
|
|
}
|
|
|
|
// Write out a namespace summaries file.
|
|
Console.WriteLine("NamespaceSummaries.xml");
|
|
using(StreamWriter writer = new StreamWriter("NamespaceSummaries.xml")) {
|
|
WriteXml(nsSummaries.DocumentElement, writer);
|
|
}
|
|
}
|
|
|
|
private static void Process (string basepath, Dictionary<string, XmlElement> outputfiles, XmlDocument nsSummaries, bool implicitFiles)
|
|
{
|
|
if (System.Environment.CurrentDirectory == System.IO.Path.GetFullPath(basepath) && implicitFiles) {
|
|
Console.WriteLine("Don't run this tool from your documentation directory, since some files could be accidentally overwritten.");
|
|
return;
|
|
}
|
|
|
|
XmlDocument index_doc = new XmlDocument();
|
|
index_doc.Load(Path.Combine(basepath, "index.xml"));
|
|
XmlElement index = index_doc.DocumentElement;
|
|
|
|
foreach (XmlElement assmbly in index.SelectNodes("Assemblies/Assembly")) {
|
|
string assemblyName = assmbly.GetAttribute("Name");
|
|
if (outputfiles.ContainsKey (assemblyName))
|
|
continue;
|
|
XmlDocument output = new XmlDocument();
|
|
XmlElement output_root = output.CreateElement("doc");
|
|
output.AppendChild(output_root);
|
|
|
|
XmlElement output_assembly = output.CreateElement("assembly");
|
|
output_root.AppendChild(output_assembly);
|
|
XmlElement output_assembly_name = output.CreateElement("name");
|
|
output_assembly.AppendChild(output_assembly_name);
|
|
output_assembly_name.InnerText = assemblyName;
|
|
|
|
XmlElement members = output.CreateElement("members");
|
|
output_root.AppendChild(members);
|
|
|
|
outputfiles.Add (assemblyName, members);
|
|
}
|
|
|
|
foreach (XmlElement nsnode in index.SelectNodes("Types/Namespace")) {
|
|
string ns = nsnode.GetAttribute("Name");
|
|
foreach (XmlElement typedoc in nsnode.SelectNodes("Type")) {
|
|
string typename = typedoc.GetAttribute("Name");
|
|
XmlDocument type = new XmlDocument();
|
|
type.Load(Path.Combine(Path.Combine(basepath, ns), typename) + ".xml");
|
|
|
|
string assemblyname = type.SelectSingleNode("Type/AssemblyInfo/AssemblyName").InnerText;
|
|
XmlElement members = outputfiles [assemblyname];
|
|
if (members == null) continue; // assembly is strangely not listed in the index
|
|
|
|
CreateMember (GetCref (type.DocumentElement), type.DocumentElement, members);
|
|
|
|
foreach (XmlElement memberdoc in type.SelectNodes("Type/Members/Member")) {
|
|
string name = GetCref (memberdoc);
|
|
CreateMember(name, memberdoc, members);
|
|
}
|
|
}
|
|
}
|
|
foreach (XmlElement nsnode in index.SelectNodes("Types/Namespace")) {
|
|
AddNamespaceSummary(nsSummaries, basepath, nsnode.GetAttribute("Name"));
|
|
}
|
|
}
|
|
|
|
static string GetCref (XmlElement member)
|
|
{
|
|
string typeName = XmlDocUtils.ToEscapedTypeName (member.SelectSingleNode("/Type/@FullName").InnerText);
|
|
if (member.Name == "Type")
|
|
return "T:" + typeName;
|
|
string memberType = member.SelectSingleNode("MemberType").InnerText;
|
|
switch (memberType) {
|
|
case "Constructor":
|
|
return "C:" + typeName + MakeArgs(member);
|
|
case "Event":
|
|
return "E:" + typeName + "." + XmlDocUtils.ToEscapedMemberName (member.GetAttribute("MemberName"));
|
|
case "Field":
|
|
return "F:" + typeName + "." + XmlDocUtils.ToEscapedMemberName (member.GetAttribute("MemberName"));
|
|
case "Method": {
|
|
string name = "M:" + typeName + "." + XmlDocUtils.ToEscapedMemberName (member.GetAttribute("MemberName")) + MakeArgs(member);
|
|
if (member.GetAttribute("MemberName") == "op_Implicit" || member.GetAttribute("MemberName") == "op_Explicit")
|
|
name += "~" + XmlDocUtils.ToTypeName (member.SelectSingleNode("ReturnValue/ReturnType").InnerText, member);
|
|
return name;
|
|
}
|
|
case "Property":
|
|
return "P:" + typeName + "." + XmlDocUtils.ToEscapedMemberName (member.GetAttribute("MemberName")) + MakeArgs(member);
|
|
default:
|
|
throw new NotSupportedException ("MemberType '" + memberType + "' is not supported.");
|
|
}
|
|
}
|
|
|
|
static string MakeArgs (XmlElement member)
|
|
{
|
|
XmlNodeList parameters = member.SelectNodes ("Parameters/Parameter");
|
|
if (parameters.Count == 0)
|
|
return "";
|
|
StringBuilder args = new StringBuilder ();
|
|
args.Append ("(");
|
|
args.Append (XmlDocUtils.ToTypeName (parameters [0].Attributes ["Type"].Value, member));
|
|
for (int i = 1; i < parameters.Count; ++i) {
|
|
args.Append (",");
|
|
args.Append (XmlDocUtils.ToTypeName (parameters [i].Attributes ["Type"].Value, member));
|
|
}
|
|
args.Append (")");
|
|
return args.ToString ();
|
|
}
|
|
|
|
private static void AddNamespaceSummary(XmlDocument nsSummaries, string basepath, string currentNs) {
|
|
foreach (var filename in new [] {
|
|
Path.Combine(basepath, currentNs + ".xml"),
|
|
Path.Combine(basepath, "ns-" + currentNs + ".xml")}) {
|
|
if (File.Exists(filename)) {
|
|
XmlDocument nsSummary = new XmlDocument();
|
|
nsSummary.Load(filename);
|
|
XmlElement ns = nsSummaries.CreateElement("namespace");
|
|
nsSummaries.DocumentElement.AppendChild(ns);
|
|
ns.SetAttribute("name", currentNs);
|
|
ns.InnerText = nsSummary.SelectSingleNode("/Namespace/Docs/summary").InnerText;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void CreateMember(string name, XmlElement input, XmlElement output) {
|
|
XmlElement member = output.OwnerDocument.CreateElement("member");
|
|
output.AppendChild(member);
|
|
|
|
member.SetAttribute("name", name);
|
|
|
|
foreach (XmlNode docnode in input.SelectSingleNode("Docs"))
|
|
member.AppendChild(output.OwnerDocument.ImportNode(docnode, true));
|
|
}
|
|
|
|
private static void WriteXml(XmlElement element, System.IO.TextWriter output) {
|
|
XmlTextWriter writer = new XmlTextWriter(output);
|
|
writer.Formatting = Formatting.Indented;
|
|
writer.Indentation = 4;
|
|
writer.IndentChar = ' ';
|
|
element.WriteTo(writer);
|
|
output.WriteLine();
|
|
}
|
|
}
|
|
|
|
}
|