From a453bf2f909e0ea01b0649ce8dc42d54689f738f Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Tue, 11 May 2021 19:54:23 +0100 Subject: refactor --- modules/assert.source.sh | 16 +++++ modules/atomfeed.source.sh | 104 ++++++++++++++++++++++++++++++++ modules/gemfeed.source.sh | 48 +++++++++++++++ modules/generate.source.sh | 109 +++++++++++++++++++++++++++++++++ modules/html.source.sh | 147 +++++++++++++++++++++++++++++++++++++++++++++ modules/md.source.sh | 55 +++++++++++++++++ 6 files changed, 479 insertions(+) create mode 100644 modules/assert.source.sh create mode 100644 modules/atomfeed.source.sh create mode 100644 modules/gemfeed.source.sh create mode 100644 modules/generate.source.sh create mode 100644 modules/html.source.sh create mode 100644 modules/md.source.sh (limited to 'modules') diff --git a/modules/assert.source.sh b/modules/assert.source.sh new file mode 100644 index 00000000..3367809d --- /dev/null +++ b/modules/assert.source.sh @@ -0,0 +1,16 @@ +assert::equals () { + local -r result="$1"; shift + local -r expected="$1"; shift + + if [ "$result" != "$expected" ]; then + 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 +} diff --git a/modules/gemfeed.source.sh b/modules/gemfeed.source.sh new file mode 100644 index 00000000..7e1c476b --- /dev/null +++ b/modules/gemfeed.source.sh @@ -0,0 +1,48 @@ +# Filters out blog posts from other files in the gemfeed dir. +gemfeed::get_posts () { + local -r gemfeed_dir="$CONTENT_DIR/gemtext/gemfeed" + local -r gmi_pattern='^[0-9]{4}-[0-9]{2}-[0-9]{2}-.*\.gmi$' + local -r draft_pattern='\.draft\.gmi$' + + ls "$gemfeed_dir" | grep -E "$gmi_pattern" | grep -E -v "$draft_pattern" | sort -r +} + +# Adds the links from gemfeed/index.gmi to the main index site. +gemfeed::updatemainindex () { + local -r index_gmi="$CONTENT_DIR/gemtext/index.gmi" + local -r gemfeed_dir="$CONTENT_DIR/gemtext/gemfeed" + + # Remove old gemfeeds from main index + $SED '/^=> .\/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 +} diff --git a/modules/generate.source.sh b/modules/generate.source.sh new file mode 100644 index 00000000..7066576a --- /dev/null +++ b/modules/generate.source.sh @@ -0,0 +1,109 @@ +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 +} diff --git a/modules/html.source.sh b/modules/html.source.sh new file mode 100644 index 00000000..9fb4a301 --- /dev/null +++ b/modules/html.source.sh @@ -0,0 +1,147 @@ +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 "
      " + echo "
    • ${line/\* /}
    • " + ;; + '```'*) + is_plain=1 + echo "
      "
      +                ;;
      +            '# '*)
      +                html::make_heading "$line" 1
      +                ;;
      +            '## '*)
      +                html::make_heading "$line" 2
      +                ;;
      +            '### '*)
      +                html::make_heading "$line" 3
      +                ;;
      +            '> '*)
      +                html::make_quote "$line"
      +                ;;
      +            '=> '*)
      +                generate::make_link html "$line"
      +                ;;
      +            *)
      +                html::make_paragraph "$line"
      +                ;;
      +        esac
      +    done
      +}
      +
      +html::test () {
      +    local line='Hello world! This is a paragraph.'
      +    assert::equals "$(html::make_paragraph "$line")" '

      Hello world! This is a paragraph.

      ' + + line='' + assert::equals "$(html::make_paragraph "$line")" '' + + line='Foo &<>& Bar!' + assert::equals "$(html::make_paragraph "$line")" '

      Foo &<>& Bar!

      ' + + line='# Header 1' + assert::equals "$(html::make_heading "$line" 1)" '

      Header 1

      ' + + line='## Header 2' + assert::equals "$(html::make_heading "$line" 2)" '

      Header 2

      ' + + line='### Header 3' + assert::equals "$(html::make_heading "$line" 3)" '

      Header 3

      ' + + line='> This is a quote' + assert::equals "$(html::make_quote "$line")" '
      This is a quote
      ' + + line='=> https://example.org' + assert::equals "$(generate::make_link html "$line")" \ + 'https://example.org
      ' + + line='=> index.gmi' + assert::equals "$(generate::make_link html "$line")" \ + 'index.html
      ' + + line='=> http://example.org Description of the link' + assert::equals "$(generate::make_link html "$line")" \ + 'Description of the link
      ' + + line='=> http://example.org/image.png' + assert::equals "$(generate::make_link html "$line")" \ + '
      ' + + line='=> http://example.org/image.png Image description' + assert::equals "$(generate::make_link html "$line")" \ + 'Image description:Image description
      ' +} diff --git a/modules/md.source.sh b/modules/md.source.sh new file mode 100644 index 00000000..197bdcf7 --- /dev/null +++ b/modules/md.source.sh @@ -0,0 +1,55 @@ +md::make_img () { + local link="$1"; shift + local descr="$1"; shift + + if [ -z "$descr" ]; then + echo "[![$link]($link)]($link) " + else + echo "[![$descr]($link \"$descr\")]($link) " + fi +} + +md::make_link () { + local link="$1"; shift + local descr="$1"; shift + + grep -F -q '://' <<< "$link" || link=${link/.gmi/.md} + test -z "$descr" && descr="$link" + + echo "[$descr]($link) " +} + +md::test () { + local line='=> https://example.org' + assert::equals "$(generate::make_link md "$line")" \ + '[https://example.org](https://example.org) ' + + line='=> index.md' + assert::equals "$(generate::make_link md "$line")" \ + '[index.md](index.md) ' + + line='=> http://example.org Description of the link' + assert::equals "$(generate::make_link md "$line")" \ + '[Description of the link](http://example.org) ' + + line='=> http://example.org/image.png' + assert::equals "$(generate::make_link md "$line")" \ + '[![http://example.org/image.png](http://example.org/image.png)](http://example.org/image.png) ' + + line='=> http://example.org/image.png Image description' + assert::equals "$(generate::make_link md "$line")" \ + '[![Image description](http://example.org/image.png "Image description")](http://example.org/image.png) ' +} + +md::fromgmi () { + while IFS='' read -r line; do + case "$line" in + '=> '*) + generate::make_link md "$line" + ;; + *) + echo "$line" + ;; + esac + done +} -- cgit v1.2.3