feat: manifest/caching
This commit is contained in:
42
.gitea/workflows/deploy-website.yml
Normal file
42
.gitea/workflows/deploy-website.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
name: Deploy Website
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy-website:
|
||||
runs-on: local
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Ensure deploy tools are available
|
||||
run: |
|
||||
if ! command -v ssh >/dev/null 2>&1 || ! command -v rsync >/dev/null 2>&1 || ! command -v ssh-keyscan >/dev/null 2>&1; then
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y openssh-client rsync
|
||||
fi
|
||||
|
||||
- name: Build website
|
||||
run: |
|
||||
sh kewt.sh --from site --to out
|
||||
|
||||
- name: Setup SSH
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
printf '%s\n' "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
|
||||
chmod 600 ~/.ssh/id_rsa
|
||||
|
||||
REMOTE_HOST_VAL="${{ secrets.REMOTE_HOST }}"
|
||||
REMOTE_ADDR=$(printf '%s\n' "$REMOTE_HOST_VAL" | awk -F@ '{print $NF}')
|
||||
|
||||
ssh-keyscan -H "$REMOTE_ADDR" >> ~/.ssh/known_hosts
|
||||
|
||||
- name: Deploy website
|
||||
run: |
|
||||
rsync -az --delete \
|
||||
-e "ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no" \
|
||||
out/ "${{ secrets.REMOTE_HOST }}:/var/www/kewt.krzak.org/"
|
||||
@@ -1,20 +0,0 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, master]
|
||||
paths:
|
||||
- '**.sh'
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.sh'
|
||||
|
||||
jobs:
|
||||
shellcheck:
|
||||
runs-on: local
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Shellcheck
|
||||
run: sudo apt-get update && sudo apt-get install -y shellcheck
|
||||
- name: Run Shellcheck
|
||||
run: shellcheck -s sh kewt.sh markdown.sh tools/build-standalone.sh || true
|
||||
17
kewt.sh
17
kewt.sh
@@ -5,15 +5,30 @@ die() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
make_temp_dir() {
|
||||
_temp_base="${TMPDIR:-/tmp}/kewt_run.$$"
|
||||
_temp_try=0
|
||||
while [ "$_temp_try" -lt 1000 ]; do
|
||||
_temp_path="${_temp_base}.${_temp_try}"
|
||||
if (umask 077 && mkdir "$_temp_path") 2>/dev/null; then
|
||||
printf '%s\n' "$_temp_path"
|
||||
return 0
|
||||
fi
|
||||
_temp_try=$((_temp_try + 1))
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
script_dir=$(CDPATH="" cd -- "$(dirname -- "$0")" && pwd)
|
||||
awk_dir="$script_dir/awk"
|
||||
|
||||
KEWT_TMPDIR=$(mktemp -d "/tmp/kewt_run.XXXXXX")
|
||||
KEWT_TMPDIR=$(make_temp_dir) || die "Could not create temporary directory."
|
||||
trap 'rm -rf "$KEWT_TMPDIR"' EXIT
|
||||
trap 'exit 0' HUP INT TERM
|
||||
|
||||
. "$script_dir/lib/config.sh"
|
||||
. "$script_dir/lib/metadata.sh"
|
||||
. "$script_dir/lib/manifest.sh"
|
||||
. "$script_dir/lib/commands.sh"
|
||||
. "$script_dir/lib/generator.sh"
|
||||
. "$script_dir/lib/builder.sh"
|
||||
|
||||
165
lib/builder.sh
165
lib/builder.sh
@@ -1,3 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
needs_rebuild() {
|
||||
src_file="$1"
|
||||
out_file="$2"
|
||||
@@ -30,6 +32,8 @@ write_content_warning_outputs() {
|
||||
build_site() {
|
||||
echo "Building site from '$src' to '$out'..."
|
||||
|
||||
build_markdown_manifest
|
||||
|
||||
eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -type d -print" | sort | while read -r dir; do
|
||||
rel_dir="${dir#"$src"}"
|
||||
rel_dir="${rel_dir#/}"
|
||||
@@ -64,9 +68,8 @@ eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -type d -print" | sort | while
|
||||
is_posts_dir="true"
|
||||
fi
|
||||
if [ "$single_file_index" = "true" ] && [ "$is_posts_dir" = "false" ] && [ "$has_list" = "false" ]; then
|
||||
md_count=$(find "$dir" ! -name "$(basename "$dir")" -prune -name "*.md" | wc -l)
|
||||
if [ "$md_count" -eq 1 ]; then
|
||||
md_file=$(find "$dir" ! -name "$(basename "$dir")" -prune -name "*.md")
|
||||
if load_manifest_dir_entry "$rel_dir" && [ "$dir_md_count" -eq 1 ]; then
|
||||
md_file="$src/$dir_first_md"
|
||||
is_home="false"; [ "$dir" = "$src" ] && is_home="true"
|
||||
target_url=$(directory_index_url "$rel_dir")
|
||||
if needs_rebuild "$md_file" "$out_dir/index.html"; then
|
||||
@@ -117,11 +120,12 @@ eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -type d -print" | sort | while
|
||||
dir_url="$(encode_url_path "$name")/index.html"
|
||||
echo "${name}|- [${name}/](${dir_url})" >> "$temp_entries"
|
||||
elif [ "${entry%.md}" != "$entry" ]; then
|
||||
entry_rel_path="${entry#"$src"/}"
|
||||
load_manifest_entry "$entry_rel_path" || continue
|
||||
label="${name%.md}"
|
||||
set_post_metadata "$entry" ""
|
||||
[ "$fm_draft" = "true" ] && continue
|
||||
[ "$manifest_draft" = "true" ] && continue
|
||||
|
||||
post_h="$post_heading"
|
||||
post_h="$manifest_title"
|
||||
|
||||
is_post_entry="false"
|
||||
if is_posts_directory_rel "$rel_dir"; then
|
||||
@@ -130,23 +134,23 @@ eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -type d -print" | sort | while
|
||||
|
||||
if [ -n "$post_h" ]; then
|
||||
if [ "$is_post_entry" = "true" ]; then
|
||||
if [ -n "$post_time" ]; then
|
||||
label="$post_h - $post_date $post_time"
|
||||
if [ -n "$manifest_post_time" ]; then
|
||||
label="$post_h - $manifest_post_date $manifest_post_time"
|
||||
else
|
||||
label="$post_h - $post_date"
|
||||
label="$post_h - $manifest_post_date"
|
||||
fi
|
||||
else
|
||||
label="$post_h"
|
||||
fi
|
||||
elif [ "$is_post_entry" = "true" ]; then
|
||||
if [ -n "$post_time" ]; then
|
||||
label="$post_date $post_time"
|
||||
if [ -n "$manifest_post_time" ]; then
|
||||
label="$manifest_post_date $manifest_post_time"
|
||||
else
|
||||
label="$post_date"
|
||||
label="$manifest_post_date"
|
||||
fi
|
||||
fi
|
||||
if [ "$is_post_entry" = "true" ]; then
|
||||
sort_key="${post_date} ${post_time}"
|
||||
sort_key="${manifest_post_date} ${manifest_post_time}"
|
||||
else
|
||||
sort_key="$name"
|
||||
fi
|
||||
@@ -196,7 +200,8 @@ eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -type d -print" | sort | while
|
||||
num_items=$(wc -l < "$temp_list")
|
||||
if [ "$is_posts_dir" = "true" ] && [ -n "$posts_per_page" ] && [ "$posts_per_page" -gt 0 ] && [ "$num_items" -gt "$posts_per_page" ]; then
|
||||
num_pages=$(( (num_items + posts_per_page - 1) / posts_per_page ))
|
||||
for p in $(seq 1 $num_pages); do
|
||||
p=1
|
||||
while [ "$p" -le "$num_pages" ]; do
|
||||
chunk_list="$KEWT_TMPDIR/chunk.md"
|
||||
start_line=$(( (p - 1) * posts_per_page + 1 ))
|
||||
tail -n +$start_line "$temp_list" | head -n "$posts_per_page" > "$chunk_list"
|
||||
@@ -255,6 +260,7 @@ eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -type d -print" | sort | while
|
||||
|
||||
render_markdown "$temp_index_p" "$is_home" "$target_url_p" > "$out_file"
|
||||
rm -f "$temp_index_p" "$chunk_list"
|
||||
p=$((p + 1))
|
||||
done
|
||||
else
|
||||
if [ "$has_custom_index" = "true" ]; then
|
||||
@@ -352,23 +358,21 @@ eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -type f -print" | sort | while
|
||||
fi
|
||||
|
||||
if [ "$single_file_index" = "true" ] && [ "${file%.md}" != "$file" ] && [ "$is_preserved" -eq 0 ] && [ ! -f "$(dirname "$file")/index.md" ] && [ "$is_posts_dir_2" = "false" ]; then
|
||||
md_count=$(find "$(dirname "$file")" ! -name "$(basename "$(dirname "$file")")" -prune -name "*.md" | wc -l)
|
||||
[ "$md_count" -eq 1 ] && continue
|
||||
load_manifest_dir_entry "$dir_rel" && [ "$dir_md_count" -eq 1 ] && continue
|
||||
fi
|
||||
|
||||
if [ "${file%.md}" != "$file" ] && [ "$is_preserved" -eq 0 ]; then
|
||||
# Skip draft files
|
||||
parse_frontmatter "$file"
|
||||
if [ "$fm_draft" = "true" ]; then
|
||||
continue
|
||||
fi
|
||||
load_manifest_entry "$rel_path" || continue
|
||||
[ "$manifest_draft" = "true" ] && continue
|
||||
is_home="false"; [ "$file" = "$src/index.md" ] && is_home="true"
|
||||
out_file="$out/${rel_path%.md}.html"
|
||||
if needs_rebuild "$file" "$out_file"; then
|
||||
if [ -n "$fm_content_warning" ]; then
|
||||
fm_title="$manifest_title"
|
||||
fm_content_warning="$manifest_content_warning"
|
||||
if [ -n "$manifest_content_warning" ]; then
|
||||
content_out_file="$out/${rel_path%.md}-content.html"
|
||||
content_rel_url="/$(encode_url_path "${rel_path%.md}")-content.html"
|
||||
orig_rel_url=$(markdown_file_url "$rel_path")
|
||||
orig_rel_url="$manifest_url"
|
||||
write_content_warning_outputs "$file" "$content_out_file" "$content_rel_url" "$orig_rel_url" "$out_file" "$is_home"
|
||||
else
|
||||
render_markdown "$file" "$is_home" > "$out_file"
|
||||
@@ -433,44 +437,32 @@ if [ "$generate_feed" = "true" ] && [ -n "$base_url" ]; then
|
||||
temp_feed_files="$KEWT_TMPDIR/feed_files_$$.txt"
|
||||
: > "$temp_feed_files"
|
||||
|
||||
find "$src" -type f -name '*.md' -path "*${posts_dir:-__no_posts__}*" -print | while IFS= read -r post_file; do
|
||||
post_basename=$(basename "$post_file" .md)
|
||||
parse_frontmatter "$post_file"
|
||||
[ "$fm_draft" = "true" ] && continue
|
||||
set_post_datetime "$fm_date" "$post_basename"
|
||||
echo "${post_date} ${post_time}|${post_file}" >> "$temp_feed_files"
|
||||
done
|
||||
while IFS= read -r manifest_rel_path; do
|
||||
case "$manifest_rel_path" in
|
||||
*"${posts_dir:-__no_posts__}"*) ;;
|
||||
*) continue ;;
|
||||
esac
|
||||
load_manifest_entry "$manifest_rel_path" || continue
|
||||
[ "$manifest_draft" = "true" ] && continue
|
||||
printf '%s %s|%s\n' "$manifest_post_date" "$manifest_post_time" "$manifest_rel_path" >> "$temp_feed_files"
|
||||
done < "$manifest_all_list"
|
||||
|
||||
LC_ALL=C sort -r "$temp_feed_files" | cut -d'|' -f2- | while IFS= read -r post_file; do
|
||||
post_basename=$(basename "$post_file" .md)
|
||||
parse_frontmatter "$post_file"
|
||||
[ "$fm_draft" = "true" ] && continue
|
||||
set_post_metadata "$post_file" "Post"
|
||||
LC_ALL=C sort -r "$temp_feed_files" | cut -d'|' -f2- | while IFS= read -r post_rel_path; do
|
||||
load_manifest_entry "$post_rel_path" || continue
|
||||
[ "$manifest_draft" = "true" ] && continue
|
||||
|
||||
post_date="$manifest_post_date"
|
||||
post_time="$manifest_post_time"
|
||||
post_heading="$manifest_title"
|
||||
post_slug="$manifest_post_slug"
|
||||
if [ -z "$post_heading" ] && [ -n "$post_slug" ] && ! echo "$post_slug" | grep -q '^[0-9]\+$'; then
|
||||
post_heading=$(echo "$post_slug" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)}1')
|
||||
fi
|
||||
feed_post_title="$post_heading - $post_date $post_time"
|
||||
|
||||
rel_path="${post_file#"$src"}"
|
||||
rel_path="${rel_path#/}"
|
||||
post_url="$base_url_feed$(markdown_file_url "$rel_path")"
|
||||
post_url="$base_url_feed$manifest_url"
|
||||
|
||||
if date -u -d "$post_date $post_time" '+%a, %d %b %Y %H:%M:%S +0000' >/dev/null 2>&1; then
|
||||
pub_date=$(date -u -d "$post_date $post_time" '+%a, %d %b %Y %H:%M:%S +0000')
|
||||
else
|
||||
pub_year=$(echo "$post_date" | cut -d- -f1)
|
||||
pub_month=$(echo "$post_date" | cut -d- -f2)
|
||||
pub_day=$(echo "$post_date" | cut -d- -f3)
|
||||
# zero-padded
|
||||
pub_day=$(printf '%02d' "${pub_day#0}")
|
||||
case "$pub_month" in
|
||||
01) pub_mon="Jan" ;; 02) pub_mon="Feb" ;; 03) pub_mon="Mar" ;;
|
||||
04) pub_mon="Apr" ;; 05) pub_mon="May" ;; 06) pub_mon="Jun" ;;
|
||||
07) pub_mon="Jul" ;; 08) pub_mon="Aug" ;; 09) pub_mon="Sep" ;;
|
||||
10) pub_mon="Oct" ;; 11) pub_mon="Nov" ;; 12) pub_mon="Dec" ;;
|
||||
esac
|
||||
pub_date="Mon, ${pub_day} ${pub_mon} ${pub_year} ${post_time}:00 +0000"
|
||||
fi
|
||||
pub_date=$(format_rfc2822_utc "$post_date" "$post_time")
|
||||
|
||||
{
|
||||
printf ' <item>\n'
|
||||
@@ -494,25 +486,25 @@ if [ "$generate_search" = "true" ] || [ "$generate_tags" = "true" ]; then
|
||||
temp_tags="$KEWT_TMPDIR/tags_$$.txt"
|
||||
: > "$temp_tags"
|
||||
|
||||
eval "find \"$src\" \( $IGNORE_ARGS -o $HIDE_ARGS -o $PRESERVE_ARGS \) -prune -o -name \"*.md\" -print" | sort | while IFS= read -r md_file; do
|
||||
is_index="false"
|
||||
[ "$(basename "$md_file")" = "index.md" ] && is_index="true"
|
||||
while IFS= read -r rel_path; do
|
||||
load_manifest_entry "$rel_path" || continue
|
||||
|
||||
rel_path="${md_file#"$src"}"
|
||||
rel_path="${rel_path#/}"
|
||||
if [ "$is_index" = "true" ]; then
|
||||
if [ "$manifest_is_index" = "true" ]; then
|
||||
if [ "$rel_path" = "index.md" ]; then
|
||||
md_url="/index.html"
|
||||
else
|
||||
md_url=$(directory_index_url "${rel_path%/index.md}")
|
||||
fi
|
||||
else
|
||||
md_url=$(markdown_file_url "$rel_path")
|
||||
md_url="$manifest_url"
|
||||
if [ "$single_file_index" = "true" ]; then
|
||||
dir_of_file="$(dirname "$md_file")"
|
||||
rel_dir_of_file="${dir_of_file#"$src"}"
|
||||
rel_dir_of_file="${rel_dir_of_file#/}"
|
||||
rel_dir_of_file="$manifest_dir_rel"
|
||||
[ -z "$rel_dir_of_file" ] && rel_dir_of_file="."
|
||||
if [ "$rel_dir_of_file" = "." ]; then
|
||||
dir_of_file="$src"
|
||||
else
|
||||
dir_of_file="$src/$rel_dir_of_file"
|
||||
fi
|
||||
|
||||
is_posts_dir_search="false"
|
||||
if [ -n "$posts_dir" ] && { [ "$rel_dir_of_file" = "$posts_dir" ] || [ "./$rel_dir_of_file" = "$posts_dir" ]; }; then
|
||||
@@ -520,8 +512,7 @@ if [ "$generate_search" = "true" ] || [ "$generate_tags" = "true" ]; then
|
||||
fi
|
||||
|
||||
if [ "$is_posts_dir_search" = "false" ] && [ ! -f "$dir_of_file/index.md" ]; then
|
||||
md_count_search=$(find "$dir_of_file" ! -name "$(basename "$dir_of_file")" -prune -name "*.md" | wc -l)
|
||||
if [ "$md_count_search" -eq 1 ]; then
|
||||
if load_manifest_dir_entry "$rel_dir_of_file" && [ "$dir_md_count" -eq 1 ]; then
|
||||
if [ "$rel_dir_of_file" = "." ]; then
|
||||
md_url="/index.html"
|
||||
else
|
||||
@@ -532,38 +523,12 @@ if [ "$generate_search" = "true" ] || [ "$generate_tags" = "true" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
parse_frontmatter "$md_file"
|
||||
[ "$fm_draft" = "true" ] && continue
|
||||
|
||||
markdown_title_from_loaded_file "$md_file" "$title - Page"
|
||||
md_heading="$markdown_title"
|
||||
[ "$manifest_draft" = "true" ] && continue
|
||||
md_heading="$manifest_title"
|
||||
|
||||
if [ "$generate_search" = "true" ]; then
|
||||
if [ -z "$fm_content_warning" ] || [ "$include_cw_pages_in_search" = "true" ]; then
|
||||
md_content=$(awk '{
|
||||
if (NR == 1 && $0 == "---") { in_fm = 1; next }
|
||||
if (in_fm && $0 == "---") { in_fm = 0; next }
|
||||
if (in_fm) next
|
||||
if ($0 ~ /^```/) { in_code = !in_code; next }
|
||||
if (in_code) next
|
||||
print
|
||||
}' "$md_file" | sed \
|
||||
-e 's/^#\{1,6\} //' \
|
||||
-e 's/\*\*\([^*]*\)\*\*/\1/g' \
|
||||
-e 's/\*\([^*]*\)\*/\1/g' \
|
||||
-e 's/__\([^_]*\)__/\1/g' \
|
||||
-e 's/_\([^_]*\)_/\1/g' \
|
||||
-e 's/`\([^`]*\)`/\1/g' \
|
||||
-e 's/\[\([^]]*\)](\([^)]*\))/\1/g' \
|
||||
-e 's/!\[\([^]]*\)](\([^)]*\))//g' \
|
||||
-e 's/^[[:space:]]*[-*+] //' \
|
||||
-e 's/^[[:space:]]*[0-9]\{1,\}\. //' \
|
||||
-e 's/^>[[:space:]]*//' \
|
||||
-e 's/<[^>]*>//g' \
|
||||
-e '/^[[:space:]]*$/d' \
|
||||
-e 's/|//g' \
|
||||
-e 's/^[[:space:]]*---[[:space:]]*$//' \
|
||||
| tr '\n' ' ' | sed -e 's/ */ /g' -e 's/\\/\\\\/g' -e 's/"/\\"/g' | head -c 500)
|
||||
if [ -z "$manifest_content_warning" ] || [ "$include_cw_pages_in_search" = "true" ]; then
|
||||
md_content="$manifest_search_content"
|
||||
if [ "$first_search_item" = "false" ]; then
|
||||
printf ',\n' >> "$out/search.json"
|
||||
fi
|
||||
@@ -572,17 +537,17 @@ if [ "$generate_search" = "true" ] || [ "$generate_tags" = "true" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$generate_tags" = "true" ] && [ -n "$fm_tags" ]; then
|
||||
if [ "$generate_tags" = "true" ] && [ -n "$manifest_tags" ]; then
|
||||
old_ifs=$IFS
|
||||
IFS=','
|
||||
for tag in $fm_tags; do
|
||||
for tag in $manifest_tags; do
|
||||
tag=$(echo "$tag" | sed 's/^[ \t]*//;s/[ \t]*$//')
|
||||
[ -z "$tag" ] && continue
|
||||
printf '%s|%s|%s\n' "$tag" "$md_url" "$md_heading" >> "$temp_tags"
|
||||
done
|
||||
IFS=$old_ifs
|
||||
fi
|
||||
done
|
||||
done < "$manifest_visible_list"
|
||||
|
||||
if [ "$generate_search" = "true" ]; then
|
||||
printf '\n]\n' >> "$out/search.json"
|
||||
@@ -614,7 +579,7 @@ if [ "$generate_search" = "true" ] || [ "$generate_tags" = "true" ]; then
|
||||
cut -d'|' -f1 "$temp_tags" | sort -u | while IFS= read -r tag; do
|
||||
tag_slug=$(echo "$tag" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g')
|
||||
|
||||
echo "- [$tag](/$(echo $tags_dir | sed 's|^\/||; s|\/$||')/$tag_slug.html)" >> "$tags_index_md"
|
||||
echo "- [$tag](/$(echo "$tags_dir" | sed 's|^\/||; s|\/$||')/$tag_slug.html)" >> "$tags_index_md"
|
||||
|
||||
tag_page_md="$KEWT_TMPDIR/tag_page_$$.md"
|
||||
echo "# Tag: $tag" > "$tag_page_md"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
usage() {
|
||||
invoked_as=$(basename "${KEWT_INVOKED_AS:-$0}")
|
||||
cat <<EOF
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
DEFAULT_CONF='title = "kewt"
|
||||
style = "kewt"
|
||||
lang = "en"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
SEARCH_FORM_FOOTER='<form class="kewt-search-footer" action="/search.html" method="get"><input type="text" name="q" placeholder="Search..." required><button type="submit">Go</button></form>'
|
||||
SEARCH_FORM_HEADER='<form class="kewt-search-header" action="/search.html" method="get"><input type="text" name="q" placeholder="Search..." required><button type="submit">Go</button></form>'
|
||||
SEARCH_FORM_NAV='<div class="kewt-search-nav"><form action="/search.html" method="get"><input type="text" name="q" placeholder="Search..." required><button type="submit">Go</button></form></div>'
|
||||
|
||||
166
lib/manifest.sh
Normal file
166
lib/manifest.sh
Normal file
@@ -0,0 +1,166 @@
|
||||
#!/bin/sh
|
||||
|
||||
shell_quote() {
|
||||
printf "'%s'" "$(printf '%s' "$1" | sed "s/'/'\\\\''/g")"
|
||||
}
|
||||
|
||||
manifest_meta_path() {
|
||||
printf '%s/manifest/meta/%s.meta\n' "$KEWT_TMPDIR" "$1"
|
||||
}
|
||||
|
||||
manifest_dir_meta_path() {
|
||||
printf '%s/manifest/dir-meta/%s.meta\n' "$KEWT_TMPDIR" "$1"
|
||||
}
|
||||
|
||||
write_manifest_dir_meta() {
|
||||
_dir_meta_rel="$1"
|
||||
_dir_meta_count="$2"
|
||||
_dir_meta_first="$3"
|
||||
_dir_meta_has_index="$4"
|
||||
_dir_meta_path=$(manifest_dir_meta_path "$_dir_meta_rel")
|
||||
mkdir -p "$(dirname "$_dir_meta_path")"
|
||||
{
|
||||
printf 'dir_manifest_rel=%s\n' "$(shell_quote "$_dir_meta_rel")"
|
||||
printf 'dir_md_count=%s\n' "$(shell_quote "$_dir_meta_count")"
|
||||
printf 'dir_first_md=%s\n' "$(shell_quote "$_dir_meta_first")"
|
||||
printf 'dir_has_index=%s\n' "$(shell_quote "$_dir_meta_has_index")"
|
||||
} > "$_dir_meta_path"
|
||||
}
|
||||
|
||||
load_manifest_dir_entry() {
|
||||
_dir_manifest_rel="$1"
|
||||
_dir_manifest_meta_path=$(manifest_dir_meta_path "$_dir_manifest_rel")
|
||||
[ -f "$_dir_manifest_meta_path" ] || return 1
|
||||
# shellcheck disable=SC1090
|
||||
. "$_dir_manifest_meta_path"
|
||||
}
|
||||
|
||||
load_manifest_entry() {
|
||||
_manifest_rel_path="$1"
|
||||
_manifest_meta_path=$(manifest_meta_path "$_manifest_rel_path")
|
||||
[ -f "$_manifest_meta_path" ] || return 1
|
||||
# shellcheck disable=SC1090
|
||||
. "$_manifest_meta_path"
|
||||
}
|
||||
|
||||
extract_search_content() {
|
||||
_search_file="$1"
|
||||
awk '{
|
||||
if (NR == 1 && $0 == "---") { in_fm = 1; next }
|
||||
if (in_fm && $0 == "---") { in_fm = 0; next }
|
||||
if (in_fm) next
|
||||
if ($0 ~ /^```/) { in_code = !in_code; next }
|
||||
if (in_code) next
|
||||
print
|
||||
}' "$_search_file" | sed \
|
||||
-e 's/^#\{1,6\} //' \
|
||||
-e 's/\*\*\([^*]*\)\*\*/\1/g' \
|
||||
-e 's/\*\([^*]*\)\*/\1/g' \
|
||||
-e 's/__\([^_]*\)__/\1/g' \
|
||||
-e 's/_\([^_]*\)_/\1/g' \
|
||||
-e 's/`\([^`]*\)`/\1/g' \
|
||||
-e 's/\[\([^]]*\)](\([^)]*\))/\1/g' \
|
||||
-e 's/!\[\([^]]*\)](\([^)]*\))//g' \
|
||||
-e 's/^[[:space:]]*[-*+] //' \
|
||||
-e 's/^[[:space:]]*[0-9]\{1,\}\. //' \
|
||||
-e 's/^>[[:space:]]*//' \
|
||||
-e 's/<[^>]*>//g' \
|
||||
-e '/^[[:space:]]*$/d' \
|
||||
-e 's/|//g' \
|
||||
-e 's/^[[:space:]]*---[[:space:]]*$//' |
|
||||
tr '\n' ' ' |
|
||||
sed -e 's/ */ /g' -e 's/\\/\\\\/g' -e 's/"/\\"/g' |
|
||||
awk '{ print substr($0, 1, 500) }'
|
||||
}
|
||||
|
||||
build_markdown_manifest() {
|
||||
manifest_root="$KEWT_TMPDIR/manifest"
|
||||
manifest_meta_root="$manifest_root/meta"
|
||||
manifest_dir_meta_root="$manifest_root/dir-meta"
|
||||
manifest_all_list="$manifest_root/all.lst"
|
||||
manifest_visible_list="$manifest_root/visible.lst"
|
||||
|
||||
rm -rf "$manifest_root"
|
||||
mkdir -p "$manifest_meta_root"
|
||||
mkdir -p "$manifest_dir_meta_root"
|
||||
: > "$manifest_all_list"
|
||||
: > "$manifest_visible_list"
|
||||
|
||||
eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -name \"*.md\" -print" | sort | while IFS= read -r manifest_file; do
|
||||
manifest_rel_path="${manifest_file#"$src"/}"
|
||||
manifest_dir_rel=$(dirname "$manifest_rel_path")
|
||||
manifest_filename=$(basename "$manifest_rel_path")
|
||||
manifest_is_index="false"
|
||||
[ "$manifest_filename" = "index.md" ] && manifest_is_index="true"
|
||||
|
||||
parse_frontmatter "$manifest_file"
|
||||
markdown_title_from_loaded_file "$manifest_file" "$title - Page"
|
||||
manifest_title="$markdown_title"
|
||||
set_post_datetime "$fm_date" "$(basename "$manifest_file" .md)"
|
||||
|
||||
manifest_post_date="$post_date"
|
||||
manifest_post_time="$post_time"
|
||||
manifest_post_slug=$(basename "$manifest_file" .md | sed \
|
||||
-e 's/^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{2\}[:\-][0-9]\{2\}//' \
|
||||
-e 's/^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}//' \
|
||||
-e 's/^[_\-]//')
|
||||
|
||||
if [ "$manifest_is_index" = "true" ]; then
|
||||
if [ "$manifest_rel_path" = "index.md" ]; then
|
||||
manifest_url="/index.html"
|
||||
else
|
||||
manifest_url=$(directory_index_url "${manifest_rel_path%/index.md}")
|
||||
fi
|
||||
else
|
||||
manifest_url=$(markdown_file_url "$manifest_rel_path")
|
||||
fi
|
||||
|
||||
manifest_search_content=""
|
||||
if [ "$generate_search" = "true" ]; then
|
||||
manifest_search_content=$(extract_search_content "$manifest_file")
|
||||
fi
|
||||
|
||||
manifest_meta_file=$(manifest_meta_path "$manifest_rel_path")
|
||||
mkdir -p "$(dirname "$manifest_meta_file")"
|
||||
{
|
||||
printf 'manifest_rel_path=%s\n' "$(shell_quote "$manifest_rel_path")"
|
||||
printf 'manifest_dir_rel=%s\n' "$(shell_quote "$manifest_dir_rel")"
|
||||
printf 'manifest_filename=%s\n' "$(shell_quote "$manifest_filename")"
|
||||
printf 'manifest_is_index=%s\n' "$(shell_quote "$manifest_is_index")"
|
||||
printf 'manifest_title=%s\n' "$(shell_quote "$manifest_title")"
|
||||
printf 'manifest_date=%s\n' "$(shell_quote "$fm_date")"
|
||||
printf 'manifest_draft=%s\n' "$(shell_quote "$fm_draft")"
|
||||
printf 'manifest_description=%s\n' "$(shell_quote "$fm_description")"
|
||||
printf 'manifest_content_warning=%s\n' "$(shell_quote "$fm_content_warning")"
|
||||
printf 'manifest_tags=%s\n' "$(shell_quote "$fm_tags")"
|
||||
printf 'manifest_url=%s\n' "$(shell_quote "$manifest_url")"
|
||||
printf 'manifest_search_content=%s\n' "$(shell_quote "$manifest_search_content")"
|
||||
printf 'manifest_post_date=%s\n' "$(shell_quote "$manifest_post_date")"
|
||||
printf 'manifest_post_time=%s\n' "$(shell_quote "$manifest_post_time")"
|
||||
printf 'manifest_post_slug=%s\n' "$(shell_quote "$manifest_post_slug")"
|
||||
} > "$manifest_meta_file"
|
||||
|
||||
if load_manifest_dir_entry "$manifest_dir_rel"; then
|
||||
:
|
||||
else
|
||||
dir_md_count=0
|
||||
dir_first_md=""
|
||||
dir_has_index="false"
|
||||
fi
|
||||
|
||||
dir_md_count=$((dir_md_count + 1))
|
||||
if [ -z "$dir_first_md" ]; then
|
||||
dir_first_md="$manifest_rel_path"
|
||||
fi
|
||||
if [ "$manifest_filename" = "index.md" ]; then
|
||||
dir_has_index="true"
|
||||
fi
|
||||
write_manifest_dir_meta "$manifest_dir_rel" "$dir_md_count" "$dir_first_md" "$dir_has_index"
|
||||
|
||||
printf '%s\n' "$manifest_rel_path" >> "$manifest_all_list"
|
||||
done
|
||||
|
||||
eval "find \"$src\" \( $IGNORE_ARGS -o $HIDE_ARGS -o $PRESERVE_ARGS \) -prune -o -name \"*.md\" -print" | sort | while IFS= read -r visible_file; do
|
||||
printf '%s\n' "${visible_file#"$src"/}" >> "$manifest_visible_list"
|
||||
done
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
parse_frontmatter() {
|
||||
_fm_file="$1"
|
||||
_fm_out="$KEWT_TMPDIR/fm_vals.txt"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
trim_whitespace() {
|
||||
printf '%s' "$1" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//'
|
||||
}
|
||||
@@ -26,6 +28,43 @@ directory_index_url() {
|
||||
fi
|
||||
}
|
||||
|
||||
format_rfc2822_utc() {
|
||||
_rfc_date="$1"
|
||||
_rfc_time="${2:-00:00}"
|
||||
[ -n "$_rfc_time" ] || _rfc_time="00:00"
|
||||
awk -v d="$_rfc_date" -v t="$_rfc_time" '
|
||||
function weekday(y, m, day, k, j, h) {
|
||||
if (m < 3) {
|
||||
m += 12
|
||||
y--
|
||||
}
|
||||
k = y % 100
|
||||
j = int(y / 100)
|
||||
h = (day + int((13 * (m + 1)) / 5) + k + int(k / 4) + int(j / 4) + 5 * j) % 7
|
||||
return (h + 6) % 7
|
||||
}
|
||||
BEGIN {
|
||||
split(d, da, "-")
|
||||
split(t, ti, ":")
|
||||
year = da[1] + 0
|
||||
month = da[2] + 0
|
||||
day = da[3] + 0
|
||||
hour = (ti[1] == "" ? 0 : ti[1]) + 0
|
||||
minute = (ti[2] == "" ? 0 : ti[2]) + 0
|
||||
|
||||
months[1] = "Jan"; months[2] = "Feb"; months[3] = "Mar"; months[4] = "Apr"
|
||||
months[5] = "May"; months[6] = "Jun"; months[7] = "Jul"; months[8] = "Aug"
|
||||
months[9] = "Sep"; months[10] = "Oct"; months[11] = "Nov"; months[12] = "Dec"
|
||||
|
||||
days[0] = "Sun"; days[1] = "Mon"; days[2] = "Tue"; days[3] = "Wed"
|
||||
days[4] = "Thu"; days[5] = "Fri"; days[6] = "Sat"
|
||||
|
||||
printf "%s, %02d %s %04d %02d:%02d:00 +0000\n",
|
||||
days[weekday(year, month, day)], day, months[month], year, hour, minute
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
append_find_rule() {
|
||||
_expr="$1"
|
||||
_rule="$2"
|
||||
@@ -72,7 +111,7 @@ append_nested_marker_rules() {
|
||||
|
||||
find "$_root" -name "$_marker" > "$_tmp_file"
|
||||
while IFS= read -r marker_path; do
|
||||
marker_dir="${marker_path%/$marker}"
|
||||
marker_dir="${marker_path%/"$marker"}"
|
||||
if [ "$marker_dir" != "$_root" ] && [ "$marker_dir" != "." ]; then
|
||||
_expr=$(append_find_rule "$_expr" "-path '$marker_dir'")
|
||||
_expr=$(append_find_rule "$_expr" "-path '$marker_dir/*'")
|
||||
@@ -130,7 +169,7 @@ refresh_build_context() {
|
||||
|
||||
asset_version=""
|
||||
if [ "$versioning" = "true" ]; then
|
||||
asset_version="?v=$(date +%s)"
|
||||
asset_version="?v=$(date '+%Y%m%d%H%M%S')"
|
||||
fi
|
||||
|
||||
resolve_template_path
|
||||
|
||||
@@ -15,7 +15,8 @@ sed_inplace() {
|
||||
fi
|
||||
}
|
||||
|
||||
temp_file=$(mktemp "${KEWT_TMPDIR:-/tmp}/markdown.XXXXXX")
|
||||
temp_parent="${KEWT_TMPDIR:-${TMPDIR:-/tmp}}"
|
||||
temp_file="${temp_parent}/markdown.$$.md"
|
||||
cat "$@" > "$temp_file"
|
||||
|
||||
trap 'rm -f "$temp_file" "$temp_file.tmp" "$temp_file.fm"' EXIT INT TERM
|
||||
|
||||
Reference in New Issue
Block a user