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
);
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
);