[mdoc] Add "internal" 'mdoc x-msitomsx' command.
authorJonathan Pryor <jonpryor@vt.edu>
Thu, 2 Sep 2010 03:12:03 +0000 (23:12 -0400)
committerJonathan Pryor <jonpryor@vt.edu>
Thu, 2 Sep 2010 22:26:59 +0000 (18:26 -0400)
The 'mdoc x-msitomsx' command converts a Microsoft internal XML dialect into
Microsoft XML Documentation format (e.g. what 'mdoc export-msxdoc' generates).

The 'mdoc x-msitomsx' command is internal, i.e. 'mdoc help' won't list it,
as this format is completely internal to Microsoft (and likely subject to
change without notice); this command only exists to help facilitate the ECMA
standardization process, converting Microsoft's existing (internal)
documentation into a format usable by the ECMA committee.

mcs/tools/mdoc/Makefile
mcs/tools/mdoc/Mono.Documentation/mdoc.cs
mcs/tools/mdoc/Mono.Documentation/msitomsx.cs [new file with mode: 0644]
mcs/tools/mdoc/Resources/msitomsx.xsl [new file with mode: 0644]
mcs/tools/mdoc/mdoc.exe.sources

index 7e77baae75ffebc3250b3f02c691d879fa94ac3b..23021b4d0353f1abc346a4b50484748ccb2e67c5 100644 (file)
@@ -9,6 +9,7 @@ MDOC_COMMON_FLAGS = \
        /resource:../monodoc/Resources/mono-ecma-css.xsl,mono-ecma-css.xsl          \
        /resource:Resources/defaulttemplate.xsl,defaulttemplate.xsl                 \
        /resource:Resources/monodoc-ecma.xsd,monodoc-ecma.xsd                       \
+       /resource:Resources/msitomsx.xsl,msitomsx.xsl                               \
        /resource:Resources/overview.xsl,overview.xsl                               \
        /resource:Resources/stylesheet.xsl,stylesheet.xsl                           \
        /r:System.Web.dll                                                           \
index d728ecbffb49c6096ad4c05fc78a4cf712680706..a67178e20462665c4109f0f2a5dfb5dc039a50a4 100644 (file)
@@ -78,7 +78,14 @@ namespace Mono.Documentation {
                        if (showHelp) {
                                extra.Add ("--help");
                        }
-                       GetCommand (extra [0]).Run (extra);
+                       switch (extra [0]) {
+                               case "x-msitomsx":
+                                       new MsidocToMsxdocConverter ().Run (extra);
+                                       break;
+                               default: 
+                                       GetCommand (extra [0]).Run (extra);
+                                       break;
+                       }
                }
 
                // Cribbed from mcs/driver.cs:LoadArgs(string)
