You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			194 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			194 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //
 | |
| // The ecmaspec provider is for ECMA specifications
 | |
| //
 | |
| // Authors:
 | |
| //	John Luke (jluke@cfl.rr.com)
 | |
| //	Ben Maurer (bmaurer@users.sourceforge.net)
 | |
| //
 | |
| // Use like this:
 | |
| //   mono assembler.exe --ecmaspec DIRECTORY --out name
 | |
| //
 | |
| 
 | |
| using System;
 | |
| using System.Diagnostics;
 | |
| using System.IO;
 | |
| using System.Text;
 | |
| using System.Xml.XPath;
 | |
| using System.Xml.Xsl;
 | |
| using System.Xml;
 | |
| using System.Collections.Generic;
 | |
| using Lucene.Net.Index;
 | |
| using Lucene.Net.Documents;
 | |
| 
 | |
| namespace Monodoc.Providers
 | |
| {
 | |
| 	public class EcmaSpecProvider : Provider
 | |
| 	{
 | |
| 		string basedir;
 | |
| 	
 | |
| 		public EcmaSpecProvider (string base_directory)
 | |
| 		{
 | |
| 			basedir = base_directory;
 | |
| 			if (!Directory.Exists (basedir))
 | |
| 				throw new DirectoryNotFoundException (String.Format ("The directory `{0}' does not exist", basedir));
 | |
| 		}
 | |
| 	
 | |
| 		public override void PopulateTree (Tree tree)
 | |
| 		{
 | |
| 			XPathNavigator n = new XPathDocument (Path.Combine (basedir, "toc.xml")).CreateNavigator ();
 | |
| 			n.MoveToRoot ();
 | |
| 			n.MoveToFirstChild ();
 | |
| 			PopulateNode (n.SelectChildren ("node", ""), tree.RootNode);
 | |
| 		}
 | |
| 	
 | |
| 		void PopulateNode (XPathNodeIterator nodes, Node treeNode)
 | |
| 		{
 | |
| 			foreach (XPathNavigator n in nodes) {
 | |
| 				string secNumber = n.GetAttribute ("number", "");
 | |
| 				string secName = n.GetAttribute ("name", "");
 | |
| 
 | |
| 				var storage = treeNode.Tree.HelpSource.Storage;
 | |
| 				using (var file = File.OpenRead (Path.Combine (basedir, secNumber + ".xml")))
 | |
| 					storage.Store (secNumber, file);
 | |
| 
 | |
| 				Node thisNode = treeNode.GetOrCreateNode (secNumber + ": " + secName, "ecmaspec:" + secNumber);
 | |
| 			
 | |
| 				if (n.HasChildren)
 | |
| 					PopulateNode (n.SelectChildren ("node", ""), thisNode);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		public override void CloseTree (HelpSource hs, Tree tree)
 | |
| 		{
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public class EcmaSpecHelpSource : HelpSource
 | |
| 	{
 | |
| 		const string EcmaspecPrefix = "ecmaspec:";
 | |
| 		const string TocPart = "%toc"; // What is returned as TocXml
 | |
| 		const string SpecPart = "%spec"; // What is returned as Ecmaspec
 | |
| 
 | |
| 		public EcmaSpecHelpSource (string base_file, bool create) : base (base_file, create)
 | |
| 		{
 | |
| 		}
 | |
| 
 | |
| 		public override DocumentType GetDocumentTypeForId (string id)
 | |
| 		{
 | |
| 			return id.EndsWith (TocPart) ? DocumentType.TocXml : DocumentType.EcmaSpecXml;
 | |
| 		}
 | |
| 
 | |
| 		public override bool IsGeneratedContent (string id)
 | |
| 		{
 | |
| 			return id == "root:" || id.EndsWith (TocPart);
 | |
| 		}
 | |
| 
 | |
| 		public override bool IsMultiPart (string id, out IEnumerable<string> parts)
 | |
| 		{
 | |
| 			if (id == "root:" || id.EndsWith (TocPart) || id.EndsWith (SpecPart)) {
 | |
| 				parts = null;
 | |
| 				return false;
 | |
| 			}
 | |
| 			parts = MakeMultiPart (id);
 | |
| 			return true;
 | |
| 		}
 | |
| 
 | |
| 		IEnumerable<string> MakeMultiPart (string baseId)
 | |
| 		{
 | |
| 			yield return baseId + SpecPart;
 | |
| 			yield return baseId + TocPart;
 | |
| 		}
 | |
| 
 | |
| 		public override string GetText (string id)
 | |
| 		{
 | |
| 			Node n = id == "root:" ? Tree.RootNode : MatchNode (EcmaspecPrefix + id.Substring (0, id.Length - TocPart.Length));
 | |
| 			if (n == null)
 | |
| 				throw new ArgumentException ("id", string.Format ("{0} -> {1}", id, EcmaspecPrefix + id.Substring (0, id.Length - TocPart.Length)));
 | |
| 			return TreeDumper.ExportToTocXml (n, "C# Language Specification", "In this section:");
 | |
| 		}
 | |
| 
 | |
| 		public override Stream GetHelpStream (string id)
 | |
| 		{
 | |
| 			return id.EndsWith (SpecPart) ? base.GetHelpStream (id.Substring (0, id.IndexOf (SpecPart))) : base.GetHelpStream (id);
 | |
| 		}
 | |
| 	
 | |
| 		public override void PopulateSearchableIndex (IndexWriter writer) 
 | |
| 		{
 | |
| 			foreach (Node n in Tree.RootNode.ChildNodes)
 | |
| 				AddDocuments (writer, n);
 | |
| 		}
 | |
| 
 | |
| 		protected override string UriPrefix {
 | |
| 			get {
 | |
| 				return EcmaspecPrefix;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		void AddDocuments (IndexWriter writer, Node node) 
 | |
| 		{
 | |
| 			string url = node.PublicUrl;
 | |
| 			Stream file_stream = GetHelpStream (url.Substring (9));
 | |
| 			if (file_stream == null) //Error
 | |
| 				return;
 | |
| 			XmlDocument xdoc = new XmlDocument ();
 | |
| 			xdoc.Load (new XmlTextReader (file_stream));
 | |
| 
 | |
| 			//Obtain the title
 | |
| 			XmlNode nelem = xdoc.DocumentElement;
 | |
| 			string title = nelem.Attributes["number"].Value + ": " + nelem.Attributes["title"].Value;
 | |
| 
 | |
| 			//Obtain the text
 | |
| 			StringBuilder s = new StringBuilder ();
 | |
| 			GetTextNode (nelem, s);
 | |
| 			string text = s.ToString ();
 | |
| 
 | |
| 			//Obtain the examples
 | |
| 			StringBuilder s2 = new StringBuilder ();
 | |
| 			GetExamples (nelem, s2);
 | |
| 			string examples = s2.ToString ();
 | |
| 
 | |
| 			//Write to the Lucene Index all the parts
 | |
| 			SearchableDocument doc = new SearchableDocument ();
 | |
| 			doc.Title = title;
 | |
| 			doc.HotText = title.Substring (title.IndexOf (':')); 
 | |
| 			doc.Url = url;
 | |
| 			doc.Text = text;
 | |
| 			doc.Examples = examples;
 | |
| 			writer.AddDocument (doc.LuceneDoc);
 | |
| 		
 | |
| 			if (node.IsLeaf)
 | |
| 				return;
 | |
| 
 | |
| 			foreach (Node n in node.ChildNodes)
 | |
| 				AddDocuments (writer, n);
 | |
| 		}
 | |
| 
 | |
| 		void GetTextNode (XmlNode n, StringBuilder s) 
 | |
| 		{
 | |
| 			//dont include c# code
 | |
| 			if (n.Name == "code_example")
 | |
| 				return;
 | |
| 			//include all text from nodes
 | |
| 			if (n.NodeType == XmlNodeType.Text)
 | |
| 				s.Append (n.Value);
 | |
| 		
 | |
| 			//recursively explore all nodes
 | |
| 			if (n.HasChildNodes)
 | |
| 				foreach (XmlNode n_child in n.ChildNodes)
 | |
| 					GetTextNode (n_child, s);
 | |
| 		}
 | |
| 
 | |
| 		void GetExamples (XmlNode n, StringBuilder s)
 | |
| 		{
 | |
| 			if (n.Name == "code_example") {
 | |
| 				if (n.FirstChild.Name == "#cdata-section")
 | |
| 					s.Append (n.FirstChild.Value);
 | |
| 			} else {
 | |
| 				if (n.HasChildNodes)
 | |
| 					foreach (XmlNode n_child in n.ChildNodes)
 | |
| 						GetExamples (n_child, s);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 |