2 // A provider that uses Windows help file xhtml TOC files and looks for the
3 // referenced documents to create the help source.
6 // Copyright 2003 Lee Mallabone <gnome@fonicmonkey.net>
7 // Johannes Roith <johannes@roith.de>
8 // Miguel de Icaza <miguel@ximian.com>
13 using System.Collections.Generic;
15 using System.Text.RegularExpressions;
17 using System.Xml.Linq;
19 namespace Monodoc.Providers
21 public class XhtmlProvider : Provider
24 readonly XNamespace ns = "http://www.w3.org/1999/xhtml";
26 public XhtmlProvider (string handbookTocFile)
28 tocFile = handbookTocFile;
29 if (!File.Exists (tocFile))
30 throw new FileNotFoundException (String.Format ("The table of contents, `{0}' does not exist", tocFile));
33 public override void PopulateTree (Tree tree)
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);
41 void ParseUl (Tree tree, Node parent, XElement ul)
43 var storage = tree.HelpSource.Storage;
44 foreach (var e in ul.Elements (ns + "li")) {
45 var inner = e.Element (ns + "object");
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);
55 using (var file = File.OpenRead (element))
56 storage.Store (element, file);
57 parent.CreateNode (caption, XhtmlHelpSource.XhtmlPrefix + element);
61 void ObjectEntryToParams (XElement obj, out string caption, out string element)
63 var ps = obj.Elements (ns + "param");
65 .Where (p => p.Attribute ("name").Value == "Name")
66 .Select (p => (string)p.Attribute ("value"))
68 caption = caption ?? string.Empty;
71 .Where (p => p.Attribute ("name").Value == "Local")
72 .Select (p => (string)p.Attribute ("value"))
74 element = element ?? string.Empty;
77 public override void CloseTree (HelpSource hs, Tree tree)
82 public class XhtmlHelpSource : HelpSource
84 public XhtmlHelpSource (string base_file, bool create) : base (base_file, create)
89 internal const string XhtmlPrefix = "xhtml:";
91 protected override string UriPrefix {
97 public override SortType SortType {
99 return SortType.Element;
103 public override DocumentType GetDocumentTypeForId (string id)
105 return id == "root:" ? DocumentType.TocXml : DocumentType.MonoBook;
108 public override bool IsGeneratedContent (string id)
110 return id == "root:";
113 public override string GetText (string url)
115 return TreeDumper.ExportToTocXml (Tree.RootNode, "Mono Handbook", string.Empty);
118 public static string GetAbsoluteLink(string target, string url)
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:"))
134 int endp = target.IndexOf(':');
138 string protocol = target.Substring(0, endp);
148 // handle absolute urls like: /html/en/images/empty.png
149 if (!target.StartsWith("/")) {
151 // url is something like "gnome/bindings/mono.html"
152 // This will get the path "gnome/bindings"
154 int slash = url.LastIndexOf ("/");
158 tmpurl = url.Substring(0, slash);
160 // Count "../" in target and go one level down
161 // for each in tmpurl, eventually, then remove "../".
163 Regex reg1 = new Regex("../");
164 MatchCollection matches = reg1.Matches(target);
166 for(int i = 1; i < matches.Count; i++) {
167 slash = tmpurl.LastIndexOf ("/");
169 tmpurl = tmpurl.Substring(0, slash);
172 target = target.Replace("../", "");
174 value = tmpurl + "/" + target;
177 value = target.Substring(1, target.Length - 1);
184 XmlDocument RewriteLinks(XmlDocument docToProcess, string url)
186 XmlNodeList nodeList = docToProcess.GetElementsByTagName("a");
188 foreach(XmlNode node in nodeList) {
190 XmlElement element = (XmlElement) node;
192 if (element.HasAttribute("href") ){
194 XmlAttribute href = element.GetAttributeNode("href");
195 string target = href.Value;
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;
205 nodeList = docToProcess.GetElementsByTagName("img");
207 foreach(XmlNode node in nodeList) {
209 XmlElement element = (XmlElement) node;
211 if (element.HasAttribute("src") ){
213 XmlAttribute href = element.GetAttributeNode("src");
214 string target = href.Value;
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;
227 public override void PopulateIndex (IndexMaker index_maker)
229 PopulateIndexFromNodes (Tree.RootNode);
232 void PopulateIndexFromNodes (Node start)
234 /*var nodes = start.Nodes;
237 foreach (Node n in nodes)
238 PopulateIndexFromNodes (n);