diff options
| -rw-r--r-- | lisp/play/decipher.el | 116 |
1 files changed, 37 insertions, 79 deletions
diff --git a/lisp/play/decipher.el b/lisp/play/decipher.el index f256a1494b4..f90e1f4a327 100644 --- a/lisp/play/decipher.el +++ b/lisp/play/decipher.el | |||
| @@ -38,11 +38,6 @@ | |||
| 38 | 38 | ||
| 39 | ;;; Commentary: | 39 | ;;; Commentary: |
| 40 | ;; | 40 | ;; |
| 41 | ;; If you want Decipher to use its Font Lock mode, you should use | ||
| 42 | ;; (setq decipher-use-font-lock t) | ||
| 43 | ;; See the variable `decipher-use-font-lock' if you want to customize | ||
| 44 | ;; the faces used. | ||
| 45 | ;; | ||
| 46 | ;; This package is designed to help you crack simple substitution | 41 | ;; This package is designed to help you crack simple substitution |
| 47 | ;; ciphers where one letter stands for another. It works for ciphers | 42 | ;; ciphers where one letter stands for another. It works for ciphers |
| 48 | ;; with or without word divisions. (You must set the variable | 43 | ;; with or without word divisions. (You must set the variable |
| @@ -75,6 +70,12 @@ | |||
| 75 | ;; | 70 | ;; |
| 76 | ;; The buffer is made read-only so it can't be modified by normal | 71 | ;; The buffer is made read-only so it can't be modified by normal |
| 77 | ;; Emacs commands. | 72 | ;; Emacs commands. |
| 73 | ;; | ||
| 74 | ;; Decipher supports Font Lock mode. To use it, you can also add | ||
| 75 | ;; (add-hook 'decipher-mode-hook 'turn-on-font-lock) | ||
| 76 | ;; See the variable `decipher-font-lock-keywords' if you want to customize | ||
| 77 | ;; the faces used. I'd like to thank Simon Marshall for his help in making | ||
| 78 | ;; Decipher work well with Font Lock. | ||
| 78 | 79 | ||
| 79 | ;;; Things To Do: | 80 | ;;; Things To Do: |
| 80 | ;; | 81 | ;; |
| @@ -91,28 +92,6 @@ | |||
| 91 | (eval-when-compile | 92 | (eval-when-compile |
| 92 | (require 'cl)) | 93 | (require 'cl)) |
| 93 | 94 | ||
| 94 | (eval-when-compile | ||
| 95 | (require 'font-lock)) | ||
| 96 | |||
| 97 | (defvar decipher-use-font-lock (featurep 'font-lock) | ||
| 98 | "Non-nil means Decipher should use its Font Lock mode. | ||
| 99 | Do *not* turn on font-lock-mode yourself, it's too slow when used with | ||
| 100 | Decipher. Decipher contains special code to keep the buffer fontified | ||
| 101 | without using Font Lock mode directly. | ||
| 102 | |||
| 103 | You should set this in your `.emacs' file or before loading Decipher; | ||
| 104 | use `\\[decipher-toggle-font-lock]' after Decipher is loaded. | ||
| 105 | |||
| 106 | Ciphertext uses `font-lock-keyword-face', plaintext uses | ||
| 107 | `font-lock-string-face', comments use `font-lock-comment-face', and | ||
| 108 | checkpoints use `font-lock-reference-face'. | ||
| 109 | |||
| 110 | For example, to display ciphertext in the `bold' face, use | ||
| 111 | (add-hook 'decipher-mode-hook | ||
| 112 | (lambda () (set (make-local-variable 'font-lock-keyword-face) | ||
| 113 | 'bold))) | ||
| 114 | in your `.emacs' file.") | ||
| 115 | |||
| 116 | (defvar decipher-force-uppercase t | 95 | (defvar decipher-force-uppercase t |
| 117 | "*Non-nil means to convert ciphertext to uppercase. | 96 | "*Non-nil means to convert ciphertext to uppercase. |
| 118 | Nil means the case of the ciphertext is preserved. | 97 | Nil means the case of the ciphertext is preserved. |
| @@ -134,18 +113,28 @@ the tail of the list.") | |||
| 134 | ;;-------------------------------------------------------------------- | 113 | ;;-------------------------------------------------------------------- |
| 135 | 114 | ||
| 136 | (defvar decipher-font-lock-keywords | 115 | (defvar decipher-font-lock-keywords |
| 137 | '(("^:.*\n" . font-lock-keyword-face) | 116 | '(("^:.*" . font-lock-keyword-face) |
| 138 | ("^>.*\n" . font-lock-string-face) | 117 | ("^>.*" . font-lock-string-face) |
| 139 | ("^%!.*\n" . font-lock-reference-face) | 118 | ("^%!.*" . font-lock-reference-face) |
| 140 | ("^%.*\n" . font-lock-comment-face) | 119 | ("^%.*" . font-lock-comment-face) |
| 141 | ("\\`(\\([a-z]+\\) +\\([A-Z]+\\).+ | 120 | ("\\`(\\([a-z]+\\) +\\([A-Z]+\\)" |
| 142 | )\\([A-Z ]*\\)\\([a-z ]*\\)" | ||
| 143 | (1 font-lock-string-face) | 121 | (1 font-lock-string-face) |
| 144 | (2 font-lock-keyword-face) | 122 | (2 font-lock-keyword-face)) |
| 145 | (3 font-lock-keyword-face) | 123 | ("^)\\([A-Z ]+\\)\\([a-z ]+\\)" |
| 146 | (4 font-lock-string-face))) | 124 | (1 font-lock-keyword-face) |
| 125 | (2 font-lock-string-face))) | ||
| 147 | "Expressions to fontify in Decipher mode. | 126 | "Expressions to fontify in Decipher mode. |
| 148 | See the variable `decipher-use-font-lock'.") | 127 | ! Ciphertext uses `font-lock-keyword-face', plaintext uses |
| 128 | `font-lock-string-face', comments use `font-lock-comment-face', and | ||
| 129 | checkpoints use `font-lock-reference-face'. You can customize the | ||
| 130 | display by changing these variables. For best results, I recommend | ||
| 131 | that all faces use the same background color. | ||
| 132 | ! For example, to display ciphertext in the `bold' face, use | ||
| 133 | (add-hook 'decipher-mode-hook | ||
| 134 | (lambda () (set (make-local-variable 'font-lock-keyword-face) | ||
| 135 | 'bold))) | ||
| 136 | in your `.emacs' file.") | ||
| 137 | |||
| 149 | (defvar decipher-mode-map nil | 138 | (defvar decipher-mode-map nil |
| 150 | "Keymap for Decipher mode.") | 139 | "Keymap for Decipher mode.") |
| 151 | (if (not decipher-mode-map) | 140 | (if (not decipher-mode-map) |
| @@ -307,14 +296,7 @@ The most useful commands are: | |||
| 307 | (lambda () (setq buffer-read-only nil | 296 | (lambda () (setq buffer-read-only nil |
| 308 | buffer-undo-list nil)) | 297 | buffer-undo-list nil)) |
| 309 | nil t) | 298 | nil t) |
| 310 | ;; If someone turns on Font Lock, turn it off and use our code instead: | ||
| 311 | (make-local-hook 'font-lock-mode-hook) | ||
| 312 | (add-hook 'font-lock-mode-hook 'decipher-turn-on-font-lock t t) | ||
| 313 | (run-hooks 'decipher-mode-hook) | 299 | (run-hooks 'decipher-mode-hook) |
| 314 | (and decipher-use-font-lock | ||
| 315 | ;; Fontify buffer after calling the mode hooks, | ||
| 316 | ;; in case they change the font-lock variables: | ||
| 317 | (font-lock-fontify-buffer)) | ||
| 318 | (setq buffer-read-only t)) | 300 | (setq buffer-read-only t)) |
| 319 | (put 'decipher-mode 'mode-class 'special) | 301 | (put 'decipher-mode 'mode-class 'special) |
| 320 | 302 | ||
| @@ -475,21 +457,18 @@ The most useful commands are: | |||
| 475 | (decipher-set-map (cdr mapping) ?\ t)) | 457 | (decipher-set-map (cdr mapping) ?\ t)) |
| 476 | (setcdr mapping cipher-char) | 458 | (setcdr mapping cipher-char) |
| 477 | (search-forward-regexp (concat "^([a-z]*" plain-string)) | 459 | (search-forward-regexp (concat "^([a-z]*" plain-string)) |
| 478 | (and decipher-use-font-lock | 460 | (decipher-insert cipher-char) |
| 479 | (put-text-property 0 1 'face font-lock-keyword-face | ||
| 480 | cipher-string)) | ||
| 481 | (decipher-insert cipher-string) | ||
| 482 | (beginning-of-line))) | 461 | (beginning-of-line))) |
| 483 | (search-forward-regexp (concat "^([a-z]+ [A-Z]*" cipher-string)) | 462 | (search-forward-regexp (concat "^([a-z]+ [A-Z]*" cipher-string)) |
| 484 | (and decipher-use-font-lock | 463 | (decipher-insert plain-char) |
| 485 | (put-text-property 0 1 'face font-lock-string-face plain-string)) | ||
| 486 | (decipher-insert plain-string) | ||
| 487 | (setq case-fold-search t ;Case is not significant | 464 | (setq case-fold-search t ;Case is not significant |
| 488 | cipher-string (downcase cipher-string)) | 465 | cipher-string (downcase cipher-string)) |
| 489 | (while (search-forward-regexp "^:" nil t) | 466 | (let ((font-lock-fontify-region-function 'ignore)) |
| 490 | (setq bound (save-excursion (end-of-line) (point))) | 467 | ;; insert-and-inherit will pick the right face automatically |
| 491 | (while (search-forward cipher-string bound 'end) | 468 | (while (search-forward-regexp "^:" nil t) |
| 492 | (decipher-insert plain-char)))))) | 469 | (setq bound (save-excursion (end-of-line) (point))) |
| 470 | (while (search-forward cipher-string bound 'end) | ||
| 471 | (decipher-insert plain-char))))))) | ||
| 493 | 472 | ||
| 494 | (defun decipher-insert (char) | 473 | (defun decipher-insert (char) |
| 495 | ;; Insert CHAR in the row below point. It replaces any existing | 474 | ;; Insert CHAR in the row below point. It replaces any existing |
| @@ -544,9 +523,7 @@ Type `\\[decipher-restore-checkpoint]' to restore a checkpoint." | |||
| 544 | (insert "\n%" (make-string 69 ?\-) | 523 | (insert "\n%" (make-string 69 ?\-) |
| 545 | "\n% Checkpoints:\n% abcdefghijklmnopqrstuvwxyz\n")) | 524 | "\n% Checkpoints:\n% abcdefghijklmnopqrstuvwxyz\n")) |
| 546 | (beginning-of-line) | 525 | (beginning-of-line) |
| 547 | (insert "%!" alphabet "! " desc ?\n)) | 526 | (insert "%!" alphabet "! " desc ?\n))) |
| 548 | (and decipher-use-font-lock | ||
| 549 | (font-lock-fontify-buffer))) | ||
| 550 | 527 | ||
| 551 | (defun decipher-restore-checkpoint () | 528 | (defun decipher-restore-checkpoint () |
| 552 | "Restore the cipher alphabet from a checkpoint. | 529 | "Restore the cipher alphabet from a checkpoint. |
| @@ -621,12 +598,10 @@ You should use this if you edit the ciphertext." | |||
| 621 | (decipher-read-alphabet) | 598 | (decipher-read-alphabet) |
| 622 | (setq alphabet decipher-alphabet) | 599 | (setq alphabet decipher-alphabet) |
| 623 | (goto-char (point-min)) | 600 | (goto-char (point-min)) |
| 624 | (and (re-search-forward "^).+$" nil t) | 601 | (and (re-search-forward "^).+" nil t) |
| 625 | (replace-match ")" nil nil)) | 602 | (replace-match ")" nil nil)) |
| 626 | (while (re-search-forward "^>.+$" nil t) | 603 | (while (re-search-forward "^>.+" nil t) |
| 627 | (replace-match ">" nil nil)) | 604 | (replace-match ">" nil nil)) |
| 628 | (and decipher-use-font-lock | ||
| 629 | (font-lock-fontify-buffer)) | ||
| 630 | (decipher-read-alphabet) | 605 | (decipher-read-alphabet) |
| 631 | (while (setq mapping (pop alphabet)) | 606 | (while (setq mapping (pop alphabet)) |
| 632 | (or (equal ?\ (cdr mapping)) | 607 | (or (equal ?\ (cdr mapping)) |
| @@ -635,19 +610,6 @@ You should use this if you edit the ciphertext." | |||
| 635 | decipher-undo-list-size 0) | 610 | decipher-undo-list-size 0) |
| 636 | (message "Reprocessing buffer...done")) | 611 | (message "Reprocessing buffer...done")) |
| 637 | 612 | ||
| 638 | (defun decipher-toggle-font-lock (&optional arg) | ||
| 639 | "Toggle Decipher's Font Lock mode in the current buffer. | ||
| 640 | With arg, turn Font Lock mode on if and only if arg is positive. | ||
| 641 | See the variable `decipher-use-font-lock' for more information." | ||
| 642 | (interactive "P") | ||
| 643 | (or (eq major-mode 'decipher-mode) | ||
| 644 | (error "This buffer is not in Decipher mode")) | ||
| 645 | (let ((on-p (if arg (> (prefix-numeric-value arg) 0) | ||
| 646 | (not decipher-use-font-lock)))) | ||
| 647 | (if on-p (font-lock-fontify-buffer) | ||
| 648 | (font-lock-unfontify-region (point-min) (point-max))) | ||
| 649 | (make-local-variable 'decipher-use-font-lock) | ||
| 650 | (setq decipher-use-font-lock on-p))) | ||
| 651 | ;;-------------------------------------------------------------------- | 613 | ;;-------------------------------------------------------------------- |
| 652 | ;; Miscellaneous functions: | 614 | ;; Miscellaneous functions: |
| 653 | ;;-------------------------------------------------------------------- | 615 | ;;-------------------------------------------------------------------- |
| @@ -664,10 +626,6 @@ See the variable `decipher-use-font-lock' for more information." | |||
| 664 | (backward-char) | 626 | (backward-char) |
| 665 | (push (cons plain-char (following-char)) decipher-alphabet) | 627 | (push (cons plain-char (following-char)) decipher-alphabet) |
| 666 | (decf plain-char))))) | 628 | (decf plain-char))))) |
| 667 | (defun decipher-turn-on-font-lock () | ||
| 668 | "Turn on Decipher's Font Lock code and turn off normal Font Lock mode." | ||
| 669 | (font-lock-mode 0) | ||
| 670 | (decipher-toggle-font-lock 1)) | ||
| 671 | 629 | ||
| 672 | ;;;=================================================================== | 630 | ;;;=================================================================== |
| 673 | ;;; Analyzing ciphertext: | 631 | ;;; Analyzing ciphertext: |