Skip to content

I7T5/nbdiff

Repository files navigation

NBDiff

A desktop app for visually diffing Mathematica notebooks (.nb files). Built for faster grading — drop in a solution key and a student submission, and instantly see what's different.

Tauri React macOS Windows

How it works

  1. Drop a key/solution .nb file on the left panel
  2. Drop a student submission .nb file or a folder containing .nb files on the right panel
  3. The app extracts input cells from each notebook using Wolfram Engine, then displays a color-coded diff:
    • 🟢 Green — lines added in the submission
    • 🔴 Red — lines removed (present in key but not submission)

You can also click either panel to open a file browser instead of dragging.

Prerequisites

  • Wolfram Engine or Mathematica (for extracting notebook inputs)
  • Python 3.10+ with wolframclient and oauthlib
  • Rust and Node.js 20+

Setup

# Install Python dependencies
pip install wolframclient oauthlib

# Install Node dependencies
npm install

# Build the Python sidecar binary
pip install pyinstaller
pyinstaller --onefile --name extract-inputs \
  --distpath src-tauri/binaries \
  --hidden-import=oauthlib --hidden-import=oauthlib.oauth1 \
  --collect-all wolframclient \
  --exclude-module PyQt6 --exclude-module PySide6 \
  --exclude-module matplotlib --exclude-module numpy \
  --exclude-module PIL --exclude-module tkinter \
  extract-inputs.py

# Rename with your target triple
mv src-tauri/binaries/extract-inputs \
   src-tauri/binaries/extract-inputs-$(rustc -vV | sed -n 's/host: //p')

Development

npx tauri dev

Build

npx tauri build

The bundled .app and .dmg will be in src-tauri/target/release/bundle/.

Project structure

nbdiff/
├── extract-inputs.py          # Python script for .nb input extraction
├── src/
│   ├── App.tsx                # Main app — drop zones, drag-drop, file dialog
│   ├── components/
│   │   └── DiffView.tsx       # Side-by-side diff with color coding
│   ├── main.tsx               # React entry point
│   └── styles.css             # Dark theme UI
├── src-tauri/
│   ├── src/lib.rs             # Rust backend — sidecar invocation
│   ├── binaries/              # PyInstaller sidecar binary (gitignored)
│   ├── capabilities/          # Tauri permission config
│   └── tauri.conf.json        # Tauri app config
└── package.json

Roadmap

  • Accept a folder of student submissions on the right panel
  • Arrow-key navigation between students for rapid grading
  • Word-level diff highlighting within changed lines
  • Add text field for each student submittion for adding quick grader notes, with an option to automatically save notes to directory
  • Display multiple student submission windows at once, the lines of each one aligning with the key window
  • Display multiple rows of key/submissions