1 ;;; morse.el --- convert to Morse code and back -*- coding: iso-8859-1 -*-
3 ;; Copyright (C) 1995, 2002, 2005, 2006 Free Software Foundation, Inc.
5 ;; Author: Rick Farnbach <rick_farnbach@MENTORG.COM>
8 ;; This file is part of GNU Emacs.
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
27 ;; Converts text to Morse code and back with M-x morse-region and
28 ;; M-x unmorse-region (though Morse code is no longer official :-().
32 (eval-when-compile (require 'cl))
34 (defvar digits-punctuation-morse-code '(("0" . "-----")
57 "The digits and punctuation in Morse code, as used internationally.")
59 (defvar english-alphabet-morse-code '(("a" . ".-")
85 "Morse code, as used for the letters of English. ")
87 (defvar german-alphabet-morse-code (nconc
92 ;; Bug; unmorse-region respects
93 ;; ch, morse-region doesn't.
95 english-alphabet-morse-code)
96 "Morse code, as used for the letters of German. ")
98 (defvar spanish-alphabet-morse-code (nconc
102 english-alphabet-morse-code)
103 "Morse code, as used for the letters of Spanish. ")
105 (defvar french-alphabet-morse-code (nconc
110 english-alphabet-morse-code))
112 (defvar swedish-alphabet-morse-code (nconc
116 english-alphabet-morse-code)
117 "Morse code, as used for the letters of Swedish. ")
119 (defvar danish-alphabet-morse-code (nconc
123 english-alphabet-morse-code)
124 "Morse code, as used for the letters of Danish. ")
126 (defvar norwegian-alphabet-morse-code danish-alphabet-morse-code
127 "Morse code, as used for the letters of Norwegian. ")
129 (when (featurep 'mule)
130 (defvar cyrillic-alphabet-morse-code
164 collect (cons (string (make-char 'cyrillic-iso8859-5 cyrillic))
166 "Morse code, as used for the letters of Russian. ")
167 (defvar japanese-alphabet-morse-code
169 for (first-octet second-octet morse)
222 collect (cons (string (make-char 'japanese-jisx0208
223 first-octet second-octet))
225 "Morse code, as used for Katakana. ")
226 (defvar korean-alphabet-morse-code
228 for (first-octet second-octet morse)
255 collect (cons (string (make-char 'korean-ksc5601
256 first-octet second-octet))
258 "Morse code, as used for Hangul. "))
260 (defvar active-morse-code nil
261 "The active Morse alphabet, digits, and punctuation, as an alist. ")
263 (defun choose-active-morse-code ()
264 "Work out what `active-morse-code' should be, and set it to that.
265 Depends on the current language environment. "
266 (let ((alphabet-sym (intern-soft
267 (format "%s-alphabet-morse-code"
268 (if (and (boundp 'current-language-environment)
269 current-language-environment)
272 current-language-environment
275 (if (and alphabet-sym (boundp alphabet-sym))
276 (setq active-morse-code
277 (append (symbol-value alphabet-sym)
278 digits-punctuation-morse-code))
279 (setq active-morse-code
280 (append english-alphabet-morse-code
281 digits-punctuation-morse-code)))))
283 (add-hook 'set-language-environment-hook 'choose-active-morse-code)
285 (choose-active-morse-code)
287 (defun read-morse-args ()
288 "Return a list of the beginning and end of the region, and a language.
289 The language will only be non-nil if the current command has a prefix
290 argument specified. "
292 (if (and (boundp 'zmacs-regions) zmacs-regions (not zmacs-region-active-p))
293 (error "The region is not active now")
294 (let ((tem (marker-buffer (apply 'mark-marker
295 (if (boundp 'zmacs-regions)
297 (unless (and tem (eq tem (current-buffer)))
298 (error "The mark is now set now"))
301 (and current-prefix-arg
302 (if (fboundp 'read-language-name)
303 (read-language-name nil "Language environment: ")
304 (read-string "Language environment: ")))))
307 (defun morse-region (beg end &optional lang)
308 "Convert all text in a given region to morse code.
309 Optional prefix arg LANG gives a language environment to use for conversion. "
310 (interactive (read-morse-args))
312 (setq end (copy-marker end)))
315 (current-language-environment
316 (and (boundp 'current-language-environment)
317 current-language-environment))
318 (active-morse-code active-morse-code)
321 ;; An actual use of dynamic binding in anger!
322 (setq current-language-environment lang)
323 (choose-active-morse-code))
325 (while (< (point) end)
326 (setq str (downcase (buffer-substring (point) (1+ (point)))))
327 (cond ((looking-at "\\s-+")
328 (goto-char (match-end 0))
330 ((setq morse (assoc str active-morse-code))
332 (insert sep (cdr morse))
339 (defun unmorse-region (beg end &optional lang)
340 "Convert morse coded text in region to ordinary text.
341 Optional prefix arg LANG gives a language environment to use for conversion."
342 (interactive (read-morse-args))
344 (setq end (copy-marker end)))
346 (let ((current-language-environment
347 (and (boundp 'current-language-environment)
348 current-language-environment))
349 (active-morse-code active-morse-code)
352 (setq current-language-environment lang)
353 (choose-active-morse-code))
355 (while (< (point) end)
356 (if (null (looking-at "[-.]+"))
358 (setq str (buffer-substring (match-beginning 0) (match-end 0)))
359 (if (null (setq morse (rassoc str active-morse-code)))
360 (goto-char (match-end 0))
362 (if (string-equal "(" (car morse))
363 (if (setq paren (null paren)) "(" ")")
366 (delete-char 1))))))))
370 ;;; morse.el ends here