This is as ES6 Module for parsing and rendering of PGNs (Portable Game Notation).
The API is similar to history()
of chess.js, but this module supports variations, nags and comments in the pgn.
I used the grammar file from PgnViewerJS of mliebelt to create the parser.
npm install cm-pgn
Use the Pgn
class as JS Module:
<script type="module">
import {Pgn} from "./PATH/TO/cm-pgn/src/Pgn.js"
// parse pgn
const pgn = new Pgn(`[Site "Berlin"]
[Date "1989.07.02"]
[White "Haack, Stefan"]
[Black "Maier, Karsten"]
1. e4 e5 (e6) 2. Nf3 $1 {Great move!} Nc6 *`)
</script>
constructor(pgnString = "", props = {})
if you set { sloppy: true }
in props, some non-standard move notations
will be accepted. See also .move(move, options) from chess.js.
The pgn
has a pgn.header
and a pgn.history
.
The header holds the PGN header elements in the key value object tags
.
pgn.header.tags = {
Site: "Berlin",
Date: "1989.07.02",
White: "Haack, Stefan",
Black: "Maier, Karsten"
}
The moves are stored in an array. Every element of that array has the following structure
pgn.history.moves[i] = {
color: "w", // the moving color
fen: "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1", // the fen after that move
flags: "b", // the flags, like described below
from: "e2", // the square from
next: {color: "b", from: "e7", to: "e6", flags: "n", piece: "p", /*…*/}, // a pointer to the next move
piece: "p", // the piece type
ply: 1, // the ply number
previous: undefined, // a pointer to the previous move
san: "e4", // the move in SAN notation
to: "e4", // the square to
uci: "e2e4", // the move in UCI notation
variation: (4) [{/*…*/}, {/*…*/}, {/*…*/}, {/*…*/}], // a pointer to the begin of the current variation
variations: [] // all variations starting with that move
}
- 'n' - a non-capture
- 'b' - a pawn push of two squares
- 'e' - an en passant capture
- 'c' - a standard capture
- 'p' - a promotion
- 'k' - kingside castling
- 'q' - queenside castling
- 'p' - pawn
- 'n' - knight
- 'b' - bishop
- 'r' - root
- 'q' - queen
- 'k' - king
const history = pgn.history
assert.equal(4, history.moves.length)
assert.equal(history.moves[0].san, "e4")
assert.equal(history.moves[1].variations.length, 1)
assert.equal(history.moves[1].variations[0][0].san, "e6")
assert.equal(history.moves[2].nag, "$1")
assert.equal(history.moves[2].commentAfter, "Great move!")
assert.equal(history.moves[2].fen, "rnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2")
assert.equal(history.moves[3].from, "b8")
assert.equal(history.moves[3].to, "c6")
assert.equal(history.moves[3].uci, "b8c6")
assert.equal(history.moves[3].san, "Nc6")
assert.equal(history.moves[3].previous.san, "Nf3")
assert.equal(history.moves[3].previous.next.san, "Nc6")
This module uses PEG.js for parser generation. The parser (pgnParser.js
)
in src/cm-pgn/parser/
is generated from the grammar file src/grammar/pgn.pegjs
.
To recreate the parser after modification of src/grammar/pgn.pegjs
, run bin/generate-parser.sh
.