tclap  1.4.0
DocBookOutput.h
Go to the documentation of this file.
1 // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
2 
3 /******************************************************************************
4  *
5  * file: DocBookOutput.h
6  *
7  * Copyright (c) 2004, Michael E. Smoot
8  * Copyright (c) 2017, Google LLC
9  * All rights reserved.
10  *
11  * See the file COPYING in the top directory of this distribution for
12  * more information.
13  *
14  * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  *
22  *****************************************************************************/
23 
24 #ifndef TCLAP_DOC_BOOK_OUTPUT_H
25 #define TCLAP_DOC_BOOK_OUTPUT_H
26 
27 #include <tclap/Arg.h>
28 #include <tclap/CmdLineInterface.h>
29 #include <tclap/CmdLineOutput.h>
30 
31 #include <algorithm>
32 #include <iostream>
33 #include <list>
34 #include <string>
35 #include <vector>
36 
37 namespace TCLAP {
38 
43 class DocBookOutput : public CmdLineOutput {
44 public:
50  virtual void usage(CmdLineInterface &c);
51 
57  virtual void version(CmdLineInterface &c);
58 
65  virtual void failure(CmdLineInterface &c, ArgException &e);
66 
68 
69 protected:
76  void substituteSpecialChars(std::string &s, char r,
77  const std::string &x) const;
78  void removeChar(std::string &s, char r) const;
79 
80  void printShortArg(Arg *it, bool required);
81  void printLongArg(const ArgGroup &it) const;
82 
84 };
85 
87  std::cout << _cmd.getVersion() << std::endl;
88 }
89 
90 namespace internal {
91 const char *GroupChoice(const ArgGroup &group) {
92  if (!group.showAsGroup()) {
93  return "plain";
94  }
95 
96  if (group.isRequired()) {
97  return "req";
98  }
99 
100  return "opt";
101 }
102 } // namespace internal
103 
105  std::list<ArgGroup *> argSets = _cmd.getArgGroups();
106  std::string progName = _cmd.getProgramName();
107  std::string xversion = _cmd.getVersion();
108  theDelimiter = _cmd.getDelimiter();
109 
110  std::cout << "<?xml version='1.0'?>\n";
111  std::cout
112  << "<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.2//EN\"\n";
113  std::cout
114  << "\t\"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd\">\n\n";
115 
116  std::cout << "<refentry>\n";
117 
118  std::cout << "<refmeta>\n";
119  std::cout << "<refentrytitle>" << progName << "</refentrytitle>\n";
120  std::cout << "<manvolnum>1</manvolnum>\n";
121  std::cout << "</refmeta>\n";
122 
123  std::cout << "<refnamediv>\n";
124  std::cout << "<refname>" << progName << "</refname>\n";
125  std::cout << "<refpurpose>" << _cmd.getMessage() << "</refpurpose>\n";
126  std::cout << "</refnamediv>\n";
127 
128  std::cout << "<refsynopsisdiv>\n";
129  std::cout << "<cmdsynopsis>\n";
130 
131  std::cout << "<command>" << progName << "</command>\n";
132 
133  for (std::list<ArgGroup *>::iterator sit = argSets.begin();
134  sit != argSets.end(); ++sit) {
135  int visible = CountVisibleArgs(**sit);
136  if (visible > 1) {
137  std::cout << "<group choice='" << internal::GroupChoice(**sit)
138  << "'>\n";
139  }
140  for (ArgGroup::iterator it = (*sit)->begin(); it != (*sit)->end();
141  ++it) {
142  if (!(*it)->visibleInHelp()) {
143  continue;
144  }
145 
146  printShortArg(*it, (*it)->isRequired() ||
147  (visible == 1 && (**sit).isRequired()));
148  }
149  if (visible > 1) {
150  std::cout << "</group>\n";
151  }
152  }
153 
154  std::cout << "</cmdsynopsis>\n";
155  std::cout << "</refsynopsisdiv>\n";
156 
157  std::cout << "<refsect1>\n";
158  std::cout << "<title>Description</title>\n";
159  std::cout << "<para>\n";
160  std::cout << _cmd.getMessage() << '\n';
161  std::cout << "</para>\n";
162  std::cout << "</refsect1>\n";
163 
164  std::cout << "<refsect1>\n";
165  std::cout << "<title>Options</title>\n";
166 
167  std::cout << "<variablelist>\n";
168 
169  for (std::list<ArgGroup *>::iterator sit = argSets.begin();
170  sit != argSets.end(); ++sit) {
171  printLongArg(**sit);
172  }
173 
174  std::cout << "</variablelist>\n";
175  std::cout << "</refsect1>\n";
176 
177  std::cout << "<refsect1>\n";
178  std::cout << "<title>Version</title>\n";
179  std::cout << "<para>\n";
180  std::cout << xversion << '\n';
181  std::cout << "</para>\n";
182  std::cout << "</refsect1>\n";
183 
184  std::cout << "</refentry>" << std::endl;
185 }
186 
188  static_cast<void>(_cmd); // unused
189  std::cout << e.what() << std::endl;
190  throw ExitException(1);
191 }
192 
193 inline void DocBookOutput::substituteSpecialChars(std::string &s, char r,
194  const std::string &x) const {
195  size_t p;
196  while ((p = s.find_first_of(r)) != std::string::npos) {
197  s.erase(p, 1);
198  s.insert(p, x);
199  }
200 }
201 
202 inline void DocBookOutput::removeChar(std::string &s, char r) const {
203  size_t p;
204  while ((p = s.find_first_of(r)) != std::string::npos) {
205  s.erase(p, 1);
206  }
207 }
208 
209 inline void DocBookOutput::printShortArg(Arg *a, bool required) {
210  std::string lt = "&lt;";
211  std::string gt = "&gt;";
212 
213  std::string id = a->shortID();
214  substituteSpecialChars(id, '<', lt);
215  substituteSpecialChars(id, '>', gt);
216  removeChar(id, '[');
217  removeChar(id, ']');
218 
219  std::string choice = "opt";
220  if (required) {
221  choice = "plain";
222  }
223 
224  std::cout << "<arg choice='" << choice << '\'';
225  if (a->acceptsMultipleValues()) std::cout << " rep='repeat'";
226 
227  std::cout << '>';
228  if (!a->getFlag().empty())
229  std::cout << a->flagStartChar() << a->getFlag();
230  else
231  std::cout << a->nameStartString() << a->getName();
232  if (a->isValueRequired()) {
233  std::string arg = a->shortID();
234  removeChar(arg, '[');
235  removeChar(arg, ']');
236  removeChar(arg, '<');
237  removeChar(arg, '>');
238  removeChar(arg, '.');
239  arg.erase(0, arg.find_last_of(theDelimiter) + 1);
240  std::cout << theDelimiter;
241  std::cout << "<replaceable>" << arg << "</replaceable>";
242  }
243  std::cout << "</arg>" << std::endl;
244 }
245 
246 inline void DocBookOutput::printLongArg(const ArgGroup &group) const {
247  const std::string lt = "&lt;";
248  const std::string gt = "&gt;";
249 
250  bool forceRequired = group.isRequired() && CountVisibleArgs(group) == 1;
251  for (ArgGroup::const_iterator it = group.begin(); it != group.end(); ++it) {
252  Arg &a = **it;
253  if (!a.visibleInHelp()) {
254  continue;
255  }
256 
257  std::string desc = a.getDescription(forceRequired || a.isRequired());
258  substituteSpecialChars(desc, '<', lt);
259  substituteSpecialChars(desc, '>', gt);
260 
261  std::cout << "<varlistentry>\n";
262 
263  if (!a.getFlag().empty()) {
264  std::cout << "<term>\n";
265  std::cout << "<option>";
266  std::cout << a.flagStartChar() << a.getFlag();
267  std::cout << "</option>\n";
268  std::cout << "</term>\n";
269  }
270 
271  std::cout << "<term>\n";
272  std::cout << "<option>";
273  std::cout << a.nameStartString() << a.getName();
274  if (a.isValueRequired()) {
275  std::string arg = a.shortID();
276  removeChar(arg, '[');
277  removeChar(arg, ']');
278  removeChar(arg, '<');
279  removeChar(arg, '>');
280  removeChar(arg, '.');
281  arg.erase(0, arg.find_last_of(theDelimiter) + 1);
282  std::cout << theDelimiter;
283  std::cout << "<replaceable>" << arg << "</replaceable>";
284  }
285 
286  std::cout << "</option>\n";
287  std::cout << "</term>\n";
288 
289  std::cout << "<listitem>\n";
290  std::cout << "<para>\n";
291  std::cout << desc << '\n';
292  std::cout << "</para>\n";
293  std::cout << "</listitem>\n";
294 
295  std::cout << "</varlistentry>" << std::endl;
296  }
297 }
298 
299 } // namespace TCLAP
300 #endif // TCLAP_DOC_BOOK_OUTPUT_H
virtual bool isRequired() const =0
Returns true if this argument group is required.
void printLongArg(const ArgGroup &it) const
A virtual base class that defines the essential data for all arguments.
Definition: Arg.h:53
A simple class that defines and argument exception.
Definition: ArgException.h:36
virtual void usage(CmdLineInterface &c)
Prints the usage to stdout.
Thrown when TCLAP thinks the program should exit.
Definition: ArgException.h:178
void removeChar(std::string &s, char r) const
virtual std::string getMessage() const =0
Returns the message string.
const char * GroupChoice(const ArgGroup &group)
Definition: DocBookOutput.h:91
Container::iterator iterator
Definition: ArgGroup.h:44
virtual std::string shortID(const std::string &valueId="val") const
Returns a short ID for the usage.
Definition: Arg.h:485
The base class that manages the command line definition and passes along the parsing to the appropria...
virtual bool acceptsMultipleValues()
Use by output classes to determine whether an Arg accepts multiple values.
Definition: Arg.h:593
virtual std::list< ArgGroup * > getArgGroups()=0
Returns the list of ArgGroups.
int CountVisibleArgs(const ArgGroup &g)
Definition: ArgGroup.h:243
virtual void version(CmdLineInterface &c)
Prints the version to stdout.
Definition: DocBookOutput.h:86
virtual bool showAsGroup() const
If arguments in this group should show up as grouped in help.
Definition: ArgGroup.h:104
void printShortArg(Arg *it, bool required)
void substituteSpecialChars(std::string &s, char r, const std::string &x) const
Substitutes the char r for string x in string s.
virtual std::string getProgramName() const =0
Returns the program name string.
virtual char getDelimiter() const =0
Returns the delimiter string.
Definition: Arg.h:46
ArgGroup is the base class for implementing groups of arguments that are mutually exclusive (it repla...
Definition: ArgGroup.h:41
virtual std::string getVersion() const =0
Returns the version string.
A class that generates DocBook output for usage() method for the given CmdLine and its Args...
Definition: DocBookOutput.h:43
virtual void failure(CmdLineInterface &c, ArgException &e)
Prints (to stderr) an error message, short usage Can be overridden to produce alternative behavior...
const char * what() const
Returns the arg id and error text.
Definition: ArgException.h:76
The interface that any output object must implement.
Definition: CmdLineOutput.h:45