From: Daiki Ueno <ueno@unixuser.org>
Cc: rms@gnu.org, alex@emacswiki.org, emacs-devel@gnu.org
Subject: Re: IRC client for Emacs
Date: Thu, 22 Aug 2002 16:13:42 +0900 [thread overview]
Message-ID: <85d5d3b0-9de7-4e33-afd6-431aeb53c8cf@deisui.org> (raw)
In-Reply-To: <20020821193900.557945.FMU965@piglet.prv.splode.com> (Noah Friedman's message of "Wed, 21 Aug 2002 19:39:00 -0700 (PDT)")
[-- Attachment #1: Type: text/plain, Size: 940 bytes --]
>>>>> In <20020821193900.557945.FMU965@piglet.prv.splode.com>
>>>>> Noah Friedman <friedman@splode.com> wrote:
> Persistent hashtables might be useful for other things (such as BBDB), so
> they seem worth considering for reasons beyond localization.
Why don't you consider reading *.mo files themselves? Even now gettext
0.11.5 has a support to Emacs Lisp. I have used my gettext.el for that
purpose in my IRC client (Liece) for several years.
Here is the example:
;; Before evaluating the following expressions, it is needed to run
;; ./prepare.sh (attached below) to generate prog.mo in the current
;; directory and to type M-x load-file gettext.el (also, attached below).
(setenv "LANG" "fr")
=> "fr"
(bind-text-domain "prog" ".")
=> (("prog" . "/home/ueno/fr/LC_MESSAGES/prog.mo"))
(dgettext "prog" "'Your command, please?', asked the waiter.")
=> "«Votre commande, s'il vous plait», dit le garçon."
[-- Attachment #2: prepare.sh --]
[-- Type: text/plain, Size: 429 bytes --]
cat <<EOF > fr.po
msgid ""
msgstr ""
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
msgid "'Your command, please?', asked the waiter."
msgstr "«Votre commande, s'il vous plait», dit le garçon."
# Reverse the arguments.
#, elisp-format
msgid "%s is replaced by %s."
msgstr "%2$s remplace %1$s."
EOF
mkdir -p fr/LC_MESSAGES
msgfmt -o fr/LC_MESSAGES/prog.mo fr.po
[-- Attachment #3: gettext.el --]
[-- Type: application/octet-stream, Size: 7125 bytes --]
;;; gettext.el --- GNU gettext interface
;; Copyright (C) 1999-2002 Daiki Ueno
;; Author: Daiki Ueno <ueno@unixuser.org>
;; Keywords: i18n
;; This file is not part of any package.
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Code:
(defvar gettext-gmo-endian 1234)
(defvar gettext-message-domain-to-catalog-alist nil)
(defvar gettext-default-message-domain "emacs")
(defvar gettext-default-mime-charset 'x-ctext)
(defvar gettext-default-locale "C")
(defconst gettext-msgid-regexp "msgid\\s-*\"")
(defconst gettext-msgstr-regexp "msgstr\\s-*\"")
(defvar gettext-mime-charset-coding-system-alist
(let ((coding-systems (coding-system-list 'base-only))
mime-charset alist)
(while coding-systems
(if (and (setq mime-charset
(coding-system-get (car coding-systems) 'mime-charset))
(not (assq mime-charset alist)))
(setq alist (cons (cons mime-charset (car coding-systems)) alist)))
(setq coding-systems (cdr coding-systems)))
alist))
(defmacro gettext-hex-char-to-integer (character)
`(if (and (>= ,character ?0) (<= ,character ?9))
(- ,character ?0)
(let ((ch (logior ,character 32)))
(if (and (>= ch ?a) (<= ch ?f))
(- ch (- ?a 10))
(error "Invalid hex digit `%c'" ch)))))
(defun gettext-hex-string-to-integer (hex-string)
(let ((hex-num 0))
(while (not (equal hex-string ""))
(setq hex-num (+ (* hex-num 16)
(gettext-hex-char-to-integer
(string-to-char hex-string)))
hex-string (substring hex-string 1)))
hex-num))
(defun gettext-gmo-read-32bit-word ()
(let ((word (string-to-list (buffer-substring (point) (+ (point) 4)))))
(forward-char 4)
(apply #'format "%02x%02x%02x%02x"
(mapcar (lambda (ch) (logand 255 ch))
(if (= gettext-gmo-endian 1234)
(nreverse word)
word)))))
(defmacro gettext-gmo-header-revision (header)
`(aref header 0))
(defmacro gettext-gmo-header-nn (header)
`(aref header 1))
(defmacro gettext-gmo-header-oo (header)
`(aref header 2))
(defmacro gettext-gmo-header-tt (header)
`(aref header 3))
(defmacro gettext-gmo-header-ss (header)
`(aref header 4))
(defmacro gettext-gmo-header-hh (header)
`(aref header 5))
(defmacro gettext-gmo-read-header ()
(cons 'vector
(make-list 6 '(gettext-hex-string-to-integer
(gettext-gmo-read-32bit-word)))))
(defun gettext-gmo-collect-strings (nn)
(let (strings pos len off)
(dotimes (i nn)
(setq len (gettext-hex-string-to-integer
(gettext-gmo-read-32bit-word))
off (gettext-hex-string-to-integer
(gettext-gmo-read-32bit-word))
pos (point))
(goto-char (1+ off))
(push (buffer-substring (point) (+ (point) len))
strings)
(goto-char pos))
(nreverse strings)))
(defun gettext-read-mime-charset (&optional header)
"Return the MIME charset of PO file."
(with-temp-buffer
(insert header)
(goto-char (point-min))
(let ((case-fold-search t))
(if (re-search-forward
"^\"Content-Type: *text/plain;[ \t]*charset=\\([^\\]+\\)"
nil t)
(intern (downcase
(buffer-substring (match-beginning 1) (match-end 1))))))))
(defun gettext-mapcar* (function &rest args)
"Apply FUNCTION to successive cars of all ARGS.
Return the list of results."
(let (result)
(while (not (memq nil args))
(push (apply function (mapcar #'car args)) result)
(setq args (mapcar #'cdr args)))
(nreverse result)))
(defun gettext-load-message-catalogue (file)
(with-temp-buffer
(let ((coding-system-for-read 'binary)
header strings charset coding-system gettext-obarray oott)
(insert-file-contents file)
(set-buffer-multibyte nil)
(goto-char (point-min))
(when (looking-at "\x95\x04\x12\xde")
(setq gettext-gmo-endian 4321))
(forward-char 4)
(setq header (gettext-gmo-read-header)
strings
(gettext-mapcar* #'cons
(progn
(goto-char (1+ (gettext-gmo-header-oo header)))
(gettext-gmo-collect-strings
(gettext-gmo-header-nn header)))
(progn
(goto-char (1+ (gettext-gmo-header-tt header)))
(gettext-gmo-collect-strings
(gettext-gmo-header-nn header))))
charset (or (gettext-read-mime-charset
(cdr (assoc "" strings)))
gettext-default-mime-charset)
gettext-obarray (make-vector
(* 2 (gettext-gmo-header-nn header))
0))
(unless (setq coding-system
(cdr (assq charset
gettext-mime-charset-coding-system-alist)))
(error "Unknown MIME-charset is used in `%s'" file))
(while strings
(set (intern (car (car strings)) gettext-obarray)
(decode-coding-string (cdr (car strings)) coding-system))
(setq strings (cdr strings)))
gettext-obarray)))
;;;###autoload
(defun dgettext (domain string)
"Look up STRING in the default message domain and return its translation."
(let ((oott (assoc domain gettext-message-domain-to-catalog-alist)))
(when (stringp (cdr oott))
(setcdr oott (gettext-load-message-catalogue
(cdr oott))))
(or (symbol-value
(intern-soft string (or (cdr oott) (make-vector 1 0))))
string)))
;;;###autoload
(defun gettext (string)
"Look up STRING in the default message domain and return its translation."
(dgettext gettext-default-message-domain string))
;;;###autoload
(defun bind-text-domain (domain pathname)
"Associate a pathname with a message domain."
(let* ((lang (or (getenv "LC_ALL") (getenv "LC_MESSAGES") (getenv "LANG")
gettext-default-locale))
(language (progn
(string-match "\\([^_.]+\\)\\(_[^.]+\\)?\\(\\.[^@]+\\)?"
lang)
(match-string 1 lang)))
(territory (match-string 2 lang))
(code-set (match-string 3 lang))
(lang-path (if lang
(delq nil (list (if (and territory code-set)
(concat language territory
code-set))
(if territory
(concat language territory))
(if code-set
(concat language code-set))
language))))
(file (concat domain ".mo"))
catalog)
(while (and (setq lang (car lang-path))
(setq catalog
(expand-file-name file
(concat pathname
"/" lang "/LC_MESSAGES")))
(not (file-exists-p catalog)))
(setq lang-path (cdr lang-path)))
(when (file-exists-p catalog)
;;(file-exists-p (setq catalog (expand-file-name file pathname)))
(push (cons domain catalog) gettext-message-domain-to-catalog-alist))))
(provide 'gettext)
;;; gettext.el ends here
[-- Attachment #4: Type: text/plain, Size: 15 bytes --]
--
Daiki Ueno
next prev parent reply other threads:[~2002-08-22 7:13 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-08-09 16:01 IRC client for Emacs Alex Schroeder
2002-08-09 20:25 ` John Wiegley
2002-08-10 5:37 ` Noah Friedman
2002-08-11 3:55 ` Richard Stallman
2002-08-11 18:14 ` Alex Schroeder
2002-08-11 23:06 ` Noah Friedman
2002-08-14 16:50 ` Mario Lang
2002-08-14 17:11 ` Karl Eichwalder
2002-08-14 19:07 ` Alex Schroeder
[not found] ` <m2sn1ht4sq.fsf@primate.xs4all.nl>
2002-08-15 8:49 ` Mario Lang
2002-08-15 19:24 ` Karl Eichwalder
2002-08-15 19:54 ` Richard Stallman
2002-08-20 21:38 ` Noah Friedman
2002-08-21 1:53 ` Richard Stallman
2002-08-21 2:07 ` Noah Friedman
2002-08-22 1:56 ` Richard Stallman
2002-08-22 2:39 ` Noah Friedman
2002-08-22 7:13 ` Daiki Ueno [this message]
2002-08-24 2:33 ` Richard Stallman
2002-08-24 4:03 ` Daiki Ueno
2002-08-25 5:27 ` Richard Stallman
2002-08-26 18:29 ` Noah Friedman
2002-08-27 19:05 ` Richard Stallman
2002-08-21 6:51 ` Eli Zaretskii
2002-08-22 0:14 ` Karl Eichwalder
2002-08-13 1:47 ` Richard Stallman
2002-08-13 2:10 ` Noah Friedman
2002-08-13 2:18 ` Mark Ayers
2002-08-14 5:14 ` Richard Stallman
2002-08-13 6:57 ` John Wiegley
2002-08-13 20:47 ` Alex Schroeder
2002-08-14 5:15 ` Richard Stallman
2002-08-12 14:30 ` Steve Youngs
2002-08-10 17:17 ` Richard Stallman
2002-08-10 19:34 ` Alex Schroeder
-- strict thread matches above, loose matches on Subject: below --
2002-08-24 4:32 IRC Client " Jonathan Walther
2002-08-24 5:11 ` Damien Elmes
2002-08-25 5:27 ` Richard Stallman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=85d5d3b0-9de7-4e33-afd6-431aeb53c8cf@deisui.org \
--to=ueno@unixuser.org \
--cc=alex@emacswiki.org \
--cc=emacs-devel@gnu.org \
--cc=rms@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.