update MEF to preview 9
[mcs.git] / tools / mdoc / Mono.Documentation / monodocs2slashdoc.cs
blob190861277f05cb6bb4ba86a092ff8040bcd1ff56
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.IO;
5 using System.Text;
6 using System.Text.RegularExpressions;
7 using System.Xml;
9 using Monodoc;
10 using Mono.Options;
12 namespace Mono.Documentation {
13 public class MDocToMSXDocConverter : MDocCommand {
15 public override void Run (IEnumerable<string> args)
17 string file = null;
18 var p = new OptionSet () {
19 { "o|out=",
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.",
24 v => file = v },
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)
31 return;
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);
47 files.Sort ();
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);
61 return;
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.");
84 return;
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))
94 continue;
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);
126 CreateMember(name, memberdoc, members);
130 foreach (XmlElement nsnode in index.SelectNodes("Types/Namespace")) {
131 AddNamespaceSummary(nsSummaries, basepath, nsnode.GetAttribute("Name"));
135 private static void AddNamespaceSummary(XmlDocument nsSummaries, string basepath, string currentNs) {
136 foreach (var filename in new [] {
137 Path.Combine(basepath, currentNs + ".xml"),
138 Path.Combine(basepath, "ns-" + currentNs + ".xml")}) {
139 if (File.Exists(filename)) {
140 XmlDocument nsSummary = new XmlDocument();
141 nsSummary.Load(filename);
142 XmlElement ns = nsSummaries.CreateElement("namespace");
143 nsSummaries.DocumentElement.AppendChild(ns);
144 ns.SetAttribute("name", currentNs);
145 ns.InnerText = nsSummary.SelectSingleNode("/Namespace/Docs/summary").InnerText;
150 private static void CreateMember(string name, XmlElement input, XmlElement output) {
151 XmlElement member = output.OwnerDocument.CreateElement("member");
152 output.AppendChild(member);
154 member.SetAttribute("name", name);
156 foreach (XmlNode docnode in input.SelectSingleNode("Docs"))
157 member.AppendChild(output.OwnerDocument.ImportNode(docnode, true));
160 private static void WriteXml(XmlElement element, System.IO.TextWriter output) {
161 XmlTextWriter writer = new XmlTextWriter(output);
162 writer.Formatting = Formatting.Indented;
163 writer.Indentation = 4;
164 writer.IndentChar = ' ';
165 element.WriteTo(writer);
166 output.WriteLine();