HTML in shell for torture and pain
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
1.5 KiB

#!/bin/sh
# hell - HTML in shell
tx()
{
: "${RAW:=false}"
if "$RAW"; then
printf '%b\n' "$*"
return
fi
while
[ "$#" -gt 0 ] && printf %s "$1"
do
[ "$#" -gt 1 ] && printf ' '
shift
done
printf '\n'
}
el()
{ # el NAME [ATTR=VALUE...] [-] [TEXT...]
el="$1"; shift
READ_IN=true
text=
attr=
class=
for word; do
case "$word" in
\\*) # words starting with backslashes are text
text="$text${text:+ }${word#\\}"
;;
class=*) # otherwise, 'class=' is a special case
class="${class:-class=\"}${class:+ }${word#class=}"
;;
*=*) # otherwise, words containing an equals are attr=value pairs
anam="${word%=*}"
aval="${word#*=}"
aval="${aval%\"}"
aval="${aval#\"}"
attr="$attr${attr:+ }${anam}=\"${aval}\""
;;
-) # otherwise, '-' denotes stdin
"$READ_IN" &&
while IFS= read -r line; do
text="$text${text:+
}$line" # this is very ugly but it works
done
;;
/) # close-tag flag: don't look for text from stdin
READ_IN=false
;;
*) # otherwise, it's text
text="$text${text:+ }$word"
;;
esac
done
# close out the class string
if [ -n "$class" ]; then
class="$class\""
attr="$attr${attr:+ }$class"
fi
# if there's no text, try reading from stdin
if [ -z "$text" ] && "$READ_IN"; then
while IFS= read -r line; do
text="$text${text:+
}$line" # this is very ugly but it works
done
fi
# print the thing
printf '<%s%s>%s' "$el" "${attr:+ }$attr" "$text"
# if there's text, close the tag
[ -n "$text" ] && printf '</%s>' "$el"
printf '\n'
}