#!/usr/bin/env sh # html-style.sh — 「哪一種 wiki 頁或議題,用哪一種版型與風格出 HTML」的設定(供 jsc-gitea:html-style、html-export 使用)。 # # 設定格式(一行一筆):{種類}={版型},{風格} # 種類:WIKI:{頁名前綴}(例 WIKI:PLAN)、ISSUE:{標籤名}(例 ISSUE:bug)、DEFAULT(都對不到時用) # 「#」開頭為註解,空白行忽略。同一種類出現多行時取最後一行。 # 解析順序: # 1. 目前工作目錄的 ./.jsc/html-styles(專案覆寫) # 2. $JSC_HOME/html-styles.conf(JSC_HOME 預設 ~/.jsc) # 3. 種類對不到就退 DEFAULT,DEFAULT 也沒有才用內建預設 report,minimal # # 用法: # html-style.sh get <種類> 印出 版型風格來源(project/global/default/builtin) # html-style.sh set <種類> <版型> <風格> [--project|--global] 寫入設定(預設 --global) # html-style.sh unset <種類> [--project|--global] 移除設定 # html-style.sh list 印出合併後的所有設定:種類版型風格來源 # html-style.sh layouts 列出可用版型:名稱繁中說明 # html-style.sh styles 列出可用風格:名稱繁中說明 # # 結束碼: 0=成功 2=用法錯誤 4=版型或風格沒有對應範本檔 # # 陷阱: # - get 永遠印得出一組值:對不到就退 DEFAULT,再對不到就退內建預設。呼叫端不必自己準備退路, # 但要看第三欄,才知道這組值是使用者設的還是撿來的。 # - set 會先確認範本檔真的存在,擋掉打錯字的版型或風格;設定寫得進去、出圖卻失敗最難查。 set -u script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) plugin_root="${CLAUDE_PLUGIN_ROOT:-$script_dir/..}" TPL="$plugin_root/templates/html" JSC_HOME="${JSC_HOME:-$HOME/.jsc}" PROJECT_FILE=./.jsc/html-styles GLOBAL_FILE="$JSC_HOME/html-styles.conf" BUILTIN_LAYOUT=report BUILTIN_STYLE=minimal usage() { cat >&2 <<'EOF' 用法: html-style.sh get <種類> html-style.sh set <種類> <版型> <風格> [--project|--global] html-style.sh unset <種類> [--project|--global] html-style.sh list | layouts | styles 種類: WIKI:{頁名前綴}、ISSUE:{標籤名}、DEFAULT 結束碼: 0=成功 2=用法錯誤 4=版型或風格沒有對應範本檔 EOF exit 2 } read_value() { # $1=設定檔 $2=種類 -> 「版型,風格」 [ -f "$1" ] || return 0 awk -F= -v want="$2" ' { sub(/\r$/, "") } /^[ \t]*#/ { next } /^[ \t]*$/ { next } index($0, "=") == 0 { next } { key = $1 gsub(/[ \t]/, "", key) if (key != want) next val = substr($0, index($0, "=") + 1) gsub(/[ \t]/, "", val) if (val != "") v = val } END { if (v != "") print v } ' "$1" } resolve() { # $1=種類 -> 版型風格來源 for _f in "$PROJECT_FILE:project" "$GLOBAL_FILE:global"; do _file=${_f%:*}; _src=${_f##*:} _v=$(read_value "$_file" "$1") if [ -n "$_v" ]; then printf '%s\t%s\t%s\n' "${_v%%,*}" "${_v##*,}" "$_src" return 0 fi done if [ "$1" != DEFAULT ]; then _d=$(resolve DEFAULT) _src=$(printf '%s' "$_d" | cut -f3) # DEFAULT 自己也沒設定時,來源照實說是 builtin,不要蓋成 default [ "$_src" = builtin ] || _src=default printf '%s\t%s\n' "$(printf '%s' "$_d" | cut -f1,2)" "$_src" return 0 fi printf '%s\t%s\tbuiltin\n' "$BUILTIN_LAYOUT" "$BUILTIN_STYLE" } # 範本檔第一行註解就是繁中說明:版型放在 ,風格放在 /* 說明 */。 describe() { # $1=檔案 head -n1 "$1" 2>/dev/null | sed 's///; s|/\*[[:space:]]*||; s|[[:space:]]*\*/||' } list_layouts() { for f in "$TPL"/layout/*.html; do [ -f "$f" ] || continue name=$(basename "$f" .html) printf '%s\t%s\n' "$name" "$(describe "$f")" done } list_styles() { for f in "$TPL"/style/*.css; do [ -f "$f" ] || continue name=$(basename "$f" .css) printf '%s\t%s\n' "$name" "$(describe "$f")" done } write_kv() { # $1=檔案 $2=種類 $3=值 dir=$(dirname "$1") mkdir -p "$dir" || { echo "[jsc][HTML 設定][ERR]:建不出目錄「$dir」。" >&2; exit 1; } tmp="$1.tmp.$$" { [ -f "$1" ] && grep -v "^[[:space:]]*$2[[:space:]]*=" "$1" || true; } > "$tmp" [ -n "$3" ] && printf '%s=%s\n' "$2" "$3" >> "$tmp" mv "$tmp" "$1" } cmd="${1:-}"; [ -n "$cmd" ] || usage shift || true case "$cmd" in layouts) list_layouts; exit 0 ;; styles) list_styles; exit 0 ;; list) keys=$( { [ -f "$PROJECT_FILE" ] && cut -d= -f1 "$PROJECT_FILE" || true [ -f "$GLOBAL_FILE" ] && cut -d= -f1 "$GLOBAL_FILE" || true; } \ | sed 's/^[[:space:]]*//; s/[[:space:]]*$//' | grep -v '^#' | grep -v '^$' | sort -u) [ -n "$keys" ] || { printf 'DEFAULT\t%s\t%s\tbuiltin\n' "$BUILTIN_LAYOUT" "$BUILTIN_STYLE"; exit 0; } printf '%s\n' "$keys" | while IFS= read -r k; do printf '%s\t%s\n' "$k" "$(resolve "$k")" done exit 0 ;; get) key="${1:-}"; [ -n "$key" ] || usage resolve "$key" exit 0 ;; set) key="${1:-}"; layout="${2:-}"; style="${3:-}" [ -n "$key" ] && [ -n "$layout" ] && [ -n "$style" ] || usage shift 3 target="$GLOBAL_FILE"; scope=global case "${1:-}" in --project) target="$PROJECT_FILE"; scope=project ;; --global|'') ;; *) usage ;; esac [ -f "$TPL/layout/$layout.html" ] || { echo "[jsc][HTML 設定][ERR]:沒有版型「$layout」。可用:$(list_layouts | cut -f1 | tr '\n' ' ')" >&2; exit 4; } [ -f "$TPL/style/$style.css" ] || { echo "[jsc][HTML 設定][ERR]:沒有風格「$style」。可用:$(list_styles | cut -f1 | tr '\n' ' ')" >&2; exit 4; } write_kv "$target" "$key" "$layout,$style" printf '已寫入 %s:%s=%s,%s(%s)\n' "$target" "$key" "$layout" "$style" "$scope" exit 0 ;; unset) key="${1:-}"; [ -n "$key" ] || usage shift target="$GLOBAL_FILE" case "${1:-}" in --project) target="$PROJECT_FILE" ;; --global|'') ;; *) usage ;; esac [ -f "$target" ] || { echo "找不到設定檔:$target" >&2; exit 0; } write_kv "$target" "$key" '' printf '已移除 %s 的 %s\n' "$target" "$key" exit 0 ;; *) usage ;; esac