Add 'mdoc update-ecma-xml' command.
[mono.git] / mcs / tools / mdoc / Mono.Documentation / mdoc.cs
1 // Part of the mdoc(7) suite of tools.
2 using System;
3 using System.Collections.Generic;
4 using System.Diagnostics;
5 using System.Linq;
6 using Mono.Options;
7
8 namespace Mono.Documentation {
9
10         class MDoc {
11
12                 private static bool debug;
13
14                 private static void Main (string[] args)
15                 {
16                         MDoc d = new MDoc ();
17                         try {
18                                 d.Run (args);
19                         }
20                         catch (Exception e) {
21                                 if (debug) {
22                                         Console.Error.WriteLine ("mdoc: {0}", e.ToString ());
23                                 }
24                                 else {
25                                         Console.Error.WriteLine ("mdoc: {0}", e.Message);
26                                 }
27                                 Console.Error.WriteLine ("See `mdoc help' for more information.");
28                                 Environment.ExitCode = 1;
29                         }
30                 }
31
32                 int verbosity = 2;
33
34                 internal Dictionary<string, MDocCommand> subcommands;
35
36                 private void Run (string[] args)
37                 {
38                         subcommands = new Dictionary<string, MDocCommand> () {
39                                 { "assemble",         new MDocAssembler () },
40                                 { "dump-tree",        new MDocTreeDumper () },
41                                 { "export-html",      new MDocToHtmlConverter () },
42                                 { "export-html-webdoc",   new MDocExportWebdocHtml () },
43                                 { "export-msxdoc",    new MDocToMSXDocConverter () },
44                                 { "help",             new MDocHelpCommand (this) },
45                                 { "update",           new MDocUpdater () },
46                                 { "update-ecma-xml",  new MDocUpdateEcmaXml () },
47                                 { "validate",         new MDocValidator () },
48                         };
49
50                         bool showVersion = false;
51                         bool showHelp    = false;
52                         var p = new OptionSet () {
53                                 { "version",  v => showVersion = v != null },
54                                 { "v:",       (int? v) => verbosity = v.HasValue ? v.Value : verbosity+1 },
55                                 { "debug",    v => debug = v != null },
56                                 { "h|?|help", v => showHelp = v != null },
57                         };
58
59                         List<string> extra = p.Parse (args);
60
61                         if (showVersion) {
62                                 Console.WriteLine ("mdoc {0}", Consts.MonoVersion);
63                                 return;
64                         }
65                         if (extra.Count == 0) {
66                                 Console.WriteLine ("Use `mdoc help' for usage.");
67                                 return;
68                         }
69                         if (showHelp) {
70                                 extra.Add ("--help");
71                         }
72                         GetCommand (extra [0]).Run (extra);
73                 }
74
75                 internal MDocCommand GetCommand (string command)
76                 {
77                         MDocCommand h;
78                         if (!subcommands.TryGetValue (command, out h)) {
79                                 Error ("Unknown command: {0}.", command);
80                         }
81                         h.TraceLevel  = (TraceLevel) verbosity;
82                         h.DebugOutput = debug;
83                         return h;
84                 }
85
86                 private static void Error (string format, params object[] args)
87                 {
88                         throw new Exception (string.Format (format, args));
89                 }
90         }
91
92         public abstract class MDocCommand {
93
94                 public TraceLevel TraceLevel { get; set; }
95                 public bool DebugOutput { get; set; }
96
97                 public abstract void Run (IEnumerable<string> args);
98
99                 protected List<string> Parse (OptionSet p, IEnumerable<string> args, 
100                                 string command, string prototype, string description)
101                 {
102                         bool showHelp = false;
103                         p.Add ("h|?|help", 
104                                         "Show this message and exit.", 
105                                         v => showHelp = v != null );
106
107                         List<string> extra = null;
108                         if (args != null) {
109                                 extra = p.Parse (args.Skip (1));
110                         }
111                         if (args == null || showHelp) {
112                                 Console.WriteLine ("usage: mdoc {0} {1}", 
113                                                 args == null ? command : args.First(), prototype);
114                                 Console.WriteLine ();
115                                 Console.WriteLine (description);
116                                 Console.WriteLine ();
117                                 Console.WriteLine ("Available Options:");
118                                 p.WriteOptionDescriptions (Console.Out);
119                                 return null;
120                         }
121                         return extra;
122                 }
123
124                 public void Error (string format, params object[] args)
125                 {
126                         throw new Exception (string.Format (format, args));
127                 }
128
129                 public void Message (TraceLevel level, string format, params object[] args)
130                 {
131                         if ((int) level > (int) TraceLevel)
132                                 return;
133                         if (level == TraceLevel.Error)
134                                 Console.Error.WriteLine (format, args);
135                         else
136                                 Console.WriteLine (format, args);
137                 }
138         }
139
140         class MDocHelpCommand : MDocCommand {
141
142                 MDoc instance;
143
144                 public MDocHelpCommand (MDoc instance)
145                 {
146                         this.instance = instance;
147                 }
148
149                 public override void Run (IEnumerable<string> args)
150                 {
151                         if (args != null && args.Count() > 1) {
152                                 foreach (var arg in args.Skip (1)) {
153                                         instance.GetCommand (arg).Run (new string[]{arg, "--help"});
154                                 }
155                                 return;
156                         }
157                         Message (TraceLevel.Warning, 
158                                 "usage: mdoc COMMAND [OPTIONS]\n" +
159                                 "Use `mdoc help COMMAND' for help on a specific command.\n" +
160                                 "\n" + 
161                                 "Available commands:\n\n   " +
162                                 string.Join ("\n   ", instance.subcommands.Keys.OrderBy (v => v).ToArray()) +
163                                 "\n\n" + 
164                                 "mdoc is a tool for documentation management.\n" +
165                                 "For additional information, see http://www.mono-project.com/"
166                         );
167                 }
168         }
169 }
170