python click help formatting newline
Asked Answered
H

2

16

I am seeing that a newline is not being preserved in my EPILOG? I want to know why if I see that newline remains only when a line has 74 characters?

# http://click.pocoo.org/5/commands/

import click, sys

def main_caller(*args, **kwargs):
    print('act on arguments', args, kwargs)

EPILOG = '''
# oneline
# twoline

\n
# oneline with 74char                                                   x
# twoline with 74char                                                   x
'''

@click.group(help='wwwwwwwwww', epilog=EPILOG, invoke_without_command=True, chain=True)
@click.argument('start_or_stop')
@click.option('-v', '--verbose', default=False, help='Print Verbose messages')
@click.option('-l', '--logfile', help='Path to logfile to store log messages')
@click.option('-a', '--action', multiple=True, type=click.Choice(['act1', 'act2', 'act3']), default=['act1', 'act2'])
def cli(*args, **kwargs):
    '''foo bar'''
    pass

@cli.command()
@click.option('--debug/--no-debug', default=False)
def cmd1(*args, **kwargs):
    print('cmd1', args, kwargs)
    return 'cmd11111'

@cli.command()
@click.option('-x', '--xxx', default='x')
def cmd2(*args, **kwargs):
    print('cmd2', args, kwargs)
    return 'cmd22222'

@cli.resultcallback()
def process_pipeline(*args, **kwargs):
    print('process', args, kwargs)
    print('args', sys.argv[1:])     

if __name__ == '__main__':
    cli()

Output is:

/click_sandbox.py --help
2017/02/24 19:31:43 Platform overridden to 'RHEL5_64'
Usage: click_sandbox.py [OPTIONS] START_OR_STOP COMMAND1 [ARGS]... [COMMAND2
                        [ARGS]...]...

  wwwwwwwwww

Options:
  -v, --verbose TEXT             Print Verbose messages
  -l, --logfile TEXT             Path to logfile to store log messages
  -a, --action [act1|act2|act3]
  --help                         Show this message and exit.

Commands:
  cmd1
  cmd2

  # oneline # twoline

  # oneline with 74char                                                   x
  # twoline with 74char                                                   x
Halfandhalf answered 24/2, 2017 at 19:36 Comment(0)
C
5

Your newlines are not being preserved because the epilog writer does word wrapping. This can be solved with a subclass to click.Group, by creating a format_epilog() which does not do word wrapping:

class SpecialEpilog(click.Group):
    def format_epilog(self, ctx, formatter):
        if self.epilog:
            formatter.write_paragraph()
            for line in self.epilog.split('\n'):
                formatter.write_text(line)

# Tell click to use our epilog formatter
@click.group(cls=SpecialEpilog,
    help='wwwwwwwwww', epilog=EPILOG, invoke_without_command=True, chain=True)
....
Catalyst answered 27/2, 2017 at 15:32 Comment(4)
This works so long as EPILOG has printable characters, if I put just a couple of newlines ('\n\n\n') it does nothing unless I anchor them with a printable character. Any ideas how to modify the above to tack a couple of newlines in a similar manner?Bina
@slm, Great question. Not a use case I had considered. Looking through the framework, the answer appears to be yes, but it will involve more overrides. If you pop up a question , I will gladly type up an answer.Catalyst
@StephenRauch - sure thing, been wrestling w/ this the last few days and didn't see a a way to accomplish it easily (I'm new to Python).Bina
@StephenRauch - #44125180Bina
A
31

In Click 7.0 you use the \b marker to indicate that the formatting is to be preserved e.g.:

This paragraph is formatted normally and Click does
not preserve new lines.

\b
This paragraph is formatted as it
appears in the source:
item 1
item 2

This paragraph is formatted normally and Click does
not preserve new lines.

From the official documentation:

Rewrapping can be disabled on a per-paragraph basis by adding a line with solely the \b escape marker in it. This line will be removed from the help text and rewrapping will be disabled.

Appellant answered 14/11, 2018 at 14:31 Comment(4)
From the docs, this feature appears to be available in all versions.Engaging
From experiments with Click 7.0, it seems the sequence needed in a help text to trigger this is '\b\n', i.e. backspace followed by newline.Ernie
@AndreasMaier - prepending my help string with \b\n prevented re-wrapping. thanks!Muro
Link to click rewrapping discussed here: click.palletsprojects.com/en/8.0.x/documentation/…Mota
C
5

Your newlines are not being preserved because the epilog writer does word wrapping. This can be solved with a subclass to click.Group, by creating a format_epilog() which does not do word wrapping:

class SpecialEpilog(click.Group):
    def format_epilog(self, ctx, formatter):
        if self.epilog:
            formatter.write_paragraph()
            for line in self.epilog.split('\n'):
                formatter.write_text(line)

# Tell click to use our epilog formatter
@click.group(cls=SpecialEpilog,
    help='wwwwwwwwww', epilog=EPILOG, invoke_without_command=True, chain=True)
....
Catalyst answered 27/2, 2017 at 15:32 Comment(4)
This works so long as EPILOG has printable characters, if I put just a couple of newlines ('\n\n\n') it does nothing unless I anchor them with a printable character. Any ideas how to modify the above to tack a couple of newlines in a similar manner?Bina
@slm, Great question. Not a use case I had considered. Looking through the framework, the answer appears to be yes, but it will involve more overrides. If you pop up a question , I will gladly type up an answer.Catalyst
@StephenRauch - sure thing, been wrestling w/ this the last few days and didn't see a a way to accomplish it easily (I'm new to Python).Bina
@StephenRauch - #44125180Bina

© 2022 - 2024 — McMap. All rights reserved.