plumbum
plumbum copied to clipboard
Display help message in multi-line format?
Way to reproduce
python multi_line.py -h
multi_line.py
#!/usr/bin/env python
from plumbum import cli
class TopupEddyEpi(cli.Application):
'''Epi and eddy correction using topup and eddy_openmp/cuda commands in fsl
For more info, see:
https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/eddy/UsersGuide
https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/topup/TopupUsersGuide
You can also view the help message:
`eddy_openmp` or `eddy_cuda`
`topup`
'''
dwi_file= cli.SwitchAttr(
['--imain'],
help='''--imain primary4D,secondary4D/3D
primary: one 4D volume input, should be PA;
secondary: another 3D/4D volume input, should be AP, which is opposite of primary 4D volume''',
mandatory=True)
def main():
pass
if __name__== '__main__':
TopupEddyEpi.run()
Expected
As I wrote in the program:
--imain VALUE:str primary4D,secondary4D/3D
primary: one 4D volume input, should be PA;
secondary: another 3D/4D volume input, should be AP, which is opposite of primary 4D volume
Actual
Spanning across my terminal in an untidy way:
--imain VALUE:str --imain primary4D,secondary4D/3D primary: one 4D volume input, should be PA; secondary: another 3D/4D
volume input, should be AP, which is opposite of primary 4D volume; required
Is the expected at all possible?
According to the code which handles it, it seems it does not assume multiline help messages:
https://github.com/tomerfiliba/plumbum/blob/3876425a04f934667e1f91ba88f526ca6976dbd8/plumbum/cli/application.py#L930-L953
Probably could be fixed, PR welcome.
@henryiii @tashrifbillah here's what I've come up with. I could do the PR but ETA is unspecified (otherwise let someone go ahead)
first, let's split the text by line breaks:
>>> text = "This is first paragraph, of average length.\n" \
... "And this is the second one.\n" \
... "That's the longest paragraph, you can see it yourself."
>>> stext = text.splitlines()
>>> stext
['This is first paragraph, of average length.', 'And this is the second one.', "That's the longest paragraph, you can see it yourself."]
now, wrap the previous stage' result using TextWrapper
(with width=15
for demo purpose):
>>> stext=text.splitlines()
>>> list(map(TextWrapper(width=15).wrap, stext))
[['This is first', 'paragraph, of', 'average length.'], ['And this is the', 'second one.'], ["That's the", 'longest', 'paragraph, you', 'can see it', 'yourself.']]
finally, lets create wrap() function which will also flatten the list and join it using specified indent:
>>> from textwrap import TextWrapper
>>> from typing import List
>>>
>>>
>>> def wrap(text: str, max_width: int, indent_size: int = 4):
... indent=' ' * indent_size
... return '\n'.join([
... line for lst in map(
... TextWrapper(width=max_width,
... initial_indent=indent,
... subsequent_indent=indent).wrap,
... text.splitlines()
... )
... for line in lst
... ])
...
>>>
>>> text = """
... This is first paragraph, of average length.\n
... And this is the second one.\n
... That's the longest paragraph, you can see it yourself.
... """
>>>
>>> print(wrap(text, max_width=15), '\n')
This is
first
paragraph,
of average
length.
And this is
the second
one.
That's the
longest
paragraph,
you can see
it
yourself.
>>> print(wrap(text, max_width=80, indent_size=8))
This is first paragraph, of average length.
And this is the second one.
That's the longest paragraph, you can see it yourself.
Hi, I shall try to do it myself. I have marked the email notification.
Hi @ink-splatters , sorry about the delay--the idea that you came up with, should it be inserted before line 931?
I inserted this block:
# break and join multi-line help message
max_width= 200
indent_size= 8
indent=' ' * indent_size
help= '\n'.join([
line for lst in map(
TextWrapper(width=max_width,
initial_indent=indent,
subsequent_indent=indent).wrap,
help.splitlines()
)
for line in lst
])
after line 931 but no effect. I believe this block joins them back together :(
https://github.com/tomerfiliba/plumbum/blob/0c574a99ef0a2419c2490db86bc8180e249c91a6/plumbum/cli/application.py#L945-L947
Replacing the latter block with msg= help
gets me the following:
Switches:
--imain VALUE:str --imain primary4D,secondary4D/3D
primary: one 4D volume input, should be PA;
secondary: another 3D/4D volume input, should be AP, which is opposite of primary 4D volume; required
I see that the second and third lines of my help message do not follow the indent of first line but it is some progress :) Please let me know how we can improve upon it.
Hi @ink-splatters , sorry about the delay--the idea that you came up with, should it be inserted before line 931?
Hi @tashrifbillah, I was completely incapable to answer on time, sorry for that, as well as contributing more, by personal reasons. It will likely change, probably soon.
Thanks a lot