Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct vertical alignment for multi-line help message #248

Closed
fanurs opened this issue Dec 13, 2022 · 3 comments · Fixed by #268
Closed

Correct vertical alignment for multi-line help message #248

fanurs opened this issue Dec 13, 2022 · 3 comments · Fixed by #268

Comments

@fanurs
Copy link
Contributor

fanurs commented Dec 13, 2022

Issue

Currently, a multi-line help message would look something like:

Positional arguments:
  program_inputs        This is the first line of help text.
And this is the second line of help text. (MISALIGNED)

Optional arguments:
  -h, --help            shows help message and exits 
  -v, --version         prints version information and exits 

This is produced from the C++ code:

argparse::ArgumentParser program("program");
program.add_argument("program_inputs")
    .help(
        "This is the first line of help text.\n"
        "And this is the second line of help text."
    );

Expecting

Is it possible to make the multi-line help message aligns properly?

Positional arguments:
  program_inputs        This is the first line of help text.
                        And this is the second line of help text. (ALIGNED)

Optional arguments:
  -h, --help            shows help message and exits 
  -v, --version         prints version information and exits 

If not, is there a way, as a hack, to access the number of spaces needed to add prior to the second line of the help message?

Thank you.

@p-ranav
Copy link
Owner

p-ranav commented Dec 13, 2022

I am not aware of a hack but the relevant code is here and it wouldn't take much to implement support.

I'd imagine something like this:

const auto name_string = name_stream.str();
stream << name_string;

auto prefix = std::string(name_string.size(), ' ') + "\t";
auto first_line = true;
auto pos = 0;
auto prev = 0;
while ((pos = argument.m_help.find('\n', prev)) != std::string::npos) {
    auto line = argument.m_help.substr(prev, pos - prev);

    // Print nth line of help message

    if (first_line) {
        // First line
        first_line = false;
        stream << "\t" << line << "\n"; 
    } else {
        // Second, Third... (N-1)th line of help message
        stream << prefix << line << "\n";
    }
    prev = pos + 1;
}
if (first_line) {
    // Print first and only line of help if no '\n' in help message
    stream << "\t" << line;
} else {
    // Print last line of help message in a multi-line help
    stream << prefix << argument.m_help.substr(prev);  
}

I'm not sure if this will fail since I've not tested anything. But I'd be open to a PR with a clean and tested implementation.

@fanurs
Copy link
Contributor Author

fanurs commented Dec 14, 2022

Thanks for the quick and detailed reply. I will try working on a PR to support this feature / fix then.

@nmoreaud
Copy link

This doesn't seem to work for optional arguments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants