#!/bin/bash # # Sends an ascii-art text file to a parallel port needle/dot-matrix printer. # # Usage: ./txt2printr.sh [ascii-art.txt] # Env: PRINTER_DEV - printer device node (default: /dev/lp0) # Reads printer.conf for PRINTER_A4 (landscape rotation) and PRINTER_MAX_LINES # (per-page line capacity, measured with pagetest.sh). dir="$(dirname "$0")" [ -f "$dir/printer.conf" ] && source "$dir/printer.conf" : "${PRINTER_A4:=false}" : "${PRINTER_MAX_LINES:=64}" infile="${1:-ascii-img.txt}" # Source - https://stackoverflow.com/a/638980 # Posted by John Feminella, modified by community. See post 'Timeline' for change history # Retrieved 2026-07-14, License - CC BY-SA 4.0 if [ -n "$PRINTER_DEV" ]; then dev="$PRINTER_DEV" elif [ -e /dev/lp0 ]; then dev=/dev/lp0 elif [ -e /dev/usb/lp0 ]; then dev=/dev/usb/lp0 else dev=/dev/stdout fi if [ ! -f "$infile" ]; then echo "txt2printr: file not found: $infile" >&2 exit 1 fi if [ ! -w "$dev" ]; then echo "txt2printr: cannot write to printer device: $dev" >&2 echo "txt2printr: set PRINTER_DEV to override, or check permissions/parport module" >&2 exit 1 fi # Rotates the ascii art 90 degrees clockwise so it reads correctly once the # printed page itself is turned 90 degrees counter-clockwise - the printer's # scan/feed directions are fixed, so this is the only way to get a landscape # reading orientation out of it. rotate90() { awk ' { if (length($0) > maxlen) maxlen = length($0); lines[NR] = $0 } END { for (c = 1; c <= maxlen; c++) { row = "" for (r = NR; r >= 1; r--) { ch = substr(lines[r], c, 1) if (ch == "") ch = " " row = row ch } print row } } ' "$infile" } body() { if [ "$PRINTER_A4" = "true" ]; then rotate90 else cat "$infile" fi } line_count=$(body | wc -l) { printf '\x1b\x40' # ESC @ - reset printer (ESC/P and IBM Proprinter compatible) body | sed 's/$/\r/' # CRLF line endings, needed for raw writes to avoid staircasing # Skip the form feed once the page is already full: printers commonly # auto-advance to a new page as soon as content hits the bottom margin, # so an explicit form feed on top of that just ejects a blank extra page. if [ "$line_count" -lt "$PRINTER_MAX_LINES" ]; then printf '\x0c' # form feed - eject the page fi } > "$dev"