-
Notifications
You must be signed in to change notification settings - Fork 0
/
build
executable file
·182 lines (158 loc) · 4.59 KB
/
build
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
#!/usr/bin/env sh
# Generate a static HTML website from Markdown with pandoc(1).
set -eu
if [ $# -ne 0 ]; then
echo usage: $0 1>&2
echo Generate a static HTML website. 1>&2
exit 1
fi
if ! command -v pandoc >/dev/null; then
echo error: pandoc not found 1>&2
exit 1
fi
# HTML Tidy executable name
if command -v tidy5 >/dev/null; then
tidy="tidy5"
elif command -v tidy >/dev/null; then
tidy="tidy"
else
echo warning: HTML Tidy not found 1>&2
tidy=""
fi
cd "$(dirname "$0")"
rootdir="$(pwd)"
outdir="$rootdir"/public
# Create scratch directory (deleted when script exits)
tmpdir="$(mktemp -d)"
trap 'rm -rf -- "$tmpdir"' EXIT
# if the output directory exists, temporarily save a copy of it as an
# optimization for reusing pages which haven't changed
olddir=
if [ -d "$outdir" ]; then
olddir="$tmpdir"/old
mv "$outdir" "$olddir"
fi
# delete and recreate the output directory so that it's a clean slate
rm -rf "$outdir"
mkdir -p "$outdir"
outdir="$(readlink -f "$outdir")"
# Everything in static/ is deployed as-is. A good place for stylesheets,
# scripts, images, standalone HTML pages, etc.
if [ -d static ]; then
cp -r static/* "$outdir"
fi
# is system using GNU coreutils stat(1)?
isgnustat() {
set +e
stat --version 2>/dev/null | grep GNU >/dev/null
grep_status=$?
set -e
return $grep_status
}
# file modification time in seconds since Unix epoch
mtime() {
$(isgnustat) && echo "$(stat -c'%Y' "$1")" || echo "$(stat -f'%m' "$1")"
}
# file modifications fractional seconds
mtime_frac() {
$(isgnustat) && \
echo "$(stat -c'%y' "$1" | sed 's/.*\.\([0-9]*\).*/\1/')" || \
echo "$(stat -f'%Fm' "$1" | sed 's/[0-9]*\.//')"
}
# is first file older than second file?
# yes, this script is reinventing make(1)
older_than() {
[ ! -f "$2" ] && return 1
[ $(mtime "$1") -lt $(mtime "$2") ] && return 0
[ $(mtime "$1") -gt $(mtime "$2") ] && return 1
[ $(mtime_frac "$1") -lt $(mtime_frac "$2") ] && return 0
return 1
}
# are all given files (after the first) older than the first given file?
all_older_than() {
first="$1"
shift
for f in "$@"; do
! $(older_than "$f" "$first") && return 1
done
return 0
}
# Update href="./" and src="./" paths to replace the "./" with the relative
# path to the top-level site directory.
update_relative_path() {
path_to_root="$1"
html_input="$2"
html_output="$3"
cat "$html_input" |
sed "s|\( href=\"\)\./|\1$path_to_root|" | \
sed "s|\( src=\"\)\./|\1$path_to_root|" \
>"$html_output"
}
cd content
find . -type f -name '*.md' | while IFS= read page; do
page_dir="$(dirname "$page")"
page_md_name="$(basename "$page")"
page_html_name="$(echo "$page_md_name" | sed 's/\.md$/.html/')"
page_html_relpath="$page_dir"/"$page_html_name"
mkdir -p "$outdir"/"$page_dir"
if [ ! -z "$olddir" ]; then
# if the HTML file is newer than all the files used to build it...
if all_older_than "$olddir"/"$page_html_relpath" "$page" "$rootdir"/layouts/*; then
# reuse the previous HTML file
echo "$page_md_name unchanged"
mv "$olddir"/"$page_html_relpath" "$outdir"/"$page_html_relpath"
continue
fi
fi
echo "$page_md_name -> $page_html_name"
# Update relative paths in the header/footer to be correct for the
# location of this page.
page_toroot="$(echo "$page_dir/" | sed 's|^./*||' | sed -r 's|[^/]+|..|g')"
update_relative_path "$page_toroot" "$rootdir"/layouts/header.html "$tmpdir"/header.html
update_relative_path "$page_toroot" "$rootdir"/layouts/footer.html "$tmpdir"/footer.html
tmpfile="$tmpdir"/"$page_html_name"
pandoc \
--from=markdown \
--to=html5 \
--standalone \
--preserve-tabs \
--eol=lf \
--toc \
--shift-heading-level-by=1 \
--highlight-style=monochrome \
--css="$page_toroot"style.css \
--include-before-body="$tmpdir"/header.html \
--include-after-body="$tmpdir"/footer.html \
"$page" --output="$tmpfile"
# The Pandoc HTML template includes the html5shiv script, using Internet
# Explorer conditional comments so that the script is only included for
# IE8 and earlier. Remove it. Removing it here is easier than
# maintaining a fork of the template.
cat "$tmpfile" | \
grep -v '<!--\[if .*IE .*\]>' | \
grep -v '<script src=".*html5shiv.*"></script>' | \
grep -v '<!\[endif\]-->' \
> "$tmpfile.tmp"
mv "$tmpfile.tmp" "$tmpfile"
if [ "$tidy" != "" ]; then
set +e
"$tidy" \
-quiet \
-modify \
-utf8 \
-ashtml \
-omit \
--doctype html5 \
--newline LF \
--keep-tabs yes \
--wrap 0 \
"$tmpdir"/"$page_html_name"
tidy_status=$?
set -e
if [ $tidy_status -eq 2 ]; then
echo "error: $tidy exited with errors"
exit 1
fi
fi
mv "$tmpdir"/"$page_html_name" "$outdir"/"$page_html_relpath"
done