@owenrees/pgn2tex
v0.1.6
Published
PGN to TeX converter
Downloads
21
Readme
PGN to TeX
This is the project that powers the PGN to TeX string conversion for chess-pdf-api. It can be found on NPM as owenrees/pgn2tex.
Install
Install the NPM package as a dependency:
npm install owenrees/pgn2tex --save
Import it into your project:
import Pgn2Tex from '@owenrees/pgn2tex';
Reference
The Pgn2Tex class exposes a single method: toTex()
. This method will convert the arguments provided to the constructor into a TeX string.
Generate TeX String
The Pgn2Tex class is used to generate a TeX string from a PGN file. It takes two arguments:
| Parameter | Type | Description |
|----------------|-----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| pgn
| string
| Required. A valid PGN of a chess game. |
| diagrams
| array
| An array of objects, containing: - ply
(integer): The move ply for a chess diagram. - fen
(string): A FEN of the board position, for rendering the correct diagram at the ply specified. |
| diagramClock
| boolean
| Display move times above and below the chessboard. Default is false
. |
The diagrams
parameter is optional, and if not provided, the TeX string will not contain any diagrams.
Example Usage
const gameTex = new Pgn2Tex(pgn, diagrams).toTex()
Example pgn
and diagram
arguments are defined as follows:
const pgn = `[Event "URS-chJ"]
[Site "Kherson"]
[Date "1991.??.??"]
[Round "?"]
[White "Ibragimov, Ildar"]
[Black "Kramnik, Vladimir"]
[Result "0-1"]
[ECO "A88"]
[WhiteElo "2455"]
[BlackElo "2480"]
[PlyCount "110"]
[EventDate "1991.??.??"]
[Source "ChessBase"]
1. d4 {A88: Dutch Defence: Leningrad System: 5 Nf3 0-0 6 0-0 d6 7 Nc3 c6} d6 2. c4 f5 3. Nf3 Nf6 4. g3 g6 5. Bg2 Bg7 6. O-O O-O 7. Nc3 Qe8 8. b3 Na6 9. Ba3 c6 10. Qd3 Rb8 11. e4 fxe4 12. Nxe4 Bf5 13. Nxf6+ Bxf6 14. Qd2 Nc7 15. Rae1 Qd7 16. h4 b5 17. Re3 bxc4 18. bxc4 Bh3 19. Rfe1 Bxg2 {last book move} 20. Kxg2 Qf5 21. Re4 Rbe8 22. Rf4 Qc8 23. Qa5 d5 24. cxd5 Nxd5 25. Rfe4 {e7 seems the pivot of the position} Qf5 26. Qd2 ( 26. Qxa7$4 {taking the pawn is naive} Qxf3+ {Annihilates a defender: f3} 27. Kxf3 Bxd4+ 28. Kg4 Bxa7 29. Bxe7 Rxf2$19 ( 29... Rxe7 30. Rxe7 Bxf2 31. a4$19 ) ( 29... Nxe7$6 30. Rxe7 Rxe7 31. Rxe7 Bxf2 32. a4$19 ) ) Bg7 27. Nh2 Rf7 28. Bc5 {The white bishop on an outpost} Qd7 29. a4 Nf6 30. Re5 Nd5 31. R5e4 ( 31. R5e2 Rb8$14 ) Nf6$11 32. Re5 Kh8 ( 32... Nd5 33. R5e2$14 ) 33. Kg1 Nd5 {A valuable piece} 34. R5e2 a6 35. Qd3 Qh3 ( 35... Ra8$14 ) 36. Nf3 ( 36. Qxa6 Ref8 37. Qa5$14 ( 37. Qxc6 Rxf2 38. Rxf2 Qxg3+ 39. Kh1 Rxf2 ( 39... Qxf2$6 40. Rf1 Qa2 41. Rxf8+ Bxf8 42. Kg1$11 ) 40. Qa8+ Bf8 41. Qxf8+ Rxf8 42. Re2 Rf2 43. Rxf2 Qxf2 44. Ng4 Qf1+ 45. Kh2 Nf4 46. Ne3 Qf2+ 47. Kh1 Qxh4+ 48. Kg1 Qg3+ 49. Kf1 Qxe3 50. Bb6 Qe2+ 51. Kg1 Qg2# ) ( 37. Bxe7$4 {White will choke on that pawn} Rxf2 ( 37... Nxe7$6 38. Rd1$19 ) 38. Rxf2 Qxg3+ 39. Kh1 Rxf2 ( 39... Qxf2 40. Re2 Qxd4 41. Bxf8 Qd1+ 42. Kg2 Nf4+ 43. Kf3$11 ) 40. Qc8+ Bf8 41. Bf6+ Nxf6 42. Qxf8+ Ng8 43. Qxf2 Qxf2$19 ) ) Nf4$15 {Do you see the mate threat?} 37. gxf4 Rxf4 {The mate threat is Rg4} 38. Ne5 ( 38. Re4$5 {is worthy of consideration} Qg4+ 39. Kf1 Rxf3 40. Rxg4 Rxd3 41. Re6$15 ) Rg4+$1$17 {keeping the advantage} 39. Nxg4 {Theme: Deflection from d3} Qxd3 40. Re4 Qf3 41. Nh2 Qf5 42. Bxe7 ( 42. Kg2 Rf8 43. f3 Bf6$19 ) Kg8 43. f3 ( 43. R1e3 Qd5$19 ) Qh3$19 44. R1e2 ( 44. Kh1$19 ) Qg3+ 45. Rg2 Bxd4+$1 {a devastating blow} 46. Kh1 ( 46. Rxd4 {A deflection} Qe1+ {Theme: Double Attack} ) Qh3 47. Rgg4 ( 47. a5 Bc3$19 ) c5 48. h5 ( 48. Re1 {does not improve anything} Bf6 49. Rge4 Bxe7 50. Rxe7 Rxe7 51. Rxe7 Qxh4$19 ) Rb8 49. Re1 Be5 50. Rh4 Qf5 51. hxg6 hxg6 52. Re2 ( 52. Bxc5 {doesn't change the outcome of the game} Bg3 53. Rb4 Rc8$19 ( 53... Bxe1$6 {is clearly worse} 54. Rxb8+ Kh7 55. Rb7+ Kh8 56. Rb8+ Kg7 57. Rb7+ Kf6 58. Ng4+ Kg5 59. Be3+ Kh4 60. Kg2 Qc2+ 61. Nf2$15 ) ( 53... Qxc5$6 {is much worse} 54. Rxb8+ Bxb8 55. Re8+ Kf7 56. Rxb8$19 ) ) Rb1+ ( 52... Qb1+$5 {keeps an even firmer grip} 53. Kg2 Rb2 54. Rxb2 Qxb2+ 55. Kg1$19 ) 53. Kg2 Bd4 54. Ng4 ( 54. Rxd4 {no good, but what else?} cxd4 55. Ng4$19 ) Rg1+ 55. Kh2 ( 55. Kh3 {doesn't do any good} Qxf3+ 56. Kh2 Rh1# ) Qf4+ ( 55... Qf4+ 56. Kh3 Qg3# ) 0-1`;
const diagrams = [
{
ply: 6,
fen: 'rnbqkb1r/ppp1p1pp/3p1n2/5p2/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq - 2 4',
},
{
ply: 13,
fen: 'rnbq1rk1/ppp1p1bp/3p1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - - 5 7',
},
];
On success, a TeX string is returned. Eg.
\documentclass{article}
\usepackage{xskak}
\usepackage{multicol}
\usepackage[a4paper]{geometry}
\usepackage{parskip}
\geometry{left=1.25cm,right=1.25cm,top=1.5cm,bottom=1.5cm,columnsep=1.2cm}
\setlength{\parindent}{0pt}
\title{Ibragimov, Ildar (2455) - Kramnik, Vladimir (2480)}
\date{1991.??.??, Kherson}
\author{URS-chJ}
\begin{document}
\begin{multicols}{2}
\maketitle
\newchessgame
\textbf{1.} \textbf{d4} \newline A88: Dutch Defence: Leningrad System: 5 Nf3 0-0 6 0-0 d6 7 Nc3 c6 \par \textbf{1...}\textbf{d6} \textbf{2.}\textbf{c4} \textbf{f5} \textbf{3.}\textbf{Nf3} \textbf{Nf6} \par\chessboard[setfen=rnbqkb1r/ppp1p1pp/3p1n2/5p2/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq - 2 4]\par \textbf{4.}\textbf{g3} \textbf{g6} \textbf{5.}\textbf{Bg2} \textbf{Bg7} \textbf{6.}\textbf{O-O} \textbf{O-O} \textbf{7.}\textbf{Nc3} \par\chessboard[setfen=rnbq1rk1/ppp1p1bp/3p1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - - 5 7]\par \textbf{7...}\textbf{Qe8} \textbf{8.}\textbf{b3} \textbf{Na6} \textbf{9.}\textbf{Ba3} \textbf{c6} \textbf{10.}\textbf{Qd3} \textbf{Rb8} \textbf{11.}\textbf{e4} \textbf{fxe4} \textbf{12.}\textbf{Nxe4} \textbf{Bf5} \textbf{13.}\textbf{Nxf6+} \textbf{Bxf6} \textbf{14.}\textbf{Qd2} \textbf{Nc7} \textbf{15.}\textbf{Rae1} \textbf{Qd7} \textbf{16.}\textbf{h4} \textbf{b5} \textbf{17.}\textbf{Re3} \textbf{bxc4} \textbf{18.}\textbf{bxc4} \textbf{Bh3} \textbf{19.}\textbf{Rfe1} \textbf{Bxg2} \newline last book move \par \textbf{20.}\textbf{Kxg2} \textbf{Qf5} \textbf{21.}\textbf{Re4} \textbf{Rbe8} \textbf{22.}\textbf{Rf4} \textbf{Qc8} \textbf{23.}\textbf{Qa5} \textbf{d5} \textbf{24.}\textbf{cxd5} \textbf{Nxd5} \textbf{25.}\textbf{Rfe4} \newline e7 seems the pivot of the position \par \textbf{25...}\textbf{Qf5} \textbf{26.}\textbf{Qd2} (26.Qxa7 Qxf3+ 27.Kxf3 Bxd4+ 28.Kg4 Bxa7 29.Bxe7 Rxf2 (...Rxe7 30.Rxe7 Bxf2 31.a4) (...Nxe7 30.Rxe7 Rxe7 31.Rxe7 Bxf2 32.a4)) \textbf{26...}\textbf{Bg7} \textbf{27.}\textbf{Nh2} \textbf{Rf7} \textbf{28.}\textbf{Bc5} \newline The white bishop on an outpost \par \textbf{28...}\textbf{Qd7} \textbf{29.}\textbf{a4} \textbf{Nf6} \textbf{30.}\textbf{Re5} \textbf{Nd5} \textbf{31.}\textbf{R5e4} (31.R5e2 Rb8) \textbf{31...}\textbf{Nf6} \textbf{32.}\textbf{Re5} \textbf{Kh8} (...Nd5 33.R5e2) \textbf{33.}\textbf{Kg1} \textbf{Nd5} \newline A valuable piece \par \textbf{34.}\textbf{R5e2} \textbf{a6} \textbf{35.}\textbf{Qd3} \textbf{Qh3} (...Ra8) \textbf{36.}\textbf{Nf3} (36.Qxa6 Ref8 37.Qa5 (37.Qxc6 Rxf2 38.Rxf2 Qxg3+ 39.Kh1 Rxf2 (...Qxf2 40.Rf1 Qa2 41.Rxf8+ Bxf8 42.Kg1)40.Qa8+ Bf8 41.Qxf8+ Rxf8 42.Re2 Rf2 43.Rxf2 Qxf2 44.Ng4 Qf1+ 45.Kh2 Nf4 46.Ne3 Qf2+ 47.Kh1 Qxh4+ 48.Kg1 Qg3+ 49.Kf1 Qxe3 50.Bb6 Qe2+ 51.Kg1 Qg2\#) (37.Bxe7 Rxf2 (...Nxe7 38.Rd1)38.Rxf2 Qxg3+ 39.Kh1 Rxf2 (...Qxf2 40.Re2 Qxd4 41.Bxf8 Qd1+ 42.Kg2 Nf4+ 43.Kf3)40.Qc8+ Bf8 41.Bf6+ Nxf6 42.Qxf8+ Ng8 43.Qxf2 Qxf2)) \textbf{36...}\textbf{Nf4} \newline Do you see the mate threat? \par \textbf{37.}\textbf{gxf4} \textbf{Rxf4} \newline The mate threat is Rg4 \par \textbf{38.}\textbf{Ne5} (38.Re4 Qg4+ 39.Kf1 Rxf3 40.Rxg4 Rxd3 41.Re6) \textbf{38...}\textbf{Rg4+} \newline keeping the advantage \par \textbf{39.}\textbf{Nxg4} \newline Theme: Deflection from d3 \par \textbf{39...}\textbf{Qxd3} \textbf{40.}\textbf{Re4} \textbf{Qf3} \textbf{41.}\textbf{Nh2} \textbf{Qf5} \textbf{42.}\textbf{Bxe7} (42.Kg2 Rf8 43.f3 Bf6) \textbf{42...}\textbf{Kg8} \textbf{43.}\textbf{f3} (43.R1e3 Qd5) \textbf{43...}\textbf{Qh3} \textbf{44.}\textbf{R1e2} (44.Kh1) \textbf{44...}\textbf{Qg3+} \textbf{45.}\textbf{Rg2} \textbf{Bxd4+} \newline a devastating blow \par \textbf{46.}\textbf{Kh1} (46.Rxd4 Qe1+) \textbf{46...}\textbf{Qh3} \textbf{47.}\textbf{Rgg4} (47.a5 Bc3) \textbf{47...}\textbf{c5} \textbf{48.}\textbf{h5} (48.Re1 Bf6 49.Rge4 Bxe7 50.Rxe7 Rxe7 51.Rxe7 Qxh4) \textbf{48...}\textbf{Rb8} \textbf{49.}\textbf{Re1} \textbf{Be5} \textbf{50.}\textbf{Rh4} \textbf{Qf5} \textbf{51.}\textbf{hxg6} \textbf{hxg6} \textbf{52.}\textbf{Re2} (52.Bxc5 Bg3 53.Rb4 Rc8 (...Bxe1 54.Rxb8+ Kh7 55.Rb7+ Kh8 56.Rb8+ Kg7 57.Rb7+ Kf6 58.Ng4+ Kg5 59.Be3+ Kh4 60.Kg2 Qc2+ 61.Nf2) (...Qxc5 54.Rxb8+ Bxb8 55.Re8+ Kf7 56.Rxb8)) \textbf{52...}\textbf{Rb1+} (...Qb1+ 53.Kg2 Rb2 54.Rxb2 Qxb2+ 55.Kg1) \textbf{53.}\textbf{Kg2} \textbf{Bd4} \textbf{54.}\textbf{Ng4} (54.Rxd4 cxd4 55.Ng4) \textbf{54...}\textbf{Rg1+} \textbf{55.}\textbf{Kh2} (55.Kh3 Qxf3+ 56.Kh2 Rh1\#) \textbf{55...}\textbf{Qf4+} (...Qf4+ 56.Kh3 Qg3\#) \textbf{0-1}
\end{multicols}
\end{document}
If you are using a custom TexLive server to generate a PDF from a string, you must ensure that the following packages are installed:
- parskip
- pgf
- chessboard
- etoolbox
- ifmtarg
- xifthen
- skaknew
- lambda-lists
- xkeyval
- chessfss
- skak
- xskak
A custom Docker image of a TexLive with these packages installed is available here.