#!/bin/ksh -e # https://romanzolotarev.com/ssg/txt2img.sh # copyright 2025-2026 romanzolotarev.com # # permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # the software is provided "as is" and the author disclaims all warranties with # regard to this software including all implied warranties of merchantability # and fitness. in no event shall the author be liable for any special, direct, # indirect, or consequential damages or any damages whatsoever resulting from # loss of use, data or profits, whether in an action of contract, negligence or # other tortious action, arising out of or in connection with the use or # performance of this software. info() { echo "$@" >&2; } fail() { info "$@" && exit 1; } usage() { fail 'usage: '"${0##*/}"' [-scale percent] [-background color] [-extent wxh] -o output < [input]'; } scale="100" background="transparent" extent="" out="" while test $# -gt 0 do case "$1" in -scale) shift && scale="$1" ;; -background) shift && background="$1" ;; -extent) shift && extent="$1" ;; -o) shift && out="$1" ;; -*) info "unknown option: $1" && usage ;; *) usage ;; esac shift done if test -z "$out"; then info 'missing option: -o' && usage; fi if test -f "$out"; then fail "$out already exists"; fi lines=$(cat) width=$(echo "$lines" | awk ' { for (i=length; i>0; i--) { c = substr($0,i,1); if (c=="*" || c=="." || c==" ") { if (i > max) max = i; break; } } } END { print max }') test -n "$width" || fail "no '*' or '.' in input" height=$(echo "$lines" | wc -l | tr -d ' ') m() { set -- convert - -strip -scale "${scale}%" -background "$background" if test -n "$extent"; then set -- "$@" -gravity center -extent "$extent"; fi "$@" "$out" 2>/dev/null } { echo 'P7 WIDTH '"$width"' HEIGHT '"$height"' DEPTH 4 MAXVAL 255 TUPLTYPE RGB_ALPHA ENDHDR' echo "$lines" | awk -v width="$width" ' function emit(r, g, b, a) { printf("%c%c%c%c", r, g, b, a); } { l = sprintf("%-*s", width, $0); for (i = 1; i <= width; i++) { c = substr(l, i, 1); if (c == "*") emit(0, 0, 0, 255); else if (c == ".") emit(255, 255, 255, 255); else emit(0, 0, 0, 0); } }' } | m