4 using System.Collections.Generic;
7 using MonkeyDoc.Generators;
9 namespace MonkeyDoc.Generators.Html
11 public class Man2Html : IHtmlExporter
13 public string CssCode {
19 public string Export (Stream input, Dictionary<string, string> extraArgs)
23 return GetTextFromReader (new StreamReader (input));
26 public string Export (string input, Dictionary<string, string> extraArgs)
28 if (string.IsNullOrEmpty (input))
30 return GetTextFromReader (new StringReader (input));
33 public static string GetTextFromReader (TextReader file)
36 StateInfo s = new StateInfo ();
38 while ((line = file.ReadLine ()) != null)
39 ProcessLine (line, s);
41 return s.output.ToString ();
52 public Stack<string> tags = new Stack<string> ();
53 public StringBuilder output = new StringBuilder ();
56 static void ProcessLine (string line, StateInfo s)
58 string[] parts = SplitLine (line);
60 case ".\\\"": // comments
61 case ".de": // define macro
64 case "..": // end macro
68 s.output.Append ("<i>");
69 Translate (parts, 1, s.output);
70 s.output.Append ("</i>");
73 s.output.Append ("<b>");
74 Translate (parts, 1, s.output);
75 s.output.Append ("</b>");
78 Translate (parts, 1, s.output);
79 s.output.Append ("<br />");
83 s.output.Append ("<pre>\n");
84 s.tags.Push ("</pre>");
90 Expect (s, "</p>", "</dd>", "</dl>");
94 s.output.Append ("<p>");
95 Translate (parts, 1, s.output);
100 s.output.Append ("<blockquote>");
101 s.tags.Push ("</blockquote>");
104 ClearUntil (s, "</blockquote>");
108 s.output.Append ("<h2>");
109 Translate (parts, 1, s.output);
110 s.output.Append ("</h2>")
111 .Append ("<blockquote>");
112 s.tags.Push ("</blockquote>");
115 s.output.Append ("<h3>");
116 Translate (parts, 1, s.output);
117 s.output.Append ("</h3>");
121 string name = "", extra = "";
122 if (parts.Length >= 4 && parts [2].Trim ().Length == 0) {
123 name = parts [1] + "(" + parts [3] + ")";
124 if (parts.Length > 4) {
126 if (parts [start].Trim ().Length == 0)
128 extra = string.Join ("", parts, start, parts.Length-start);
132 name = string.Join ("", parts, 1, parts.Length-1);
133 s.output.Append ("<table width=\"100%\" bgcolor=\"#b0c4da\">" +
134 "<tr colspan=\"2\"><td>Manual Pages</td></tr>\n" +
136 Translate (name, s.output);
137 s.output.Append ("</h3></td><td align=\"right\">");
138 Translate (extra, s.output);
139 s.output.Append ("</td></tr></table>");
144 if (s.tags.Count > 0 && s.tags.Peek ().ToString () != "</dd>") {
145 s.output.Append ("<dl>");
146 s.tags.Push ("</dl>");
150 s.output.Append ("<dt>");
151 s.tags.Push ("</dt>");
152 s.ls = ListState.Start;
155 Translate (line, s.output);
158 if (s.ls == ListState.Start)
159 s.ls = ListState.Title;
160 else if (s.ls == ListState.Title) {
162 s.output.Append ("<dd>");
163 s.tags.Push ("</dd>");
164 s.ls = ListState.None;
166 s.output.Append ("\n");
169 static string[] SplitLine (string line)
171 if (line.Length > 1 && line [0] != '.')
172 return new string[]{null, line};
175 for (i = 0; i < line.Length; ++i) {
176 if (char.IsWhiteSpace (line, i))
180 if (i == line.Length)
181 return new string[]{line};
183 var pieces = new List<string> ();
184 pieces.Add (line.Substring (0, i));
185 bool inQuotes = false;
189 for ( ; i < line.Length; ++i) {
193 Add (pieces, line, start, i);
199 if (prevWs && c == '"') {
200 Add (pieces, line, start, i);
204 else if (char.IsWhiteSpace (c)) {
206 Add (pieces, line, start, i);
213 Add (pieces, line, start, i);
220 if (start > 0 && start != line.Length)
221 pieces.Add (line.Substring (start, line.Length-start));
222 return pieces.ToArray ();
225 static void Add (List<string> pieces, string line, int start, int end)
229 pieces.Add (line.Substring (start, end-start));
232 static void Expect (StateInfo s, params string[] expected)
235 while (s.tags.Count > 0 &&
236 Array.IndexOf (expected, (e = s.tags.Peek ().ToString ())) >= 0) {
237 s.output.Append (s.tags.Pop ().ToString ());
241 static void ClearUntil (StateInfo s, string required)
244 while (s.tags.Count > 0 &&
245 (e = s.tags.Peek ().ToString ()) != required) {
246 s.output.Append (s.tags.Pop ().ToString ());
249 s.output.Append (s.tags.Pop ().ToString ());
252 static void ClearAll (StateInfo s)
254 while (s.tags.Count > 0)
255 s.output.Append (s.tags.Pop ().ToString ());
258 static void Translate (string[] lines, int startIndex, StringBuilder output)
260 if (lines.Length <= startIndex)
263 Translate (lines [startIndex++], output);
264 if (startIndex == lines.Length)
266 } while (startIndex < lines.Length);
269 static void Translate (string line, StringBuilder output)
272 int start = output.Length;
273 for (int i = 0; i < line.Length; ++i) {
276 if ((i+2) < line.Length && line [i+1] == 'f') {
277 if (line [i+2] == 'I') {
278 output.Append ("<i>");
281 else if (line [i+2] == 'B') {
282 output.Append ("<b>");
285 else if (line [i+2] == 'R' || line [i+2] == 'P') {
286 output.Append (span);
292 else if ((i+1) < line.Length) {
293 output.Append (line [i+1]);
301 output.Append ("<");
304 output.Append (">");
307 output.Append ("&");
310 output.Append (line [i]);