49 lines
1.8 KiB
Bash
49 lines
1.8 KiB
Bash
#!/bin/bash
|
|
# A simple helper tool to reflow the text from the standard input to a given width
|
|
#
|
|
# Usage: cat [file] | phlow.sh [width] [leading_spaces] [trailing_spaces]
|
|
#
|
|
# Created by Luxferre in 2023, released into public domain
|
|
|
|
TARGET_WIDTH="$1"
|
|
LSPACES="$2"
|
|
TSPACES="$3"
|
|
|
|
CRLF=$'\r\n'
|
|
SPC=$'\x20'
|
|
|
|
[[ -z "$TARGET_WIDTH" ]] && TARGET_WIDTH=67 # default page width
|
|
[[ -z "$LSPACES" ]] && LSPACES=0
|
|
[[ -z "$TSPACES" ]] && TSPACES=0
|
|
|
|
fmtstr="%-$(( LSPACES ))s%-${TARGET_WIDTH}s%-$(( TSPACES ))s${CRLF}" # params: smth, line, smth
|
|
|
|
while read -rs line; do # fully line-based operation
|
|
line="${line%%$'\r'}" # remove a trailing CR if it is there
|
|
llen="${#line}" # get effective line length
|
|
if (( llen < TARGET_WIDTH )); then # no need to run the logic for smaller lines
|
|
printf "$fmtstr" '' "$line" ''
|
|
continue
|
|
fi
|
|
lastws=0 # variable to track last whitespace
|
|
cpos=0 # variable to track current position within the page line
|
|
pagepos=0 # variable to track the position of new line start
|
|
outbuf='' # temporary output buffer
|
|
for ((i=0;i<llen;i++,cpos++)); do # start iterating over characters
|
|
c="${line:i:1}" # get the current one
|
|
if (( cpos >= TARGET_WIDTH )); then # we already exceeded the page width
|
|
(( lastws == 0 )) && lastws=$TARGET_WIDTH # no whitespace encountered here
|
|
printf "$fmtstr" '' "${outbuf:0:$lastws}" '' # truncate the buffer
|
|
outbuf=''
|
|
pagepos=$(( pagepos + lastws ))
|
|
cpos=0
|
|
lastws=0
|
|
i=$pagepos # update current iteration index from the last valid whitespace
|
|
else # save the whitespace position if found
|
|
[[ "$c" == "$SPC" ]] && lastws="$cpos"
|
|
outbuf="${outbuf}${c}" # save the character itself
|
|
fi
|
|
done
|
|
[[ ! -z "$outbuf" ]] && printf "$fmtstr" '' "$outbuf" '' # output the last unprocessed chunk
|
|
done
|