Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pgn_prep

This tool is for playing with Portable Game Notation (PGN) files, by allowing to split them up into several chunks and also shuffling them. The reason for chunking is that Lichess silently drops everything past game 64 when you import a PGN into a study. Shuffling becomes useful for training, as if your PGN file is sorted by opening or theme, the game number already hints at what position/tactic/whatever is coming. Shuffle it first and you have to actually recognise the position rather than remember where it is in the file.

Python 3.10+, no dependencies.

Setup

git clone https://github.com/your-username/pgn-prep
cd pgn-prep
python pgn_prep.py my_games.pgn

Or pip install -e . if you want a pgn-prep command on your PATH.

Usage

# split into 64-game chunks
python pgn_prep.py tournament_2024.pgn

# shuffle then split into 32-game chunks
python pgn_prep.py repertoire.pgn --shuffle --chunk-size 32

# same seed = same shuffle every time, useful for sharing with others
python pgn_prep.py repertoire.pgn --seed 42

# named chapters — won't cut across opening sections
python pgn_prep.py repertoire.pgn --split-at 25,55 --names "1.e4,1.d4,Flank"

# see what would happen without writing anything
python pgn_prep.py repertoire.pgn --dry-run --verbose

Chapter boundaries

If your PGN is divided into sections (openings, endgame themes, whatever), --split-at lets you mark where each section ends so the chunks never cross those boundaries:

python pgn_prep.py repertoire.pgn \
    --split-at 30,75,110 \
    --names "Open Games,Semi-Open,Closed,Flank"

This gives you Open Games.pgn, Semi-Open.pgn, and so on. If a section still has more than 64 games it gets split further and the pieces are numbered (Open Games_1.pgn, Open Games_2.pgn).

--names works without --split-at too — handy if you just want the output called something other than repertoire_part1.pgn.

All options

default
--chunk-size N 64 max games per file
--shuffle off randomise order before splitting
--seed N pin the shuffle; implies --shuffle
--split-at N1,N2,... force splits at these game numbers
--names NAME,... filenames for each --split-at segment
--output-dir DIR next to source where to write files
--prefix STR prepend to every output filename
--dry-run off print plan, don't write
--encoding ENC utf-8-sig strips BOM automatically
--no-number-pad off _part1 not _part01
--verbose off print each game as it's processed
--remove-nulls off strip null moves (--) so it can be imported to Lichess with no errors

How it works

The script finds game boundaries in the raw text rather than parsing moves. A line matching [TagName "Value"] that isn't inside a { comment } or ( variation ) marks the start of a new game header. Brace and parenthesis depth are tracked as it scans, so annotation text that happens to look like a tag pair doesn't trigger a false split. Everything between boundaries — moves, comments, NAGs, variations — passes through untouched.

Output files are always UTF-8, no BOM. Games are separated by one blank line regardless of how the original was formatted.

This won't fix a broken PGN. If Lichess rejects a chunk after import, the problem was in the original file, not something introduced here.

License

MIT — Mikel Iturbe

About

A tool for chunking and shuffling PGN files

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages