New SSG Process

ever forward, but slowly.

Last update: 2024-09-14

A fresh start. I’ve built a new obsidian vault with the following directories:

  1. Root: Contains the .md and related files (e.g. images, .css and .html templates).
  2. Pages: This is where the html files are populated for uploading to codeberg.
  3. Templates: I have four templates to start quick notes for authors, book notes, recipes and unique notes (i.e. zettelkasten notes).

Obsidian Plugins

In this vault I have the following plugins:

  1. Citations
  2. Footnote shortcut
  3. Linter
  4. Minimal theme settings
  5. Pandoc reference list
  6. Paster URL into selection
  7. Tag wrangler
  8. Change case
  9. Wikilinks to mdlinks

HTML conversion is done with pandoc using the script convert_to_html.sh, so I’m not using any plugin for this purpose (previously I used the Enhanced Export plugin).

Shell Scripts

I have four scripts to run:1

  1. sync_assets.sh
  2. convert_to_html.sh
  3. feed.sh
  4. push_changes.sh

I simply run the ssg.sh script that executes all of the above at once. In a few moments, the website is refreshed to final state.

#!/bin/bash
clear

# Echo the name of the script
echo "Running script: $0"

# Synchronize assets using the rsync command
./sync_assets.sh

# Convert .md files to .html files:
./convert_to_html.sh

# Generate RSS feed
./feed.sh

# Push changes to the remote repository
./push_changes.sh

Sync Assets

#!/bin/bash

# Synchronize .css .pdf .jpeg .png etc. files between two directories using the rsync command

# Source directory containing the markdown files
SOURCE_DIR="/path/to/your/local/source/"

# Destination directory where files will be synchronized
DEST_DIR="/path/to/your/local/destination/"

# Perform the synchronization with rsync
rsync -av --delete --include="*.css" --include="*.pdf" --include="*.png" --include="*.jpg" --include="*.jpeg" --include="*.mp3" --include="*.mp4" --exclude="*" "$SOURCE_DIR" "$DEST_DIR"

# echo "Synchronized .css and .png files from $SOURCE_DIR to $DEST_DIR."
echo "Synchronized assets between source and destination directories."

#Explanation:
#   rsync -av:
#   -a (archive mode) preserves file attributes like timestamps, permissions, and symbolic links.
#   -v (verbose) gives detailed output during the operation.
#   --delete: This option deletes files in the destination directory that no longer exist in the source directory. This ensures that the destination is an exact mirror of the source, with no extra files.
#   --include="*.md": Includes only .md files in the synchronization.
#   --exclude="*": Excludes everything else, so only .md files and directories are considered.
#   "${SOURCE_DIR}" and "${DEST_DIR}" represent the source and destination directories, respectively. Ensure that these paths end with a slash (/) to avoid any path concatenation issues.

Convert to HTML

#!/bin/bash

# Directories
SRC_DIR="/path/to/your/local/source/"  # Replace with the path to your source directory
DEST_DIR="/path/to/your/local/destination"  # Replace with the path to your destination directory

# Initialize a counter for converted files
converted_count=0

# Iterate over all .md files in the source directory
for SRC_FILE in $(find "$SRC_DIR" -name "*.md"); do
  # Skip files that begin with an underscore
  if [[ "$(basename "$SRC_FILE")" == _*.md ]]; then
    continue
  fi
  # Get the relative path of the file to mirror directory structure
  REL_PATH="${SRC_FILE#$SRC_DIR/}"
  
  # Set the destination file path
  DEST_FILE="$DEST_DIR/${REL_PATH%.md}.html"
  
  # Check if the destination directory needs to be created
  mkdir -p "$(dirname "$DEST_FILE")"
  
  # Get the modification times
  if [ ! -f "$DEST_FILE" ] || [ "$SRC_FILE" -nt "$DEST_FILE" ]; then
    # Print just the filename without the full path
    SRC_FILENAME=$(basename "$SRC_FILE")
    DEST_FILENAME=$(basename "$DEST_FILE")
    echo "Converting $SRC_FILENAME to $DEST_FILENAME"
    
    # Convert the markdown file to HTML using pandoc
    pandoc --standalone --mathjax --template template.html --bibliography ./refs.bib --citeproc --csl ./apa.csl "$SRC_FILE" -o "$DEST_FILE"
    
    # Check if the HTML file was created successfully
    if [ -f "$DEST_FILE" ]; then
      # Increment the converted file counter
      converted_count=$((converted_count + 1))
    else
      echo "Error: Failed to convert $SRC_FILENAME to HTML."
    fi
  fi
