Files
sharechess/src/game/PGNHelpers.ts
Maciej Caderek 7052c74171 WIP
2022-01-16 05:20:19 +01:00

80 lines
1.7 KiB
TypeScript

import { Chess } from "chess.js";
const PGN_KEYS_TO_SHORT = {
Event: "E",
Site: "S",
White: "W",
Black: "B",
Date: "D",
Result: "R",
FEN: "F",
};
const PGN_KEYS = Object.keys(PGN_KEYS_TO_SHORT);
const PGN_KEYS_TO_LONG = Object.fromEntries(
Object.entries(PGN_KEYS_TO_SHORT).map(([long, short]) => [short, long])
);
const cleanPGN = (pgn: string) => {
const game = new Chess();
game.load_pgn(pgn);
game.delete_comments();
const [_, moves] = game.pgn().split("\n\n");
const header = Object.entries(game.header())
.filter(([key]) => PGN_KEYS.includes(key))
.map(([key, val]) => `[${key} "${val}"]`)
.sort()
.join("\n");
return [header, moves].join("\n\n");
};
const compressPGN = (pgn: string) => {
const game = new Chess();
game.load_pgn(pgn);
const moves = game.history().join(" ");
const header = Object.entries(game.header())
.filter(([key]) => PGN_KEYS.includes(key))
.map(([key, val]) => `${key[0].toUpperCase()} ${val}`)
.sort()
.join("\n");
return btoa([header, moves].join("\n\n"));
};
const decompressPGN = (compressedPGN: string) => {
const [headerRaw, movesRaw] = atob(compressedPGN).split("\n\n");
let result;
const header = headerRaw
.split("\n")
.map((entry) => {
const [shortKey, ...data] = entry.split(" ");
const value = data.join(" ");
if (shortKey === "R") {
result = value;
}
return `[${PGN_KEYS_TO_LONG[shortKey]} "${value}"]`;
})
.join("\n");
const moves =
movesRaw
.split(" ")
.map((move, index) =>
index % 2 === 0 ? `${index / 2 + 1}. ${move}` : move
)
.join(" ") + ` ${result}`;
return [header, moves].join("\n\n");
};
export { cleanPGN, compressPGN, decompressPGN };