Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/build-content.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: true

- name: Set up Python
uses: actions/setup-python@v5
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/build-cv.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: true

- name: Install TeX Live
run: |
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "lab-manual"]
path = lab-manual
url = https://github.com/ContextLab/lab-manual.git
4 changes: 3 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ contextlab.github.io/
├── scripts/ # Python build system (see scripts/AGENTS.md)
├── images/ # Assets: people/, publications/, software/, research/, news/
├── documents/ # CV files (JRM_CV.tex → .pdf, .html)
├── lab-manual/ # Git submodule (ContextLab/lab-manual)
└── tests/ # pytest suite for build system
```

Expand All @@ -29,7 +30,8 @@ contextlab.github.io/
|------|----------|-------|
| Add publication | `data/publications.xlsx` | Auto-builds via GitHub Actions |
| Add team member | `scripts/onboard_member.py` | Processes photo, generates bio, updates CV |
| Offboard member | `scripts/offboard_member.py` | Moves to alumni, updates CV |
| Offboard member | `scripts/offboard_member.py` | Moves to alumni, updates CV + lab-manual |
| Reconcile people | `scripts/reconcile_people.py` | Three-way sync: people.xlsx ↔ CV ↔ lab-manual |
| Add software | `data/software.xlsx` | |
| Add news | `data/news.xlsx` | Thumbnail in `images/news/` |
| Update CV | `documents/JRM_CV.tex` | Auto-compiles to PDF+HTML |
Expand Down
104 changes: 104 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# CLAUDE.md

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

## Project Overview

Static website for the Contextual Dynamics Lab at Dartmouth College. Hosted on GitHub Pages at [context-lab.com](https://context-lab.com). Content pages (publications, people, software, news) are **auto-generated** from Excel spreadsheets via a Python build system — never edit the root HTML for those pages directly.

## Commands

```bash
# Install dependencies
pip install -r requirements-build.txt

# Validate spreadsheet data
cd scripts && python validate_data.py

# Build all content pages (publications, people, software, news)
cd scripts && python build.py

# Build CV (requires XeLaTeX + Dartmouth Ruzicka fonts)
cd scripts && python build_cv.py

# Run full test suite
python -m pytest tests/ -v

# Run a single test file
python -m pytest tests/test_build_publications.py -v

# Pre-push validation (validation + build + tests)
cd scripts && python pre_push_check.py

# Local dev server
python3 -m http.server 8000

# Add hand-drawn borders to images
python scripts/add_borders.py image.png images/publications/
python scripts/add_borders.py photo.jpg images/people/ --face

# Onboard new member (from scripts/ dir)
python onboard_member.py "First Last" --rank "grad student" --photo headshot --skip-llm

# Offboard member to alumni (from scripts/ dir)
python offboard_member.py "member name" --end-year 2025

# Reconcile people across website, CV, and lab-manual
cd scripts && python reconcile_people.py --dry-run # report only
cd scripts && python reconcile_people.py # apply auto-fixes

