1 ;;; ogonek.el --- basic editing commands for Emacs
3 ;; Copyright (C) 1997 Free Software Foundation, Inc.
5 ;; Author: W{\l}odek Bzyl, Ryszard Kubiak
6 ;; Maintainer: rysiek@ipipan.gda.pl (Ryszard Kubiak)
9 ;; This file is part of GNU Emacs.
11 ;; GNU Emacs is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
28 ;; To use this library load it using
29 ;; M-x load-library [enter] ogonek
30 ;; Then, you may get a short info by calling one of
31 ;; M-x ogonek-jak -- in Polish
32 ;; M-x ogonek-how -- in English "
34 (defconst ogonek-name-encoding-alist
35 '(("ascii" . (?A ?C ?E ?L ?N ?O ?S ?Z ?Z
36 ?a ?c ?e ?l ?n ?o ?s ?z ?z))
37 ("iso8859-2" . (161 198 202 163 209 211 166 172 175
38 177 230 234 179 241 243 182 188 191))
39 ("mazovia" . (143 149 144 156 165 163 152 160 161
40 134 141 145 146 164 162 158 166 167))
41 ("windows-EE" . (165 198 202 163 209 211 140 143 175
42 185 230 234 179 241 243 156 159 191))
43 ("windows-PL" . (165 198 202 163 209 211 140 143 175
44 185 230 234 179 241 243 156 159 191))
45 ("latin-2" . (164 143 168 157 227 224 151 141 189
46 165 134 169 136 228 162 152 171 190))
47 ("CP852" . (164 143 168 157 227 224 151 141 189
48 165 134 169 136 228 162 152 171 190))
49 ("MeX" . (129 130 134 138 139 211 145 153 155
50 161 162 166 170 171 243 177 185 187))
51 ("CorelDraw" . (197 242 201 163 209 211 255 225 237
52 229 236 230 198 241 243 165 170 186))
53 ("Amiga" . (194 202 203 206 207 211 212 218 219
54 226 234 235 238 239 243 244 250 251))
55 ("Mac" . (132 140 162 252 193 238 229 143 251
56 136 141 171 184 196 151 230 144 253))
58 "The constant `ogonek-name-encoding-alist' is a list of (NAME.LIST) pairs.
59 Each LIST contains codes for 18 Polish diacritic characters.
60 The codes are given in the following order:
61 Aogonek Cacute Eogonek Lslash Nacute Oacute Sacute Zacute Zdotaccent
62 aogonek cacute eogonek lslash nacute oacute sacute zacute zdotaccent.")
64 ; ------ A Little Info in Polish ---------------
66 (defconst ogonek-informacja
67 " FUNKCJE INTERAKCYJNE UDOST/EPNIANE PRZEZ BIBLIOTEK/E `ogonek'
69 Je/sli czytasz ten tekst, to albo przegl/adasz plik /zr/od/lowy
70 biblioteki `ogonek.el', albo wywo/la/le/s polecenie `ogonek-jak'.
71 W drugim przypadku mo/zesz usun/a/c tekst z ekranu, stosuj/ac
72 polecenie `M-x kill-buffer'.
74 Niniejsza bibliteka dostarcza funkcji do zmiany kodowania polskich
75 znak/ow diakrytycznych. Funkcje te mo/zna pogrupowa/c nast/epuj/aco.
77 1. Funkcje `ogonek-recode-region' oraz `ogonek-recode-buffer'
78 przekodowu/j/a zaznaczony fragment wzgl/ednie ca/ly buffor.
79 Po wywo/laniu interakcyjnym funkcji zadawane s/a
80 pytania o parametry przekodowania, czyli o nazw/e kodowania
81 w tek/scie /zr/od/lowym i nazw/e kodowania docelowego.
82 Poni/zsze przyk/lady pokazuj/a, jakich parametr/ow
83 oczekuj/a wymienione funkcje:
85 (ogonek-recode-region (poczatek) (koniec)
86 nazwa-kodowania-w-tekscie-zrodlowym nazwa-kodowania-docelowa)
88 nazwa-kodowania-w-tekscie-zrodlowym nazwa-kodowania-docelowa)
90 2. Funkcje `ogonek-prefixify-region' oraz `ogonek-prefixify-buffer'
91 do wprowadzania notacji prefiksowej.
93 (ogonek-prefixify-region (poczatek) (koniec)
94 nazwa-kodowania-w-tekscie-zrodlowym znak-prefiksu)
95 (ogonek-prefixify-buffer
96 nazwa-kodowania-w-tekscie-zrodlowym znak-prefiksu)
98 3. Funkcje `ogonek-deprefixify-region' oraz `ogonek-deprefixify-buffer'
99 do usuwania notacji prefiksowej.
101 (ogonek-deprefixify-region (poczatek) (koniec)
102 znak-prefiksu nazwa-kodowania-docelowa)
103 (ogonek-prefixify-buffer
104 znak-prefiksu nazwa-kodowania-docelowa)
106 U/zycie klawisza TAB w trybie interakcyjnym powoduje wy/swietlenie
107 listy dopuszczalnych nazw kod/ow, odczytywanych ze sta/lej
108 `ogonek-name-encoding-alist'.
110 Funkcje biblioteki odwo/luj/a si/e do pi/eciu zmiennych, kt/ore
111 przechowuj/a podpowiedzi do zadawanych pyta/n. Nazwy tych zmiennych
112 oraz ich warto/sci domy/slne s/a nast/epuj/ace:
114 ogonek-from-encoding iso8859-2
115 ogonek-to-encoding mazovia
117 ogonek-prefix-from-encoding iso8859-2
118 ogonek-prefix-to-encoding iso8859-2
120 Powy/zsze warto/sci domy/slne mo/zna zmieni/c przez umieszczenie w pliku
121 konfiguracyjnym `~/.emacs' odpowiednich przypisa/n, na przyk/lad:
123 (setq ogonek-prefix-char ?/)
124 (setq ogonek-prefix-to-encoding \"iso8859-2\")
126 Zamiast wczytywania ca/lej biblioteki `ogonek.el' mo/zna w pliku
127 `~/.emacs' za/z/ada/c wczytania wybranych funkcji i to dopiero w
128 chwili ich wywo/lania:
130 (autoload 'ogonek-jak \"ogonek\")
131 (autoload 'ogonek-recode-region \"ogonek\")
132 (autoload 'ogonek-prefixify-region \"ogonek\")
133 (autoload 'ogonek-deprefixify-region \"ogonek\")
135 Cz/esto wyst/epuj/ace kombinacje wywo/la/n funkcji mo/zna dla wygody
136 skr/oci/c i przypisa/c klawiszom. Oto praktyczne przyk/lady:
138 (defun deprefixify-iso8859-2-region ()
140 (ogonek-deprefixify-region
141 (region-beginning) (region-end) ?/ \"iso8859-2\"))
142 (global-set-key \"\\C-cd\" 'deprefixify-iso8859-2-region) ; ctrl-c d
144 (defun mazovia-to-iso8859-2 ()
146 (ogonek-recode-region \"mazovia\" \"iso8859-2\"))
147 (global-set-key \"\\C-cr\" 'mazovia-to-iso8859-2) ; ctrl-c r
149 (defun prefixify-iso8859-2-region ()
151 (ogonek-prefixify-region
152 (region-beginning) (region-end) \"iso8859-2\" ?/))
153 (global-set-key \"\\C-cp\" 'prefixify-iso8859-2-region) ; ctrl-c p
155 Ka/zd/a operacj/e przekodowania mo/zna w ca/lo/sci odwo/la/c
156 przez wykonanie polecenia `undo'.")
159 "Display the string constant `ogonek-informacja'
160 by inserting it into an auxiliary *ogonek-jak* buffer."
162 (set-buffer (get-buffer-create " *ogonek-jak*"))
163 (insert ogonek-informacja)
164 (switch-to-buffer " *ogonek-jak*")
165 (beginning-of-buffer))
167 ; ------ A Little Info in English --------
169 (defconst ogonek-information
170 " INTERACTIVE FUNCTIONS PROVIDED BY THE LIBRARY `ogonek'.
172 If you read this text then you are either looking at the library's
173 source text or you have called the `ogonek-howto' command. In the
174 latter case you may remove this text using `M-x kill-buffer'.
176 The library provides functions for changing the encoding of Polish
177 diacritic characters, the ones with an `ogonek' below or above them.
178 The functions come in the following gropus.
180 1. Functions `ogonek-recode-region' and `ogonek-recode-buffer' to
181 change between one-character encodings, such as `iso-8859-2',
182 `mazovia', plain `ascii' or `TeX'. As the names suggest you may
183 recode either the entire current buffer or just a marked region
184 of it. You may use these functions interactively as commands. Once
185 you call a command you will be asked about the code used in
186 the source text and the target encoding, the one you want to get.
187 The following examples show a non-interactive use of the functions
188 in a program. They also illustrtate what parameters the functions
191 (ogonek-recode-region (region-beginning) (region-end)
192 from-code-name to-code-name)
193 (ogonek-recode-buffer from-code-name to-code-name)
195 2. Functions `ogonek-prefixify-region' and `ogonek-prefixify-buffer'.
196 for introducing prefix notation:
198 (ogonek-prefixify-region (region-beginning) (region-end)
199 from-code-name prefix-char)
200 (ogonek-prefixify-buffer from-code-name prefix-char)
202 3. Functions `ogonek-deprefixify-region' and `ogonek-deprefixify-buffer'
203 for removing prefix notation:
205 (ogonek-deprefixify-region (region-beginning) (region-end)
206 prefix-char to-code-name)
207 (ogonek-prefixify-buffer prefix-char to-code-name)
209 The use of the TAB character in interactive makes `emacs' display
210 the list of encodings recognized by the library - the code names
211 are stored in the constant `ogonek-name-encoding-alist'
213 The functions of the library refer to five variables that keep
214 hints to the questions asked. The names of those variables as well
215 as their default values are:
217 ogonek-from-encoding iso8859-2
218 ogonek-to-encoding mazovia
220 ogonek-prefix-from-encoding iso8859-2
221 ogonek-prefix-to-encoding iso8859-2
223 The above default values can be changed by placing appropriate settings
224 in the '~/.emacs' file:
226 (setq ogonek-prefix-char ?/)
227 (setq ogonek-prefix-to-encoding \"iso8859-2\")
229 Instead of loading the whole library `ogonek.el' it may be better to
230 autoload chosen functions in `~/.emacs':
232 (autoload 'ogonek-jak \"ogonek\")
233 (autoload 'ogonek-recode-region \"ogonek\")
234 (autoload 'ogonek-prefixify-region \"ogonek\")
235 (autoload 'ogonek-deprefixify-region \"ogonek\")
237 The most frequent function calls can be abbreviated and assigned to
238 keyboard keys. Here are a few practical examples:
240 (setq ogonek-from-code-name \"iso8859-2\")
241 (setq ogonek-to-code-name \"mazovia\")
242 (setq ogonek-prefix-char ?/)
243 (setq ogonek-prefix-from-code-name \"iso8859-2\")
244 (setq ogonek-prefix-to-code-name \"iso8859-2\")
246 (defun deprefixify-iso8859-2-region ()
248 (ogonek-deprefixify-region
249 (region-beginning) (region-end) ?/ \"iso8859-2\"))
250 (global-set-key \"\\C-cd\" 'deprefixify-iso8859-2-region) ; ctrl-c d
252 (defun mazovia-to-iso8859-2 ()
254 (ogonek-recode-region \"mazovia\" \"iso8859-2\"))
255 (global-set-key \"\\C-cr\" 'mazovia-to-iso8859-2) ; ctrl-c r
257 (defun prefixify-iso8859-2-region ()
259 (ogonek-prefixify-region
260 (region-beginning) (region-end) \"iso8859-2\" ?/))
261 (global-set-key \"\\C-cp\" 'prefixify-iso8859-2-region) ; ctrl-c p
263 Each recoding opertation can be called off by executing the `undo'
267 "Display the string constant `ogonek-information'
268 by inserting it into an auxiliary *recode-help* buffer."
270 (set-buffer (get-buffer-create " *ogonek-help*"))
271 (insert ogonek-information)
272 (switch-to-buffer " *ogonek-help*")
273 (beginning-of-buffer))
275 ;; ------ Variables for keeping hints to the questions ---------
277 (defvar ogonek-from-encoding "iso8859-2"
278 "*Encoding in the source file of recoding.")
279 (defvar ogonek-to-encoding "ascii"
280 "*Encoding in the target file of recoding.")
281 (defvar ogonek-prefix-char ?/
282 "*Prefix character for prefix encodings.")
283 (defvar ogonek-prefix-from-encoding "iso8859-2"
284 "*Encoding in the source file subject to prefixifation.")
285 (defvar ogonek-prefix-to-encoding "iso8859-2"
286 "*Encoding in the target file subject to deprefixifation.")
288 ;; ------- Utilities for reading function parameters -------------
290 (defun ogonek-read-encoding (prompt default-name-var)
291 "Change with completion based on alist `ogonek-name-encoding-alist'."
294 (format "%s (default %s): " prompt (eval default-name-var))
295 ogonek-name-encoding-alist nil t)))
296 ; set the new default name to be the one just read
297 (set default-name-var
298 (if (string= encoding "") (eval default-name-var) encoding))
299 ; return the new default as the name you read
300 (eval default-name-var)))
302 (defun ogonek-read-prefix (prompt default-prefix-var)
306 (format "%s (default %s): " prompt
307 (char-to-string (eval default-prefix-var))))))
308 (if (> (length prefix-string) 1)
309 (error "! Only one character expected.")
310 ; set the default prefix character to the one just read
311 (set default-prefix-var
312 (if (string= prefix-string "")
313 (eval default-prefix-var)
314 (string-to-char prefix-string)))
315 ; return the new default prefix as the code you read)
316 (eval default-prefix-var))))
318 (defun ogonek-lookup-encoding (encoding)
319 "Pick up an association for `encoding' in `ogonek-name-encoding-alist'.
320 Before returning a result test whether it has been properly set
321 which should be true if the encoding is one of those in
322 `ogonek-name-encoding-alist'"
323 (let ((code-list (assoc encoding ogonek-name-encoding-alist)))
325 (error "! Name `%s' not known in `ogonek-name-encoding-alist'."
329 ; ------- A utility for zipping two lists -----------
331 (defun ogonek-zip-lists (xs ys)
332 "Build a list of pairs with elements from lists `xs' and `ys'.
333 We assume that `xs' and `ys' are of the same length."
336 (setq pairs (cons (cons (car xs) (car ys)) pairs))
339 ; `pairs' are the function's result
342 ; -------- Dealing with one-character cencodings -------
344 (defun ogonek-build-table (recoding-pairs)
345 "Build a table nedeed by emacs's `translate-region' function.
346 The `recoding-pairs' argument is a list of pairs of characters.
347 By using the built-in `translate-region' function
348 we gain better performance compared to converting characters
349 by a hand-written routine as it is done for prefix encodings."
350 (let ((table (make-string 256 0))
355 ; make changes in `table' according to `recoding-pairs'
356 (while recoding-pairs
357 (aset table (car (car recoding-pairs)) (cdr (car recoding-pairs)))
358 (setq recoding-pairs (cdr recoding-pairs)))
359 ; return the table just built
362 (defun ogonek-recode-region (start end from-encoding to-encoding)
363 "This function recodes text in a region delineated by the current-mark
364 and the current point according to the defaults set by the variables
365 `ogonek-from-encoding' and `ogonek-to-encoding'."
366 (interactive (progn (barf-if-buffer-read-only)
370 (ogonek-read-encoding "From code" 'ogonek-from-encoding)
371 (ogonek-read-encoding "To code" 'ogonek-to-encoding))))
377 (ogonek-lookup-encoding from-encoding)
378 (ogonek-lookup-encoding to-encoding))))))
380 (defun ogonek-recode-buffer (from-encoding to-encoding)
381 "Call `ogonek-region' on the entire buffer."
382 (interactive (progn (barf-if-buffer-read-only)
384 (ogonek-read-encoding "From code" 'ogonek-from-encoding)
385 (ogonek-read-encoding "To code" 'ogonek-to-encoding))))
386 (ogonek-recode-region
387 (point-min) (point-max) from-encoding to-encoding))
389 ; --------------------------------
390 ; Recoding with prefix notation
391 ; --------------------------------
393 (defconst prefix-code '(?A ?C ?E ?L ?N ?O ?S ?X ?Z
394 ?a ?c ?e ?l ?n ?o ?s ?x ?z))
396 (defun ogonek-prefixify-region (start end from-encoding prefix-char)
397 "Replace -- in the region delineated by the current-mark
398 and the point -- each character from `ogonek-from-encoding'
399 by two characters: `ogonek-prefix-char' and the corresponding
400 character from the `prefix' list. Double the character
401 `ogonek-prefix-char'"
402 (interactive (progn (barf-if-buffer-read-only)
406 (ogonek-read-encoding "From code" 'ogonek-prefix-from-encoding)
407 (ogonek-read-prefix "Prefix character" 'ogonek-prefix-char))))
409 ((from-code (ogonek-lookup-encoding from-encoding))
410 (to-code prefix-code)
411 (recoding-pairs ; we add `ogonek-prefix-char' for doubling
413 (cons prefix-char from-code)
414 (cons prefix-char to-code))))
417 (while (< (point) end)
418 (let ((pair (assoc (following-char) recoding-pairs)))
420 ; not a Polish character -- skip it
422 ; Polish character -- replace it by a two characters
424 (insert ogonek-prefix-char)
426 ; the region is now one character longer
427 (setq end (1+ end))))))))
429 (defun ogonek-prefixify-buffer (from-encoding prefix-char)
430 "Call `ogonek-prefixify-region' on the entire buffer."
431 (interactive (progn (barf-if-buffer-read-only)
433 (ogonek-read-encoding "From code" 'ogonek-prefix-from-encoding)
434 (ogonek-read-prefix "Prefix character" 'ogonek-prefix-char))))
435 (ogonek-prefixify-region
436 (point-min) (point-max) from-encoding prefix-char))
438 (defun ogonek-deprefixify-region (start end prefix-char to-encoding)
439 "Replace `ogonek-prefix-char' followed by a character from
440 the `prefix' list or another `ogonek-prefix-char' by
441 the corresponding character from `ogonek-from-encoding'
442 or by one `ogonek-prefix-char'."
443 (interactive (progn (barf-if-buffer-read-only)
444 (list (region-beginning)
447 "Prefix character" 'ogonek-prefix-char)
448 (ogonek-read-encoding
449 "To code" 'ogonek-prefix-to-encoding))))
451 ((from-code prefix-code)
452 (to-code (ogonek-lookup-encoding to-encoding))
455 (cons prefix-char from-code)
456 (cons prefix-char to-code))))
459 (while (< (point) end)
461 (if (or (not (= (preceding-char) prefix-char)) (= (point) end))
462 ; non-prefix character or the end-of-region -- do nothing
464 ; now, we can check the next character
465 (let ((pair (assoc (following-char) recoding-pairs)))
467 ; `following-char' is not a Polish character nor it is
468 ; `prefix-char' since the one is among `recoding-pairs'
470 ; else prefix followed by a Polish character has been found
471 ; replace it by the corresponding Polish character
475 ; the region got shorter by one character
476 (setq end (1- end)))))))))
478 (defun ogonek-deprefixify-buffer (prefix-char to-encoding)
479 "Call `ogonek-deprefixify-region' on the entire buffer."
480 (interactive (progn (barf-if-buffer-read-only)
482 (ogonek-read-prefix "Prefix character" 'ogonek-prefix-char)
483 (ogonek-read-encoding "To code" 'ogonek-prefix-to-encoding))))
484 (ogonek-deprefixify-region
485 (point-min) (point-max) prefix-char to-encoding))
489 ;;; ogonek.el ends here