22 #ifndef GEARS_OPTPARSE_FORMATTER_HPP
23 #define GEARS_OPTPARSE_FORMATTER_HPP
25 #include "subcommand.hpp"
61 virtual std::string
wrap(
const std::string& str,
size_t indent = 0) {
68 std::string indentation(indent,
' ');
70 if(str.size() + indent > c) {
71 std::istringstream in(str);
75 size_t spaces = c - word.size() - indent;
77 if(spaces < word.size() + 1) {
78 result.append(1,
'\n').append(indent,
' ').append(word);
79 spaces = c - word.size() - indent;
82 result.append(1,
' ').append(word);
83 spaces -= word.size() + 1;
87 result.push_back(
'\n');
90 result.append(str).push_back(
'\n');
106 virtual std::string
usage(
const std::string& name,
const std::string& command,
const std::string& str) {
107 std::string result =
"usage: " + name;
108 if(!command.empty()) {
109 result.push_back(
' ');
112 result.push_back(
' ');
129 auto&& desc =
wrap(str);
131 desc.push_back(
'\n');
146 virtual std::string
epilogue(
const std::string& str) {
160 virtual std::string
subcommands(
const std::vector<subcommand>& subs) {
166 std::string out =
"subcommands\n";
169 return lhs.
name < rhs.name;
173 if(
max != subs.end()) {
174 indent +=
max->name.size();
177 for(
auto&& i : subs) {
178 out.append(4,
' ').append(i.name);
179 size_t current = indent - 4 - i.name.size();
180 out.append(current,
' ');
181 if(!i.help.empty()) {
182 out.append(
wrap(i.help, current));
219 std::string result =
"options:\n";
221 auto&& max_name = std::max_element(opts.
begin(), opts.
end(), [](
const option& lhs,
const option& rhs) {
222 return lhs.
name < rhs.name;
225 auto&& max_meta = std::max_element(opts.
begin(), opts.
end(), [](
const option& lhs,
const option& rhs) {
226 return lhs.
metavar() < rhs.metavar();
229 size_t max_indent = 14u;
231 if(max_name != opts.
end()) {
232 max_indent += max_name->name.size();
235 if(max_meta != opts.
end()) {
236 max_indent += 5u + max_meta->metavar().size();
239 for(
auto&& opt : opts) {
240 if((opt.flags & trait::hidden) == trait::hidden) {
244 size_t indent = max_indent;
245 const bool has_long_option = !opt.name.empty();
246 const bool has_short_option = opt.alias !=
'\0';
247 const std::string metavar = opt.metavar();
248 const bool has_metavar = !metavar.empty();
250 if(has_long_option && has_short_option) {
251 result.append(4,
' ').append(1,
'-').append(1, opt.alias).append(
", --").append(opt.name);
252 indent -= 10u + opt.name.size();
254 else if(has_long_option) {
255 result.append(4,
' ').append(
" --").append(opt.name);
256 indent -= 10u + opt.name.size();
258 else if(has_short_option) {
259 result.append(4,
' ').append(1,
'-').append(1, opt.alias);
264 if(has_long_option) {
265 result.append(
"[=<").append(metavar).append(
">]");
266 indent -= 5u + metavar.size();
269 result.append(1,
' ').append(1,
'<').append(metavar).append(1,
'>');
270 indent -= 3u + metavar.size();
274 result.append(indent,
' ');
276 if(opt.help.empty()) {
277 result.push_back(
'\n');
281 result.append(
wrap(opt.help, indent));
290 #endif // GEARS_OPTPARSE_FORMATTER_HPP