{"id":21076094,"url":"https://github.com/shaack/cm-pgn","last_synced_at":"2025-09-04T09:42:58.679Z","repository":{"id":57144776,"uuid":"124200287","full_name":"shaack/cm-pgn","owner":"shaack","description":"Parse and create PGNs (Portable Game Notation for chess games)","archived":false,"fork":false,"pushed_at":"2025-03-26T10:51:55.000Z","size":180,"stargazers_count":30,"open_issues_count":4,"forks_count":22,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-04T05:42:46.055Z","etag":null,"topics":["chess","chessmail","es6","javascript","parser","pgn","released"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shaack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-07T07:59:25.000Z","updated_at":"2025-03-26T10:51:59.000Z","dependencies_parsed_at":"2024-05-07T14:54:48.432Z","dependency_job_id":"f65a17b3-d68d-424b-b27f-bebeec91080d","html_url":"https://github.com/shaack/cm-pgn","commit_stats":{"total_commits":188,"total_committers":4,"mean_commits":47.0,"dds":0.0478723404255319,"last_synced_commit":"b145c455674eb243a2f8bd47d59ed8cecc29b05e"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shaack%2Fcm-pgn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shaack%2Fcm-pgn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shaack%2Fcm-pgn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shaack%2Fcm-pgn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shaack","download_url":"https://codeload.github.com/shaack/cm-pgn/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247128739,"owners_count":20888234,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chess","chessmail","es6","javascript","parser","pgn","released"],"created_at":"2024-11-19T19:26:36.015Z","updated_at":"2025-04-06T14:12:34.973Z","avatar_url":"https://github.com/shaack.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cm-pgn\n\n## Parser for PGNs (Portable Game Notation)\n\nThis is as **ES6 Module for parsing and rendering of PGNs** ([Portable Game Notation](https://de.wikipedia.org/wiki/Portable_Game_Notation)).\n\nThe API is similar to `history()` of [chess.js](https://github.com/jhlywa/chess.js), but this module **supports variations, nags and comments** in the pgn.\n\nI used the grammar file from [PgnViewerJS](https://github.com/mliebelt/PgnViewerJS) of [mliebelt](https://github.com/mliebelt) to create the parser.\n\n## Install\n\n`npm install cm-pgn`\n\n## Usage\n\nUse the `Pgn` class as JS Module:\n\n```html\n\n\u003cscript type=\"module\"\u003e\n    import {Pgn} from \"./PATH/TO/cm-pgn/src/Pgn.js\"\n    // parse pgn\n    const pgn = new Pgn(`[Site \"Berlin\"]\n[Date \"1989.07.02\"]\n[White \"Haack, Stefan\"]\n[Black \"Maier, Karsten\"]\n\n1. e4 e5 (e6) 2. Nf3 $1 {Great move!} Nc6 *`)\n\u003c/script\u003e\n```\n\n## Pgn constructor\n\n`constructor(pgnString = \"\", props = {})`\n\nif you set `{ sloppy: true }` in props, some non-standard move notations\nwill be accepted. See also [.move(move, options)](https://github.com/jhlywa/chess.js/blob/master/README.md#movemove--options-) from chess.js.\n\n## Data structure\n\nThe `pgn` has a `pgn.header` and a `pgn.history`.\n\n### pgn.header\n\nThe header holds the PGN header elements in the key value object `tags`.\n\n```js\npgn.header.tags = {\n    Site: \"Berlin\",\n    Date: \"1989.07.02\",\n    White: \"Haack, Stefan\",\n    Black: \"Maier, Karsten\"\n}\n```\n\n### pgn.history\n\nThe moves are stored in an array. Every element of that array has the following structure\n\n```js\npgn.history.moves[i] = {\n    color: \"w\", // the moving color\n    fen: \"rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1\", // the fen after that move\n    flags: \"b\", // the flags, like described below\n    from: \"e2\", // the square from\n    next: {color: \"b\", from: \"e7\", to: \"e6\", flags: \"n\", piece: \"p\", /*…*/}, // a pointer to the next move \n    piece: \"p\", // the piece type \n    ply: 1, // the ply number\n    previous: undefined, // a pointer to the previous move\n    san: \"e4\", // the move in SAN notation\n    to: \"e4\", // the square to\n    uci: \"e2e4\", // the move in UCI notation\n    variation: (4) [{/*…*/}, {/*…*/}, {/*…*/}, {/*…*/}], // a pointer to the begin of the current variation\n    variations: [] // all variations starting with that move\n}\n```\n\n#### pgn.history.moves[i].flags\n\n- 'n' - a non-capture\n- 'b' - a pawn push of two squares\n- 'e' - an en passant capture\n- 'c' - a standard capture\n- 'p' - a promotion\n- 'k' - kingside castling\n- 'q' - queenside castling\n\n#### pgn.history.moves[i].piece\n\n- 'p' - pawn\n- 'n' - knight\n- 'b' - bishop\n- 'r' - root\n- 'q' - queen\n- 'k' - king\n\n#### Examples\n\n```js\nconst history = pgn.history\nassert.equal(4, history.moves.length)\nassert.equal(history.moves[0].san, \"e4\")\nassert.equal(history.moves[1].variations.length, 1)\nassert.equal(history.moves[1].variations[0][0].san, \"e6\")\nassert.equal(history.moves[2].nag, \"$1\")\nassert.equal(history.moves[2].commentAfter, \"Great move!\")\nassert.equal(history.moves[2].fen, \"rnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2\")\nassert.equal(history.moves[3].from, \"b8\")\nassert.equal(history.moves[3].to, \"c6\")\nassert.equal(history.moves[3].uci, \"b8c6\")\nassert.equal(history.moves[3].san, \"Nc6\")\nassert.equal(history.moves[3].previous.san, \"Nf3\")\nassert.equal(history.moves[3].previous.next.san, \"Nc6\")\n```\n\n## Development\n\nThis module uses [PEG.js](https://pegjs.org/) for parser generation. The parser (`pgnParser.js`)\nin `src/cm-pgn/parser/` is generated from the grammar file `src/grammar/pgn.pegjs`.\n\nTo recreate the parser after modification of `src/grammar/pgn.pegjs`, run `bin/generate-parser.sh`.\n\n## Testing\n\n[Run the unit tests](https://shaack.com/projekte/cm-pgn/test)\n\n## External Links\n\n- [Wikipedia Portable_Game_Notation](https://en.wikipedia.org/wiki/Portable_Game_Notation)\n- [Portable Game Notation Specification and Implementation Guide](http://www.saremba.de/chessgml/standards/pgn/pgn-complete.htm)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshaack%2Fcm-pgn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshaack%2Fcm-pgn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshaack%2Fcm-pgn/lists"}