2 using System.Collections;
3 using System.Collections.Generic;
6 using System.Text.RegularExpressions;
12 namespace Mono.Documentation {
13 public class MDocToMSXDocConverter : MDocCommand {
15 public override void Run (IEnumerable<string> args)
18 var p = new OptionSet () {
20 "The XML {FILE} to generate.\n" +
21 "If not specified, will create a set of files in the curent directory " +
22 "based on the //AssemblyInfo/AssemblyName values within the documentation.\n" +
23 "Use '-' to write to standard output.",
26 List<string> directories = Parse (p, args, "export-slashdoc",
27 "[OPTIONS]+ DIRECTORIES",
28 "Export mdoc(5) documentation within DIRECTORIES into \n" +
29 "Microsoft XML Documentation format files.");
30 if (directories == null)
32 Run (file, directories);
35 public static void Run (string file, IEnumerable<string> dirs)
37 Dictionary<string, XmlElement> outputfiles = new Dictionary<string, XmlElement> ();
39 XmlDocument nsSummaries = new XmlDocument();
40 nsSummaries.LoadXml("<namespaces/>");
42 foreach (string dir in dirs)
43 Process (dir, outputfiles, nsSummaries, file == null);
45 if (outputfiles.Count > 0 && file != null) {
46 List<string> files = new List<string> (outputfiles.Keys);
48 XmlDocument d = new XmlDocument ();
49 d.AppendChild (d.CreateElement ("doc"));
50 d.FirstChild.AppendChild (
51 d.ImportNode (outputfiles [files [0]].SelectSingleNode ("/doc/assembly"), true));
52 XmlElement members = d.CreateElement ("members");
53 d.FirstChild.AppendChild (members);
54 foreach (string f in files) {
55 XmlElement from = (XmlElement) outputfiles [f];
56 foreach (XmlNode n in from.SelectNodes ("/doc/members/*"))
57 members.AppendChild (d.ImportNode (n, true));
59 using (TextWriter tw = file == "-" ? Console.Out : new StreamWriter (file))
60 WriteXml (d.DocumentElement, tw);
64 // Write out each of the assembly documents
65 foreach (string assemblyName in outputfiles.Keys) {
66 XmlElement members = (XmlElement)outputfiles[assemblyName];
67 Console.WriteLine(assemblyName + ".xml");
68 using(StreamWriter sw = new StreamWriter(assemblyName + ".xml")) {
69 WriteXml(members.OwnerDocument.DocumentElement, sw);
73 // Write out a namespace summaries file.
74 Console.WriteLine("NamespaceSummaries.xml");
75 using(StreamWriter writer = new StreamWriter("NamespaceSummaries.xml")) {
76 WriteXml(nsSummaries.DocumentElement, writer);
80 private static void Process (string basepath, Dictionary<string, XmlElement> outputfiles, XmlDocument nsSummaries, bool implicitFiles)
82 if (System.Environment.CurrentDirectory == System.IO.Path.GetFullPath(basepath) && implicitFiles) {
83 Console.WriteLine("Don't run this tool from your documentation directory, since some files could be accidentally overwritten.");
87 XmlDocument index_doc = new XmlDocument();
88 index_doc.Load(Path.Combine(basepath, "index.xml"));
89 XmlElement index = index_doc.DocumentElement;
91 foreach (XmlElement assmbly in index.SelectNodes("Assemblies/Assembly")) {
92 string assemblyName = assmbly.GetAttribute("Name");
93 if (outputfiles.ContainsKey (assemblyName))
95 XmlDocument output = new XmlDocument();
96 XmlElement output_root = output.CreateElement("doc");
97 output.AppendChild(output_root);
99 XmlElement output_assembly = output.CreateElement("assembly");
100 output_root.AppendChild(output_assembly);
101 XmlElement output_assembly_name = output.CreateElement("name");
102 output_assembly.AppendChild(output_assembly_name);
103 output_assembly_name.InnerText = assemblyName;
105 XmlElement members = output.CreateElement("members");
106 output_root.AppendChild(members);
108 outputfiles.Add (assemblyName, members);
111 foreach (XmlElement nsnode in index.SelectNodes("Types/Namespace")) {
112 string ns = nsnode.GetAttribute("Name");
113 foreach (XmlElement typedoc in nsnode.SelectNodes("Type")) {
114 string typename = typedoc.GetAttribute("Name");
115 XmlDocument type = new XmlDocument();
116 type.Load(Path.Combine(Path.Combine(basepath, ns), typename) + ".xml");
118 string assemblyname = type.SelectSingleNode("Type/AssemblyInfo/AssemblyName").InnerText;
119 XmlElement members = outputfiles [assemblyname];
120 if (members == null) continue; // assembly is strangely not listed in the index
122 //CreateMember(EcmaDoc.GetCref (type.DocumentElement), type.DocumentElement, members);
124 foreach (XmlElement memberdoc in type.SelectNodes("Type/Members/Member")) {
125 //string name = EcmaDoc.GetCref (memberdoc);
127 string name = ns + "." + typename + "." + memberdoc.GetAttribute ("MemberName");
128 CreateMember(name, memberdoc, members);
132 foreach (XmlElement nsnode in index.SelectNodes("Types/Namespace")) {
133 AddNamespaceSummary(nsSummaries, basepath, nsnode.GetAttribute("Name"));
137 private static void AddNamespaceSummary(XmlDocument nsSummaries, string basepath, string currentNs) {
138 foreach (var filename in new [] {
139 Path.Combine(basepath, currentNs + ".xml"),
140 Path.Combine(basepath, "ns-" + currentNs + ".xml")}) {
141 if (File.Exists(filename)) {
142 XmlDocument nsSummary = new XmlDocument();
143 nsSummary.Load(filename);
144 XmlElement ns = nsSummaries.CreateElement("namespace");
145 nsSummaries.DocumentElement.AppendChild(ns);
146 ns.SetAttribute("name", currentNs);
147 ns.InnerText = nsSummary.SelectSingleNode("/Namespace/Docs/summary").InnerText;
152 private static void CreateMember(string name, XmlElement input, XmlElement output) {
153 XmlElement member = output.OwnerDocument.CreateElement("member");
154 output.AppendChild(member);
156 member.SetAttribute("name", name);
158 foreach (XmlNode docnode in input.SelectSingleNode("Docs"))
159 member.AppendChild(output.OwnerDocument.ImportNode(docnode, true));
162 private static void WriteXml(XmlElement element, System.IO.TextWriter output) {
163 XmlTextWriter writer = new XmlTextWriter(output);
164 writer.Formatting = Formatting.Indented;
165 writer.Indentation = 4;
166 writer.IndentChar = ' ';
167 element.WriteTo(writer);