diff --git a/mcs/tools/mdoc/Mono.Documentation/msitomsx.cs b/mcs/tools/mdoc/Mono.Documentation/msitomsx.cs
new file mode 100644 (file)
index 0000000..adc6b61
--- /dev/null
@@ -0,0 +1,161 @@
+//
+// msitomsx.cs: Microsoft Internal XML to Microsoft XML Documentation
+//
+// Arguably this doesn't belong in mdoc, but I'd rather not do some
+// stand-alone tool either, especially since the primary reason it exists is
+// to facilitate generating ECMA documentation via mdoc-update and
+// mdoc-update-ecma-xml...
+//
+// Author:
+//   Jonathan Pryor  <jpryor@novell.com>
+//
+// Copyright (c) 2010 Novell, Inc. (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using System.Xml;
+using System.Xml.Linq;
+using System.Xml.Xsl;
+
+using Mono.Options;
+
+namespace Mono.Documentation {
+
+       class MsidocToMsxdocConverter : MDocCommand {
+
+               XslCompiledTransform msiToMsxTransform = new XslCompiledTransform ();
+
+               public MsidocToMsxdocConverter ()
+               {
+                       using (var r = XmlReader.Create (
+                                               Assembly.GetExecutingAssembly ().GetManifestResourceStream ("msitomsx.xsl")))
+                               msiToMsxTransform.Load (r);
+               }
+
+               public override void Run (IEnumerable<string> args)
+               {
+                       string current_library = "";
+
+                       var types = new List<string> ();
+                       string outdir = null;
+
+                       var options = new OptionSet () {
+                               { "o|out=", 
+                                       "{DIRECTORY} to create Microsoft XML assembly.xml documentation files.",
+                                       v => outdir = v },
+                               { "library=",
+                                       "Ignored for compatibility with update-ecma-xml.",
+                                       v => {} },
+                               { "type=",
+                                       "The full {TYPE} name of a type to copy into the output file.",
+                                       v => types.Add (v) },
+                       };
+                       var sources = Parse (options, args, "export-ecma-xml", 
+                                       "[OPTIONS]+ DIRECTORIES",
+                                       "Convert Microsoft internal XML documentation within DIRECTORIES " +
+                                       "into Microsoft XML documentation.\n\n");
+                       if (sources == null)
+                               return;
+                       if (sources.Count == 0)
+                               Error ("No directories specified.");
+                       if (outdir == null)
+                               Error ("No output directory specified.  Please use --out=DIRECTORY.");
+
+                       types.Sort ();
+
+                       Dictionary<string, XDocument> docs = Convert (sources, types);
+                       foreach (KeyValuePair<string, XDocument> e in docs) {
+                               using (var o = CreateWriter (Path.Combine (outdir, e.Key + ".xml")))
+                                       e.Value.WriteTo (o);
+                       }
+               }
+
+               private Dictionary<string, XDocument> Convert (List<string> sources, List<string> types)
+               {
+                       var docs = new Dictionary<string, XDocument> ();
+
+                       foreach (var source in sources) {
+                               foreach (var dir in Directory.GetDirectories (source)) {
+                                       foreach (var file in Directory.GetFiles (dir, "*.xml")) {
+                                               ConvertDocs (docs, types, file);
+                                       }
+                               }
+                       }
+
+                       return docs;
+               }
+
+               private void ConvertDocs (Dictionary<string, XDocument> docs, List<string> types, string file)
+               {
+                       var doc = LoadFile (file);
+                       var type = doc.Root.Element ("members").Element ("member").Attribute ("name").Value;
+
+                       if (type.StartsWith ("N:"))
+                               return;
+
+                       if (!type.StartsWith ("T:"))
+                               throw new InvalidOperationException ("File '" + file + "' doesn't contain type documentation, it contains docs for: " + type);
+
+                       type = type.Substring (2);
+                       if (types.Count > 0 && types.BinarySearch (type) < 0)
+                               return;
+
+                       var assembly = doc.Root.Element ("assembly").Element ("name").Value;
+                       XDocument asmdocs;
+                       if (!docs.TryGetValue (assembly, out asmdocs)) {
+                               docs.Add (assembly, 
+                                               asmdocs = new XDocument (
+                                                       new XElement ("doc", 
+                                                               new XElement ("members"))));
+                       }
+
+                       var import = new XDocument ();
+                       msiToMsxTransform.Transform (doc.CreateReader (), import.CreateWriter ());
+
+                       asmdocs.Root.Element ("members").Add (import.Root.Element ("members").Elements ("member"));
+               }
+
+               static XDocument LoadFile (string file)
+               {
+                       using (XmlReader r = XmlReader.Create (file))
+                               return XDocument.Load (r);
+               }
+
+               static XmlWriter CreateWriter (string file)
+               {
+                       var settings = new XmlWriterSettings {
+                               Encoding            = new UTF8Encoding (false),
+                               Indent              = true,
+                               IndentChars         = "    ",
+                               NewLineChars        = "\r\n",
+                               OmitXmlDeclaration  = true,
+                       };
+
+                       return XmlWriter.Create (file, settings);
+               }
+       }
+}
+
diff --git a/mcs/tools/mdoc/Resources/msitomsx.xsl b/mcs/tools/mdoc/Resources/msitomsx.xsl
new file mode 100644 (file)
index 0000000..9a9a1d2
--- /dev/null
@@ -0,0 +1,115 @@
+<?xml version="1.0"?>
+<!--
+  Converts the "Microsoft Internal XML Documentation Format" into the 
+  "Microsoft XML Documentation Format".
+
+  The "Microsoft Internal XML Documentation Format" (msidoc) is whatever XML
+  format is used within Microsoft to document the BCL, as deduced from reading
+  their ECMA documentation dump.
+
+  The "Microsoft XML Documentation Format" (msxdoc) is what 'gmcs /doc' 
+  produces, and is documented in ECMA 334 §E.
+
+  msidoc is similar, but not identical to, msxdoc.  For example, where msxdoc
+  uses <see cref="FOO"/>, msidoc uses
+  <codeEntityReference>FOO</codeEntityReference>.  They also introduce
+  additional "wrapping" elements in various places (e.g. <content/>), useful
+  extensions (such as documenting method overload lists), and other oddities.
+  -->
+<xsl:stylesheet
+  version="1.0"
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
+  xmlns:authoring="http://ddue.schemas.microsoft.com/authoring/2003/5"
+  exclude-result-prefixes="msxsl authoring"
+  >
+
+  <xsl:output omit-xml-declaration="yes" />
+
+  <xsl:template match="assembly" />
+
+  <xsl:template match="member">
+    <!-- skip Overload: members, as these have no msxdoc equivalent. -->
+    <xsl:if test="not (starts-with (@name, 'Overload:'))">
+      <member name="{@name}">
+        <xsl:apply-templates />
+      </member>
+    </xsl:if>
+  </xsl:template>
+
+  <xsl:template match="authoring:dduexml" >
+    <xsl:apply-templates />
+  </xsl:template>
+
+  <xsl:template match="authoring:codeEntityReference">
+    <see cref="{.}" />
+  </xsl:template>
+
+  <xsl:template match="authoring:parameters">
+    <xsl:apply-templates />
+  </xsl:template>
+
+  <xsl:template match="authoring:parameter">
+    <param name="{authoring:parameterReference}">
+      <xsl:for-each select="*">
+        <xsl:if test="not (position () = 1)">
+          <xsl:apply-templates />
+        </xsl:if>
+      </xsl:for-each>
+    </param>
+  </xsl:template>
+
+  <xsl:template match="authoring:parameterReference">
+    <paramref name="{.}" />
+  </xsl:template>
+
+  <xsl:template match="authoring:returnValue">
+    <returns>
+      <xsl:apply-templates />
+    </returns>
+  </xsl:template>
+
+  <xsl:template match="authoring:codeExamples">
+    <xsl:apply-templates />
+  </xsl:template>
+
+  <xsl:template match="authoring:exceptions">
+    <xsl:apply-templates />
+  </xsl:template>
+
+  <xsl:template match="authoring:exception">
+    <exception cref="{authoring:codeEntityReference}">
+      <xsl:apply-templates select="authoring:content" />
+    </exception>
+  </xsl:template>
+
+  <xsl:template match="authoring:overload" />
+
+  <xsl:template match="authoring:codeExample">
+    <xsl:choose>
+      <xsl:when test="count(authoring:legacy) &gt; 0">
+      </xsl:when>
+      <xsl:otherwise>
+        <example>
+          <xsl:apply-templates />
+        </example>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="authoring:content">
+    <xsl:apply-templates />
+  </xsl:template>
+
+  <xsl:template match="authoring:languageKeyword">
+    <see langword="{.}" />
+  </xsl:template>
+
+  <!-- cute trick to remove the xmlns attributes on copied nodes. -->
+  <xsl:template match="*">
+    <xsl:element name="{local-name()}">
+      <xsl:apply-templates />
+    </xsl:element>
+  </xsl:template>
+</xsl:stylesheet>
+
index 65e477a7a8f10590b1667a4b0c8c5f861d2e498c..d39aea29d6934cade3e5115f945f69be6a5957fb 100644 (file)
@@ -9,6 +9,7 @@ Mono.Documentation/MdocFile.cs
 Mono.Documentation/monodocer.cs
 Mono.Documentation/monodocs2html.cs
 Mono.Documentation/monodocs2slashdoc.cs
+Mono.Documentation/msitomsx.cs
 Mono.Documentation/normalize.cs
 Mono.Documentation/validate.cs
 Mono.Documentation/webdoc.cs