#!/usr/bin/env bash declare -r ARG=$1; shift source buetow.org.conf declare DATE=date declare SED=sed which gdate &>/dev/null && DATE=gdate which gsed &>/dev/null && SED=gsed ## Test module assert::equals () { local -r result="$1"; shift local -r expected="$1"; shift if [ "$result" != "$expected" ]; then cat < .\/gemfeed\/[0-9].* - .*/d;' "$index_gmi" > "$index_gmi.tmp" # Add current gemfeeds to main index $SED -n '/^=> / { s| ./| ./gemfeed/|; p; }' "$gemfeed_dir/index.gmi" >> "$index_gmi.tmp" mv "$index_gmi.tmp" "$index_gmi" test "$ADD_GIT" == yes && git add "$index_gmi" } # This generates a index.gmi in the ./gemfeed subdir. gemfeed::generate () { local -r gemfeed_dir="$CONTENT_DIR/gemtext/gemfeed" cat < "$gemfeed_dir/index.gmi.tmp" # $DOMAIN's Gemfeed ## $SUBTITLE GEMFEED gemfeed::get_posts | while read gmi_file; do # Extract first heading as post title. local title=$($SED -n '/^# / { s/# //; p; q; }' "$gemfeed_dir/$gmi_file" | tr '"' "'") # Extract the date from the file name. local filename_date=$(basename "$gemfeed_dir/$gmi_file" | cut -d- -f1,2,3) echo "=> ./$gmi_file $filename_date - $title" >> "$gemfeed_dir/index.gmi.tmp" done mv "$gemfeed_dir/index.gmi.tmp" "$gemfeed_dir/index.gmi" test "$ADD_GIT" == yes && git add "$gemfeed_dir/index.gmi" gemfeed::updatemainindex } ## Atom module atomfeed::meta () { local -r gmi_file_path="$1"; shift local -r meta_file=$($SED 's|gemtext|meta|; s|.gmi$|.meta|;' <<< "$gmi_file_path") local is_draft=no if grep -E -q '\.draft\.meta$' <<< "$meta_file"; then is_draft=yes fi local -r meta_dir=$(dirname "$meta_file") test ! -d "$meta_dir" && mkdir -p "$meta_dir" if [ ! -f "$meta_file" ]; then # Extract first heading as post title. local title=$($SED -n '/^# / { s/# //; p; q; }' "$gmi_file_path" | tr '"' "'") # Extract first paragraph from Gemtext local summary=$($SED -n '/^[A-Z]/ { p; q; }' "$gmi_file_path" | tr '"' "'") # Extract the date from the file name. local filename_date=$(basename $gmi_file_path | cut -d- -f1,2,3) local date=$($DATE --iso-8601=seconds --date "$filename_date $($DATE +%H:%M:%S)") cat < "$atom_file.tmp" $now $DOMAIN feed $SUBTITLE gemini://$DOMAIN/ ATOMHEADER while read -r gmi_file; do # Load cached meta information about the post. source <(atomfeed::meta "$gemfeed_dir/$gmi_file") # Get HTML content for the feed local content="$(atomfeed::content "$gemfeed_dir/$gmi_file")" cat <> "$atom_file.tmp" $meta_title gemini://$DOMAIN/gemfeed/$gmi_file $meta_date $meta_author $meta_email $meta_summary
$content
ATOMENTRY done < <(gemfeed::get_posts | head -n $ATOM_MAX_ENTRIES) cat <> "$atom_file.tmp"
ATOMFOOTER # Delete the 3rd line of the atom feeds (global feed update timestamp) if ! diff -u <($SED 3d "$atom_file") <($SED 3d "$atom_file.tmp"); then echo "Feed got something new!" mv "$atom_file.tmp" "$atom_file" test "$ADD_GIT" == yes && git add "$atom_file" else echo "Nothing really new in the feed" rm "$atom_file.tmp" fi } ## Generic generate module generate::make_link () { local -r what="$1"; shift local -r line="${1/=> }"; shift local link local descr while read -r token; do if [ -z "$link" ]; then link="$token" elif [ -z "$descr" ]; then descr="$token" else descr="$descr $token" fi done < <(echo "$line" | tr ' ' '\n') if grep -E -q "$IMAGE_PATTERN" <<< "$link"; then if [ $what == md ]; then md::make_img "$link" "$descr" else html::make_img "$link" "$(html::special "$descr")" fi return fi if [ $what == md ]; then md::make_link "$link" "$descr" else html::make_link "$link" "$(html::special "$descr")" fi } generate::fromgmi_ () { local -r src="$1"; shift local -r format="$1"; shift local dest=${src/gemtext/$format} dest=${dest/.gmi/.$format} local dest_dir=$(dirname "$dest") test ! -d "$dest_dir" && mkdir -p "$dest_dir" if [ $format == html ]; then cat header.html.part > "$dest.tmp" html::fromgmi < "$src" >> "$dest.tmp" cat footer.html.part >> "$dest.tmp" elif [ $format == md ]; then md::fromgmi < "$src" >> "$dest.tmp" fi mv "$dest.tmp" "$dest" test "$ADD_GIT" == yes && git add "$dest" } generate::fromgmi_add_docs () { local -r src="$1"; shift local -r format="$1"; shift local -r dest=${src/gemtext/$format} local -r dest_dir=$(dirname "$dest") test ! -d "$dest_dir" && mkdir -p "$dest_dir" cp "$src" "$dest" test "$ADD_GIT" == yes && git add "$dest" } generate::fromgmi_convert_atom () { local -r format="$1"; shift test $format != html && return $SED 's|.gmi|.html|g; s|gemini://|https://|g' \ < $CONTENT_DIR/gemtext/gemfeed/atom.xml \ > $CONTENT_DIR/html/gemfeed/atom.xml test "$ADD_GIT" == yes && git add $CONTENT_DIR/html/gemfeed/atom.xml } generate::fromgmi_cleanup () { local -r src="$1"; shift local -r format="$1"; shift local dest=${src/.$format/.gmi} dest=${dest/$format/gemtext} test ! -f "$dest" && test "$ADD_GIT" == yes && git rm "$src" } generate::fromgmi () { find $CONTENT_DIR/gemtext -type f -name \*.gmi | while read -r src; do for format in "$@"; do generate::fromgmi_ "$src" "$format" done done # Add non-.gmi files to html dir. find $CONTENT_DIR/gemtext -type f | grep -E -v '(.gmi|atom.xml|.tmp)$' | while read -r src; do for format in "$@"; do generate::fromgmi_add_docs "$src" "$format" done done # Add atom feed for HTML for format in "$@"; do generate::fromgmi_convert_atom "$format" done # Remove obsolete files from ./html/ for format in "$@"; do find $CONTENT_DIR/$format -type f | while read -r src; do generate::fromgmi_cleanup "$src" "$format" done done } ## HTML module html::special () { $SED ' s|\&|\&|g; s|<|\<|g; s|>|\>|g; ' <<< "$@" } html::make_paragraph () { local -r text="$1"; shift test -n "$text" && echo "

$(html::special "$text")

" } html::make_heading () { local -r text=$($SED -E 's/^#+ //' <<< "$1"); shift local -r level="$1"; shift echo "$(html::special "$text")" } html::make_quote () { local -r quote="${1/> }" echo "
$(html::special "$quote")
" } html::make_img () { local link="$1"; shift local descr="$1"; shift if [ -z "$descr" ]; then echo -n "" else echo -n "$descr:" echo -n "\"$descr\"" fi echo "
" } html::make_link () { local link="$1"; shift local descr="$1"; shift grep -F -q '://' <<< "$link" || link=${link/.gmi/.html} test -z "$descr" && descr="$link" echo "$descr
" } html::fromgmi () { local -r gmi_file=$1 local -i is_list=0 local -i is_plain=0 while IFS='' read -r line; do if [ $is_list -eq 1 ]; then if [[ "$line" == '* '* ]]; then echo "
  • ${line/\* /}
  • " else is_list=0 echo "" fi continue elif [ $is_plain -eq 1 ]; then if [[ "$line" == '```'* ]]; then echo "" is_plain=0 else html::special "$line" fi continue fi case "$line" in '* '*) is_list=1 echo "