# Initialize lab-manual submodule (required for reconciliation)
git submodule update --init
```

## Architecture

### Content Pipeline

```
data/*.xlsx → scripts/build_*.py → root *.html (auto-generated)
templates/*.html (markers like <!-- PUBLICATIONS_PAPERS -->)
```

Each `build_*.py` follows the same pattern:
1. Load spreadsheet with `utils.load_spreadsheet_all_sheets()`
2. Generate HTML fragments
3. Inject into template via `utils.inject_content(template, output, {"MARKER": html})`

### Key Directories

| Directory | Purpose |
|-|-|
| `data/` | Source spreadsheets (publications.xlsx, people.xlsx, software.xlsx, news.xlsx) + Dartmouth fonts |
| `templates/` | HTML templates with `<!-- MARKER -->` injection points |
| `scripts/` | Python build system, validation, onboarding/offboarding tools |
| `tests/` | pytest suite — conftest.py adds `scripts/` to sys.path |
| `documents/` | CV source (JRM_CV.tex) and generated outputs (PDF, HTML) |
| `css/style.css` | Single stylesheet with CSS variables at top |
| `js/main.js` | All JS components (9 init functions) |
| `lab-manual/` | Git submodule — [ContextLab/lab-manual](https://github.com/ContextLab/lab-manual) (init with `git submodule update --init`) |

### CV Pipeline

`documents/JRM_CV.tex` → `scripts/build_cv.py` + `scripts/extract_cv.py` (custom LaTeX→HTML parser) → `documents/JRM_CV.pdf` + `documents/JRM_CV.html`

### GitHub Actions

- **build-content.yml**: Triggers on changes to `data/`, `templates/`, `scripts/`. Validates, builds, runs tests, auto-commits regenerated HTML.
- **build-cv.yml**: Triggers on changes to `documents/JRM_CV.tex`, CV scripts, or `css/cv.css`. Compiles LaTeX, runs tests, auto-commits PDF+HTML.

## Critical Rules

- **Never edit auto-generated root HTML** (`publications.html`, `people.html`, `software.html`, `news.html`) — edit `data/*.xlsx` or `templates/*.html` instead
- **Never use `!important`** in CSS without explicit justification
- **Never add inline styles** to templates — use CSS classes
- **Always run tests before pushing**: `python -m pytest tests/ -v`
- **All headings are lowercase** via `text-transform: lowercase` in CSS

## Design System

- **Colors**: `--primary-green: rgb(0, 112, 60)`, `--bg-green: rgba(0, 112, 60, 0.2)`, `--dark-text: rgba(0, 0, 0, 0.7)`
- **Font**: Nunito Sans, 300 weight body, 14px base, 1.7 line-height
- **Images**: 500x500px with hand-drawn green borders (use `scripts/add_borders.py`), face-detect cropping for people photos (`--face`)
- **Forms**: Formspree backend — endpoint in form `action` attribute
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ The script will:
- Generate or edit the bio using a local LLM (gpt-oss-20b)
- Add the member to `people.xlsx`
- Add the member to `JRM_CV.tex`
- Update `lab_manual.tex` in the lab-manual submodule (if initialized)
- Invite to GitHub organization and teams (if `--github` provided)
- Share Google Calendars with appropriate permissions (if `--gmail` provided)
- Rebuild `people.html`
Expand Down Expand Up @@ -268,10 +269,31 @@ python offboard_member.py --list-no-photo
The script will:
- Move the member from `members` sheet to `alumni_undergrads` in `people.xlsx`
- Update `JRM_CV.tex` to add the end date
- Update `lab_manual.tex` in the lab-manual submodule (if initialized)
- Prompt to rebuild `people.html`

**Idempotent**: Running twice with the same name detects the member is already offboarded.

#### Reconciling People Data

The reconciliation tool compares member/alumni data across `people.xlsx` (source of truth), `JRM_CV.tex`, and the lab-manual's `lab_manual.tex`:

```bash
cd scripts

# Report discrepancies without making changes
python reconcile_people.py --dry-run

# Apply auto-fixes (people.xlsx entries missing from other sources)
python reconcile_people.py
```

The tool uses fuzzy name matching to catch spelling variations and nicknames. Discrepancies are categorized as:
- **Auto-resolved**: People in people.xlsx missing from CV or lab-manual (auto-added)
- **Flagged for review**: People in other sources missing from people.xlsx (requires manual review)

**Requires**: Lab-manual submodule initialized (`git submodule update --init`)

#### Adding Alumni (Manual)

1. Open `data/people.xlsx`
Expand Down Expand Up @@ -301,6 +323,9 @@ The script will:
# Install dependencies
pip install -r requirements-build.txt

# Initialize lab-manual submodule (required for reconciliation)
git submodule update --init

# Validate data files
python scripts/validate_data.py

Expand Down
Binary file modified data/people.xlsx
Binary file not shown.
Loading
Loading