bollux/typeset_gemini.sh

169 lines
3.5 KiB
Bash

typeset_gemini() {
local pre=false
while read -r line; do
case "$line" in
'```')
flip pre
continue
;;
=\>*) gemini_link "$line" $pre ;;
\#*) gemini_header "$line" $pre ;;
\**) gemini_list "$line" $pre ;;
*) gemini_text "$line" $pre ;;
esac
done
}
gemini_link() {
local re="^(=>)[[:blank:]]*([^[:blank:]]+)[[:blank:]]*(.*)"
local s t a # sigil, text, annotation(url)
if ! ${2-false} && [[ "$1" =~ $re ]]; then
s="${BASH_REMATCH[1]}"
t="${BASH_REMATCH[3]}"
a="${BASH_REMATCH[2]}"
printf "$C_SIGIL%-${MARGIN}s" "$s"
fold_line "$WIDTH" "$(printf "$C_LINK_TITLE%s $C_LINK_URL%s$C_RESET\n" \
"$t" "$a")"
else
gemini_pre "$1"
fi
}
gemini_header() {
local re="^(#+)[[:blank:]]*(.*)"
local s t a # sigil, text, annotation(lvl)
if ! ${2-false} && [[ "$1" =~ $re ]]; then
s="${BASH_REMATCH[1]}"
a="${#BASH_REMATCH[1]}"
t="${BASH_REMATCH[2]}"
local hdrfmt
hdrfmt="$(eval echo "\$C_HEADER$a")"
printf "$C_SIGIL%-${MARGIN}s$hdrfmt%s$C_RESET\n" \
"$s" "$(fold_line "$WIDTH" "$t")"
else
gemini_pre "$1"
fi
}
gemini_list() {
local re="^(\*)[[:blank:]]*(.*)"
local s t a # sigil, text, annotation(n/a)
if ! ${2-false} && [[ "$1" =~ $re ]]; then
s="${BASH_REMATCH[1]}"
t="${BASH_REMATCH[2]}"
printf "$C_SIGIL%-${MARGIN}s$C_LIST%s$C_RESET\n" \
"$s" "$(fold_line "$WIDTH" "$t")"
else
gemini_pre "$1"
fi
}
gemini_text() {
printf "%${MARGIN}s" ' '
if ! ${2-false}; then
fold_line "$WIDTH" "$1"
else
gemini_pre "$1"
fi
}
gemini_pre() {
printf "%${MARGIN}s%s" ' ' "$1"
}
flip() { # flip NAME
[[ "${!1}" == true || "${!1}" == false ]] || return 1
if "${!1}"; then
eval "$1=false"
else
eval "$1=true"
fi
}
fold_line() { # fold_line WIDTH TEXT
local width="$1"
local ll=0 wl plain
# shellcheck disable=2086
# TODO: determine if this is the best way to do it
set -- $2
for word; do
plain="${word//$'\x1b'\[*([0-9;])m/}"
wl=$((${#plain} + 1))
if (((ll + wl) >= width)); then
printf "\n%${MARGIN}s" ' '
ll=$wl
else
ll=$((ll + wl))
fi
printf '%s ' "$word"
done
printf '\n'
}
# just here for reference
strip() { # strip control sequences
# https://stackoverflow.com/a/55872518
shopt -s extglob
while IFS='' read -r x; do
# remove colors
echo "${x//$'\x1b'\[*([0-9;])m/}"
done
}
test() {
MARGIN=4
WIDTH=60
#shopt -s checkwinsize; (:;:)
#WIDTH="$((COLUMNS - (MARGIN*2)))"
C_LINK_TITLE=$'\e[34m'
C_LINK_URL=$'\e[31m'
C_RESET=$'\e[0m'
typeset_gemini <<-'EOF'
# Project Gemini
## Overview
Gemini is a new internet protocol which:
* Is heavier than gopher
* Is lighter than the web
* Will not replace either
* Strives for maximum power to weight ratio
* Takes user privacy very seriously
## Resources
=> docs/ Gemini documentation
=> software/ Gemini software
=> servers/ Known Gemini servers
=> https://lists.orbitalfox.eu/listinfo/gemini Gemini mailing list
=> gemini://gemini.conman.org/test/torture/ Gemini client torture test
## Web proxies
=> https://portal.mozz.us/?url=gemini%3A%2F%2Fgemini.circumlunar.space%2F&fmt=fixed Gemini-to-web proxy service
=> https://proxy.vulpes.one/gemini/gemini.circumlunar.space Another Gemini-to-web proxy service
## Search engines
=> gemini://gus.guru/ Gemini Universal Search engine
=> gemini://houston.coder.town Houston search engine
## Geminispace aggregators (experimental!)
=> capcom/ CAPCOM
=> gemini://rawtext.club:1965/~sloum/spacewalk.gmi Spacewalk
## Free Gemini hosting
=> users/ Users with Gemini content on this server
EOF
}
test