You people are just great! Four workable sources.
SB - That lead is so sophisticated that I yearn to learn. Another promise to myself. Thank you, so-o-o interesting.
I put a fair bit of effort into Squashman's pointers to two scripts, both of which worked almost out of the box. Antonio's code was elegant, as usual, and flowed the whole input file. The code by MaGoo also worked but flowed only at the record level and not the whole file at a time. I chose not to convert the file to a single string to use it and added a very clumsy back end to Antonio's code to justify the output to both margins, producing output as described in my first post. They both compressed internal white-space and Antonio's technique added a space before the first word which I altered with a small change. This code seems to do what I asked:
Code: Select all
@echo off
:: Author - John Andrejsons - accepting PM to user: thefeduke at DOStips forum
:: acknowledges code and influences from DOStips.com and its forum
:: Squashman - Post subject: Re: Text Flow (like word wrapping to a margin) of free form text lines
:: http://www.dostips.com/forum/viewtopic.php?p=46017#p46017
:: Aacini - In Batch can I make a line of displayed text not split words appart when it goes to a new line?
:: http://stackoverflow.com/a/20944604/1417694
setlocal EnableDelayedExpansion
rem Force the wrap width
Set /A "width=50"
If .%2 NEQ . Set /A "width=%2"
rem Read the file given by first param and show its contents with no word split
rem Force the Input file
set "FileIn=%Temp%\SPFdocINI_Head.txt"
If .%1 NEQ . Set "FileIn=%1"
set "output="
rem For each line in input file
for /F "delims=" %%a in (%FileIn%) do (
rem For each word in input line
for %%b in (%%a) do (
rem Add the new word
If .!newOutput! EQU . (
set "newOutput=%%b"
) Else (
set "newOutput=!output! %%b"
)
rem If new word don't exceed window width
if "!newOutput:~%width%,1!" equ "" (
rem Keep it
set "output=!newOutput!"
) else (
rem Show the output before the new word
Call :ReSpace %width% "!output!"
rem and store the new word
set "output=%%b"
)
)
)
rem Show the last output, if any
if defined output Echo.!output!
Exit /B
:Respace
SET "Width=%~1"
SET "Wrapped=%~2"
Call :StrLen Wrapped columns
SET /a Short=%Width% - %columns%
SET /a lastsp=%columns%
If "%Short%" GTR "0" (
For /L %%S in (%Short%,-1,1) Do (
SET /a lastsp-=1
CALL :StretchLine !lastsp! "!Wrapped!" lastnew Warped
Set "Wrapped=!Warped!"
Set "lastsp=!lastnew!"
)
)
Echo.%Wrapped%
GOTO :eof
:StretchLine
setlocal EnableDelayedExpansion
SET lastsp=%1
SET savesp=%1
:insert
SET /a lastsp-=1
Call SET "Wrapped=%~2"
CALL SET line=%%Wrapped:~%lastsp%,1%%
IF "%line%" EQU " " (
SET "line=!Wrapped:~0,%lastsp%! !Wrapped:~%lastsp%!"
) Else (
GOTO insert
)
( ENDLOCAL & REM RETURN VALUES
IF "%~3" NEQ "" SET %~3=%lastsp%
IF "%~4" NEQ "" SET %~4=%line%
)
Exit /B
:strLen string len -- returns the length of a string
@Echo Off
:: -- string [in] - variable name containing the string being measured for length
:: -- len [out] - variable to be used to return the string length
:: Many thanks to 'sowgtsoi', but also 'jeb' and 'amel27' dostips forum users helped making this short and efficient
:$created 20081122 :$changed 20101116 :$categories StringOperation
:$source http://www.dostips.com
( SETLOCAL ENABLEDELAYEDEXPANSION
set "str=A!%~1!"&rem keep the A up front to ensure we get the length and not the upper bound
rem it also avoids trouble in case of empty string
set "len=0"
for /L %%A in (12,-1,0) do (
set /a "len|=1<<%%A"
for %%B in (!len!) do if "!str:~%%B,1!"=="" set /a "len&=~1<<%%A"
)
)
( ENDLOCAL & REM RETURN VALUES
IF "%~2" NEQ "" SET /a %~2=%len%
)
EXIT /b
The above nearing completion, ShadowThief offered some code, that I found so appealing in approach, comments and coding style that I made the following changes to my copy from his post:
Code: Select all
:: Strip the quotes from any arguments
if not "%~1"=="" (
set unformattedText=%~1
:: Accept the first argument as a file if supplied
If Exist "%~1" (
set unformattedFile=%~1
set "unformattedText= "
For /F "usebackq delims=" %%A in ("!unformattedFile!") do (
Set "unformattedText=!unformattedText! %%A"
)
)
)
This was the creation of a long string from an input file that I did not create for the 'MaGoo' code. This produced satisfactory left-justified and right-padded output, so I am now enticed to capitalize on those arrays of words to add the white-space within the lines instead of at the end in a less clumsy method. My thanks.
Just my luck, ShadowThief, that I stumbled upon some poison WORDS in my input. Head-scratching revealed that the spacing counts were thrown awry by the words 'off' or 'on' in the text. You should correct your code when determining word size:
Code: Select all
:: Using a space with Echo makes on and off become poison words in the text
echo.!words[%%A]!>tmp.txt
because 'echo on' becomes a command and nothing goes to tmp.txt .
Thanks, all, for pointing me to the good stuff.
John A.