7171 PAGES_URL="https://${OWNER}.github.io/${REPO_NAME}/"
7272 fi
7373
74- # Minimal Pandoc template — CORRECT TOC PLACEHOLDER
74+ # Minimal Pandoc template (no reliance on built-in TOC)
7575 cat > pandoc_template.html <<'TPL'
7676 <!doctype html>
7777 <html>
8484 $for(include-before)$
8585 $include-before$
8686 $endfor$
87-
88- $if(toc)$
89- <nav id="TOC" role="doc-toc">
90- $table-of-contents$
91- </nav>
92- $endif$
93-
9487 $body$
95-
9688 $for(include-after)$
9789 $include-after$
9890 $endfor$
@@ -136,15 +128,14 @@ jobs:
136128 }
137129 </style>'
138130
139- # Always rebuild index.html from README.md
131+ # Build index.html from README.md
140132 if [ -f README.md ]; then
141- echo "Generating index.html from README.md with a TOC ..."
133+ echo "Generating index.html from README.md..."
142134 rm -f index.html
143135 pandoc README.md -f gfm+yaml_metadata_block -t html -s \
144136 --template=pandoc_template.html \
145137 -o index.html \
146- --metadata title="$REPO_HTML_TITLE" \
147- --toc --toc-depth=6 -V toc-title=""
138+ --metadata title="$REPO_HTML_TITLE"
148139 GENERATED=1
149140 else
150141 echo "No README.md found; writing minimal page."
@@ -164,7 +155,7 @@ jobs:
164155 mv "$TMP" index.html
165156 fi
166157
167- # === Sidebar with Home + placeholder for TOC links ===
158+ # === Sidebar wrapper with Home + placeholder for TOC links ===
168159 HOMELINK="https://democracy-lab.github.io/"
169160 if grep -qi '<div class="page"' index.html; then
170161 echo "Wrapper already present; skipping."
@@ -185,12 +176,30 @@ jobs:
185176 awk 'BEGIN{IGNORECASE=1} { sub(/<\/body>/, "</div></main></div></body>"); print }' index.html > index.html.tmp && mv index.html.tmp index.html
186177 fi
187178
188- # >>> DEBUG: check for TOC before extraction <<<
189- echo "DEBUG: Checking for TOC presence before extraction..."
190- grep -niE '<nav[^>]+(id="TOC"|role="doc-toc"|class="[^"]*toc[^"]*")' index.html || echo "TOC not found pre-extraction"
191-
192- # === Extract Pandoc TOC and move it into the sidebar ===
193- TOC_INNER=$(perl -0777 -ne 'if (m|<(nav|div)\s+[^>]*(id="TOC"|role="doc-toc")[^>]*>(.*?)</\1>|si){print $3} elsif (m|<nav\s+id="TOC"[^>]*>(.*?)</nav>|si){print $1} elsif (m|<nav\s+role="doc-toc"[^>]*>(.*?)</nav>|si){print $1}' index.html || true)
179+ # === Build a TOC by parsing headings already in index.html ===
180+ # We look for <h1..h6 id="...">Title</hN>, strip any inline tags, and nest <ul> by level.
181+ TOC_BUILT=$(perl -0777 -ne '
182+ my @H;
183+ while (m|<h([1-6])\s+[^>]*id="([^"]+)"[^>]*>(.*?)</h\1>|sig) {
184+ my ($lvl,$id,$raw) = ($1,$2,$3);
185+ $raw =~ s/<[^>]+>//g; # strip tags
186+ $raw =~ s/\s+/ /g; $raw =~ s/^\s+|\s+$//g;
187+ push @H, [$lvl,$id,$raw] if length $raw;
188+ }
189+ if (!@H) { exit 0 }
190+ my $html = "";
191+ my $prev = 0;
192+ for my $r (@H) {
193+ my ($l,$id,$t) = @$r;
194+ if ($prev==0) { $html .= "<ul>\n"; $prev=$l; }
195+ while ($l > $prev) { $html .= "<ul>\n"; $prev++ }
196+ while ($l < $prev) { $html .= "</ul>\n"; $prev-- }
197+ $html .= qq{<li><a href="#$id">$t</a></li>\n};
198+ }
199+ while ($prev-- > 1) { $html .= "</ul>\n"; }
200+ $html .= "</ul>\n";
201+ print $html;
202+ ' index.html || true)
194203
195204 # Count README headings (diagnostics)
196205 if [ -f README.md ]; then
@@ -199,37 +208,33 @@ jobs:
199208 HCOUNT=0
200209 fi
201210
202- if [ -n "$TOC_INNER" ]; then
203- TOC_CLEAN=$(printf "%s" "$TOC_INNER" | perl -0777 -pe 's|<h[1-6][^>]*>.*?</h[1-6]>||si')
204-
211+ if [ -n "$TOC_BUILT" ]; then
212+ # Inject into sidebar
205213 if grep -q "<!--SIDEBAR_LINKS-->" index.html; then
206- awk -v block="$TOC_CLEAN " 'BEGIN{IGNORECASE=1}
214+ awk -v block="$TOC_BUILT " 'BEGIN{IGNORECASE=1}
207215 { sub(/<!--SIDEBAR_LINKS-->/, block); print }' index.html > index.html.tmp && mv index.html.tmp index.html
208216 else
209- perl -0777 -pe 's|(<nav\s+class="toc"[^>]*>).*?(</nav>)|$1'"$TOC_CLEAN "'$2|si' -i index.html
217+ perl -0777 -pe 's|(<nav\s+class="toc"[^>]*>).*?(</nav>)|$1'"$TOC_BUILT "'$2|si' -i index.html
210218 fi
211219
212- perl -0777 -pe 's|<(nav|div)\s+(id="TOC"|role="doc-toc")[^>]*>.*?</\1>||si' -i index.html
213-
214- echo "TOC extracted and injected; README headings: $HCOUNT"
220+ echo "Sidebar TOC built from headings; README headings: $HCOUNT"
215221 {
216222 echo "### Sidebar TOC status"
217223 echo ""
218224 echo "- README headings detected: $HCOUNT"
219- echo "- TOC injected into sidebar ✅"
225+ echo "- Sidebar TOC built from headings ✅"
220226 } >> "$GITHUB_STEP_SUMMARY"
221227 else
222- echo "No TOC found ; leaving sidebar placeholder empty."
228+ echo "No headings parsed ; leaving sidebar placeholder empty."
223229 {
224230 echo "### Sidebar TOC status"
225231 echo ""
226232 echo "- README headings detected: $HCOUNT"
227- echo "- Pandoc TOC not found in built HTML ❌"
233+ echo "- Could not parse headings from built HTML ❌"
228234 echo ""
229235 echo "Hints:"
230- echo "1) Ensure your README uses Markdown ATX headings like: #, ##, ###"
231- echo "2) Headings inside HTML blocks or code fences are ignored"
232- echo "3) Confirm this job installed Pandoc and used --toc --toc-depth=6"
236+ echo "1) Ensure headings are not inside code fences or raw HTML blocks"
237+ echo "2) Confirm Pandoc produced <h1..h6 id=\"...\"> elements"
233238 } >> "$GITHUB_STEP_SUMMARY"
234239 fi
235240
@@ -252,6 +257,7 @@ jobs:
252257 OWNER : ${{ github.repository_owner }}
253258 run : |
254259 set -e
260+
255261 REPO_NAME="${REPO#*/}"
256262 REPO_URL="https://github.com/$REPO"
257263 if [ "$REPO_NAME" = "${OWNER}.github.io" ]; then
@@ -347,3 +353,4 @@ jobs:
347353 echo "${{ steps.deployment.outputs.page_url }}" >> "$GITHUB_STEP_SUMMARY"
348354
349355
356+
0 commit comments