Code Monkey home page Code Monkey logo

pgn-parser's Introduction

pgn-parser

Build Status

Parse PGN files into a JS data structure (and syntax validation on the PGN)

Usage

From the command line: src/pgn-parser.js some/pgn/file.pgn

From js

const pgnParser = require('pgn-parser');

const [result] = pgnParser.parse('[White "me"]\n[Black "you"]\n1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 (3. ...Nf6 {is the two knights}) 4. b4 Bxb4 5. c3 Ba5 6. d4 exd4 7. O-O Nge7 $1 *');

console.log(result);

Output

The result parsing the PGN above would be

[
    {
        headers: [ 
            {name: "White", value: "me"},
            {name: "Black", value: "you"}
        ],
        result: "*",
        moves: [
            { move: 'e4', move_number: 1},
            { move: 'e5',
            { move: 'Nf3', move_number: 2},
            { move: 'Nc6'},
            { move: 'Bc4', move_number: 3},
            { move: 'Bc5', ravs: [{ moves: [{move_number: 3, move: "...Nf6", comments: [{text: "is the two knights"}]}]}]},
            { move: 'b4', move_number: 4},
            { move: 'Bxb4'},
            { move: 'c3', move_number: 5},
            { move: 'Ba5'},
            { move: 'd4', move_number: 6},
            { move: 'exd4'},
            { move: 'O-O', move_number: 7},
            { move: 'Nge7', nags: ["$1"]}
        ]
    }
]

Run tests


npm install
npm test

pgn-parser's People

Contributors

ejezisek avatar kevinludwig avatar loloof64 avatar tneisinger avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

pgn-parser's Issues

Doesn't handle pgn's with null moves

Some pgn's have null moves tabulated with --, quite a few available at The Week in Chess (https://theweekinchess.com/).

Example:

[Event "Turkey Cup 2014"]
[Site "Kemer TUR"]
[Date "2014.02.02"]
[Round "2.71"]
[White "Subasi,Zeki"]
[Black "Yuvarlak,U"]
[Result "1/2-1/2"]
[WhiteElo "1714"]
[BlackElo "1850"]
[ECO "C45"]
[Opening "Scotch"]
[Variation "Schmidt variation"]
[WhiteFideId "6345433"]
[BlackFideId "6305598"]
[EventDate "2014.02.01"]

1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Nf6 5. Nc3 Bb4 6. Nxc6 bxc6 7. Bd3 d5 8.
O-O Bxc3 9. bxc3 dxe4 10. Qe2 O-O 11. Bxe4 Re8 12. f3 Bf5 13. Bg5 -- 14. Rad1
Qe7 15. Bxf6 Qxf6 16. Qc4 Rad8 17. Bxc6 1/2-1/2

See also
https://lichess.org/forum/lichess-feedback/request-allow-null-moves-in-studies.
https://www.chess.com/forum/view/general/what-is-a-null-move-and-how-to-make-it

Handle single line comments

Single line comments start with a ; character and go to the end of the line

https://en.wikipedia.org/wiki/Portable_Game_Notation#Comments

Sample PGN file from this url does not work.
https://zanchess.wordpress.com/2018/02/15/1st-american-chess-congress-new-york-1857/


;; <Paulsen // Raphael * (R3.1) 25 1-0>
;; <Raphael, Benjamin -- Paulsen, Louis  (R3.1) 25 0-1>

[Event "1st American Chess Congress"]
[Site "New York, NY USA"]
[Date "1857.10.26"]
[Round "3.1"]
[White "Raphael, Benjamin"]
[Black "Paulsen, Louis"]
[Result "0-1"]
[WhiteElo "?"]
[BlackElo "?"]
[ECO "B40"]
[EventDate "1857.10.05"]
[PlyCount "50"]

1.e4 c5 2.d4 cxd4 3.Nf3 e6 4.Nxd4 Bc5 5.Nc3 Qb6 6.Na4 Qa5+ 7.c3 Bxd4 8.Qxd4 Nf6 9.f3 Nc6 10.Qd1 O-O 11.b4 Qe5 12.Bd3 Nxb4 13.cxb4 Qxa1 14.Qc2 Qd4 15.Bb2 Qe3+ 16.Kd1 Qh6 17.Bc1 Qh4 18.Nc3 d5 19.g3 Qh5 20.Qf2 Nxe4 21.Bxe4 dxe4 22.Nxe4 Qd5+ 23.Bd2 Qxa2 24.Re1 Bd7 25.Qe3 Bb5 0-1


;; <Paulsen // Raphael   (R3.2) 47 1/2-1/2>
;; <Paulsen, Louis -- Raphael, Benjamin  (R3.2) 47 1/2-1/2>

[Event "1st American Chess Congress"]
[Site "New York, NY USA"]
[Date "1857.10.27"]
[Round "3.2"]
[White "Paulsen, Louis"]
[Black "Raphael, Benjamin"]
[Result "1/2-1/2"]
[WhiteElo "?"]
[BlackElo "?"]
[ECO "C47"]
[EventDate "1857.10.05"]
[PlyCount "93"]

1.e4 e5 2.Nc3 Nf6 3.Nf3 Nc6 4.d4 Bb4 5.d5 Ne7 6.Nxe5 d6 7.Nf3 Nxe4 8.Qd4 Bxc3+ 9.bxc3 Nf6 10.Bc4 O-O 11.O-O h6 12.Bb3 a5 13.a4 Ng6 14.Ba3 Re8 15.Rfe1 Bg4 16.Nd2 Ne5 17.c4 Re7 18.c5 Qd7 19.cxd6 cxd6 20.c4 Rae8 21.c5 Nc6 22.Rxe7 Nxd4 23.Rxd7 Nxd7 24.f3 Re2 25.Rd1 Bh3 26.c6 Rxg2+ 27.Kh1 bxc6 28.dxc6 Ne5 29.Bxd6 Nexc6 30.Bc4 Rg6 31.Bg3 Nf5 32.Ne4 Ne3 33.Rc1 Bg2+ 34.Kg1 Bxf3 35.Bd3 f5 36.Nd6 Nd4 37.Rc5 Rf6 38.Rxa5 f4 39.Nc4 fxg3 40.Nxe3 gxh2+ 41.Kxh2 g5 42.Ra7 Kf8 43.a5 Rf7 44.Ra6 Re7 45.Rf6+ Ke8 46.Nf5 Nxf5 47.Bxf5 1/2-1/2


;; <Fiske // Marache   (R1.4) 35 0-1>
;; <Fiske, Daniel -- Marache, Napoleon  (R1.4) 35 0-1>

[Event "1st American Chess Congress"]
[Site "New York, NY USA"]
[Date "1857.10.19"]
[Round "1.4"]
[White "Fiske, Daniel"]
[Black "Marache, Napoleon"]
[Result "0-1"]
[WhiteElo "?"]
[BlackElo "?"]
[ECO "A84"]
[EventDate "1857.10.05"]
[PlyCount "70"]

1.d4 e6 2.c4 f5 3.Nc3 Nf6 4.e3 b6 5.Nf3 Bb4 6.a3 Bxc3+ 7.bxc3 O-O 8.Bd3 Bb7 9.O-O Nc6 10.Bb2 Ne7 11.Nh4 d6 12.f4 Qd7 13.Qc2 Ng4 14.Rae1 Rf6 15.e4 Rh6 16.Nf3 Rf8 17.h3 Nf6 18.exf5 exf5 19.d5 c6 20.Qe2 Ng6 21.dxc6 Qxc6 22.Nd4 Qc5 23.Qe6+ Kh8 24.Bxf5 Nh5 25.Qe8 Nf6 26.Qe2 Nh4 27.Qe7 Rb8 28.Bd3 Bxg2 29.Rf2 Bxh3 30.f5 Rh5 31.Bc1 Bxf5 32.Bxf5 Nxf5 33.Nxf5 Rxf5 34.Be3 Qe5 35.Qxa7 Qg3+ 0-1


;; <Lichtenhein // Perrin   (R2.3) 30 1-0>
;; <Lichtenhein, Theodore -- Perrin, Frederick  (R2.3) 30 1-0>

[Event "1st American Chess Congress"]
[Site "New York, NY USA"]
[Date "1857.10.19"]
[Round "2.3"]
[White "Lichtenhein, Theodore"]
[Black "Perrin, Frederick"]
[Result "1-0"]
[WhiteElo "?"]
[BlackElo "?"]
[ECO "B00"]
[EventDate "1857.10.05"]
[PlyCount "59"]

1.e4 b6 2.d4 Bb7 3.Bd3 e6 4.Ne2 g6 5.O-O Bg7 6.c3 Ne7 7.f4 f5 8.e5 d6 9.Nd2 dxe5 10.fxe5 Bxe5 11.Bc4 Bd6 12.Bxe6 Bd5 13.Bxd5 Nxd5 14.Nf3 Nc6 15.Bg5 Qd7 16.Qb3 h6 17.Bh4 Na5 18.Qc2 Ne3 19.Qd3 Nxf1 20.Rxf1 g5 21.Bg3 f4 22.Qe4+ Kf7 23.Bxf4 Kg7 24.Be5+ Bxe5 25.Nxe5 Qe6 26.Rf7+ Qxf7 27.Nxf7 Kxf7 28.b4 Rae8 29.Qf3+ Kg8 30.bxa5 1-0

Parse fails on pgn from chess.com that includes computer analysis due to ±, ∓, and = characters

The chess.com analysis tool puts ±, ∓, and = characters into its pgn text when computer analysis is included. These characters are not contained within move comments. This causes parsing to fail.

Below is example pgn text from chess.com. Note the ± character in move 8:

1. e4 d5 2. exd5 Qxd5 3. Nc3 Qa5 4. Nf3 Nf6 5. Bc4 e6 6. d3 Bb4 7. Bd2 O-O 8. a3
Bd6? ± {MISTAKE (+3.05) Critical mistake.} ({(+1.06) The best move was} 8...
Bxc3 9. Bxc3 Qf5 *

I'm not sure if this usage of the ±, ∓, and = characters is normal in pgn, but I think it would be good for this package to be able to handle all chess.com pgn strings.

I'm happy to work on a pull request to fix this, but I'm not sure how those characters should be handled. Any opinions on that? Maybe the character should be prepended to the comment that follows it?

%cal and %cls not parsed

Hi,

nice library! Unfortunately %cal and %cls (arrows and square highlighting on the chess board) information is currently not parsed and creates an error.

Example (from https://lichess.org/study/D6DfYHZe):

{ [%csl Gf3,Gc6][%cal Gd2d4] }
1. e4 { this is a comment } { [%csl Gd5,Gf5][%cal Ge4d5,Ge4f5] } *

Also could you add a license to the project so others (like me :) ) could use it?

Accented characters are ignored in comments

The parser ignores comments with accented characters.

Example pgn:

[Event ""]
[Site ""]
[Date "????.??.??"]
[Round ""]
[White ""]
[Black ""]
[Result "*"]

1.e4 e5 2.f4 {A à E é I î O ô U ù Y} *

The comment is parsed as A E I O U Y.

there are correct pgns that it is not parsed correctly (with errors)

I have tried to parse this pgn :

[Event "?"]
[Site "?"]
[Date "2022.04.11"]
[Round "?"]
[White "Sistema Colle"]
[Black "Defensa india de rey"]
[Result "*"]
[ECO "A70"]
[Annotator "sky10p"]
[PlyCount "26"]
[SourceVersionDate "2022.04.11"]

  1. d4 Nf6 2. Nf3 g6 3. e3 Bg7 {[%cal Gf1e2,Gf1d3]} 4. Bd3 O-O 5. O-O {[%cal
    Gd7d5,Gc7c5,Gd7d6]} d6 {[%cal Gc2c4,Gb2b3,Gc2c3]} 6. Nbd2 (6. c4 e5 7. dxe5 (7.
    Nc3 {Si no cambia los peones, queremos forzar que haga d5, desarrollamos el
    caballo para eso} Nc6 8. d5 (8. b3 Nd7 {[%cal Gg7d4,Ge5d4,Gd7e5,Ge5g4]} 9. d5
    Ne7 {[%csl Gc5,Gf5][%cal Gf7f5,Gd7c5]}) 8... Ne7 9. e4 Nd7) 7... dxe5 8. Nxe5
    Qe7 9. Nf3 (9. f4 Nbd7 10. Nxd7 Bxd7 11. Nc3 {[%csl Ge3]} Bc6 {[%cal Gf8e8,
    Ga8d8,Gc6h1,Ge7e3,Gg7a1]}) 9... Rd8 10. Qc2 Nc6 {[%cal Gc6b4]} 11. a3 Qd6 {
    [%csl Gd3][%cal Gd6d3]} 12. Rd1 (12. Be2 Bf5 13. Qb3 Ne4 14. Qxb7 (14. Nc3 Na5
  2. Qa4 (15. Qb4 Bxc3 16. bxc3 Qa6 {[%csl Gc4,Gc5,Ge2][%cal Ga6e2,Gc7c5]} 17.
    Bb2 c5 18. Qb5 Be6 19. Qxa6 bxa6 {[%csl Gc4][%cal Ga5c4,Ge6c4,Gd8d1]}) 15...
    Bxc3 16. bxc3 Nxc3) 14... Rdb8) 12... Bf5 {[%csl Gd3][%cal Gf5c2,Gd6d1]}) (6.
    b3 {[%cal Gc1b2]} e5 7. dxe5 dxe5 {[%csl Ge4][%cal Ge5e4]} 8. Nxe5 (8. Nbd2 e4
  3. Nxe4 Nxe4 10. Bxe4 Bxa1) (8. e4 Qe7 {[%csl Gd8][%cal Gf8d8,Ge7e5]} 9. Ba3 {
    [%csl Gf4][%cal Gf6h5,Gh5f4]} (9. Bb2 Rd8 10. Nbd2 Nh5 {[%csl Gf4][%cal Gh5f4]}
  4. Nc4 c5 {[%csl Gd4][%cal Gb8c6,Gc6d4]} 12. Ncxe5 {[%cal Gg7a1]} Nd7 13. Nxd7
    (13. Nc4 b5 14. Bxg7 bxc4 {[%cal Gc4d3,Gh5g7,Gg8g7]}) 13... Bxb2 14. Rb1 Bg7 {
    [%csl Gb6,Gb8,Gc5,Gd7,Ge5,Gf6,Gf8]}) 9... c5 10. Nbd2 Nh5 11. g3 Rd8 12. Nc4
    Nc6 13. Ne3 Nf6 14. Qe2 Nd4) 8... Ng4 9. Nxg4 (9. f4 Nxe5 10. fxe5 Bxe5 {
    [%cal Ge5a1,Gd8h4]} 11. c3 Qh4 12. h3 (12. g3 Bxg3 13. hxg3 Qxg3+ 14. Kh1 Rd8 {
    [%csl Gh5][%cal Gd8d5,Gd5h5]}) 12... Bxh3 13. gxh3 Qg3+ 14. Kh1 Qh2#) 9... Bxa1
    ) 6... a5 {Las negras quieren que las blancas hagan el avance e4 para romper
    en el centro con su peón de e y empiezan su ataque en el flanco de dama} 7. c3
    (7. c4 e5 8. dxe5 (8. b3 Re8 9. Qc2 Na6 10. a3 Qe7 11. Be2 Bf5) 8... dxe5 9.
    Nxe5 Ne8 {[%csl Gc4][%cal Gg7e5,Gd8d3] Su caballo está atrapado} 10. Ndf3 {
    [%cal Gd1d3]} Qe7) 7... a4 8. e4 (8. Re1 e5 9. dxe5 dxe5 10. Nxe5 Ng4 11. Nxg4
    Qxd3 12. e4 {[%cal Gg4e3]} a3 13. bxa3 Bxg4 14. Qxg4 Bxc3) 8... e5 9. dxe5 dxe5
  5. Nxe5 Ng4 {[%cal Gg4e5,Gg7e5,Gd8d3]} 11. Nxg4 Qxd3 {[%csl Gg4][%cal Gg7a1]
    Por el peón dejamos su caballo débil y desubicado y abrimos la diagonal del
    alfil} 12. Ne3 (12. a3 f5 13. exf5 gxf5 14. Ne3 f4 15. Nc2 (15. Nec4 b5 {
    El caballo queda atrapado}) 15... Be6 16. Nf3 (16. Nb4 Qf5 17. Nf3 c5 {[%csl
    Ga6,Gd5]} 18. Nc2 (18. Nd3 Rd8) 18... Bb3) 16... Qxd1 17. Rxd1 Bb3 {[%cal
    Gb3d1]} 18. Rd2 Nc6 19. Ncd4 Nxd4 20. Nxd4 Rfe8 {[%cal Ge8e1]} 21. Kf1 Bc4+ 22.
    Ne2 Rxe2 23. Rxe2 Re8) 12... Be6 {[%csl Ge4][%cal Gd2f3,Gd3e4]} 13. Nf3 (13.
    Qc2 Rd8 14. Qxd3 Rxd3 {[%csl Gc3][%cal Ga4a3,Gg7c3]} 15. a3 Na6 {[%csl Gd2,Ge4]
    [%cal Gc1d2,Gd2e4]} 16. Nf3 Nc5 17. e5 Nb3 18. Rb1 Ra5 {[%csl Ge5][%cal Ga5e5,
    Gg7e5]}) 13... Qxe4 *

but it's thrown this error:
Expected " ", """, "\r", "\t", or "\x0C" but "\n" found.

Pawn promotion handling

Pawn promotion(for example c8Q) doesn't work now.

peg$SyntaxError: Expected " ", "!!", "!", "!?", "#", "+", "=", "?!", "?", "??", "\n", "\r", "\t", or "\x0C" but "Q" found.

target pgn:

[Event "Altibox Norway Chess"]
[Site "chess24.com"]
[Date "2019.06.04"]
[Round "2"]
[White "Mamedyarov, Shakhriyar"]
[Black "Caruana, Fabiano"]
[Result "1-0"]
[Board "2"]
[WhiteElo "2774"]
[WhiteTitle "GM"]
[WhiteCountry "AZE"]
[WhiteFideId "13401319"]
[WhiteEloChange "6"]
[BlackElo "2819"]
[BlackTitle "GM"]
[BlackCountry "USA"]
[BlackFideId "2020009"]
[BlackEloChange "-6"]

1. d4 {[%clk 0:09:59]} Nf6 {[%clk 0:06:59]} 2. Bg5 {[%clk 0:09:58]} e6 {[%clk
0:06:57]} 3. e4 {[%clk 0:09:56]} h6 {[%clk 0:06:56]} 4. Bxf6 {[%clk 0:09:53]}
Qxf6 {[%clk 0:06:55]} 5. c3 {[%clk 0:09:48]} d5 {[%clk 0:06:53]} 6. Qe2 {[%clk
0:08:31]} dxe4 {[%clk 0:06:50]} 7. Qxe4 {[%clk 0:08:27]} Bd6 {[%clk 0:06:43]} 8.
Nf3 {[%clk 0:08:21]} O-O {[%clk 0:06:41]} 9. Bd3 {[%clk 0:08:15]} g6 {[%clk
0:06:39]} 10. Nbd2 {[%clk 0:08:10]} Nd7 {[%clk 0:06:30]} 11. Nc4 {[%clk 0:07:53]}
Qe7 {[%clk 0:06:25]} 12. O-O-O {[%clk 0:07:32]} Nf6 {[%clk 0:06:23]} 13. Qe2
{[%clk 0:07:30]} c5 {[%clk 0:06:07]} 14. Kb1 {[%clk 0:07:11]} cxd4 {[%clk
0:06:05]} 15. Nxd4 {[%clk 0:07:08]} Bc7 {[%clk 0:06:00]} 16. Rde1 {[%clk
0:06:24]} Kg7 {[%clk 0:05:59]} 17. g3 {[%clk 0:05:55]} Rd8 {[%clk 0:05:57]} 18.
f4 {[%clk 0:05:52]} Qc5 {[%clk 0:05:38]} 19. Ne5 {[%clk 0:05:46]} Bxe5 {[%clk
0:05:06]} 20. fxe5 {[%clk 0:05:44]} Nd5 {[%clk 0:05:05]} 21. Qf2 {[%clk 0:04:57]}
Qe7 {[%clk 0:05:02]} 22. h4 {[%clk 0:04:55]} Bd7 {[%clk 0:04:56]} 23. h5 {[%clk
0:04:41]} g5 {[%clk 0:04:55]} 24. Qe2 {[%clk 0:03:57]} Rac8 {[%clk 0:04:54]} 25.
Ka1 {[%clk 0:03:56]} a5 {[%clk 0:04:45]} 26. Rhf1 {[%clk 0:03:47]} a4 {[%clk
0:04:36]} 27. c4 {[%clk 0:03:38]} Nb4 {[%clk 0:04:32]} 28. Bb1 {[%clk 0:03:37]}
a3 {[%clk 0:04:19]} 29. bxa3 {[%clk 0:03:04]} Na6 {[%clk 0:04:16]} 30. Rf6 {[%clk
0:02:50]} Rh8 {[%clk 0:03:06]} 31. Ref1 {[%clk 0:02:49]} Be8 {[%clk 0:03:05]} 32.
Qf2 {[%clk 0:02:30]} Nc5 {[%clk 0:02:51]} 33. Qc2 {[%clk 0:02:23]} Rd8 {[%clk
0:02:44]} 34. Nb5 {[%clk 0:01:49]} Nd7 {[%clk 0:02:43]} 35. Qc3 {[%clk 0:01:41]}
Qc5 {[%clk 0:02:33]} 36. Nd6 {[%clk 0:01:23]} Nxf6 {[%clk 0:01:46]} 37. exf6+
{[%clk 0:01:17]} Kf8 {[%clk 0:01:46]} 38. Nxb7 {[%clk 0:01:15]} Qd4 {[%clk
0:01:45]} 39. Rf3 {[%clk 0:01:14]} Qxc3+ {[%clk 0:01:13]} 40. Rxc3 {[%clk
0:01:14]} Rd1 {[%clk 0:01:12]} 41. a4 {[%clk 0:00:46]} Bc6 {[%clk 0:01:08]} 42.
Nc5 {[%clk 0:00:45]} Rf1 {[%clk 0:00:59]} 43. Rb3 {[%clk 0:00:41]} Rxf6 {[%clk
0:00:54]} 44. Rb6 {[%clk 0:00:41]} Bxa4 {[%clk 0:00:44]} 45. Nxa4 {[%clk
0:00:38]} Kg7 {[%clk 0:00:43]} 46. c5 {[%clk 0:00:34]} Rf3 {[%clk 0:00:42]} 47.
Rb3 {[%clk 0:00:30]} Rf1 {[%clk 0:00:41]} 48. Kb2 {[%clk 0:00:28]} Rd8 {[%clk
0:00:40]} 49. Bc2 {[%clk 0:00:26]} Rf2 {[%clk 0:00:39]} 50. Rc3 {[%clk 0:00:26]}
Rb8+ {[%clk 0:00:33]} 51. Ka3 {[%clk 0:00:25]} Rc8 {[%clk 0:00:38]} 52. c6 {[%clk
0:00:25]} Rc7 {[%clk 0:00:37]} 53. Kb4 {[%clk 0:00:24]} f5 {[%clk 0:00:36]} 54.
Kb5 {[%clk 0:00:23]} f4 {[%clk 0:00:30]} 55. gxf4 {[%clk 0:00:23]} Rxf4 {[%clk
0:00:35]} 56. Kb6 {[%clk 0:00:22]} Rc8 {[%clk 0:00:34]} 57. Kb7 {[%clk 0:00:21]}
Rcf8 {[%clk 0:00:32]} 58. Nb6 {[%clk 0:00:14]} g4 {[%clk 0:00:28]} 59. c7 {[%clk
0:00:20]} R4f7 {[%clk 0:00:27]} 60. a4 {[%clk 0:00:21]} Kf6 {[%clk 0:00:27]} 61.
a5 {[%clk 0:00:23]} Rg8 {[%clk 0:00:29]} 62. a6 {[%clk 0:00:24]} g3 {[%clk
0:00:31]} 63. Be4 {[%clk 0:00:27]} Ke5 {[%clk 0:00:33]} 64. Bg2 {[%clk 0:00:29]}
Kd4 {[%clk 0:00:36]} 65. Rc2 {[%clk 0:00:30]} Kd3 {[%clk 0:00:38]} 66. Rc6 {[%clk
0:00:32]} Rf2 {[%clk 0:00:39]} 67. c8Q {[%clk 0:00:33]} Rxc8 {[%clk 0:00:41]} 68.
Rxc8 {[%clk 0:00:35]} Rxg2 {[%clk 0:00:43]} 69. a7 {[%clk 0:00:37]} Ra2 {[%clk
0:00:45]} 70. Rg8 {[%clk 0:00:39]} g2 {[%clk 0:00:45]} 71. a8Q {[%clk 0:00:38]}
1-0

Does not parse PGN with moves that have both rank and file

Consider the following game
https://www.chess.com/live/game/4610358993

Move 49 is Qg8f7because both rank and file are needed to disambiguate the move. So this is a valid pgn but while parsing we get the error:
Expected " ", "!!", "!", "!?", "#", "+", "?!", "?", "??", "\n", "\t", or "\x0C" but "f" found.

Full PGN is

[Event "Live Chess"]
[Site "Chess.com"]
[Date "2020.03.19"]
[Round "-"]
[White "eatmyrook8"]
[Black "TheZahlen"]
[Result "1/2-1/2"]
[ECO "D38"]
[ECOUrl "https://www.chess.com/openings/Queens-Gambit-Declined-Ragozin-Defense-5.Bg5"]
[CurrentPosition "k7/4QQQR/3Q4/8/4K3/2P5/P7/8 w - -"]
[Timezone "UTC"]
[UTCDate "2020.03.19"]
[UTCTime "01:08:13"]
[WhiteElo "1505"]
[BlackElo "1568"]
[TimeControl "60"]
[Termination "Game drawn by timeout vs insufficient material"]
[StartTime "01:08:13"]
[EndDate "2020.03.19"]
[EndTime "01:10:34"]
[Link "https://www.chess.com/live/game/4610358993"]

1. d4 {[%clk 0:00:59.9]} 1... d5 {[%clk 0:00:59.9]} 2. c4 {[%clk 0:00:59.8]} 2... e6 {[%clk 0:00:59.2]} 3. Nc3 {[%clk 0:00:59.7]} 3... Nf6 {[%clk 0:00:58.7]} 4. Nf3 {[%clk 0:00:59.6]} 4... Bb4 {[%clk 0:00:58.3]} 5. Bg5 {[%clk 0:00:59.5]} 5... O-O {[%clk 0:00:57.4]} 6. e3 {[%clk 0:00:59.4]} 6... h6 {[%clk 0:00:57]} 7. Bh4 {[%clk 0:00:59.3]} 7... g5 {[%clk 0:00:55.3]} 8. Nxg5 {[%clk 0:00:58.7]} 8... hxg5 {[%clk 0:00:55.2]} 9. Bxg5 {[%clk 0:00:58.3]} 9... Bxc3+ {[%clk 0:00:55.1]} 10. bxc3 {[%clk 0:00:57.5]} 10... b6 {[%clk 0:00:54.4]} 11. Qf3 {[%clk 0:00:56]} 11... Kg7 {[%clk 0:00:51]} 12. h4 {[%clk 0:00:55.2]} 12... Rh8 {[%clk 0:00:50.4]} 13. h5 {[%clk 0:00:54.6]} 13... Nbd7 {[%clk 0:00:48.2]} 14. Bd3 {[%clk 0:00:53.3]} 14... Kf8 {[%clk 0:00:47.3]} 15. cxd5 {[%clk 0:00:49.7]} 15... Ke7 {[%clk 0:00:46.6]} 16. dxe6 {[%clk 0:00:48.9]} 16... fxe6 {[%clk 0:00:45.1]} 17. e4 {[%clk 0:00:48.7]} 17... Kd6 {[%clk 0:00:44.4]} 18. e5+ {[%clk 0:00:48.2]} 18... Ke7 {[%clk 0:00:42.5]} 19. Bxf6+ {[%clk 0:00:47.7]} 19... Ke8 {[%clk 0:00:41.9]} 20. Bxd8 {[%clk 0:00:46.8]} 20... Kxd8 {[%clk 0:00:41.8]} 21. O-O-O {[%clk 0:00:42.9]} 21... Rf8 {[%clk 0:00:41.1]} 22. Qg3 {[%clk 0:00:40.6]} 22... Bb7 {[%clk 0:00:40.3]} 23. f3 {[%clk 0:00:38.7]} 23... Kc8 {[%clk 0:00:39.8]} 24. h6 {[%clk 0:00:38.2]} 24... Bc6 {[%clk 0:00:39.2]} 25. h7 {[%clk 0:00:37.8]} 25... Kb7 {[%clk 0:00:38.6]} 26. Qg7 {[%clk 0:00:35.5]} 26... Rh8 {[%clk 0:00:36.7]} 27. g4 {[%clk 0:00:32]} 27... Raf8 {[%clk 0:00:34.9]} 28. Rdf1 {[%clk 0:00:31.4]} 28... Bxf3 {[%clk 0:00:33.5]} 29. Rhg1 {[%clk 0:00:30.5]} 29... Nxe5 {[%clk 0:00:28.4]} 30. dxe5 {[%clk 0:00:29.5]} 30... Rd8 {[%clk 0:00:25.9]} 31. Rxf3 {[%clk 0:00:27.6]} 31... a6 {[%clk 0:00:23.6]} 32. g5 {[%clk 0:00:26.8]} 32... Ka8 {[%clk 0:00:23.5]} 33. g6 {[%clk 0:00:26.4]} 33... Rdf8 {[%clk 0:00:22.4]} 34. Rxf8+ {[%clk 0:00:24.4]} 34... Rxf8 {[%clk 0:00:21.7]} 35. Qxf8+ {[%clk 0:00:23.6]} 35... Kb7 {[%clk 0:00:21.6]} 36. h8=Q {[%clk 0:00:23.3]} 36... Kc6 {[%clk 0:00:21.5]} 37. g7 {[%clk 0:00:22.9]} 37... Kd7 {[%clk 0:00:19.1]} 38. g8=Q {[%clk 0:00:22.8]} 38... Kc6 {[%clk 0:00:18.4]} 39. Qxe6+ {[%clk 0:00:22]} 39... Kb7 {[%clk 0:00:18.3]} 40. Qeg8 {[%clk 0:00:18.6]} 40... Kc6 {[%clk 0:00:18.2]} 41. e6 {[%clk 0:00:18.1]} 41... Kb7 {[%clk 0:00:18.1]} 42. e7 {[%clk 0:00:18]} 42... Kc6 {[%clk 0:00:18]} 43. e8=Q+ {[%clk 0:00:17.9]} 43... Kb7 {[%clk 0:00:17.8]} 44. Be4+ {[%clk 0:00:16.5]} 44... Ka7 {[%clk 0:00:16.6]} 45. Bb7 {[%clk 0:00:16.4]} 45... Kxb7 {[%clk 0:00:15.4]} 46. Rg7 {[%clk 0:00:14.8]} 46... Ka7 {[%clk 0:00:14.6]} 47. Rh7 {[%clk 0:00:14.1]} 47... Kb7 {[%clk 0:00:13.8]} 48. Qhg7 {[%clk 0:00:14]} 48... Ka7 {[%clk 0:00:13.5]} 49. Qg8f7 {[%clk 0:00:13.9]} 49... Kb7 {[%clk 0:00:13.4]} 50. Qf8e7 {[%clk 0:00:13.8]} 50... Ka7 {[%clk 0:00:13.3]} 51. Q8d7 {[%clk 0:00:13.2]} 51... Kb7 {[%clk 0:00:13.2]} 52. Kd2 {[%clk 0:00:12.1]} 52... Ka7 {[%clk 0:00:13.1]} 53. Ke3 {[%clk 0:00:11.7]} 53... Kb7 {[%clk 0:00:13]} 54. Ke4 {[%clk 0:00:11.6]} 54... Ka7 {[%clk 0:00:12.9]} 55. Qxc7+ {[%clk 0:00:08.4]} 55... Ka8 {[%clk 0:00:11.9]} 56. Qc6+ {[%clk 0:00:04.5]} 56... Kb8 {[%clk 0:00:10.5]} 57. Qxb6+ {[%clk 0:00:04]} 57... Ka8 {[%clk 0:00:09.7]} 58. Qxa6+ {[%clk 0:00:03.5]} 58... Kb8 {[%clk 0:00:09.1]} 59. Qad6+ {[%clk 0:00:02.3]} 59... Ka8 {[%clk 0:00:08.5]} 1/2-1/2`

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.