24 namespace seqan3::detail
37 class format_help :
public format_help_base<format_help>
40 using base_type = format_help_base<format_help>;
48 format_help() =
default;
49 format_help(format_help
const & pf) =
default;
50 format_help & operator=(format_help
const &) =
default;
51 format_help(format_help &&) =
default;
52 format_help & operator=(format_help &&) =
default;
53 ~format_help() =
default;
56 format_help(std::vector<std::string>
const & names,
bool const advanced =
false) : base_type{names,
advanced}
63 struct console_layout_struct
68 uint32_t defaultScreenWidth;
70 uint32_t maximalScreenWidth;
72 uint32_t minimalScreenWidth;
76 uint32_t centerPadding;
78 uint32_t rightPadding;
80 uint32_t leftColumnWidth;
82 uint32_t rightColumnWidth;
84 uint32_t rightColumnTab;
88 console_layout_struct(uint32_t
const terminal_width) :
89 screenWidth{0}, defaultScreenWidth{80}, maximalScreenWidth{120}, minimalScreenWidth{40},
90 leftPadding{4}, centerPadding{2}, rightPadding{2}, leftColumnWidth{4}, rightColumnWidth{0}
93 screenWidth = (terminal_width > 0) ? terminal_width : defaultScreenWidth;
94 screenWidth = std::max(screenWidth, minimalScreenWidth);
95 screenWidth = std::min(screenWidth, maximalScreenWidth);
96 screenWidth -= rightPadding;
98 rightColumnWidth = screenWidth - leftPadding - leftColumnWidth - centerPadding - rightPadding;
99 rightColumnTab = leftPadding + leftColumnWidth + centerPadding;
103 console_layout_struct() : console_layout_struct{get_terminal_width()} {}
109 std::ostream_iterator<char> out(std::cout);
111 std::cout << meta.app_name;
112 if (!empty(meta.short_description))
113 std::cout <<
" - " << meta.short_description;
116 unsigned len = text_width(meta.app_name) + (empty(meta.short_description) ? 0 : 3) +
117 text_width(meta.short_description);
118 std::fill_n(out, len,
'=');
125 void print_section(std::string
const & title)
127 std::ostream_iterator<char> out(std::cout);
128 std::cout <<
'\n' << to_text(
"\\fB");
129 std::transform(title.begin(), title.end(), out, [] (
unsigned char c) { return std::toupper(c); });
130 std::cout << to_text(
"\\fP") <<
'\n';
131 prev_was_paragraph =
false;
137 void print_subsection(std::string
const & title)
139 std::ostream_iterator<char> out(std::cout);
141 std::fill_n(out, layout.leftPadding / 2,
' ');
142 std::cout << in_bold(title) <<
'\n';
143 prev_was_paragraph =
false;
151 void print_line(std::string
const & text,
bool const line_is_paragraph)
153 if (prev_was_paragraph)
156 std::ostream_iterator<char> out(std::cout);
157 std::fill_n(out, layout.leftPadding,
' ');
158 print_text(text, layout.leftPadding);
159 prev_was_paragraph = line_is_paragraph;
176 void print_list_item(std::string
const & term, std::string
const & desc)
178 if (prev_was_paragraph)
181 std::ostream_iterator<char> out(std::cout);
184 std::fill_n(out, layout.leftPadding,
' ');
185 std::cout << to_text(term);
186 unsigned pos = layout.leftPadding + term.size();
187 if (pos + layout.centerPadding > layout.rightColumnTab)
192 std::fill_n(out, layout.rightColumnTab - pos,
' ');
193 print_text(desc, layout.rightColumnTab);
195 prev_was_paragraph =
false;
207 std::string to_text(std::string
const & str)
211 for (
auto it = str.begin(); it != str.end(); ++it)
217 assert(it != str.end());
220 result.push_back(*it);
225 assert(it != str.end());
229 result.append(
"\033[4m");
234 result.append(
"\033[1m");
239 result.append(
"\033[0m");
243 result.append(
"\\f");
244 result.push_back(*it);
249 result.push_back(
'\\');
250 result.push_back(*it);
255 result.push_back(*it);
266 unsigned text_width(std::string
const & text)
270 for (
unsigned i = 0; i < text.size(); ++i)
278 if (i + 1 == text.size())
284 if (text[i + 1] ==
'\\' || text[i + 1] ==
'-')
291 if (i + 2 == text.size())
298 if (text[i + 1] ==
'f')
300 if (text[i + 2] ==
'B' || text[i + 2] ==
'I' || text[i + 2] ==
'P')
314 void print_text(std::string
const & text,
unsigned const tab)
317 std::ostream_iterator<char> out(std::cout);
320 std::istringstream iss(text.c_str());
321 std::vector<std::string> tokens;
322 std::ranges::copy(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(),
323 std::cpp20::back_inserter(tokens));
327 std::fill_n(out, tab - pos,
' ');
330 typedef std::vector<std::string>::const_iterator TConstIter;
331 for (TConstIter it = tokens.begin(); it != tokens.end(); ++it)
333 if (it == tokens.begin())
335 std::cout << to_text(*it);
336 pos += text_width(*it);
337 if (pos > layout.screenWidth)
340 std::fill_n(out, tab,
' ');
346 if (pos + 1 + text_width(*it) > layout.screenWidth)
350 fill_n(out, tab,
' ');
351 std::cout << to_text(*it);
352 pos = tab + text_width(*it);
357 std::cout << to_text(*it);
358 pos += text_width(*it) + 1;
370 std::string in_bold(std::string
const & str)
372 return to_text(
"\\fB") + str + to_text(
"\\fP");
376 bool prev_was_paragraph{
false};
379 friend struct ::seqan3::detail::test_accessor;
382 console_layout_struct layout{};
394 class format_short_help :
public format_help
400 void parse(argument_parser_meta_data
const & parser_meta)
406 if (!parser_meta.synopsis.empty())
409 print_line(
"Try -h or --help for more information.\n",
true);
411 std::exit(EXIT_SUCCESS);
424 class format_version :
public format_help
430 void parse(argument_parser_meta_data & parser_meta)
437 std::exit(EXIT_SUCCESS);
450 class format_copyright :
public format_help
456 void parse(argument_parser_meta_data
const & parser_meta)
459 debug_stream_type stream{std::cout};
460 std::string seqan_license{
461 R
"(Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
462 Copyright (c) 2016-2021, Knut Reinert & MPI für molekulare Genetik
465 Redistribution and use in source and binary forms, with or without
466 modification, are permitted provided that the following conditions are met:
468 * Redistributions of source code must retain the above copyright
469 notice, this list of conditions and the following disclaimer.
470 * Redistributions in binary form must reproduce the above copyright
471 notice, this list of conditions and the following disclaimer in the
472 documentation and/or other materials provided with the distribution.
473 * Neither the name of Knut Reinert or the FU Berlin nor the names of
474 its contributors may be used to endorse or promote products derived
475 from this software without specific prior written permission.
477 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
478 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
479 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
480 ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
481 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
482 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
483 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
484 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
485 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
486 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
489 stream << std::string(80, '=') <<
"\n"
490 << in_bold(
"Copyright information for " + meta.app_name +
":\n")
491 << std::string(80,
'-') <<
'\n';
493 if (!empty(meta.long_copyright))
495 stream << to_text(
"\\fP") << meta.long_copyright <<
"\n";
497 else if (!empty(meta.short_copyright))
499 stream << in_bold(meta.app_name +
" full copyright information not available. " +
500 "Displaying short copyright information instead:\n" )
501 << meta.short_copyright <<
"\n";
505 stream << to_text(
"\\fP") << meta.app_name <<
" copyright information not available.\n";
508 stream << std::string(80,
'=') <<
'\n'
509 << in_bold(
"This program contains SeqAn code licensed under the following terms:\n")
510 << std::string(80,
'-') <<
'\n' << seqan_license <<
'\n';
512 std::exit(EXIT_SUCCESS);
@ advanced
Definition: auxiliary.hpp:245
decltype(detail::transform< trait_t >(list_t{})) transform
Apply a transformation trait to every type in the list and return a seqan3::type_list of the results.
Definition: traits.hpp:471
Checks if program is run interactively and retrieves dimensions of terminal (Transferred from seqan2)...
Forward declares seqan3::detail::test_accessor.