169 lines
3.5 KiB
Bash
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
|