done

# Print a summary at the end
if [ "$converted_count" -gt 0 ]; then
  echo "$converted_count file(s) were converted."
else
  echo "All files are up to date. No conversions were necessary."
fi

Generate the RSS Feed

#!/bin/bash

# Define the output file for the RSS feed
OUTPUT_FILE="/path/to/your/local/destination/feed.rss"

# Set the variables
TITLE="Continuum"
DESCRIPTION="No hurry, no pause."
LINK="https://continuum.codeberg.page"
LANGUAGE="en-ca"
DATE=$(date +"%a, %d %b %Y %T %z") # Current date and time in RFC-822 format
NOTE="Thank you for keeping RSS alive."
GENERATOR="Custom RSS Generator"

# Find all HTML files in the ROOT_DIR recursively
ROOT_DIR="/path/to/your/local/source/"
HTML_FILES=$(find "$ROOT_DIR" -name "*.html" -type f -exec stat -f "%m %N" {} + | sort -nr | cut -d' ' -f2-)

# Start writing the RSS feed  
echo "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
<rss version=\"2.0\">
<channel>
<title>$TITLE</title>
<description>$DESCRIPTION</description>
<link>$LINK</link>
<language>$LANGUAGE</language>
<lastBuildDate>$DATE</lastBuildDate>
<note>$NOTE</note>
<generator>$GENERATOR</generator>" > "$OUTPUT_FILE"

# Loop through each HTML file and extract required fields
for FILE in $HTML_FILES; do
    MOD_TIME=$(date -R -r "$FILE")
    TITLE=$(grep -o '<title>[^<]*' "$FILE" | sed 's/<title>//')
    DESCRIPTION=$(grep -o '<meta name="description" content="[^"]*' "$FILE" | sed 's/<meta name="description" content="//')
    DESCRIPTION=${DESCRIPTION:-"No hurry, no pause."}

    # Create URL by removing the ROOT_DIR prefix from the file path
    RELATIVE_PATH=$(echo "$FILE" | sed "s|^$ROOT_DIR||")
    URL="https://continuum.codeberg.page/$RELATIVE_PATH"
    URL=${URL// /%20}  # Encode spaces in the URL

    guid="$URL"

    # Write item to RSS feed
    echo "<item>
    <pubDate>$MOD_TIME</pubDate>
    <title>$TITLE</title>
    <link>$URL</link>
    <description>$DESCRIPTION</description>
    <guid>$guid</guid>
    </item>" >> "$OUTPUT_FILE"
done

# Close the RSS feed
echo "</channel>
</rss>" >> "$OUTPUT_FILE"

#echo "Generated $OUTPUT_FILE successfully."
echo "Generated feed.rss successfully."

Push Changes to the Remote Repository

#!/bin/bash

# Change to the directory of your Git repository
REPO_DIR="/path/to/your/local/repository"
cd "$REPO_DIR" || exit

# Stage all changes (new, modified, deleted files)
git add .

# Commit changes with a message
COMMIT_MESSAGE="Automated commit: $(date +'%Y-%m-%d %H:%M:%S')"
git commit -m "$COMMIT_MESSAGE"

# Push changes to the remote repository (Codeberg in this case)
git push origin main

echo "Changes have been pushed to the repository."

Footnotes


  1. All code generated with ChatGTP.↩︎