What:新增 html-export 與 html-style 兩支技能、tools/html-render.sh 與 tools/html-style.sh 兩支工具,以及六種版型乘五種風格的 HTML 範本。 Why:wiki 頁與議題要拿給 Gitea 以外的人看時,只能複製 markdown;不同類型的文件也該有各自的版面,不是每份都長一樣。 How:版型(report、slide、dashboard、spec、timeline、onepager)決定內容怎麼排,風格(minimal、corporate、dark、print、vivid)決定看起來長怎樣,兩者自由搭配。哪一種頁面套哪一組由設定決定:專案的 .jsc/html-styles 優先,其次 $JSC_HOME/html-styles.conf,對不到退 DEFAULT,再對不到才用內建的 report/minimal。產出是單一 HTML 檔,CSS 與腳本全部內嵌。 Who:需要把 wiki 頁或議題寄給客戶、主管或跨團隊同事的人。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
170 lines
6.2 KiB
Bash
Executable File
170 lines
6.2 KiB
Bash
Executable File
#!/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 <種類> 印出 版型<TAB>風格<TAB>來源(project/global/default/builtin)
|
||
# html-style.sh set <種類> <版型> <風格> [--project|--global] 寫入設定(預設 --global)
|
||
# html-style.sh unset <種類> [--project|--global] 移除設定
|
||
# html-style.sh list 印出合併後的所有設定:種類<TAB>版型<TAB>風格<TAB>來源
|
||
# html-style.sh layouts 列出可用版型:名稱<TAB>繁中說明
|
||
# html-style.sh styles 列出可用風格:名稱<TAB>繁中說明
|
||
#
|
||
# 結束碼: 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=種類 -> 版型<TAB>風格<TAB>來源
|
||
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/<!--[[:space:]]*//; s/[[:space:]]*-->//; 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
|