[runtime] Disable some tests in full-aot mode which cannot be AOTed because of type...
[mono.git] / mcs / class / monodoc / Monodoc / providers / xhtml-provider.cs
1 //
2 // A provider that uses Windows help file xhtml TOC files and looks for the
3 // referenced documents to create the help source. 
4 //
5 // Authors:
6 // Copyright 2003 Lee Mallabone <gnome@fonicmonkey.net>
7 //   Johannes Roith <johannes@roith.de>
8 //   Miguel de Icaza <miguel@ximian.com>
9
10 using System;
11 using System.IO;
12 using System.Linq;
13 using System.Collections.Generic;
14 using System.Text;
15 using System.Text.RegularExpressions;
16 using System.Xml;
17 using System.Xml.Linq;
18
19 namespace Monodoc.Providers
20 {
21         public class XhtmlProvider : Provider
22         {
23                 string tocFile;
24                 readonly XNamespace ns = "http://www.w3.org/1999/xhtml";
25         
26                 public XhtmlProvider (string handbookTocFile)
27                 {
28                         tocFile = handbookTocFile;
29                         if (!File.Exists (tocFile))
30                                 throw new FileNotFoundException (String.Format ("The table of contents, `{0}' does not exist", tocFile));               
31                 }
32
33                 public override void PopulateTree (Tree tree)
34                 {
35                         var doc = XDocument.Load (tocFile);
36                         var uls = doc.Descendants (ns + "body").First ().Elements (ns + "ul");
37                         foreach (var ul in uls)
38                                 ParseUl (tree, tree.RootNode, ul);
39                 }
40
41                 void ParseUl (Tree tree, Node parent, XElement ul)
42                 {
43                         var storage = tree.HelpSource.Storage;
44                         foreach (var e in ul.Elements (ns + "li")) {
45                                 var inner = e.Element (ns + "object");
46                                 if (inner == null)
47                                         continue;
48                                 string caption, element;
49                                 ObjectEntryToParams (inner, out caption, out element);
50                                 // Don't add if the backing file doesn't exist
51                                 if (!File.Exists (element)) {
52                                         Console.Error.WriteLine ("Warning: File `{0}' referenced in TOC but it doesn't exist. It will be ignored.", element);
53                                         continue;
54                                 }
55                                 using (var file = File.OpenRead (element))
56                                         storage.Store (element, file);
57                                 parent.CreateNode (caption, XhtmlHelpSource.XhtmlPrefix + element);
58                         }
59                 }
60
61                 void ObjectEntryToParams (XElement obj, out string caption, out string element)
62                 {
63                         var ps = obj.Elements (ns + "param");
64                         caption = ps
65                                 .Where (p => p.Attribute ("name").Value == "Name")
66                                 .Select (p => (string)p.Attribute ("value"))
67                                 .FirstOrDefault ();
68                         caption = caption ?? string.Empty;
69
70                         element = ps
71                                 .Where (p => p.Attribute ("name").Value == "Local")
72                                 .Select (p => (string)p.Attribute ("value"))
73                                 .FirstOrDefault ();
74                         element = element ?? string.Empty;
75                 }
76
77                 public override void CloseTree (HelpSource hs, Tree tree)
78                 {
79                 }
80         }
81
82         public class XhtmlHelpSource : HelpSource
83         {
84                 public XhtmlHelpSource (string base_file, bool create) : base (base_file, create)
85                 {
86
87                 }
88
89                 internal const string XhtmlPrefix = "xhtml:";
90
91                 protected override string UriPrefix {
92                         get {
93                                 return XhtmlPrefix;
94                         }
95                 }
96
97                 public override SortType SortType {
98                         get {
99                                 return SortType.Element;
100                         }
101                 }
102                 
103                 public override DocumentType GetDocumentTypeForId (string id)
104                 {
105                         return id == "root:" ? DocumentType.TocXml : DocumentType.MonoBook;
106                 }
107
108                 public override bool IsGeneratedContent (string id)
109                 {
110                         return id == "root:";
111                 }
112         
113                 public override string GetText (string url)
114                 {
115                         return TreeDumper.ExportToTocXml (Tree.RootNode, "Mono Handbook", string.Empty);
116                 }
117
118                 public static string GetAbsoluteLink(string target, string url)
119                 {
120                         string value = null;
121                 
122                         if (target.StartsWith ("#") ||
123                             target.StartsWith ("T:") ||
124                             target.StartsWith ("M:") ||
125                             target.StartsWith ("P:") ||
126                             target.StartsWith ("T:") ||
127                             target.StartsWith ("E:") ||
128                             target.StartsWith ("F:") ||
129                             target.StartsWith ("O:") ||
130                             target.StartsWith ("N:") ||
131                             target.StartsWith ("api:"))
132                                 return null;
133                 
134                         int endp = target.IndexOf(':');
135                 
136                         if (endp == -1)
137                                 endp = 0;
138                         string protocol = target.Substring(0, endp);
139                         switch (protocol) {
140                         case "mailto": 
141                         case "http":
142                         case "https":
143                         case "ftp":
144                         case "news":
145                         case "irc":
146                                 break;
147                         default:
148                                 // handle absolute urls like: /html/en/images/empty.png
149                                 if (!target.StartsWith("/")) {
150                                 
151                                         // url is something like "gnome/bindings/mono.html"
152                                         // This will get the path "gnome/bindings"
153                                 
154                                         int slash = url.LastIndexOf ("/");
155                                         string tmpurl = url;
156                                 
157                                         if (slash != -1)
158                                                 tmpurl  = url.Substring(0, slash);
159                                 
160                                         // Count "../" in target and go one level down
161                                         // for each in tmpurl, eventually, then remove "../".
162                                 
163                                         Regex reg1 = new Regex("../");
164                                         MatchCollection matches = reg1.Matches(target);
165                                 
166                                         for(int i = 1; i < matches.Count; i++) {
167                                                 slash = tmpurl.LastIndexOf ("/");
168                                                 if (slash != -1) 
169                                                         tmpurl  = tmpurl.Substring(0, slash);
170                                         }
171                                 
172                                         target = target.Replace("../", "");
173                                 
174                                         value = tmpurl + "/" + target;
175                                 
176                                 } else {
177                                         value = target.Substring(1, target.Length - 1);
178                                 }
179                                 break;
180                         }
181                         return value;
182                 }
183         
184                 XmlDocument RewriteLinks(XmlDocument docToProcess, string url)
185                 {
186                         XmlNodeList nodeList = docToProcess.GetElementsByTagName("a");
187                 
188                         foreach(XmlNode node in nodeList) {
189                         
190                                 XmlElement element = (XmlElement) node;
191                         
192                                 if (element.HasAttribute("href") ){
193                                 
194                                         XmlAttribute href = element.GetAttributeNode("href");
195                                         string target = href.Value;
196                                 
197                                         target = GetAbsoluteLink(target, url);
198                                         if (target != null) {
199                                                 string newtarget = String.Format ("source-id:{0}:xhtml:{1}", SourceID, target);
200                                                 href.Value = newtarget;
201                                         }
202                                 }
203                         }
204
205                         nodeList = docToProcess.GetElementsByTagName("img");
206
207                         foreach(XmlNode node in nodeList) {
208                                                                                                                                     
209                                 XmlElement element = (XmlElement) node;
210                                                                                                                                     
211                                 if (element.HasAttribute("src") ){
212                                                                                                                                     
213                                         XmlAttribute href = element.GetAttributeNode("src");
214                                         string target = href.Value;
215                                                                                                                                     
216                                         target = GetAbsoluteLink(target, url);
217                                         if (target != null) {
218                                                 string newtarget = String.Format ("source-id:{0}:xhtml:{1}", SourceID, target);
219                                                 href.Value = newtarget;
220                                         }
221                                 }               
222                         }
223
224                         return docToProcess;
225                 }
226
227                 public override void PopulateIndex (IndexMaker index_maker)
228                 {
229                         PopulateIndexFromNodes (Tree.RootNode);
230                 }
231
232                 void PopulateIndexFromNodes (Node start)
233                 {
234                         /*var nodes = start.Nodes;
235                 
236                         if (nodes != null) {
237                                 foreach (Node n in nodes)
238                                         PopulateIndexFromNodes (n);
239                         }*/
240                 }
241         }
242 }