~luxferre/Bopher-NG

cd94a161f0f6b718c7d8047c55647239da95dfb3 — Luxferre 1 year, 2 months ago 31cc129
Added phlow.sh tool
2 files changed, 78 insertions(+), 4 deletions(-)

M tools/README-tools.md
A tools/phlow.sh
M tools/README-tools.md => tools/README-tools.md +30 -4
@@ 1,4 1,4 @@
# Bopher Tools: a set of simple Bash scripts to not just browse Gopher but also create for it
# Bopher Tools: a set of simple Bash scripts to not just browse Gopher but also create content for it

Bopher Tools is a small collection of simple shell scripts that are:



@@ 15,9 15,9 @@ Without further ado, let's begin!

This tool converts every line of the standard input into a valid CRLF-terminated Gophermap line of the `i` type that obeys RFC1436. It accepts three **optional** parameters: the number of leading spaces (0 by default), the number of trailing spaces (0 by default) and the placeholder (';' by default) to put into the selector and host fields unused in the `i` type (and the port field is always set to 0). It also pads every input line with the amount of spaces required to make the line length the same as the longest one in the input. All this is done to make your output Gophermap look nice when viewed in plaintext as well.

Note that the tool **does not** output the trailing dot to end the Gophermap, because its output can be used as a part of other Gophermaps. To end the map manually according to the RFC1436, just invoke `printf '.\r\n'` afterwards redirecting to the same output.
Note that the tool **does not** output the trailing dot to end the Gophermap, because its output can be used as a part of another Gophermap. To end the map manually according to the RFC1436, just invoke `printf '.\r\n'` afterwards redirecting to the same output.

Example of using `gopherinfo.sh` in combination with FIGlet, using 4 leading spaces, 0 trailing spaces and `|` as the placeholder:
Example of using `gopherinfo.sh` in combination with FIGlet, using 4 leading spaces, 0 trailing spaces and `|` as the placeholder (CR and Tab characters in the output are not shown):
```
$ figlet 'Bash it' | bash gopherinfo.sh 4 0 '|'
i     ____            _       _ _       |       |       0


@@ 36,4 36,30 @@ A non-trivial task would be using this output in some Web-based services like Ha
4. Paste your escaped string and hit Enter. If everything went correctly, the output should not be mangled.
5. Copy your `console.log` output again (make sure to fully copy the last line too!) and paste it in your Web service's posting textarea.

This hack also appies to any Gophermaps and not just the ones generated with this tool.
This hack also appies to any Gophermaps and not just the fragments generated with this tool.

## `phlow.sh`

This tool processes every line of text from the standard input to fit exactly the given amount of characters, optionally adding some leading and/or trailing whitespaces **after** the reflow is done. It also replaces all LF line endings with CRLF in the output to achieve maximum compatibility with legacy clients.

As `phlow.sh` does not know anything about hyphenation rules and doesn't do any heuristics, it just breaks at whatever whitespace is the closest to the page's right edge.

Example - fitting the previous paragraph into 30-character width and prepend every line with 5 spaces (CR characters in the output are not shown):
```
$ echo 'This tool processes every line of text from the standard input to fit exactly the given amount of characters, optionally adding some leading and/or trailing whitespaces **after** the reflow is done. It also replaces all LF line endings with CRLF in the output to achieve maximum compatibility with legacy clients.' | bash phlow.sh 30 5
     This tool processes every     
     line of text from the         
     standard input to fit         
     exactly the given amount of   
     characters, optionally        
     adding some leading and/or    
     trailing whitespaces          
     **after** the reflow is       
     done. It also replaces all    
     LF line endings with CRLF in  
     the output to achieve         
     maximum compatibility with    
     legacy clients.               
```



A tools/phlow.sh => tools/phlow.sh +48 -0
@@ 0,0 1,48 @@
#!/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" ''
done