CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commit conventions

Do not add a Co-Authored-By: Claude ... trailer (or any AI attribution) to commit messages.

What this is

A single-page academic personal homepage built on the acad-homepage Jekyll template (a fork of it). It is hosted on GitHub Pages and served at https://cao-wuhui.github.io. upstream points at RayeRen/acad-homepage.github.io for pulling template improvements; when merging from upstream, take framework/template changes only and ignore the upstream author’s personal content.

Local development

bash run_server.sh   # = bundle exec jekyll liveserve; serves http://127.0.0.1:4000 with livereload
bundle install       # install Ruby gem dependencies (first-time setup, requires Ruby + GCC + Make)

There are no tests, linters, or a build step to run manually — Jekyll regenerates the site and GitHub Pages builds/deploys automatically on push to main. _config.yml is not hot-reloaded; restart the server after editing it.

Where content lives

Nearly all page content is in one file: _pages/about.md. It has permalink: /, so it is the homepage. Every visible section (About Me, Publications, Educations, Experiences, Teaching, Honors & Awards, CVEs, Reports, Visiting Record) is a top-level # heading in this single Markdown file, which mixes Markdown and raw HTML freely. To edit the site’s content, edit this file.

The nav ↔ heading anchor contract (important)

The top navigation bar is defined in _data/navigation.yml. Each link’s url is an anchor into the single-page body (e.g. /#-publications). These anchors are auto-generated by kramdown (auto_ids: true) from the # headings in about.md, using this rule: lowercase, spaces → -, and non-alphanumerics (including emoji and &) stripped.

  • # 📝 Publications → id -publications → nav url /#-publications (leading - because the emoji is stripped but its trailing space becomes a dash)
  • # 🏅 Honors & Awards → id -honors--awards

Consequence: if you rename or reorder a section heading in about.md, you must update the matching url in navigation.yml, or that nav link breaks. The “About Me” section is the exception — it has no visible heading; its anchor is a manual <span class='anchor' id='about-me'></span> in the body, and the nav points at /#about-me.

masthead.html renders nav links as ``, and domain is set in _config.yml (https://cao-wuhui.github.io). This absolute prefix makes anchor links like /#-publications jump back to the homepage even when viewed from a sub-page. If nav links break after a fork/rename, check that domain in _config.yml matches the actual live GitHub Pages URL (the username-derived USERNAME.github.io, not whatever is in CNAME).

Google Scholar citation counts (automated)

Citation stats are fetched by a scheduled GitHub Action, not committed to main:

  • .github/workflows/google_scholar_crawler.yaml runs google_scholar_crawler/main.py daily (08:00 UTC) and on each page build.
  • It reads the GOOGLE_SCHOLAR_ID repo secret, then force-pushes the resulting gs_data.json to a separate google-scholar-stats branch (this force-push is by design and lives only on that data branch — never force-push main).
  • The site reads that JSON at runtime via _includes/fetch_google_scholar_stats.html; google_scholar_stats_use_cdn: true in _config.yml controls whether it’s loaded via jsDelivr CDN or raw GitHub. Per-paper counts use <span class='show_paper_citations' data='SCHOLAR_ID:PAPER_ID'></span> in about.md.

Layout / theme structure

Standard Jekyll minimal-mistakes-derived layout: _layouts/default.html is the only layout, composed from partials in _includes/ (masthead.html nav, sidebar.html + author-profile.html for the left profile card driven by the author: block in _config.yml, head/, scripts.html, seo.html, analytics.html). Styles are SCSS in _sass/ compiled from assets/. Static assets: images/ (avatar referenced by author.avatar), files/ (linked PDFs/slides). docs/ and google_scholar_crawler/ are excluded from the Jekyll build via _config.yml.