195 lines
No EOL
5.9 KiB
Bash
Executable file
195 lines
No EOL
5.9 KiB
Bash
Executable file
#!/bin/bash
|
||
|
||
# Simple script to populate content index.json files from existing markdown files
|
||
|
||
set -e
|
||
|
||
# Colors
|
||
GREEN='\033[0;32m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m'
|
||
|
||
log_info() { echo -e "${BLUE}ℹ️ $1${NC}"; }
|
||
log_success() { echo -e "${GREEN}✅ $1${NC}"; }
|
||
|
||
# Function to extract value from YAML frontmatter
|
||
get_yaml_value() {
|
||
local file="$1"
|
||
local key="$2"
|
||
|
||
# Extract frontmatter and get the value
|
||
awk '/^---$/{if(p==1){exit} p++; next} p==1 && /^'$key':/ {gsub(/^'$key': */, ""); gsub(/^"/, ""); gsub(/"$/, ""); print}' "$file"
|
||
}
|
||
|
||
# Function to extract tags array from YAML
|
||
get_yaml_tags() {
|
||
local file="$1"
|
||
|
||
# Extract tags array - handle both inline and multiline formats
|
||
awk '/^---$/{if(p==1){exit} p++; next}
|
||
p==1 && /^tags:/ {
|
||
if(/\[.*\]/) {
|
||
# Inline array format: tags: ["tag1", "tag2"]
|
||
gsub(/^tags: *\[/, ""); gsub(/\].*$/, ""); gsub(/"/, ""); gsub(/, */, "\",\"");
|
||
if(length($0) > 0) print "\"" $0 "\""
|
||
} else {
|
||
# Multiline format - skip for now, would need more complex parsing
|
||
next
|
||
}
|
||
}' "$file"
|
||
}
|
||
|
||
# Function to process a single markdown file
|
||
process_markdown_file() {
|
||
local md_file="$1"
|
||
local content_type="$2"
|
||
local language="$3"
|
||
|
||
# Extract values
|
||
local id=$(get_yaml_value "$md_file" "id")
|
||
local title=$(get_yaml_value "$md_file" "title")
|
||
local slug=$(get_yaml_value "$md_file" "slug")
|
||
local excerpt=$(get_yaml_value "$md_file" "excerpt")
|
||
local date=$(get_yaml_value "$md_file" "date")
|
||
local read_time=$(get_yaml_value "$md_file" "read_time")
|
||
local featured=$(get_yaml_value "$md_file" "featured")
|
||
local category=$(get_yaml_value "$md_file" "category")
|
||
local tags=$(get_yaml_tags "$md_file")
|
||
|
||
# Defaults
|
||
id=${id:-$(basename "$md_file" .md)}
|
||
slug=${slug:-$id}
|
||
title=${title:-"Untitled"}
|
||
excerpt=${excerpt:-""}
|
||
date=${date:-$(date +"%Y-%m-%d")}
|
||
read_time=${read_time:-"5 min read"}
|
||
featured=${featured:-false}
|
||
|
||
# Infer category from directory if not set
|
||
if [ -z "$category" ]; then
|
||
local dir_name=$(basename "$(dirname "$md_file")")
|
||
if [ "$dir_name" != "$language" ]; then
|
||
category="$dir_name"
|
||
fi
|
||
fi
|
||
|
||
# Build categories array
|
||
local categories=""
|
||
if [ -n "$category" ]; then
|
||
categories="\"$category\""
|
||
fi
|
||
|
||
# Build tags array
|
||
if [ -z "$tags" ]; then
|
||
tags=""
|
||
fi
|
||
|
||
# Build source_file path (relative to content root, includes category directory)
|
||
# Use basename and dirname to manually construct the relative path since macOS realpath doesn't have --relative-to
|
||
local file_dir=$(dirname "$md_file")
|
||
local content_relative_dir=${file_dir#content/}
|
||
local filename=$(basename "$md_file")
|
||
local relative_path="$content_relative_dir/$filename"
|
||
|
||
# Create JSON using jq for safety
|
||
jq -n \
|
||
--arg id "$id" \
|
||
--arg title "$title" \
|
||
--arg slug "$slug" \
|
||
--arg language "$language" \
|
||
--arg content_type "$content_type" \
|
||
--argjson categories "[$categories]" \
|
||
--argjson tags "[$tags]" \
|
||
--argjson featured "$featured" \
|
||
--arg excerpt "$excerpt" \
|
||
--arg content "" \
|
||
--arg created_at "$date" \
|
||
--arg read_time "$read_time" \
|
||
--arg source_file "$relative_path" \
|
||
'{
|
||
id: $id,
|
||
title: $title,
|
||
slug: $slug,
|
||
language: $language,
|
||
content_type: $content_type,
|
||
categories: $categories,
|
||
tags: $tags,
|
||
emoji: null,
|
||
featured: $featured,
|
||
excerpt: $excerpt,
|
||
content: $content,
|
||
created_at: $created_at,
|
||
updated_at: null,
|
||
read_time: $read_time,
|
||
source_file: $source_file
|
||
}'
|
||
}
|
||
|
||
# Function to process content type and language
|
||
process_content_lang() {
|
||
local content_type="$1"
|
||
local language="$2"
|
||
local lang_dir="content/${content_type}/${language}"
|
||
|
||
if [ ! -d "$lang_dir" ]; then
|
||
return
|
||
fi
|
||
|
||
log_info "Processing $content_type/$language"
|
||
|
||
# Start with empty array
|
||
echo "[]" > "/tmp/${content_type}_${language}.json"
|
||
|
||
# Process each markdown file
|
||
local count=0
|
||
find "$lang_dir" -name "*.md" -type f | while read -r md_file; do
|
||
log_info " Processing: $(basename "$md_file")"
|
||
|
||
# Generate entry and add to array
|
||
local entry=$(process_markdown_file "$md_file" "$content_type" "$language")
|
||
echo "$entry" > "/tmp/current_entry.json"
|
||
|
||
# Add to main array
|
||
jq '. += [inputs]' "/tmp/${content_type}_${language}.json" "/tmp/current_entry.json" > "/tmp/${content_type}_${language}_new.json"
|
||
mv "/tmp/${content_type}_${language}_new.json" "/tmp/${content_type}_${language}.json"
|
||
|
||
count=$((count + 1))
|
||
done
|
||
|
||
# Create final index file
|
||
local index_file="${lang_dir}/index.json"
|
||
local entries=$(cat "/tmp/${content_type}_${language}.json")
|
||
|
||
cat > "$index_file" << EOF
|
||
{
|
||
"$content_type": $entries,
|
||
"language": "$language"
|
||
}
|
||
EOF
|
||
|
||
local final_count=$(jq length "/tmp/${content_type}_${language}.json")
|
||
log_success "Created $content_type/$language index with $final_count entries"
|
||
|
||
# Cleanup temp files
|
||
rm -f "/tmp/${content_type}_${language}.json" "/tmp/current_entry.json"
|
||
}
|
||
|
||
# Main execution
|
||
log_info "Populating content indices..."
|
||
|
||
# Check for jq
|
||
if ! command -v jq &> /dev/null; then
|
||
echo "❌ jq is required but not installed"
|
||
exit 1
|
||
fi
|
||
|
||
# Process blog content
|
||
process_content_lang "blog" "en"
|
||
process_content_lang "blog" "es"
|
||
|
||
# Process recipes content
|
||
process_content_lang "recipes" "en"
|
||
process_content_lang "recipes" "es"
|
||
|
||
log_success "Content indices populated successfully!"
|
||
log_info "Run 'just dev' to rebuild and embed the new indices." |