#!/usr/bin/env bash gemtext2gophermap() { MAP_FILE="gopher/specific/$(basename "$1").map" if [[ -f "$MAP_FILE" ]]; then gemtext2gophermap/gemtext2gophermap - - 69 "$MAP_FILE" >> "$1/gophermap" else gemtext2gophermap/gemtext2gophermap - - 69 >> "$1/gophermap" fi } getMarkdownPath() { echo "src/content/posts/$(basename "$1").md" } getPostProperties() { grep -zoP "(?s)(---.*?---)" "$1" | head -zn 1 | tr -d '\0' } getTranslations() { grep -zoP "(?s)id[ ']*:[ ']*$1.*?(?=\n-[ ']*id|$)" src/content/languages.yaml | tr -d '\0' } getAuthor() { grep -zoP "(?s)id[ ']*:[ ']*$1.*?(?=\n-[ ']*id|$)" src/content/authors.yaml | tr -d '\0' } getTextProperty() { echo "$1" | grep -oPm 1 "$2:\K.+" | xargs } getArrayProperty() { echo "$1" | grep -oPm 1 "$2: *\[\K(.*?)(?=\])" } MARKDOWN_POST="$(getMarkdownPath "$1")" POST_PROPERTIES="$(getPostProperties "$MARKDOWN_POST")" GOPHER_POST_DIR="$1" POST_ID="$(basename "$1")" LANGUAGE="$(getTextProperty "$POST_PROPERTIES" language)" TITLE="$(getTextProperty "$POST_PROPERTIES" title)" AUTHORS="$(getArrayProperty "$POST_PROPERTIES" authors)" RELATED_POSTS="$(getArrayProperty "$POST_PROPERTIES" relatedPosts)" IS_FEATURED_INSTEAD_OF_RELATED="$(getTextProperty "$POST_PROPERTIES" featuredInsteadOfRelated)" ALTERNATIVE_LANGUAGE_POSTS="$(getArrayProperty "$POST_PROPERTIES" alternativeLanguagesPosts)" PUBLISHED_DATE="$(getTextProperty "$POST_PROPERTIES" publishedDate)" UPDATED_DATE="$(getTextProperty "$POST_PROPERTIES" updatedDate)" SHOULD_HIDE_TITLE="$(getTextProperty "$POST_PROPERTIES" hideTitle)" SHOULD_PREPEND_LOGO="$(getTextProperty "$POST_PROPERTIES" gopherPrependLogo)" TRANSLATIONS="$(getTranslations "$LANGUAGE")" LANGUAGE_NAME="$(getTextProperty "$TRANSLATIONS" name)" TRANSLATION_LATEST="$(getTextProperty "$TRANSLATIONS" latest)" TRANSLATION_RELATED="$(getTextProperty "$TRANSLATIONS" related)" TRANSLATION_FEATURED="$(getTextProperty "$TRANSLATIONS" featured)" TRANSLATION_PUBLISHED_ON="$(getTextProperty "$TRANSLATIONS" publishedOn)" TRANSLATION_LAST_UPDATED_ON="$(getTextProperty "$TRANSLATIONS" lastUpdatedOn)" TRANSLATION_AVAILABLE_IN_OTHER_LANGUAGES="$(getTextProperty "$TRANSLATIONS" availableInOtherLanguages)" mkdir -p "$1" if [[ "$SHOULD_HIDE_TITLE" != 'true' ]]; then printf '# %s\n\n' "$TITLE" > $1/index.gmi printf '!%s\n' "$TITLE" > $1/gophermap fi DEFAULT_IFS="$IFS" SCRIPT_DIRECTORY="$(dirname $0)" printLogo() { echo '```' cat "$SCRIPT_DIRECTORY/logo.txt" echo '```' } generateHeader() { IFS=',' if [[ "$SHOULD_PREPEND_LOGO" == 'true' ]]; then printf '\n' >> "$GOPHER_POST_DIR/gophermap" printLogo fi if [[ -n "$AUTHORS" ]]; then for author_id in $AUTHORS; do author_id="$(echo "$author_id" | xargs)" author_properties="$(getAuthor "$author_id")" author_name="$(getTextProperty "$author_properties" name)" author_callsign="$(getTextProperty "$author_properties" callsign)" author_bioPostId="$(getTextProperty "$author_properties" bioPostId)" if [[ -n "$author_bioPostId" ]]; then printf '=> /%s/ ' "$author_bioPostId" fi printf "$author_name" if [[ -n "$author_callsign" ]]; then printf ' (%s)' "$author_callsign" fi printf '\n' done fi if [[ -n "$ALTERNATIVE_LANGUAGE_POSTS" ]]; then if [[ -n "$AUTHORS" ]]; then printf '\n' fi for post_id in $ALTERNATIVE_LANGUAGE_POSTS; do post_id="$(echo "$post_id" | xargs)" post_path="$(getMarkdownPath "$post_id")" post_properties="$(getPostProperties "$post_path")" post_language_id="$(getTextProperty "$post_properties" language)" translations="$(getTranslations "$post_language_id")" language_name="$(getTextProperty "$translations" name)" printf '=> %s %s: %s\n' "/$post_id/" "$TRANSLATION_AVAILABLE_IN_OTHER_LANGUAGES" "$language_name" done fi if [[ -n "$PUBLISHED_DATE" || -n "$UPDATED_DATE" ]]; then printf '```\n' if [[ -n "$PUBLISHED_DATE" ]]; then printf '%s: %s\n' "$TRANSLATION_PUBLISHED_ON" "$PUBLISHED_DATE" fi if [[ -n "$UPDATED_DATE" ]]; then printf '%s: %s\n' "$TRANSLATION_LAST_UPDATED_ON" "$UPDATED_DATE" fi printf '```\n' else printf '\n' fi cat } generateFooter() { IFS=',' if [[ -n "$RELATED_POSTS" ]]; then if [[ "$IS_FEATURED_INSTEAD_OF_RELATED" == 'true' ]]; then printf '## %s\n' "$TRANSLATION_FEATURED" else printf '## %s\n' "$TRANSLATION_RELATED" fi for post_id in $RELATED_POSTS; do post_id="$(echo "$post_id" | xargs)" post_path="$(getMarkdownPath "$post_id")" post_properties="$(getPostProperties "$post_path")" post_title="$(getTextProperty "$post_properties" title)" post_published_date="$(getTextProperty "$post_properties" publishedDate)" printf '=> %s %s %s\n' "/$post_id/" "$post_published_date" "$post_title" done fi } generateMainMenu() { declare -A menu_items IFS="$DEFAULT_IFS" for post_path in src/content/posts/*.md; do post_properties="$(getPostProperties "$post_path")" post_id="$(basename "$post_path" | sed 's/.md//')" if [[ "$(getTextProperty "$post_properties" putInMainMenu)" == 'true' && "$(getTextProperty "$post_properties" language)" == "$LANGUAGE" && "$post_id" != "$POST_ID" ]]; then main_menu_title="$(getTextProperty "$post_properties" mainMenuTitle)" main_menu_priority="$(getTextProperty "$post_properties" mainMenuPriority)" data=("$post_id" "$main_menu_title") printf -v data_str '%q ' "${data[@]}" menu_items["$main_menu_priority"]="$data_str" fi done mapfile -d '' sorted_menu_indexes < <(printf '%s\0' "${!menu_items[@]}" | sort -z) for index in "${sorted_menu_indexes[@]}"; do printf -v array_cmd "%q=( %s )" "data" "${menu_items["$index"]}" eval "$array_cmd" printf '[%s](%s)\n\n' "${data[1]}" "/${data[0]}/" done } generateLatest() { cat declare -A menu_items IFS="$DEFAULT_IFS" for post_path in src/content/posts/*.md; do post_properties="$(getPostProperties "$post_path")" post_id="$(basename "$post_path" | sed 's/.md//')" if [[ "$(getTextProperty "$post_properties" hideFromLatest)" != 'true' && "$(getTextProperty "$post_properties" language)" == "$LANGUAGE" && "$post_id" != "$POST_ID" ]]; then post_title="$(getTextProperty "$post_properties" title)" post_published_date="$(getTextProperty "$post_properties" publishedDate)" if [[ -z post_published_date ]]; then post_published_date="$post_id" fi data=("$post_id" "$post_title") printf -v data_str '%q ' "${data[@]}" menu_items["$post_published_date"]="$data_str" fi done mapfile -d '' sorted_menu_indexes < <(printf '%s\0' "${!menu_items[@]}" | sort -r -z) $1 if [[ ${#menu_items[@]} != 0 ]]; then echo "##" "$TRANSLATION_LATEST" fi for index in "${sorted_menu_indexes[@]}"; do printf -v array_cmd "%q=( %s )" "data" "${menu_items["$index"]}" eval "$array_cmd" printf '[%s %s](%s)\n\n' "$index" "${data[1]}" "/${data[0]}/" done } replaceWithCommandOutput() { has_executed_additional_command=false while IFS= read -r line; do if [[ "$line" == *"$1"* ]]; then $2 $3 | xargs -0 -I INSERT -- $SHELL -c "echo '$line' | awk -v VAR='INSERT' '{ sub(/$1/, VAR); print; }'" has_executed_additional_command=true else echo "$line" fi done < /dev/stdin if [[ -v 3 && $has_executed_additional_command == false ]]; then $3 fi } generateMeainMenuWithSeparator() { printf '\n---\n' generateMainMenu } set +H # Turn off history substitution to allow using !- in a string sed 's/](..\/..\/assets/](\/assets/g' "$MARKDOWN_POST" \ | generateLatest generateFooter \ | replaceWithCommandOutput '' generateMainMenu generateMeainMenuWithSeparator \ | md2gemini/bin/md2gemini -l paragraph -f -a -p \ | generateHeader \ | tee -a "$1/index.gmi" \ | gemtext2gophermap $1