-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstp.sh
113 lines (96 loc) · 3.03 KB
/
stp.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/bin/sh
set -e
readonly CONFIG="${STP_CONFIG:-.stp}"
readonly TMP="$CONFIG/tmp"
ROOT_TITLE="${STP_ROOT_TITLE:-}"
TITLE_FORMAT="${STP_TITLE_FORMAT-capitalize}"
TITLE_SPACE_CHARACTERS="${STP_TITLE_SPACE_CHARACTERS-_-}"
println() {
printf '%s\n' "$@"
}
slugify() {
println "$1" | sed 's|[^[:alnum:]_-]|_|g;s|__*|_|g;s|^_||;s|_$||'
}
is_function() {
[ "$1" != "" ] && [ "$(command -v "$1")" = "$1" ]
}
try() {
if is_function "${1:?}" && "$1"; then return; else shift && try "$@"; fi
}
find_files() {
find "$1" -name '.?*' -prune -o -type f -name "$2" -print
}
capitalize() {
tr ' ' '\n' |
while IFS='' read -r word; do
printf ' %.1s' "$word" | tr '[:lower:]' '[:upper:]'
printf '%s' "${word#?}"
done | cut -c 2-
}
format_title() {
_format() { tr " $TITLE_SPACE_CHARACTERS" '[ *]' | ${TITLE_FORMAT:-cat}; }
println "$1" | if [ "${1%.*}" != "$1" ]; then cat; else _format; fi
}
get_directory_title() {
title="$(format_title "$(basename "$1")")"
root_title="${ROOT_TITLE:-"$(format_title "$(basename "$(pwd)")")"}"
if [ "${1%/}" = "." ]; then println "$root_title"; else println "$title"; fi
}
title() {
_fallback() { format_title "$(basename "$DEST_PATH" ".${DEST_PATH##*.}")"; }
try "get_title_${SOURCE_PATH##*.}" _fallback
}
input() {
"${@:-cat}" < "${SOURCE_PATH:?}"
}
root() {
dir="${DEST_PATH%/*}/"
println "${dir#./}" | sed 's|[^/]*/|\.\./|g;s|/$||;s|^$|.|'
}
instantiate() {
: "${GENERATOR:?}" "${DEST_PATH:?}" "${TITLE:?}" "${ROOT:?}"
path="${1:+"$CONFIG/templates/$1"}"
path="${path:-"${SOURCE_PATH:?}"}"
eval "printf '%s\\n' \"$(sed 's/\\*\(["`]\)/\\\1/g' "$path")\""
}
import() {
if [ -d "$1" ]; then
for plugin in "$1"/*.sh; do
if [ -e "$plugin" ]; then . "$plugin"; fi
done
fi
}
process() {
processor="$1"; root="${2%/.}";
ls "$CONFIG/templates" | grep -F '.to.' | LC_ALL=C sort |
while IFS='' read -r template_filename; do
source_ext="${template_filename%%.to.*}"
dest_ext="${template_filename#*.to.}"
find_files "${root%/}" "*.$source_ext" |
while IFS='' read -r SOURCE_PATH; do
DEST_PATH="${SOURCE_PATH%.$source_ext}.$dest_ext"
"$processor" "$template_filename"
done
done
unset SOURCE_PATH DEST_PATH
}
generate() {
if [ ! -e "$SOURCE_PATH" ] || [ "$SOURCE_PATH" -nt "$DEST_PATH" ]; then
println "${DEST_PATH#./}" >&2
ROOT="$(root)" TITLE="${2:-$(title)}" instantiate "$1" > "$DEST_PATH"
unset ROOT TITLE
fi
}
main() {
import "$CONFIG/hooks"
if [ "$#" = 0 ]; then try pre_hook :; fi
for path in "${@:-.}"; do
rel="${path#$PWD/}"
if [ "${rel#/}" = "$rel" ] && [ "${rel#*..}" = "$rel" ]; then
GENERATOR="core" process generate "./${rel#./}"
else println "Error: invalid path: $path" >&2; fi
done
if [ "$#" = 0 ]; then unset GENERATOR && try post_hook :; fi
}
import "$CONFIG/plugins"
if [ "$1" = "-e" ]; then is_function "$2" && shift && "$@"; else main "$@"; fi