# Anki YAML Sync

A Python CLI tool for bi-directional syncing of Anki notes as YAML files for easy editing and version control.

Inspired by [visserle/DeckOps](https://github.com/visserle/DeckOps).

## Features

- **Bi-Directional Syncing**: Import notes from Anki to YAML and export YAML back to Anki
- **Human-Readable Format**: Notes are stored as YAML files for easy editing
- **Flexible**: Update existing notes or create new notes (based on ID field)
- **Deck-Aware Storage**: Notes are stored in folders that mirror deck nesting

## Requirements

- **Anki**: Running instance of Anki desktop
- **AnkiConnect**: Must be installed and running on `localhost:8765` (default)

To set up AnkiConnect (https://ankiweb.net/shared/info/2055492159):

1. Open Anki > Menu Bar > Tools > Add-ons > Get Add-ons
2. Enter the code `2055492159` and click "OK" to install AnkiConnect
3. Restart Anki

## Installation

Run the following command to install globally: `pipx install anki-yaml-sync`

## Usage

### Import Notes from Anki

Fetch all notes from Anki and save them as YAML files:

```bash
anki-yaml-sync import [--output-dir OUTPUT]
```

Aliases: `get-from-anki`, `fetch`, `gfa`, `f`

Options:
- `--output-dir`, `-o`: Directory to save YAML files (default: `notes`)

Example:
```bash
anki-yaml-sync import --output-dir ./my-notes
```

### Export Notes to Anki

Sync YAML files back to Anki:

```bash
anki-yaml-sync export [--input-dir INPUT] [--deck DECK]
```

Aliases: `send-to-anki`, `push`, `sta`, `p`

Options:
- `--input-dir`, `-i`: Directory containing YAML files (default: `notes`)
- `--deck`: Deck to add new notes to (default: `Default`)

Example:
```bash
anki-yaml-sync export --input-dir ./my-notes --deck "My Deck"
```

### Verbose Output

Add `-v` or `--verbose` flag to any command for detailed logging:

```bash
anki-yaml-sync -v import
anki-yaml-sync -v export
```

### YAML Format

Each note is stored as a separate YAML file. Example:

```yaml
id: 1234567890
type: Basic
deck: Languages::French
tags:
  - french
  - vocabulary
fields:
  Front: Bonjour
  Back: Hello
```

**Fields:**
- `id`: Anki note ID (required for updates)
- `type`: Note type name (e.g., "Basic", "Cloze")
- `deck`: Full deck name using `::` (e.g., `Parent::Child`)
- `tags`: List of tags to apply
- `fields`: Dictionary of field names to field values
- `created`: Creation timestamp
- `modified`: LastModification timestamp

### Deck Folder Structure

Deck nesting is reflected in folders. For example, a note in deck `Languages::French` is stored as:

```
notes/Languages/French/<note>.yaml
```

### Workflow

1. **Initial Import**: Run `anki-yaml-sync import` to create YAML files from your Anki collection
2. **Edit**: Open and edit the YAML files with your text editor or IDE
3. **Sync Back**: Run `anki-yaml-sync export` to sync your changes back to Anki

### Updating Existing Notes

If a YAML file has an `id` field that matches an existing Anki note, the export will update that note. Fields are completely replaced (not merged).

If the YAML `deck` differs from the current deck, the note's cards will be moved to the YAML deck.

### Creating New Notes

To create a new note:

1. Create a new YAML file with a temporary or missing `id` (e.g., `0` or `null`)
2. Run `anki-yaml-sync export`
3. The YAML file will be automatically updated with the assigned note ID

**Note**: If the ID is that of an existing note, the existing note may be overwritten with the YAML file instead of creating a new note in Anki.

## Contributing

[See CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on contributing to this project and setting up development environment on your device.