#!/bin/bash # Check if yq, jq, and nak are installed if ! command -v yq &> /dev/null; then echo "Error: yq is not installed. Please install yq to proceed." exit 1 fi if ! command -v jq &> /dev/null; then echo "Error: jq is not installed. Please install jq to proceed." exit 1 fi if ! command -v nak &> /dev/null; then echo "Error: nak is not installed. Please install nak to proceed." exit 1 fi # Check if at least one input file is provided if [ $# -lt 1 ]; then echo "Usage: $0 [relay...]" echo "Converts a Markdown file with front matter to a Nostr event (kind 30023 if published: true, else kind 30024), prompts for secret key, and optionally publishes to relays." exit 1 fi MD_FILE="$1" shift # Remove MD_FILE from arguments, leaving relays (if any) # Check if file exists and is a Markdown file if [ ! -f "$MD_FILE" ] || [[ ! "$MD_FILE" =~ \.md$ ]]; then echo "Error: '$MD_FILE' is not a valid .md file" exit 1 fi # Extract filename without .md extension for d tag D_TAG=$(basename "$MD_FILE" .md) # Extract front matter (between --- delimiters) FRONT_MATTER=$(awk ' BEGIN { in_front_matter=0; front_matter_count=0 } /^---$/ { front_matter_count++ if (front_matter_count == 1) { in_front_matter=1; next } else if (front_matter_count == 2) { in_front_matter=0; exit } } in_front_matter { print } ' "$MD_FILE") # Check if front matter is empty or invalid if [ -z "$FRONT_MATTER" ]; then echo "Error: '$MD_FILE' has no valid front matter" exit 1 fi # Parse front matter with yq using a temporary file echo "$FRONT_MATTER" > .temp_front_matter.yaml FRONT_MATTER_JSON=$(yq -r '.' .temp_front_matter.yaml 2>/dev/null) rm .temp_front_matter.yaml if [ $? -ne 0 ] || [ -z "$FRONT_MATTER_JSON" ]; then echo "Error: '$MD_FILE' has invalid YAML front matter" exit 1 fi # Extract title, summary, date, tags, image, and published from front matter TITLE=$(echo "$FRONT_MATTER_JSON" | jq -r '.title // ""') SUMMARY=$(echo "$FRONT_MATTER_JSON" | jq -r '.summary // ""') DATE=$(echo "$FRONT_MATTER_JSON" | jq -r '.date // ""') TAGS=$(echo "$FRONT_MATTER_JSON" | jq -r '.tags // ""') IMAGE=$(echo "$FRONT_MATTER_JSON" | jq -r '.image // ""') PUBLISHED=$(echo "$FRONT_MATTER_JSON" | jq -r '.published // "false"') # Convert ISO 8601 date to Unix timestamp for published_at (if valid) if [ -n "$DATE" ]; then PUBLISHED_AT=$(date -d "$DATE" +%s 2>/dev/null || echo "$DATE") else PUBLISHED_AT="" fi # Extract content (everything after front matter) and trim only leading/trailing blank lines CONTENT=$(awk ' BEGIN { in_front_matter=0; front_matter_count=0; content_started=0 } /^---$/ { front_matter_count++ if (front_matter_count == 1) { in_front_matter=1 } else if (front_matter_count == 2) { in_front_matter=0; next } } !in_front_matter && front_matter_count >= 2 { if (!content_started && $0 ~ /^[[:space:]]*$/) { next # Skip leading blank lines } content_started=1 content = content $0 "\n" } END { # Trim trailing blank lines if (content != "") { sub(/\n*[[:space:]]*\n*$/, "", content) print content } } ' "$MD_FILE") # Check if content is empty if [ -z "$CONTENT" ]; then echo "Error: No content found after front matter in '$MD_FILE'" exit 1 fi # Write content to a temporary file to avoid escaping issues TEMP_CONTENT=$(mktemp) echo -n "$CONTENT" > "$TEMP_CONTENT" # Determine event kind based on published status if [ "$PUBLISHED" = "true" ]; then EVENT_KIND=30023 else EVENT_KIND=30024 fi # Build nak command with --prompt-sec NAK_CMD="nak event --kind $EVENT_KIND --content \"\$(cat $TEMP_CONTENT)\" --prompt-sec" # Add tags NAK_CMD="$NAK_CMD -d \"$D_TAG\"" if [ -n "$TITLE" ]; then NAK_CMD="$NAK_CMD --tag title=\"$TITLE\"" fi if [ -n "$SUMMARY" ]; then NAK_CMD="$NAK_CMD --tag summary=\"$SUMMARY\"" fi if [ -n "$PUBLISHED_AT" ]; then NAK_CMD="$NAK_CMD --tag published_at=\"$PUBLISHED_AT\"" fi if [ -n "$IMAGE" ]; then NAK_CMD="$NAK_CMD --tag image=\"$IMAGE\"" fi # Add t tags from comma-separated front matter tags if [ -n "$TAGS" ]; then # Split comma-separated tags, trim whitespace, and add as t tags IFS=',' read -ra TAG_ARRAY <<< "$TAGS" for TAG in "${TAG_ARRAY[@]}"; do # Trim leading/trailing whitespace from tag TAG=$(echo "$TAG" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//') if [ -n "$TAG" ]; then NAK_CMD="$NAK_CMD --tag t=\"$TAG\"" fi done fi # Add relays (if provided) for RELAY in "$@"; do NAK_CMD="$NAK_CMD \"$RELAY\"" done # Create a temporary file for nak output TEMP_OUTPUT=$(mktemp) # Execute nak command, directing prompt to terminal and capturing output # Use /dev/tty for stdin to ensure prompt is interactive eval "$NAK_CMD > $TEMP_OUTPUT" < /dev/tty NAK_EXIT=$? # Read the output from the temporary file EVENT_JSON=$(cat "$TEMP_OUTPUT") # Clean up temporary files rm "$TEMP_CONTENT" "$TEMP_OUTPUT" # Check if nak command succeeded if [ $NAK_EXIT -ne 0 ] || [ -z "$EVENT_JSON" ]; then echo "Error: Failed to create Nostr event with nak (check secret key input)" exit 1 fi # Output the JSON object on a single line echo "$EVENT_JSON" | jq -c .