1 ;;; punycode.el --- An ASCII compatible Unicode encoding format.
3 ;; Copyright (C) 2003 Simon Josefsson
4 ;; Keywords: punycode, idna, idn, unicode, encoding
6 ;; This file is part of GNU Libidn.
8 ;; GNU Libidn is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; GNU Libidn is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU Libidn; see the file COPYING. If not, write to the
20 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
25 ;; A simple wrapper around the command line "idn" utility in GNU
26 ;; Libidn to make punycode operations available in Emacs.
30 ;; (punycode-encode "räksmörgås")
31 ;; => "rksmrgs-5wao1o"
33 ;; (punycode-encode "foo")
36 ;; (punycode-decode "rksmrgs-5wao1o")
39 ;; (punycode-decode "foo-")
42 ;; This package is useless unless your emacs has at least partial
43 ;; support for the UTF-8 coding system.
45 ;; Report bugs to bug-libidn@gnu.org.
49 (defgroup punycode nil
50 "Punycode: An ASCII compatible Unicode encoding format.")
52 (defcustom punycode-program
"env CHARSET=UTF-8 idn"
53 "Name of the GNU Libidn \"idn\" application."
57 (defcustom punycode-encode-parameters
"--quiet --punycode-encode"
58 "Parameters passed to `punycode-program' to invoke punycode encoding mode."
62 (defcustom punycode-decode-parameters
"--quiet --punycode-decode"
63 "Parameters passed to `punycode-program' to invoke punycode decoding mode."
67 ;; Internal process handling:
69 (defvar punycode-encode-process nil
70 "Internal variable holding process for punycode encoding.")
71 (defvar punycode-encode-response nil
72 "Internal variable holding response data received from punycode process.")
74 (defun punycode-encode-response-clear ()
75 (setq punycode-encode-response nil
))
77 (defun punycode-encode-response ()
78 (while (and (eq (process-status punycode-encode-process
) 'run
)
79 (null punycode-encode-response
))
80 (accept-process-output punycode-encode-process
1))
81 punycode-encode-response
)
83 (defun punycode-encode-filter (process string
)
84 (setq punycode-encode-response
(concat punycode-encode-response string
)))
86 (defun punycode-encode-process ()
87 (if (and punycode-encode-process
88 (eq (process-status punycode-encode-process
) 'run
))
89 punycode-encode-process
90 (if punycode-encode-process
92 (kill-process punycode-encode-process
)
94 (when (setq punycode-encode-process
95 (start-process "punycode" nil
96 shell-file-name shell-command-switch
97 (concat punycode-program
" "
98 punycode-encode-parameters
)))
99 (set-process-filter punycode-encode-process
'punycode-encode-filter
)
100 (set-process-coding-system punycode-encode-process
'utf-8
'utf-8
)
101 (process-kill-without-query punycode-encode-process
))
102 punycode-encode-process
))
104 (defvar punycode-decode-process nil
105 "Internal variable holding process for punycode encoding.")
106 (defvar punycode-decode-response nil
107 "Internal variable holding response data received from punycode process.")
109 (defun punycode-decode-response-clear ()
110 (setq punycode-decode-response nil
))
112 (defun punycode-decode-response ()
113 (while (and (eq (process-status punycode-decode-process
) 'run
)
114 (null punycode-decode-response
))
115 (accept-process-output punycode-decode-process
1))
116 punycode-decode-response
)
118 (defun punycode-decode-filter (process string
)
119 (setq punycode-decode-response
(concat punycode-decode-response string
)))
121 (defun punycode-decode-process ()
122 (if (and punycode-decode-process
123 (eq (process-status punycode-decode-process
) 'run
))
124 punycode-decode-process
125 (if punycode-decode-process
127 (kill-process punycode-decode-process
)
129 (when (setq punycode-decode-process
130 (start-process "punycode" nil
131 shell-file-name shell-command-switch
132 (concat punycode-program
" "
133 punycode-decode-parameters
)))
134 (set-process-filter punycode-decode-process
'punycode-decode-filter
)
135 (set-process-coding-system punycode-decode-process
'utf-8
'utf-8
)
136 (process-kill-without-query punycode-decode-process
))
137 punycode-decode-process
))
139 ;; Punycode Elisp API:
141 (defun punycode-encode (str)
142 "Returns a Punycode encoding of STR."
143 (let ((proc (punycode-encode-process))
146 (error "Cannot start idn application")
147 (punycode-encode-response-clear)
148 (process-send-string proc
(concat str
"\n"))
149 (setq string
(punycode-encode-response))
150 (if (string= (substring string
(1- (length string
))) "\n")
151 (substring string
0 (1- (length string
)))
154 (defun punycode-decode (str)
155 "Returns a possibly multibyte string which is the punycode decoding of STR."
156 (let ((proc (punycode-decode-process))
159 (error "Cannot start idn application")
160 (punycode-decode-response-clear)
161 (process-send-string proc
(concat str
"\n"))
162 (setq string
(punycode-decode-response))
163 (if (string= (substring string
(1- (length string
))) "\n")
164 (substring string
0 (1- (length string
)))
169 ;;; punycode.el ends here