# acad

> Terminal-based academic workflow CLI — courses, lectures, problem sets, grades, and a status dashboard, with first-class neovim and fish integration. Compile LaTeX with `latexmk`, insert Ipe figures with one keymap, and track grades from the command line.

Inspired by the late [Gilles Castel](https://castel.dev).

---

## What this is

`acad` is a single command-line tool for organizing notes-as-code. It manages courses, scaffolds new lectures and problem sets (in LaTeX or Org-mode), tracks grades, renders a live dashboard of recent activity, and integrates with `latexmk` for compilation and an [Ipe](https://ipe.otfried.org/) pipeline for figures.

It is designed to live next to **neovim** (with [vimtex](https://github.com/lervag/vimtex)) and **fish** — but the core CLI works in any shell with any editor.

---

## Quickstart (if you already have Python and LaTeX)

```bash
pipx install acad-cli
acad init                            # interactive: pick a content directory
export UNI_ROOT="$HOME/academic"     # add to your shell config
acad d                               # dashboard
```

If those four commands worked, you're done with setup. Jump to [Usage](#usage) or [Editor integration](#editor-integration-neovim).

If you don't have Python or pipx or LaTeX, keep reading.

---

## Prerequisites

`acad` itself is a small Python program. It calls out to `pdflatex` / `latexmk` for compilation, and optionally to `ipe` for figures and `task`/`timew` for the task panel of the dashboard.

| Requirement | Required? | What it's for |
|---|---|---|
| Python 3.9+ | yes | running `acad` itself |
| pipx | yes | installing `acad` in an isolated environment |
| TeX Live or MacTeX | yes (for compilation) | `pdflatex`, `latexmk` |
| neovim 0.9+ | recommended | the editor experience this tool is designed around |
| vimtex | recommended | LaTeX-aware editing inside neovim |
| Skim (macOS) or zathura (Linux) | recommended | synctex-capable PDF viewer |
| Ipe | optional | figure-insertion keymaps |
| Taskwarrior + Timewarrior | optional | populating the "TASKS" panel on the dashboard |
| fish | optional | the `uni` wrapper + aliases (any POSIX shell works for `acad` itself) |

### Installing Python and pipx

**macOS (recommended: Homebrew)**

```bash
# Install Homebrew if you don't have it: https://brew.sh
brew install python pipx
pipx ensurepath
exec $SHELL   # reload your shell so ~/.local/bin is on PATH
```

**Linux (Debian/Ubuntu)**

```bash
sudo apt update
sudo apt install python3 python3-pip pipx
pipx ensurepath
exec $SHELL
```

**Linux (Arch)**

```bash
sudo pacman -S python python-pipx
pipx ensurepath
```

**Windows** — install Python from [python.org](https://www.python.org/downloads/) (check "Add Python to PATH" during install), then in PowerShell:

```powershell
python -m pip install --user pipx
python -m pipx ensurepath
```

To verify: `python3 --version` should print 3.9 or higher, and `pipx --version` should print a version number.

### Installing LaTeX

**macOS** — install [MacTeX](https://www.tug.org/mactex/) (the full distribution, ~4 GB) or BasicTeX (smaller). With Homebrew:

```bash
brew install --cask mactex          # full
# or:
brew install --cask basictex        # smaller
```

**Linux (Debian/Ubuntu)**

```bash
sudo apt install texlive-full       # full
# or smaller subset:
sudo apt install texlive-latex-recommended texlive-latex-extra latexmk
```

**Linux (Arch)**

```bash
sudo pacman -S texlive-most texlive-latexextra
```

**Windows** — install [MiKTeX](https://miktex.org/download).

To verify: `pdflatex --version` and `latexmk --version` should both work.

### Installing Ipe (optional)

If you want the figure pipeline.

- macOS: `brew install --cask ipe`
- Linux: `sudo apt install ipe` (Debian/Ubuntu) or `sudo pacman -S ipe` (Arch)
- Windows: download from [ipe.otfried.org](https://ipe.otfried.org/)

### Installing neovim and vimtex

`acad`'s editor integration is designed around neovim. You can use any editor, but you'll get the most out of it with nvim.

**Install neovim:**

- macOS: `brew install neovim`
- Linux (Debian/Ubuntu): `sudo apt install neovim` (note: distro versions are sometimes old — for the latest, use the [official AppImage](https://github.com/neovim/neovim/releases) or [bob](https://github.com/MordechaiHadad/bob))
- Linux (Arch): `sudo pacman -S neovim`
- Windows: see [neovim.io](https://neovim.io/)

**Install vimtex** — vimtex is a neovim plugin. Use whatever plugin manager you already have (lazy.nvim, packer, vim-plug). For lazy.nvim, add `{ "lervag/vimtex" }` to your plugin list. For vim-plug, add `Plug 'lervag/vimtex'` to your `init.vim` and run `:PlugInstall`.

If you don't have a neovim setup yet, the easiest starting point is a kickstart distribution like [kickstart.nvim](https://github.com/nvim-lua/kickstart.nvim) or [LazyVim](https://www.lazyvim.org/) — both come with sensible defaults that work well with vimtex.

---

## Installing acad

Once Python and pipx are working:

```bash
pipx install acad-cli
```

This puts the `acad` command on your PATH (in `~/.local/bin/acad`) inside an isolated virtual environment, so it won't conflict with other Python packages.

To verify:

```bash
acad --help
```

You should see a usage line listing the subcommands (`new`, `pset`, `course`, `list`, `dashboard`, `init`, `grades`, `select`, `info`, `format`).

If you get "command not found", `~/.local/bin` is not on your PATH. Run `pipx ensurepath` and restart your shell.

---

## Setting up your content directory

```bash
acad init
```

`acad init` prompts you to either use the default location (`~/academic`) or specify a custom path. It creates the directory and drops in:

- `preamble.tex` — a starter LaTeX preamble (you'll edit this to taste)
- `preamble-darkmode.tex` — optional dark-mode tweaks
- `.latexmkrc` — the build config (plain `pdflatex` via `latexmk`)
- `.academic/config.json` — semester, author name, course list

Then tell your shell where this is:

**bash / zsh** — add to `~/.bashrc` or `~/.zshrc`:

```bash
export UNI_ROOT="$HOME/academic"     # or whatever path you chose
```

**fish** — run once:

```fish
set -Ux UNI_ROOT "$HOME/academic"
```

Open a new terminal (or `source` the config), then run `acad d` to see your dashboard. It will be empty until you add courses.

### Adding your first course

```bash
acad course add math101 --code "MATH 101" --instructor "Dr. Smith" --schedule "MWF 10am"
acad list
```

This creates `$UNI_ROOT/math101/` and registers it in `.academic/config.json`.

### Creating a lecture

```bash
acad select math101                  # set "current course"
acad new -t "Vector Spaces" --tex    # scaffold lecture_01.tex
```

This creates a numbered lecture file (`lecture_01.tex`) with the right preamble inputs, opens cleanly in vimtex, compiles with `latexmk` against the shared preamble.

---

## Editor integration: neovim

The recommended setup is neovim + vimtex + the `acad` keymap layer.

### Step 1: Ensure vimtex is installed

(See [Installing neovim and vimtex](#installing-neovim-and-vimtex) above.)

### Step 2: Copy the integration files

This repo ships two starter files under `integration/nvim/`:

- `vimtex.lua` — vimtex compiler config (plain `pdflatex` via `latexmk`, synctex-correct, Skim-aware autocompile)
- `keymaps.lua` — `<leader>a*` and `<leader>i*` keymap stanzas wired to `acad` and the Ipe pipeline

Copy them into your neovim config:

```bash
# clone or download this repo if you haven't:
git clone https://github.com/sdvstephens/acad-cli.git
cd acad-cli

# adapt these into your own config — the exact paths depend on your setup:
cp integration/nvim/vimtex.lua  ~/.config/nvim/lua/plugins/
cp integration/nvim/keymaps.lua ~/.config/nvim/lua/config/acad-keymaps.lua
```

Then `require("config.acad-keymaps")` from your `init.lua`.

### Step 3: Verify

Open any `.tex` file in your `$UNI_ROOT`, then try:

| keymap | what it does |
|---|---|
| `<leader>tc` | compile (vimtex) |
| `<leader>tv` | view PDF in Skim/zathura |
| `<leader>al` | new lecture (prompts for course + topic) |
| `<leader>ah` | new problem set |
| `<leader>ad` | dashboard (inside nvim) |
| `<leader>ar` | list courses |
| `<leader>ai` | current course info |
| `<leader>ic` | create new Ipe figure (requires `ipe-figures.py` — see note in `keymaps.lua`) |

---

## Shell integration: fish (optional)

If you use fish, copy `integration/fish/uni.fish` into `~/.config/fish/conf.d/`. It gives you a `uni <subcommand>` wrapper plus a `grades` shorthand alias:

```bash
cp integration/fish/uni.fish ~/.config/fish/conf.d/
exec fish
uni help
```

For bash/zsh users, an equivalent function is on the roadmap. For now, just call `acad` directly.

---

## Usage

```bash
# Dashboard
acad d                               # or `acad dashboard` — courses, tasks, recent files
acad d --json                        # machine-readable

# Courses
acad list                            # list all courses
acad course add <name>               # add a new course
acad course edit <name> --code C101  # edit metadata
acad course cleanup --name <course>  # delete aux files in a course
acad select <name>                   # set the "current course"
acad info                            # info about current course

# Lectures and psets
acad new -c <course> -t "<topic>" --tex      # create a numbered lecture
acad pset -c <course> -t "<title>" --tex     # create a numbered problem set

# Grades
acad grades list                                          # list courses with grade tracking
acad grades add-course -c "Linear Algebra" --credits 3
acad grades add-category -c "Linear Algebra" --category PSets --weight 30
acad grades add-grade -c "Linear Algebra" -a "PS1" -g 95 --max 100 --category PSets
acad grades show -c "Linear Algebra"                      # full grade card
acad grades show-all                                      # all courses
acad grades export-latex -c "Linear Algebra"              # LaTeX table

# Output format default
acad format tex                      # default to LaTeX for new lectures
acad format org                      # default to Org-mode
```

---

## Troubleshooting

**`acad: command not found`** — `~/.local/bin` is not on your `PATH`. Run `pipx ensurepath` and open a new shell.

**`pdflatex: command not found`** — TeX Live / MacTeX is not installed, or its `bin` directory is not on `PATH`. On macOS, the MacTeX installer normally adds `/Library/TeX/texbin` to PATH; reopen your terminal after install.

**`acad d` shows "No courses found"** — either `UNI_ROOT` isn't exported (check with `echo $UNI_ROOT`) or there are no course directories under it. Run `acad init` if you haven't, then `acad course add <name>` to add one.

**vimtex compile fails with "preamble.tex not found"** — `_UNI_ROOT` in the LaTeX `\input` resolves to whatever `UNI_ROOT` was when `acad new` scaffolded the lecture. Check the first lines of the generated `.tex` file — they should reference your actual content directory.

**Skim doesn't open the PDF on save** — make sure Skim is set as the default `.pdf` handler, and that vimtex's `g:vimtex_view_method = "skim"` (already configured in the shipped `vimtex.lua`).

**Permission denied opening `acad`** — pipx installed it, but `~/.local/bin/acad` isn't executable somehow. Try `pipx reinstall acad-cli`.

---

## Privacy

`acad` reads and writes only inside `$UNI_ROOT` (and `~/.local/share/pipx/...` for the install itself). It does not phone home, does not collect telemetry, does not require an account. Your `.grades.json` and `.academic/config.json` stay on your machine.

---

## Roadmap

- [ ] Fold `compile_master.py` (multi-lecture master compile) into `acad` as `acad compile`
- [ ] Fold `ipe-figures.py` into `acad` as `acad fig`
- [ ] Bash/zsh equivalent of `integration/fish/uni.fish`
- [ ] CI + smoke tests
- [ ] Optional Google Calendar sync subcommand
- [ ] PyPI release notes / changelog

---

## License

MIT — see [LICENSE](LICENSE).

Inspired by the late [Gilles Castel](https://castel.dev/post/lecture-notes-1/). Built atop neovim, vimtex, latexmk, and Ipe.
