You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			334 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			334 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.IO;
 | |
| using System.Text;
 | |
| using System.Linq;
 | |
| using System.Xml;
 | |
| using System.Xml.Xsl;
 | |
| using System.Xml.XPath;
 | |
| using System.Collections.Generic;
 | |
| 
 | |
| using Mono.Documentation;
 | |
| using BF = System.Reflection.BindingFlags;
 | |
| 
 | |
| namespace Monodoc.Generators.Html
 | |
| {
 | |
| 	public class Ecma2Html : IHtmlExporter
 | |
| 	{
 | |
| 		static string css_ecma;
 | |
| 		static string js;
 | |
| 		static XslCompiledTransform ecma_transform;
 | |
| 		readonly ExtensionObject ExtObject = new ExtensionObject ();
 | |
| 
 | |
| 		public Ecma2Html ()
 | |
| 		{
 | |
| 		}
 | |
| 
 | |
| 		public string CssCode {
 | |
| 			get {
 | |
| 				if (css_ecma != null)
 | |
| 					return css_ecma;
 | |
| 				var assembly = typeof(Ecma2Html).Assembly;
 | |
| 				Stream str_css = assembly.GetManifestResourceStream ("mono-ecma.css");
 | |
| 				css_ecma = (new StreamReader (str_css)).ReadToEnd();
 | |
| 				return css_ecma;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		public string JsCode {
 | |
| 			get {
 | |
| 				if (js != null)
 | |
| 					return js;
 | |
| 				var assembly = typeof(Ecma2Html).Assembly;
 | |
| 				Stream str_js = assembly.GetManifestResourceStream ("helper.js");
 | |
| 				js = (new StreamReader (str_js)).ReadToEnd();
 | |
| 				return js;
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		public string Htmlize (XmlReader ecma_xml, Dictionary<string, string> extraArgs)
 | |
| 		{
 | |
| 			var args = new XsltArgumentList ();
 | |
| 			args.AddExtensionObject("monodoc:///extensions", ExtObject);
 | |
| 			string specialPage;
 | |
| 			if (extraArgs.TryGetValue ("specialpage", out specialPage) && specialPage == "root") {
 | |
| 				extraArgs.Remove ("specialpage");
 | |
| 				extraArgs["show"] = "masteroverview";
 | |
| 			}
 | |
| 
 | |
| 			foreach (var kvp in extraArgs)
 | |
| 				args.AddParam (kvp.Key, string.Empty, kvp.Value);
 | |
| 
 | |
| 			return Htmlize (ecma_xml, args);
 | |
| 		}
 | |
| 
 | |
| 		public string Htmlize (XmlReader ecma_xml, XsltArgumentList args)
 | |
| 		{
 | |
| 			try{
 | |
| 				EnsureTransform ();
 | |
| 			
 | |
| 				var output = new StringBuilder ();
 | |
| 				ecma_transform.Transform (ecma_xml, 
 | |
| 				                          args, 
 | |
| 				                          XmlWriter.Create (output, ecma_transform.OutputSettings),
 | |
| 				                          CreateDocumentResolver ());
 | |
| 				return output.ToString ();
 | |
| 			}
 | |
| 			catch(Exception x)
 | |
| 			{
 | |
| 				var msg = x.ToString ();
 | |
| 				return msg;
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		protected virtual XmlResolver CreateDocumentResolver ()
 | |
| 		{
 | |
| 			// results in using XmlUrlResolver
 | |
| 			return null;
 | |
| 		}
 | |
| 
 | |
| 		public string Export (Stream stream, Dictionary<string, string> extraArgs)
 | |
| 		{
 | |
| 			return Htmlize (XmlReader.Create (new StreamReader(stream)), extraArgs);
 | |
| 		}
 | |
| 
 | |
| 		public string Export (string input, Dictionary<string, string> extraArgs)
 | |
| 		{
 | |
| 			return Htmlize (XmlReader.Create (new StringReader(input)), extraArgs);
 | |
| 		}
 | |
| 
 | |
| 		
 | |
| 		static void EnsureTransform ()
 | |
| 		{
 | |
| 			if (ecma_transform == null) {
 | |
| 				ecma_transform = new XslCompiledTransform ();
 | |
| 				var assembly = System.Reflection.Assembly.GetAssembly (typeof (Ecma2Html));
 | |
| 			
 | |
| 				Stream stream = assembly.GetManifestResourceStream ("mono-ecma-css.xsl");
 | |
| 				XmlReader xml_reader = new XmlTextReader (stream);
 | |
| 				XmlResolver r = new ManifestResourceResolver (".");
 | |
| 				ecma_transform.Load (xml_reader, XsltSettings.TrustedXslt, r);			
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		public class ExtensionObject
 | |
| 		{
 | |
| 			bool quiet = true;
 | |
| 			Dictionary<string, System.Reflection.Assembly> assemblyCache = new Dictionary<string, System.Reflection.Assembly> ();
 | |
| 
 | |
| 			public string Colorize(string code, string lang)
 | |
| 			{
 | |
| 				return Mono.Utilities.Colorizer.Colorize(code,lang);
 | |
| 			}
 | |
| 
 | |
| 			// Used by stylesheet to nicely reformat the <see cref=> tags. 
 | |
| 			public string MakeNiceSignature(string sig, string contexttype)
 | |
| 			{
 | |
| 				if (sig.Length < 3)
 | |
| 					return sig;
 | |
| 				if (sig[1] != ':')
 | |
| 					return sig;
 | |
| 
 | |
| 				char s = sig[0];
 | |
| 				sig = sig.Substring(2);
 | |
| 			
 | |
| 				switch (s) {
 | |
| 				case 'N': return sig;
 | |
| 				case 'T': return ShortTypeName (sig, contexttype);
 | |
| 
 | |
| 				case 'C': case 'M': case 'P': case 'F': case 'E':
 | |
| 					string type, mem, arg;
 | |
| 					
 | |
| 					// Get arguments
 | |
| 					int paren;
 | |
| 					if (s == 'C' || s == 'M')
 | |
| 						paren = sig.IndexOf("(");
 | |
| 					else if (s == 'P')
 | |
| 						paren = sig.IndexOf("[");
 | |
| 					else
 | |
| 						paren = 0;
 | |
| 					
 | |
| 					if (paren > 0 && paren < sig.Length-1) {
 | |
| 						string[] args = sig.Substring(paren+1, sig.Length-paren-2).Split(',');						
 | |
| 						for (int i = 0; i < args.Length; i++)
 | |
| 							args[i] = ShortTypeName(args[i], contexttype);
 | |
| 						arg = "(" + String.Join(", ", args) + ")";
 | |
| 						sig = sig.Substring(0, paren); 
 | |
| 					} else {
 | |
| 						arg = string.Empty;
 | |
| 					}
 | |
| 
 | |
| 					// Get type and member names
 | |
| 					int dot = sig.LastIndexOf(".");
 | |
| 					if (s == 'C' || dot <= 0 || dot == sig.Length-1) {
 | |
| 						mem = string.Empty;
 | |
| 						type = sig;
 | |
| 					} else {
 | |
| 						type = sig.Substring(0, dot);
 | |
| 						mem = sig.Substring(dot);
 | |
| 					}
 | |
| 						
 | |
| 					type = ShortTypeName(type, contexttype);
 | |
| 					
 | |
| 					return type + mem + arg;
 | |
| 
 | |
| 				default:
 | |
| 					return sig;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			static string ShortTypeName(string name, string contexttype)
 | |
| 			{
 | |
| 				int dot = contexttype.LastIndexOf(".");
 | |
| 				if (dot < 0) return name;
 | |
| 				string contextns = contexttype.Substring(0, dot+1);
 | |
| 
 | |
| 				if (name == contexttype)
 | |
| 					return name.Substring(dot+1);
 | |
| 			
 | |
| 				if (name.StartsWith(contextns))
 | |
| 					return name.Substring(contextns.Length);
 | |
| 			
 | |
| 				return name.Replace("+", ".");
 | |
| 			}
 | |
| 
 | |
| 			string MonoImpInfo(string assemblyname, string typename, string membername, string arglist, bool strlong)
 | |
| 			{
 | |
| 				if (quiet)
 | |
| 					return string.Empty;
 | |
| 				
 | |
| 				var a = new List<string> ();
 | |
| 				if (!string.IsNullOrEmpty (arglist)) a.Add (arglist);
 | |
| 				return MonoImpInfo(assemblyname, typename, membername, a, strlong);
 | |
| 			}
 | |
| 
 | |
| 			string MonoImpInfo(string assemblyname, string typename, string membername, XPathNodeIterator itr, bool strlong)
 | |
| 			{
 | |
| 				if (quiet)
 | |
| 					return string.Empty;
 | |
| 				
 | |
| 				var rgs = itr.Cast<XPathNavigator> ().Select (nav => nav.Value).ToList ();
 | |
| 			
 | |
| 				return MonoImpInfo (assemblyname, typename, membername, rgs, strlong);
 | |
| 			}
 | |
| 		
 | |
| 			string MonoImpInfo(string assemblyname, string typename, string membername, List<string> arglist, bool strlong)
 | |
| 			{
 | |
| 				try {
 | |
| 					System.Reflection.Assembly assembly = null;
 | |
| 				
 | |
| 					try {
 | |
| 						if (!assemblyCache.TryGetValue (assemblyname, out assembly)) {
 | |
| 							assembly = System.Reflection.Assembly.LoadWithPartialName(assemblyname);
 | |
| 							if (assembly != null)
 | |
| 								assemblyCache[assemblyname] = assembly;
 | |
| 						}
 | |
| 					} catch (Exception) {
 | |
| 						// nothing.
 | |
| 					}
 | |
| 				
 | |
| 					if (assembly == null) {
 | |
| 						/*if (strlong) return "The assembly " + assemblyname + " is not available to MonoDoc.";
 | |
| 						  else return string.Empty;*/
 | |
| 						return string.Empty; // silently ignore
 | |
| 					}
 | |
| 
 | |
| 					Type t = assembly.GetType(typename, false);
 | |
| 					if (t == null) {
 | |
| 						if (strlong)
 | |
| 							return typename + " has not been implemented.";
 | |
| 						else
 | |
| 							return "Not implemented.";
 | |
| 					}
 | |
| 
 | |
| 					// The following code is flakey and fails to find existing members
 | |
| 					return string.Empty;
 | |
| 				} catch (Exception) {
 | |
| 					return string.Empty;
 | |
| 				}
 | |
| 			}
 | |
| 		
 | |
| 			string MonoImpInfo(System.Reflection.MemberInfo mi, string itemtype, bool strlong)
 | |
| 			{
 | |
| 				if (quiet)
 | |
| 					return string.Empty;
 | |
| 				
 | |
| 				string s = string.Empty;
 | |
| 
 | |
| 				object[] atts = mi.GetCustomAttributes(true);
 | |
| 				int todoctr = 0;
 | |
| 				foreach (object att in atts) if (att.GetType().Name == "MonoTODOAttribute") todoctr++;
 | |
| 
 | |
| 				if (todoctr > 0) {
 | |
| 					if (strlong)
 | |
| 						s = "This " + itemtype + " is marked as being unfinished.<BR/>\n";
 | |
| 					else 
 | |
| 						s = "Unfinished.";
 | |
| 				}
 | |
| 
 | |
| 				return s;
 | |
| 			}
 | |
| 
 | |
| 			public string MonoImpInfo(string assemblyname, string typename, bool strlong)
 | |
| 			{
 | |
| 				if (quiet)
 | |
| 					return string.Empty;
 | |
| 				
 | |
| 				try {
 | |
| 					if (assemblyname == string.Empty)
 | |
| 						return string.Empty;
 | |
| 
 | |
| 					System.Reflection.Assembly assembly;
 | |
| 					if (!assemblyCache.TryGetValue (assemblyname, out assembly)) {
 | |
| 						assembly = System.Reflection.Assembly.LoadWithPartialName(assemblyname);
 | |
| 						if (assembly != null)
 | |
| 							assemblyCache[assemblyname] = assembly;
 | |
| 					}
 | |
| 
 | |
| 					if (assembly == null)
 | |
| 						return string.Empty;
 | |
| 
 | |
| 					Type t = assembly.GetType(typename, false);
 | |
| 					if (t == null) {
 | |
| 						if (strlong)
 | |
| 							return typename + " has not been implemented.";
 | |
| 						else
 | |
| 							return "Not implemented.";
 | |
| 					}
 | |
| 
 | |
| 					string s = MonoImpInfo(t, "type", strlong);
 | |
| 
 | |
| 					if (strlong) {
 | |
| 						var mis = t.GetMembers (BF.Static | BF.Instance | BF.Public | BF.NonPublic);
 | |
| 
 | |
| 						// Scan members for MonoTODO attributes
 | |
| 						int mctr = 0;
 | |
| 						foreach (var mi in mis) {
 | |
| 							string mii = MonoImpInfo(mi, null, false);
 | |
| 							if (mii != string.Empty) mctr++; 
 | |
| 						}
 | |
| 						if (mctr > 0) {
 | |
| 							s += "This type has " + mctr + " members that are marked as unfinished.<BR/>";
 | |
| 						}
 | |
| 					}
 | |
| 
 | |
| 					return s;
 | |
| 
 | |
| 				} catch (Exception) {
 | |
| 					return string.Empty;
 | |
| 				}			
 | |
| 			}
 | |
| 
 | |
| 			public bool MonoEditing ()
 | |
| 			{
 | |
| 				return false;
 | |
| 			}
 | |
| 		
 | |
| 			public bool IsToBeAdded(string text)
 | |
| 			{
 | |
| 				return text.StartsWith ("To be added");
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 		
 | |
| }
 |