Skip to content

Commit 88a9df5

Browse files
authored
Update pages.yml
1 parent bab412c commit 88a9df5

File tree

1 file changed

+45
-41
lines changed

1 file changed

+45
-41
lines changed

.github/workflows/pages.yml

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
git push
5454
5555
- id: build_page
56-
name: Build index.html with custom template + grid sidebar (dynamic URLs)
56+
name: Build index.html with sidebar TOC from README headings
5757
env:
5858
REPO_HTML_TITLE: ${{ github.repository }}
5959
OWNER: ${{ github.repository_owner }}
@@ -65,15 +65,13 @@ jobs:
6565
# === Compute dynamic URLs ===
6666
REPO_NAME="${REPO_FULL#*/}"
6767
REPO_URL="https://github.com/${REPO_FULL}"
68-
69-
# Pages URL: special-case owner.github.io
7068
if [ "$REPO_NAME" = "${OWNER}.github.io" ]; then
7169
PAGES_URL="https://${OWNER}.github.io/"
7270
else
7371
PAGES_URL="https://${OWNER}.github.io/${REPO_NAME}/"
7472
fi
7573
76-
# Minimal Pandoc template (no default CSS)
74+
# Minimal Pandoc template
7775
cat > pandoc_template.html <<'TPL'
7876
<!doctype html>
7977
<html>
@@ -97,47 +95,41 @@ jobs:
9795
if [ -f index.html ]; then
9896
echo "Keeping existing index.html (not regenerating)."
9997
elif [ -f README.md ]; then
100-
echo "Generating index.html from README.md..."
98+
echo "Generating index.html from README.md with a TOC..."
10199
pandoc README.md -f markdown -t html -s \
102100
--template=pandoc_template.html \
103101
-o index.html \
104-
--metadata title="$REPO_HTML_TITLE"
102+
--metadata title="$REPO_HTML_TITLE" \
103+
--toc --toc-depth=3 -V toc-title=""
105104
GENERATED=1
106105
else
107106
echo "No index.html or README.md found; writing minimal page."
108107
printf '%s\n' '<!doctype html><html><head><meta charset="utf-8"><title>Site</title></head><body>' '<h1>Site</h1>' '<p>No README.md found. Add one and push to regenerate this page.</p>' '</body></html>' > index.html
109108
GENERATED=1
110109
fi
111110
112-
# Styles: grid layout + "full-height" painted sidebar column
111+
# Styles (grid layout + sidebar + nice TOC)
113112
CSS='<style>
114113
html, body { width:100%; max-width:none; margin:0; padding:0; font-family: Arial, Helvetica, sans-serif; color:#222; }
115114
h1, h2, h3, h4, h5, h6 { font-family: Arial, Helvetica, sans-serif; }
116115
pre code { display:block; padding:.75em; background:#f6f8fa; border-radius:6px; font-size:90%; overflow:auto; }
117116
code { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; }
118117
119-
/* Page uses CSS Grid; paint the left column so the sidebar appears full-height */
120-
.page {
121-
display: grid;
122-
grid-template-columns: 220px 1fr;
123-
min-height: 100vh;
124-
background: linear-gradient(to right, #f4f4f4 0, #f4f4f4 220px, transparent 220px);
125-
}
126-
127-
.sidebar {
128-
padding: 20px;
129-
position: sticky;
130-
top: 0;
131-
height: 100vh; /* sidebar content scrolls independently if long */
132-
overflow: auto;
133-
}
134-
.sidebar a { display:block; margin-bottom:10px; color:#0366d6; text-decoration:none; font-weight:600; }
135-
.sidebar a:hover { text-decoration:underline; }
136-
137-
.content { width: 100%; }
138-
.container { width:100%; max-width: 1400px; margin: 0 auto; padding: 48px; }
118+
.page { display:grid; grid-template-columns: 240px 1fr; min-height:100vh;
119+
background: linear-gradient(to right, #f4f4f4 0, #f4f4f4 240px, transparent 240px); }
120+
.sidebar { padding:20px; position:sticky; top:0; height:100vh; overflow:auto; }
121+
.sidebar a.home { display:block; margin-bottom:14px; color:#0366d6; text-decoration:none; font-weight:700; }
122+
.sidebar a.home:hover { text-decoration:underline; }
123+
.sidebar nav.toc { font-size:14px; line-height:1.4; }
124+
.sidebar nav.toc ul { list-style:none; padding-left:0; margin:0; }
125+
.sidebar nav.toc li { margin:4px 0; }
126+
.sidebar nav.toc a { color:#24292f; text-decoration:none; }
127+
.sidebar nav.toc a:hover { text-decoration:underline; }
128+
.sidebar nav.toc ul ul { padding-left:14px; border-left:2px solid #e5e7eb; margin-left:6px; }
129+
130+
.content { width:100%; }
131+
.container { width:100%; max-width: 1400px; margin:0 auto; padding:48px; }
139132
140-
/* Extras block spacing */
141133
.extras { margin-top: 48px; }
142134
.extras h2, .extras h3 { margin-top: 1.2em; }
143135
@@ -148,44 +140,60 @@ jobs:
148140
}
149141
</style>'
150142
151-
# Inject CSS into <head> (or wrap if missing)
143+
# Inject CSS into <head>
152144
if grep -qi '</head>' index.html; then
153145
awk -v css="$CSS" 'BEGIN{IGNORECASE=1} { if (!done && match(tolower($0), /<\/head>/)) { sub(/<\/head>/, css"</head>"); done=1 } print }' index.html > index.html.tmp
154146
mv index.html.tmp index.html
155147
else
156148
TMP=$(mktemp)
157149
printf '%s\n' '<!doctype html><html><head><meta charset="utf-8">' "$CSS" '</head><body>' > "$TMP"
158-
# Keep body content (if any) after opening <body>
159150
sed '1,/<body[^>]*>/d' index.html >> "$TMP" || true
160151
printf '%s\n' '</body></html>' >> "$TMP"
161152
mv "$TMP" index.html
162153
fi
163154
164-
# === Use dynamic Pages URL for the sidebar "Home" link ===
155+
# === Sidebar with Home + placeholder for TOC links ===
165156
HOMELINK="https://democracy-lab.github.io/"
166-
167-
# Wrap body with grid + sidebar + content container (idempotent)
168157
if grep -qi '<div class="page"' index.html; then
169158
echo "Wrapper already present; skipping."
170159
else
171160
awk -v home="$HOMELINK" 'BEGIN{IGNORECASE=1}
172161
{
173162
if (!done && match(tolower($0), /<body[^>]*>/)) {
174-
sub(/<body[^>]*>/, "&\n<div class=\"page\"><aside class=\"sidebar\"><a href=\"" home "\" aria-label=\"Go to home\">← Home</a></aside>\n<main class=\"content\"><div class=\"container\">");
163+
sub(/<body[^>]*>/,
164+
"&\n<div class=\"page\"><aside class=\"sidebar\">" \
165+
"<a class=\"home\" href=\"" home "\" aria-label=\"Go to home\">← Home</a>" \
166+
"<nav class=\"toc\"><!--SIDEBAR_LINKS--></nav>" \
167+
"</aside>\n<main class=\"content\"><div class=\"container\">");
175168
done=1
176169
}
177170
print
178171
}' index.html > index.html.tmp && mv index.html.tmp index.html
179172
180-
# Close container/main/page before </body>
181173
awk 'BEGIN{IGNORECASE=1} { sub(/<\/body>/, "</div></main></div></body>"); print }' index.html > index.html.tmp && mv index.html.tmp index.html
182174
fi
183175
184-
# === Replace placeholders anywhere in the page ===
176+
# === Extract Pandoc TOC and move it into the sidebar ===
177+
# Grab inner HTML of <nav id="TOC"> ... </nav>
178+
TOC_INNER=$(perl -0777 -ne 'if (m|<nav\s+id="TOC"[^>]*>(.*?)</nav>|si){print $1}' index.html || true)
179+
180+
# If a TOC exists, clean it and inject; then remove original TOC
181+
if [ -n "$TOC_INNER" ]; then
182+
# Remove any <h2>Contents</h2> title inside the nav
183+
TOC_CLEAN=$(printf "%s" "$TOC_INNER" | perl -0777 -pe 's|<h[1-6][^>]*>.*?</h[1-6]>||si')
184+
# Inject into sidebar placeholder
185+
awk -v block="$TOC_CLEAN" 'BEGIN{IGNORECASE=1}
186+
{ sub(/<!--SIDEBAR_LINKS-->/, block); print }' index.html > index.html.tmp && mv index.html.tmp index.html
187+
# Remove original nav#TOC from main content
188+
perl -0777 -pe 's|<nav\s+id="TOC"[^>]*>.*?</nav>||si' -i index.html
189+
else
190+
echo "No TOC found; leaving sidebar placeholder empty."
191+
fi
192+
193+
# Replace any placeholders, just in case
185194
esc() { printf '%s' "$1" | sed 's/[&/\\]/\\&/g'; }
186195
REPO_URL_ESC=$(esc "$REPO_URL")
187196
PAGES_URL_ESC=$(esc "$PAGES_URL")
188-
189197
sed -i \
190198
-e "s/GITHUB_REPO_URL/${REPO_URL_ESC}/g" \
191199
-e "s/GITHUB_REPO/${REPO_URL_ESC}/g" \
@@ -212,7 +220,6 @@ jobs:
212220
LAST_UPDATE=$(git log -1 --format=%cI || date -u +%Y-%m-%dT%H:%M:%SZ)
213221
YEAR=$(date -u -d "$LAST_UPDATE" +%Y 2>/dev/null || date -u +%Y)
214222
215-
# Gather human contributors (optional enhancement)
216223
logins=$(curl -s -H "Authorization: Bearer $GH_TOKEN" \
217224
"https://api.github.com/repos/$REPO/contributors?per_page=100&anon=false" \
218225
| jq -r '.[] | select((.type // "") != "Bot") | select(.login != "ghost") | .login' | sort -fu)
@@ -246,7 +253,6 @@ jobs:
246253
note = {Last updated: $LAST_UPDATE}
247254
}"
248255
249-
# Build the extras HTML block (includes both URLs)
250256
EXTRAS=$(cat <<HTML
251257
<section class="extras">
252258
<hr>
@@ -268,7 +274,6 @@ jobs:
268274
HTML
269275
)
270276
271-
# Inject JUST BEFORE the wrapper closes: </div></main></div></body>
272277
awk -v block="$EXTRAS" 'BEGIN{IGNORECASE=1}
273278
{
274279
line=$0
@@ -298,4 +303,3 @@ jobs:
298303
run: |
299304
echo "### Deployed Pages URL" >> "$GITHUB_STEP_SUMMARY"
300305
echo "${{ steps.deployment.outputs.page_url }}" >> "$GITHUB_STEP_SUMMARY"
301-

0 commit comments

Comments
 (0)