Skip to content

Instantly share code, notes, and snippets.

@ruario
Last active January 13, 2022 22:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ruario/3bd570d265ca5a42cb039092ed4f1299 to your computer and use it in GitHub Desktop.
Save ruario/3bd570d265ca5a42cb039092ed4f1299 to your computer and use it in GitHub Desktop.
A quick and dirty script to reformat Gemtext for use on Gopher
#!/usr/bin/env bash
#
# A quick and dirty script to reformat Gemtext for use on Gopher.
#
# To use, make it executable, then you pipe or redirect the Gemtext in.
#
# ./gmi2txt.sh < yourfile.gmi
LINE_LENGTH=70 # Adjust as you see fit ;)
# The following are just examples. A complete list is not realistic, so just
# tweak this to the ones you are likely to use (or want to remove).
filter_chrs () {
echo "$1" | sed \
-e 's/⁰/[0]/g' \
-e 's/¹/[1]/g' \
-e 's/²/[2]/g' \
-e 's/³/[3]/g' \
-e 's/⁴/[4]/g' \
-e 's/⁵/[5]/g' \
-e 's/⁶/[6]/g' \
-e 's/⁷/[7]/g' \
-e 's/⁸/[8]/g' \
-e 's/⁹/[9]/g' \
-e 's/†/[+]/g' \
-e 's/‡/[++]/g' \
-e 's/🇦/A/g' \
-e 's/🇧/B/g' \
-e 's/🇨/C/g' \
-e 's/🇩/D/g' \
-e 's/🇪/E/g' \
-e 's/🇫/F/g' \
-e 's/🇬/G/g' \
-e 's/🇭/H/g' \
-e 's/🇮/I/g' \
-e 's/🇯/J/g' \
-e 's/🇰/K/g' \
-e 's/🇱/L/g' \
-e 's/🇲/M/g' \
-e 's/🇳/N/g' \
-e 's/🇴/O/g' \
-e 's/🇵/P/g' \
-e 's/🇶/Q/g' \
-e 's/🇷/R/g' \
-e 's/🇸/S/g' \
-e 's/🇹/T/g' \
-e 's/🇺/U/g' \
-e 's/🇻/V/g' \
-e 's/🇼/W/g' \
-e 's/🇽/X/g' \
-e 's/🇾/Y/g' \
-e 's/🇿/Z/g' \
-e 's/[ÆÄ]/Ae/g' \
-e 's/[æä]/ae/g' \
-e 's/[ØÖ]/Oe/g' \
-e 's/[øö]/oe/g' \
-e 's/Å/Aa/g' \
-e 's/å/aa/g' \
-e 's/Ü/Ue/g' \
-e 's/ü/ue/g' \
-e 's/ẞ/SS/g' \
-e 's/ß/ss/g' \
-e 's/í/i/g' \
-e 's/ż/z/g' \
-e "s/[′‘’]/'/g" \
-e 's/[″„“”]/"/g' \
-e 's/[…⋮]/.../g' \
-e 's/‖/[||]/g' \
-e 's/[•◦]/*/g' \
-e 's,¼, 1/4,g' \
-e 's,⅓, 1/3,g' \
-e 's,⅜, 3/8,g' \
-e 's,½, 1/2,g' \
-e 's/¶/P./g' \
-e 's/§/S./g' \
-e 's/✍/EDIT/g' \
-e 's/‽/!?/g' \
-e 's/⁂/* * */g' \
-e 's/—/--/g' \
-e 's/–/-/g' \
-e 's/←/[<]/g' \
-e 's/↑/[^]/g' \
-e 's/[→☞]/[>]/g' \
-e 's/↓/[v]/g' \
-e 's/€/EUR/g' \
-e 's/£/GBP/g' \
-e 's/¥/Y=/g' \
-e 's/⌘/[CMD]/g' \
-e 's/¤/[currency]/g' \
-e 's/ℹ/[i]/g' \
-e 's/[😊🙂☺️]/:)/g' \
-e 's/[😛😜🤪😋🙃]/:P/g' \
-e 's/[😀😃😁😂]/:D/g' \
-e 's/😉/;)/g' \
-e 's/[😝😆]/XD/g' \
-e 's/[😔😞☹️]/:(/g' \
-e "s/[😢😭]/:'(/g" \
-e 's/[😒😐😑😬]/:|/g' \
-e 's/[😲🤯😱]/:o/g' \
-e 's/[😘😗😙😚]/:*/g' \
-e 's/[😠😡]/>:[/g' \
-e 's/😳/:$/g' \
-e 's/🥴/%)/g' \
-e 's/😎/B)/g' \
-e 's/😈/}:)/g' \
-e 's/🎅/*<|:‑)/g' \
-e 's/[😇👼]/O:)/g' \
-e 's/[♥💖🥰😍]/<3/g' \
-e 's/🐟/}<(((*>/g' \
-e 's/🤓/[geek]/g' \
-e 's/🤔/[thinks]/g' \
-e 's/🤷/[shrugs]/g' \
-e 's/👍/[+1]/g' \
-e 's/🥇/[1st]/g' \
-e 's/🥈/[2nd]/g' \
-e 's/🥉/[3rd]/g' \
-e 's/🚲/[bike]/g' \
-e 's/[❄🌨]/[snow]/g' \
-e 's/♊/[II]/g' \
-e 's/[☕🍺🍷🍻🥂]/[drink]/g' \
-e 's/💭/[thought]/g' \
-e 's/💡/[light bulb]/g' \
-e 's/[🎉💨🎄🎁🍓💻🕹🚗👨🚩🏤🔄🔙🔝🔗🐧📰📝📧📪❓🚀°Δ◊♠♣♦​]//g'
}
end_quote () {
[ "$QUOTING" = ON ] && printf '\n'; QUOTING=OFF
}
end_linetypes () {
LINK_NEWLINE=OFF
LIST_NEWLINE=OFF
end_quote
}
# These will get reset during processing. The following are default states.
PREFORMAT=OFF
QUOTING=OFF
LINK_NEWLINE=OFF
LIST_NEWLINE=OFF
# Process one line of the input file at a time.
while IFS= read -r line;
do
if [ "$PREFORMAT" = ON ]; then
case "$line" in
'```'*)
PREFORMAT=OFF
;;
*)
echo "$line"
;;
esac
else
case "$line" in
'###'*) # Third level header
end_linetypes
filter_chrs "$line" | cut -d' ' -f2- | sed 's/$/-/' | fmt -w "$(($LINE_LENGTH - 2))" | sed 's/^/ /;1s/^ /-/'
;;
'##'*) # Second level header
end_linetypes
filter_chrs "$line" | cut -d' ' -f2- | fmt -w "$LINE_LENGTH"
filter_chrs "$line" | cut -d' ' -f2- | sed 's/./-/g' | cut -c -"$LINE_LENGTH"
;;
'#'*) # First level header
end_linetypes
filter_chrs "$line" | cut -d' ' -f2- | fmt -w "$LINE_LENGTH"
filter_chrs "$line" | cut -d' ' -f2- | sed 's/./=/g' | cut -c -"$LINE_LENGTH"
;;
'* '*) # List
end_quote
[ "$LIST_NEWLINE" = ON ] && printf '\n'
filter_chrs "$line" | fmt -w "$(($LINE_LENGTH - 2))" | sed -E 's/^([^\*])/ \1/'
LIST_NEWLINE=ON
;;
'=>'*) # Links
end_quote
[ "$LINK_NEWLINE" = ON ] && printf '\n'
echo "$line" | sed -E 's/^=>[[:blank:]]*([^[:blank:]]+)[[:blank:]]+(.*)/~ \2:\n\1/;s/^=>[[:blank:]]*([^[:blank:]]+)/~ :\n\1/' \
| while IFS= read -r linkline;
do
case "$linkline" in
~*)
filter_chrs "$linkline" | fmt -w "$(($LINE_LENGTH - 2))" | sed -E 's/^([^\~])/ \1/'
;;
*)
echo "$linkline"
;;
esac
done
LINK_NEWLINE=ON
;;
'>'*) # Quote
LINK_NEWLINE=OFF
LIST_NEWLINE=OFF
[ "$QUOTING" = OFF ] && echo ' ``'; QUOTING=ON
filter_chrs "$line" | sed -E 's/^>[[:blank:]]?//' | fmt -w "$(($LINE_LENGTH - 2))" | sed 's/^/ /'
;;
'```'*) # Pre-formatted text
PREFORMAT=ON
;;
*) # Regular text
end_linetypes
filter_chrs "$line" | fmt -w "$LINE_LENGTH"
;;
esac
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment