/** Version: 0.6.4 **/ /** * Copyright 2008 Toomas Römer * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. **/ function Pgn(pgn) { // properties of the game eg players, ELOs etc this.props = new Object(); this.validProps = ['Event','Site','Date','Round', 'White','Black','Result','FEN', 'WhiteElo','BlackElo','TimeControl']; // the moves, one move contains the black and white move this.moves = new Array(); // the current move in the game this.currentMove = 0; // for outputting white and black moves separately this.skip = 0; // strip newlines this.pgnOrig = pgn; pgn = pgn.replace(/\n/g," "); // replace dollar signs //"!", "?", "!!", "!?", "?!", and "??" pgn = pgn.replace(/\ \$1[0-9]*/g, "!"); pgn = pgn.replace(/\ \$2[0-9]*/g, "?"); pgn = pgn.replace(/\ \$3[0-9]*/g, "!!"); pgn = pgn.replace(/\ \$4[0-9]*/g, "??"); pgn = pgn.replace(/\ \$5[0-9]*/g, "!?"); pgn = pgn.replace(/\ \$6[0-9]*/g, "?!"); // make double spaces to single spaces pgn = pgn.replace(/\s+/g,' '); this.pgn = pgn; this.pgnRaw = pgn; this.pgnStripped = stripIt(pgn); /* constructor */ // strip comments this.pgn = stripIt(pgn,true); // Match all properties var reprop = /\[([^\]]*)\]/gi; var matches = this.pgn.match(reprop); if (matches) { // extract information from each matched property for(var i = 0;i < matches.length; i++) { // lose the brackets tmpMatches = matches[i].substring(1, matches[i].length-1); // split by the first space var key = tmpMatches.substring(0, tmpMatches.indexOf(" ")); var value = tmpMatches.substring(tmpMatches.indexOf(" ")+1); if (value.charAt(0) == '"') value = value.substr(1); if (value.charAt(value.length-1) == '"') value = value.substr(0, value.length-1); this.props[key] = value; this.pgn = this.pgn.replace(matches[i], ""); } } // remove the properties this.pgn = this.pgn.replace(/\[[^\]]*\]/g,''); //trim this.pgn = this.pgn.replace(/^\s+|\s+$/g, ''); var gameOverre = new Array( /1\/2-1\/2/, /0-1/, /1-0/, /\*/ ); // the moves; var themoves = this.pgn.split(" "); var tmp = new Array(); tmp[1] = null; var tmpidx = 0; //make this 1 if FEN and black to move if (this.props["FEN"]) { var fen = this.props['FEN'].split(/\/| /g); if (fen[8] == 'b') { tmpidx = 1; this.skip = 1; } } if (themoves.length>0 && themoves[themoves.length-1] == "...") { themoves = themoves.slice(0, themoves.length-1); } var sizeOfTheMoves = themoves.length; if (themoves.length>0) { for (var i=0;i= '1' && c <= '9') { //move number c = themoves[i].charAt(themoves[i].length-1); if (c == '.') { //ends with . so nothing but a move continue; } var found = false; for (var j=0;j= '0' && c <= '9') { continue; } else { found = true; var idx = j; // 6.0-0 goes wrong as 0 is used for castling if (!(themoves[i].charAt(j) >= '0' && themoves[i].charAt(j)<='9')) { idx = j+1; } themoves[i] = themoves[i].substring(idx); //strip move number break; } } if (!found) { continue; } } tmp[tmpidx] = themoves[i]; if (tmpidx == 1) { //black's move or last move var move = new Move(tmp[0], tmp[1]); this.moves[this.moves.length] = move; tmpidx = 0; tmp = new Array(); tmp[1] = null; } else { tmpidx = 1; } } if (tmp[0] || tmp[1]) { var move = new Move(tmp[0], tmp[1]); this.moves[this.moves.length] = move; } }; function Move(white, black) { this.white = white; this.black = black; this.toString = function() { return this.white+" "+this.black; }; }; /* Strip game comments from a PGN string. If second parameter set false true then comments will be replaced by an underscore. */ function stripIt(val, strip) { var count = 0; var out = new Array(); /* At one point chesspastebin.com started getting cames with invalid PGNs, mostly in the form { comment comment ( something between starting brackets}. As you can see, the ( is not closed. isOpen and isCurlyO are just for that to take normal guesses in that kind of situations. */ var isOpen = false; var isCurlyO = false; var curlyOpenedFst = false; for (var i=0;i 0) { if (!strip) { out[out.length] = '_'; } } else { out[out.length] = c; } } } return out.join(""); };