blob: 2973c2ff3a2175158021d5970ebfa400e750bfa1 (
plain) (
blame)
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
|
#!/bin/bash
# build.sh - ubergeek static site generator
# Converts the wiki markdown structure into HTML using lowdown + mo.
[[ "$(basename "${0}")" == "build.sh" ]] || { echo "Do not source build.sh"; exit 1; }
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ ! -f "${SCRIPT_DIR}/build/mo" ]]; then
echo "[error] build/mo not found. Run: curl -sL https://raw.githubusercontent.com/tests-always-included/mo/master/mo -o build/mo && chmod +x build/mo" >&2
exit 1
fi
. "${SCRIPT_DIR}/build/mo"
FORCE=false
while [[ $# -gt 0 ]]; do
case "$1" in
-f|--force) FORCE=true ;;
*) echo "[error] Unknown option: $1" >&2; exit 1 ;;
esac
shift
done
TMPDIR_BUILD="$(mktemp -d)"
cleanup() { rm -rf "${TMPDIR_BUILD}"; }
trap cleanup EXIT INT TERM
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
get_frontmatter() {
local key="$1" file="$2"
lowdown -X "${key}" "${file}" 2>/dev/null || true
}
check_has_code() {
local html="$1"
if echo "${html}" | grep -qE '<pre><code|<code class='; then
HAS_CODE="true"
else
HAS_CODE=""
fi
}
render_page() {
local template="$1" outfile="$2"
mkdir -p "$(dirname "${outfile}")"
local tname="${template##build/templates/}"
cp "${template}" "build/templates/partials/${tname}"
(cd build/templates/partials && mo "${tname}") > "${outfile}"
rm -f "build/templates/partials/${tname}"
}
build_breadcrumbs() {
local path="$1"
BREADCRUMBS=""
local components="${path}"
while [[ "${components}" != "." ]]; do
BREADCRUMBS=" / <a href=\"/${components}\">$(basename "${components}")</a>${BREADCRUMBS}"
components="$(dirname "${components}")"
done
}
# ---------------------------------------------------------------------------
# process_dir dir
# Recursively renders topic and module pages, returns a markdown list
# of direct children into ${TMPDIR_BUILD}/${dir//\//_}.list.md
# ---------------------------------------------------------------------------
process_dir() {
local dir="$1"
local list_file="${TMPDIR_BUILD}/${dir//\//_}.list.md"
: > "${list_file}"
local find_list="${TMPDIR_BUILD}/${dir//\//_}.find.list"
find "${dir}" -mindepth 1 -maxdepth 1 -not -name '.*' -print0 | sort -z > "${find_list}"
while IFS= read -r -d '' node; do
if [[ -d "${node}" ]]; then
local subdir_title
subdir_title="$(get_frontmatter title "${node}/index.md" 2>/dev/null || true)"
[[ -z "${subdir_title}" ]] && subdir_title="$(basename "${node}")"
printf -- '- [%s](/%s)\n' "${subdir_title}" "${node}" >> "${list_file}"
process_dir "${node}"
elif [[ "${node}" == *.md && "$(basename "${node}")" != "index.md" ]]; then
local slug="${node%.md}"
local title date lang
title="$(get_frontmatter title "${node}")"
[[ -z "${title}" ]] && title="$(basename "${slug}")"
date="$(get_frontmatter date "${node}")"
lang="$(get_frontmatter lang "${node}")"
local out_html="output/${slug}/index.html"
local content
content="$(lowdown "${node}")"
check_has_code "${content}"
build_breadcrumbs "${slug}"
export PAGE_TITLE="${title}"
export CONTENT="${content}"
export BREADCRUMBS
export HEADER_EXTRA="${date}"
export META_DATE="${date}"
export META_DESCRIPTION=""
export HAS_CODE
export LANG="${lang:-en}"
export DIR=""
render_page "build/templates/page.html" "${out_html}"
printf -- '- [%s](/%s)\n' "${title}" "${slug}" >> "${list_file}"
echo "[built] ${out_html}"
fi
done < "${find_list}"
# Build this directory's index page
local index_src="${dir}/index.md"
local index_md="${TMPDIR_BUILD}/${dir//\//_}.index.md"
local dir_title
if [[ -f "${index_src}" ]]; then
dir_title="$(get_frontmatter title "${index_src}")"
cp "${index_src}" "${index_md}"
else
dir_title="$(basename "${dir}")"
printf '# %s\n\n' "${dir_title}" > "${index_md}"
fi
printf '\n\n' >> "${index_md}"
cat "${list_file}" >> "${index_md}"
local out_html="output/${dir}/index.html"
local content
content="$(lowdown "${index_md}")"
check_has_code "${content}"
build_breadcrumbs "${dir}"
export PAGE_TITLE="${dir_title}"
export CONTENT="${content}"
export BREADCRUMBS
export HEADER_EXTRA=""
export META_DATE=""
export META_DESCRIPTION=""
export HAS_CODE
export LANG="en"
export DIR=""
render_page "build/templates/page.html" "${out_html}"
echo "[built] output/${dir}/index.html"
}
# ---------------------------------------------------------------------------
# Main build
# ---------------------------------------------------------------------------
mkdir -p output
# Discover top-level topic directories (exclude hidden, build, output)
topics_list="${TMPDIR_BUILD}/topics.list.md"
: > "${topics_list}"
find_list="${TMPDIR_BUILD}/toplevel.find.list"
find . -mindepth 1 -maxdepth 1 -type d \
-not -name '.*' -not -name 'build' -not -name 'output' \
-print0 | sort -z > "${find_list}"
while IFS= read -r -d '' topic; do
topic="${topic#./}"
topic_title="$(get_frontmatter title "${topic}/index.md" 2>/dev/null || true)"
[[ -z "${topic_title}" ]] && topic_title="${topic}"
printf -- '- [%s](/%s)\n' "${topic_title}" "${topic}" >> "${topics_list}"
process_dir "${topic}"
done < "${find_list}"
# Home page — README.md + topic listing
home_md="${TMPDIR_BUILD}/home.md"
cp README.md "${home_md}"
printf '\n\n## topics:\n\n' >> "${home_md}"
cat "${topics_list}" >> "${home_md}"
content="$(lowdown "${home_md}")"
check_has_code "${content}"
export PAGE_TITLE=""
export CONTENT="${content}"
export BREADCRUMBS=""
export HEADER_EXTRA=""
export META_DATE=""
export META_DESCRIPTION=""
export HAS_CODE
export LANG="en"
export DIR=""
render_page "build/templates/home.html" "output/index.html"
echo "[built] output/index.html"
# License page
if [[ -f "LICENSE.md" ]]; then
content="$(lowdown LICENSE.md)"
check_has_code "${content}"
export PAGE_TITLE="license"
export CONTENT="${content}"
export BREADCRUMBS=" / <a href=\"/license\">license</a>"
export HEADER_EXTRA=""
export META_DATE=""
export META_DESCRIPTION=""
export HAS_CODE
export LANG="en"
export DIR=""
render_page "build/templates/page.html" "output/license/index.html"
echo "[built] output/license/index.html"
fi
echo ""
echo "[done] Build complete. Output in output/"
|