initial commit
This commit is contained in:
commit
cbf844cf87
4 changed files with 422 additions and 0 deletions
103
.gitignore
vendored
Normal file
103
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
# Created by https://www.toptal.com/developers/gitignore/api/vim,emacs,osx
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=vim,emacs,osx
|
||||
|
||||
### Emacs ###
|
||||
# -*- mode: gitignore; -*-
|
||||
*~
|
||||
\#*\#
|
||||
/.emacs.desktop
|
||||
/.emacs.desktop.lock
|
||||
*.elc
|
||||
auto-save-list
|
||||
tramp
|
||||
.\#*
|
||||
|
||||
# Org-mode
|
||||
.org-id-locations
|
||||
*_archive
|
||||
|
||||
# flymake-mode
|
||||
*_flymake.*
|
||||
|
||||
# eshell files
|
||||
/eshell/history
|
||||
/eshell/lastdir
|
||||
|
||||
# elpa packages
|
||||
/elpa/
|
||||
|
||||
# reftex files
|
||||
*.rel
|
||||
|
||||
# AUCTeX auto folder
|
||||
/auto/
|
||||
|
||||
# cask packages
|
||||
.cask/
|
||||
dist/
|
||||
|
||||
# Flycheck
|
||||
flycheck_*.el
|
||||
|
||||
# server auth directory
|
||||
/server/
|
||||
|
||||
# projectiles files
|
||||
.projectile
|
||||
|
||||
# directory configuration
|
||||
.dir-locals.el
|
||||
|
||||
# network security
|
||||
/network-security.data
|
||||
|
||||
|
||||
### OSX ###
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
### Vim ###
|
||||
# Swap
|
||||
[._]*.s[a-v][a-z]
|
||||
!*.svg # comment out if you don't need vector files
|
||||
[._]*.sw[a-p]
|
||||
[._]s[a-rt-v][a-z]
|
||||
[._]ss[a-gi-z]
|
||||
[._]sw[a-p]
|
||||
|
||||
# Session
|
||||
Session.vim
|
||||
Sessionx.vim
|
||||
|
||||
# Temporary
|
||||
.netrwhist
|
||||
# Auto-generated tag files
|
||||
tags
|
||||
# Persistent undo
|
||||
[._]*.un~
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/vim,emacs,osx
|
||||
68
bin/install.sh
Executable file
68
bin/install.sh
Executable file
|
|
@ -0,0 +1,68 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
DEBUG=false
|
||||
|
||||
# --- Resolve project root directory (always works regardless of where script is run from) ---
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT_SRC="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
PREFIX="${PREFIX:-/usr/local}"
|
||||
|
||||
INSTALL_DIR="$PREFIX/bin"
|
||||
|
||||
TARGET_NAME="export-notes"
|
||||
SCRIPT_NAME="$TARGET_NAME.sh"
|
||||
SCRIPT_PATH="$ROOT_SRC/$SCRIPT_NAME"
|
||||
|
||||
# Optional --prefix CLI override
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--debug)
|
||||
DEBUG=true
|
||||
shift
|
||||
;;
|
||||
--prefix)
|
||||
PREFIX="$2"
|
||||
INSTALL_DIR="$PREFIX/bin"
|
||||
shift 2
|
||||
;;
|
||||
--help|-h)
|
||||
echo "Usage: $0 [--prefix /desired/install/path]" >&2
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
echo "Usage: $0 [--prefix /desired/install/path]" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ "$DEBUG" == true ]]; then
|
||||
echo "🪵 Debug mode enabled"
|
||||
echo "PREFIX: $PREFIX"
|
||||
echo
|
||||
echo "SCRIPT_DIR: $SCRIPT_DIR"
|
||||
echo "ROOT_SRC: $ROOT_SRC"
|
||||
echo
|
||||
echo "INSTALL_DIR: $INSTALL_DIR"
|
||||
echo "TARGET_NAME: $TARGET_NAME"
|
||||
echo "SCRIPT_NAME: $SCRIPT_NAME"
|
||||
echo "SCRIPT_PATH: $SCRIPT_PATH"
|
||||
fi
|
||||
|
||||
# Check script exists
|
||||
if [[ ! -f "$SCRIPT_PATH" ]]; then
|
||||
echo "❌ Error: Expected to find $SCRIPT_NAME at: $SCRIPT_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Copy to install location
|
||||
echo "📦 Installing $SCRIPT_NAME to $INSTALL_DIR/$TARGET_NAME ..."
|
||||
sudo install -m 755 "$SCRIPT_PATH" "$INSTALL_DIR/$TARGET_NAME"
|
||||
|
||||
echo "Installed successfully."
|
||||
echo "Run it with: $TARGET_NAME"
|
||||
echo "Add to your PATH if not already:"
|
||||
echo " export PATH=\"$INSTALL_DIR:\$PATH\""
|
||||
49
bin/uninstall.sh
Executable file
49
bin/uninstall.sh
Executable file
|
|
@ -0,0 +1,49 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
DEBUG=false
|
||||
|
||||
ROOT_SRC=".."
|
||||
TARGET_NAME="export-notes"
|
||||
|
||||
PREFIX="${PREFIX:-/usr/local}"
|
||||
INSTALL_PATH="$PREFIX/bin/$TARGET_NAME"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--debug)
|
||||
DEBUG=true
|
||||
shift
|
||||
;;
|
||||
--prefix)
|
||||
PREFIX="$2"
|
||||
INSTALL_PATH="$PREFIX/bin/$TARGET_NAME"
|
||||
shift 2
|
||||
;;
|
||||
--help|-h)
|
||||
echo "Usage: $0 [--prefix /custom/bin/path]" >&2
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option $1" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ "$DEBUG" == true ]]; then
|
||||
echo "ROOT_SRC=$ROOT_SRC"
|
||||
echo "TARGET_NAME=$TARGET_NAME"
|
||||
echo "PREFIX=$PREFIX"
|
||||
echo "INSTALL_PATH=$INSTALL_PATH"
|
||||
fi
|
||||
|
||||
# check and remove
|
||||
if [[ ! -f "$INSTALL_PATH" ]]; then
|
||||
echo "❌ $INSTALL_PATH not found. Nothing to uninstall."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🗑️ Removing $INSTALL_PATH ..."
|
||||
sudo rm "$INSTALL_PATH"
|
||||
echo "✅ Uninstalled successfully."
|
||||
202
export-notes.sh
Executable file
202
export-notes.sh
Executable file
|
|
@ -0,0 +1,202 @@
|
|||
#!/bin/bash
|
||||
|
||||
# ----------------------------
|
||||
# Configurable Section
|
||||
# ----------------------------
|
||||
#
|
||||
#
|
||||
# ----------------------------
|
||||
# Default Values
|
||||
# ----------------------------
|
||||
|
||||
SOURCE_BASE="$HOME"
|
||||
NOTES_ROOT="notes/courses"
|
||||
SECTION_DIR=""
|
||||
SHARE_REL=""
|
||||
DEBUG=0
|
||||
|
||||
# ----------------------------
|
||||
# Help Message
|
||||
# ----------------------------
|
||||
|
||||
print_help() {
|
||||
cat <<EOF
|
||||
Usage: $0 [options]
|
||||
|
||||
Options:
|
||||
--source-base PATH Base directory where notes root begins (default: \$HOME)
|
||||
--notes-root PATH Path from base to notes root (default: notes/courses)
|
||||
--section-dir PATH Relative path under notes root to export (default: current directory)
|
||||
|
||||
--share-rel PATH Relative path (from section-dir) to a shared _share directory (e.g. ../_share)
|
||||
If provided, its contents will be copied to the DEST/_share folder (as a sibling)
|
||||
|
||||
--debug Print resolved paths and stop before exporting
|
||||
--help Show this help message
|
||||
|
||||
|
||||
Behavior:
|
||||
- .org files are exported only if newer than corresponding .html files.
|
||||
- Shared assets from both --share-rel and section-local _share/ are merged into the destination.
|
||||
- Symlinks are preserved; .bak, .log, and dotfiles are excluded from rsync copies.
|
||||
|
||||
Examples:
|
||||
cd ~/notes/courses/business/music_money_makeover
|
||||
$0 --debug
|
||||
|
||||
$0 \\
|
||||
--source-base ~/notes \\
|
||||
--notes-root notes/courses \\
|
||||
--section-dir business/music_money_makeover \\
|
||||
--share-rel ../_share
|
||||
EOF
|
||||
}
|
||||
|
||||
# ----------------------------
|
||||
# Flag Parsing
|
||||
# ----------------------------
|
||||
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--source-base)
|
||||
SOURCE_BASE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--notes-root)
|
||||
NOTES_ROOT="$2"
|
||||
shift 2
|
||||
;;
|
||||
--section-dir)
|
||||
SECTION_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
--share-rel)
|
||||
SHARE_REL="$2"
|
||||
shift 2
|
||||
;;
|
||||
--debug)
|
||||
DEBUG=1
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
print_help
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "❌ Unknown option: $1"
|
||||
print_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Auto-determine SECTION_DIR if not provided
|
||||
if [ -z "$SECTION_DIR" ]; then
|
||||
full_path="$(cd "$(pwd)" && pwd)"
|
||||
base_path="$(cd "$SOURCE_BASE/$NOTES_ROOT" && pwd)"
|
||||
SECTION_DIR="${full_path#"$base_path"/}"
|
||||
fi
|
||||
|
||||
|
||||
# ----------------------------
|
||||
# Path Setup
|
||||
# ----------------------------
|
||||
|
||||
SRC_DIR="$SOURCE_BASE/$NOTES_ROOT/$SECTION_DIR"
|
||||
SHARE_DIR="$SRC_DIR/_share"
|
||||
DATA_DIR="$SRC_DIR/_data"
|
||||
|
||||
# Detect OS and use appropriate destination base
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
DEST_ROOT="/usr/local/var/www"
|
||||
else
|
||||
DEST_ROOT="/var/www"
|
||||
fi
|
||||
|
||||
DEST_DIR="$DEST_ROOT/$NOTES_ROOT/$SECTION_DIR"
|
||||
|
||||
# ----------------------------
|
||||
# Debug Output
|
||||
# ----------------------------
|
||||
|
||||
echo "📁 SOURCE_BASE: $SOURCE_BASE"
|
||||
echo "📁 NOTES_ROOT: $NOTES_ROOT"
|
||||
echo "📁 SECTION_DIR: $SECTION_DIR"
|
||||
echo "📁 SRC_DIR: $SRC_DIR"
|
||||
echo "📁 DEST_DIR: $DEST_DIR"
|
||||
echo "📁 SHARE_DIR: $SHARE_DIR"
|
||||
echo "📁 DATA_DIR: $DATA_DIR"
|
||||
|
||||
if [ "$DEBUG" -eq 1 ]; then
|
||||
echo "🛑 Debug mode enabled. Exiting before export."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
# ----------------------------
|
||||
# Export .org to .html if changed
|
||||
# ----------------------------
|
||||
|
||||
mkdir -p "$DEST_DIR"
|
||||
|
||||
find "$SRC_DIR" -name '*.org' ! -path "*/_share/*" | while read -r file; do
|
||||
|
||||
rel_path="${file#$SRC_DIR/}"
|
||||
rel_dir="$(dirname "$rel_path")"
|
||||
dest_subdir="$DEST_DIR/$rel_dir"
|
||||
output_file="$dest_subdir/$(basename "${file%.org}.html")"
|
||||
|
||||
if [ ! -f "$output_file" ] || [ "$file" -nt "$output_file" ]; then
|
||||
echo "Exporting $rel_path"
|
||||
mkdir -p "$dest_subdir"
|
||||
emacs "$file" --batch -l org --eval="(org-export-to-file 'html \"$output_file\")"
|
||||
else
|
||||
echo "Skipping $rel_path (no changes)"
|
||||
fi
|
||||
done
|
||||
|
||||
# ----------------------------
|
||||
# Copy shared assets (_share), preserving symlinks but skipping junk files
|
||||
# ----------------------------
|
||||
#
|
||||
# --- Shared assets from --share-rel (e.g. ../_share → sibling)
|
||||
if [ -n "$SHARE_REL" ]; then
|
||||
SHARE_SRC="$(cd "$SRC_DIR/$SHARE_REL" && pwd)"
|
||||
DEST_SHARE="$(dirname "$DEST_DIR")/_share"
|
||||
|
||||
if [ -d "$SHARE_SRC" ]; then
|
||||
echo "📦 Copying shared assets from $SHARE_SRC to $DEST_SHARE"
|
||||
mkdir -p "$DEST_SHARE"
|
||||
rsync -a --update --keep-dirlinks \
|
||||
--exclude=".*" \
|
||||
--exclude="*.bak" \
|
||||
--exclude="*.log" \
|
||||
"$SHARE_SRC/" "$DEST_SHARE/"
|
||||
else
|
||||
echo "⚠️ Warning: resolved --share-rel '$SHARE_REL' to '$SHARE_SRC', but it does not exist"
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- Fallback to local _share (section-specific)
|
||||
if [ -d "$SHARE_DIR" ]; then
|
||||
mkdir -p "$DEST_DIR/_share"
|
||||
rsync -a --update --keep-dirlinks \
|
||||
--exclude=".*" \
|
||||
--exclude="*.bak" \
|
||||
--exclude="*.log" \
|
||||
"$SHARE_DIR/" "$DEST_DIR/_share/"
|
||||
fi
|
||||
|
||||
# ----------------------------
|
||||
# Copy course-specific _data directory (if it exists)
|
||||
# ----------------------------
|
||||
if [ -d "$DATA_DIR" ]; then
|
||||
mkdir -p "$DEST_DIR/_data"
|
||||
rsync -a --update --keep-dirlinks \
|
||||
--exclude=".*" \
|
||||
--exclude="*.bak" \
|
||||
--exclude="*.log" \
|
||||
"$DATA_DIR/" "$DEST_DIR/_data/"
|
||||
fi
|
||||
|
||||
echo "✅ Export complete for $SECTION_DIR → $DEST_DIR"
|
||||
Loading…
Add table
Reference in a new issue