diff options
| author | John Wiegley <johnw@newartisans.com> | 2002-03-01 06:17:46 +0000 |
|---|---|---|
| committer | John Wiegley <johnw@newartisans.com> | 2002-03-01 06:17:46 +0000 |
| commit | f115e4627966ae900aef55cb10f9e6207dbe7adf (patch) | |
| tree | 0718fd859aa8995889a1d7b7a5dc9007c39767df /chess-pgn.el | |
Initial revision
Diffstat (limited to 'chess-pgn.el')
| -rw-r--r-- | chess-pgn.el | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/chess-pgn.el b/chess-pgn.el new file mode 100644 index 0000000..56fab5a --- /dev/null +++ b/chess-pgn.el @@ -0,0 +1,111 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Convert a chess game to/from PGN notation +;; +;; $Revision$ + +(require 'chess-game) +(require 'chess-algebraic) + +(defun chess-pgn-read-plies (position &optional top-level) + (let ((plies (list t)) prevpos done) + (while (not (or done (eobp))) + (cond + ((looking-at "[1-9][0-9]*\\.[. ]*") + (goto-char (match-end 0))) + ((looking-at chess-algebraic-regexp) + (goto-char (match-end 0)) + (setq prevpos position) + (let ((ply (chess-algebraic-to-ply position (match-string 0)))) + (setq position (chess-ply-next-pos ply)) + (nconc plies (list ply)))) + ((and top-level + (looking-at "\\(\\*\\|1-0\\|0-1\\|1/2-1/2\\)")) + (goto-char (match-end 0)) + (chess-game-set-tag game "Result" (match-string-no-properties 0)) + (setq done t)) + ((looking-at "{") + (forward-char) + (let ((begin (point))) + (search-forward "}") + (forward-char) + (chess-pos-add-annotation prevpos (buffer-substring-no-properties + begin (- (point) 2))))) + ((looking-at "(") + (forward-char) + (skip-chars-forward " \t\n") + (chess-pos-add-annotation prevpos (chess-pgn-read-plies + (chess-pos-copy prevpos)))) + ((and (not top-level) + (looking-at ")")) + (forward-char) + (setq done t)) + (t (error "Error parsing PGN syntax"))) + (skip-chars-forward " \t\n")) + (cdr plies))) + +(defun chess-pgn-to-game () + "Convert PGN notation at point into a chess game." + (when (search-forward "[" nil t) + (let ((game (chess-game-create))) + (setcar game nil) + (backward-char) + (while (looking-at "^\\s-*\\[\\(\\S-+\\)\\s-+\\(\".+?\"\\)\\][ \t\n]+") + (chess-game-set-tag game (match-string-no-properties 1) + (read (match-string-no-properties 2))) + (goto-char (match-end 0))) + (let ((fen (chess-game-tag game "FEN"))) + (chess-game-set-plies + game (chess-pgn-read-plies + (if fen + (chess-fen-to-position fen) + (chess-pos-copy chess-starting-position)) t))) + game))) + +(defun chess-pgn-insert-annotations (ply) + (dolist (ann (chess-pos-annotations (chess-ply-pos ply))) + (if (stringp ann) + (insert (format " {%s}" ann)) + (assert (listp ann)) + (chess-pgn-insert-plies index ann)))) + +(defun chess-pgn-insert-plies (index plies &optional for-black indented) + "NYI: Still have to implement INDENTED argument." + (while plies + (unless for-black + (insert (format "%d. %s" index + (chess-ply-to-algebraic (car plies)))) + (chess-pgn-insert-annotations (car plies)) + (setq plies (cdr plies) index (1+ index))) + (when plies + (when for-black + (insert (format "%d. ..." index)) + (setq for-black nil)) + (insert (format " %s" (chess-ply-to-algebraic (car plies)))) + (chess-pgn-insert-annotations (car plies)) + (setq plies (cdr plies))) + (if plies + (insert ? )))) + +(defun chess-game-to-pgn (game &optional indented) + "Convert a chess GAME to PGN notation. +If INDENTED is non-nil, indent the move texts." + (let ((fen (chess-game-tag game "FEN")) + (first-pos (chess-ply-pos (chess-game-ply game 0)))) + (when (and fen (not (equal fen (chess-pos-to-fen first-pos)))) + (chess-game-del-tag game "FEN") + (setq fen nil)) + (if (and (not fen) + (not (equal chess-starting-position first-pos))) + (chess-game-set-tag game "FEN" (chess-pos-to-fen first-pos)))) + (dolist (tag (chess-game-tags game)) + (insert (format "[%s \"%s\"]\n" (car tag) (cdr tag)))) + (insert ?\n) + (let ((begin (point))) + (chess-pgn-insert-plies 1 (chess-game-plies game)) + (insert (or (chess-game-tag game "Result") "*") ?\n) + (fill-region begin (point)))) + +(provide 'chess-pgn) + +;;; chess-pgn.el ends here |
