#!/bin/sh
export author="Liv"
web_url="https://liv.envs.net/"
# All files in static dir will be copied directly to public dir, files in assets will not be copied
base_dirs="./static ./assets ./public ./content ./layouts ./assets"
root_file="./layouts/root.html"
head_file="./layouts/head.html"
header_file="./layouts/header.html"
footer_file="./layouts/footer.html"
temp_list=$(mktemp)
temp_xml=$(mktemp)
trap 'rm "$temp_list" "$temp_xml"' EXIT
show_help() {
cat << EOF
Usage: $0 [options]
-h, --help Show this help message
-i, --init Create default directories and templates
EOF
}
process_template() {
if [ -n "$css" ]; then
css_content=$(cat << EOF
EOF
)
fi
awk -v css="$css_content" '
BEGIN {
split("title description keywords author", keys)
}
/^\+\+\+$/ { in_p = !in_p; next }
in_p { next }
{
line = $0
for (i in keys) {
k = keys[i]; v = ENVIRON[k]; pat = "{{ *" k " *}}"
if (v != "") gsub(pat, v, line)
else if (line ~ pat) next
}
if (css != "") sub("", css "\n", line)
print line
}' "$1" > "$2"
}
extract_preamble() {
unset title date description keywords css
eval "$(awk '/^\+\+\+$/{if(++c==2) exit; next} c==1' "$1")"
export title date description keywords css
}
apply_layout() {
sed "
/{{ *main *}}/ { r ${1}
d; }
/{{ *head *}}/ { r ${head_file}
d; }
/{{ *header *}}/ { r ${header_file}
d; }
/{{ *footer *}}/ { r ${footer_file}
d; }
" "$root_file" > "${2}.tmp"
process_template "$2.tmp" "$2"
rm "$2.tmp"
}
compile_rss() {
extract_preamble "./content/index.html"
cat << EOF > "./public/index.xml"
${title}
${web_url}
${web_url}favicon.ico
${description}
en
$(date -u -R)
EOF
if [ -s "$temp_xml" ]; then
sort -r "$temp_xml" | sed 's/^[^|]*|//' | tr '\001' '\n' | sed '/^$/d' >> "./public/index.xml"
fi
cat << EOF >> "./public/index.xml"
EOF
}
compile_content() {
item_count=0
find "./content/" -type f -name "*.html" ! -name "index.html" | while IFS= read -r file; do
extract_preamble "$file"
temp="${file#./content/}"
dest_path="./public/${temp%.html}/"
dest="${dest_path}index.html"
url="./${temp%.html}/"
mkdir -p "$dest_path"
apply_layout "$file" "$dest"
item_count=$((item_count + 1))
sortable_date=$(date -d "$date" +%Y%m%d%H%M%S)$(printf "%04d" "$item_count")
if [ -n "$description" ]; then
echo "
${date} ${title}${description}" >> "$temp_list"
else
echo "${date} ${title}" >> "$temp_list"
fi
{
cat << EOF
-
${title}
${web_url}${url#./}
$(date -d "${date}" -u -R)
${web_url}${url#./}
EOF
if [ -n "$description" ]; then
cat << EOF
${description}
EOF
fi
echo "
"
} | tr '\n' '\001' | awk -v key="$sortable_date" '{print key "|" $0}' >> "$temp_xml"
done
}
compile_index() {
find "./content/" -type f -name "index.html" | sort | while IFS= read -r file; do
extract_preamble "$file"
temp="${file#./content/}"
dest_path="./public/${temp%index.html}"
dest="${dest_path}index.html"
mkdir -p "$dest_path"
sorted_list=$(mktemp)
{
cat "$file"
echo ""
if [ "$dest" = "./public/index.html" ]; then
sort -r "$temp_list" | head -n 5
cat << EOF
More blogs
EOF
else
sort -r "$temp_list" | sed "s|/blogs/|/|g"
echo ""
fi
} > "$sorted_list"
apply_layout "$sorted_list" "$dest"
rm "$sorted_list"
done
}
init() {
for dir in $base_dirs; do
mkdir -p "$dir"
done
[ ! -f "$root_file" ] && cat << 'EOF' > "$root_file"
{{head}}
{{main}}
EOF
[ ! -f "$footer_file" ] && cat << 'EOF' > "$footer_file"
All rights reserved.
EOF
[ ! -f "$head_file" ] && cat << 'EOF' > "$head_file"
{{title}}
EOF
[ ! -f "$header_file" ] && cat << 'EOF' > "$header_file"
{{title}}
EOF
}
# Main execution
while [ "$#" -gt 0 ]; do
case $1 in
-h|--help) show_help; exit 0 ;;
-i|--init) init; exit 0 ;;
*) echo "Unknown flag '$1'"; show_help; exit 1 ;;
esac
done
# Check dirs
for dir in $base_dirs; do
if [ ! -d "$dir" ]; then
echo "Run $0 --init first!"
exit 1
fi
done
rm -r public/
mkdir -p public/
cp -r static/. public/
compile_content
compile_index
compile_rss