#!/usr/bin/env bash
# setup-docsify.sh — Bootstrap a self-hosted Docsify site on Apache 2.
#
# Run this script from your Apache document root:
# cd /path/to/docroot
# bash setup-docsify.sh [--with-prism] [--with-copy-code]
#
# Options:
# --with-prism Also download Prism and enable syntax highlighting in index.html
# --with-copy-code Also download the docsify-copy-code plugin (copy button on code blocks)
set -euo pipefail
# ── Configuration ───────────────────────────────────────────────────────────────
# Use "4" for the latest 4.x release, or pin to a specific version e.g. "4.13.1"
DOCSIFY_VERSION="4"
PRISM=false
COPY_CODE=false
# ── Argument parsing ────────────────────────────────────────────────────────────
for arg in "$@"; do
case "$arg" in
--with-prism) PRISM=true ;;
--with-copy-code) COPY_CODE=true ;;
*) echo "Unknown option: $arg" >&2; exit 1 ;;
esac
done
# ── Output helpers ──────────────────────────────────────────────────────────────
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
BOLD='\033[1m'
NC='\033[0m'
step() { echo -e "\n${BLUE}${BOLD}==> $1${NC}"; }
ok() { echo -e " ${GREEN}✓${NC} $1"; }
die() { echo -e " ${RED}✗${NC} $1" >&2; exit 1; }
# ── Preflight checks ────────────────────────────────────────────────────────────
step "Preflight checks"
command -v curl &>/dev/null \
|| die "curl is required but not found. Install curl and try again."
ok "curl $(curl --version | head -1 | awk '{print $2}')"
if [[ -f index.html ]]; then
echo -e " ${RED}!${NC} index.html already exists in: $(pwd)"
echo -e " This script will overwrite index.html and all boilerplate .md files."
read -r -p " Continue? [y/N] " reply
[[ "${reply,,}" == "y" ]] || { echo "Aborted."; exit 0; }
fi
echo -e " Working in: $(pwd)"
# ── Step 1: Directories ─────────────────────────────────────────────────────────
step "Step 1 — Creating directory structure"
mkdir -p assets/js assets/css
ok "assets/js/"
ok "assets/css/"
# ── Step 2: Download Docsify assets ─────────────────────────────────────────────
step "Step 2 — Downloading Docsify assets"
CDN="https://cdn.jsdelivr.net/npm"
fetch() {
local url="$1" dest="$2"
curl -sL --fail "$url" -o "$dest" || die "Failed to download: $url"
ok "$dest"
}
fetch "${CDN}/docsify@${DOCSIFY_VERSION}/lib/docsify.min.js" assets/js/docsify.min.js
fetch "${CDN}/docsify@${DOCSIFY_VERSION}/lib/plugins/search.min.js" assets/js/search.min.js
fetch "${CDN}/docsify@${DOCSIFY_VERSION}/themes/vue.css" assets/css/vue.css
if [[ "$PRISM" == true ]]; then
echo ""
echo " Downloading Prism syntax highlighting..."
fetch "${CDN}/prismjs@1/components/prism-core.min.js" assets/js/prism-core.min.js
fetch "${CDN}/prismjs@1/components/prism-bash.min.js" assets/js/prism-bash.min.js
fetch "${CDN}/prismjs@1/components/prism-yaml.min.js" assets/js/prism-yaml.min.js
fetch "${CDN}/prismjs@1/components/prism-javascript.min.js" assets/js/prism-javascript.min.js
fi
if [[ "$COPY_CODE" == true ]]; then
echo ""
echo " Downloading copy-to-clipboard plugin..."
fetch "${CDN}/docsify-copy-code@3/dist/docsify-copy-code.min.js" assets/js/docsify-copy-code.min.js
fi
# ── Step 3: index.html ──────────────────────────────────────────────────────────
step "Step 3 — Creating index.html"
# index.html is assembled in parts so the Prism
HTML_HEAD
if [[ "$COPY_CODE" == true ]]; then
cat << 'HTML_COPYCODE'
HTML_COPYCODE
fi
if [[ "$PRISM" == true ]]; then
cat << 'HTML_PRISM'
HTML_PRISM
fi
cat << 'HTML_FOOT'