0

I am writing a small console application. This app should print a help when -h is passed. This is what I'm trying to get:

Program that prints help.
Usage:
  prg [OPTIONS]

Options:
  -h - print help.
  -x - some very very very very very very very very very very very very very very
       very very very very long parameter description.
  -y - another  very very very very very very very very very very very very very
       very very very very long parameter description.

I'm using echo. -x - {long description here} to print parameter description. And of course when the string is too long it is printed like this:

           -x - some very very very very very very very very very very very very
very very very very long parameter description.

So the question is how can I print a long string with something like left border specified?

Evgeny
  • 92
  • 1
  • 7

3 Answers3

1
@ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION 
for /f %%I in ('powershell ^(Get-Host^).UI.RawUI.WindowSize.width') do set width=%%I
SET "spaces= "
:splp
IF "!spaces:~%width%!"=="" SET spaces=%spaces%%spaces%&GOTO splp

CALL :display 0 "Program that prints help."
CALL :display 0 "Usage:"
CALL :display 2 "prg [OPTIONS]"
CALL :display 0
CALL :display 0 "Options:"
CALL :display 2 "-x" 5 "- some very very very very very very very very very very very very very very very very very very long parameter description."
CALL :display 2 "-y" 5 "- another  very very very very very very very very very very very very very very very very very long parameter description."

GOTO :EOF

:display
SET "remainder="
SET "line=!spaces:~0,%1!"
IF "%~2"=="" GOTO write
IF "%3"=="" SET "line=%line%%~2"&GOTO write
SET /a indent=%1+%3
SET "remainder=%~2%spaces%"
SET "line=%line%!remainder:~0,%3!
SET "remainder=%~4"
:remainlp
SET /a eol=width-indent-1
:seteollp
SET "eolchar=!remainder:~%eol%,1!"
IF NOT DEFINED eolchar SET "line=%line%%remainder%"&set "remainder="&goto write
IF NOT "%eolchar%"==" " set /a eol-=1&GOTO seteollp
SET "line=%line%!remainder:~0,%eol%!
SET /a eol+=1
set "remainder=!remainder:~%eol%!"
:write
ECHO(%line%
IF NOT DEFINED remainder GOTO :EOF
SET "line=!spaces:~0,%indent%!"
GOTO remainlp

I'll claim no originality for the magic powershell line - it came from Rojo's response here

Community
  • 1
  • 1
Magoo
  • 77,302
  • 8
  • 62
  • 84
  • Spent about half of an hour to understand how this script works. But this is definitly what I was looking for. The only question I have is is there any requirements for running the powershell string? I mean will it be working on any windows machine? – Evgeny Jul 25 '14 at 06:23
  • AFAIAA, it should work on any machine where powershell can be executed. – Magoo Jul 25 '14 at 13:40
0

Have you tried using tabs?

For example:

echo.^     -x - some very very very very very very very very very very
echo.^  ^   very very very very very very very 
echo.^  ^   very long parameter description.

I've used the '^' character to show where the tabs are and had to split the message over a few lines to stop the word wrapping.

Here is the script I just tried (option x uses tabs and option y does not)

@echo OFF

echo.   Usage:
echo.       prg [OPTIONS]
echo.
echo.   Options:
echo.     -h - print help.
echo.      -x - some very very very very very very very very very very
echo.       very very very very very very very 
echo.       very long parameter description.
echo.      -y - another  very very very very very very very very very very very very very
echo.            very very very very long parameter description.

And I get the following output (option x uses tabs and option y does not)

C:\Temp>usage.bat
        Usage:
                prg [OPTIONS]

        Options:
          -h - print help.
           -x - some very very very very very very very very very very
                very very very very very very very
                very long parameter description.
           -y - another  very very very very very very very very very very very
very very
                 very very very very long parameter description.
Steven
  • 44
  • 3
  • Yes, I use tabs in each `echo` statement. But what if user will use custom window width. Try running your script after `mode con:cols=40`, for example. BTW, I don't think `^` sign is required to escape tab symbol, when `echo.` (with dot) is used. – Evgeny Jul 24 '14 at 11:44
  • Your right it will only really work in a standard 80 column prompt. I guess you could query the number of columns and display different usage messages accordingly, but that would lead to a lot of repetition.
    How about forcing the console window to be 80 columns at the start of the script.
    In my answer I was just using the '^' character to illustrate where I'd put my tabs :)
    – Steven Jul 24 '14 at 13:18
0
echo off
setlocal enabledelayedexpansion

set "textx=some very very very very very very very very very very very very very very very very very very long parameter description."

REM find screen widht (subtract 8 for a leading tab and two for a right "border" :
for /f "tokens=2 delims=: " %%i in ('mode^|find "Columns"') do set /a colums=%%i-10

call :wrap "-x" "%textx%"
call :wrap "-y" "another quite quite quite quite quite quite quite quite quite quite quite quite quite quite quite quite quite long parameter description."

exit /b

:wrap <option> <text>
 set "text=%~2"
 set /p ".=%~1"<nul
 for /l %%i in (0,%colums%,1000) do echo.   !text:~%%i,%colums%!|findstr ".."
goto :eof

NOTE: there is a between the echo. and !text....

You may have to replace Columns in find "Columns" with the correct string (it's language dependent)

I subtracted 10 from the screen width: 8 for the leading and two to end the line two chars before the windows ends.

1000 is the max length of the string. Adapt as needed. (the higher the value, the slower the output)

|findstr ".." supresses the output of empty lines

This has a few disadvantages:

there is no space in front of -x (set does not support it)

It will wrap at the end of the line even if it's in the middle of a word. Doing a "word wrap" could be done, but with a lot more code.

It has problems with special chars (for example &, !, |)

Stephan
  • 53,940
  • 10
  • 58
  • 91