forked from void-linux/void-packages
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcreate-web
More file actions
executable file
·425 lines (368 loc) · 11.1 KB
/
create-web
File metadata and controls
executable file
·425 lines (368 loc) · 11.1 KB
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
#!/usr/bin/env bash
#shellcheck disable=SC2089
#
# Make website from .md files
#
# Author: zenobit <zen@duck.com>
# Date: February 14, 2026
# License: MIT
#
count=$(find ./ -name '*.md' | wc -l)
# Functions for colored bordered messages (gum) or ANSI colored messages
if command -v gum -v >/dev/null; then
_r() {
gum style --border rounded --border-foreground "#e50203" --padding "0 1" "${@}"
}
_re() {
gum style --border rounded --border-foreground "#e50203" --padding "0 1" "${@}"
exit 1
}
_g() {
gum style --border rounded --border-foreground "#14a113" --padding "0 1" "$@"
}
_b() {
gum style --border rounded --border-foreground "#004EFB" --padding "0 1" "$@"
}
_y() {
gum style --border rounded --border-foreground "#fdde13" --padding "0 1" "$@"
}
ask() {
gum confirm "$@"
}
_header() {
local text green red yellow
text="${1}"
red=$(gum style --border rounded --border-foreground "#e50203" --padding "0 1" "$text")
yellow=$(gum style --border rounded --border-foreground "#fdde13" --padding "0 1" "$red")
green=$(gum style --border rounded --border-foreground "#14a113" --padding "0 1" "$yellow")
echo "$green"
}
_footer() {
local text green red yellow
text="${1}"
green=$(gum style --border rounded --border-foreground "#14a113" --padding "0 1" "$text")
yellow=$(gum style --border rounded --border-foreground "#fdde13" --padding "0 1" "$green")
red=$(gum style --border rounded --border-foreground "#e50203" --padding "0 1" "$yellow")
echo "$red"
}
else
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
#CYAN='\033[0;36m'
NC='\033[0m'
_g() {
echo -e "${GREEN}${1}${NC}"
}
_r() {
echo -e "${RED}${1}${NC}"
}
_re() {
echo -e "${RED}${1}${NC}" >&2
exit 1
}
_b() {
echo -e "${BLUE}${1}${NC}"
}
_y() {
echo -e "${YELLOW}${1}${NC}"
}
ask() {
_y "Press Enter to continue
anything else for Quit..."
echo "$1"
read -n 1 -s key
if [[ ! $key == '' ]]; then
exit 1
fi
}
_header() {
echo -e "\n${RED}${1}${NC}\n"
}
_footer() {
echo -e "\n${RED}${1}${NC}\n"
}
fi
export -f _r _re _g _b _y
# ---------------------------------------------------------------------------
# Optional override: set FORGE_URL to your Gitea/Forgejo base URL to skip
# auto-detection, e.g. in .env or before calling the script:
# export FORGE_URL="https://git.example.com"
# ---------------------------------------------------------------------------
[ -f .env ] && source .env
# Try to detect a Gitea/Forgejo instance by probing /api/v1/meta
# Returns 0 (true) if confirmed, 1 if not
_is_gitea() {
local base_url="$1"
local response
response=$(curl -sf --max-time 5 "${base_url}/api/v1/meta" 2>/dev/null)
# Gitea/Forgejo meta endpoint returns JSON with a "version" field
[[ "$response" =~ \"version\" ]] && return 0
return 1
}
# Detect repository URL and platform from git remote origin
_detect_repo() {
if ! git rev-parse --git-dir >/dev/null 2>&1; then
_r "Not a git repository — repo buttons will be disabled"
REPO_URL="" REPO_PLATFORM="" REPO_ZIP_URL="" REPO_RELEASE_URL=""
return
fi
# Always use the main remote repository
local raw
raw=$(git remote get-url "$(git remote | head -n 1)" 2>/dev/null)
if [ -z "$raw" ]; then
_r "No git remote found — repo buttons will be disabled"
REPO_URL="" REPO_PLATFORM="" REPO_ZIP_URL="" REPO_RELEASE_URL=""
return
fi
# Normalize SSH → HTTPS
local https_url
if [[ "$raw" =~ ^git@ ]]; then
https_url=$(echo "$raw" | sed 's|git@\(.*\):\(.*\)\.git|https://\1/\2|; s|git@\(.*\):\(.*\)|https://\1/\2|')
else
https_url="${raw%.git}"
fi
# Extract base URL (scheme + host) and slug (user/repo)
local base_url slug
base_url=$(echo "$https_url" | grep -oP 'https?://[^/]+')
slug=$(echo "$https_url" | sed "s|${base_url}/||")
# Detect platform — known hosts first, then Gitea/Forgejo probe
if [[ "$https_url" =~ github\.com ]]; then
REPO_PLATFORM="github"
REPO_URL="$https_url"
REPO_ZIP_URL="${https_url}/archive/refs/heads/main.zip"
REPO_RELEASE_URL="${https_url}/releases/latest"
elif [[ "$https_url" =~ gitlab\.com ]]; then
REPO_PLATFORM="gitlab"
REPO_URL="$https_url"
# GitLab: project path needed for archive URL
local proj_path
proj_path=$(echo "$https_url" | sed 's|https://gitlab\.com/||')
REPO_ZIP_URL="https://gitlab.com/${proj_path}/-/archive/main/${proj_path##*/}-main.zip"
REPO_RELEASE_URL="${https_url}/-/releases"
else
# Gitea/Forgejo: use FORGE_URL override or auto-detect via API probe
local forge_base="${FORGE_URL:-}"
if [ -n "$forge_base" ]; then
_b "FORGE_URL override: $forge_base"
REPO_PLATFORM="gitea"
elif _is_gitea "$base_url"; then
_g "Gitea/Forgejo detected at: $base_url"
forge_base="$base_url"
REPO_PLATFORM="gitea"
else
_y "Unknown platform — only source link will be shown"
REPO_PLATFORM="other"
REPO_URL="$https_url"
REPO_ZIP_URL=""
REPO_RELEASE_URL=""
_check_release
return
fi
REPO_URL="$https_url"
REPO_ZIP_URL="${forge_base}/${slug}/archive/main.zip"
REPO_RELEASE_URL="${https_url}/releases/latest"
fi
_g "Repo detected [$REPO_PLATFORM]: $REPO_URL"
# Check if any release exists via API
_check_release
}
# Query platform API to detect if at least one release exists
_check_release() {
REPO_HAS_RELEASE=0
[ -z "$REPO_URL" ] && return
local base_url slug http_code body
base_url=$(echo "$REPO_URL" | grep -oP 'https?://[^/]+')
slug=$(echo "$REPO_URL" | sed "s|${base_url}/||")
case "$REPO_PLATFORM" in
github)
http_code=$(curl -sf -o /dev/null -w "%{http_code}" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/${slug}/releases/latest" 2>/dev/null)
# 200 = release exists, 404 = no releases
[ "$http_code" = "200" ] && REPO_HAS_RELEASE=1
;;
gitlab)
local encoded_slug
encoded_slug=$(echo "$slug" | sed 's|/|%2F|g')
body=$(curl -sf \
"https://gitlab.com/api/v4/projects/${encoded_slug}/releases?per_page=1" 2>/dev/null)
[ -n "$body" ] && [ "$body" != "[]" ] && REPO_HAS_RELEASE=1
;;
gitea)
# Gitea/Forgejo: GET /api/v1/repos/{owner}/{repo}/releases?limit=1
body=$(curl -sf --max-time 5 \
"${base_url}/api/v1/repos/${slug}/releases?limit=1" 2>/dev/null)
[ -n "$body" ] && [ "$body" != "[]" ] && [ "$body" != "null" ] && REPO_HAS_RELEASE=1
;;
*)
REPO_HAS_RELEASE=0
;;
esac
if [ "$REPO_HAS_RELEASE" = "1" ]; then
_g "Release found"
else
_y "No release found — release button will be shown as strikethrough"
fi
}
add_validation() {
echo '
<p>
<a href="https://jigsaw.w3.org/css-validator/check/referer">
<img style="border:0;width:88px;height:31px"
src="https://jigsaw.w3.org/css-validator/images/vcss-blue"
alt="Ověřit CSS!" />
</a>
</p>
' >> "$output"
}
# Build nav snippet for a given page with active class
# Injects: oSoWoSo | Home | [Download Release] [Download ZIP] [Source] | other pages...
_build_nav() {
local current="$1"
local nav_file="$2"
echo '<nav><ul>' > "$nav_file"
# oSoWoSo button — always first
echo ' <li><a href="https://osowoso.org">oSoWoSo</a></li>' >> "$nav_file"
# Home button
local home_active=""
[ "$current" = "index" ] && home_active=' class="active"'
echo " <li><a href=\"index.html\"${home_active}>Home</a></li>" >> "$nav_file"
# Repo buttons (only when URLs are available)
if [ -n "$REPO_RELEASE_URL" ]; then
if [ "${REPO_HAS_RELEASE:-0}" = "1" ]; then
echo " <li><a href=\"${REPO_RELEASE_URL}\">⏬ release</a></li>" >> "$nav_file"
else
echo " <li><a class=\"no-release\" href=\"${REPO_RELEASE_URL}\">⏬ release</a></li>" >> "$nav_file"
fi
fi
if [ -n "$REPO_ZIP_URL" ]; then
echo " <li><a href=\"${REPO_ZIP_URL}\">📦repo zip</a></li>" >> "$nav_file"
fi
if [ -n "$REPO_URL" ]; then
echo " <li><a href=\"${REPO_URL}\">🔗git</a></li>" >> "$nav_file"
fi
echo " <li>⏭️</a></li>" >> "$nav_file"
# Other .md pages
for md in *.md; do
[ -f "$md" ] || continue
[ "$md" = "README.md" ] && continue
local name=$(echo "${md%.md}" | sed 's/_/ /g')
local active=""
[ "$name" = "$current" ] && active=' class="active"'
echo " <li><a href=\"${name}.html\"${active}>${name}</a></li>" >> "$nav_file"
done
echo '</ul></nav>' >> "$nav_file"
}
# Target: build
target_build() { ## Builds the website, optional: title argument
_detect_repo
if [ -z "$1" ]; then
_r "No website title provided
using generated one!"
title=$(basename "$(pwd)" | sed 's/_/ /g')
else
title="$1"
fi
_g "Creating: $title"
if [ -f docs/CNAME ]; then
cp docs/CNAME src/
fi
rm -rf docs && mkdir -p docs
cp -r src/* docs/
rm -f docs/toggle.html docs/toc.html docs/svg-color.html
if [ "$count" = 1 ]; then
for file in *.md; do
[ -f "$file" ] || continue
local nav_file="docs/_nav.html"
_build_nav "index" "$nav_file"
echo "Processing: $file → index.html"
# single file
pandoc "$file" -f gfm -s \
--css=style.css \
--toc \
--toc-depth=3 \
--include-before-body=src/toggle.html \
--include-before-body=src/toc.html \
--include-before-body="$nav_file" \
--include-after-body=src/svg-color.html \
--metadata title="$title" \
-o docs/index.html
rm -f "$nav_file"
done
elif [ "$count" -gt 1 ]; then
for file in *.md; do
[ -f "$file" ] || continue
if [ "$file" = "README.md" ]; then
output="docs/index.html"
meta_title="$title"
current="index"
else
output="docs/${file%.md}.html"
meta_title=$(echo "${file%.md}" | sed 's/_/ /g')
current="${file%.md}"
fi
local nav_file="docs/_nav_${current}.html"
_build_nav "$current" "$nav_file"
echo "Processing: $file → $output"
# multi file
pandoc "$file" -f gfm -s \
--css=style.css \
--toc \
--toc-depth=3 \
--include-before-body=src/toggle.html \
--include-before-body=src/toc.html \
--include-before-body="$nav_file" \
--include-after-body=src/svg-color.html \
--metadata title="$meta_title" \
-o "$output"
rm -f "$nav_file"
done
else
_re "ERROR: No .md files found!"
fi
_g "Finished"
}
# Target: help
target_help() { ## Show this help message
_b 'OSOWOSO Website Build System'
echo ""
echo "Usage: $0 [target]"
echo ""
echo "Available targets:"
echo ""
awk 'BEGIN {FS = "## "} /^target_[a-zA-Z_-]+\(\).*## / {
sub(/target_/, "", $1)
sub(/\(\) \{/, "", $1)
gsub(/^[ \t]+/, "", $1)
printf " \033[36m%-15s\033[0m %s\n", $1, $2
}' "$0" | sort || _re 'ERROR: No functions found!
Create function you want use for arguments and help as:
target_"Name of argument aka function"() { ## Your usage message here.'
echo ""
}
# Target: serve
target_serve() { ## Serve site locally out of docs folder
if [ ! -f docs/index.html ]; then
_r "Site not built!"
ask 'Build first?' && target_build "$@" || _re "Exiting"
fi
_g 'Press Ctrl+C to stop'
python3 -m http.server -d docs 8000
}
# Main script logic
main() {
local target="${1:-help}"
target="${target#target_}"
local func_name="target_${target//-/_}"
if declare -f "$func_name" > /dev/null; then
shift
"$func_name" "$@"
else
#shellcheck disable=SC2016,2086
_re 'Unknown target: $target. Run '$0 help' for available targets.'
fi
}
# Run main with all arguments
main "$@"