@chess-fu/pgn-parser
Version:
Chess PGN parser for 8x8 chess games for import or export standards
191 lines • 6.99 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var pgnGame_1 = require("./pgnGame");
var pgnDataCursor_1 = require("./pgnDataCursor");
var PgnParser = (function () {
function PgnParser() {
}
PgnParser.prototype.parse = function (data, offset, limit) {
var games = [];
var cursor = new pgnDataCursor_1.PgnDataCursor(data, offset, limit);
var lastPos = -1;
while (!cursor.isEOF()) {
if (lastPos === cursor.position()) {
return cursor.throwError('No progress made');
}
lastPos = cursor.position();
var game = new pgnGame_1.default();
try {
this._parseHeaders(cursor, game.headers);
this._parseMoves(cursor, game.history);
}
finally {
if (game.headers.length || game.history.length) {
games.push(game);
}
}
}
return games;
};
PgnParser.prototype.parseHeaders = function (data, offset, limit) {
var cursor = new pgnDataCursor_1.PgnDataCursor(data, offset, limit);
var result = [];
this._parseHeaders(cursor, result);
return result;
};
PgnParser.prototype.parseMoves = function (data, offset, limit) {
var cursor = new pgnDataCursor_1.PgnDataCursor(data, offset, limit);
var result = [];
this._parseMoves(cursor, result);
return result;
};
PgnParser.prototype.parseMove = function (data, offset, limit) {
var cursor = new pgnDataCursor_1.PgnDataCursor(data, offset, limit);
var result = this._parseMove(cursor);
return result;
};
PgnParser.prototype._parseHeaders = function (cursor, headers) {
while (!cursor.isEOF()) {
var comments = [];
cursor.skipWhitespace(true, comments);
if (comments.length) {
headers.push({ comments: comments });
}
if (cursor.peekToken() === pgnDataCursor_1.PgnTokenType.TagPairStart) {
var tag = cursor.readTagPair();
if (tag) {
headers.push(tag);
}
}
else {
return;
}
}
};
PgnParser.prototype._parseMoves = function (cursor, history, depth) {
if (depth === void 0) { depth = 0; }
var lastPos = -1;
var comments = [];
while (!cursor.isEOF()) {
if (lastPos === cursor.position()) {
return cursor.throwError('No progress made');
}
lastPos = cursor.position();
cursor.skipWhitespace(false, comments);
var token = cursor.peekToken();
if (comments.length) {
history.push({ comments: comments });
comments = [];
}
if (token === pgnDataCursor_1.PgnTokenType.Newline) {
cursor.read();
if (cursor.peekToken() === pgnDataCursor_1.PgnTokenType.Newline) {
return;
}
else {
continue;
}
}
if (token === pgnDataCursor_1.PgnTokenType.SymbolChar || token === pgnDataCursor_1.PgnTokenType.Asterisks) {
var move = this._parseMove(cursor);
if (move) {
history.push(move);
}
if (move && move.result) {
break;
}
}
else if (token === pgnDataCursor_1.PgnTokenType.RavStart) {
cursor.read();
var ravHistory = [];
this._parseMoves(cursor, ravHistory, (depth || 0) + 1);
var prevMove = history.length > 0 ? history[history.length - 1] : undefined;
if (prevMove && !prevMove.rav) {
prevMove.rav = ravHistory;
}
else {
history.push({ rav: ravHistory });
}
}
else if (token === pgnDataCursor_1.PgnTokenType.RavEnd) {
if (depth <= 0) {
cursor.throwError('Unexpected close of RAV');
}
cursor.read();
break;
}
else {
if (token === pgnDataCursor_1.PgnTokenType.EndOfFile) {
return;
}
else {
return cursor.throwError("Expected move text, found \"" + cursor.peek() + "\"");
}
}
}
};
PgnParser.prototype._parseMove = function (cursor) {
var comments = [];
var move = {};
var lastPos = -1;
while (!cursor.isEOF()) {
if (lastPos === cursor.position()) {
return cursor.throwError('No progress made');
}
lastPos = cursor.position();
cursor.skipWhitespace(false, comments);
var letter = cursor.peek();
var token = cursor.peekToken();
var temp = void 0;
if (token === pgnDataCursor_1.PgnTokenType.Newline) {
break;
}
else if (letter >= '0' && letter <= '9') {
temp = letter > '1' ? undefined :
letter === '0' ? cursor.peekExact('0-1') :
(cursor.peekExact('1-0') || cursor.peekExact('1/2-1/2'));
if (temp) {
cursor.seek(temp.length);
move.result = temp;
break;
}
var moveNum = cursor.readNumber();
if (moveNum) {
move.number = moveNum;
cursor.readAll('.');
}
}
else if (token === pgnDataCursor_1.PgnTokenType.Asterisks) {
move.result = cursor.read();
break;
}
else if (token === pgnDataCursor_1.PgnTokenType.FullStop) {
if (cursor.peekExact('...')) {
cursor.readAll('.', 3);
move.raw = move.to = '...';
break;
}
}
else if (token === pgnDataCursor_1.PgnTokenType.SymbolChar) {
var data = cursor.readMoveText();
if (data) {
Object.assign(move, data);
break;
}
cursor.throwError('Expected move notation');
}
else {
return null;
}
}
cursor.skipWhitespace(false, comments);
if (comments.length) {
move.comments = comments;
}
return move;
};
return PgnParser;
}());
exports.PgnParser = PgnParser;
exports.default = PgnParser;
//# sourceMappingURL=pgnParser.js.map