GEMLOG_NAME="# 無 Muu Online"
GEMLOG_SUMMARY="Гемлог про у-вэй и юникс-вэй"
GEMLOG_FOOTER="© Muu, 2023-2024 - Licensed under CC BY-SA 4.0"
DEFAULT_CATEGORY="Blog"
CONTENT_DIR="content"
OUTPUT_DIR="output"
STATIC_DIR="static"
GEM_BROWSER="amfora"
DEPLOY_SCRIPT="./deploy.sh"
GEM_EDITOR="nvim +star!"
DEBUG=0
case "$1" in
-l)
if [ $DEBUG = 1 ]; then echo "Передан параметр -l, запускаем $GEM_BROWSER"; fi
# скорректируем все абсолютные ссылки для локальной навигации
temp_path=$(pwd)
mkdir -p ./preview
cp -r ./$OUTPUT_DIR/* ./preview
for filename in $(find ./preview -type f | grep gmi); do
# awk в BSD, в отличие от GNU gawk не знает опции -i для инлайн-редактирования,
# поэтому трюк с временным файлом придется проделывать вручную
awk '{gsub("=> /","=> '$(pwd)'/preview/",$0); print $0}' $filename > $filename.tmp
mv $filename.tmp $filename
done
# запускаем браузер для просмотра
$GEM_BROWSER "file:///$(pwd)/preview/index.gmi"
# после просмотра удалим временные файлы
rm -r ./preview
exit 0
;;
-d)
if [ $DEBUG = 1 ]; then echo "Передан параметр -d, запускаем скрипт деплоя ./$DEPLOY_SCRIPT"; fi
if [ ! -e ./$DEPLOY_SCRIPT ]; then
echo "Скрипт $DEPLOY_SCRIPT не найден в текущем каталоге!"
exit 1
else
/bin/sh -c "./$DEPLOY_SCRIPT"
exit 0
fi
;;
-n)
# Проверяем, что указано имя файла для новой статьи
if test -z "$2"; then echo "Не указано имя файла для новой статьи (без расширения .gmi)"; exit 1; fi
# Проверяем, что нет такого файла
if [ -e "./$CONTENT_DIR/$2.gmi" ]; then
echo "Файл $2.gmi уже существует в $CONTENT_DIR!"
exit 1
fi
if [ $DEBUG = 1 ]; then echo "Передан параметр -n, запускаем $GEM_EDITOR для $2.gmi"; fi
# Создаем файл статьи и заполняем шаблон заголовка
echo "# \n" >> "./$CONTENT_DIR/$2.gmi"
echo "Опубликовано: $(date '+%Y-%m-%d')" >> "./$CONTENT_DIR/$2.gmi"
echo "Категория: $DEFAULT_CATEGORY" >> "./$CONTENT_DIR/$2.gmi"
echo "Теги: " >> "./$CONTENT_DIR/$2.gmi"
echo "Статус: черновик (удалить для публикации)" >> "./$CONTENT_DIR/$2.gmi"
$GEM_EDITOR "$CONTENT_DIR/$2.gmi"
# если убрать exit в строке ниже, то после завершения редактирования проект будет пересобираться
# автоматически, но я предпочитаю делать это вручную т.к. часто оставляю незавершенные черновики
exit 0
;;
*)
if [ $DEBUG = 1 ]; then echo "Запуск без параметров: компилируем контент"; fi
;;
esac
mkdir -p "./$OUTPUT_DIR"
echo "Очищаем каталог $OUTPUT_DIR перед использованием..."
rm -r ./$OUTPUT_DIR
echo "Обрабатываем файлы из каталога $CONTENT_DIR..."
for CURRENT_FILE in ./$CONTENT_DIR/*; do
CURRENT_FILE=$(basename $CURRENT_FILE)
# Info-сообщение: какой файл обрабатываем
echo -n "Обрабатываем файл $CURRENT_FILE... "
# Проверяем, гипертекст в файле или другой контент, который нужно положить в папку статики
ext=$(echo $CURRENT_FILE | cut -d "." -f 2)
if [ $ext != "gmi" ]; then
if [ $DEBUG = 1 ]; then
echo "\nФайл $CURRENT_FILE имеет расшиение = $ext, переносим как есть\n-----------------";
else
echo "скопирован."
fi
mkdir -p ./$OUTPUT_DIR/$STATIC_DIR
cp ./$CONTENT_DIR/$CURRENT_FILE ./$OUTPUT_DIR/$STATIC_DIR
else
if [ $DEBUG = 1 ]; then echo "\nФайл $CURRENT_FILE имеет расширение = $ext, парсим метаданные..."; fi
# Определяем статус, если он = черновик, то пропускаем, иначе (иное или просто отсуствует) идем дальше
if test ! -z "$(head ./$CONTENT_DIR/$CURRENT_FILE | grep "Статус: черновик")"; then
if [ $DEBUG = 1 ]; then
echo "Файл $CURRENT_FILE это черновик, пропускаем его.\n-----------------"
else
echo "черновик, пропущен."
fi
else
if [ $DEBUG = 1 ]; then echo "Файл $CURRENT_FILE НЕ является черновиком, продолжаем парсинг..."; fi
# Ищем в файле дату-время публикации по мета DATE (если нет - берем текущее системное время), присваиваем
# DATE_PUB - дата создания в формате YYYY-MM-DD, используется на главной странице
# YEAR = год из DATE_PUB, используется как имя каталога для хранения статьи
# MONTH = месяц из DATE_PUB, используется как имя подкаталога для хранения статьи
if ! $(head ./$CONTENT_DIR/$CURRENT_FILE | grep "Опубликовано: " >/dev/null); then
if [ $DEBUG = 1 ]; then echo "Файл $CURRENT_FILE не содержит даты публикации, используем текущую"; fi
DATE_PUB=$(date '+%Y-%m-%d')
YEAR=$(echo $DATE_PUB | cut -c 1-4)
MONTH=$(echo $DATE_PUB | cut -c 6-7)
else
if [ $DEBUG = 1 ]; then echo "Файл $CURRENT_FILE содержит дату публикации, парсим дату"; fi
DATE_PUB=$(head ./$CONTENT_DIR/$CURRENT_FILE | grep "Опубликовано: " | cut -c 15-24)
YEAR=$(echo $DATE_PUB | cut -c 1-4)
MONTH=$(echo $DATE_PUB | cut -c 6-7)
fi
# Определяем категорию публикации, при отсутствии таковой используем дефолт = Blog
if ! $(head ./$CONTENT_DIR/$CURRENT_FILE | grep "Категория: " >/dev/null); then
if [ $DEBUG = 1 ]; then echo "Файл $CURRENT_FILE не содержит категории, используем ($DEFAULT_CATEGORY)"; fi
CATEGORY=$DEFAULT_CATEGORY
else
if [ $DEBUG = 1 ]; then echo "Файл $CURRENT_FILE содержит категорию, обрабатываем"; fi
CATEGORY=$(head ./$CONTENT_DIR/$CURRENT_FILE | grep "Категория: " | cut -d ":" -f 2 | cut -c 2- | tr -d ' ')
fi
# Определяем тему публикации как первый заголовок любого уровня (символы заголовка и пробел после них уберем)
TITLE=$(grep -m 1 "#" ./$CONTENT_DIR/$CURRENT_FILE | sed 's/#//' | cut -c 2-)
# Определяем теги публикации по мета TAGS = , при отсутствии = ""
TAGS=$(head ./$CONTENT_DIR/$CURRENT_FILE | grep "Теги: " | cut -d ":" -f 2)
# Вывод результатов парсинга в режиме отладки
if [ $DEBUG = 1 ]; then
echo "Файл $CURRENT_FILE, результаты парсинга:"
echo " DATE_PUB = $DATE_PUB"
echo " YEAR = $YEAR"
echo " MONTH = $MONTH"
echo " CATEGORY = $CATEGORY"
echo " TITLE = $TITLE"
echo " TAGS = $TAGS"
echo "-----------------"
else
echo "обработан."
fi
# Создаем (если не существуют) каталоги для года/месяца
mkdir -p "./$OUTPUT_DIR/$YEAR/$MONTH"
# и копируем туда текущий файл
cp "./$CONTENT_DIR/$CURRENT_FILE" "./$OUTPUT_DIR/$YEAR/$MONTH"
# пишем линк для текущего файла в помесячный интекс
echo "=> /$YEAR/$MONTH/$CURRENT_FILE $DATE_PUB - $TITLE" >> ./$OUTPUT_DIR/$YEAR/$MONTH/index.gmi
# и сортируем индекс-файл по дате статьи
sort -k3,3r ./$OUTPUT_DIR/$YEAR/$MONTH/index.gmi -o ./$OUTPUT_DIR/$YEAR/$MONTH/index.gmi
# теперь выводим то же самое в файл категорий, для которы создадим каталог
mkdir -p ./$OUTPUT_DIR/Categories
echo "=> /$YEAR/$MONTH/$CURRENT_FILE $DATE_PUB - $TITLE" >> ./$OUTPUT_DIR/Categories/$CATEGORY.gmi
# в файле данной категории тоже отсортируем записи по дате
sort -k3,3r ./$OUTPUT_DIR/Categories/$CATEGORY.gmi -o ./$OUTPUT_DIR/Categories/$CATEGORY.gmi
# теперь в то же самое для тегов (для каждого создадим свой файл)
mkdir -p ./$OUTPUT_DIR/Tags
# если, конечно, для обрабатываемого файла список тегов вообще не пуст
if test "! -z $TAGS"; then
for current_tag in $TAGS; do
echo "=> /$YEAR/$MONTH/$CURRENT_FILE $DATE_PUB - $TITLE" >> ./$OUTPUT_DIR/Tags/$current_tag.gmi
sort -k3,3r ./$OUTPUT_DIR/Tags/$current_tag.gmi -o ./$OUTPUT_DIR/Tags/$current_tag.gmi
done
fi
# Конец условия, где мы проверяли, что это НЕ черновик
fi
# Конец условия, где мы определяли это файл .gmi и его нужно парсить
fi
done
for cur_file in ./$OUTPUT_DIR/Tags/*; do
sed -i '1i\
'"$GEMLOG_NAME"'
' $cur_file
sed -i '2i\
'"$GEMLOG_SUMMARY"'\
\
' $cur_file
sed -i '3i\
\
' $cur_file
echo "\n=> /Tags/index.gmi К списку тегов" >> $cur_file
echo "=> /index.gmi На главную" >> $cur_file
echo "\n$GEMLOG_FOOTER" >> $cur_file
done
echo "$GEMLOG_NAME" >> ./$OUTPUT_DIR/Tags/index.gmi
echo "$GEMLOG_SUMMARY\n" >> ./$OUTPUT_DIR/Tags/index.gmi
echo "## Список тегов:\n" >> ./$OUTPUT_DIR/Tags/index.gmi
for cur_file in ./$OUTPUT_DIR/Tags/*; do
if [ $cur_file != "./output/Tags/index.gmi" ]; then
echo "=> /Tags/$(basename $cur_file) $(basename $cur_file | cut -d . -f 1)" >> ./$OUTPUT_DIR/Tags/index.gmi
fi
done
echo "\n=> /index.gmi На главную\n" >> ./$OUTPUT_DIR/Tags/index.gmi
echo "$GEMLOG_FOOTER" >> ./$OUTPUT_DIR/Tags/index.gmi
for cur_file in ./$OUTPUT_DIR/Categories/*; do
sed -i '1i\
'"$GEMLOG_NAME"'
' $cur_file
sed -i '2i\
'"$GEMLOG_SUMMARY"'\
\
' $cur_file
sed -i '3i\
\
' $cur_file
echo "\n=> /Categories/index.gmi К списку категорий" >> $cur_file
echo "=> /index.gmi На главную" >> $cur_file
echo "\n$GEMLOG_FOOTER" >> $cur_file
done
echo "$GEMLOG_NAME" >> ./$OUTPUT_DIR/Categories/index.gmi
echo "$GEMLOG_SUMMARY\n" >> ./$OUTPUT_DIR/Categories/index.gmi
echo "## Категории:\n" >> ./$OUTPUT_DIR/Categories/index.gmi
for cur_file in ./$OUTPUT_DIR/Categories/*; do
if [ $cur_file != "./output/Categories/index.gmi" ]; then
echo "=> /Categories/$(basename $cur_file) $(basename $cur_file | cut -d . -f 1)" >> ./$OUTPUT_DIR/Categories/index.gmi
fi
done
echo "\n=> /index.gmi На главную\n" >> ./$OUTPUT_DIR/Categories/index.gmi
echo "$GEMLOG_FOOTER" >> ./$OUTPUT_DIR/Categories/index.gmi
echo "$GEMLOG_NAME" >> ./$OUTPUT_DIR/index.gmi
echo "$GEMLOG_SUMMARY\n" >> ./$OUTPUT_DIR/index.gmi
echo "=> /Categories/index.gmi Поиск по категориям" >> ./$OUTPUT_DIR/index.gmi
echo "=> /Tags/index.gmi Поиск по тегам\n" >> ./$OUTPUT_DIR/index.gmi
for year_dir in $(ls -r ./$OUTPUT_DIR); do
year_dir=$(basename $year_dir)
# если текущий каталог не в списке специальных каталогов 1 уровня
if ! $(echo "Categories Tags static index.gmi" | grep -w -q "$year_dir"); then
echo "## $year_dir\n" >> ./$OUTPUT_DIR/index.gmi
for month_dir in $(ls -r ./$OUTPUT_DIR/$year_dir); do
month_dir=$(basename $month_dir)
# в общем случае, локализованное название месяца может выдать команда date, но увы, это не
# про OpenBSD, где все локали повыпиливали за неимением ресурсов на поддержку и date собрана без них
case "$month_dir" in
"12") month_name="Декабрь" ;;
"11") month_name="Ноябрь" ;;
"10") month_name="Октябрь" ;;
"09") month_name="Сентябрь" ;;
"08") month_name="Август" ;;
"07") month_name="Июль" ;;
"06") month_name="Июнь" ;;
"05") month_name="Май" ;;
"04") month_name="Апрель" ;;
"03") month_name="Март" ;;
"02") month_name="Февраль" ;;
"01") month_name="Январь" ;;
esac
echo "### $month_name \n" >> ./$OUTPUT_DIR/index.gmi
cat ./$OUTPUT_DIR/$year_dir/$month_dir/index.gmi >> ./$OUTPUT_DIR/index.gmi
echo "" >> ./$OUTPUT_DIR/index.gmi
done
fi
done
echo "$GEMLOG_FOOTER" >> ./$OUTPUT_DIR/index.gmi
echo "User-agent: *\nDisallow: /Categories\nDisallow: /Tags\n" >> ./$OUTPUT_DIR/robots.txt
echo "Готово! Контент для гемлога размещен в каталоге $OUTPUT_DIR."
text/plain
This content has been proxied by September (ba2dc).