5 using System.Collections.Generic;
9 namespace Monodoc.Generators
13 interface IHtmlExporter
15 string CssCode { get; }
16 string Export (Stream input, Dictionary<string, string> extras);
17 string Export (string input, Dictionary<string, string> extras);
20 public class HtmlGenerator : IDocGenerator<string>
22 const string cachePrefix = "htmlcached#";
24 static string css_code;
26 IDocCache defaultCache;
27 static Dictionary<DocumentType, IHtmlExporter> converters;
29 static HtmlGenerator ()
31 converters = new Dictionary<DocumentType, IHtmlExporter> {
32 { DocumentType.EcmaXml, new Ecma2Html () },
33 { DocumentType.Man, new Man2Html () },
34 { DocumentType.TocXml, new Toc2Html () },
35 { DocumentType.EcmaSpecXml, new Ecmaspec2Html () },
36 { DocumentType.ErrorXml, new Error2Html () },
37 { DocumentType.Html, new Idem () },
38 { DocumentType.MonoBook, new MonoBook2Html () },
39 { DocumentType.AddinXml, new Addin2Html () },
40 { DocumentType.PlainText, new Idem () },
44 public HtmlGenerator (IDocCache defaultCache)
46 this.defaultCache = defaultCache;
49 public string Generate (HelpSource hs, string id, Dictionary<string, string> context)
51 string specialPage = null;
52 if (context != null && context.TryGetValue ("specialpage", out specialPage) && specialPage == "master-root")
53 return GenerateMasterRootPage (hs != null ? hs.RootTree : null);
55 if (id == "root:" && hs == null)
56 return MakeEmptySummary ();
58 if (hs == null || string.IsNullOrEmpty (id))
59 return MakeHtmlError (string.Format ("Your request has found no candidate provider [hs=\"{0}\", id=\"{1}\"]",
60 hs == null ? "(null)" : hs.Name, id ?? "(null)"));
62 var cache = defaultCache ?? hs.Cache;
63 if (cache != null && cache.IsCached (MakeCacheKey (hs, id, null)))
64 return cache.GetCachedString (MakeCacheKey (hs, id, null));
66 IEnumerable<string> parts;
67 if (hs.IsMultiPart (id, out parts))
68 return GenerateMultiPart (hs, parts, id, context);
70 if (hs.IsRawContent (id))
71 return hs.GetText (id) ?? string.Empty;
73 DocumentType type = hs.GetDocumentTypeForId (id);
74 if (cache != null && context != null && cache.IsCached (MakeCacheKey (hs, id, context)))
75 return cache.GetCachedString (MakeCacheKey (hs, id, context));
77 IHtmlExporter exporter;
78 if (!converters.TryGetValue (type, out exporter))
79 return MakeHtmlError (string.Format ("Input type '{0}' not supported",
81 var result = hs.IsGeneratedContent (id) ?
82 exporter.Export (hs.GetCachedText (id), context) :
83 exporter.Export (hs.GetCachedHelpStream (id), context);
86 cache.CacheText (MakeCacheKey (hs, id, context), result);
90 string GenerateMultiPart (HelpSource hs, IEnumerable<string> ids, string originalId, Dictionary<string, string> context)
92 var sb = new StringBuilder ();
93 foreach (var id in ids)
94 sb.AppendLine (Generate (hs, id, context));
96 var cache = defaultCache ?? hs.Cache;
98 cache.CacheText (MakeCacheKey (hs, originalId, null), sb.ToString ());
99 return sb.ToString ();
102 string GenerateMasterRootPage (RootTree rootTree)
104 if (rootTree == null)
106 var assembly = System.Reflection.Assembly.GetAssembly (typeof (HtmlGenerator));
107 var hpStream = assembly.GetManifestResourceStream ("home.html");
108 var home = new StreamReader (hpStream).ReadToEnd ();
109 var links = string.Join (Environment.NewLine,
110 rootTree.RootNode.ChildNodes.Select (n => string.Format ("<li><a href=\"{0}\">{1}</a></li>", n.Element, n.Caption)));
111 return home.Replace ("@@API_DOCS@@", links);
114 public static string InlineCss {
116 if (css_code != null)
119 System.Reflection.Assembly assembly = System.Reflection.Assembly.GetAssembly (typeof (HtmlGenerator));
120 Stream str_css = assembly.GetManifestResourceStream ("base.css");
121 StringBuilder sb = new StringBuilder ((new StreamReader (str_css)).ReadToEnd());
122 sb.Replace ("@@FONT_FAMILY@@", "Sans Serif");
123 sb.Replace ("@@FONT_SIZE@@", "100%");
124 css_code = sb.ToString () + converters.Values
125 .Select (c => c.CssCode)
126 .Where (css => !string.IsNullOrEmpty (css))
127 .DefaultIfEmpty (string.Empty)
128 .Aggregate (string.Concat);
136 string MakeHtmlError (string error)
138 return string.Format ("<html><head></head><body><p><em>Error:</em> {0}</p></body></html>", error);
141 string MakeEmptySummary ()
143 return @"<html><head></head><body><p><em>This node doesn't have a summary available</p></body></html>";
146 string MakeCacheKey (HelpSource hs, string page, IDictionary<string,string> extraParams)
148 var key = cachePrefix + hs.SourceID + page;
149 if (extraParams != null && extraParams.Count > 0) {
150 var paramPart = string.Join ("-", extraParams.Select (kvp => kvp.Key + kvp.Value));
151 key += '_' + paramPart;