00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef TCLAP_DOCBOOKOUTPUT_H
00024 #define TCLAP_DOCBOOKOUTPUT_H
00025
00026 #include <string>
00027 #include <vector>
00028 #include <list>
00029 #include <iostream>
00030 #include <algorithm>
00031
00032 #include <tclap/CmdLineInterface.h>
00033 #include <tclap/CmdLineOutput.h>
00034 #include <tclap/XorHandler.h>
00035 #include <tclap/Arg.h>
00036
00037 namespace TCLAP {
00038
00043 class DocBookOutput : public CmdLineOutput
00044 {
00045
00046 public:
00047
00053 virtual void usage(CmdLineInterface& c);
00054
00060 virtual void version(CmdLineInterface& c);
00061
00068 virtual void failure(CmdLineInterface& c,
00069 ArgException& e );
00070
00071 protected:
00072
00079 void substituteSpecialChars( std::string& s, char r, std::string& x );
00080 void removeChar( std::string& s, char r);
00081 void basename( std::string& s );
00082
00083 void printShortArg(Arg* it);
00084 void printLongArg(Arg* it);
00085
00086 char theDelimiter;
00087 };
00088
00089
00090 inline void DocBookOutput::version(CmdLineInterface& _cmd)
00091 {
00092 std::cout << _cmd.getVersion() << std::endl;
00093 }
00094
00095 inline void DocBookOutput::usage(CmdLineInterface& _cmd )
00096 {
00097 std::list<Arg*> argList = _cmd.getArgList();
00098 std::string progName = _cmd.getProgramName();
00099 std::string xversion = _cmd.getVersion();
00100 theDelimiter = _cmd.getDelimiter();
00101 XorHandler xorHandler = _cmd.getXorHandler();
00102 std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
00103 basename(progName);
00104
00105 std::cout << "<?xml version='1.0'?>" << std::endl;
00106 std::cout << "<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.2//EN\"" << std::endl;
00107 std::cout << "\t\"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd\">" << std::endl << std::endl;
00108
00109 std::cout << "<refentry>" << std::endl;
00110
00111 std::cout << "<refmeta>" << std::endl;
00112 std::cout << "<refentrytitle>" << progName << "</refentrytitle>" << std::endl;
00113 std::cout << "<manvolnum>1</manvolnum>" << std::endl;
00114 std::cout << "</refmeta>" << std::endl;
00115
00116 std::cout << "<refnamediv>" << std::endl;
00117 std::cout << "<refname>" << progName << "</refname>" << std::endl;
00118 std::cout << "<refpurpose>" << _cmd.getMessage() << "</refpurpose>" << std::endl;
00119 std::cout << "</refnamediv>" << std::endl;
00120
00121 std::cout << "<refsynopsisdiv>" << std::endl;
00122 std::cout << "<cmdsynopsis>" << std::endl;
00123
00124 std::cout << "<command>" << progName << "</command>" << std::endl;
00125
00126
00127 for ( int i = 0; (unsigned int)i < xorList.size(); i++ )
00128 {
00129 std::cout << "<group choice='req'>" << std::endl;
00130 for ( ArgVectorIterator it = xorList[i].begin();
00131 it != xorList[i].end(); it++ )
00132 printShortArg((*it));
00133
00134 std::cout << "</group>" << std::endl;
00135 }
00136
00137
00138 for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
00139 if ( !xorHandler.contains( (*it) ) )
00140 printShortArg((*it));
00141
00142 std::cout << "</cmdsynopsis>" << std::endl;
00143 std::cout << "</refsynopsisdiv>" << std::endl;
00144
00145 std::cout << "<refsect1>" << std::endl;
00146 std::cout << "<title>Description</title>" << std::endl;
00147 std::cout << "<para>" << std::endl;
00148 std::cout << _cmd.getMessage() << std::endl;
00149 std::cout << "</para>" << std::endl;
00150 std::cout << "</refsect1>" << std::endl;
00151
00152 std::cout << "<refsect1>" << std::endl;
00153 std::cout << "<title>Options</title>" << std::endl;
00154
00155 std::cout << "<variablelist>" << std::endl;
00156
00157 for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
00158 printLongArg((*it));
00159
00160 std::cout << "</variablelist>" << std::endl;
00161 std::cout << "</refsect1>" << std::endl;
00162
00163 std::cout << "<refsect1>" << std::endl;
00164 std::cout << "<title>Version</title>" << std::endl;
00165 std::cout << "<para>" << std::endl;
00166 std::cout << xversion << std::endl;
00167 std::cout << "</para>" << std::endl;
00168 std::cout << "</refsect1>" << std::endl;
00169
00170 std::cout << "</refentry>" << std::endl;
00171
00172 }
00173
00174 inline void DocBookOutput::failure( CmdLineInterface& _cmd,
00175 ArgException& e )
00176 {
00177 static_cast<void>(_cmd);
00178 std::cout << e.what() << std::endl;
00179 throw ExitException(1);
00180 }
00181
00182 inline void DocBookOutput::substituteSpecialChars( std::string& s,
00183 char r,
00184 std::string& x )
00185 {
00186 size_t p;
00187 while ( (p = s.find_first_of(r)) != std::string::npos )
00188 {
00189 s.erase(p,1);
00190 s.insert(p,x);
00191 }
00192 }
00193
00194 inline void DocBookOutput::removeChar( std::string& s, char r)
00195 {
00196 size_t p;
00197 while ( (p = s.find_first_of(r)) != std::string::npos )
00198 {
00199 s.erase(p,1);
00200 }
00201 }
00202
00203 inline void DocBookOutput::basename( std::string& s )
00204 {
00205 size_t p = s.find_last_of('/');
00206 if ( p != std::string::npos )
00207 {
00208 s.erase(0, p + 1);
00209 }
00210 }
00211
00212 inline void DocBookOutput::printShortArg(Arg* a)
00213 {
00214 std::string lt = "<";
00215 std::string gt = ">";
00216
00217 std::string id = a->shortID();
00218 substituteSpecialChars(id,'<',lt);
00219 substituteSpecialChars(id,'>',gt);
00220 removeChar(id,'[');
00221 removeChar(id,']');
00222
00223 std::string choice = "opt";
00224 if ( a->isRequired() )
00225 choice = "plain";
00226
00227 std::cout << "<arg choice='" << choice << '\'';
00228 if ( a->acceptsMultipleValues() )
00229 std::cout << " rep='repeat'";
00230
00231
00232 std::cout << '>';
00233 if ( !a->getFlag().empty() )
00234 std::cout << a->flagStartChar() << a->getFlag();
00235 else
00236 std::cout << a->nameStartString() << a->getName();
00237 if ( a->isValueRequired() )
00238 {
00239 std::string arg = a->shortID();
00240 removeChar(arg,'[');
00241 removeChar(arg,']');
00242 removeChar(arg,'<');
00243 removeChar(arg,'>');
00244 arg.erase(0, arg.find_last_of(theDelimiter) + 1);
00245 std::cout << theDelimiter;
00246 std::cout << "<replaceable>" << arg << "</replaceable>";
00247 }
00248 std::cout << "</arg>" << std::endl;
00249
00250 }
00251
00252 inline void DocBookOutput::printLongArg(Arg* a)
00253 {
00254 std::string lt = "<";
00255 std::string gt = ">";
00256
00257 std::string desc = a->getDescription();
00258 substituteSpecialChars(desc,'<',lt);
00259 substituteSpecialChars(desc,'>',gt);
00260
00261 std::cout << "<varlistentry>" << std::endl;
00262
00263 if ( !a->getFlag().empty() )
00264 {
00265 std::cout << "<term>" << std::endl;
00266 std::cout << "<option>";
00267 std::cout << a->flagStartChar() << a->getFlag();
00268 std::cout << "</option>" << std::endl;
00269 std::cout << "</term>" << std::endl;
00270 }
00271
00272 std::cout << "<term>" << std::endl;
00273 std::cout << "<option>";
00274 std::cout << a->nameStartString() << a->getName();
00275 if ( a->isValueRequired() )
00276 {
00277 std::string arg = a->shortID();
00278 removeChar(arg,'[');
00279 removeChar(arg,']');
00280 removeChar(arg,'<');
00281 removeChar(arg,'>');
00282 arg.erase(0, arg.find_last_of(theDelimiter) + 1);
00283 std::cout << theDelimiter;
00284 std::cout << "<replaceable>" << arg << "</replaceable>";
00285 }
00286 std::cout << "</option>" << std::endl;
00287 std::cout << "</term>" << std::endl;
00288
00289 std::cout << "<listitem>" << std::endl;
00290 std::cout << "<para>" << std::endl;
00291 std::cout << desc << std::endl;
00292 std::cout << "</para>" << std::endl;
00293 std::cout << "</listitem>" << std::endl;
00294
00295 std::cout << "</varlistentry>" << std::endl;
00296 }
00297
00298 } //namespace TCLAP
00299 #endif