Sharg 1.2.3-rc.1
The argument parser for bio-c++ tools.
Loading...
Searching...
No Matches
format_help.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2026, Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2026, Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
12#pragma once
13
17
18namespace sharg::detail
19{
20
33class format_help : public format_help_base<format_help>
34{
37
39 friend base_type;
40
41public:
45 format_help() = default;
46 format_help(format_help const & pf) = default;
47 format_help & operator=(format_help const &) = default;
48 format_help(format_help &&) = default;
50 ~format_help() = default;
51
54 update_notifications const version_updates,
55 bool const advanced = false) :
56 base_type{names, version_updates, advanced} {};
58
59protected:
112
115 {
117
119 if (!empty(meta.short_description))
120 std::cout << " - " << meta.short_description;
121
122 std::cout << "\n";
123 unsigned len =
125 std::fill_n(out, len, '=');
126 std::cout << '\n';
127 }
128
132 void print_section(std::string const & title)
133 {
134 std::cout << '\n' << to_text("\\fB");
135 print_as_uppercase(title);
136 std::cout << to_text("\\fP") << '\n';
137 prev_was_paragraph = false;
138 }
139
143 void print_subsection(std::string const & title)
144 {
146 std::cout << '\n';
147 std::fill_n(out, layout.leftPadding / 2, ' ');
148 std::cout << in_bold(title) << '\n';
149 prev_was_paragraph = false;
150 }
151
157 void print_line(std::string const & text, bool const line_is_paragraph)
158 {
160 std::cout << '\n';
161
163 std::fill_n(out, layout.leftPadding, ' ');
165 prev_was_paragraph = line_is_paragraph;
166 }
167
182 void print_list_item(std::string const & term, std::string const & desc)
183 {
185 std::cout << '\n';
186
188
189 // Print term.
190 std::fill_n(out, layout.leftPadding, ' ');
191 std::cout << to_text(term);
192 unsigned pos = layout.leftPadding + text_width(term);
194 {
195 std::cout << '\n';
196 pos = 0;
197 }
198 if (!desc.empty())
199 {
200 std::fill_n(out, layout.rightColumnTab - pos, ' ');
202 }
203
204 prev_was_paragraph = false;
205 }
206
209 {
210 // no footer
211 }
212
217 {
218 std::string result;
219
220 for (auto it = str.begin(); it != str.end(); ++it)
221 {
222 if (*it == '\\')
223 {
224 // Handle escape sequence, we interpret only "\-", "\fI", and "\fB".
225 ++it;
226 assert(it != str.end());
227 if (*it == '-')
228 {
229 result.push_back(*it);
230 }
231 else if (*it == 'f')
232 {
233 ++it;
234 assert(it != str.end());
235 if (*it == 'I')
236 {
237 if (stdout_is_terminal())
238 result.append("\033[4m");
239 }
240 else if (*it == 'B')
241 {
242 if (stdout_is_terminal())
243 result.append("\033[1m");
244 }
245 else if (*it == 'P')
246 {
247 if (stdout_is_terminal())
248 result.append("\033[0m");
249 }
250 else
251 {
252 result.append("\\f");
253 result.push_back(*it);
254 }
255 }
256 else
257 {
258 result.push_back('\\');
259 result.push_back(*it);
260 }
261 }
262 else
263 {
264 result.push_back(*it);
265 }
266 }
267
268 return result;
269 }
270
275 unsigned text_width(std::string const & text)
276 {
277 unsigned result = 0;
278
279 for (unsigned i = 0; i < text.size(); ++i)
280 {
281 if (text[i] != '\\')
282 {
283 result += 1;
284 continue;
285 }
286
287 if (i + 1 == text.size())
288 {
289 result += 1; // Will print "\\".
290 continue;
291 }
292
293 if (text[i + 1] == '\\' || text[i + 1] == '-')
294 {
295 i += 1;
296 result += 1;
297 continue; // Will print '\\' or '-'.
298 }
299
300 if (i + 2 == text.size())
301 {
302 i += 1;
303 result += 2; // Will print two chars.
304 continue;
305 }
306
307 if (text[i + 1] == 'f')
308 {
309 if (text[i + 2] == 'B' || text[i + 2] == 'I' || text[i + 2] == 'P')
310 i += 2; // Skip f and {B, I, P}.
311 else
312 result += 1;
313 }
314 }
315
316 return result;
317 }
318
323 void print_text(std::string const & text, unsigned const tab)
324 {
325 unsigned pos = tab;
327
328 // Tokenize the text.
329 std::istringstream iss(text.c_str());
331
332 // Print the text.
333 assert(pos <= tab);
334 std::fill_n(out, tab - pos, ' '); // go to tab
335
336 pos = tab;
337 for (auto it = tokens.begin(); it != tokens.end(); ++it)
338 {
339 if (it == tokens.begin())
340 {
341 std::cout << to_text(*it);
342 pos += text_width(*it);
343 if (pos > layout.screenWidth)
344 {
345 std::cout << '\n';
346 std::fill_n(out, tab, ' ');
347 pos = tab;
348 }
349 }
350 else
351 {
352 if (pos + 1 + text_width(*it) > layout.screenWidth)
353 {
354 // Would go over screen with next, print current word on next line.
355 std::cout << '\n';
356 fill_n(out, tab, ' ');
357 std::cout << to_text(*it);
358 pos = tab + text_width(*it);
359 }
360 else
361 {
362 std::cout << ' ';
363 std::cout << to_text(*it);
364 pos += text_width(*it) + 1;
365 }
366 }
367 }
368 if (!empty(tokens))
369 std::cout << '\n';
370 }
371
377 {
378 return to_text("\\fB") + str + to_text("\\fP");
379 }
380
383
385 friend struct ::sharg::detail::test_accessor;
386
389};
390
403{
404public:
410 void parse(parser_meta_data const & parser_meta, std::vector<std::string> const & executable_name)
411 {
412 meta = parser_meta;
413
414 print_header();
415
416 if (meta.synopsis.empty())
417 generate_default_synopsis(executable_name);
418
419 // Synopsis can be disabled by setting `parser.info.synopsis = {""};`
420 if (!meta.synopsis.empty() && !meta.synopsis.front().empty())
422
423 print_line("Try -h or --help for more information.\n", true);
424 }
425};
426
439{
440public:
444 void parse(parser_meta_data & parser_meta, std::vector<std::string> const & /*executable_name*/)
445 {
446 meta = parser_meta;
447
448 print_header();
450 }
451};
452
465{
466public:
470 void parse(parser_meta_data const & parser_meta, std::vector<std::string> const & /*executable_name*/)
471 {
472 meta = parser_meta;
473 std::string seqan_license{
474 R"(Copyright (c) 2006-2026, Knut Reinert & Freie Universität Berlin
475Copyright (c) 2016-2026, Knut Reinert & MPI für molekulare Genetik
476All rights reserved.
477
478Redistribution and use in source and binary forms, with or without
479modification, are permitted provided that the following conditions are met:
480
481 * Redistributions of source code must retain the above copyright
482 notice, this list of conditions and the following disclaimer.
483 * Redistributions in binary form must reproduce the above copyright
484 notice, this list of conditions and the following disclaimer in the
485 documentation and/or other materials provided with the distribution.
486 * Neither the name of Knut Reinert or the FU Berlin nor the names of
487 its contributors may be used to endorse or promote products derived
488 from this software without specific prior written permission.
489
490THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
491AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
492IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
493ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
494FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
495DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
496SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
497CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
498LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
499OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
500DAMAGE.)"};
501
502 std::cout << std::string(80, '=') << "\n"
503 << in_bold("Copyright information for " + meta.app_name + ":\n") << std::string(80, '-') << '\n';
504
505 if (!empty(meta.long_copyright))
506 {
507 std::cout << to_text("\\fP") << meta.long_copyright << "\n";
508 }
509 else if (!empty(meta.short_copyright))
510 {
511 std::cout << in_bold(meta.app_name + " full copyright information not available. "
512 + "Displaying short copyright information instead:\n")
513 << meta.short_copyright << "\n";
514 }
515 else
516 {
517 std::cout << to_text("\\fP") << meta.app_name << " copyright information not available.\n";
518 }
519
520 std::cout << std::string(80, '=') << '\n'
521 << in_bold("This program contains SeqAn code licensed under the following terms:\n")
522 << std::string(80, '-') << '\n'
523 << seqan_license << '\n';
524 }
525};
526
527} // namespace sharg::detail
T append(T... args)
T begin(T... args)
T c_str(T... args)
static void print_as_uppercase(std::string const &str)
Prints a string to std::cout converted to uppercase.
Definition format_base.hpp:301
The format that contains all helper functions needed in all formats for printing the interface descri...
Definition format_base.hpp:319
parser_meta_data meta
Stores all meta information about the application.
Definition format_base.hpp:601
void print_synopsis()
Prints a synopsis in any format.
Definition format_base.hpp:617
void generate_default_synopsis(std::vector< std::string > executable_name)
Generates default synopsis from stored elements.
Definition format_base.hpp:716
void print_version()
Prints the version information.
Definition format_base.hpp:640
The format that prints the help page to std::cout.
Definition format_help.hpp:34
format_help(std::vector< std::string > const &names, update_notifications const version_updates, bool const advanced=false)
Defaulted.
Definition format_help.hpp:53
unsigned text_width(std::string const &text)
Returns width of text if printed.
Definition format_help.hpp:275
format_help(format_help const &pf)=default
Defaulted.
bool prev_was_paragraph
Needed for correct formatting while calling different print functions.
Definition format_help.hpp:382
void print_header()
Prints a help page header to std::cout.
Definition format_help.hpp:114
void print_section(std::string const &title)
Prints a help page section to std::cout.
Definition format_help.hpp:132
format_help & operator=(format_help const &)=default
Defaulted.
std::string to_text(std::string const &str)
Formats text for pretty command line printing.
Definition format_help.hpp:216
console_layout_struct layout
Stores the relevant parameters of the documentation on the screen.
Definition format_help.hpp:388
void print_line(std::string const &text, bool const line_is_paragraph)
Prints a text to std::cout.
Definition format_help.hpp:157
std::string in_bold(std::string const &str)
Format string in bold.
Definition format_help.hpp:376
format_help & operator=(format_help &&)=default
Defaulted.
~format_help()=default
Defaulted.
void print_list_item(std::string const &term, std::string const &desc)
Prints a help page list_item to std::cout.
Definition format_help.hpp:182
format_help(format_help &&)=default
Defaulted.
void print_subsection(std::string const &title)
Prints a help page subsection to std::cout.
Definition format_help.hpp:143
friend base_type
Befriend the base class to give access to the private member functions.
Definition format_help.hpp:39
format_help()=default
Defaulted.
void print_footer()
Prints a help page footer to std::cout.
Definition format_help.hpp:208
void print_text(std::string const &text, unsigned const tab)
Prints text with correct line wrapping to the command line (std::cout).
Definition format_help.hpp:323
The format that prints a short help message to std::cout.
Definition format_help.hpp:403
void parse(parser_meta_data const &parser_meta, std::vector< std::string > const &executable_name)
Initiates the printing of a short help message to std::cout.
Definition format_help.hpp:410
The format that prints the version to std::cout.
Definition format_help.hpp:439
void parse(parser_meta_data &parser_meta, std::vector< std::string > const &)
Initiates the printing of the version information to std::cout.
Definition format_help.hpp:444
T empty(T... args)
T end(T... args)
T fill_n(T... args)
Provides the format_base struct containing all helper functions that are needed in all formats.
T front(T... args)
update_notifications
Indicates whether application allows automatic update notifications by the sharg::parser.
Definition auxiliary.hpp:27
bool stdout_is_terminal()
Check whether the standard output is interactive.
Definition terminal.hpp:48
unsigned get_terminal_width()
Retrieve size of terminal.
Definition terminal.hpp:86
T is_same_v
T max(T... args)
T min(T... args)
T push_back(T... args)
T size(T... args)
Stores the relevant parameters of the documentation on the screen.
Definition format_help.hpp:63
uint32_t rightColumnWidth
The right Column Width.
Definition format_help.hpp:81
uint32_t rightPadding
The right Padding.
Definition format_help.hpp:77
uint32_t screenWidth
The screen width.
Definition format_help.hpp:65
console_layout_struct()
The default constructor.
Definition format_help.hpp:109
uint32_t rightColumnTab
The right Column Tab.
Definition format_help.hpp:83
uint32_t defaultScreenWidth
The default screen width.
Definition format_help.hpp:67
uint32_t leftPadding
The left Padding.
Definition format_help.hpp:73
uint32_t maximalScreenWidth
The maximal screen width.
Definition format_help.hpp:69
uint32_t leftColumnWidth
The left Column Width.
Definition format_help.hpp:79
uint32_t minimalScreenWidth
The minimal screen width.
Definition format_help.hpp:71
uint32_t centerPadding
The center Padding.
Definition format_help.hpp:75
console_layout_struct(uint32_t const terminal_width)
The constructor.
Definition format_help.hpp:87
Stores all parser related meta information of the sharg::parser.
Definition auxiliary.hpp:99
std::string short_description
A short description of the application (e.g. "A tool for mapping reads to the genome").
Definition auxiliary.hpp:111
std::string app_name
The application name that will be displayed on the help page.
Definition auxiliary.hpp:105
std::vector< std::string > synopsis
Add lines of usage to the synopsis section of the help page (e.g. "./my_read_mapper [OPTIONS] FILE1 F...
Definition auxiliary.hpp:156
std::string long_copyright
Detailed copyright information that will be displayed when the user specifies "--copyright" on the co...
Definition auxiliary.hpp:133
std::string short_copyright
Brief copyright (and/or license) information.
Definition auxiliary.hpp:128
Checks if program is run interactively and retrieves dimensions of terminal (Transferred from seqan2)...
Forward declares sharg::detail::test_accessor.
Hide me