diff -Nru ddskk-16.2/ChangeLog ddskk-16.2+0.20190423/ChangeLog --- ddskk-16.2/ChangeLog 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/ChangeLog 2019-04-23 12:49:58.000000000 +0000 @@ -1,3 +1,150 @@ +2019-04-23 Tetsuo Tsukamoto <> + + * skk-annotation.el (skk-annotation-start-python): Bug Fix #72. + Function `set-process-coding-system' takes BUFFER as the 1st arg. + +2019-04-13 Tatsuya Kinoshita + + * skk-gadget.el (skk-default-current-date, skk-ad-to-gengo-1) + (skk-gengo-to-ad-1): Support 昭和64年, 大正15年 and 明治45年. + + * skk-gadget.el (skk-default-current-date, skk-ad-to-gengo-1) + (skk-gengo-to-ad-1): Support 令和元年(2019/5-) and 平成31年(-2019/4). + * skk-vars.el (skk-gengo-alist): Add Japan's new era 令和 (Reiwa). + +2019-02-16 Tsuyoshi Kitamoto + + * skk-develop.el (skk-get-download): Change URL skk-dev.github.io/dict/. + + * make1.bat: Ditto. + +2019-01-09 Tatsuya Kinoshita + + * skk-macs.el (skk-char-to-unibyte-string): Bug Fix. + +2019-01-05 Tsuyoshi Kitamoto + + * skk-macs.el (skk-char-to-unibyte-string): 2017-02-11 の変更が間違いであるため + 元に戻す. + +2018-12-20 Takeshi Abe + + * doc/skk.org, doc/skk.texi, tar-util.el: Fix typo. + + * doc/obsolete-doc/obsolete-skk.texi: Ditto. + +2018-07-07 Tsuyoshi Kitamoto + + * skk-annotation.el (skk-annotation-start-python): Use function + set-process-coding-system instead of set-buffer-process-coding-system. + + * SKK-MK (SKK-MK-install-info-1): Fix install-info. + +2017-07-10 Tsuyoshi Kitamoto + + * SKK-MK (SKK-MK-export-to-texinfo): Use linkcolor and urlcolor. + +2017-07-09 Tsuyoshi Kitamoto + + * skk-annotation.el (skk-annotation-wait-for-input): Fix indent. + (skk-annotation-wait-for-input): Fix #58. + + * skk.el (skk-compile-rule-list): Fix indent. + +2017-07-09 Tsuyoshi Kitamoto + + * SKK-MK (SKK-MK-export-to-texinfo): `{' と `}' に 接頭辞 `@' を追加. + + * Makefile: ターゲット `mobi' を追加. + +2017-07-06 Tsuyoshi Kitamoto + + * Makefile (PDFTEX): Use macro TEXI2PDF. + +2017-07-05 Tsuyoshi Kitamoto + + * Makefile: ターゲット `pdf' を追加. PDF の生成方法を texi2pdf へ変更. + + * SKK-MK (SKK-MK-edit-texi): New functionfor pdf. + + * .gitignore: 無視する拡張子を追加. + +2017-07-01 Tsuyoshi Kitamoto + + * SKK-MK (SKK-MK-export-to-html): `RET' と `SPC' を class (span.key) とした. + + * .gitignore: Add `skk.html'. + +2017-06-30 Tsuyoshi Kitamoto + + * Makefile, SKK-MK: 新たなターゲット texi, html を追加. + skk.texi から skk.org への移行. + +2017-06-11 Tsuyoshi Kitamoto + + * skk-annotation.el (eval-and-compile): make 時の Warning 対策のため + python-shell-internal-get-or-create-process と + python-shell-get-process-name を追加. + +2017-06-09 Tsuyoshi Kitamoto + + * skk.el (skk-search-ja-dic-maybe): Add argument. + (skk-mode): Call skk-search-ja-dic-maybe() with argument. + +2017-05-31 Tetsuo Tsukamoto + + * skk-annotation.el (skkannot-py-check-comint-prompt) + (skk-annotation-start-python, skk-annotation-start-python): Update + for GNU Emacs 25. + * skk-vars.el (skk-annotation-python-program): Default to "python”. + +2017-03-22 Tsuyoshi Kitamoto + + * skk-vars.el (skk-previous-candidate-char): Remove obsolete variable. + + * skk.el (skk-setup-j-mode-map-options): Remove `skk-previous-candidate-char'. + +2017-03-19 Tsuyoshi Kitamoto + + * skk-dcomp.el (defadvice skk-kana-input): skk-pre-henkan 対応. + 候補の確定操作を不要とする. + + * SKK-MK (SKK_MODULES): Add skk-pre-henkan. + +2017-03-14 Tsuyoshi Kitamoto + + * experimental/skk-pre-henkan.el (skk-pre-henkan-make-candidates): modify. + +2017-03-13 Tsuyoshi Kitamoto + + * experimental/skk-pre-henkan.el (skk-pre-henkan-make-candidates): + Remove debug code. + +2017-03-12 Tsuyoshi Kitamoto + + * skk-search-web.el (skk-comp-google-candidates): New internal variable. + (skk-comp-google, skk-comp-google-make-candidates): New functions. + + * experimental/skk-pre-henkan.el (skk-pre-henkan-make-candidates): + let*() から let() へ変更. + skk-dcomp-activate を nil へ. + +2017-03-11 Tsuyoshi Kitamoto + + * experimental/skk-pre-henkan.el: Add new file. + + * skk-dcomp.el (skk-dcomp-multiple-get-candidates): コメントを追加. + + * skk-comp.el (skk-comp-do): インデントを修正. + (skk-comp-get-candidate): コメントを追加. + + * skk.el (skk-treat-strip-note-from-word): 引数が nil の場合にエラーと + なることを防ぐ. + +2017-03-04 Tsuyoshi Kitamoto + + * Makefile, ddskk-pkg.el, skk-version.el: Bump SKK version to 16.2.50. + 2017-03-04 Tsuyoshi Kitamoto * Version 16.2 Warabitai Released. diff -Nru ddskk-16.2/ddskk-pkg.el ddskk-16.2+0.20190423/ddskk-pkg.el --- ddskk-16.2/ddskk-pkg.el 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/ddskk-pkg.el 2019-04-23 12:49:58.000000000 +0000 @@ -5,6 +5,6 @@ ;;; 39.3 Multi-file Packages ;;; One of the files in the content directory must be named name-pkg.el. -(define-package "ddskk" "16.2" +(define-package "ddskk" "16.2.50" "Simple Kana to Kanji conversion program." '((ccc "1.43") (cdb "20141201.754"))) ; REQUIREMENTS diff -Nru ddskk-16.2/debian/changelog ddskk-16.2+0.20190423/debian/changelog --- ddskk-16.2/debian/changelog 2019-04-12 12:18:06.000000000 +0000 +++ ddskk-16.2+0.20190423/debian/changelog 2019-07-14 04:06:22.000000000 +0000 @@ -1,3 +1,17 @@ +ddskk (16.2+0.20190423-1) unstable; urgency=medium + + * New upstream version 16.2+0.20190423 + - vip.el is no longer included (closes: #431071) + * Drop debian/patches + * Update debian/docs to install history.md and skk.org + * Don't install nicola/*.bat + * Update debian/copyright + * Update Standards-Version to 4.4.0 + * Skip old flavors xemacs20 and xemacs19 + * Handle maint/*.el files + + -- Tatsuya Kinoshita Sun, 14 Jul 2019 13:06:22 +0900 + ddskk (16.2-7) unstable; urgency=medium * New patch 020_reiwa.patch to not fail when 令和元年 (2019/5-) diff -Nru ddskk-16.2/debian/control ddskk-16.2+0.20190423/debian/control --- ddskk-16.2/debian/control 2019-01-09 15:37:40.000000000 +0000 +++ ddskk-16.2+0.20190423/debian/control 2019-07-14 03:50:23.000000000 +0000 @@ -4,7 +4,7 @@ Maintainer: Tatsuya Kinoshita Build-Depends: debhelper-compat (= 11) Build-Depends-Indep: emacs-nox | emacs | emacs25 | emacs24 | emacs23 -Standards-Version: 4.3.0 +Standards-Version: 4.4.0 Vcs-Browser: https://salsa.debian.org/debian/ddskk Vcs-Git: https://salsa.debian.org/debian/ddskk.git Homepage: https://github.com/skk-dev/ddskk diff -Nru ddskk-16.2/debian/copyright ddskk-16.2+0.20190423/debian/copyright --- ddskk-16.2/debian/copyright 2019-01-09 15:37:40.000000000 +0000 +++ ddskk-16.2+0.20190423/debian/copyright 2019-07-14 03:50:23.000000000 +0000 @@ -22,11 +22,13 @@ 1999-2001, GUNJI Takao 1996-2000, Itsushi Minoura 2000-2004, Tetsuo Tsukamoto - 2010-2011, Tsuyoshi Kitamoto + 2010-2017, Tsuyoshi Kitamoto 2010, Yusuke Shinyama 2010-2011, HAMANO Kiyoto 1985-2006, Free Software Foundation, Inc. License: GPL-2+ + +License: GPL-2+ 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 @@ -40,12 +42,21 @@ On Debian systems, the complete text of the GNU General Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". +Files: doc/htmlize.el +Copyright: 1997-2013, Hrvoje Niksic +License: GPL-2+ + Files: tar-util.el Copyright: 2016, Tsuyoshi Kitamoto License: GPL-3+ -Files: doc/txi-ja.tex -Copyright: 1985-2006, Free Software Foundation, Inc. +Files: doc/dash.el doc/obsolete-doc/txi-ja.tex doc/texinfo-ja.tex doc/txi-ja.tex +Copyright: 1985-2017, Free Software Foundation, Inc. +License: GPL-3+ + +Files: doc/ox-texinfo+.el +Copyright: 2012-2015, Free Software Foundation, Inc. + 2015-2017, Jonas Bernoulli License: GPL-3+ License: GPL-3+ @@ -65,7 +76,49 @@ On Debian systems, the complete text of the GNU General Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". -Files: doc/skk.texi +Files: doc/texinfo.tex +Copyright: 1985-2017, Free Software Foundation, Inc. +License: GPL-3+ with Texinfo exception + This texinfo.tex file 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 3 of the + License, or (at your option) any later version. + . + This texinfo.tex file 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 this program. If not, see . + . + As a special exception, when this file is read by TeX when processing + a Texinfo source document, you may use the result without + restriction. This Exception is an additional permission under section 7 + of the GNU General Public License, version 3 ("GPLv3"). + +Files: doc/mobi.xsl +Copyright: 2010, Kan-Ru Chen +License: Expat + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + . + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +Files: doc/obsolete-doc/obsolete-skk.texi doc/skk.texi Copyright: 1991-2007, Masahiko Sato (佐藤雅彦), Yukiyoshi Kameyama (亀山幸義), NAKAJIMA Mikio (中島幹夫), IRIE Tetsuya (入江), Kitamoto Tsuyoshi (北本剛), Teika Kazura (定家), Tsukamoto Tetsuo (塚本徹雄) and Tsuyoshi AKIHO (秋保強). Revised by Kiyotaka Sakai (酒井清隆) and Satoshi Harauchi (原内聡) License: copyleft-texi Permission is granted to make and distribute verbatim copies of diff -Nru ddskk-16.2/debian/docs ddskk-16.2+0.20190423/debian/docs --- ddskk-16.2/debian/docs 2016-10-08 23:40:38.000000000 +0000 +++ ddskk-16.2+0.20190423/debian/docs 2019-07-14 03:50:11.000000000 +0000 @@ -10,5 +10,7 @@ READMEs/README.VIP.ja READMEs/README.ccc* READMEs/TODO.ja +READMEs/history* +doc/skk.org experimental/dbm/README.dbm tut-code/README.tut diff -Nru ddskk-16.2/debian/emacsen-install ddskk-16.2+0.20190423/debian/emacsen-install --- ddskk-16.2/debian/emacsen-install 2018-11-25 09:59:34.000000000 +0000 +++ ddskk-16.2+0.20190423/debian/emacsen-install 2019-07-14 04:05:02.000000000 +0000 @@ -7,11 +7,11 @@ if [ -z "${FLAVOR}" ]; then exit 1; fi -if [ "X${FLAVOR}" = Xemacs22 ]; then exit 0; fi -if [ "X${FLAVOR}" = Xemacs21 ]; then exit 0; fi -if [ "X${FLAVOR}" = Xemacs20 ]; then exit 0; fi -if [ "X${FLAVOR}" = Xemacs19 ]; then exit 0; fi -if [ "X${FLAVOR}" = Xmule2 ]; then exit 0; fi +case $FLAVOR in + emacs22|emacs21|emacs20|emacs19|mule2|xemacs20|xemacs19) + exit 0 + ;; +esac ELCDIR=/usr/share/$FLAVOR/site-lisp/$PACKAGE ELDIR=/usr/share/$PACKAGE @@ -56,6 +56,7 @@ for f in $LINKS; do ln -sf "../../../$PACKAGE/$f" . done +cp -R "$ELDIR/maint" . cat << EOF > __path.el (set-language-environment "Japanese") @@ -77,7 +78,7 @@ ${EMACSEN} ${FLAGS} -l NICOLA-DDSKK-ELS -l NICOLA-DDSKK-MK -f nicola-ddskk-generate-autoloads >>CompilationLog 2>&1 ${EMACSEN} ${FLAGS} -f batch-byte-compile nicola-ddskk-autoloads.el >>CompilationLog 2>&1 -${EMACSEN} ${FLAGS} -l install.el -l NICOLA-DDSKK-MK -f compile-nicola-ddskk NONE NONE NONE >>CompilationLog 2>&1 +${EMACSEN} ${FLAGS} -l maint/install.el -l NICOLA-DDSKK-MK -f compile-nicola-ddskk NONE NONE NONE >>CompilationLog 2>&1 for f in skk-exsearch.el skk-exserv.el; do ln -sf "../../../$PACKAGE/$f" . @@ -88,6 +89,7 @@ fi rm -f ${ELCDIR}/skk-lookup.elc ${ELCDIR}/skk-jisx0213.elc rm -f ${ELCDIR}/ptexinfmt.el* ${ELCDIR}/install.el* +rm -rf "$ELCDIR/maint" gzip -9qf CompilationLog if [ -f /usr/share/emacsen-common/debian-startup.el ] && \ diff -Nru ddskk-16.2/debian/emacsen-remove ddskk-16.2+0.20190423/debian/emacsen-remove --- ddskk-16.2/debian/emacsen-remove 2018-08-19 15:49:03.000000000 +0000 +++ ddskk-16.2+0.20190423/debian/emacsen-remove 2019-07-14 03:50:23.000000000 +0000 @@ -7,11 +7,11 @@ if [ -z "${FLAVOR}" ]; then exit 1; fi -if [ "X${FLAVOR}" = Xemacs22 ]; then exit 0; fi -if [ "X${FLAVOR}" = Xemacs21 ]; then exit 0; fi -if [ "X${FLAVOR}" = Xemacs20 ]; then exit 0; fi -if [ "X${FLAVOR}" = Xemacs19 ]; then exit 0; fi -if [ "X${FLAVOR}" = Xmule2 ]; then exit 0; fi +case $FLAVOR in + emacs22|emacs21|emacs20|emacs19|mule2|xemacs20|xemacs19) + exit 0 + ;; +esac if test -x /usr/sbin/install-info-altdir; then echo remove/${PACKAGE}: removing Info links for ${FLAVOR} diff -Nru ddskk-16.2/debian/patches/010_unibyte.patch ddskk-16.2+0.20190423/debian/patches/010_unibyte.patch --- ddskk-16.2/debian/patches/010_unibyte.patch 2019-01-09 15:35:02.000000000 +0000 +++ ddskk-16.2+0.20190423/debian/patches/010_unibyte.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -Subject: Enable M-SPC and M-Q for Emacs 26 -Origin: upstream, https://github.com/skk-dev/ddskk/commit/363a91933d8c83e03be042bd7fbbda8eac3b0b72 - -diff --git a/skk-macs.el b/skk-macs.el -index c6e126d..d10f7ee 100644 ---- a/skk-macs.el -+++ b/skk-macs.el -@@ -445,7 +445,7 @@ but the contents viewed as characters do change. - (char-to-string char)) - ;; GNU Emacs 26 $B$+$i(B - ((eval-when-compile (>= emacs-major-version 26)) -- (encode-coding-string (char-to-string char) 'us-ascii)) -+ (encode-coding-string (char-to-string char) 'iso-8859-1)) - ;; GNU Emacs 25 $B$^$G(B - (t - (string-make-unibyte (char-to-string char)))))) diff -Nru ddskk-16.2/debian/patches/020_reiwa.patch ddskk-16.2+0.20190423/debian/patches/020_reiwa.patch --- ddskk-16.2/debian/patches/020_reiwa.patch 2019-04-11 22:19:41.000000000 +0000 +++ ddskk-16.2+0.20190423/debian/patches/020_reiwa.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -Subject: Don't fail when 令和元年 (2019/5-) -Author: Tatsuya Kinoshita -Bug: https://github.com/skk-dev/ddskk/pull/70 -Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=926861 - - Add Japan's new era 令和 (Reiwa), and prevent an error when 元年 - for skk-default-current-date. - -diff --git a/skk-gadget.el b/skk-gadget.el -index 9bd407ee..7584f979 100644 ---- a/skk-gadget.el -+++ b/skk-gadget.el -@@ -169,13 +169,17 @@ AND-TIME $B$O;~9o$bI=<($9$k$+$I$&$+(B \(boolean\)$B!#(B" - (multiple-value-bind (year month day day-of-week hour minute second v) - date-information - (when gengo -- (setq v (skk-ad-to-gengo-1 (string-to-number year)))) -+ (setq v (skk-ad-to-gengo-1 -+ (string-to-number year) nil -+ (string-to-number (nth 0 (cdr (assoc month skk-month-alist))))))) - (setq year (if gengo - (concat (if gengo-index - (nth gengo-index (car v)) - (caar v)) -- (skk-num-exp (number-to-string (cdr v)) -- num-type)) -+ (if (numberp (cdr v)) -+ (skk-num-exp (number-to-string (cdr v)) -+ num-type) -+ (cdr v))) - (skk-num-exp year num-type))) - (when month-alist-index - (setq month (skk-num-exp (nth month-alist-index -@@ -351,7 +355,7 @@ interactive $B$K5/F0$9$kB>!"(B\"clock /(skk-clock)/\" $B$J$I$N%(%s%H%j$r(B S - tail))) - - ;;;###autoload --(defun skk-ad-to-gengo-1 (ad &optional not-gannen) -+(defun skk-ad-to-gengo-1 (ad &optional not-gannen month) - ;; AD is a number and NOT-GANNEN is a boolean optional - ;; arg. - ;; return a cons cell of which car is a Gengo list -@@ -370,9 +374,12 @@ interactive $B$K5/F0$9$kB>!"(B\"clock /(skk-clock)/\" $B$J$I$N%(%s%H%j$r(B S - ((>= 1988 ad) - (setq ad (- ad 1925)) - (cdr (assq 'showa skk-gengo-alist))) -- (t -+ ((or (< ad 2019) (and (= ad 2019) month (< month 5))) - (setq ad (- ad 1988)) -- (cdr (assq 'heisei skk-gengo-alist)))) -+ (cdr (assq 'heisei skk-gengo-alist))) -+ (t -+ (setq ad (- ad 2018)) -+ (cdr (assq 'reiwa skk-gengo-alist)))) - (cond (not-gannen ad) - ((= ad 1) "$B85(B") - (t ad)))) -@@ -404,6 +411,8 @@ interactive $B$K5/F0$9$kB>!"(B\"clock /(skk-clock)/\" $B$J$I$N%(%s%H%j$r(B S - ((eq number 0) - (skk-error "0 $BG/$O$"$jF@$J$$(B" - "Cannot convert 0 year")) -+ ((member gengo '("$B$l$$$o(B" "$BNaOB(B")) -+ 2018) - ((member gengo '("$B$X$$$;$$(B" "$BJ?@.(B")) - 1988) - ((member gengo '("$B$7$g$&$o(B" "$B> + + * mobi.xsl: New file for `make mobi'. + + * README.org: mobi に関する記述を追加. + +2017-07-08 Tsuyoshi Kitamoto + + * skk.org: Underfull や Overfull 生じないよう微調整. + +2017-07-07 Tsuyoshi Kitamoto + + * txi-ja.tex (\gdef\putwordpage): `p.' を `ページ' に変更. + + * texinfo.tex (\def\xrefX): \refx と \putwordpage の位置を入れ替え. + (\def\xrefprintnodename): `[ノード名]' を `「ノード名」' に変更. + +2017-07-06 Tsuyoshi Kitamoto + + * README.org: Update. + +2017-07-05 Tsuyoshi Kitamoto + + * obsolete-doc/makepdf.bat, obsolete-doc/makepdf.sh: + * obsolete-doc/obsolete-skk.texi, obsolete-doc/txi-ja.tex: Renamed. old files. + + * texinfo-ja.tex, texinfo.tex, txi-ja.tex: New file from + http://www.trueroad.jp/2016/05/14-01.html . + + * README.org, skk.org, skk.texi: Modify. + +2017-07-04 Tsuyoshi Kitamoto + + * makepdf.bat, makepdf.sh: Add comment. + +2017-07-01 Tsuyoshi Kitamoto + + * skk.css: Add new file. + +2017-06-30 Tsuyoshi Kitamoto + + * README.org: skk.texi から skk.org への移行. + + * skk.texi: skk.org から自動生成. + + * obsolete-skk.texi: 旧 skk.texi をリネームしたもの。今後は保守しない. + + * dash.el, htmlize.el, ox-texinfo+.el: org export. + + * skk.org: 今後保守するマニュアル. + 2017-03-04 Tsuyoshi Kitamoto * skk.texi: Bump SKK version to 16.2. diff -Nru ddskk-16.2/doc/dash.el ddskk-16.2+0.20190423/doc/dash.el --- ddskk-16.2/doc/dash.el 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/dash.el 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,2618 @@ +;;; dash.el --- A modern list library for Emacs -*- lexical-binding: t -*- + +;; Copyright (C) 2012-2016 Free Software Foundation, Inc. + +;; Author: Magnar Sveen +;; Version: 2.13.0 +;; Keywords: lists + +;; 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 3 of the License, 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 this program. If not, see . + +;;; Commentary: + +;; A modern list api for Emacs. +;; +;; See documentation on https://github.com/magnars/dash.el#functions +;; +;; **Please note** The lexical binding in this file is not utilised at the +;; moment. We will take full advantage of lexical binding in an upcoming 3.0 +;; release of Dash. In the meantime, we've added the pragma to avoid a bug that +;; you can read more about in https://github.com/magnars/dash.el/issues/130. +;; + +;;; Code: + +(defgroup dash () + "Customize group for dash.el" + :group 'lisp + :prefix "dash-") + +(defun dash--enable-fontlock (symbol value) + (when value + (dash-enable-font-lock)) + (set-default symbol value)) + +(defcustom dash-enable-fontlock nil + "If non-nil, enable fontification of dash functions, macros and +special values." + :type 'boolean + :set 'dash--enable-fontlock + :group 'dash) + +(defmacro !cons (car cdr) + "Destructive: Set CDR to the cons of CAR and CDR." + `(setq ,cdr (cons ,car ,cdr))) + +(defmacro !cdr (list) + "Destructive: Set LIST to the cdr of LIST." + `(setq ,list (cdr ,list))) + +(defmacro --each (list &rest body) + "Anaphoric form of `-each'." + (declare (debug (form body)) + (indent 1)) + (let ((l (make-symbol "list"))) + `(let ((,l ,list) + (it-index 0)) + (while ,l + (let ((it (car ,l))) + ,@body) + (setq it-index (1+ it-index)) + (!cdr ,l))))) + +(defmacro -doto (eval-initial-value &rest forms) + "Eval a form, then insert that form as the 2nd argument to other forms. +The EVAL-INITIAL-VALUE form is evaluated once. Its result is +passed to FORMS, which are then evaluated sequentially. Returns +the target form." + (declare (indent 1)) + (let ((retval (make-symbol "value"))) + `(let ((,retval ,eval-initial-value)) + ,@(mapcar (lambda (form) + (if (sequencep form) + `(,(-first-item form) ,retval ,@(cdr form)) + `(funcall form ,retval))) + forms) + ,retval))) + +(defun -each (list fn) + "Call FN with every item in LIST. Return nil, used for side-effects only." + (--each list (funcall fn it))) + +(put '-each 'lisp-indent-function 1) + +(defalias '--each-indexed '--each) + +(defun -each-indexed (list fn) + "Call (FN index item) for each item in LIST. + +In the anaphoric form `--each-indexed', the index is exposed as `it-index`. + +See also: `-map-indexed'." + (--each list (funcall fn it-index it))) +(put '-each-indexed 'lisp-indent-function 1) + +(defmacro --each-while (list pred &rest body) + "Anaphoric form of `-each-while'." + (declare (debug (form form body)) + (indent 2)) + (let ((l (make-symbol "list")) + (c (make-symbol "continue"))) + `(let ((,l ,list) + (,c t) + (it-index 0)) + (while (and ,l ,c) + (let ((it (car ,l))) + (if (not ,pred) (setq ,c nil) ,@body)) + (setq it-index (1+ it-index)) + (!cdr ,l))))) + +(defun -each-while (list pred fn) + "Call FN with every item in LIST while (PRED item) is non-nil. +Return nil, used for side-effects only." + (--each-while list (funcall pred it) (funcall fn it))) + +(put '-each-while 'lisp-indent-function 2) + +(defmacro --dotimes (num &rest body) + "Repeatedly executes BODY (presumably for side-effects) with `it` bound to integers from 0 through NUM-1." + (declare (debug (form body)) + (indent 1)) + (let ((n (make-symbol "num"))) + `(let ((,n ,num) + (it 0)) + (while (< it ,n) + ,@body + (setq it (1+ it)))))) + +(defun -dotimes (num fn) + "Repeatedly calls FN (presumably for side-effects) passing in integers from 0 through NUM-1." + (--dotimes num (funcall fn it))) + +(put '-dotimes 'lisp-indent-function 1) + +(defun -map (fn list) + "Return a new list consisting of the result of applying FN to the items in LIST." + (mapcar fn list)) + +(defmacro --map (form list) + "Anaphoric form of `-map'." + (declare (debug (form form))) + `(mapcar (lambda (it) ,form) ,list)) + +(defmacro --reduce-from (form initial-value list) + "Anaphoric form of `-reduce-from'." + (declare (debug (form form form))) + `(let ((acc ,initial-value)) + (--each ,list (setq acc ,form)) + acc)) + +(defun -reduce-from (fn initial-value list) + "Return the result of applying FN to INITIAL-VALUE and the +first item in LIST, then applying FN to that result and the 2nd +item, etc. If LIST contains no items, return INITIAL-VALUE and +FN is not called. + +In the anaphoric form `--reduce-from', the accumulated value is +exposed as `acc`. + +See also: `-reduce', `-reduce-r'" + (--reduce-from (funcall fn acc it) initial-value list)) + +(defmacro --reduce (form list) + "Anaphoric form of `-reduce'." + (declare (debug (form form))) + (let ((lv (make-symbol "list-value"))) + `(let ((,lv ,list)) + (if ,lv + (--reduce-from ,form (car ,lv) (cdr ,lv)) + (let (acc it) ,form))))) + +(defun -reduce (fn list) + "Return the result of applying FN to the first 2 items in LIST, +then applying FN to that result and the 3rd item, etc. If LIST +contains no items, FN must accept no arguments as well, and +reduce return the result of calling FN with no arguments. If +LIST has only 1 item, it is returned and FN is not called. + +In the anaphoric form `--reduce', the accumulated value is +exposed as `acc`. + +See also: `-reduce-from', `-reduce-r'" + (if list + (-reduce-from fn (car list) (cdr list)) + (funcall fn))) + +(defun -reduce-r-from (fn initial-value list) + "Replace conses with FN, nil with INITIAL-VALUE and evaluate +the resulting expression. If LIST is empty, INITIAL-VALUE is +returned and FN is not called. + +Note: this function works the same as `-reduce-from' but the +operation associates from right instead of from left. + +See also: `-reduce-r', `-reduce'" + (if (not list) initial-value + (funcall fn (car list) (-reduce-r-from fn initial-value (cdr list))))) + +(defmacro --reduce-r-from (form initial-value list) + "Anaphoric version of `-reduce-r-from'." + (declare (debug (form form form))) + `(-reduce-r-from (lambda (&optional it acc) ,form) ,initial-value ,list)) + +(defun -reduce-r (fn list) + "Replace conses with FN and evaluate the resulting expression. +The final nil is ignored. If LIST contains no items, FN must +accept no arguments as well, and reduce return the result of +calling FN with no arguments. If LIST has only 1 item, it is +returned and FN is not called. + +The first argument of FN is the new item, the second is the +accumulated value. + +Note: this function works the same as `-reduce' but the operation +associates from right instead of from left. + +See also: `-reduce-r-from', `-reduce'" + (cond + ((not list) (funcall fn)) + ((not (cdr list)) (car list)) + (t (funcall fn (car list) (-reduce-r fn (cdr list)))))) + +(defmacro --reduce-r (form list) + "Anaphoric version of `-reduce-r'." + (declare (debug (form form))) + `(-reduce-r (lambda (&optional it acc) ,form) ,list)) + +(defmacro --filter (form list) + "Anaphoric form of `-filter'." + (declare (debug (form form))) + (let ((r (make-symbol "result"))) + `(let (,r) + (--each ,list (when ,form (!cons it ,r))) + (nreverse ,r)))) + +(defun -filter (pred list) + "Return a new list of the items in LIST for which PRED returns a non-nil value. + +Alias: `-select' + +See also: `-keep'" + (--filter (funcall pred it) list)) + +(defalias '-select '-filter) +(defalias '--select '--filter) + +(defmacro --remove (form list) + "Anaphoric form of `-remove'." + (declare (debug (form form))) + `(--filter (not ,form) ,list)) + +(defun -remove (pred list) + "Return a new list of the items in LIST for which PRED returns nil. + +Alias: `-reject'" + (--remove (funcall pred it) list)) + +(defalias '-reject '-remove) +(defalias '--reject '--remove) + +(defun -remove-first (pred list) + "Return a new list with the first item matching PRED removed. + +Alias: `-reject-first' + +See also: `-remove', `-map-first'" + (let (front) + (while (and list (not (funcall pred (car list)))) + (push (car list) front) + (!cdr list)) + (if list + (-concat (nreverse front) (cdr list)) + (nreverse front)))) + +(defmacro --remove-first (form list) + "Anaphoric form of `-remove-first'." + (declare (debug (form form))) + `(-remove-first (lambda (it) ,form) ,list)) + +(defalias '-reject-first '-remove-first) +(defalias '--reject-first '--remove-first) + +(defun -remove-last (pred list) + "Return a new list with the last item matching PRED removed. + +Alias: `-reject-last' + +See also: `-remove', `-map-last'" + (nreverse (-remove-first pred (reverse list)))) + +(defmacro --remove-last (form list) + "Anaphoric form of `-remove-last'." + (declare (debug (form form))) + `(-remove-last (lambda (it) ,form) ,list)) + +(defalias '-reject-last '-remove-last) +(defalias '--reject-last '--remove-last) + +(defun -remove-item (item list) + "Remove all occurences of ITEM from LIST. + +Comparison is done with `equal'." + (declare (pure t) (side-effect-free t)) + (--remove (equal it item) list)) + +(defmacro --keep (form list) + "Anaphoric form of `-keep'." + (declare (debug (form form))) + (let ((r (make-symbol "result")) + (m (make-symbol "mapped"))) + `(let (,r) + (--each ,list (let ((,m ,form)) (when ,m (!cons ,m ,r)))) + (nreverse ,r)))) + +(defun -keep (fn list) + "Return a new list of the non-nil results of applying FN to the items in LIST. + +If you want to select the original items satisfying a predicate use `-filter'." + (--keep (funcall fn it) list)) + +(defun -non-nil (list) + "Return all non-nil elements of LIST." + (declare (pure t) (side-effect-free t)) + (-remove 'null list)) + +(defmacro --map-indexed (form list) + "Anaphoric form of `-map-indexed'." + (declare (debug (form form))) + (let ((r (make-symbol "result"))) + `(let (,r) + (--each ,list + (!cons ,form ,r)) + (nreverse ,r)))) + +(defun -map-indexed (fn list) + "Return a new list consisting of the result of (FN index item) for each item in LIST. + +In the anaphoric form `--map-indexed', the index is exposed as `it-index`. + +See also: `-each-indexed'." + (--map-indexed (funcall fn it-index it) list)) + +(defmacro --map-when (pred rep list) + "Anaphoric form of `-map-when'." + (declare (debug (form form form))) + (let ((r (make-symbol "result"))) + `(let (,r) + (--each ,list (!cons (if ,pred ,rep it) ,r)) + (nreverse ,r)))) + +(defun -map-when (pred rep list) + "Return a new list where the elements in LIST that do not match the PRED function +are unchanged, and where the elements in LIST that do match the PRED function are mapped +through the REP function. + +Alias: `-replace-where' + +See also: `-update-at'" + (--map-when (funcall pred it) (funcall rep it) list)) + +(defalias '-replace-where '-map-when) +(defalias '--replace-where '--map-when) + +(defun -map-first (pred rep list) + "Replace first item in LIST satisfying PRED with result of REP called on this item. + +See also: `-map-when', `-replace-first'" + (let (front) + (while (and list (not (funcall pred (car list)))) + (push (car list) front) + (!cdr list)) + (if list + (-concat (nreverse front) (cons (funcall rep (car list)) (cdr list))) + (nreverse front)))) + +(defmacro --map-first (pred rep list) + "Anaphoric form of `-map-first'." + `(-map-first (lambda (it) ,pred) (lambda (it) (ignore it) ,rep) ,list)) + +(defun -map-last (pred rep list) + "Replace last item in LIST satisfying PRED with result of REP called on this item. + +See also: `-map-when', `-replace-last'" + (nreverse (-map-first pred rep (reverse list)))) + +(defmacro --map-last (pred rep list) + "Anaphoric form of `-map-last'." + `(-map-last (lambda (it) ,pred) (lambda (it) (ignore it) ,rep) ,list)) + +(defun -replace (old new list) + "Replace all OLD items in LIST with NEW. + +Elements are compared using `equal'. + +See also: `-replace-at'" + (declare (pure t) (side-effect-free t)) + (--map-when (equal it old) new list)) + +(defun -replace-first (old new list) + "Replace the first occurence of OLD with NEW in LIST. + +Elements are compared using `equal'. + +See also: `-map-first'" + (declare (pure t) (side-effect-free t)) + (--map-first (equal old it) new list)) + +(defun -replace-last (old new list) + "Replace the last occurence of OLD with NEW in LIST. + +Elements are compared using `equal'. + +See also: `-map-last'" + (declare (pure t) (side-effect-free t)) + (--map-last (equal old it) new list)) + +(defmacro --mapcat (form list) + "Anaphoric form of `-mapcat'." + (declare (debug (form form))) + `(apply 'append (--map ,form ,list))) + +(defun -mapcat (fn list) + "Return the concatenation of the result of mapping FN over LIST. +Thus function FN should return a list." + (--mapcat (funcall fn it) list)) + +(defun -flatten (l) + "Take a nested list L and return its contents as a single, flat list. + +Note that because `nil' represents a list of zero elements (an +empty list), any mention of nil in L will disappear after +flattening. If you need to preserve nils, consider `-flatten-n' +or map them to some unique symbol and then map them back. + +Conses of two atoms are considered \"terminals\", that is, they +aren't flattened further. + +See also: `-flatten-n'" + (declare (pure t) (side-effect-free t)) + (if (and (listp l) (listp (cdr l))) + (-mapcat '-flatten l) + (list l))) + +(defmacro --iterate (form init n) + "Anaphoric version of `-iterate'." + (declare (debug (form form form))) + `(-iterate (lambda (it) ,form) ,init ,n)) + +(defun -flatten-n (num list) + "Flatten NUM levels of a nested LIST. + +See also: `-flatten'" + (declare (pure t) (side-effect-free t)) + (-last-item (--iterate (--mapcat (-list it) it) list (1+ num)))) + +(defun -concat (&rest lists) + "Return a new list with the concatenation of the elements in the supplied LISTS." + (declare (pure t) (side-effect-free t)) + (apply 'append lists)) + +(defalias '-copy 'copy-sequence + "Create a shallow copy of LIST. + +\(fn LIST)") + +(defun -splice (pred fun list) + "Splice lists generated by FUN in place of elements matching PRED in LIST. + +FUN takes the element matching PRED as input. + +This function can be used as replacement for `,@' in case you +need to splice several lists at marked positions (for example +with keywords). + +See also: `-splice-list', `-insert-at'" + (let (r) + (--each list + (if (funcall pred it) + (let ((new (funcall fun it))) + (--each new (!cons it r))) + (!cons it r))) + (nreverse r))) + +(defmacro --splice (pred form list) + "Anaphoric form of `-splice'." + `(-splice (lambda (it) ,pred) (lambda (it) ,form) ,list)) + +(defun -splice-list (pred new-list list) + "Splice NEW-LIST in place of elements matching PRED in LIST. + +See also: `-splice', `-insert-at'" + (-splice pred (lambda (_) new-list) list)) + +(defmacro --splice-list (pred new-list list) + "Anaphoric form of `-splice-list'." + `(-splice-list (lambda (it) ,pred) ,new-list ,list)) + +(defun -cons* (&rest args) + "Make a new list from the elements of ARGS. + +The last 2 members of ARGS are used as the final cons of the +result so if the final member of ARGS is not a list the result is +a dotted list." + (declare (pure t) (side-effect-free t)) + (-reduce-r 'cons args)) + +(defun -snoc (list elem &rest elements) + "Append ELEM to the end of the list. + +This is like `cons', but operates on the end of list. + +If ELEMENTS is non nil, append these to the list as well." + (-concat list (list elem) elements)) + +(defmacro --first (form list) + "Anaphoric form of `-first'." + (declare (debug (form form))) + (let ((n (make-symbol "needle"))) + `(let (,n) + (--each-while ,list (not ,n) + (when ,form (setq ,n it))) + ,n))) + +(defun -first (pred list) + "Return the first x in LIST where (PRED x) is non-nil, else nil. + +To get the first item in the list no questions asked, use `car'. + +Alias: `-find'" + (--first (funcall pred it) list)) + +(defalias '-find '-first) +(defalias '--find '--first) + +(defmacro --some (form list) + "Anaphoric form of `-some'." + (declare (debug (form form))) + (let ((n (make-symbol "needle"))) + `(let (,n) + (--each-while ,list (not ,n) + (setq ,n ,form)) + ,n))) + +(defun -some (pred list) + "Return (PRED x) for the first LIST item where (PRED x) is non-nil, else nil. + +Alias: `-any'" + (--some (funcall pred it) list)) + +(defalias '-any '-some) +(defalias '--any '--some) + +(defmacro --last (form list) + "Anaphoric form of `-last'." + (declare (debug (form form))) + (let ((n (make-symbol "needle"))) + `(let (,n) + (--each ,list + (when ,form (setq ,n it))) + ,n))) + +(defun -last (pred list) + "Return the last x in LIST where (PRED x) is non-nil, else nil." + (--last (funcall pred it) list)) + +(defalias '-first-item 'car + "Return the first item of LIST, or nil on an empty list. + +\(fn LIST)") + +;; Ensure that calls to `-first-item' are compiled to a single opcode, +;; just like `car'. +(put '-first-item 'byte-opcode 'byte-car) +(put '-first-item 'byte-compile 'byte-compile-one-arg) + +;; TODO: emacs23 support, when dropped remove the condition +(eval-when-compile + (require 'cl) + (if (fboundp 'gv-define-simple-setter) + (gv-define-simple-setter -first-item setcar) + (require 'cl) + (with-no-warnings + (defsetf -first-item (x) (val) `(setcar ,x ,val))))) + +(defun -last-item (list) + "Return the last item of LIST, or nil on an empty list." + (declare (pure t) (side-effect-free t)) + (car (last list))) + +;; TODO: emacs23 support, when dropped remove the condition +(eval-when-compile + (if (fboundp 'gv-define-setter) + (gv-define-setter -last-item (val x) `(setcar (last ,x) ,val)) + (with-no-warnings + (defsetf -last-item (x) (val) `(setcar (last ,x) ,val))))) + +(defun -butlast (list) + "Return a list of all items in list except for the last." + ;; no alias as we don't want magic optional argument + (declare (pure t) (side-effect-free t)) + (butlast list)) + +(defmacro --count (pred list) + "Anaphoric form of `-count'." + (declare (debug (form form))) + (let ((r (make-symbol "result"))) + `(let ((,r 0)) + (--each ,list (when ,pred (setq ,r (1+ ,r)))) + ,r))) + +(defun -count (pred list) + "Counts the number of items in LIST where (PRED item) is non-nil." + (--count (funcall pred it) list)) + +(defun ---truthy? (val) + (declare (pure t) (side-effect-free t)) + (not (null val))) + +(defmacro --any? (form list) + "Anaphoric form of `-any?'." + (declare (debug (form form))) + `(---truthy? (--first ,form ,list))) + +(defun -any? (pred list) + "Return t if (PRED x) is non-nil for any x in LIST, else nil. + +Alias: `-any-p', `-some?', `-some-p'" + (--any? (funcall pred it) list)) + +(defalias '-some? '-any?) +(defalias '--some? '--any?) +(defalias '-any-p '-any?) +(defalias '--any-p '--any?) +(defalias '-some-p '-any?) +(defalias '--some-p '--any?) + +(defmacro --all? (form list) + "Anaphoric form of `-all?'." + (declare (debug (form form))) + (let ((a (make-symbol "all"))) + `(let ((,a t)) + (--each-while ,list ,a (setq ,a ,form)) + (---truthy? ,a)))) + +(defun -all? (pred list) + "Return t if (PRED x) is non-nil for all x in LIST, else nil. + +Alias: `-all-p', `-every?', `-every-p'" + (--all? (funcall pred it) list)) + +(defalias '-every? '-all?) +(defalias '--every? '--all?) +(defalias '-all-p '-all?) +(defalias '--all-p '--all?) +(defalias '-every-p '-all?) +(defalias '--every-p '--all?) + +(defmacro --none? (form list) + "Anaphoric form of `-none?'." + (declare (debug (form form))) + `(--all? (not ,form) ,list)) + +(defun -none? (pred list) + "Return t if (PRED x) is nil for all x in LIST, else nil. + +Alias: `-none-p'" + (--none? (funcall pred it) list)) + +(defalias '-none-p '-none?) +(defalias '--none-p '--none?) + +(defmacro --only-some? (form list) + "Anaphoric form of `-only-some?'." + (declare (debug (form form))) + (let ((y (make-symbol "yes")) + (n (make-symbol "no"))) + `(let (,y ,n) + (--each-while ,list (not (and ,y ,n)) + (if ,form (setq ,y t) (setq ,n t))) + (---truthy? (and ,y ,n))))) + +(defun -only-some? (pred list) + "Return `t` if at least one item of LIST matches PRED and at least one item of LIST does not match PRED. +Return `nil` both if all items match the predicate or if none of the items match the predicate. + +Alias: `-only-some-p'" + (--only-some? (funcall pred it) list)) + +(defalias '-only-some-p '-only-some?) +(defalias '--only-some-p '--only-some?) + +(defun -slice (list from &optional to step) + "Return copy of LIST, starting from index FROM to index TO. + +FROM or TO may be negative. These values are then interpreted +modulo the length of the list. + +If STEP is a number, only each STEPth item in the resulting +section is returned. Defaults to 1." + (declare (pure t) (side-effect-free t)) + (let ((length (length list)) + (new-list nil)) + ;; to defaults to the end of the list + (setq to (or to length)) + (setq step (or step 1)) + ;; handle negative indices + (when (< from 0) + (setq from (mod from length))) + (when (< to 0) + (setq to (mod to length))) + + ;; iterate through the list, keeping the elements we want + (--each-while list (< it-index to) + (when (and (>= it-index from) + (= (mod (- from it-index) step) 0)) + (push it new-list))) + (nreverse new-list))) + +(defun -take (n list) + "Return a new list of the first N items in LIST, or all items if there are fewer than N. + +See also: `-take-last'" + (declare (pure t) (side-effect-free t)) + (let (result) + (--dotimes n + (when list + (!cons (car list) result) + (!cdr list))) + (nreverse result))) + +(defun -take-last (n list) + "Return the last N items of LIST in order. + +See also: `-take'" + (declare (pure t) (side-effect-free t)) + (copy-sequence (last list n))) + +(defalias '-drop 'nthcdr + "Return the tail of LIST without the first N items. + +See also: `-drop-last' + +\(fn N LIST)") + +(defun -drop-last (n list) + "Remove the last N items of LIST and return a copy. + +See also: `-drop'" + ;; No alias because we don't want magic optional argument + (declare (pure t) (side-effect-free t)) + (butlast list n)) + +(defmacro --take-while (form list) + "Anaphoric form of `-take-while'." + (declare (debug (form form))) + (let ((r (make-symbol "result"))) + `(let (,r) + (--each-while ,list ,form (!cons it ,r)) + (nreverse ,r)))) + +(defun -take-while (pred list) + "Return a new list of successive items from LIST while (PRED item) returns a non-nil value." + (--take-while (funcall pred it) list)) + +(defmacro --drop-while (form list) + "Anaphoric form of `-drop-while'." + (declare (debug (form form))) + (let ((l (make-symbol "list"))) + `(let ((,l ,list)) + (while (and ,l (let ((it (car ,l))) ,form)) + (!cdr ,l)) + ,l))) + +(defun -drop-while (pred list) + "Return the tail of LIST starting from the first item for which (PRED item) returns nil." + (--drop-while (funcall pred it) list)) + +(defun -split-at (n list) + "Return a list of ((-take N LIST) (-drop N LIST)), in no more than one pass through the list." + (declare (pure t) (side-effect-free t)) + (let (result) + (--dotimes n + (when list + (!cons (car list) result) + (!cdr list))) + (list (nreverse result) list))) + +(defun -rotate (n list) + "Rotate LIST N places to the right. With N negative, rotate to the left. +The time complexity is O(n)." + (declare (pure t) (side-effect-free t)) + (if (> n 0) + (append (last list n) (butlast list n)) + (append (-drop (- n) list) (-take (- n) list)))) + +(defun -insert-at (n x list) + "Return a list with X inserted into LIST at position N. + +See also: `-splice', `-splice-list'" + (declare (pure t) (side-effect-free t)) + (let ((split-list (-split-at n list))) + (nconc (car split-list) (cons x (cadr split-list))))) + +(defun -replace-at (n x list) + "Return a list with element at Nth position in LIST replaced with X. + +See also: `-replace'" + (declare (pure t) (side-effect-free t)) + (let ((split-list (-split-at n list))) + (nconc (car split-list) (cons x (cdr (cadr split-list)))))) + +(defun -update-at (n func list) + "Return a list with element at Nth position in LIST replaced with `(func (nth n list))`. + +See also: `-map-when'" + (let ((split-list (-split-at n list))) + (nconc (car split-list) (cons (funcall func (car (cadr split-list))) (cdr (cadr split-list)))))) + +(defmacro --update-at (n form list) + "Anaphoric version of `-update-at'." + (declare (debug (form form form))) + `(-update-at ,n (lambda (it) ,form) ,list)) + +(defun -remove-at (n list) + "Return a list with element at Nth position in LIST removed. + +See also: `-remove-at-indices', `-remove'" + (declare (pure t) (side-effect-free t)) + (-remove-at-indices (list n) list)) + +(defun -remove-at-indices (indices list) + "Return a list whose elements are elements from LIST without +elements selected as `(nth i list)` for all i +from INDICES. + +See also: `-remove-at', `-remove'" + (declare (pure t) (side-effect-free t)) + (let* ((indices (-sort '< indices)) + (diffs (cons (car indices) (-map '1- (-zip-with '- (cdr indices) indices)))) + r) + (--each diffs + (let ((split (-split-at it list))) + (!cons (car split) r) + (setq list (cdr (cadr split))))) + (!cons list r) + (apply '-concat (nreverse r)))) + +(defmacro --split-with (pred list) + "Anaphoric form of `-split-with'." + (declare (debug (form form))) + (let ((l (make-symbol "list")) + (r (make-symbol "result")) + (c (make-symbol "continue"))) + `(let ((,l ,list) + (,r nil) + (,c t)) + (while (and ,l ,c) + (let ((it (car ,l))) + (if (not ,pred) + (setq ,c nil) + (!cons it ,r) + (!cdr ,l)))) + (list (nreverse ,r) ,l)))) + +(defun -split-with (pred list) + "Return a list of ((-take-while PRED LIST) (-drop-while PRED LIST)), in no more than one pass through the list." + (--split-with (funcall pred it) list)) + +(defmacro -split-on (item list) + "Split the LIST each time ITEM is found. + +Unlike `-partition-by', the ITEM is discarded from the results. +Empty lists are also removed from the result. + +Comparison is done by `equal'. + +See also `-split-when'" + (declare (debug (form form))) + `(-split-when (lambda (it) (equal it ,item)) ,list)) + +(defmacro --split-when (form list) + "Anaphoric version of `-split-when'." + (declare (debug (form form))) + `(-split-when (lambda (it) ,form) ,list)) + +(defun -split-when (fn list) + "Split the LIST on each element where FN returns non-nil. + +Unlike `-partition-by', the \"matched\" element is discarded from +the results. Empty lists are also removed from the result. + +This function can be thought of as a generalization of +`split-string'." + (let (r s) + (while list + (if (not (funcall fn (car list))) + (push (car list) s) + (when s (push (nreverse s) r)) + (setq s nil)) + (!cdr list)) + (when s (push (nreverse s) r)) + (nreverse r))) + +(defmacro --separate (form list) + "Anaphoric form of `-separate'." + (declare (debug (form form))) + (let ((y (make-symbol "yes")) + (n (make-symbol "no"))) + `(let (,y ,n) + (--each ,list (if ,form (!cons it ,y) (!cons it ,n))) + (list (nreverse ,y) (nreverse ,n))))) + +(defun -separate (pred list) + "Return a list of ((-filter PRED LIST) (-remove PRED LIST)), in one pass through the list." + (--separate (funcall pred it) list)) + +(defun ---partition-all-in-steps-reversed (n step list) + "Private: Used by -partition-all-in-steps and -partition-in-steps." + (when (< step 1) + (error "Step must be a positive number, or you're looking at some juicy infinite loops.")) + (let ((result nil)) + (while list + (!cons (-take n list) result) + (setq list (-drop step list))) + result)) + +(defun -partition-all-in-steps (n step list) + "Return a new list with the items in LIST grouped into N-sized sublists at offsets STEP apart. +The last groups may contain less than N items." + (declare (pure t) (side-effect-free t)) + (nreverse (---partition-all-in-steps-reversed n step list))) + +(defun -partition-in-steps (n step list) + "Return a new list with the items in LIST grouped into N-sized sublists at offsets STEP apart. +If there are not enough items to make the last group N-sized, +those items are discarded." + (declare (pure t) (side-effect-free t)) + (let ((result (---partition-all-in-steps-reversed n step list))) + (while (and result (< (length (car result)) n)) + (!cdr result)) + (nreverse result))) + +(defun -partition-all (n list) + "Return a new list with the items in LIST grouped into N-sized sublists. +The last group may contain less than N items." + (declare (pure t) (side-effect-free t)) + (-partition-all-in-steps n n list)) + +(defun -partition (n list) + "Return a new list with the items in LIST grouped into N-sized sublists. +If there are not enough items to make the last group N-sized, +those items are discarded." + (declare (pure t) (side-effect-free t)) + (-partition-in-steps n n list)) + +(defmacro --partition-by (form list) + "Anaphoric form of `-partition-by'." + (declare (debug (form form))) + (let ((r (make-symbol "result")) + (s (make-symbol "sublist")) + (v (make-symbol "value")) + (n (make-symbol "new-value")) + (l (make-symbol "list"))) + `(let ((,l ,list)) + (when ,l + (let* ((,r nil) + (it (car ,l)) + (,s (list it)) + (,v ,form) + (,l (cdr ,l))) + (while ,l + (let* ((it (car ,l)) + (,n ,form)) + (unless (equal ,v ,n) + (!cons (nreverse ,s) ,r) + (setq ,s nil) + (setq ,v ,n)) + (!cons it ,s) + (!cdr ,l))) + (!cons (nreverse ,s) ,r) + (nreverse ,r)))))) + +(defun -partition-by (fn list) + "Apply FN to each item in LIST, splitting it each time FN returns a new value." + (--partition-by (funcall fn it) list)) + +(defmacro --partition-by-header (form list) + "Anaphoric form of `-partition-by-header'." + (declare (debug (form form))) + (let ((r (make-symbol "result")) + (s (make-symbol "sublist")) + (h (make-symbol "header-value")) + (b (make-symbol "seen-body?")) + (n (make-symbol "new-value")) + (l (make-symbol "list"))) + `(let ((,l ,list)) + (when ,l + (let* ((,r nil) + (it (car ,l)) + (,s (list it)) + (,h ,form) + (,b nil) + (,l (cdr ,l))) + (while ,l + (let* ((it (car ,l)) + (,n ,form)) + (if (equal ,h ,n) + (when ,b + (!cons (nreverse ,s) ,r) + (setq ,s nil) + (setq ,b nil)) + (setq ,b t)) + (!cons it ,s) + (!cdr ,l))) + (!cons (nreverse ,s) ,r) + (nreverse ,r)))))) + +(defun -partition-by-header (fn list) + "Apply FN to the first item in LIST. That is the header +value. Apply FN to each item in LIST, splitting it each time FN +returns the header value, but only after seeing at least one +other value (the body)." + (--partition-by-header (funcall fn it) list)) + +(defmacro --group-by (form list) + "Anaphoric form of `-group-by'." + (declare (debug t)) + (let ((n (make-symbol "n")) + (k (make-symbol "k")) + (grp (make-symbol "grp"))) + `(nreverse + (-map + (lambda (,n) + (cons (car ,n) + (nreverse (cdr ,n)))) + (--reduce-from + (let* ((,k (,@form)) + (,grp (assoc ,k acc))) + (if ,grp + (setcdr ,grp (cons it (cdr ,grp))) + (push + (list ,k it) + acc)) + acc) + nil ,list))))) + +(defun -group-by (fn list) + "Separate LIST into an alist whose keys are FN applied to the +elements of LIST. Keys are compared by `equal'." + (--group-by (funcall fn it) list)) + +(defun -interpose (sep list) + "Return a new list of all elements in LIST separated by SEP." + (declare (pure t) (side-effect-free t)) + (let (result) + (when list + (!cons (car list) result) + (!cdr list)) + (while list + (setq result (cons (car list) (cons sep result))) + (!cdr list)) + (nreverse result))) + +(defun -interleave (&rest lists) + "Return a new list of the first item in each list, then the second etc." + (declare (pure t) (side-effect-free t)) + (let (result) + (while (-none? 'null lists) + (--each lists (!cons (car it) result)) + (setq lists (-map 'cdr lists))) + (nreverse result))) + +(defmacro --zip-with (form list1 list2) + "Anaphoric form of `-zip-with'. + +The elements in list1 is bound as `it`, the elements in list2 as `other`." + (declare (debug (form form form))) + (let ((r (make-symbol "result")) + (l1 (make-symbol "list1")) + (l2 (make-symbol "list2"))) + `(let ((,r nil) + (,l1 ,list1) + (,l2 ,list2)) + (while (and ,l1 ,l2) + (let ((it (car ,l1)) + (other (car ,l2))) + (!cons ,form ,r) + (!cdr ,l1) + (!cdr ,l2))) + (nreverse ,r)))) + +(defun -zip-with (fn list1 list2) + "Zip the two lists LIST1 and LIST2 using a function FN. This +function is applied pairwise taking as first argument element of +LIST1 and as second argument element of LIST2 at corresponding +position. + +The anaphoric form `--zip-with' binds the elements from LIST1 as `it`, +and the elements from LIST2 as `other`." + (--zip-with (funcall fn it other) list1 list2)) + +(defun -zip (&rest lists) + "Zip LISTS together. Group the head of each list, followed by the +second elements of each list, and so on. The lengths of the returned +groupings are equal to the length of the shortest input list. + +If two lists are provided as arguments, return the groupings as a list +of cons cells. Otherwise, return the groupings as a list of lists. + +Please note! This distinction is being removed in an upcoming 3.0 +release of Dash. If you rely on this behavior, use -zip-pair instead." + (declare (pure t) (side-effect-free t)) + (let (results) + (while (-none? 'null lists) + (setq results (cons (mapcar 'car lists) results)) + (setq lists (mapcar 'cdr lists))) + (setq results (nreverse results)) + (if (= (length lists) 2) + ;; to support backward compatability, return + ;; a cons cell if two lists were provided + (--map (cons (car it) (cadr it)) results) + results))) + +(defalias '-zip-pair '-zip) + +(defun -zip-fill (fill-value &rest lists) + "Zip LISTS, with FILL-VALUE padded onto the shorter lists. The +lengths of the returned groupings are equal to the length of the +longest input list." + (declare (pure t) (side-effect-free t)) + (apply '-zip (apply '-pad (cons fill-value lists)))) + +(defun -unzip (lists) + "Unzip LISTS. + +This works just like `-zip' but takes a list of lists instead of +a variable number of arguments, such that + + (-unzip (-zip L1 L2 L3 ...)) + +is identity (given that the lists are the same length). + +See also: `-zip'" + (apply '-zip lists)) + +(defun -cycle (list) + "Return an infinite copy of LIST that will cycle through the +elements and repeat from the beginning." + (declare (pure t) (side-effect-free t)) + (let ((newlist (-map 'identity list))) + (nconc newlist newlist))) + +(defun -pad (fill-value &rest lists) + "Appends FILL-VALUE to the end of each list in LISTS such that they +will all have the same length." + (let* ((annotations (-annotate 'length lists)) + (n (-max (-map 'car annotations)))) + (--map (append (cdr it) (-repeat (- n (car it)) fill-value)) annotations))) + +(defun -annotate (fn list) + "Return a list of cons cells where each cell is FN applied to each +element of LIST paired with the unmodified element of LIST." + (-zip (-map fn list) list)) + +(defmacro --annotate (form list) + "Anaphoric version of `-annotate'." + (declare (debug (form form))) + `(-annotate (lambda (it) ,form) ,list)) + +(defun dash--table-carry (lists restore-lists &optional re) + "Helper for `-table' and `-table-flat'. + +If a list overflows, carry to the right and reset the list." + (while (not (or (car lists) + (equal lists '(nil)))) + (setcar lists (car restore-lists)) + (pop (cadr lists)) + (!cdr lists) + (!cdr restore-lists) + (when re + (push (nreverse (car re)) (cadr re)) + (setcar re nil) + (!cdr re)))) + +(defun -table (fn &rest lists) + "Compute outer product of LISTS using function FN. + +The function FN should have the same arity as the number of +supplied lists. + +The outer product is computed by applying fn to all possible +combinations created by taking one element from each list in +order. The dimension of the result is (length lists). + +See also: `-table-flat'" + (let ((restore-lists (copy-sequence lists)) + (last-list (last lists)) + (re (make-list (length lists) nil))) + (while (car last-list) + (let ((item (apply fn (-map 'car lists)))) + (push item (car re)) + (setcar lists (cdar lists)) ;; silence byte compiler + (dash--table-carry lists restore-lists re))) + (nreverse (car (last re))))) + +(defun -table-flat (fn &rest lists) + "Compute flat outer product of LISTS using function FN. + +The function FN should have the same arity as the number of +supplied lists. + +The outer product is computed by applying fn to all possible +combinations created by taking one element from each list in +order. The results are flattened, ignoring the tensor structure +of the result. This is equivalent to calling: + + (-flatten-n (1- (length lists)) (apply '-table fn lists)) + +but the implementation here is much more efficient. + +See also: `-flatten-n', `-table'" + (let ((restore-lists (copy-sequence lists)) + (last-list (last lists)) + re) + (while (car last-list) + (let ((item (apply fn (-map 'car lists)))) + (push item re) + (setcar lists (cdar lists)) ;; silence byte compiler + (dash--table-carry lists restore-lists))) + (nreverse re))) + +(defun -partial (fn &rest args) + "Take a function FN and fewer than the normal arguments to FN, +and return a fn that takes a variable number of additional ARGS. +When called, the returned function calls FN with ARGS first and +then additional args." + (apply 'apply-partially fn args)) + +(defun -elem-index (elem list) + "Return the index of the first element in the given LIST which +is equal to the query element ELEM, or nil if there is no +such element." + (declare (pure t) (side-effect-free t)) + (car (-elem-indices elem list))) + +(defun -elem-indices (elem list) + "Return the indices of all elements in LIST equal to the query +element ELEM, in ascending order." + (declare (pure t) (side-effect-free t)) + (-find-indices (-partial 'equal elem) list)) + +(defun -find-indices (pred list) + "Return the indices of all elements in LIST satisfying the +predicate PRED, in ascending order." + (apply 'append (--map-indexed (when (funcall pred it) (list it-index)) list))) + +(defmacro --find-indices (form list) + "Anaphoric version of `-find-indices'." + (declare (debug (form form))) + `(-find-indices (lambda (it) ,form) ,list)) + +(defun -find-index (pred list) + "Take a predicate PRED and a LIST and return the index of the +first element in the list satisfying the predicate, or nil if +there is no such element. + +See also `-first'." + (car (-find-indices pred list))) + +(defmacro --find-index (form list) + "Anaphoric version of `-find-index'." + (declare (debug (form form))) + `(-find-index (lambda (it) ,form) ,list)) + +(defun -find-last-index (pred list) + "Take a predicate PRED and a LIST and return the index of the +last element in the list satisfying the predicate, or nil if +there is no such element. + +See also `-last'." + (-last-item (-find-indices pred list))) + +(defmacro --find-last-index (form list) + "Anaphoric version of `-find-last-index'." + `(-find-last-index (lambda (it) ,form) ,list)) + +(defun -select-by-indices (indices list) + "Return a list whose elements are elements from LIST selected +as `(nth i list)` for all i from INDICES." + (declare (pure t) (side-effect-free t)) + (let (r) + (--each indices + (!cons (nth it list) r)) + (nreverse r))) + +(defun -select-columns (columns table) + "Select COLUMNS from TABLE. + +TABLE is a list of lists where each element represents one row. +It is assumed each row has the same length. + +Each row is transformed such that only the specified COLUMNS are +selected. + +See also: `-select-column', `-select-by-indices'" + (declare (pure t) (side-effect-free t)) + (--map (-select-by-indices columns it) table)) + +(defun -select-column (column table) + "Select COLUMN from TABLE. + +TABLE is a list of lists where each element represents one row. +It is assumed each row has the same length. + +The single selected column is returned as a list. + +See also: `-select-columns', `-select-by-indices'" + (declare (pure t) (side-effect-free t)) + (--mapcat (-select-by-indices (list column) it) table)) + +(defmacro -> (x &optional form &rest more) + "Thread the expr through the forms. Insert X as the second item +in the first form, making a list of it if it is not a list +already. If there are more forms, insert the first form as the +second item in second form, etc." + (declare (debug (form &rest [&or symbolp (sexp &rest form)]))) + (cond + ((null form) x) + ((null more) (if (listp form) + `(,(car form) ,x ,@(cdr form)) + (list form x))) + (:else `(-> (-> ,x ,form) ,@more)))) + +(defmacro ->> (x &optional form &rest more) + "Thread the expr through the forms. Insert X as the last item +in the first form, making a list of it if it is not a list +already. If there are more forms, insert the first form as the +last item in second form, etc." + (declare (debug ->)) + (cond + ((null form) x) + ((null more) (if (listp form) + `(,@form ,x) + (list form x))) + (:else `(->> (->> ,x ,form) ,@more)))) + +(defmacro --> (x form &rest more) + "Thread the expr through the forms. Insert X at the position +signified by the token `it' in the first form. If there are more +forms, insert the first form at the position signified by `it' in +in second form, etc." + (declare (debug (form &rest [&or symbolp (sexp &rest [&or "it" form])]))) + (if (null more) + (if (listp form) + (--map-when (eq it 'it) x form) + (list form x)) + `(--> (--> ,x ,form) ,@more))) + +(defmacro -some-> (x &optional form &rest more) + "When expr is non-nil, thread it through the first form (via `->'), +and when that result is non-nil, through the next form, etc." + (declare (debug ->)) + (if (null form) x + (let ((result (make-symbol "result"))) + `(-some-> (-when-let (,result ,x) + (-> ,result ,form)) + ,@more)))) + +(defmacro -some->> (x &optional form &rest more) + "When expr is non-nil, thread it through the first form (via `->>'), +and when that result is non-nil, through the next form, etc." + (declare (debug ->)) + (if (null form) x + (let ((result (make-symbol "result"))) + `(-some->> (-when-let (,result ,x) + (->> ,result ,form)) + ,@more)))) + +(defmacro -some--> (x &optional form &rest more) + "When expr in non-nil, thread it through the first form (via `-->'), +and when that result is non-nil, through the next form, etc." + (declare (debug ->)) + (if (null form) x + (let ((result (make-symbol "result"))) + `(-some--> (-when-let (,result ,x) + (--> ,result ,form)) + ,@more)))) + +(defun -grade-up (comparator list) + "Grade elements of LIST using COMPARATOR relation, yielding a +permutation vector such that applying this permutation to LIST +sorts it in ascending order." + ;; ugly hack to "fix" lack of lexical scope + (let ((comp `(lambda (it other) (funcall ',comparator (car it) (car other))))) + (->> (--map-indexed (cons it it-index) list) + (-sort comp) + (-map 'cdr)))) + +(defun -grade-down (comparator list) + "Grade elements of LIST using COMPARATOR relation, yielding a +permutation vector such that applying this permutation to LIST +sorts it in descending order." + ;; ugly hack to "fix" lack of lexical scope + (let ((comp `(lambda (it other) (funcall ',comparator (car other) (car it))))) + (->> (--map-indexed (cons it it-index) list) + (-sort comp) + (-map 'cdr)))) + +(defvar dash--source-counter 0 + "Monotonic counter for generated symbols.") + +(defun dash--match-make-source-symbol () + "Generate a new dash-source symbol. + +All returned symbols are guaranteed to be unique." + (prog1 (make-symbol (format "--dash-source-%d--" dash--source-counter)) + (setq dash--source-counter (1+ dash--source-counter)))) + +(defun dash--match-ignore-place-p (symbol) + "Return non-nil if SYMBOL is a symbol and starts with _." + (and (symbolp symbol) + (eq (aref (symbol-name symbol) 0) ?_))) + +(defun dash--match-cons-skip-cdr (skip-cdr source) + "Helper function generating idiomatic shifting code." + (cond + ((= skip-cdr 0) + `(pop ,source)) + (t + `(prog1 ,(dash--match-cons-get-car skip-cdr source) + (setq ,source ,(dash--match-cons-get-cdr (1+ skip-cdr) source)))))) + +(defun dash--match-cons-get-car (skip-cdr source) + "Helper function generating idiomatic code to get nth car." + (cond + ((= skip-cdr 0) + `(car ,source)) + ((= skip-cdr 1) + `(cadr ,source)) + (t + `(nth ,skip-cdr ,source)))) + +(defun dash--match-cons-get-cdr (skip-cdr source) + "Helper function generating idiomatic code to get nth cdr." + (cond + ((= skip-cdr 0) + source) + ((= skip-cdr 1) + `(cdr ,source)) + (t + `(nthcdr ,skip-cdr ,source)))) + +(defun dash--match-cons (match-form source) + "Setup a cons matching environment and call the real matcher." + (let ((s (dash--match-make-source-symbol)) + (n 0) + (m match-form)) + (while (and (consp m) + (dash--match-ignore-place-p (car m))) + (setq n (1+ n)) (!cdr m)) + (cond + ;; when we only have one pattern in the list, we don't have to + ;; create a temporary binding (--dash-source--) for the source + ;; and just use the input directly + ((and (consp m) + (not (cdr m))) + (dash--match (car m) (dash--match-cons-get-car n source))) + ;; handle other special types + ((> n 0) + (dash--match m (dash--match-cons-get-cdr n source))) + ;; this is the only entry-point for dash--match-cons-1, that's + ;; why we can't simply use the above branch, it would produce + ;; infinite recursion + (t + (cons (list s source) (dash--match-cons-1 match-form s)))))) + +(defun dash--match-cons-1 (match-form source &optional props) + "Match MATCH-FORM against SOURCE. + +MATCH-FORM is a proper or improper list. Each element of +MATCH-FORM is either a symbol, which gets bound to the respective +value in source or another match form which gets destructured +recursively. + +If the cdr of last cons cell in the list is `nil', matching stops +there. + +SOURCE is a proper or improper list." + (let ((skip-cdr (or (plist-get props :skip-cdr) 0))) + (cond + ((consp match-form) + (cond + ((cdr match-form) + (cond + ((and (symbolp (car match-form)) + (memq (car match-form) '(&keys &plist &alist &hash))) + (dash--match-kv match-form (dash--match-cons-get-cdr skip-cdr source))) + ((dash--match-ignore-place-p (car match-form)) + (dash--match-cons-1 (cdr match-form) source + (plist-put props :skip-cdr (1+ skip-cdr)))) + (t + (-concat (dash--match (car match-form) (dash--match-cons-skip-cdr skip-cdr source)) + (dash--match-cons-1 (cdr match-form) source))))) + (t ;; Last matching place, no need for shift + (dash--match (car match-form) (dash--match-cons-get-car skip-cdr source))))) + ((eq match-form nil) + nil) + (t ;; Handle improper lists. Last matching place, no need for shift + (dash--match match-form (dash--match-cons-get-cdr skip-cdr source)))))) + +(defun dash--vector-tail (seq start) + "Return the tail of SEQ starting at START." + (cond + ((vectorp seq) + (let* ((re-length (- (length seq) start)) + (re (make-vector re-length 0))) + (--dotimes re-length (aset re it (aref seq (+ it start)))) + re)) + ((stringp seq) + (substring seq start)))) + +(defun dash--match-vector (match-form source) + "Setup a vector matching environment and call the real matcher." + (let ((s (dash--match-make-source-symbol))) + (cond + ;; don't bind `s' if we only have one sub-pattern + ((= (length match-form) 1) + (dash--match (aref match-form 0) `(aref ,source 0))) + ;; if the source is a symbol, we don't need to re-bind it + ((symbolp source) + (dash--match-vector-1 match-form source)) + ;; don't bind `s' if we only have one sub-pattern which is not ignored + ((let* ((ignored-places (mapcar 'dash--match-ignore-place-p match-form)) + (ignored-places-n (length (-remove 'null ignored-places)))) + (when (= ignored-places-n (1- (length match-form))) + (let ((n (-find-index 'null ignored-places))) + (dash--match (aref match-form n) `(aref ,source ,n)))))) + (t + (cons (list s source) (dash--match-vector-1 match-form s)))))) + +(defun dash--match-vector-1 (match-form source) + "Match MATCH-FORM against SOURCE. + +MATCH-FORM is a vector. Each element of MATCH-FORM is either a +symbol, which gets bound to the respective value in source or +another match form which gets destructured recursively. + +If second-from-last place in MATCH-FORM is the symbol &rest, the +next element of the MATCH-FORM is matched against the tail of +SOURCE, starting at index of the &rest symbol. This is +conceptually the same as the (head . tail) match for improper +lists, where dot plays the role of &rest. + +SOURCE is a vector. + +If the MATCH-FORM vector is shorter than SOURCE vector, only +the (length MATCH-FORM) places are bound, the rest of the SOURCE +is discarded." + (let ((i 0) + (l (length match-form)) + (re)) + (while (< i l) + (let ((m (aref match-form i))) + (push (cond + ((and (symbolp m) + (eq m '&rest)) + (prog1 (dash--match + (aref match-form (1+ i)) + `(dash--vector-tail ,source ,i)) + (setq i l))) + ((and (symbolp m) + ;; do not match symbols starting with _ + (not (eq (aref (symbol-name m) 0) ?_))) + (list (list m `(aref ,source ,i)))) + ((not (symbolp m)) + (dash--match m `(aref ,source ,i)))) + re) + (setq i (1+ i)))) + (-flatten-n 1 (nreverse re)))) + +(defun dash--match-kv (match-form source) + "Setup a kv matching environment and call the real matcher. + +kv can be any key-value store, such as plist, alist or hash-table." + (let ((s (dash--match-make-source-symbol))) + (cond + ;; don't bind `s' if we only have one sub-pattern (&type key val) + ((= (length match-form) 3) + (dash--match-kv-1 (cdr match-form) source (car match-form))) + ;; if the source is a symbol, we don't need to re-bind it + ((symbolp source) + (dash--match-kv-1 (cdr match-form) source (car match-form))) + (t + (cons (list s source) (dash--match-kv-1 (cdr match-form) s (car match-form))))))) + +(defun dash--match-kv-1 (match-form source type) + "Match MATCH-FORM against SOURCE of type TYPE. + +MATCH-FORM is a proper list of the form (key1 place1 ... keyN +placeN). Each placeK is either a symbol, which gets bound to the +value of keyK retrieved from the key-value store, or another +match form which gets destructured recursively. + +SOURCE is a key-value store of type TYPE, which can be a plist, +an alist or a hash table. + +TYPE is a token specifying the type of the key-value store. +Valid values are &plist, &alist and &hash." + (-flatten-n 1 (-map + (lambda (kv) + (let* ((k (car kv)) + (v (cadr kv)) + (getter (cond + ((or (eq type '&plist) (eq type '&keys)) + `(plist-get ,source ,k)) + ((eq type '&alist) + `(cdr (assoc ,k ,source))) + ((eq type '&hash) + `(gethash ,k ,source))))) + (cond + ((symbolp v) + (list (list v getter))) + (t (dash--match v getter))))) + (-partition 2 match-form)))) + +(defun dash--match-symbol (match-form source) + "Bind a symbol. + +This works just like `let', there is no destructuring." + (list (list match-form source))) + +(defun dash--match (match-form source) + "Match MATCH-FORM against SOURCE. + +This function tests the MATCH-FORM and dispatches to specific +matchers based on the type of the expression. + +Key-value stores are disambiguated by placing a token &plist, +&alist or &hash as a first item in the MATCH-FORM." + (cond + ((symbolp match-form) + (dash--match-symbol match-form source)) + ((consp match-form) + (cond + ;; Handle the "x &as" bindings first. + ((and (consp (cdr match-form)) + (symbolp (car match-form)) + (eq '&as (cadr match-form))) + (let ((s (car match-form))) + (cons (list s source) + (dash--match (cddr match-form) s)))) + ((memq (car match-form) '(&keys &plist &alist &hash)) + (dash--match-kv match-form source)) + (t (dash--match-cons match-form source)))) + ((vectorp match-form) + ;; We support the &as binding in vectors too + (cond + ((and (> (length match-form) 2) + (symbolp (aref match-form 0)) + (eq '&as (aref match-form 1))) + (let ((s (aref match-form 0))) + (cons (list s source) + (dash--match (dash--vector-tail match-form 2) s)))) + (t (dash--match-vector match-form source)))))) + +(defmacro -let* (varlist &rest body) + "Bind variables according to VARLIST then eval BODY. + +VARLIST is a list of lists of the form (PATTERN SOURCE). Each +PATTERN is matched against the SOURCE structurally. SOURCE is +only evaluated once for each PATTERN. + +Each SOURCE can refer to the symbols already bound by this +VARLIST. This is useful if you want to destructure SOURCE +recursively but also want to name the intermediate structures. + +See `-let' for the list of all possible patterns." + (declare (debug ((&rest (sexp form)) body)) + (indent 1)) + (let ((bindings (--mapcat (dash--match (car it) (cadr it)) varlist))) + `(let* ,bindings + ,@body))) + +(defmacro -let (varlist &rest body) + "Bind variables according to VARLIST then eval BODY. + +VARLIST is a list of lists of the form (PATTERN SOURCE). Each +PATTERN is matched against the SOURCE \"structurally\". SOURCE +is only evaluated once for each PATTERN. Each PATTERN is matched +recursively, and can therefore contain sub-patterns which are +matched against corresponding sub-expressions of SOURCE. + +All the SOURCEs are evalled before any symbols are +bound (i.e. \"in parallel\"). + +If VARLIST only contains one (PATTERN SOURCE) element, you can +optionally specify it using a vector and discarding the +outer-most parens. Thus + + (-let ((PATTERN SOURCE)) ..) + +becomes + + (-let [PATTERN SOURCE] ..). + +`-let' uses a convention of not binding places (symbols) starting +with _ whenever it's possible. You can use this to skip over +entries you don't care about. However, this is not *always* +possible (as a result of implementation) and these symbols might +get bound to undefined values. + +Following is the overview of supported patterns. Remember that +patterns can be matched recursively, so every a, b, aK in the +following can be a matching construct and not necessarily a +symbol/variable. + +Symbol: + + a - bind the SOURCE to A. This is just like regular `let'. + +Conses and lists: + + (a) - bind `car' of cons/list to A + + (a . b) - bind car of cons to A and `cdr' to B + + (a b) - bind car of list to A and `cadr' to B + + (a1 a2 a3 ...) - bind 0th car of list to A1, 1st to A2, 2nd to A3 ... + + (a1 a2 a3 ... aN . rest) - as above, but bind the Nth cdr to REST. + +Vectors: + + [a] - bind 0th element of a non-list sequence to A (works with + vectors, strings, bit arrays...) + + [a1 a2 a3 ...] - bind 0th element of non-list sequence to A0, 1st to + A1, 2nd to A2, ... + If the PATTERN is shorter than SOURCE, the values at + places not in PATTERN are ignored. + If the PATTERN is longer than SOURCE, an `error' is + thrown. + + [a1 a2 a3 ... &rest rest] - as above, but bind the rest of + the sequence to REST. This is + conceptually the same as improper list + matching (a1 a2 ... aN . rest) + +Key/value stores: + + (&plist key0 a0 ... keyN aN) - bind value mapped by keyK in the + SOURCE plist to aK. If the + value is not found, aK is nil. + + (&alist key0 a0 ... keyN aN) - bind value mapped by keyK in the + SOURCE alist to aK. If the + value is not found, aK is nil. + + (&hash key0 a0 ... keyN aN) - bind value mapped by keyK in the + SOURCE hash table to aK. If the + value is not found, aK is nil. + +Further, special keyword &keys supports \"inline\" matching of +plist-like key-value pairs, similarly to &keys keyword of +`cl-defun'. + + (a1 a2 ... aN &keys key1 b1 ... keyN bK) + +This binds N values from the list to a1 ... aN, then interprets +the cdr as a plist (see key/value matching above). + +You can name the source using the syntax SYMBOL &as PATTERN. +This syntax works with lists (proper or improper), vectors and +all types of maps. + + (list &as a b c) (list 1 2 3) + +binds A to 1, B to 2, C to 3 and LIST to (1 2 3). + +Similarly: + + (bounds &as beg . end) (cons 1 2) + +binds BEG to 1, END to 2 and BOUNDS to (1 . 2). + + (items &as first . rest) (list 1 2 3) + +binds FIRST to 1, REST to (2 3) and ITEMS to (1 2 3) + + [vect &as _ b c] [1 2 3] + +binds B to 2, C to 3 and VECT to [1 2 3] (_ avoids binding as usual). + + (plist &as &plist :b b) (list :a 1 :b 2 :c 3) + +binds B to 2 and PLIST to (:a 1 :b 2 :c 3). Same for &alist and &hash. + +This is especially useful when we want to capture the result of a +computation and destructure at the same time. Consider the +form (function-returning-complex-structure) returning a list of +two vectors with two items each. We want to capture this entire +result and pass it to another computation, but at the same time +we want to get the second item from each vector. We can achieve +it with pattern + + (result &as [_ a] [_ b]) (function-returning-complex-structure) + +Note: Clojure programmers may know this feature as the \":as +binding\". The difference is that we put the &as at the front +because we need to support improper list binding." + (declare (debug ([&or (&rest (sexp form)) + (vector [&rest [sexp form]])] + body)) + (indent 1)) + (if (vectorp varlist) + `(let* ,(dash--match (aref varlist 0) (aref varlist 1)) + ,@body) + (let* ((inputs (--map-indexed (list (make-symbol (format "input%d" it-index)) (cadr it)) varlist)) + (new-varlist (--map (list (caar it) (cadr it)) (-zip varlist inputs)))) + `(let ,inputs + (-let* ,new-varlist ,@body))))) + +(defmacro -lambda (match-form &rest body) + "Return a lambda which destructures its input as MATCH-FORM and executes BODY. + +Note that you have to enclose the MATCH-FORM in a pair of parens, +such that: + + (-lambda (x) body) + (-lambda (x y ...) body) + +has the usual semantics of `lambda'. Furthermore, these get +translated into normal lambda, so there is no performance +penalty. + +See `-let' for the description of destructuring mechanism." + (declare (doc-string 2) (indent defun) + (debug (&define sexp + [&optional stringp] + [&optional ("interactive" interactive)] + def-body))) + (cond + ((not (consp match-form)) + (signal 'wrong-type-argument "match-form must be a list")) + ;; no destructuring, so just return regular lambda to make things faster + ((-all? 'symbolp match-form) + `(lambda ,match-form ,@body)) + (t + (let* ((inputs (--map-indexed (list it (make-symbol (format "input%d" it-index))) match-form))) + ;; TODO: because inputs to the lambda are evaluated only once, + ;; -let* need not to create the extra bindings to ensure that. + ;; We should find a way to optimize that. Not critical however. + `(lambda ,(--map (cadr it) inputs) + (-let* ,inputs ,@body)))))) + +(defmacro -if-let* (vars-vals then &rest else) + "If all VALS evaluate to true, bind them to their corresponding +VARS and do THEN, otherwise do ELSE. VARS-VALS should be a list +of (VAR VAL) pairs. + +Note: binding is done according to `-let*'. VALS are evaluated +sequentially, and evaluation stops after the first nil VAL is +encountered." + (declare (debug ((&rest (sexp form)) form body)) + (indent 2)) + (->> vars-vals + (--mapcat (dash--match (car it) (cadr it))) + (--reduce-r-from + (let ((var (car it)) + (val (cadr it))) + `(let ((,var ,val)) + (if ,var ,acc ,@else))) + then))) + +(defmacro -if-let (var-val then &rest else) + "If VAL evaluates to non-nil, bind it to VAR and do THEN, +otherwise do ELSE. VAR-VAL should be a (VAR VAL) pair. + +Note: binding is done according to `-let'." + (declare (debug ((sexp form) form body)) + (indent 2)) + `(-if-let* (,var-val) ,then ,@else)) + +(defmacro --if-let (val then &rest else) + "If VAL evaluates to non-nil, bind it to `it' and do THEN, +otherwise do ELSE." + (declare (debug (form form body)) + (indent 2)) + `(-if-let (it ,val) ,then ,@else)) + +(defmacro -when-let* (vars-vals &rest body) + "If all VALS evaluate to true, bind them to their corresponding +VARS and execute body. VARS-VALS should be a list of (VAR VAL) +pairs. + +Note: binding is done according to `-let*'. VALS are evaluated +sequentially, and evaluation stops after the first nil VAL is +encountered." + (declare (debug ((&rest (sexp form)) body)) + (indent 1)) + `(-if-let* ,vars-vals (progn ,@body))) + +(defmacro -when-let (var-val &rest body) + "If VAL evaluates to non-nil, bind it to VAR and execute body. +VAR-VAL should be a (VAR VAL) pair. + +Note: binding is done according to `-let'." + (declare (debug ((sexp form) body)) + (indent 1)) + `(-if-let ,var-val (progn ,@body))) + +(defmacro --when-let (val &rest body) + "If VAL evaluates to non-nil, bind it to `it' and execute +body." + (declare (debug (form body)) + (indent 1)) + `(--if-let ,val (progn ,@body))) + +(defvar -compare-fn nil + "Tests for equality use this function or `equal' if this is nil. +It should only be set using dynamic scope with a let, like: + + (let ((-compare-fn #'=)) (-union numbers1 numbers2 numbers3)") + +(defun -distinct (list) + "Return a new list with all duplicates removed. +The test for equality is done with `equal', +or with `-compare-fn' if that's non-nil. + +Alias: `-uniq'" + (let (result) + (--each list (unless (-contains? result it) (!cons it result))) + (nreverse result))) + +(defalias '-uniq '-distinct) + +(defun -union (list list2) + "Return a new list containing the elements of LIST and elements of LIST2 that are not in LIST. +The test for equality is done with `equal', +or with `-compare-fn' if that's non-nil." + ;; We fall back to iteration implementation if the comparison + ;; function isn't one of `eq', `eql' or `equal'. + (let* ((result (reverse list)) + ;; TODO: get rid of this dynamic variable, pass it as an + ;; argument instead. + (-compare-fn (if (bound-and-true-p -compare-fn) + -compare-fn + 'equal))) + (if (memq -compare-fn '(eq eql equal)) + (let ((ht (make-hash-table :test -compare-fn))) + (--each list (puthash it t ht)) + (--each list2 (unless (gethash it ht) (!cons it result)))) + (--each list2 (unless (-contains? result it) (!cons it result)))) + (nreverse result))) + +(defun -intersection (list list2) + "Return a new list containing only the elements that are members of both LIST and LIST2. +The test for equality is done with `equal', +or with `-compare-fn' if that's non-nil." + (--filter (-contains? list2 it) list)) + +(defun -difference (list list2) + "Return a new list with only the members of LIST that are not in LIST2. +The test for equality is done with `equal', +or with `-compare-fn' if that's non-nil." + (--filter (not (-contains? list2 it)) list)) + +(defun -powerset (list) + "Return the power set of LIST." + (if (null list) '(()) + (let ((last (-powerset (cdr list)))) + (append (mapcar (lambda (x) (cons (car list) x)) last) + last)))) + +(defun -permutations (list) + "Return the permutations of LIST." + (if (null list) '(()) + (apply #'append + (mapcar (lambda (x) + (mapcar (lambda (perm) (cons x perm)) + (-permutations (remove x list)))) + list)))) + +(defun -contains? (list element) + "Return non-nil if LIST contains ELEMENT. + +The test for equality is done with `equal', or with `-compare-fn' +if that's non-nil. + +Alias: `-contains-p'" + (not + (null + (cond + ((null -compare-fn) (member element list)) + ((eq -compare-fn 'eq) (memq element list)) + ((eq -compare-fn 'eql) (memql element list)) + (t + (let ((lst list)) + (while (and lst + (not (funcall -compare-fn element (car lst)))) + (setq lst (cdr lst))) + lst)))))) + +(defalias '-contains-p '-contains?) + +(defun -same-items? (list list2) + "Return true if LIST and LIST2 has the same items. + +The order of the elements in the lists does not matter. + +Alias: `-same-items-p'" + (let ((length-a (length list)) + (length-b (length list2))) + (and + (= length-a length-b) + (= length-a (length (-intersection list list2)))))) + +(defalias '-same-items-p '-same-items?) + +(defun -is-prefix? (prefix list) + "Return non-nil if PREFIX is prefix of LIST. + +Alias: `-is-prefix-p'" + (declare (pure t) (side-effect-free t)) + (--each-while list (equal (car prefix) it) + (!cdr prefix)) + (not prefix)) + +(defun -is-suffix? (suffix list) + "Return non-nil if SUFFIX is suffix of LIST. + +Alias: `-is-suffix-p'" + (declare (pure t) (side-effect-free t)) + (-is-prefix? (reverse suffix) (reverse list))) + +(defun -is-infix? (infix list) + "Return non-nil if INFIX is infix of LIST. + +This operation runs in O(n^2) time + +Alias: `-is-infix-p'" + (declare (pure t) (side-effect-free t)) + (let (done) + (while (and (not done) list) + (setq done (-is-prefix? infix list)) + (!cdr list)) + done)) + +(defalias '-is-prefix-p '-is-prefix?) +(defalias '-is-suffix-p '-is-suffix?) +(defalias '-is-infix-p '-is-infix?) + +(defun -sort (comparator list) + "Sort LIST, stably, comparing elements using COMPARATOR. +Return the sorted list. LIST is NOT modified by side effects. +COMPARATOR is called with two elements of LIST, and should return non-nil +if the first element should sort before the second." + (sort (copy-sequence list) comparator)) + +(defmacro --sort (form list) + "Anaphoric form of `-sort'." + (declare (debug (form form))) + `(-sort (lambda (it other) ,form) ,list)) + +(defun -list (&rest args) + "Return a list with ARGS. + +If first item of ARGS is already a list, simply return ARGS. If +not, return a list with ARGS as elements." + (declare (pure t) (side-effect-free t)) + (let ((arg (car args))) + (if (listp arg) arg args))) + +(defun -repeat (n x) + "Return a list with X repeated N times. +Return nil if N is less than 1." + (declare (pure t) (side-effect-free t)) + (let (ret) + (--dotimes n (!cons x ret)) + ret)) + +(defun -sum (list) + "Return the sum of LIST." + (declare (pure t) (side-effect-free t)) + (apply '+ list)) + +(defun -product (list) + "Return the product of LIST." + (declare (pure t) (side-effect-free t)) + (apply '* list)) + +(defun -max (list) + "Return the largest value from LIST of numbers or markers." + (declare (pure t) (side-effect-free t)) + (apply 'max list)) + +(defun -min (list) + "Return the smallest value from LIST of numbers or markers." + (declare (pure t) (side-effect-free t)) + (apply 'min list)) + +(defun -max-by (comparator list) + "Take a comparison function COMPARATOR and a LIST and return +the greatest element of the list by the comparison function. + +See also combinator `-on' which can transform the values before +comparing them." + (--reduce (if (funcall comparator it acc) it acc) list)) + +(defun -min-by (comparator list) + "Take a comparison function COMPARATOR and a LIST and return +the least element of the list by the comparison function. + +See also combinator `-on' which can transform the values before +comparing them." + (--reduce (if (funcall comparator it acc) acc it) list)) + +(defmacro --max-by (form list) + "Anaphoric version of `-max-by'. + +The items for the comparator form are exposed as \"it\" and \"other\"." + (declare (debug (form form))) + `(-max-by (lambda (it other) ,form) ,list)) + +(defmacro --min-by (form list) + "Anaphoric version of `-min-by'. + +The items for the comparator form are exposed as \"it\" and \"other\"." + (declare (debug (form form))) + `(-min-by (lambda (it other) ,form) ,list)) + +(defun -iterate (fun init n) + "Return a list of iterated applications of FUN to INIT. + +This means a list of form: + + (init (fun init) (fun (fun init)) ...) + +N is the length of the returned list." + (if (= n 0) nil + (let ((r (list init))) + (--dotimes (1- n) + (push (funcall fun (car r)) r)) + (nreverse r)))) + +(defun -fix (fn list) + "Compute the (least) fixpoint of FN with initial input LIST. + +FN is called at least once, results are compared with `equal'." + (let ((re (funcall fn list))) + (while (not (equal list re)) + (setq list re) + (setq re (funcall fn re))) + re)) + +(defmacro --fix (form list) + "Anaphoric form of `-fix'." + `(-fix (lambda (it) ,form) ,list)) + +(defun -unfold (fun seed) + "Build a list from SEED using FUN. + +This is \"dual\" operation to `-reduce-r': while -reduce-r +consumes a list to produce a single value, `-unfold' takes a +seed value and builds a (potentially infinite!) list. + +FUN should return `nil' to stop the generating process, or a +cons (A . B), where A will be prepended to the result and B is +the new seed." + (let ((last (funcall fun seed)) r) + (while last + (push (car last) r) + (setq last (funcall fun (cdr last)))) + (nreverse r))) + +(defmacro --unfold (form seed) + "Anaphoric version of `-unfold'." + (declare (debug (form form))) + `(-unfold (lambda (it) ,form) ,seed)) + +(defun -cons-pair? (con) + "Return non-nil if CON is true cons pair. +That is (A . B) where B is not a list." + (declare (pure t) (side-effect-free t)) + (and (listp con) + (not (listp (cdr con))))) + +(defun -cons-to-list (con) + "Convert a cons pair to a list with `car' and `cdr' of the pair respectively." + (declare (pure t) (side-effect-free t)) + (list (car con) (cdr con))) + +(defun -value-to-list (val) + "Convert a value to a list. + +If the value is a cons pair, make a list with two elements, `car' +and `cdr' of the pair respectively. + +If the value is anything else, wrap it in a list." + (declare (pure t) (side-effect-free t)) + (cond + ((-cons-pair? val) (-cons-to-list val)) + (t (list val)))) + +(defun -tree-mapreduce-from (fn folder init-value tree) + "Apply FN to each element of TREE, and make a list of the results. +If elements of TREE are lists themselves, apply FN recursively to +elements of these nested lists. + +Then reduce the resulting lists using FOLDER and initial value +INIT-VALUE. See `-reduce-r-from'. + +This is the same as calling `-tree-reduce-from' after `-tree-map' +but is twice as fast as it only traverse the structure once." + (cond + ((not tree) nil) + ((-cons-pair? tree) (funcall fn tree)) + ((listp tree) + (-reduce-r-from folder init-value (mapcar (lambda (x) (-tree-mapreduce-from fn folder init-value x)) tree))) + (t (funcall fn tree)))) + +(defmacro --tree-mapreduce-from (form folder init-value tree) + "Anaphoric form of `-tree-mapreduce-from'." + (declare (debug (form form form form))) + `(-tree-mapreduce-from (lambda (it) ,form) (lambda (it acc) ,folder) ,init-value ,tree)) + +(defun -tree-mapreduce (fn folder tree) + "Apply FN to each element of TREE, and make a list of the results. +If elements of TREE are lists themselves, apply FN recursively to +elements of these nested lists. + +Then reduce the resulting lists using FOLDER and initial value +INIT-VALUE. See `-reduce-r-from'. + +This is the same as calling `-tree-reduce' after `-tree-map' +but is twice as fast as it only traverse the structure once." + (cond + ((not tree) nil) + ((-cons-pair? tree) (funcall fn tree)) + ((listp tree) + (-reduce-r folder (mapcar (lambda (x) (-tree-mapreduce fn folder x)) tree))) + (t (funcall fn tree)))) + +(defmacro --tree-mapreduce (form folder tree) + "Anaphoric form of `-tree-mapreduce'." + (declare (debug (form form form))) + `(-tree-mapreduce (lambda (it) ,form) (lambda (it acc) ,folder) ,tree)) + +(defun -tree-map (fn tree) + "Apply FN to each element of TREE while preserving the tree structure." + (cond + ((not tree) nil) + ((-cons-pair? tree) (funcall fn tree)) + ((listp tree) + (mapcar (lambda (x) (-tree-map fn x)) tree)) + (t (funcall fn tree)))) + +(defmacro --tree-map (form tree) + "Anaphoric form of `-tree-map'." + (declare (debug (form form))) + `(-tree-map (lambda (it) ,form) ,tree)) + +(defun -tree-reduce-from (fn init-value tree) + "Use FN to reduce elements of list TREE. +If elements of TREE are lists themselves, apply the reduction recursively. + +FN is first applied to INIT-VALUE and first element of the list, +then on this result and second element from the list etc. + +The initial value is ignored on cons pairs as they always contain +two elements." + (cond + ((not tree) nil) + ((-cons-pair? tree) tree) + ((listp tree) + (-reduce-r-from fn init-value (mapcar (lambda (x) (-tree-reduce-from fn init-value x)) tree))) + (t tree))) + +(defmacro --tree-reduce-from (form init-value tree) + "Anaphoric form of `-tree-reduce-from'." + (declare (debug (form form form))) + `(-tree-reduce-from (lambda (it acc) ,form) ,init-value ,tree)) + +(defun -tree-reduce (fn tree) + "Use FN to reduce elements of list TREE. +If elements of TREE are lists themselves, apply the reduction recursively. + +FN is first applied to first element of the list and second +element, then on this result and third element from the list etc. + +See `-reduce-r' for how exactly are lists of zero or one element handled." + (cond + ((not tree) nil) + ((-cons-pair? tree) tree) + ((listp tree) + (-reduce-r fn (mapcar (lambda (x) (-tree-reduce fn x)) tree))) + (t tree))) + +(defmacro --tree-reduce (form tree) + "Anaphoric form of `-tree-reduce'." + (declare (debug (form form))) + `(-tree-reduce (lambda (it acc) ,form) ,tree)) + +(defun -tree-map-nodes (pred fun tree) + "Call FUN on each node of TREE that satisfies PRED. + +If PRED returns nil, continue descending down this node. If PRED +returns non-nil, apply FUN to this node and do not descend +further." + (if (funcall pred tree) + (funcall fun tree) + (if (and (listp tree) + (not (-cons-pair? tree))) + (-map (lambda (x) (-tree-map-nodes pred fun x)) tree) + tree))) + +(defmacro --tree-map-nodes (pred form tree) + "Anaphoric form of `-tree-map-nodes'." + `(-tree-map-nodes (lambda (it) ,pred) (lambda (it) ,form) ,tree)) + +(defun -tree-seq (branch children tree) + "Return a sequence of the nodes in TREE, in depth-first search order. + +BRANCH is a predicate of one argument that returns non-nil if the +passed argument is a branch, that is, a node that can have children. + +CHILDREN is a function of one argument that returns the children +of the passed branch node. + +Non-branch nodes are simply copied." + (cons tree + (when (funcall branch tree) + (-mapcat (lambda (x) (-tree-seq branch children x)) + (funcall children tree))))) + +(defmacro --tree-seq (branch children tree) + "Anaphoric form of `-tree-seq'." + `(-tree-seq (lambda (it) ,branch) (lambda (it) ,children) ,tree)) + +(defun -clone (list) + "Create a deep copy of LIST. +The new list has the same elements and structure but all cons are +replaced with new ones. This is useful when you need to clone a +structure such as plist or alist." + (declare (pure t) (side-effect-free t)) + (-tree-map 'identity list)) + +(defun dash-enable-font-lock () + "Add syntax highlighting to dash functions, macros and magic values." + (eval-after-load 'lisp-mode + '(progn + (let ((new-keywords '( + "-each" + "--each" + "-each-indexed" + "--each-indexed" + "-each-while" + "--each-while" + "-dotimes" + "--dotimes" + "-map" + "--map" + "-reduce-from" + "--reduce-from" + "-reduce" + "--reduce" + "-reduce-r-from" + "--reduce-r-from" + "-reduce-r" + "--reduce-r" + "-filter" + "--filter" + "-select" + "--select" + "-remove" + "--remove" + "-reject" + "--reject" + "-remove-first" + "--remove-first" + "-reject-first" + "--reject-first" + "-remove-last" + "--remove-last" + "-reject-last" + "--reject-last" + "-remove-item" + "-non-nil" + "-keep" + "--keep" + "-map-indexed" + "--map-indexed" + "-splice" + "--splice" + "-splice-list" + "--splice-list" + "-map-when" + "--map-when" + "-replace-where" + "--replace-where" + "-map-first" + "--map-first" + "-map-last" + "--map-last" + "-replace" + "-replace-first" + "-replace-last" + "-flatten" + "-flatten-n" + "-concat" + "-mapcat" + "--mapcat" + "-copy" + "-cons*" + "-snoc" + "-first" + "--first" + "-find" + "--find" + "-some" + "--some" + "-any" + "--any" + "-last" + "--last" + "-first-item" + "-last-item" + "-butlast" + "-count" + "--count" + "-any?" + "--any?" + "-some?" + "--some?" + "-any-p" + "--any-p" + "-some-p" + "--some-p" + "-all?" + "--all?" + "-every?" + "--every?" + "-all-p" + "--all-p" + "-every-p" + "--every-p" + "-none?" + "--none?" + "-none-p" + "--none-p" + "-only-some?" + "--only-some?" + "-only-some-p" + "--only-some-p" + "-slice" + "-take" + "-drop" + "-take-while" + "--take-while" + "-drop-while" + "--drop-while" + "-split-at" + "-rotate" + "-insert-at" + "-replace-at" + "-update-at" + "--update-at" + "-remove-at" + "-remove-at-indices" + "-split-with" + "--split-with" + "-split-on" + "-split-when" + "--split-when" + "-separate" + "--separate" + "-partition-all-in-steps" + "-partition-in-steps" + "-partition-all" + "-partition" + "-partition-by" + "--partition-by" + "-partition-by-header" + "--partition-by-header" + "-group-by" + "--group-by" + "-interpose" + "-interleave" + "-zip-with" + "--zip-with" + "-zip" + "-zip-fill" + "-cycle" + "-pad" + "-annotate" + "--annotate" + "-table" + "-table-flat" + "-partial" + "-elem-index" + "-elem-indices" + "-find-indices" + "--find-indices" + "-find-index" + "--find-index" + "-find-last-index" + "--find-last-index" + "-select-by-indices" + "-select-columns" + "-select-column" + "-grade-up" + "-grade-down" + "->" + "->>" + "-->" + "-when-let" + "-when-let*" + "--when-let" + "-if-let" + "-if-let*" + "--if-let" + "-let*" + "-let" + "-lambda" + "-distinct" + "-uniq" + "-union" + "-intersection" + "-difference" + "-contains?" + "-contains-p" + "-same-items?" + "-same-items-p" + "-is-prefix-p" + "-is-prefix?" + "-is-suffix-p" + "-is-suffix?" + "-is-infix-p" + "-is-infix?" + "-sort" + "--sort" + "-list" + "-repeat" + "-sum" + "-product" + "-max" + "-min" + "-max-by" + "--max-by" + "-min-by" + "--min-by" + "-iterate" + "--iterate" + "-fix" + "--fix" + "-unfold" + "--unfold" + "-cons-pair?" + "-cons-to-list" + "-value-to-list" + "-tree-mapreduce-from" + "--tree-mapreduce-from" + "-tree-mapreduce" + "--tree-mapreduce" + "-tree-map" + "--tree-map" + "-tree-reduce-from" + "--tree-reduce-from" + "-tree-reduce" + "--tree-reduce" + "-tree-seq" + "--tree-seq" + "-tree-map-nodes" + "--tree-map-nodes" + "-clone" + "-rpartial" + "-juxt" + "-applify" + "-on" + "-flip" + "-const" + "-cut" + "-orfn" + "-andfn" + "-iteratefn" + "-fixfn" + "-prodfn" + )) + (special-variables '( + "it" + "it-index" + "acc" + "other" + ))) + (font-lock-add-keywords 'emacs-lisp-mode `((,(concat "\\_<" (regexp-opt special-variables 'paren) "\\_>") + 1 font-lock-variable-name-face)) 'append) + (font-lock-add-keywords 'emacs-lisp-mode `((,(concat "(\\s-*" (regexp-opt new-keywords 'paren) "\\_>") + 1 font-lock-keyword-face)) 'append)) + (--each (buffer-list) + (with-current-buffer it + (when (and (eq major-mode 'emacs-lisp-mode) + (boundp 'font-lock-mode) + font-lock-mode) + (font-lock-refresh-defaults))))))) + +(provide 'dash) +;;; dash.el ends here diff -Nru ddskk-16.2/doc/htmlize.el ddskk-16.2+0.20190423/doc/htmlize.el --- ddskk-16.2/doc/htmlize.el 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/htmlize.el 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,1924 @@ +;;; htmlize.el --- Convert buffer text and decorations to HTML. + +;; Copyright (C) 1997-2013 Hrvoje Niksic + +;; Author: Hrvoje Niksic +;; Keywords: hypermedia, extensions +;; Version: 1.43 + +;; This file is not part of GNU Emacs. + +;; 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 this program; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; This package converts the buffer text and the associated +;; decorations to HTML. Mail to to discuss +;; features and additions. All suggestions are more than welcome. + +;; To use it, just switch to the buffer you want HTML-ized and type +;; `M-x htmlize-buffer'. You will be switched to a new buffer that +;; contains the resulting HTML code. You can edit and inspect this +;; buffer, or you can just save it with C-x C-w. `M-x htmlize-file' +;; will find a file, fontify it, and save the HTML version in +;; FILE.html, without any additional intervention. `M-x +;; htmlize-many-files' allows you to htmlize any number of files in +;; the same manner. `M-x htmlize-many-files-dired' does the same for +;; files marked in a dired buffer. + +;; htmlize supports three types of HTML output, selected by setting +;; `htmlize-output-type': `css', `inline-css', and `font'. In `css' +;; mode, htmlize uses cascading style sheets to specify colors; it +;; generates classes that correspond to Emacs faces and uses ... to color parts of text. In this mode, the +;; produced HTML is valid under the 4.01 strict DTD, as confirmed by +;; the W3C validator. `inline-css' is like `css', except the CSS is +;; put directly in the STYLE attribute of the SPAN element, making it +;; possible to paste the generated HTML into existing HTML documents. +;; In `font' mode, htmlize uses ... to +;; colorize HTML, which is not standard-compliant, but works better in +;; older browsers. `css' mode is the default. + +;; You can also use htmlize from your Emacs Lisp code. When called +;; non-interactively, `htmlize-buffer' and `htmlize-region' will +;; return the resulting HTML buffer, but will not change current +;; buffer or move the point. htmlize will do its best to work on +;; non-windowing Emacs sessions but the result will be limited to +;; colors supported by the terminal. + +;; htmlize aims for compatibility with Emacsen version 21 and later. +;; Please let me know if it doesn't work on the version of XEmacs or +;; GNU Emacs that you are using. The package relies on the presence +;; of CL extensions, especially for cross-emacs compatibility; please +;; don't try to remove that dependency. I see no practical problems +;; with using the full power of the CL extensions, except that one +;; might learn to like them too much. + +;; The latest version is available as a git repository at: +;; +;; +;; +;; The snapshot of the latest release can be obtained at: +;; +;; +;; +;; You can find a sample of htmlize's output (possibly generated with +;; an older version) at: +;; +;; + +;; Thanks go to the many people who have sent reports and contributed +;; comments, suggestions, and fixes. They include Ron Gut, Bob +;; Weiner, Toni Drabik, Peter Breton, Ville Skytta, Thomas Vogels, +;; Juri Linkov, Maciek Pasternacki, and many others. + +;; User quotes: "You sir, are a sick, sick, _sick_ person. :)" +;; -- Bill Perry, author of Emacs/W3 + + +;;; Code: + +(require 'cl) +(eval-when-compile + (defvar unresolved) + (if (string-match "XEmacs" emacs-version) + (byte-compiler-options + (warnings (- unresolved)))) + (defvar font-lock-auto-fontify) + (defvar font-lock-support-mode) + (defvar global-font-lock-mode)) + +(defconst htmlize-version "1.43") + +(defgroup htmlize nil + "Convert buffer text and faces to HTML." + :group 'hypermedia) + +(defcustom htmlize-head-tags "" + "Additional tags to insert within HEAD of the generated document." + :type 'string + :group 'htmlize) + +(defcustom htmlize-output-type 'css + "Output type of generated HTML, one of `css', `inline-css', or `font'. +When set to `css' (the default), htmlize will generate a style sheet +with description of faces, and use it in the HTML document, specifying +the faces in the actual text with . + +When set to `inline-css', the style will be generated as above, but +placed directly in the STYLE attribute of the span ELEMENT: . This makes it easier to paste the resulting HTML to +other documents. + +When set to `font', the properties will be set using layout tags +, , , , and . + +`css' output is normally preferred, but `font' is still useful for +supporting old, pre-CSS browsers, and both `inline-css' and `font' for +easier embedding of colorized text in foreign HTML documents (no style +sheet to carry around)." + :type '(choice (const css) (const inline-css) (const font)) + :group 'htmlize) + +(defcustom htmlize-use-images t + "Whether htmlize generates `img' for images attached to buffer contents." + :type 'boolean + :group 'htmlize) + +(defcustom htmlize-force-inline-images nil + "Non-nil means generate all images inline using data URLs. +Normally htmlize converts image descriptors with :file properties to +relative URIs, and those with :data properties to data URIs. With this +flag set, the images specified as a file name are loaded into memory and +embedded in the HTML as data URIs." + :type 'boolean + :group 'htmlize) + +(defcustom htmlize-max-alt-text 100 + "Maximum size of text to use as ALT text in images. + +Normally when htmlize encounters text covered by the `display' property +that specifies an image, it generates an `alt' attribute containing the +original text. If the text is larger than `htmlize-max-alt-text' characters, +this will not be done.") + +(defcustom htmlize-transform-image 'htmlize-default-transform-image + "Function called to modify the image descriptor. + +The function is called with the image descriptor found in the buffer and +the text the image is supposed to replace. It should return a (possibly +different) image descriptor property list or a replacement string to use +instead of of the original buffer text. + +Returning nil is the same as returning the original text." + :type 'boolean + :group 'htmlize) + +(defcustom htmlize-generate-hyperlinks t + "Non-nil means auto-generate the links from URLs and mail addresses in buffer. + +This is on by default; set it to nil if you don't want htmlize to +autogenerate such links. Note that this option only turns off automatic +search for contents that looks like URLs and converting them to links. +It has no effect on whether htmlize respects the `htmlize-link' property." + :type 'boolean + :group 'htmlize) + +(defcustom htmlize-hyperlink-style " + a { + color: inherit; + background-color: inherit; + font: inherit; + text-decoration: inherit; + } + a:hover { + text-decoration: underline; + } +" + "The CSS style used for hyperlinks when in CSS mode." + :type 'string + :group 'htmlize) + +(defcustom htmlize-replace-form-feeds t + "Non-nil means replace form feeds in source code with HTML separators. +Form feeds are the ^L characters at line beginnings that are sometimes +used to separate sections of source code. If this variable is set to +`t', form feed characters are replaced with the
separator. If this +is a string, it specifies the replacement to use. Note that
 is
+temporarily closed before the separator is inserted, so the default
+replacement is effectively \"

\".  If you specify
+another replacement, don't forget to close and reopen the 
 if you
+want the output to remain valid HTML.
+
+If you need more elaborate processing, set this to nil and use
+htmlize-after-hook."
+  :type 'boolean
+  :group 'htmlize)
+
+(defcustom htmlize-html-charset nil
+  "The charset declared by the resulting HTML documents.
+When non-nil, causes htmlize to insert the following in the HEAD section
+of the generated HTML:
+
+  
+
+where CHARSET is the value you've set for htmlize-html-charset.  Valid
+charsets are defined by MIME and include strings like \"iso-8859-1\",
+\"iso-8859-15\", \"utf-8\", etc.
+
+If you are using non-Latin-1 charsets, you might need to set this for
+your documents to render correctly.  Also, the W3C validator requires
+submitted HTML documents to declare a charset.  So if you care about
+validation, you can use this to prevent the validator from bitching.
+
+Needless to say, if you set this, you should actually make sure that
+the buffer is in the encoding you're claiming it is in.  (This is
+normally achieved by using the correct file coding system for the
+buffer.)  If you don't understand what that means, you should probably
+leave this option in its default setting."
+  :type '(choice (const :tag "Unset" nil)
+		 string)
+  :group 'htmlize)
+
+(defcustom htmlize-convert-nonascii-to-entities t
+  "Whether non-ASCII characters should be converted to HTML entities.
+
+When this is non-nil, characters with codes in the 128-255 range will be
+considered Latin 1 and rewritten as \"&#CODE;\".  Characters with codes
+above 255 will be converted to \"&#UCS;\", where UCS denotes the Unicode
+code point of the character.  If the code point cannot be determined,
+the character will be copied unchanged, as would be the case if the
+option were nil.
+
+When the option is nil, the non-ASCII characters are copied to HTML
+without modification.  In that case, the web server and/or the browser
+must be set to understand the encoding that was used when saving the
+buffer.  (You might also want to specify it by setting
+`htmlize-html-charset'.)
+
+Note that in an HTML entity \"&#CODE;\", CODE is always a UCS code point,
+which has nothing to do with the charset the page is in.  For example,
+\"©\" *always* refers to the copyright symbol, regardless of charset
+specified by the META tag or the charset sent by the HTTP server.  In
+other words, \"©\" is exactly equivalent to \"©\".
+
+For most people htmlize will work fine with this option left at the
+default setting; don't change it unless you know what you're doing."
+  :type 'sexp
+  :group 'htmlize)
+
+(defcustom htmlize-ignore-face-size 'absolute
+  "Whether face size should be ignored when generating HTML.
+If this is nil, face sizes are used.  If set to t, sizes are ignored
+If set to `absolute', only absolute size specifications are ignored.
+Please note that font sizes only work with CSS-based output types."
+  :type '(choice (const :tag "Don't ignore" nil)
+		 (const :tag "Ignore all" t)
+		 (const :tag "Ignore absolute" absolute))
+  :group 'htmlize)
+
+(defcustom htmlize-css-name-prefix ""
+  "The prefix used for CSS names.
+The CSS names that htmlize generates from face names are often too
+generic for CSS files; for example, `font-lock-type-face' is transformed
+to `type'.  Use this variable to add a prefix to the generated names.
+The string \"htmlize-\" is an example of a reasonable prefix."
+  :type 'string
+  :group 'htmlize)
+
+(defcustom htmlize-use-rgb-txt t
+  "Whether `rgb.txt' should be used to convert color names to RGB.
+
+This conversion means determining, for instance, that the color
+\"IndianRed\" corresponds to the (205, 92, 92) RGB triple.  `rgb.txt'
+is the X color database that maps hundreds of color names to such RGB
+triples.  When this variable is non-nil, `htmlize' uses `rgb.txt' to
+look up color names.
+
+If this variable is nil, htmlize queries Emacs for RGB components of
+colors using `color-instance-rgb-components' and `color-values'.
+This can yield incorrect results on non-true-color displays.
+
+If the `rgb.txt' file is not found (which will be the case if you're
+running Emacs on non-X11 systems), this option is ignored."
+  :type 'boolean
+  :group 'htmlize)
+
+(defcustom htmlize-html-major-mode nil
+  "The mode the newly created HTML buffer will be put in.
+Set this to nil if you prefer the default (fundamental) mode."
+  :type '(radio (const :tag "No mode (fundamental)" nil)
+		 (function-item html-mode)
+		 (function :tag "User-defined major mode"))
+  :group 'htmlize)
+
+(defvar htmlize-before-hook nil
+  "Hook run before htmlizing a buffer.
+The hook functions are run in the source buffer (not the resulting HTML
+buffer).")
+
+(defvar htmlize-after-hook nil
+  "Hook run after htmlizing a buffer.
+Unlike `htmlize-before-hook', these functions are run in the generated
+HTML buffer.  You may use them to modify the outlook of the final HTML
+output.")
+
+(defvar htmlize-file-hook nil
+  "Hook run by `htmlize-file' after htmlizing a file, but before saving it.")
+
+(defvar htmlize-buffer-places)
+
+;;; Some cross-Emacs compatibility.
+
+;; I try to conditionalize on features rather than Emacs version, but
+;; in some cases checking against the version *is* necessary.
+(defconst htmlize-running-xemacs (string-match "XEmacs" emacs-version))
+
+;; We need a function that efficiently finds the next change of a
+;; property regardless of whether the change occurred because of a
+;; text property or an extent/overlay.
+(cond
+ (htmlize-running-xemacs
+  (defun htmlize-next-change (pos prop &optional limit)
+    (if prop
+        (next-single-char-property-change pos prop nil (or limit (point-max)))
+      (next-property-change pos nil (or limit (point-max)))))
+  (defun htmlize-next-face-change (pos &optional limit)
+    (htmlize-next-change pos 'face limit)))
+ ((fboundp 'next-single-char-property-change)
+  ;; GNU Emacs 21+
+  (defun htmlize-next-change (pos prop &optional limit)
+    (if prop
+        (next-single-char-property-change pos prop nil limit)
+      (next-char-property-change pos limit)))
+  (defun htmlize-overlay-faces-at (pos)
+    (delq nil (mapcar (lambda (o) (overlay-get o 'face)) (overlays-at pos))))
+  (defun htmlize-next-face-change (pos &optional limit)
+    ;; (htmlize-next-change pos 'face limit) would skip over entire
+    ;; overlays that specify the `face' property, even when they
+    ;; contain smaller text properties that also specify `face'.
+    ;; Emacs display engine merges those faces, and so must we.
+    (or limit
+        (setq limit (point-max)))
+    (let ((next-prop (next-single-property-change pos 'face nil limit))
+          (overlay-faces (htmlize-overlay-faces-at pos)))
+      (while (progn
+               (setq pos (next-overlay-change pos))
+               (and (< pos next-prop)
+                    (equal overlay-faces (htmlize-overlay-faces-at pos)))))
+      (setq pos (min pos next-prop))
+      ;; Additionally, we include the entire region that specifies the
+      ;; `display' property.
+      (when (get-char-property pos 'display)
+        (setq pos (next-single-char-property-change pos 'display nil limit)))
+      pos)))
+ (t
+  (error "htmlize requires next-single-property-change or \
+next-single-char-property-change")))
+
+(defmacro htmlize-lexlet (&rest letforms)
+  (declare (indent 1) (debug let))
+  (if (and (boundp 'lexical-binding)
+           lexical-binding)
+      `(let ,@letforms)
+    ;; cl extensions have a macro implementing lexical let
+    `(lexical-let ,@letforms)))
+
+;; Simple overlay emulation for XEmacs
+
+(cond
+ (htmlize-running-xemacs
+  (defalias 'htmlize-make-overlay 'make-extent)
+  (defalias 'htmlize-overlay-put 'set-extent-property)
+  (defalias 'htmlize-overlay-get 'extent-property)
+  (defun htmlize-overlays-in (beg end) (extent-list nil beg end))
+  (defalias 'htmlize-delete-overlay 'detach-extent))
+ (t
+  (defalias 'htmlize-make-overlay 'make-overlay)
+  (defalias 'htmlize-overlay-put 'overlay-put)
+  (defalias 'htmlize-overlay-get 'overlay-get)
+  (defalias 'htmlize-overlays-in 'overlays-in)
+  (defalias 'htmlize-delete-overlay 'delete-overlay)))
+
+
+;;; Transformation of buffer text: HTML escapes, untabification, etc.
+
+(defvar htmlize-basic-character-table
+  ;; Map characters in the 0-127 range to either one-character strings
+  ;; or to numeric entities.
+  (let ((table (make-vector 128 ?\0)))
+    ;; Map characters in the 32-126 range to themselves, others to
+    ;; &#CODE entities;
+    (dotimes (i 128)
+      (setf (aref table i) (if (and (>= i 32) (<= i 126))
+			       (char-to-string i)
+			     (format "&#%d;" i))))
+    ;; Set exceptions manually.
+    (setf
+     ;; Don't escape newline, carriage return, and TAB.
+     (aref table ?\n) "\n"
+     (aref table ?\r) "\r"
+     (aref table ?\t) "\t"
+     ;; Escape &, <, and >.
+     (aref table ?&) "&"
+     (aref table ?<) "<"
+     (aref table ?>) ">"
+     ;; Not escaping '"' buys us a measurable speedup.  It's only
+     ;; necessary to quote it for strings used in attribute values,
+     ;; which htmlize doesn't typically do.
+     ;(aref table ?\") """
+     )
+    table))
+
+;; A cache of HTML representation of non-ASCII characters.  Depending
+;; on the setting of `htmlize-convert-nonascii-to-entities', this maps
+;; non-ASCII characters to either "&#;" or "" (mapconcat's
+;; mapper must always return strings).  It's only filled as characters
+;; are encountered, so that in a buffer with e.g. French text, it will
+;; only ever contain French accented characters as keys.  It's cleared
+;; on each entry to htmlize-buffer-1 to allow modifications of
+;; `htmlize-convert-nonascii-to-entities' to take effect.
+(defvar htmlize-extended-character-cache (make-hash-table :test 'eq))
+
+(defun htmlize-protect-string (string)
+  "HTML-protect string, escaping HTML metacharacters and I18N chars."
+  ;; Only protecting strings that actually contain unsafe or non-ASCII
+  ;; chars removes a lot of unnecessary funcalls and consing.
+  (if (not (string-match "[^\r\n\t -%'-;=?-~]" string))
+      string
+    (mapconcat (lambda (char)
+		 (cond
+		  ((< char 128)
+		   ;; ASCII: use htmlize-basic-character-table.
+		   (aref htmlize-basic-character-table char))
+		  ((gethash char htmlize-extended-character-cache)
+		   ;; We've already seen this char; return the cached
+		   ;; string.
+		   )
+		  ((not htmlize-convert-nonascii-to-entities)
+		   ;; If conversion to entities is not desired, always
+		   ;; copy the char literally.
+		   (setf (gethash char htmlize-extended-character-cache)
+			 (char-to-string char)))
+		  ((< char 256)
+		   ;; Latin 1: no need to call encode-char.
+		   (setf (gethash char htmlize-extended-character-cache)
+			 (format "&#%d;" char)))
+		  ((encode-char char 'ucs)
+                   ;; Must check if encode-char works for CHAR;
+                   ;; it fails for Arabic and possibly elsewhere.
+		   (setf (gethash char htmlize-extended-character-cache)
+			 (format "&#%d;" (encode-char char 'ucs))))
+		  (t
+		   ;; encode-char doesn't work for this char.  Copy it
+		   ;; unchanged and hope for the best.
+		   (setf (gethash char htmlize-extended-character-cache)
+			 (char-to-string char)))))
+	       string "")))
+
+(defun htmlize-attr-escape (string)
+  ;; Like htmlize-protect-string, but also escapes double-quoted
+  ;; strings to make it usable in attribute values.
+  (setq string (htmlize-protect-string string))
+  (if (not (string-match "\"" string))
+      string
+    (mapconcat (lambda (char)
+                 (if (eql char ?\")
+                     """
+                   (char-to-string char)))
+               string "")))
+
+(defsubst htmlize-concat (list)
+  (if (and (consp list) (null (cdr list)))
+      ;; Don't create a new string in the common case where the list only
+      ;; consists of one element.
+      (car list)
+    (apply #'concat list)))
+
+(defun htmlize-format-link (linkprops text)
+  (let ((uri (if (stringp linkprops)
+                 linkprops
+               (plist-get linkprops :uri)))
+        (escaped-text (htmlize-protect-string text)))
+    (if uri
+        (format "%s" (htmlize-attr-escape uri) escaped-text)
+      escaped-text)))
+
+(defun htmlize-escape-or-link (string)
+  ;; Escape STRING and/or add hyperlinks.  STRING comes from a
+  ;; `display' property.
+  (let ((pos 0) (end (length string)) outlist)
+    (while (< pos end)
+      (let* ((link (get-char-property pos 'htmlize-link string))
+             (next-link-change (next-single-property-change
+                                pos 'htmlize-link string end))
+             (chunk (substring string pos next-link-change)))
+        (push
+         (cond (link
+                (htmlize-format-link link chunk))
+               ((get-char-property 0 'htmlize-literal chunk)
+                chunk)
+               (t
+                (htmlize-protect-string chunk)))
+         outlist)
+        (setq pos next-link-change)))
+    (htmlize-concat (nreverse outlist))))
+
+(defun htmlize-display-prop-to-html (display text)
+  (let (desc)
+    (cond ((stringp display)
+           ;; Emacs ignores recursive display properties.
+           (htmlize-escape-or-link display))
+          ((not (eq (car-safe display) 'image))
+           (htmlize-protect-string text))
+          ((null (setq desc (funcall htmlize-transform-image
+                                     (cdr display) text)))
+           (htmlize-escape-or-link text))
+          ((stringp desc)
+           (htmlize-escape-or-link desc))
+          (t
+           (htmlize-generate-image desc text)))))
+
+(defun htmlize-string-to-html (string)
+  ;; Convert the string to HTML, including images attached as
+  ;; `display' property and links as `htmlize-link' property.  In a
+  ;; string without images or links, this is equivalent to
+  ;; `htmlize-protect-string'.
+  (let ((pos 0) (end (length string)) outlist)
+    (while (< pos end)
+      (let* ((display (get-char-property pos 'display string))
+             (next-display-change (next-single-property-change
+                                   pos 'display string end))
+             (chunk (substring string pos next-display-change)))
+        (push
+         (if display
+             (htmlize-display-prop-to-html display chunk)
+           (htmlize-escape-or-link chunk))
+         outlist)
+        (setq pos next-display-change)))
+    (htmlize-concat (nreverse outlist))))
+
+(defun htmlize-default-transform-image (imgprops _text)
+  "Default transformation of image descriptor to something usable in HTML.
+
+If `htmlize-use-images' is nil, the function always returns nil, meaning
+use original text.  Otherwise, it tries to find the image for images that
+specify a file name.  If `htmlize-force-inline-images' is non-nil, it also
+converts the :file attribute to :data and returns the modified property
+list."
+  (when htmlize-use-images
+    (when (plist-get imgprops :file)
+      (let ((location (plist-get (cdr (find-image (list imgprops))) :file)))
+        (when location
+          (setq imgprops (plist-put (copy-list imgprops) :file location)))))
+    (if htmlize-force-inline-images
+        (let ((location (plist-get imgprops :file))
+              data)
+          (when location
+            (with-temp-buffer
+              (condition-case nil
+                  (progn
+                    (insert-file-contents-literally location)
+                    (setq data (buffer-string)))
+                (error nil))))
+          ;; if successful, return the new plist, otherwise return
+          ;; nil, which will use the original text
+          (and data
+               (plist-put (plist-put imgprops :file nil)
+                          :data data)))
+      imgprops)))
+
+(defun htmlize-alt-text (_imgprops origtext)
+  (and (/= (length origtext) 0)
+       (<= (length origtext) htmlize-max-alt-text)
+       (not (string-match "[\0-\x1f]" origtext))
+       origtext))
+
+(defun htmlize-generate-image (imgprops origtext)
+  (let* ((alt-text (htmlize-alt-text imgprops origtext))
+         (alt-attr (if alt-text
+                       (format " alt=\"%s\"" (htmlize-attr-escape alt-text))
+                     "")))
+    (cond ((plist-get imgprops :file)
+           ;; Try to find the image in image-load-path
+           (let* ((found-props (cdr (find-image (list imgprops))))
+                  (file (or (plist-get found-props :file)
+                            (plist-get imgprops :file))))
+             (format ""
+                     (htmlize-attr-escape (file-relative-name file))
+                     alt-attr)))
+          ((plist-get imgprops :data)
+	   (if (equalp (plist-get imgprops :type) 'svg)
+	       (plist-get imgprops :data)
+	     (format ""
+		     (or (plist-get imgprops :type) "")
+		     (base64-encode-string (plist-get imgprops :data))
+		     alt-attr))))))
+
+(defconst htmlize-ellipsis "...")
+(put-text-property 0 (length htmlize-ellipsis) 'htmlize-ellipsis t htmlize-ellipsis)
+
+(defun htmlize-match-inv-spec (inv)
+  (member* inv buffer-invisibility-spec
+           :key (lambda (i)
+                  (if (symbolp i) i (car i)))))
+
+(defun htmlize-decode-invisibility-spec (invisible)
+  ;; Return t, nil, or `ellipsis', depending on how invisible text should be inserted.
+
+  (if (not (listp buffer-invisibility-spec))
+      ;; If buffer-invisibility-spec is not a list, then all
+      ;; characters with non-nil `invisible' property are visible.
+      (not invisible)
+
+    ;; Otherwise, the value of a non-nil `invisible' property can be:
+    ;; 1. a symbol -- make the text invisible if it matches
+    ;;    buffer-invisibility-spec.
+    ;; 2. a list of symbols -- make the text invisible if
+    ;;    any symbol in the list matches
+    ;;    buffer-invisibility-spec.
+    ;; If the match of buffer-invisibility-spec has a non-nil
+    ;; CDR, replace the invisible text with an ellipsis.
+    (let ((match (if (symbolp invisible)
+                     (htmlize-match-inv-spec invisible)
+                   (some #'htmlize-match-inv-spec invisible))))
+      (cond ((null match) t)
+            ((cdr-safe (car match)) 'ellipsis)
+            (t nil)))))
+
+(defun htmlize-add-before-after-strings (beg end text)
+  ;; Find overlays specifying before-string and after-string in [beg,
+  ;; pos).  If any are found, splice them into TEXT and return the new
+  ;; text.
+  (let (additions)
+    (dolist (overlay (overlays-in beg end))
+      (let ((before (overlay-get overlay 'before-string))
+            (after (overlay-get overlay 'after-string)))
+        (when after
+          (push (cons (- (overlay-end overlay) beg)
+                      after)
+                additions))
+        (when before
+          (push (cons (- (overlay-start overlay) beg)
+                      before)
+                additions))))
+    (if additions
+        (let ((textlist nil)
+              (strpos 0))
+          (dolist (add (stable-sort additions #'< :key #'car))
+            (let ((addpos (car add))
+                  (addtext (cdr add)))
+              (push (substring text strpos addpos) textlist)
+              (push addtext textlist)
+              (setq strpos addpos)))
+          (push (substring text strpos) textlist)
+          (apply #'concat (nreverse textlist)))
+      text)))
+
+(defun htmlize-copy-prop (prop beg end string)
+  ;; Copy the specified property from the specified region of the
+  ;; buffer to the target string.  We cannot rely on Emacs to copy the
+  ;; property because we want to handle properties coming from both
+  ;; text properties and overlays.
+  (let ((pos beg))
+    (while (< pos end)
+      (let ((value (get-char-property pos prop))
+            (next-change (htmlize-next-change pos prop end)))
+        (when value
+          (put-text-property (- pos beg) (- next-change beg)
+                             prop value string))
+        (setq pos next-change)))))
+
+(defun htmlize-get-text-with-display (beg end)
+  ;; Like buffer-substring-no-properties, except it copies the
+  ;; `display' property from the buffer, if found.
+  (let ((text (buffer-substring-no-properties beg end)))
+    (htmlize-copy-prop 'display beg end text)
+    (htmlize-copy-prop 'htmlize-link beg end text)
+    (unless htmlize-running-xemacs
+      (setq text (htmlize-add-before-after-strings beg end text)))
+    text))
+
+(defun htmlize-buffer-substring-no-invisible (beg end)
+  ;; Like buffer-substring-no-properties, but don't copy invisible
+  ;; parts of the region.  Where buffer-substring-no-properties
+  ;; mandates an ellipsis to be shown, htmlize-ellipsis is inserted.
+  (let ((pos beg)
+	visible-list invisible show last-show next-change)
+    ;; Iterate over the changes in the `invisible' property and filter
+    ;; out the portions where it's non-nil, i.e. where the text is
+    ;; invisible.
+    (while (< pos end)
+      (setq invisible (get-char-property pos 'invisible)
+	    next-change (htmlize-next-change pos 'invisible end)
+            show (htmlize-decode-invisibility-spec invisible))
+      (cond ((eq show t)
+	     (push (htmlize-get-text-with-display pos next-change)
+                   visible-list))
+            ((and (eq show 'ellipsis)
+                  (not (eq last-show 'ellipsis))
+                  ;; Conflate successive ellipses.
+                  (push htmlize-ellipsis visible-list))))
+      (setq pos next-change last-show show))
+    (htmlize-concat (nreverse visible-list))))
+
+(defun htmlize-trim-ellipsis (text)
+  ;; Remove htmlize-ellipses ("...") from the beginning of TEXT if it
+  ;; starts with it.  It checks for the special property of the
+  ;; ellipsis so it doesn't work on ordinary text that begins with
+  ;; "...".
+  (if (get-text-property 0 'htmlize-ellipsis text)
+      (substring text (length htmlize-ellipsis))
+    text))
+
+(defconst htmlize-tab-spaces
+  ;; A table of strings with spaces.  (aref htmlize-tab-spaces 5) is
+  ;; like (make-string 5 ?\ ), except it doesn't cons.
+  (let ((v (make-vector 32 nil)))
+    (dotimes (i (length v))
+      (setf (aref v i) (make-string i ?\ )))
+    v))
+
+(defun htmlize-untabify (text start-column)
+  "Untabify TEXT, assuming it starts at START-COLUMN."
+  (let ((column start-column)
+	(last-match 0)
+	(chunk-start 0)
+	chunks match-pos tab-size)
+    (while (string-match "[\t\n]" text last-match)
+      (setq match-pos (match-beginning 0))
+      (cond ((eq (aref text match-pos) ?\t)
+	     ;; Encountered a tab: create a chunk of text followed by
+	     ;; the expanded tab.
+	     (push (substring text chunk-start match-pos) chunks)
+	     ;; Increase COLUMN by the length of the text we've
+	     ;; skipped since last tab or newline.  (Encountering
+	     ;; newline resets it.)
+	     (incf column (- match-pos last-match))
+	     ;; Calculate tab size based on tab-width and COLUMN.
+	     (setq tab-size (- tab-width (% column tab-width)))
+	     ;; Expand the tab, carefully recreating the `display'
+	     ;; property if one was on the TAB.
+             (let ((display (get-text-property match-pos 'display text))
+                   (expanded-tab (aref htmlize-tab-spaces tab-size)))
+               (when display
+                 (put-text-property 0 tab-size 'display display expanded-tab))
+               (push expanded-tab chunks))
+	     (incf column tab-size)
+	     (setq chunk-start (1+ match-pos)))
+	    (t
+	     ;; Reset COLUMN at beginning of line.
+	     (setq column 0)))
+      (setq last-match (1+ match-pos)))
+    ;; If no chunks have been allocated, it means there have been no
+    ;; tabs to expand.  Return TEXT unmodified.
+    (if (null chunks)
+	text
+      (when (< chunk-start (length text))
+	;; Push the remaining chunk.
+	(push (substring text chunk-start) chunks))
+      ;; Generate the output from the available chunks.
+      (htmlize-concat (nreverse chunks)))))
+
+(defun htmlize-extract-text (beg end trailing-ellipsis)
+  ;; Extract buffer text, sans the invisible parts.  Then
+  ;; untabify it and escape the HTML metacharacters.
+  (let ((text (htmlize-buffer-substring-no-invisible beg end)))
+    (when trailing-ellipsis
+      (setq text (htmlize-trim-ellipsis text)))
+    ;; If TEXT ends up empty, don't change trailing-ellipsis.
+    (when (> (length text) 0)
+      (setq trailing-ellipsis
+            (get-text-property (1- (length text))
+                               'htmlize-ellipsis text)))
+    (setq text (htmlize-untabify text (current-column)))
+    (setq text (htmlize-string-to-html text))
+    (values text trailing-ellipsis)))
+
+(defun htmlize-despam-address (string)
+  "Replace every occurrence of '@' in STRING with %40.
+This is used to protect mailto links without modifying their meaning."
+  ;; Suggested by Ville Skytta.
+  (while (string-match "@" string)
+    (setq string (replace-match "%40" nil t string)))
+  string)
+
+(defun htmlize-make-tmp-overlay (beg end props)
+  (let ((overlay (htmlize-make-overlay beg end)))
+    (htmlize-overlay-put overlay 'htmlize-tmp-overlay t)
+    (while props
+      (htmlize-overlay-put overlay (pop props) (pop props)))
+    overlay))
+
+(defun htmlize-delete-tmp-overlays ()
+  (dolist (overlay (htmlize-overlays-in (point-min) (point-max)))
+    (when (htmlize-overlay-get overlay 'htmlize-tmp-overlay)
+      (htmlize-delete-overlay overlay))))
+
+(defun htmlize-make-link-overlay (beg end uri)
+  (htmlize-make-tmp-overlay beg end `(htmlize-link (:uri ,uri))))
+
+(defun htmlize-create-auto-links ()
+  "Add `htmlize-link' property to all mailto links in the buffer."
+  (save-excursion
+    (goto-char (point-min))
+    (while (re-search-forward
+            "<\\(\\(mailto:\\)?\\([-=+_.a-zA-Z0-9]+@[-_.a-zA-Z0-9]+\\)\\)>"
+            nil t)
+      (let* ((address (match-string 3))
+             (beg (match-beginning 0)) (end (match-end 0))
+             (uri (concat "mailto:" (htmlize-despam-address address))))
+        (htmlize-make-link-overlay beg end uri)))
+    (goto-char (point-min))
+    (while (re-search-forward "<\\(\\(URL:\\)?\\([a-zA-Z]+://[^;>]+\\)\\)>"
+                              nil t)
+      (htmlize-make-link-overlay
+       (match-beginning 0) (match-end 0) (match-string 3)))))
+
+;; Tests for htmlize-create-auto-links:
+
+;; 
+;; 
+;; 
+;; 
+;; 
+;; 
+
+(defun htmlize-shadow-form-feeds ()
+  (let ((s "\n
")) + (put-text-property 0 (length s) 'htmlize-literal t s) + (let ((disp `(display ,s))) + (while (re-search-forward "\n\^L" nil t) + (htmlize-make-tmp-overlay (match-beginning 0) (match-end 0) disp))))) + +(defun htmlize-defang-local-variables () + ;; Juri Linkov reports that an HTML-ized "Local variables" can lead + ;; visiting the HTML to fail with "Local variables list is not + ;; properly terminated". He suggested changing the phrase to + ;; syntactically equivalent HTML that Emacs doesn't recognize. + (goto-char (point-min)) + (while (search-forward "Local Variables:" nil t) + (replace-match "Local Variables:" nil t))) + + +;;; Color handling. + +(defvar htmlize-x-library-search-path + `(,data-directory + "/etc/X11/rgb.txt" + "/usr/share/X11/rgb.txt" + ;; the remainder of this list really belongs in a museum + "/usr/X11R6/lib/X11/" + "/usr/X11R5/lib/X11/" + "/usr/lib/X11R6/X11/" + "/usr/lib/X11R5/X11/" + "/usr/local/X11R6/lib/X11/" + "/usr/local/X11R5/lib/X11/" + "/usr/local/lib/X11R6/X11/" + "/usr/local/lib/X11R5/X11/" + "/usr/X11/lib/X11/" + "/usr/lib/X11/" + "/usr/local/lib/X11/" + "/usr/X386/lib/X11/" + "/usr/x386/lib/X11/" + "/usr/XFree86/lib/X11/" + "/usr/unsupported/lib/X11/" + "/usr/athena/lib/X11/" + "/usr/local/x11r5/lib/X11/" + "/usr/lpp/Xamples/lib/X11/" + "/usr/openwin/lib/X11/" + "/usr/openwin/share/lib/X11/")) + +(defun htmlize-get-color-rgb-hash (&optional rgb-file) + "Return a hash table mapping X color names to RGB values. +The keys in the hash table are X11 color names, and the values are the +#rrggbb RGB specifications, extracted from `rgb.txt'. + +If RGB-FILE is nil, the function will try hard to find a suitable file +in the system directories. + +If no rgb.txt file is found, return nil." + (let ((rgb-file (or rgb-file (locate-file + "rgb.txt" + htmlize-x-library-search-path))) + (hash nil)) + (when rgb-file + (with-temp-buffer + (insert-file-contents rgb-file) + (setq hash (make-hash-table :test 'equal)) + (while (not (eobp)) + (cond ((looking-at "^\\s-*\\([!#]\\|$\\)") + ;; Skip comments and empty lines. + ) + ((looking-at + "[ \t]*\\([0-9]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\(.*\\)") + (setf (gethash (downcase (match-string 4)) hash) + (format "#%02x%02x%02x" + (string-to-number (match-string 1)) + (string-to-number (match-string 2)) + (string-to-number (match-string 3))))) + (t + (error + "Unrecognized line in %s: %s" + rgb-file + (buffer-substring (point) (progn (end-of-line) (point)))))) + (forward-line 1)))) + hash)) + +;; Compile the RGB map when loaded. On systems where rgb.txt is +;; missing, the value of the variable will be nil, and rgb.txt will +;; not be used. +(defvar htmlize-color-rgb-hash (htmlize-get-color-rgb-hash)) + +;;; Face handling. + +(defun htmlize-face-specifies-property (face prop) + ;; Return t if face specifies PROP, as opposed to it being inherited + ;; from the default face. The problem with e.g. + ;; `face-foreground-instance' is that it returns an instance for + ;; EVERY face because every face inherits from the default face. + ;; However, we'd like htmlize-face-{fore,back}ground to return nil + ;; when called with a face that doesn't specify its own foreground + ;; or background. + (or (eq face 'default) + (assq 'global (specifier-spec-list (face-property face prop))))) + +(defun htmlize-face-color-internal (face fg) + ;; Used only under GNU Emacs. Return the color of FACE, but don't + ;; return "unspecified-fg" or "unspecified-bg". If the face is + ;; `default' and the color is unspecified, look up the color in + ;; frame parameters. + (let* ((function (if fg #'face-foreground #'face-background)) + color) + (setq color (funcall function face nil t)) + (when (and (eq face 'default) (null color)) + (setq color (cdr (assq (if fg 'foreground-color 'background-color) + (frame-parameters))))) + (when (or (eq color 'unspecified) + (equal color "unspecified-fg") + (equal color "unspecified-bg")) + (setq color nil)) + (when (and (eq face 'default) + (null color)) + ;; Assuming black on white doesn't seem right, but I can't think + ;; of anything better to do. + (setq color (if fg "black" "white"))) + color)) + +(defun htmlize-face-foreground (face) + ;; Return the name of the foreground color of FACE. If FACE does + ;; not specify a foreground color, return nil. + (cond (htmlize-running-xemacs + ;; XEmacs. + (and (htmlize-face-specifies-property face 'foreground) + (color-instance-name (face-foreground-instance face)))) + (t + ;; GNU Emacs. + (htmlize-face-color-internal face t)))) + +(defun htmlize-face-background (face) + ;; Return the name of the background color of FACE. If FACE does + ;; not specify a background color, return nil. + (cond (htmlize-running-xemacs + ;; XEmacs. + (and (htmlize-face-specifies-property face 'background) + (color-instance-name (face-background-instance face)))) + (t + ;; GNU Emacs. + (htmlize-face-color-internal face nil)))) + +;; Convert COLOR to the #RRGGBB string. If COLOR is already in that +;; format, it's left unchanged. + +(defun htmlize-color-to-rgb (color) + (let ((rgb-string nil)) + (cond ((null color) + ;; Ignore nil COLOR because it means that the face is not + ;; specifying any color. Hence (htmlize-color-to-rgb nil) + ;; returns nil. + ) + ((string-match "\\`#" color) + ;; The color is already in #rrggbb format. + (setq rgb-string color)) + ((and htmlize-use-rgb-txt + htmlize-color-rgb-hash) + ;; Use of rgb.txt is requested, and it's available on the + ;; system. Use it. + (setq rgb-string (gethash (downcase color) htmlize-color-rgb-hash))) + (t + ;; We're getting the RGB components from Emacs. + (let ((rgb + (if (fboundp 'color-instance-rgb-components) + (mapcar (lambda (arg) + (/ arg 256)) + (color-instance-rgb-components + (make-color-instance color))) + (mapcar (lambda (arg) + (/ arg 256)) + (color-values color))))) + (when rgb + (setq rgb-string (apply #'format "#%02x%02x%02x" rgb)))))) + ;; If RGB-STRING is still nil, it means the color cannot be found, + ;; for whatever reason. In that case just punt and return COLOR. + ;; Most browsers support a decent set of color names anyway. + (or rgb-string color))) + +;; We store the face properties we care about into an +;; `htmlize-fstruct' type. That way we only have to analyze face +;; properties, which can be time consuming, once per each face. The +;; mapping between Emacs faces and htmlize-fstructs is established by +;; htmlize-make-face-map. The name "fstruct" refers to variables of +;; type `htmlize-fstruct', while the term "face" is reserved for Emacs +;; faces. + +(defstruct htmlize-fstruct + foreground ; foreground color, #rrggbb + background ; background color, #rrggbb + size ; size + boldp ; whether face is bold + italicp ; whether face is italic + underlinep ; whether face is underlined + overlinep ; whether face is overlined + strikep ; whether face is struck through + css-name ; CSS name of face + ) + +(defun htmlize-face-emacs21-attr (fstruct attr value) + ;; For ATTR and VALUE, set the equivalent value in FSTRUCT. + (case attr + (:foreground + (setf (htmlize-fstruct-foreground fstruct) (htmlize-color-to-rgb value))) + (:background + (setf (htmlize-fstruct-background fstruct) (htmlize-color-to-rgb value))) + (:height + (setf (htmlize-fstruct-size fstruct) value)) + (:weight + (when (string-match (symbol-name value) "bold") + (setf (htmlize-fstruct-boldp fstruct) t))) + (:slant + (setf (htmlize-fstruct-italicp fstruct) (or (eq value 'italic) + (eq value 'oblique)))) + (:bold + (setf (htmlize-fstruct-boldp fstruct) value)) + (:italic + (setf (htmlize-fstruct-italicp fstruct) value)) + (:underline + (setf (htmlize-fstruct-underlinep fstruct) value)) + (:overline + (setf (htmlize-fstruct-overlinep fstruct) value)) + (:strike-through + (setf (htmlize-fstruct-strikep fstruct) value)))) + +(defun htmlize-face-size (face) + ;; The size (height) of FACE, taking inheritance into account. + ;; Only works in Emacs 21 and later. + (let ((size-list + (loop + for f = face then (face-attribute f :inherit) + until (or (not f) (eq f 'unspecified)) + for h = (face-attribute f :height) + collect (if (eq h 'unspecified) nil h)))) + (reduce 'htmlize-merge-size (cons nil size-list)))) + +(defun htmlize-face-css-name (face) + ;; Generate the css-name property for the given face. Emacs places + ;; no restrictions on the names of symbols that represent faces -- + ;; any characters may be in the name, even control chars. We try + ;; hard to beat the face name into shape, both esthetically and + ;; according to CSS1 specs. + (let ((name (downcase (symbol-name face)))) + (when (string-match "\\`font-lock-" name) + ;; font-lock-FOO-face -> FOO. + (setq name (replace-match "" t t name))) + (when (string-match "-face\\'" name) + ;; Drop the redundant "-face" suffix. + (setq name (replace-match "" t t name))) + (while (string-match "[^-a-zA-Z0-9]" name) + ;; Drop the non-alphanumerics. + (setq name (replace-match "X" t t name))) + (when (string-match "\\`[-0-9]" name) + ;; CSS identifiers may not start with a digit. + (setq name (concat "X" name))) + ;; After these transformations, the face could come out empty. + (when (equal name "") + (setq name "face")) + ;; Apply the prefix. + (concat htmlize-css-name-prefix name))) + +(defun htmlize-face-to-fstruct (face) + "Convert Emacs face FACE to fstruct." + (let ((fstruct (make-htmlize-fstruct + :foreground (htmlize-color-to-rgb + (htmlize-face-foreground face)) + :background (htmlize-color-to-rgb + (htmlize-face-background face))))) + (if htmlize-running-xemacs + ;; XEmacs doesn't provide a way to detect whether a face is + ;; bold or italic, so we need to examine the font instance. + (let* ((font-instance (face-font-instance face)) + (props (font-instance-properties font-instance))) + (when (equalp (cdr (assq 'WEIGHT_NAME props)) "bold") + (setf (htmlize-fstruct-boldp fstruct) t)) + (when (or (equalp (cdr (assq 'SLANT props)) "i") + (equalp (cdr (assq 'SLANT props)) "o")) + (setf (htmlize-fstruct-italicp fstruct) t)) + (setf (htmlize-fstruct-strikep fstruct) + (face-strikethru-p face)) + (setf (htmlize-fstruct-underlinep fstruct) + (face-underline-p face))) + ;; GNU Emacs + (dolist (attr '(:weight :slant :underline :overline :strike-through)) + (let ((value (face-attribute face attr nil t))) + (when (and value (not (eq value 'unspecified))) + (htmlize-face-emacs21-attr fstruct attr value)))) + (let ((size (htmlize-face-size face))) + (unless (eql size 1.0) ; ignore non-spec + (setf (htmlize-fstruct-size fstruct) size)))) + (setf (htmlize-fstruct-css-name fstruct) (htmlize-face-css-name face)) + fstruct)) + +(defmacro htmlize-copy-attr-if-set (attr-list dest source) + ;; Generate code with the following pattern: + ;; (progn + ;; (when (htmlize-fstruct-ATTR source) + ;; (setf (htmlize-fstruct-ATTR dest) (htmlize-fstruct-ATTR source))) + ;; ...) + ;; for the given list of boolean attributes. + (cons 'progn + (loop for attr in attr-list + for attr-sym = (intern (format "htmlize-fstruct-%s" attr)) + collect `(when (,attr-sym ,source) + (setf (,attr-sym ,dest) (,attr-sym ,source)))))) + +(defun htmlize-merge-size (merged next) + ;; Calculate the size of the merge of MERGED and NEXT. + (cond ((null merged) next) + ((integerp next) next) + ((null next) merged) + ((floatp merged) (* merged next)) + ((integerp merged) (round (* merged next))))) + +(defun htmlize-merge-two-faces (merged next) + (htmlize-copy-attr-if-set + (foreground background boldp italicp underlinep overlinep strikep) + merged next) + (setf (htmlize-fstruct-size merged) + (htmlize-merge-size (htmlize-fstruct-size merged) + (htmlize-fstruct-size next))) + merged) + +(defun htmlize-merge-faces (fstruct-list) + (cond ((null fstruct-list) + ;; Nothing to do, return a dummy face. + (make-htmlize-fstruct)) + ((null (cdr fstruct-list)) + ;; Optimize for the common case of a single face, simply + ;; return it. + (car fstruct-list)) + (t + (reduce #'htmlize-merge-two-faces + (cons (make-htmlize-fstruct) fstruct-list))))) + +;; GNU Emacs 20+ supports attribute lists in `face' properties. For +;; example, you can use `(:foreground "red" :weight bold)' as an +;; overlay's "face", or you can even use a list of such lists, etc. +;; We call those "attrlists". +;; +;; htmlize supports attrlist by converting them to fstructs, the same +;; as with regular faces. + +(defun htmlize-attrlist-to-fstruct (attrlist) + ;; Like htmlize-face-to-fstruct, but accepts an ATTRLIST as input. + (let ((fstruct (make-htmlize-fstruct))) + (cond ((eq (car attrlist) 'foreground-color) + ;; ATTRLIST is (foreground-color . COLOR) + (setf (htmlize-fstruct-foreground fstruct) + (htmlize-color-to-rgb (cdr attrlist)))) + ((eq (car attrlist) 'background-color) + ;; ATTRLIST is (background-color . COLOR) + (setf (htmlize-fstruct-background fstruct) + (htmlize-color-to-rgb (cdr attrlist)))) + (t + ;; ATTRLIST is a plist. + (while attrlist + (let ((attr (pop attrlist)) + (value (pop attrlist))) + (when (and value (not (eq value 'unspecified))) + (htmlize-face-emacs21-attr fstruct attr value)))))) + (setf (htmlize-fstruct-css-name fstruct) "ATTRLIST") + fstruct)) + +(defun htmlize-decode-face-prop (prop) + "Turn face property PROP into a list of face-like objects." + ;; PROP can be a symbol naming a face, a string naming such a + ;; symbol, a cons (foreground-color . COLOR) or (background-color + ;; COLOR), a property list (:attr1 val1 :attr2 val2 ...), or a list + ;; of any of those. + ;; + ;; (htmlize-decode-face-prop 'face) -> (face) + ;; (htmlize-decode-face-prop '(face1 face2)) -> (face1 face2) + ;; (htmlize-decode-face-prop '(:attr "val")) -> ((:attr "val")) + ;; (htmlize-decode-face-prop '((:attr "val") face (foreground-color "red"))) + ;; -> ((:attr "val") face (foreground-color "red")) + ;; + ;; Unrecognized atoms or non-face symbols/strings are silently + ;; stripped away. + (cond ((null prop) + nil) + ((symbolp prop) + (and (facep prop) + (list prop))) + ((stringp prop) + (and (facep (intern-soft prop)) + (list prop))) + ((atom prop) + nil) + ((and (symbolp (car prop)) + (eq ?: (aref (symbol-name (car prop)) 0))) + (list prop)) + ((or (eq (car prop) 'foreground-color) + (eq (car prop) 'background-color)) + (list prop)) + (t + (apply #'nconc (mapcar #'htmlize-decode-face-prop prop))))) + +(defun htmlize-make-face-map (faces) + ;; Return a hash table mapping Emacs faces to htmlize's fstructs. + ;; The keys are either face symbols or attrlists, so the test + ;; function must be `equal'. + (let ((face-map (make-hash-table :test 'equal)) + css-names) + (dolist (face faces) + (unless (gethash face face-map) + ;; Haven't seen FACE yet; convert it to an fstruct and cache + ;; it. + (let ((fstruct (if (symbolp face) + (htmlize-face-to-fstruct face) + (htmlize-attrlist-to-fstruct face)))) + (setf (gethash face face-map) fstruct) + (let* ((css-name (htmlize-fstruct-css-name fstruct)) + (new-name css-name) + (i 0)) + ;; Uniquify the face's css-name by using NAME-1, NAME-2, + ;; etc. + (while (member new-name css-names) + (setq new-name (format "%s-%s" css-name (incf i)))) + (unless (equal new-name css-name) + (setf (htmlize-fstruct-css-name fstruct) new-name)) + (push new-name css-names))))) + face-map)) + +(defun htmlize-unstringify-face (face) + "If FACE is a string, return it interned, otherwise return it unchanged." + (if (stringp face) + (intern face) + face)) + +(defun htmlize-faces-in-buffer () + "Return a list of faces used in the current buffer. +Under XEmacs, this returns the set of faces specified by the extents +with the `face' property. (This covers text properties as well.) Under +GNU Emacs, it returns the set of faces specified by the `face' text +property and by buffer overlays that specify `face'." + (let (faces) + ;; Testing for (fboundp 'map-extents) doesn't work because W3 + ;; defines `map-extents' under FSF. + (if htmlize-running-xemacs + (let (face-prop) + (map-extents (lambda (extent ignored) + (setq face-prop (extent-face extent) + ;; FACE-PROP can be a face or a list of + ;; faces. + faces (if (listp face-prop) + (union face-prop faces) + (adjoin face-prop faces))) + nil) + nil + ;; Specify endpoints explicitly to respect + ;; narrowing. + (point-min) (point-max) nil nil 'face)) + ;; FSF Emacs code. + ;; Faces used by text properties. + (let ((pos (point-min)) face-prop next) + (while (< pos (point-max)) + (setq face-prop (get-text-property pos 'face) + next (or (next-single-property-change pos 'face) (point-max))) + (setq faces (nunion (htmlize-decode-face-prop face-prop) + faces :test 'equal)) + (setq pos next))) + ;; Faces used by overlays. + (dolist (overlay (overlays-in (point-min) (point-max))) + (let ((face-prop (overlay-get overlay 'face))) + (setq faces (nunion (htmlize-decode-face-prop face-prop) + faces :test 'equal))))) + faces)) + +;; htmlize-faces-at-point returns the faces in use at point. The +;; faces are sorted by increasing priority, i.e. the last face takes +;; precedence. +;; +;; Under XEmacs, this returns all the faces in all the extents at +;; point. Under GNU Emacs, this returns all the faces in the `face' +;; property and all the faces in the overlays at point. + +(cond (htmlize-running-xemacs + (defun htmlize-faces-at-point () + (let (extent extent-list face-list face-prop) + (while (setq extent (extent-at (point) nil 'face extent)) + (push extent extent-list)) + ;; extent-list is in reverse display order, meaning that + ;; smallest ones come last. That is the order we want, + ;; except it can be overridden by the `priority' property. + (setq extent-list (stable-sort extent-list #'< + :key #'extent-priority)) + (dolist (extent extent-list) + (setq face-prop (extent-face extent)) + ;; extent's face-list is in reverse order from what we + ;; want, but the `nreverse' below will take care of it. + (setq face-list (if (listp face-prop) + (append face-prop face-list) + (cons face-prop face-list)))) + (nreverse face-list)))) + (t + (defun htmlize-faces-at-point () + (let (all-faces) + ;; Faces from text properties. + (let ((face-prop (get-text-property (point) 'face))) + (setq all-faces (htmlize-decode-face-prop face-prop))) + ;; Faces from overlays. + (let ((overlays + ;; Collect overlays at point that specify `face'. + (delete-if-not (lambda (o) + (overlay-get o 'face)) + (overlays-at (point)))) + list face-prop) + ;; Sort the overlays so the smaller (more specific) ones + ;; come later. The number of overlays at each one + ;; position should be very small, so the sort shouldn't + ;; slow things down. + (setq overlays (sort* overlays + ;; Sort by ascending... + #'< + ;; ...overlay size. + :key (lambda (o) + (- (overlay-end o) + (overlay-start o))))) + ;; Overlay priorities, if present, override the above + ;; established order. Larger overlay priority takes + ;; precedence and therefore comes later in the list. + (setq overlays (stable-sort + overlays + ;; Reorder (stably) by acending... + #'< + ;; ...overlay priority. + :key (lambda (o) + (or (overlay-get o 'priority) 0)))) + (dolist (overlay overlays) + (setq face-prop (overlay-get overlay 'face) + list (nconc (htmlize-decode-face-prop face-prop) list))) + ;; Under "Merging Faces" the manual explicitly states + ;; that faces specified by overlays take precedence over + ;; faces specified by text properties. + (setq all-faces (nconc all-faces list))) + all-faces)))) + +;; htmlize supports generating HTML in several flavors, some of which +;; use CSS, and others the element. We take an OO approach and +;; define "methods" that indirect to the functions that depend on +;; `htmlize-output-type'. The currently used methods are `doctype', +;; `insert-head', `body-tag', and `text-markup'. Not all output types +;; define all methods. +;; +;; Methods are called either with (htmlize-method METHOD ARGS...) +;; special form, or by accessing the function with +;; (htmlize-method-function 'METHOD) and calling (funcall FUNCTION). +;; The latter form is useful in tight loops because `htmlize-method' +;; conses. + +(defmacro htmlize-method (method &rest args) + ;; Expand to (htmlize-TYPE-METHOD ...ARGS...). TYPE is the value of + ;; `htmlize-output-type' at run time. + `(funcall (htmlize-method-function ',method) ,@args)) + +(defun htmlize-method-function (method) + ;; Return METHOD's function definition for the current output type. + ;; The returned object can be safely funcalled. + (let ((sym (intern (format "htmlize-%s-%s" htmlize-output-type method)))) + (indirect-function (if (fboundp sym) + sym + (let ((default (intern (concat "htmlize-default-" + (symbol-name method))))) + (if (fboundp default) + default + 'ignore)))))) + +(defvar htmlize-memoization-table (make-hash-table :test 'equal)) + +(defmacro htmlize-memoize (key generator) + "Return the value of GENERATOR, memoized as KEY. +That means that GENERATOR will be evaluated and returned the first time +it's called with the same value of KEY. All other times, the cached +\(memoized) value will be returned." + (let ((value (gensym))) + `(let ((,value (gethash ,key htmlize-memoization-table))) + (unless ,value + (setq ,value ,generator) + (setf (gethash ,key htmlize-memoization-table) ,value)) + ,value))) + +;;; Default methods. + +(defun htmlize-default-doctype () + nil ; no doc-string + ;; Note that the `font' output is technically invalid under this DTD + ;; because the DTD doesn't allow embedding in
.
+  ""
+  )
+
+(defun htmlize-default-body-tag (face-map)
+  nil					; no doc-string
+  face-map ; shut up the byte-compiler
+  "")
+
+;;; CSS based output support.
+
+;; Internal function; not a method.
+(defun htmlize-css-specs (fstruct)
+  (let (result)
+    (when (htmlize-fstruct-foreground fstruct)
+      (push (format "color: %s;" (htmlize-fstruct-foreground fstruct))
+	    result))
+    (when (htmlize-fstruct-background fstruct)
+      (push (format "background-color: %s;"
+		    (htmlize-fstruct-background fstruct))
+	    result))
+    (let ((size (htmlize-fstruct-size fstruct)))
+      (when (and size (not (eq htmlize-ignore-face-size t)))
+	(cond ((floatp size)
+	       (push (format "font-size: %d%%;" (* 100 size)) result))
+	      ((not (eq htmlize-ignore-face-size 'absolute))
+	       (push (format "font-size: %spt;" (/ size 10.0)) result)))))
+    (when (htmlize-fstruct-boldp fstruct)
+      (push "font-weight: bold;" result))
+    (when (htmlize-fstruct-italicp fstruct)
+      (push "font-style: italic;" result))
+    (when (htmlize-fstruct-underlinep fstruct)
+      (push "text-decoration: underline;" result))
+    (when (htmlize-fstruct-overlinep fstruct)
+      (push "text-decoration: overline;" result))
+    (when (htmlize-fstruct-strikep fstruct)
+      (push "text-decoration: line-through;" result))
+    (nreverse result)))
+
+(defun htmlize-css-insert-head (buffer-faces face-map)
+  (insert "    \n"))
+
+(defun htmlize-css-text-markup (fstruct-list buffer)
+  ;; Open the markup needed to insert text colored with FACES into
+  ;; BUFFER.  Return the function that closes the markup.
+
+  ;; In CSS mode, this is easy: just nest the text in one  tag for each face in FSTRUCT-LIST.
+  (dolist (fstruct fstruct-list)
+    (princ "" buffer))
+  (htmlize-lexlet ((fstruct-list fstruct-list) (buffer buffer))
+    (lambda ()
+      (dolist (fstruct fstruct-list)
+        (ignore fstruct)                ; shut up the byte-compiler
+        (princ "" buffer)))))
+
+;; `inline-css' output support.
+
+(defun htmlize-inline-css-body-tag (face-map)
+  (format ""
+	  (mapconcat #'identity (htmlize-css-specs (gethash 'default face-map))
+		     " ")))
+
+(defun htmlize-inline-css-text-markup (fstruct-list buffer)
+  (let* ((merged (htmlize-merge-faces fstruct-list))
+	 (style (htmlize-memoize
+		 merged
+		 (let ((specs (htmlize-css-specs merged)))
+		   (and specs
+			(mapconcat #'identity (htmlize-css-specs merged) " "))))))
+    (when style
+      (princ "" buffer))
+    (htmlize-lexlet ((style style) (buffer buffer))
+      (lambda ()
+        (when style
+          (princ "" buffer))))))
+
+;;; `font' tag based output support.
+
+(defun htmlize-font-body-tag (face-map)
+  (let ((fstruct (gethash 'default face-map)))
+    (format ""
+	    (htmlize-fstruct-foreground fstruct)
+	    (htmlize-fstruct-background fstruct))))
+
+(defun htmlize-font-text-markup (fstruct-list buffer)
+  ;; In `font' mode, we use the traditional HTML means of altering
+  ;; presentation:  tag for colors,  for bold,  for
+  ;; underline, and  for strike-through.
+  (let* ((merged (htmlize-merge-faces fstruct-list))
+	 (markup (htmlize-memoize
+		  merged
+		  (cons (concat
+			 (and (htmlize-fstruct-foreground merged)
+			      (format "" (htmlize-fstruct-foreground merged)))
+			 (and (htmlize-fstruct-boldp merged)      "")
+			 (and (htmlize-fstruct-italicp merged)    "")
+			 (and (htmlize-fstruct-underlinep merged) "")
+			 (and (htmlize-fstruct-strikep merged)    ""))
+			(concat
+			 (and (htmlize-fstruct-strikep merged)    "")
+			 (and (htmlize-fstruct-underlinep merged) "")
+			 (and (htmlize-fstruct-italicp merged)    "")
+			 (and (htmlize-fstruct-boldp merged)      "")
+			 (and (htmlize-fstruct-foreground merged) ""))))))
+    (princ (car markup) buffer)
+    (htmlize-lexlet ((markup markup) (buffer buffer))
+      (lambda ()
+        (princ (cdr markup) buffer)))))
+
+(defun htmlize-buffer-1 ()
+  ;; Internal function; don't call it from outside this file.  Htmlize
+  ;; current buffer, writing the resulting HTML to a new buffer, and
+  ;; return it.  Unlike htmlize-buffer, this doesn't change current
+  ;; buffer or use switch-to-buffer.
+  (save-excursion
+    ;; Protect against the hook changing the current buffer.
+    (save-excursion
+      (run-hooks 'htmlize-before-hook))
+    ;; Convince font-lock support modes to fontify the entire buffer
+    ;; in advance.
+    (htmlize-ensure-fontified)
+    (clrhash htmlize-extended-character-cache)
+    (clrhash htmlize-memoization-table)
+    ;; It's important that the new buffer inherits default-directory
+    ;; from the current buffer.
+    (let ((htmlbuf (generate-new-buffer (if (buffer-file-name)
+                                            (htmlize-make-file-name
+                                             (file-name-nondirectory
+                                              (buffer-file-name)))
+                                          "*html*")))
+          (completed nil))
+      (unwind-protect
+          (let* ((buffer-faces (htmlize-faces-in-buffer))
+                 (face-map (htmlize-make-face-map (adjoin 'default buffer-faces)))
+                 (places (gensym))
+                 (title (if (buffer-file-name)
+                            (file-name-nondirectory (buffer-file-name))
+                          (buffer-name))))
+            (when htmlize-generate-hyperlinks
+              (htmlize-create-auto-links))
+            (when htmlize-replace-form-feeds
+              (htmlize-shadow-form-feeds))
+
+            ;; Initialize HTMLBUF and insert the HTML prolog.
+            (with-current-buffer htmlbuf
+              (buffer-disable-undo)
+              (insert (htmlize-method doctype) ?\n
+                      (format "\n"
+                              htmlize-version htmlize-output-type)
+                      "\n  ")
+              (put places 'head-start (point-marker))
+              (insert "\n"
+                      "    " (htmlize-protect-string title) "\n"
+                      (if htmlize-html-charset
+                          (format (concat "    \n")
+                                  htmlize-html-charset)
+                        "")
+                      htmlize-head-tags)
+              (htmlize-method insert-head buffer-faces face-map)
+              (insert "  ")
+              (put places 'head-end (point-marker))
+              (insert "\n  ")
+              (put places 'body-start (point-marker))
+              (insert (htmlize-method body-tag face-map)
+                      "\n    ")
+              (put places 'content-start (point-marker))
+              (insert "
\n"))
+            (let ((text-markup
+                   ;; Get the inserter method, so we can funcall it inside
+                   ;; the loop.  Not calling `htmlize-method' in the loop
+                   ;; body yields a measurable speed increase.
+                   (htmlize-method-function 'text-markup))
+                  ;; Declare variables used in loop body outside the loop
+                  ;; because it's faster to establish `let' bindings only
+                  ;; once.
+                  next-change text face-list trailing-ellipsis
+                  fstruct-list last-fstruct-list
+                  (close-markup (lambda ())))
+              ;; This loop traverses and reads the source buffer, appending
+              ;; the resulting HTML to HTMLBUF.  This method is fast
+              ;; because: 1) it doesn't require examining the text
+              ;; properties char by char (htmlize-next-face-change is used
+              ;; to move between runs with the same face), and 2) it doesn't
+              ;; require frequent buffer switches, which are slow because
+              ;; they rebind all buffer-local vars.
+              (goto-char (point-min))
+              (while (not (eobp))
+                (setq next-change (htmlize-next-face-change (point)))
+                ;; Get faces in use between (point) and NEXT-CHANGE, and
+                ;; convert them to fstructs.
+                (setq face-list (htmlize-faces-at-point)
+                      fstruct-list (delq nil (mapcar (lambda (f)
+                                                       (gethash f face-map))
+                                                     face-list)))
+                (multiple-value-setq (text trailing-ellipsis)
+                  (htmlize-extract-text (point) next-change trailing-ellipsis))
+                ;; Don't bother writing anything if there's no text (this
+                ;; happens in invisible regions).
+                (when (> (length text) 0)
+                  ;; Open the new markup if necessary and insert the text.
+                  (when (not (equalp fstruct-list last-fstruct-list))
+                    (funcall close-markup)
+                    (setq last-fstruct-list fstruct-list
+                          close-markup (funcall text-markup fstruct-list htmlbuf)))
+                  (princ text htmlbuf))
+                (goto-char next-change))
+
+              ;; We've gone through the buffer; close the markup from
+              ;; the last run, if any.
+              (funcall close-markup))
+
+            ;; Insert the epilog and post-process the buffer.
+            (with-current-buffer htmlbuf
+              (insert "
") + (put places 'content-end (point-marker)) + (insert "\n ") + (put places 'body-end (point-marker)) + (insert "\n\n") + (htmlize-defang-local-variables) + (goto-char (point-min)) + (when htmlize-html-major-mode + ;; What sucks about this is that the minor modes, most notably + ;; font-lock-mode, won't be initialized. Oh well. + (funcall htmlize-html-major-mode)) + (set (make-local-variable 'htmlize-buffer-places) + (symbol-plist places)) + (run-hooks 'htmlize-after-hook) + (buffer-enable-undo)) + (setq completed t) + htmlbuf) + + (when (not completed) + (kill-buffer htmlbuf)) + (htmlize-delete-tmp-overlays))))) + +;; Utility functions. + +(defmacro htmlize-with-fontify-message (&rest body) + ;; When forcing fontification of large buffers in + ;; htmlize-ensure-fontified, inform the user that he is waiting for + ;; font-lock, not for htmlize to finish. + `(progn + (if (> (buffer-size) 65536) + (message "Forcing fontification of %s..." + (buffer-name (current-buffer)))) + ,@body + (if (> (buffer-size) 65536) + (message "Forcing fontification of %s...done" + (buffer-name (current-buffer)))))) + +(defun htmlize-ensure-fontified () + ;; If font-lock is being used, ensure that the "support" modes + ;; actually fontify the buffer. If font-lock is not in use, we + ;; don't care because, except in htmlize-file, we don't force + ;; font-lock on the user. + (when (and (boundp 'font-lock-mode) + font-lock-mode) + ;; In part taken from ps-print-ensure-fontified in GNU Emacs 21. + (cond + ((and (boundp 'jit-lock-mode) + (symbol-value 'jit-lock-mode)) + (htmlize-with-fontify-message + (jit-lock-fontify-now (point-min) (point-max)))) + ((and (boundp 'lazy-lock-mode) + (symbol-value 'lazy-lock-mode)) + (htmlize-with-fontify-message + (lazy-lock-fontify-region (point-min) (point-max)))) + ((and (boundp 'lazy-shot-mode) + (symbol-value 'lazy-shot-mode)) + (htmlize-with-fontify-message + ;; lazy-shot is amazing in that it must *refontify* the region, + ;; even if the whole buffer has already been fontified. + (lazy-shot-fontify-region (point-min) (point-max)))) + ;; There's also fast-lock, but we don't need to handle specially, + ;; I think. fast-lock doesn't really defer fontification, it + ;; just saves it to an external cache so it's not done twice. + ))) + + +;;;###autoload +(defun htmlize-buffer (&optional buffer) + "Convert BUFFER to HTML, preserving colors and decorations. + +The generated HTML is available in a new buffer, which is returned. +When invoked interactively, the new buffer is selected in the current +window. The title of the generated document will be set to the buffer's +file name or, if that's not available, to the buffer's name. + +Note that htmlize doesn't fontify your buffers, it only uses the +decorations that are already present. If you don't set up font-lock or +something else to fontify your buffers, the resulting HTML will be +plain. Likewise, if you don't like the choice of colors, fix the mode +that created them, or simply alter the faces it uses." + (interactive) + (let ((htmlbuf (with-current-buffer (or buffer (current-buffer)) + (htmlize-buffer-1)))) + (when (interactive-p) + (switch-to-buffer htmlbuf)) + htmlbuf)) + +;;;###autoload +(defun htmlize-region (beg end) + "Convert the region to HTML, preserving colors and decorations. +See `htmlize-buffer' for details." + (interactive "r") + ;; Don't let zmacs region highlighting end up in HTML. + (when (fboundp 'zmacs-deactivate-region) + (zmacs-deactivate-region)) + (let ((htmlbuf (save-restriction + (narrow-to-region beg end) + (htmlize-buffer-1)))) + (when (interactive-p) + (switch-to-buffer htmlbuf)) + htmlbuf)) + +(defun htmlize-region-for-paste (beg end) + "Htmlize the region and return just the HTML as a string. +This forces the `inline-css' style and only returns the HTML body, +but without the BODY tag. This should make it useful for inserting +the text to another HTML buffer." + (let* ((htmlize-output-type 'inline-css) + (htmlbuf (htmlize-region beg end))) + (unwind-protect + (with-current-buffer htmlbuf + (buffer-substring (plist-get htmlize-buffer-places 'content-start) + (plist-get htmlize-buffer-places 'content-end))) + (kill-buffer htmlbuf)))) + +(defun htmlize-make-file-name (file) + "Make an HTML file name from FILE. + +In its default implementation, this simply appends `.html' to FILE. +This function is called by htmlize to create the buffer file name, and +by `htmlize-file' to create the target file name. + +More elaborate transformations are conceivable, such as changing FILE's +extension to `.html' (\"file.c\" -> \"file.html\"). If you want them, +overload this function to do it and htmlize will comply." + (concat file ".html")) + +;; Older implementation of htmlize-make-file-name that changes FILE's +;; extension to ".html". +;(defun htmlize-make-file-name (file) +; (let ((extension (file-name-extension file)) +; (sans-extension (file-name-sans-extension file))) +; (if (or (equal extension "html") +; (equal extension "htm") +; (equal sans-extension "")) +; (concat file ".html") +; (concat sans-extension ".html")))) + +;;;###autoload +(defun htmlize-file (file &optional target) + "Load FILE, fontify it, convert it to HTML, and save the result. + +Contents of FILE are inserted into a temporary buffer, whose major mode +is set with `normal-mode' as appropriate for the file type. The buffer +is subsequently fontified with `font-lock' and converted to HTML. Note +that, unlike `htmlize-buffer', this function explicitly turns on +font-lock. If a form of highlighting other than font-lock is desired, +please use `htmlize-buffer' directly on buffers so highlighted. + +Buffers currently visiting FILE are unaffected by this function. The +function does not change current buffer or move the point. + +If TARGET is specified and names a directory, the resulting file will be +saved there instead of to FILE's directory. If TARGET is specified and +does not name a directory, it will be used as output file name." + (interactive (list (read-file-name + "HTML-ize file: " + nil nil nil (and (buffer-file-name) + (file-name-nondirectory + (buffer-file-name)))))) + (let ((output-file (if (and target (not (file-directory-p target))) + target + (expand-file-name + (htmlize-make-file-name (file-name-nondirectory file)) + (or target (file-name-directory file))))) + ;; Try to prevent `find-file-noselect' from triggering + ;; font-lock because we'll fontify explicitly below. + (font-lock-mode nil) + (font-lock-auto-fontify nil) + (global-font-lock-mode nil) + ;; Ignore the size limit for the purposes of htmlization. + (font-lock-maximum-size nil) + ;; Disable font-lock support modes. This will only work in + ;; more recent Emacs versions, so htmlize-buffer-1 still needs + ;; to call htmlize-ensure-fontified. + (font-lock-support-mode nil)) + (with-temp-buffer + ;; Insert FILE into the temporary buffer. + (insert-file-contents file) + ;; Set the file name so normal-mode and htmlize-buffer-1 pick it + ;; up. Restore it afterwards so with-temp-buffer's kill-buffer + ;; doesn't complain about killing a modified buffer. + (let ((buffer-file-name file)) + ;; Set the major mode for the sake of font-lock. + (normal-mode) + (font-lock-mode 1) + (unless font-lock-mode + ;; In GNU Emacs (font-lock-mode 1) doesn't force font-lock, + ;; contrary to the documentation. This seems to work. + (font-lock-fontify-buffer)) + ;; htmlize the buffer and save the HTML. + (with-current-buffer (htmlize-buffer-1) + (unwind-protect + (progn + (run-hooks 'htmlize-file-hook) + (write-region (point-min) (point-max) output-file)) + (kill-buffer (current-buffer))))))) + ;; I haven't decided on a useful return value yet, so just return + ;; nil. + nil) + +;;;###autoload +(defun htmlize-many-files (files &optional target-directory) + "Convert FILES to HTML and save the corresponding HTML versions. + +FILES should be a list of file names to convert. This function calls +`htmlize-file' on each file; see that function for details. When +invoked interactively, you are prompted for a list of files to convert, +terminated with RET. + +If TARGET-DIRECTORY is specified, the HTML files will be saved to that +directory. Normally, each HTML file is saved to the directory of the +corresponding source file." + (interactive + (list + (let (list file) + ;; Use empty string as DEFAULT because setting DEFAULT to nil + ;; defaults to the directory name, which is not what we want. + (while (not (equal (setq file (read-file-name + "HTML-ize file (RET to finish): " + (and list (file-name-directory + (car list))) + "" t)) + "")) + (push file list)) + (nreverse list)))) + ;; Verify that TARGET-DIRECTORY is indeed a directory. If it's a + ;; file, htmlize-file will use it as target, and that doesn't make + ;; sense. + (and target-directory + (not (file-directory-p target-directory)) + (error "target-directory must name a directory: %s" target-directory)) + (dolist (file files) + (htmlize-file file target-directory))) + +;;;###autoload +(defun htmlize-many-files-dired (arg &optional target-directory) + "HTMLize dired-marked files." + (interactive "P") + (htmlize-many-files (dired-get-marked-files nil arg) target-directory)) + +(provide 'htmlize) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions lexical unresolved obsolete) +;; lexical-binding: t +;; End: + +;;; htmlize.el ends here diff -Nru ddskk-16.2/doc/makepdf.bat ddskk-16.2+0.20190423/doc/makepdf.bat --- ddskk-16.2/doc/makepdf.bat 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/makepdf.bat 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -@echo off - -ptex skk.texi - -for %%f in (skk.??) do texindex %%f - -ptex skk.texi - -for %%f in (skk.??) do texindex %%f - -ptex skk.texi -dvipdfmx skk.dvi - -del skk.cp* skk.fn* skk.ky* skk.pg* skk.tp* skk.vr* -del skk.aux skk.dvi skk.toc - diff -Nru ddskk-16.2/doc/makepdf.sh ddskk-16.2+0.20190423/doc/makepdf.sh --- ddskk-16.2/doc/makepdf.sh 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/makepdf.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -#!/bin/sh -set -e - -ptex skk.texi -for f in skk.??; do texindex "$f"; done -ptex skk.texi -for f in skk.??; do texindex "$f"; done -ptex skk.texi -dvipdfmx skk.dvi -/bin/rm -f skk.cp* skk.fn* skk.ky* skk.pg* skk.tp* skk.vr* -/bin/rm -f skk.aux skk.dvi skk.toc skk.log diff -Nru ddskk-16.2/doc/mobi.xsl ddskk-16.2+0.20190423/doc/mobi.xsl --- ddskk-16.2/doc/mobi.xsl 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/mobi.xsl 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,260 @@ + + + + + + + +ul + + + + + + + + + + + + + + + + + + + 2005-1 + + + + + + cover + + + + + + + + dtb:uid + + isbn: + + + + + + + + + dtb:depth + -1 + + + dtb:totalPageCount + 0 + + + dtb:maxPageNumber + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru ddskk-16.2/doc/.nosearch ddskk-16.2+0.20190423/doc/.nosearch --- ddskk-16.2/doc/.nosearch 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/.nosearch 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,2 @@ +This file keeps the containing directory of the `load-path' +See `normal-top-level-add-subdirs-to-load-path's doc-string. diff -Nru ddskk-16.2/doc/obsolete-doc/makepdf.bat ddskk-16.2+0.20190423/doc/obsolete-doc/makepdf.bat --- ddskk-16.2/doc/obsolete-doc/makepdf.bat 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/obsolete-doc/makepdf.bat 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,24 @@ +@echo off + +REM このスクリプトは Texinfo マニュアルの +REM 19. Formatting and Printing Hardcopy +REM 19.3 Format with tex/texindex +REM に記載された手順を実行するものです。 +REM skk.texi --(ptex)--> skk.dvi --(dvipdfmx)--> skk.pdf +REM サイズの小さい (約 824 Kbyte) PDF が完成しますが、 +REM その pdf は参照 ( リファレンス, @ref{} ) が clickable ではありません。 + +ptex skk.texi + +for %%f in (skk.??) do texindex %%f + +ptex skk.texi + +for %%f in (skk.??) do texindex %%f + +ptex skk.texi +dvipdfmx skk.dvi + +del skk.cp* skk.fn* skk.ky* skk.pg* skk.tp* skk.vr* +del skk.aux skk.dvi skk.toc + diff -Nru ddskk-16.2/doc/obsolete-doc/makepdf.sh ddskk-16.2+0.20190423/doc/obsolete-doc/makepdf.sh --- ddskk-16.2/doc/obsolete-doc/makepdf.sh 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/obsolete-doc/makepdf.sh 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,20 @@ +#!/bin/sh + +# このスクリプトは Texinfo マニュアルの +# 19. Formatting and Printing Hardcopy +# 19.3 Format with tex/texindex +# に記載された手順を実行するものです。 +# skk.texi --(ptex)--> skk.dvi --(dvipdfmx)--> skk.pdf +# サイズの小さい (約 824 Kbyte) PDF が完成しますが、 +# その pdf は参照 ( リファレンス, @ref{} ) が clickable ではありません。 + +set -e + +ptex skk.texi +for f in skk.??; do texindex "$f"; done +ptex skk.texi +for f in skk.??; do texindex "$f"; done +ptex skk.texi +dvipdfmx skk.dvi +/bin/rm -f skk.cp* skk.fn* skk.ky* skk.pg* skk.tp* skk.vr* +/bin/rm -f skk.aux skk.dvi skk.toc skk.log diff -Nru ddskk-16.2/doc/obsolete-doc/obsolete-skk.texi ddskk-16.2+0.20190423/doc/obsolete-doc/obsolete-skk.texi --- ddskk-16.2/doc/obsolete-doc/obsolete-skk.texi 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/obsolete-doc/obsolete-skk.texi 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,11298 @@ +\input texinfo @c -*- mode: texinfo; coding: utf-8 -*- +@setfilename skk.info +@settitle SKK Manual +@documentlanguage ja +@documentencoding utf-8 +@iftex +@usedvipdfmx +@end iftex +@paragraphindent 1 +@c メモ +@c 1 makeinfo でコンパイルすることもできます。一瞬で終わり、リンク切れを含む +@c エラーの検出に便利です。(make info はリンク切れを検出しません) +@c 方法は、このファイルを utf-8 で保存し、makeinfo skk.texi とします。 +@c 生成される info は、make info のそれとは異なります。特に改行は +@c 変になります。 +@c 2 @ref などのコマンドは、改行されると正常に働きません。 @w の中に入れて下さい。 +@c あるいは、3 つ引数を渡すのも良いでしょう。 +@c 3 @footnote は、そのページの一つ目では、texi の改行/非改行がそのまま +@c info の改行/非改行になり、二つ目以降は他の文と同様、自動的に改行されます。 +@c ただし、例外もあるようです。 +@c また、@footnote 以外にも、改行が編集されないケースがあるようです。 +@c +@c Author: Masahiko Sato +@c Yukiyoshi Kameyama +@c NAKAJIMA Mikio +@c IRIE Tetsuya +@c Kitamoto Tsuyoshi +@c Teika Kazura +@c Tsukamoto Tetsuo +@c Tsuyoshi AKIHO +@c SAKAI Kiyotaka +@c Satoshi Harauchi +@c Maintainer: SKK Development Team +@c Keywords: japanese +@c +@set SKK-VERSION 16.3 +@set UPDATED Date: 2017/03/04 + +@dircategory Emacs +@dircategory GNU Emacs Lisp +@direntry +* SKK: (skk). Simple Kana to Kanji conversion program. +@end direntry + +@c Texinfo に追加できたら良いなぁと思う点を述べます。中島は単なる LaTeX +@c ユーザで、Plain TeX マクロの組み方なんて全然知りませんので、ユー +@c ザーの立場でやりたいことを卒直に、また無責任に述べるに留めます。あし +@c からず。実現できる方法をご存知の方がいらっしゃいましたら、是非教えて +@c 下さい。 +@c +@c (1)日本語の用語についてゴシック体でプリントアウトし、info では "「" +@c と "」" を自動的に付けるような@jdfn{}が欲しい。本書では、日本語 +@c の用語定義をとりあえず`「',`」' で囲み、@b コマンドでゴシック体を +@c 出力するようにしている。 +@c +@c (2)アスキー文字と全角文字を連接して書いたとしても pTeX がその間に適切 +@c に空白を挿入して印刷してくれる。一方 info は連接したままで空白は挿 +@c 入されないので少し見にくい気がする。info ではアスキー文字と全角文 +@c 字との間に半角スペースを挿入してはどうか? +@c +@c (3)LaTeX の表を書くコマンドを実装して欲しい (なら Latexinfo を使えと +@c は言わないでね。互換性が大きく損なわれるから嫌なんです)。 + +@synindex pg cp +@footnotestyle end +@iftex +@afourpaper +@end iftex +@ifinfo +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries a copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). + +@end ignore +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation approved +by the author. +@end ifinfo +@titlepage +@sp 10 +@comment The title is printed in a large font. +@title SKK Manual +@subtitle This edition is for SKK version @value{SKK-VERSION} +@c @subtitle @value{UPDATED-MONTH} +@subtitle @value{UPDATED} + +@c The following two commands start the copyright page. +@page +@vskip 0pt plus 1filll +Copyright @copyright{}1991-2007 @w{Masahiko Sato}(佐藤雅彦), @* +@w{Yukiyoshi Kameyama}(亀山幸義), @w{NAKAJIMA Mikio}(中島幹夫), +@w{IRIE Tetsuya}(入江), @w{Kitamoto Tsuyoshi}(北本剛), +@w{Teika Kazura}(定家), @w{Tsukamoto Tetsuo}(塚本徹雄) +and @w{Tsuyoshi AKIHO}(秋保強). Revised by @w{Kiyotaka Sakai}(酒井清隆) +and @w{Satoshi Harauchi}(原内聡). + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation +approved by the author. + +@end titlepage +@page +@ifinfo +@node Top +@top SKK + +この @cite{SKK マニュアル} は SKK のバージョン @value{SKK-VERSION} に対 +応しています。 + +@menu +* はじめに:: +* インストール:: +* はじめの設定:: +* 基本的な使い方:: +* 便利な応用機能:: +* ローマ字入力以外の入力方式:: +* そのほかの拡張機能:: +* SKKに関する情報:: +* よくある質問とその回答(FAQ):: +* 事項索引:: +* 変数索引:: +* 関数索引:: +* キー索引:: + +@detailmenu + --- 以下は各章の項目です。 --- + +はじめに + +* このバージョンのSKKについて:: +* SKKとはなにか:: + +インストール + +* DDSKK のインストール:: +* 辞書について:: +* 辞書の入手:: +* 辞書を DDSKK と同時にインストールする:: +* 辞書サーバの入手:: + +はじめの設定 + +* 最も基本的な設定:: +* インクリメント検索の設定:: +* 辞書サーバを使いたいときの設定:: + +基本的な使い方 + +* 起動と終了:: +* 入力モード:: 文字種別毎のモード +* 変換モード:: 辞書を用いた変換の状態毎のモード +* インクリメンタル・サーチ:: +* チュートリアル:: + +便利な応用機能 -- 予備知識 + +* ファイル構成:: 応用機能を使いこなすための予備知識。 +* ユーザオプションの設定方法:: + +便利な応用機能 -- 入力関係 + +* カタカナ、英字入力の便法:: これと次の項は絶対、便利です。 +* 補完:: 「かしたん」 + Tab -> 「かしたんぽせきにん」 +* 便利な変換、その他の変換:: 単漢字、接頭辞、漢数字、等々。 + +便利な応用機能 -- 様々な設定 + +* キー設定:: ローマ字のルールなども変更できます。 +* 変換、確定の前後:: 誤変換の訂正、一発確定、確定のタイミングなど +* 送り仮名関連:: 送り仮名の処理について。 +* 候補の順序:: 関連のある語は上位に表示など、効率を求めて +* 辞書関連:: 辞書にまつわる設定及び機能。 + +便利な応用機能 -- 他 + +* 注釈 (アノテーション):: +* 文字コード関連:: 文字コードにまつわる機能。 +* DDSKK 以外のツールを用いた辞書変換:: +* 飾りつけ:: 様々な表示の設定。 +* ユーザガイダンス関連:: +* I-search関連:: インクリメンタル・サーチにまつわる機能。 +* VIP/VIPERとの併用:: +* picture-modeとの併用:: picture-mode との併用の際の問題点。 + +ローマ字入力以外の入力方式 + +* AZIK:: +* ACT:: +* TUT-code:: +* かな入力と親指シフト:: + +SKKに関する情報 + +* 最新情報:: +* SKKメーリングリスト:: +* SKK関連ソフトウェア:: +* SKK辞書について:: +* 辞書ツール:: +* SKKの作者:: +* SKKの歴史:: +* このマニュアルについて:: +* 謝辞:: + +よくある質問とその回答(FAQ) + +* Introduction:: SKK のなぜなに。 +* Installation:: SKK の入手から導入まで。 +* Customization:: SKK の基本設定からお好みのカスタマイズまで。 +* Dictionaries:: SKK 辞書関連。 +* Miscellaneous:: SKK の活用法その他。 + +@end detailmenu +@end menu +@end ifinfo + +@node はじめに +@chapter はじめに +@cindex はじめに + +@menu +* このバージョンのSKKについて:: +* SKKとはなにか:: +@end menu + +@node このバージョンのSKKについて +@section このバージョンのSKKについて + +Daredevil SKK (以下、このマニュアルにおいて @samp{DDSKK} と呼びます。)は、 +動作が早くて効率的な日本語入力環境を提供するソフトウェアです。 + +GNU General Public License に基づいて配布されているフリー・ソフトウェアです。 +DDSKK @value{SKK-VERSION} が動作すると思われる Emacsen のバージョンは、次のと +おりです。 + +@itemize @bullet +@item GNU Emacs 23.1 以降 (推奨) +@item GNU Emacs 24.1 以降 (推奨) +@item GNU Emacs 25.1 以降 (推奨) +@item Mule 機能付きでコンパイルされた XEmacs 21.4 の最新版 +@item Mule 機能付きでコンパイルされた XEmacs 21.5 の最新版 +@end itemize + +XEmacs に関しては、XEmacs 本体とは別に配布されているパッケージ群は最新版が要 +求されます。少なくとも xemacs-base パッケージが最新であることに加えて、fsf-compat パ +ッケージが必須です。 + +総論として、現在は XEmacs よりも GNU Emacs での動作がよくテストされてお +り、最近では XEmacs でのテストは充分行われていません。 +GNU Emacs 23 以上での利用が最も推奨されます。 + +現時点で Emacs のバージョンごとに少なくとも以下の制限があります。 + +@table @b +@item GNU Emacs 20.x + +DDSKK 14.2 以降は GNU Emacs 20 はサポート対象外です。 +GNU Emacs 20 のユーザは DDSKK 14.1 をお使いください。 + +@item GNU Emacs 21.4 + +DDSKK 15.1 以降は GNU Emacs 21 はサポート対象外です。 +GNU Emacs 21 のユーザは DDSKK 14.4 をお使いください。 + +@item GNU Emacs 22.3 + +DDSKK 16.2 以降は GNU Emacs 22 はサポート対象外です。 +GNU Emacs 22 のユーザは DDSKK 16.1 をお使いください。 + +@item GNU Emacs 23.3 + +@itemize @bullet +@item X Window System 上でのメニューバーの日本語表示は GTK 対応版のみです。 +@item MELPA を利用してインストールするには、先に @file{package.el} をインストールする必要があります。 +@end itemize + +@item GNU Emacs 24.3 + +GNU Emacs 24.3 と DDSKK 14 の組み合わせで isearch 使用時の不具合が発見されています。 +GNU Emacs 24.3 のユーザは DDSKK 15 以上をお使いください。 + +@url{http://mail.ring.gr.jp/skk/201211/msg00000.html} + +@url{http://mail.ring.gr.jp/skk/201212/msg00000.html} + +辞書のダウンロード機能である @kbd{M-x skk-get} と @command{make get} について、 +tar 展開は非対応です。 + +@item GNU Emacs 24.4 + +@itemize @bullet +@item coding tag を明示していないファイルは utf-8 と取り扱われます@footnote{@code{2013-06-11 international/mule-conf.el (file-coding-system-alist)}}。DDSKK 15.2 で対策済みです。 +@item NTEmacs は 24.3 と比べてディレクトリ構成が異なります@footnote{Emacs News: Changes in Emacs 24.4 on Non-Free Operating Systems}。DDSKK 15.2 で対策済みです。 +@end itemize + +@item GNU Emacs 25.1 + +DDSKK 15.2 以降をお使いください(DDSKK 16 を推奨します)。 + +@item XEmacs 21.4 + +@itemize @bullet +@item @file{skk-kcode.el} の機能を含む JIS X 0213 対応が機能しません。 +@item インライン候補表示は機能しません。 +@item 動的補完における複数候補表示は機能しません。 +@item ツールティップ表示が機能しません。 +@item 日本語メニュー表示は X リソースによる方法のみテストされています。 +@item GNU Emacs 標準添付辞書 ja-dic は利用できません。 +@item skk-search-web は利用できません。 +@end itemize + +@item XEmacs 21.5 (beta) + +@itemize @bullet +@item @file{skk-kcode.el} の機能を含む JIS X 0213 対応が機能しません。 +@item インライン候補表示は機能しません。 +@item 動的補完における複数候補表示は機能しません。 +@item 日本語メニュー表示は X リソースによる方法のみテストされています。 +@item GNU Emacs 標準添付辞書 ja-dic は利用できません。 +@item skk-search-web は利用できません。 +@end itemize + +@end table + +@node SKKとはなにか +@section SKKとはなにか + +SKK は、かな漢字変換プログラムです。 +Simple Kana to Kanji conversion program にちなんで名付けられ、その名 +は Combinatory Logic での有名な等式 @samp{SKK = I} にも由来していま +す @footnote{@samp{SKK = I} について詳しくは @url{http://openlab.jp/skk/SKK.html} を +ご参照下さい。}。 + +Daredevil SKK (DDSKK) は、 SKK の更なる拡張版です @footnote{@samp{Daredevil} の名の由来については @ref{Q1-1 Daredevil SKK って SKK とは違うのですか?} を参照して下さい。}。 + +ただし、@samp{SKK モード}、@samp{SKK 辞書}、@samp{SKK サーバ} といった歴 +史的な用語は引き続き使用しており、DDSKK と呼ばない場合もあります。また、 +SKK 方式の入力方法を採用したプログラムなど、広く SKK family を意味する場 +合も同様です。 + +DDSKK の主な特徴は、次のとおりです。 + +@itemize @bullet +@item 多彩な入力方式をサポート。ローマ/かな 両対応のかな入力のほか、AZIK、ACT、TUT-code の各方式による入力も可能。 +@item 文法的知識を用いない高速な「かな → 漢字」変換。 +@item シームレスかつ再帰的な単語登録モード。 +@item 確定語を個人辞書へ自動登録することによって、変換候補を効率的に表示する。 +@item マイナーモードとして実装されているので、メジャーモードにほとんど影響を与えない。つまり、Emacs との親和性が高い。 +@item DDSKK 本体 (Emacs Lisp) と辞書ファイルのみで動作可能。つまり、辞書サーバは必須ではなく、辞書サーバがダウンしていても使用できる。 +@item 辞書サーバを使うことで、使用メモリの削減が可能。 +@item ディスク容量に応じて選べる辞書ファイル。 +@item 辞書ファイルの一括ダウンロード機能。 +@item Emacs のオリジナル操作と同様に行える日本語インクリメンタル・サーチ。 +@item Emacs Lisp で書かれたプログラムが返す値を変換候補に挙げることができる。 +@item 入力モードの自動切り替え @file{context-skk.el} +@item 多彩なアノテーション表示 (ユーザ・アノテーション、EPWING 辞書、Apple OS X 辞書、Wikipedia/Wiktionary) +@item 見出し語の動的補完 +@item 総画数変換、部首変換、文字コード入力 +@end itemize + +@node インストール +@chapter インストール +@cindex インストール + +@menu +* DDSKK のインストール:: +* 辞書について:: +* 辞書の入手:: +* 辞書を DDSKK と同時にインストールする:: +* 辞書サーバの入手:: +@end menu + +@node DDSKK のインストール +@section DDSKK のインストール + +ここでは、UNIX 上で @command{make} コマンドが利用できる環境を想定します +@footnote{Microsoft Windows 環境では、@command{makeit.bat} を使用することで +同様の操作でインストールできます。@url{https://github.com/skk-dev/ddskk/blob/master/READMEs/README.w32.ja.org} + +cygwin 環境をインストールされている方は @command{make} コマンドが使用できる +ので、本文の解説がそのまま当てはまります。 + +Apple OS X 環境の方は @url{https://github.com/skk-dev/ddskk/blob/master/READMEs/README.MacOSX.ja} を参照してください。 +}。 + +まず、DDSKK のアーカイブ @file{ddskk-VERSION.tar.gz} を @command{tar} コ +マンドと @command{gzip} コマンドを使用して展開します。 + +@example +% gzip -cd ddskk-@value{SKK-VERSION}.tar.gz | tar xvf - +@end example + +次に、DDSKK のトップディレクトリ@footnote{@file{ChangeLog} や @file{Makefile} が置かれているディレクトリです。}をカレントディレクトリにします。 + +@example +% cd ddskk-@value{SKK-VERSION} +@end example + +@menu +* GNU Emacs へのインストール:: +* XEmacs へのインストール:: +* 対話的なインストール:: +* MELPA によるインストール:: +@end menu + +@node GNU Emacs へのインストール +@subsection GNU Emacs へのインストール + +まずは、DDSKK がどのディレクトリにインストールされるのか確認するため +に @option{what-where} を引数に @command{make} コマンドを実行しましょう。 + +@example +@group +% make what-where +@print{}emacs -batch -q -no-site-file -l SKK-MK -f SKK-MK-what-where +@print{}Loading /home/USER/temp/ddskk-@value{SKK-VERSION}/SKK-CFG... + +@print{}Running in: +@print{} GNU Emacs 25.0.50.10 (x86_64-unknown-linux-gnu, GTK+ Version 3.10.9) @dots{} + +@print{}SKK modules: +@print{} skk-cursor, skk-viper, @dots{} +@print{} -> /path/to/emacs/site-lisp/skk + +@print{}SKK infos: +@print{} skk.info +@print{} -> /path/to/share/info + +@print{}SKK tutorials: +@print{} SKK.tut, SKK.tut.E, NICOLA-SKK.tut, skk.xpm +@print{} -> /path/to/share/skk +@end group +@end example + +emacs の実体ファイルを特定することもできます。 + +@example +$ make what-where EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs +@end example + +また、DDSKK のインストール先ディレクトリを変更したい場合 +は @file{SKK-CFG} ファイルを編集してください。編集後は必ず @command{make what-where} を +実行して表示内容を確認してください。 + +つぎにスーパーユーザになって、 + +@example +$ su +% make install +@end example + +@noindent +と実行すると、実際に DDSKK がインストールされます。 + +あるいは、一般ユーザが自分の home directory を root directory として DDSKK を +インストールするには、 + +@example +% make install PREFIX=~/ +@end example + +@noindent +と、PREFIX を指定して @command{make} を実行します。 + +特定の Emacs を指定する場合は、 + +@example +% make install EMACS=mule +@end example + +@noindent +と指定します。 + +@node XEmacs へのインストール +@subsection XEmacs へのインストール +@cindex APEL + +XEmacs をお使いの場合は、 DDSKK をインストールする前に APEL (APEL 10.8 以 +上を推奨) をインストールして下さい。APEL は次のサイトから入手できます。 + +@uref{http://git.chise.org/elisp/apel/, APEL} + +XEmacs でパッケージとしてインストールする場合は、 +まず、@option{what-where-package} を引数に @command{make} コマンドを実行 +してパッケージのインストール先を確認しましょう。 + +@example +@group +% make what-where-package XEMACS=/usr/bin/xemacs +@print{}xemacs -batch -q -no-site-file -l SKK-MK -f SKK-MK-what-where-package + +@print{} Loading /home/user/temp/ddskk-@value{SKK-VERSION}/SKK-CFG... + +@print{}Running in: +@print{} XEmacs 21.5 (beta29) garbanzo [Lucid] (i386-redhat-linux, Mule) of @dots{} + +@print{}SKK modules: +@print{} skk-cursor, skk-viper, @dots{} +@print{} -> /usr/share/xemacs/site-packages/lisp/skk + +@print{}SKK infos: +@print{} skk.info +@print{} -> /usr/share/xemacs/site-packages/info + +@print{}SKK tutorials: +@print{} SKK.tut, SKK.tut.E, NICOLA-SKK.tut, skk.xpm +@print{} -> /usr/share/xemacs/site-packages/etc/skk +@end group +@end example + +つぎに、スーパーユーザになって @option{install-package} を引数 +に @command{make} を実行すると、実際にインストールされます。 + +@example +@group +% make install-package XEMACS=/usr/bin/xemacs +@print{}xemacs -batch -q -no-site-file -l SKK-MK -f SKK-MK-install-package +@print{} Loading /home/user/temp/ddskk-@value{SKK-VERSION}/SKK-CFG@dots{} +@dots{} +@end group +@end example + +@node 対話的なインストール +@subsection 対話的なインストール + +DDSKK 14.3 では「対話的インストーラ」が追加されました。 + +まず、@kbd{M-x dired} とタイプして dired を起動してください。このとき、デ +ィレクトリを問われますので、先に述べた「DDSKK のアーカイブを展開したディ +レクトリ」を指定してください。 + +@example +@group +------ Minibuffer ------- +Dired (directory): ~/temp/ddskk-@value{SKK-VERSION} @key{RET} +------ Minibuffer ------- +@end group +@end example + +次に、表示されたディレクトリ一覧の @file{SKK-MK} にカーソルをあわせ +て @kbd{L} (@key{SHIFT} を押しながらアルファベットのエル)をタイプしてく +ださい。 + +@example +@group +------ Dired ------- +-rw-r--r-- 1 user user 99999 2011-00-00 00:00 SKK-CFG +-rw-r--r-- 1 user user 99999 2011-00-00 00:00@point{}SKK-MK @kbd{L} +drwxr-xr-x 1 user user 99999 2011-00-00 00:00 bayesian +------ Dired ------- +@end group +@end example + +プロンプト @samp{Load SKK-MK?} には @kbd{y} をタイプしてください。 + +以降、インストーラが表示する質問に答えながら DDSKK のインストールを進めて +ください。なお、パーミッションは一切考慮していませんので、インストール先 +は書き込み権限を有するディレクトリを指定してください。 + +@node MELPA によるインストール +@subsection MELPA によるインストール +@cindex MELPA +@cindex @file{package.el} +@vindex package-archives +@findex package-initialize + +2014年12月、MELPA@footnote{@uref{https://melpa.org/, Milkypostman's Emacs Lisp Package Archive}} +に DDSKK が登録されたことにより GNU Emacs でも @file{package.el} +@footnote{GNU Emacs 24 以降で標準で搭載されています。GNU Emacs 23 以前では手動でインストール必要があります。@* +@url{http://wikemacs.org/wiki/Package.el}} +によるインストールが可能となりました。 + +詳細については、次のドキュメントを参照してください。 + +@url{https://github.com/skk-dev/ddskk/blob/master/READMEs/INSTALL.MELPA.md} + +@node 辞書について +@section 辞書について + +DDSKK を使用するには、いわゆる辞書 (主にかなと漢字の対応を記述したデータ) +が必要です。 + +DDSKK 14.2 からは、 GNU Emacs 同梱の辞書データ @file{ja-dic} を利用した +かな漢字変換に対応しましたので、SKK 辞書ファイルを別途インストールしなく +ても最低限の使用ができます(XEmacs では @file{ja-dic} は利用できませんの +で、後述する SKK 辞書をインストールする必要があります)。 + +しかし、@file{ja-dic} は、 Emacs の入力メソッド LEIM のために @file{SKK-JISYO.L} か +ら変換して生成されたものであり、英数変換や数値変換などのエントリ、および +「大丈夫」など複合語とみなし得る語が大幅に削除されています。 +そのため、@file{SKK-JISYO.L} を利用したかな漢字変換と同等の結果は得られま +せん。 + +有志の知恵を結集して作られている各種 SKK 辞書は便利ですから、是非入手し +てインストールしましょう。 + +@node 辞書の入手 +@section 辞書の入手 + +@table @b +@item SKK 各辞書の解説とダウンロード +@url{http://openlab.jp/skk/wiki/wiki.cgi?page=SKK%BC%AD%BD%F1} + +このサイトには様々な辞書が用意されています。以下は一例です。 +@end table + +@table @code +@item SKK-JISYO.S +S 辞書(主に単漢字が登録。最小限必要な語を収録) + +@item SKK-JISYO.M +M 辞書(普通に使う分には足りる程度) + +@item SKK-JISYO.ML +M 辞書と L 辞書の中間のサイズの辞書。L 辞書収録語の内、EPWING 辞書やオン +ライン辞書で正しいと判別された語をベースにして加除。 + +@item SKK-JISYO.L +L 辞書(あらゆる単語を収録) + +@item zipcode +郵便番号辞書 + +@item SKK-JISYO.JIS2 +JIS X 0208 で定められている第2水準の文字を、部首の読みを見出し語として +単漢字を収録した辞書 + +@item SKK-JISYO.JIS3_4 +JIS 第3水準、第4水準の文字に代表される、JIS X 0208 には含まれない +が JIS X 0213 には含まれる文字及びそれらを含む語録を収録した辞書 + +@item SKK-JISYO.public+ +public+ 辞書 + +@item SKK-JISYO.edict +edict 辞書(英和辞書) + +@item SKK-JISYO.lisp +候補に Emacs Lisp 関数を含むエントリーを集めた辞書。見出し語を変換する過 +程で Emacs Lisp 関数を評価し、その値を候補として表示します。 + +@xref{プログラム実行変換}. + +@item SKK-JISYO.wrong +間違い辞書(S, M, L 辞書に既に登録されていたが、間違いであったので削除さ +れた単語を収録) +@end table + +一部の辞書は、著作権が GNU GPL v2 ではありませんのでご注意下さい。 +詳細は、次の資料を参照して下さい。 + +@url{http://openlab.jp/skk/skk/dic/READMEs/committers.txt} + +@kindex M-x skk-get +@defun {コマンド} skk-get + +Emacs の使用中に @kbd{M-x skk-get} と実行すると、辞書ファイルを一括ダウン +ロードすることができます。 + +なお、GNU Emacs 24.3 以下では tar 展開に対応していないため +@file{SKK-JISYO.edict.tar.gz} と @file{zipcode.tar.gz} は処理されません。 + +@end defun + +@defun skk-get &optional DIRECTORY + +@code{skk-get} を関数として使用することで、ユーザプログラムの中からでも辞 +書ファイルを一括ダウンロードすることができます + +@lisp +@group +(skk-get "~/jisyofiles") +@end group +@end lisp + +@end defun + +@node 辞書を DDSKK と同時にインストールする +@section 辞書を DDSKK と同時にインストールする + +DDSKK のソースを展開すると、中に @file{dic} というディレクトリが存在しま +す。@file{SKK-JISYO.L} などをこのディレクトリにコピーしてから @command{make install} を +実行すると、辞書ファイルがチュートリアル (@file{SKK.tut}) と同じディ +レクトリ (@file{/usr/share/skk} や @file{c:/emacs-24.5/etc/skk} など) に +インストールされます。 + +@file{dic} ディレクトリに辞書ファイルを置くためには @command{make get} と +実行するのが簡単です@footnote{Microsoft Windows 環境では @command{makeit.bat get} と +実行します。}。 + +@file{dic} ディレクトリに辞書ファイルが置かれている場合、@command{make what-where} 実 +行時に辞書ファイルのインストール先も表示します。 + +@example +@group +@print{}SKK dictionaries: +@print{} SKK-JISYO.lisp, SKK-JISYO.zipcode, SKK-JISYO.office.zipcode, @dots{} +@print{} -> c:/emacs-24.5/share/emacs/24.5/etc/skk +@end group +@end example + +@c さらに、@file{SKK-JISYO.L} を DDSKK ソースの @file{dic} ディレクトリにコ +@c ピーしてから @command{make cdb} を実行すると、CDB 形式辞書ファイル @file{SKK-JISYO.L.cdb} が +@c 生成されます@footnote{CDB 形式辞書ファイルの生成には python スクリプト @file{etc/skk2cdb.py} +@c が実行されるので、あらかじめ python 処理系をインストールしておく必要があ +@c ります。}。 +@c この状態で @command{make install} を実行すると @file{SKK-JISYO.L.cdb} も +@c @file{SKK-JISYO.L} と共にインストールされます。 + +@node 辞書サーバの入手 +@section 辞書サーバの入手 + +辞書サーバはオプションです。 +辞書サーバが無くても DDSKK は動作しますが、特に辞書のサイズが大きい場合は +辞書サーバを利用することで省メモリ効果を得られます。また、辞書サーバによ +っては複数辞書の検索、EPWING 辞書の検索ができたりするものもあります。 + +DDSKK は特定の辞書サーバの実装に依存していませんので、下記の辞書サーバの +いずれでも動作可能です。ソースやバイナリの入手、インストールについてはそ +れぞれのウェブサイトをご参照下さい。 + +@table @b +@item 辞書サーバの説明とリンク + +@url{http://openlab.jp/skk/skkserv-ja.html} +@end table + +@node はじめの設定 +@chapter はじめの設定 +@cindex @file{leim-list.el} + +標準的にインストールした場合は、特段の設定なしに Emacs を起動するだけ +で DDSKK が使える状態になります。 +自動的に @file{skk-setup.el} というファイルが読み込まれ、設定されます +@footnote{Emacs が起動する過程(関数@code{normal-top-level})で @file{SKK_LISPDIR/leim-list.el} が読み込まれます。 + +@file{leim-list.el} は @file{skk-autoloads.el} と @file{skk-setup.el} を @code{require} します。 + +@findex register-input-method +@file{skk-autoloads.el} は DDSKK の @command{make} 時に自動的に生成されるファイル +であり、各関数を自動ロード(autoload)するよう定義するほか @code{register-input-method} も +行います。 + +@file{skk-setup.el} はキーバインド(@kbd{C-x C-j} @result{} @code{'skk-mode})、変数 @code{skk-tut-file} の定義及びインクリメンタル・サーチの定義を行っています。}。 + +この自動設定によらずに手動で設定したい場合は、以下の説明を参照してください。 + +@menu +* 最も基本的な設定:: +* インクリメント検索の設定:: +* 辞書サーバを使いたいときの設定:: +* DDSKK を Emacs の Input Method とする:: +@end menu + +@node 最も基本的な設定 +@section 最も基本的な設定 +@vindex skk-cdb-large-jisyo + +自動設定によらず手動で設定する場合は、次の内容を @file{~/.emacs.d/init.el} に書きま +す@footnote{サンプルとして、配布物に @file{etc/dot.emacs}、@file{etc/dot.skk} フ +ァイルがあります。参考にして下さい。}。 + +@lisp +@group +(require 'skk-autoloads) ; @b{XEmacs でパッケージとしてインストールした場合は不要} +(global-set-key "\C-x\C-j" 'skk-mode) +(global-set-key "\C-xj" 'skk-auto-fill-mode) +(global-set-key "\C-xt" 'skk-tutorial) +@end group +@end lisp + +辞書サーバを使わない場合は、辞書ファイルを指定する必要があります。 + +@lisp +(setq skk-large-jisyo "/your/path/to/SKK-JISYO.L") +@end lisp + +@noindent +辞書サーバを使わない場合は Emacs のバッファに @code{skk-large-jisyo} が指 +すファイルを取り込んで使用するためメモリ使用量が増加します。これが支障と +なる場合は、上記の @file{SKK-JISYO.L} を @file{SKK-JISYO.M}、@file{SKK-JISYO.ML} 又 +は @file{SKK-JISYO.S} に変更してください。 + +@cindex CDB 形式辞書ファイル + +DDSKK 14.1 以降は辞書サーバを経由せずとも CDB 形式@footnote{constant database の +こと。詳しくは @url{http://cr.yp.to/cdb.html} 又は @url{http://ja.wikipedia.org/wiki/Cdb} を参照のこと。} +の辞書ファイルを直接利用できるようになりました。CDB 形式辞書ファイル@footnote{ +SKK 辞書 の @file{Makefile} 中の cdb ターゲットを実行することで @file{SKK-JISYO.L} か +ら @file{SKK-JISYO.L.cdb} を生成することができます。} +を利用する場合は、以下のように指定してください。 + +@lisp +(setq skk-cdb-large-jisyo "/your/path/to/SKK-JISYO.L.cdb") +@end lisp + +@noindent +変数 @code{skk-large-jisyo} と 変数 @code{skk-cdb-large-jisyo} を同時に指 +定した場合は、標準では CDB 形式辞書ファイルの方が先に検索されます。これに関して +は @w{@ref{辞書検索の設定の具体例}} も参照してください。 + +@node インクリメント検索の設定 +@section インクリメント検索の設定 +@vindex isearch-mode-hook +@vindex isearch-mode-end-hook + +基本的な設定は @file{skk-setup.el} が読み込まれた時点で完了しています +@footnote{@file{skk-setup.el} では、関数 @code{isearch-mode-hook} に @code{skk-isearch-setup-maybe} を、 +関数 @code{isearch-mode-end-hook} に @code{skk-isearch-cleanup-maybe} を +、それぞれ hook に追加しています。 +@code{skk-isearch-@{setup|cleanup@}-maybe} とも @file{skk-setup.el} で定義されており、 +実態は、関数 @code{skk-isearch-mode-@{setup|cleanup@}} です。}。 + +@defvr {ユーザ変数} skk-isearch-mode-enable + +@code{Non-nil} なら SKK が ON になっているバッファで @code{skk-isearch} を有効 +にします。デフォルトは @code{t} です。 + +@code{nil} に設定すると @code{skk-isearch} を無効にすることができます +@footnote{変数 @code{skk-isearch-mode-enable} は @file{~/.emacs.d/init.el} か @kbd{M-x customize-variable} で設定してください。}。 + +@lisp +(setq skk-isearch-mode-enable nil) +@end lisp + +この変数の値をシンボル @code{'always} に設定すると、 SKK が ON になってい +ないバッファでも @code{skk-isearch} を有効にします。 + +@lisp +(setq skk-isearch-mode-enable 'always) +@end lisp +@end defvr + +@node 辞書サーバを使いたいときの設定 +@section 辞書サーバを使いたいときの設定 + +辞書サーバを使いたいときは、@file{~/.skk} で以下のように設定します。 + +@lisp +@group +(setq skk-server-host "example.org") +(setq skk-server-portnum 1178) +@end group +@end lisp + +@defvr {ユーザ変数} skk-server-host + +辞書サーバが起動しているホスト名又は IP アドレス。 +@end defvr + +@defvr {ユーザ変数} skk-server-portnum + +辞書サーバが使うポート番号。@file{/etc/services} に skkserv のエントリが +記述されていれば @code{skk-server-portnum} を指定する必要は無い。 +@end defvr + +@vindex skk-server-inhibit-startup-server +辞書サーバが起動していなかったときに Emacs から skkserv プロセスを立ち上げる +事もできます。@code{skk-server-inhibit-startup-server} を @code{nil} に +する事でこの機能が有効になります。@ref{サーバ関連} も参照してください。 + +Emacs から立ち上げて利用する事ができる辞書サーバは、 + +@example +skkserv [-p port] [jisyo] +@end example + +@noindent +のようなオプションを受け付け、inetd などを経由せず直接起動するものに限ら +れます。 + +辞書サーバプログラムと辞書ファイルは、次のように設定します。 + +@lisp +@group +(setq skk-server-prog "/your/path/to/skkserv") +(setq skk-server-jisyo "/your/path/to/SKK-JISYO.L") +@end group +@end lisp + +@defvr {ユーザ変数} skk-server-prog + +辞書サーバプログラムをフルパスで指定する。 +@end defvr + +@defvr {ユーザ変数} skk-server-jisyo + +辞書サーバに渡す辞書をフルパスで指定する。辞書サーバによっては独自の方法 +で辞書ファイルを指定して emacs からの指定を無視するものもあります。 +詳しくは各辞書サーバの説明書を読んで下さい。 +@end defvr + +@noindent +これらの設定は、環境変数を利用して下記のようにすることもできます。 +@cindex @code{SKKSERVER} +@cindex @code{SKKSERV} +@cindex @code{SKK_JISYO} + +@table @b +@item B シェルの場合 (sh, bash, ksh, zsh など) + +@example +export SKKSERVER=example.org +export SKKSERV=/your/path/to/skkserv +export SKK_JISYO=/your/path/to/SKK-JISYO.L +@end example + +@item C シェルの場合 (csh, tcsh など) + +@example +setenv SKKSERVER example.org +setenv SKKSERV /your/path/to/skkserv +setenv SKK_JISYO /your/path/to/SKK-JISYO.L +@end example +@end table + +関連項目: @w{@ref{辞書サーバの入手}}、@w{@ref{サーバ関連}} + +@node DDSKK を Emacs の Input Method とする +@section DDSKK を Emacs の Input Method とする +@cindex LEIM +@cindex input method +@cindex @file{skk-leim.el} +@kindex C-\ +@kindex M-x list-input-methods +@kindex M-x set-input-method + +Emacs の標準キーバインドでは @kbd{C-\} をタイプすると +関数 @code{toggle-input-method} を実行します。 +この関数は、変数 @code{default-input-method} が指す input method をトグル切り替えします。 + +変数 @code{default-input-method} の値はおそらく @code{"Japanese"} であり、 +結果として @kbd{C-\} のタイプで LEIM @footnote{Library of Emacs Input Method} を on/off します。 + +使用可能な input method は @kbd{M-x list-input-methods} で確認することができ、 +コマンド @code{set-input-method} を実行する @footnote{@kbd{M-x set-input-method} また +は @kbd{C-x @key{RET} C-\}} ことで input method を切り替えることができます。 + +ファイル @file{skk-leim.el} から生成されるファイル @file{skk-autoloads.el} で input method をふたつ追加しています。 + +@table @b +@item "japanese-skk" + +内容は @code{(skk-mode 1)} です。 + +@item "japanese-skk-auto-fill" + +内容は @code{(skk-auto-fill-mode 1)} です。 +@end table + + +@defvr {ユーザ変数} default-input-method + +Emacs 起動時の input method を DDSKK とするには、@file{~/.emacs.d/init.el} に + +@lisp +(setq default-input-method "japanese-skk") +@end lisp + +と記述してください。 + +@end defvr + +@node 基本的な使い方, 便利な応用機能, はじめの設定, Top +@comment node-name, next, previous, up +@chapter 基本的な使い方 + +本章では、DDSKK の基本的な使用方法を説明します。これを読めば、とりあえず +DDSKK を使ってみるには充分です。 + +DDSKK を使った入力方法に慣れるには、付属のチュートリアルが最適なので、お +試しください。 + +@xref{チュートリアル}. + +なお、次章の「便利な応用機能」は、興味のある個所のみをピックアップして +お読みになるのがいいでしょう。 + +@menu +* 起動と終了:: +* 入力モード:: 文字種別毎のモード +* 変換モード:: 辞書を用いた変換の状態毎のモード +* インクリメンタル・サーチ:: +* チュートリアル:: +@end menu + +@node 起動と終了 +@section 起動と終了 +@kindex C-x C-j +@kindex C-x j + +SKK モードに入るには @kbd{C-x C-j}、もしくは @kbd{C-x j} とタイプします。 +モードラインの左端には、下記のように @w{@samp{--かな:}} が追加されます +@footnote{@file{skk.el} の @code{skk-setup-modeline} にて、@code{mode-line-format} に @code{skk-icon} と @code{skk-modeline-input-mode} を追加しています}。 + +@example +--かな:MULE/7bit----- Buffer-name (Major-mode)--- +@end example + +また、カーソルの色が変化します +@footnote{カラーディスプレイを使用し、カラー表示をサポートしている +Window System 下で対応する Emacs を使用している場合。 + +@w{@xref{入力モードを示すカーソル色に関する設定}.}}。 + +@kbd{C-x C-j}、もしくは @kbd{C-x j} を再度タイプすることで、SKK モードに +入る前のモードに戻り、カーソル色も元に戻ります +@footnote{ただし、@b{「アスキーモード」}を利用すれば SKK モードから抜ける +必要はほとんどありません。 + +@xref{入力モード, , アスキーモード}.}。 + +@defvr {ユーザ変数} skk-status-indicator + +デフォルトはシンボル @code{'left} です。この変数をシンボル @code{'minor-mode} と +設定すれば、インジケータはモードラインのマイナーモードの位置に表示されます。 + +@example +-MULE/7bit----- Buffer-name (Major-mode かな)--- +@end example + +@end defvr + +@defvr {ユーザ変数} skk-preload + +@file{~/.emacs.d/init.el} にて変数 @code{skk-preload} を @code{non-nil} と設定するこ +とにより、DDSKK の初回起動を速くすることができます。 + +@lisp +(setq skk-preload t) +@end lisp + +これは、SKK 本体プログラムの読み込みと変数 @code{skk-search-prog-list} に +指定された辞書の読み込みを Emacs の起動時に済ませてしまうことにより実現し +ています。そのため、Emacs の起動そのものは遅くなりますが、DDSKK を使い始 +めるときのレスポンスが軽快になります。 +@end defvr + +@findex skk-restart +@kindex M-x skk-restart + +@defun {コマンド} skk-restart + +@kbd{M-x skk-restart} と実行すると SKK を再起動します。 +@file{~/.skk} は再ロードしますが、@file{~/.emacs.d/init.el} は再ロードしません。 + +@end defun + +@kindex M-x skk-version + +@defun {コマンド} skk-version + +@kbd{M-x skk-version} と実行すると エコーエリアに SKK のバージョンを表示します。 +@w{@ref{エラーなどの日本語表示}} + +@example +-------------------- Echo Area -------------------- +Daredevil SKK/@value{SKK-VERSION} (CODENAME) +-------------------- Echo Area -------------------- +@end example + +@end defun + +@menu +* SKKオートフィルモード:: +* 辞書の保存:: +@end menu + +@node SKKオートフィルモード +@subsection SKKオートフィルモード +@cindex オートフィル +@cindex Auto Fill +@kindex C-x j + +@kbd{C-x j} とタイプすれば、SKK モードに入ると同時にオートフィルモード +(@pxref{Auto Fill, , Auto Fill, emacs, GNU Emacs Manual}) +をオンにします。 + +既にオートフィルモードがオンになっているバッファで @kbd{C-x j} をタイプす +ると、オートフィルモードは逆にオフになるので注意してください。 + +@kindex M-1 C-x j +@kindex C-u C-x j +バッファの状態にかかわらず強制的にオートフィルモード付で SKK モードに入 +りたい場合は、@kbd{M-1 C-x j} や @kbd{C-u C-x j} などとタイプし、このコ +マンドに正の引数を渡します +@footnote{「引数」については、 + +@display +@ref{Arguments, , Arguments, emacs, GNU Emacs Manual}. +@end display + +@noindent +を参照のこと。}。 + +@kindex C-u -1 C-x j +@kindex M-- C-x j +オートフィルモードをオフにし、かつ SKK モードも終了したい場合には +@w{@kbd{M-- C-x j}} や @w{@kbd{C-u -1 C-x j}} などとタイプし、このコマン +ドに負の引数を渡します。 + +@node 辞書の保存 +@subsection 辞書の保存 +@vindex skk-backup-jisyo +@vindex skk-jisyo + +Emacs を終了するときは、保存前の個人辞書を @file{~/.skk-jisyo.BAK} に退避 +してから、個人辞書 (@pxref{辞書の種類, , 個人辞書})の内容を @file{~/.skk-jisyo} に +保存します。 + +@file{~/.skk-jisyo} や @file{~/.skk-jisyo.BAK} のファイル名を変更したけ +れば、それぞれ @code{skk-jisyo} や @code{skk-backup-jisyo} の値を変更して +下さい。 + +@findex skk-kill-emacs-without-saving-jisyo +@kindex M-x skk-kill-emacs-without-saving-jisyo + +個人辞書を保存せずに Emacs を終了させたい場合には、 + +@example +@kbd{M-x skk-kill-emacs-without-saving-jisyo} +@end example + +@noindent +とタイプします。 + +個人辞書の保存動作について更に詳しくは、@ref{個人辞書の保存動作} を参照 +してください。 + +@node 入力モード +@section 入力モード + +SKK モードは、文字種類による4種類の@b{「入力モード」}と、辞書を用いた +変換の状態により3つの@b{「変換モード」}を持ちます。 + +@menu +* 入力モードの説明:: +* 入力モードを切り替えるキー:: +@end menu + +@node 入力モードの説明 +@subsection 入力モードの説明 + +@table @b +@cindex かなモード +@item 「かなモード」 + +アスキー小文字をひらがなに変換するモード。 + +マイナーモードの表示: @samp{かな} + +カーソル色: 赤系 + +@cindex カナモード +@item 「カナモード」 + +アスキー小文字をカタカナに変換するモード。 + +マイナーモードの表示: @samp{カナ} + +カーソル色: 緑系 + +@cindex 全英モード +@item 「全英モード」 + +アスキー小文字/大文字を全角アルファベット@footnote{JIS X 0208 英字のこと。 +このマニュアルでは「全角アルファベット」と表記する。}に変換するモード。 + +マイナーモードの表示: @samp{全英} + +カーソル色: 黄系 + +@cindex アスキーモード +@item 「アスキーモード」 + +文字を変換しないモード。入力されたキーは @kbd{C-j} を除いて通常の Emacs の +コマンドとして解釈される。 + +マイナーモードの表示: @samp{SKK} + +カーソル色: 背景によりアイボリーかグレイ。 +@end table + +入力モードに伴うカーソル色の変更方法については、 +@ref{入力モードを示すカーソル色に関する設定} を参照してください。 + +@node 入力モードを切り替えるキー +@subsection 入力モードを切り替えるキー + +@table @kbd +@item q +「かなモード」、「カナモード」間をトグルする。 + +@item l +「かなモード」又は「カナモード」から「アスキーモード」へ。 + +@item L +「かなモード」又は「カナモード」から「全英モード」へ。 + +@item C-j +「アスキーモード」又は「全英モード」から「かなモード」へ。 +@end table + +実際にはカナモードや全英モードで長時間入力を続けることはほとんどないの +で、かなモードのままでカナ文字や全英文字を入力する便法が用意されています。 + +@itemize @bullet +@item +@w{@pxref{かなモードからカタカナを入力}} + +@item +@w{@pxref{全英文字の入力}} +@end itemize + +@kindex M-x skk-show-mode +@defvr {ユーザ変数} skk-show-mode-show + +現在の入力モードは、モードラインに表示されています。 + +@ref{起動と終了} + +この変数を @code{Non-nil} とすると、入力モードを切り替えたときにカーソル +付近にも一瞬表示するようになります。 + +@kbd{M-x skk-show-mode} でトグル可能です。 + +@ref{入力モードを示すモードラインの文字列の変更} + +@end defvr + +@defvr {ユーザ変数} skk-show-mode-style + +デフォルトは @code{'inline} です。@code{'tooltip} を指定することも可能です。 + +@ref{インジケータ} + +@end defvr + +@defvr {ユーザ変数} skk-show-mode-inline-face + +@code{'inline} 利用時の face + +@end defvr + +@node 変換モード +@section 変換モード + +変換モードは、次の 3 種類のいずれかです。 + +@table @b +@item 「■モード(確定入力モード)」 + +あるキー入力に対応する文字列を、辞書を用いた文字変換を行わずに直接バッ +ファへ入力するモード。入力モードに応じてローマ字からひらがな、ローマ字か +らカタカナ、あるいはアスキー文字から全角アルファベットへ文字を変換する。 + +@item 「▽モード」 + +辞書変換の対象となる文字列「見出し語」を入力するモード。 + +@item 「▼モード」 + +見出し語について、辞書変換を行うモード。 +@end table + +また、▽モードの変種として @dfn{SKK abbrev mode} があり、▼モードのサブモー +ドとして、@b{「辞書登録モード」}があります。 + +@menu +* ■モード:: 辞書変換を行わない確定入力のモード。 +* ▽モード:: 辞書変換のため見出し語の入力を行うモード。 +* ▼モード:: 辞書変換を行うモード。 +* 辞書登録モード:: 個人辞書へ単語を登録するモード。 +@end menu + +@node ■モード +@subsection ■モード + +@cindex 確定入力 +@cindex 確定入力モード +@cindex ■モード +確定入力モードを@b{「■モード」}と呼びます。■モードでは、あるキー入力に +対応した特定の文字列への変換を行うだけで、辞書変換は行いません。アスキー +文字列から、入力モードに応じて、ひらがな、カタカナ、あるいは全角アルファ +ベットへ文字を変換します。カレントバッファにこのモード特有のマークは表示 +されません。 + +@cindex ローマ字入力 +かなモード、カナモードで、かつ ■モードである場合、デフォルトの入力方法 +はいわゆるローマ字入力です。訓令式、ヘボン式のどちらによっても入力するこ +とができます。主な注意点は以下のとおりです。 + +@itemize @bullet +@item +@samp{ん} は @kbd{n n} 又は @kbd{n '} で入力する。直後に @samp{n}、 +@samp{y} 以外の子音が続くときは @kbd{n} だけで入力できる。 + +@item +促音は、@kbd{c h o t t o} @result{} @samp{ちょっと}、@kbd{m o p p a r a} +@result{} @samp{もっぱら} のように次の子音を重ねて入力する。 + +@item +促音や拗音(ひらがなの小文字)を単独で入力するときは、@kbd{x a} @result{} +@samp{ぁ}、@kbd{x y a} @result{} @samp{ゃ} などのように @kbd{x} を用いる。 + +@item +長音は、@kbd{-} で入力する。@kbd{-} @result{} @samp{ー}。 +@end itemize + +@node ▽モード +@subsection ▽モード + +@cindex 辞書変換対象の文字列の決定 +@cindex ▽モード +@b{「▽モード」}では、辞書変換の対象となる文字列を入力します。かなモード、 +もしくはカナモード@footnote{@xref{入力モード, , かなモード、カナモード}.} +で、かつ、■モードであるときに、キー入力を大文字で開始することで、▽モー +ドに入ります。例えば、 + +@example +@kbd{K a n j i} + +@group +------ Buffer: foo ------ +▽かんじ@point{} +------ Buffer: foo ------ +@end group +@end example + +@noindent +のようにタイプすることで▽モードに入り、続けて辞書変換の対象となる文字 +列「見出し語」を入力します。@samp{▽}マークは「▽モードである」 +という表示ですが、見出し語の開始点を示す表示でもあります。 + +@menu +* 後から▽モードに入る方法:: +* ▽モードを抜ける方法:: +@end menu + +@node 後から▽モードに入る方法 +@subsubsection 後から▽モードに入る方法 +@cindex 後から▽モードに入る方法 +@kindex Q + +辞書変換の対象としたい文字列であったにも関わらず、先頭の文字を大文字で入力し忘れた場 +合は、その位置までポイント@footnote{@xref{Point, ,ポイント, emacs, GNU Emacs Manual}.} +を戻してから @kbd{Q} をタイプすることで、▽モードに入ることができます。例えば、 +下記のように操作します (@point{} の地点にカーソルがあります)。 + +@example +@kbd{k a n j i} + +@group +------ Buffer: foo ------ +かんじ@point{} +------ Buffer: foo ------ +@end group + +@kbd{C-u 3 C-b} + +@group +------ Buffer: foo ------ +@point{}かんじ +------ Buffer: foo ------ +@end group + +@kbd{Q} + +@group +------ Buffer: foo ------ +▽@point{}かんじ +------ Buffer: foo ------ +@end group + +@kbd{C-e} + +@group +------ Buffer: foo ------ +▽かんじ@point{} +------ Buffer: foo ------ +@end group +@end example + +@cindex 数字から始まる見出し語の入力 +@samp{7がつ24にち} のように大文字から始めることができない文字列を見出し語 +としたい場合は、 @kbd{Q} をタイプして▽モードにしてから @samp{7がつ24にち} の +文字列を入力します。 + +なお、▽モードでは、文字列の間に空白を含めることはできません。 +これは、辞書エントリの見出し語に空白を含めることができない制限からきています。 + +@node ▽モードを抜ける方法 +@subsubsection ▽モードを抜ける方法 + +@kindex C-g +@kindex C-j +誤って▽モードに入ってしまったときは、 @kbd{C-j} とタイプして■モードに戻 +るか、 @kbd{C-g} とタイプして見出し語を消去するか、どちらかの方法があります。 +具体例を下記に示します。 + +@example +@kbd{K a n j i} + +@group +------ Buffer: foo ------ +▽かんじ@point{} +------ Buffer: foo ------ +@end group + +@kbd{C-j} + +@group +------ Buffer: foo ------ +かんじ@point{} +------ Buffer: foo ------ +@end group +@end example + +@noindent +あるいは、 + +@example +@kbd{K a n j i} + +@group +------ Buffer: foo ------ +▽かんじ@point{} +------ Buffer: foo ------ +@end group + +@kbd{C-g} + +@group +------ Buffer: foo ------ +@point{} +------ Buffer: foo ------ +@end group +@end example + +@node ▼モード +@subsection ▼モード +@cindex Overlays +@cindex ハイライト +@cindex 暗黙の確定 +@cindex 変換開始 + +@b{「▼モード」} では、▽モードで入力した見出し語を、辞書に従って変換する作 +業を行います。▽モードで見出し語を入力した後に @key{SPC} をタイプするこ +とで▼モードに入ります。@samp{▽} マークから @key{SPC} をタイプしたとき +のポイントまでの文字列が見出し語として確定され、 @samp{▽} マークは +@samp{▼} マークで置き換えられ、この見出し語が辞書の中で検索されます。 + +@menu +* 送り仮名が無い場合:: +* 次候補・前候補:: +* 送り仮名が有る場合:: +@end menu + +@node 送り仮名が無い場合 +@subsubsection 送り仮名が無い場合 + +仮に、辞書に + +@example +かんじ /漢字/幹事/ +@end example + +@noindent +というエントリ +@footnote{本マニュアルでは、見出し語と候補群を合わせた一行を「エントリ」 +と呼びます。詳細は、@ref{送りありエントリと送りなしエントリ}を参照してく +ださい。}を含むとして、例を示します。 + +@example +@kbd{K a n j i} + +@group +------ Buffer: foo ------ +▽かんじ@point{} +------ Buffer: foo ------ +@end group + +@key{SPC} + +@group +------ Buffer: foo ------ +▼漢字@point{} +------ Buffer: foo ------ +@end group +@end example + +@noindent +この例では、▽モードにおける @samp{▽} マークからポイントまでの間の文字列 +@samp{かんじ} を辞書変換の対象文字列として確定し、それについて辞書内での +検索を行っています。実際の変換動作では、候補部分がハイライト表示されます +@footnote{ハイライト表示は FSF Emacs の Overlays、XEmacs の extent の機能を使 +用しています。}。 + +@samp{漢字} が求める語であれば @kbd{C-j} をタイプしてこの変換を +確定します。ハイライト表示も @samp{▼} マークも消えます。 + +また、 @kbd{C-j} をタイプせずに新たな確定入力を続けるか又は新たな変換 +を開始すると、直前の変換は自動的に確定されます。これを @b{「暗黙の確定」} と +呼んでいます。副作用として確定を伴うキーは、印字可能な文字 +全てと @key{RET} です。詳細は @ref{暗黙の確定のタイミング} を参照してく +ださい。 + +@node 次候補・前候補 +@subsubsection 次候補・前候補 + +求める語がすぐに表示されなければ、更に続けて @key{SPC} をタイプすることで、 +次候補を検索します。 + +@example +@group +------ Buffer: foo ------ +▼漢字@point{} +------ Buffer: foo ------ +@end group + +@key{SPC} + +@group +------ Buffer: foo ------ +▼幹事@point{} +------ Buffer: foo ------ +@end group +@end example + +候補が5つ以上あるときは、5番目以降の候補は7つずつまとめて +@footnote{@code{skk-henkan-number-to-display-candidates}} +エコーエリアに表示されます。例えば、辞書が + +@example +@group +きょ /距/巨/居/裾/嘘/拒/拠/虚/挙/許/渠/据/去/ +@end group +@end example + +@noindent +というエントリを含むときに @kbd{K y o} の後に @key{SPC} を5回 +@footnote{skk-show-candidates-nth-henkan-char} +続けてタイプすれば + + +@example +@group +-------------------- Echo Area -------------------- +A:嘘 S:拒 D:拠 F:虚 J:挙 K:許 L:渠 [残り 2] +-------------------- Echo Area -------------------- +@end group +@end example + +@noindent +がエコーエリア +@footnote{エコーエリアとミニバッファは視覚的には同一の場所にありますが、 +エコーエリアが単にユーザへのメッセージを表示するのみであるのに対し、ミ +ニバッファは独立したバッファとして機能する点が異なります。}に表示されます。 +ここで仮に @samp{許} を選択したければ @kbd{k} を入力します。 + +@samp{A}, @samp{S}, @samp{D}, @samp{F}, @samp{J}, @samp{K}, @samp{L} の +各文字は、押し易さを考慮してキーボードのホームポジションから横方向に一直 +線に配置されているキーが選ばれています。また、候補の選択のために押すキー +は、大文字、小文字のいずれでも構いません。候補の選択に用いるキーの変更に +ついては、@w{@ref{候補の選択に用いるキー}} を参照してください。 + +@key{SPC} を連打してしまい求める候補を誤って通過してしまったときは +@kbd{x} をタイプすれば前候補/前候補群に戻ることができます +@footnote{@samp{x} は小文字で入力する必要があります}。 + +候補を次々と探しても求める語がなければ、自動的に辞書登録モードになります +(辞書登録モードは▼モードのサブモードです) 。 +@ref{辞書登録モード}にて説明します。 + +@defvr {ユーザ変数} skk-previous-candidate-keys +前候補/前候補群に戻る関数 @code{skk-previous-candidate} を割り当てるオブ +ジェクトのリストを指定する。 +オブジェクトにはキーを表す文字列または event vector が指定できます。 + +デフォルトは @code{(list "x" "\C-p")} です。 +@end defvr + +@defvr {ユーザ変数} skk-search-excluding-word-pattern-function +詳しくは docstring を参照のこと。 +@end defvr + +@defvr {ユーザ変数} skk-show-candidates-nth-henkan-char +候補一覧を表示する関数 @code{skk-henkan-show-candidates} を呼び出すまで +の @code{skk-start-henkan-char} を打鍵する回数。2 以上の整数である必要。 +@end defvr + +@defvr {ユーザ変数} skk-henkan-number-to-display-candidates +いちどに表示する候補の数。 +@end defvr + +@node 送り仮名が有る場合 +@subsubsection 送り仮名が有る場合 + +次に送り仮名のある単語について説明します。 + +@samp{動く} を変換により求めたいときは @kbd{U g o K u} のように、まず ▽ +モード に入るために @kbd{U} を大文字で入力し、次に送り仮名の開始を DDSKK +に教えるために @kbd{K} を大文字で入力します。送り仮名の @kbd{K} をタイプ +した時点で @key{SPC} をタイプすることなく、▼モード に入り辞書変換が行わ +れます。 + +送り仮名の入力時(ローマ字プレフィックスが挿入された瞬間)、プレフィック +スの直前に @samp{*} を一瞬挿入し、送り仮名の開始時点を明示します。プレ +フィックスに続くキー入力で、かな文字が完成した時点で @samp{*} は消えます。 + +キー入力を分解して追いながらもう少し詳しく説明します。 + +@example +@kbd{U g o} + +@group +------ Buffer: foo ------ +▽うご@point{} +------ Buffer: foo ------ +@end group + +@kbd{K} + +@group +------ Buffer: foo ------ +▽うご*k@point{} +------ Buffer: foo ------ +@end group + +@kbd{u} + +@group +------ Buffer: foo ------ +▼動く@point{} +------ Buffer: foo ------ +@end group +@end example + +このように、DDSKK では送り仮名の開始地点をユーザが明示的に入力するので、 +システム側で送り仮名を分解する必要がありません。これにより、高速でヒット +効率が高い変換が可能になります。@xref{送り仮名の自動処理}. + +ただし、サ変動詞の変換では、サ変動詞の語幹となる名詞を @b{「送りなし変換」} +@footnote{詳細は、@ref{送り仮名が無い場合}を参照してください。} +として変換し、その後 @samp{する} を■モードで入力した方が効率が良くなり +ます。@xref{サ変動詞の辞書登録に関する注意, , サ変動詞の入力}. + +@node 辞書登録モード +@subsection 辞書登録モード + +@cindex 辞書登録 +DDSKK には独立した辞書登録モードはありません。その代わり、辞書にない単語に +関して変換を行った場合に、自動的に辞書登録モードに入ります。例えば辞書に + +@example +へんかんちゅう /変換中/ +@end example + +@noindent +のエントリがない場合に、@samp{変換中} を入力しようとして、@w{@kbd{H e n +k a n t y u u @key{SPC}}} とタイプすると、下記のように、カレントバッファ +は ▼モード のまま @samp{へんかんちゅう} に対して変換ができない状態で休 +止し、同時にミニバッファに @samp{へんかんちゅう} というプロンプトが表示 +されます。 + +@example +@group +------ Buffer: foo ------ +▼へんかんちゅう +------ Buffer: foo ------ + +------ Minibuffer ------- +[辞書登録] へんかんちゅう: @point{} +------ Minibuffer ------- +@end group +@end example + +@menu +* 送り仮名が無い場合の辞書登録:: +* 送り仮名が有る場合の辞書登録:: +* サ変動詞の辞書登録に関する注意:: +* 再帰的辞書登録:: +* 改行文字を含む辞書登録:: +@end menu + +もちろん、誤って登録した単語は削除できます。 +(@w{@pxref{誤った登録の削除}}, @w{@pxref{個人辞書ファイルの編集}}) + +@defvr {ユーザ変数} skk-read-from-minibuffer-function +この変数に「文字列を返す関数」を収めると、その文字列を辞書登録モードに入 +ったときのプロンプトに初期表示します。関数 @code{read-from-minibuffer} の +引数 INITIAL-CONTENTS に相当します。 + +@lisp +@group +(setq skk-read-from-minibuffer-function + (lambda () skk-henkan-key)) +@end group +@end lisp + +@end defvr + +@defvr {ユーザ変数} skk-jisyo-registration-badge-face + +変数 @code{skk-show-inline} が @code{non-nil} であれば、辞書登録モードに +移ったことを明示するためにカレントバッファに「@b{↓辞書登録中↓}」とイン +ライン表示します。この「↓辞書登録中↓」に適用するフェイスです。 + +@end defvr + +@node 送り仮名が無い場合の辞書登録 +@subsubsection 送り仮名が無い場合の辞書登録 + +@noindent +辞書登録モードでは、キー入力はミニバッファに対して行われます。仮に辞書に + +@example +@group +へんかん /変換/ +ちゅう /中/ +@end group +@end example + +@noindent +のようなエントリがあるとして、ミニバッファで @samp{変換中} の文字列を +@samp{変換} と @samp{中} とに分けて作ります。 + +@example +@group +@kbd{H e n k a n @key{SPC} T y u u @key{SPC}} + +----------- Minibuffer ------------ +[辞書登録] へんかんちゅう: 変換▼中@point{} +----------- Minibuffer ------------ +@end group +@end example + +@cindex 暗黙の確定 +@noindent +ここで @key{RET} をタイプすれば @samp{変換中} が個人辞書に登録され、辞書 +登録モードは終了します +@footnote{ここでは「暗黙の確定」が行われるので @kbd{C-j} をタイプする必要 +はありません。ただし、@ref{▼モードでのRET} を参照してください。}。 +同時に、変換を行っているカレントバッファには @samp{変換中} が挿入され確定 +されます。@xref{辞書の種類, , 個人辞書}. + +辞書登録モードを抜けたいときは @kbd{C-g} をタイプするか、または何も登録 +せず @key{RET} をタイプすると▽モードに戻ります。 + +@node 送り仮名が有る場合の辞書登録 +@subsubsection 送り仮名が有る場合の辞書登録 + +送り仮名のある単語の登録では、ミニバッファで作る候補に送り仮名そのものを +登録しないように注意しなければいけません。仮に辞書に + +@example +うごk /動/ +@end example + +@noindent +というエントリがないとして、例を挙げて説明します。 + +@example +@group +@kbd{U g o K u} + +@end group +@group +------ Buffer: foo ------ +▼うごく +------ Buffer: foo ------ + +------ Minibuffer ------- +[辞書登録] うご*く: @point{} +------ Minibuffer ------- +@end group +@end example + +@noindent +ミニバッファで辞書登録すべき文字列は @samp{動} だけであり、送り仮名の +@samp{く} は含めてはいけません。 @samp{動く} と登録してしまうと、次に +@kbd{U g o K u} とタイプしたときに出力される候補が @samp{動くく} になっ +てしまいます。 + +@example +@group +@kbd{D o u @key{SPC}} + +@end group +@group +------ Minibuffer ------- +[辞書登録] うご*く: 動@point{} +------ Minibuffer ------- + +@end group +@key{RET} +@group + +------ Buffer: foo ------ +動く@point{} +------ Buffer: foo ------ +@end group +@end example + +@defvr {ユーザ変数} skk-check-okurigana-on-touroku + +デフォルトは @code{nil} です。@code{non-nil} であれば、辞書登録時に送り仮 +名のチェックを行います。 + +シンボル @code{ask} を設定すれば、ユーザに確認を求め、送り仮名と認められ +れば送り仮名を取り除いてから登録します。 + +シンボル @code{auto} を設定すれば、ユーザに確認を求めず、勝手に送り仮名を +判断して削除してから登録します。 + +@end defvr + +@node サ変動詞の辞書登録に関する注意 +@subsubsection サ変動詞の辞書登録に関する注意 +@cindex サ変動詞の辞書登録に関する注意 + +サ変動詞(名詞の後に @samp{する} を付けた形で構成される動詞)については +@samp{する} を送り仮名とした送りあり変換 (@w{@pxref{送り仮名が有る場合}}) +をしないで、@samp{運動} と @samp{する} とに分けて入力することを前提として +います。@footnote{@file{SKK-JISYO.L} など共有辞書のメンテナンス上、原則と +してサ変動詞を送りありエントリに追加していません。そのため、@samp{する} を +送り仮名とした送りあり変換では、辞書に候補がなく辞書登録モードに入ってし +まうので、名詞として分解して入力することが一般的です。ただし、DDSKK 13 以 +降では暫定的にサ変動詞の送りあり変換を可能にする機能を用意しました。 +(@w{@pxref{サ変動詞変換}})} + +例えば @samp{運動する} は @kbd{U n d o u @key{SPC} s u r u} とタイプする +ことにより入力できます。名詞から作られる形容詞等も同様です。 + +@node 再帰的辞書登録 +@subsubsection 再帰的辞書登録 + +@cindex 再帰的辞書登録 +ミニバッファを再帰的に使って辞書登録を再帰的に行うことができます。 + +仮に辞書に + +@example +@group +さいきてき /再帰的/ +さいき /再帰/ +@end group +@end example + +@noindent +のようなエントリがなく、かつ + +@example +@group +さい /再/ +き /帰/ +てき /的/ +@end group +@end example + +@noindent +のようなエントリがあるとします。 + +ここで @kbd{S a i k i t e k i @key{SPC}} とタイプすると、見出し語 @samp{さ +いきてき} に対する候補を見つけられないので、ミニバッファに @samp{さいき +てき} というプロンプトを表示して辞書登録モードに入ります。 + +@samp{さいきてき} に対する辞書エントリを作るため @kbd{S a i k i @key{SPC}} +とタイプすると、更にこの候補も見つけられないので、ミニバッファに +@samp{さいき} というプロンプトを表示して、再帰的に @samp{さいき} の辞書 +登録モードに入ります。 + +@kbd{S a i @key{SPC} K i @key{SPC}} とタイプすると、ミニバッファは、 + +@example +------ Minibuffer ------- +[[辞書登録]] さいき: 再▼帰 +------ Minibuffer ------- +@end example + +@noindent +となります。プロンプトが @samp{[[辞書登録]]} となり、@samp{[]} がひとつ増 +えていますが、この @samp{[]} の数が再帰的な辞書登録モードの深さを表わして +います。ここで @key{RET} をタイプすると、個人辞書には + +@example +さいき /再帰/ +@end example + +@noindent +というエントリが登録され、ミニバッファは @samp{さいきてき} の辞書登録モー +ドに戻り、プロンプトは @samp{さいきてき} となります。 + +今度は @samp{再帰} が変換可能なので @kbd{S a i k i @key{SPC} T e k i +@key{SPC}} とタイプすると、 + +@example +------ Minibuffer ------- +[辞書登録] さいきてき: 再帰▼的 +------ Minibuffer ------- +@end example + +@noindent +となります。ここで @key{RET} をタイプすることで、@samp{さいきてき} の辞 +書登録モードから抜け、個人辞書に + +@example +さいきてき /再帰的/ +@end example + +@noindent +というエントリが登録されます。カレントバッファのポイントには、@samp{再帰 +的} が挿入されます。 + +@node 改行文字を含む辞書登録 +@subsubsection 改行文字を含む辞書登録 +@kindex C-q C-j + +@cindex 改行文字を含む文字列の辞書登録 +改行文字を含む文字列を辞書に登録するには、辞書登録モードで改行文字を +@kbd{C-q C-j} により入力します。例えば、 + +@example +@group +〒980 +仙台市青葉区片平2-1-1 +東北大学電気通信研究所 +@end group +@end example + +@noindent +を辞書に登録するには、辞書登録モードで、 + +@example +@group +@samp{〒980} +@kbd{C-q C-j} +@samp{仙台市青葉区片平2-1-1} +@kbd{C-q C-j} +@samp{東北大学電気通信研究所} +@key{RET} +@end group +@end example + +@noindent +と入力します。 + +@node インクリメンタル・サーチ +@section インクリメンタル・サーチ +@cindex @file{isearch.el} +@cindex I-search +@cindex Incremental search + +DDSKK では、専用のインクリメンタル・サーチプログラムを Emacs 添付の +@file{isearch.el} のラッパーとして実装しているため、日本語文字列のイ +ンクリメンタル・サーチをアスキー文字と同様の操作で行うことができます。 + +@menu +* skk-isearchの操作性:: +* skk-isearchと入力モード:: +@end menu + +@node skk-isearchの操作性 +@subsection skk-isearchの操作性 + +大部分の動作は、Emacs オリジナルのインクリメンタル・サーチのままですから、 +Emacs オリジナルのインクリメンタル・サーチ +@footnote{@w{@ref{Incremental Search, ,Incremental Search, emacs, GNU Emacs Manual}.}} +のコマンド +@footnote{@kbd{M-y} の @code{isearch-yank-kill} や @kbd{M-p} の +@code{isearch-ring-retreat}, @kbd{M-n} の @code{isearch-ring-advance} な +ど}やユーザ変数でのカスタマイズ @footnote{@code{search-highlight} など} +もそのまま利用できます。 + +インクリメンタル・サーチ中の入力方法は、通常のバッファにおける各入力モー +ド、変換モードでの入力方法と同一です。 + +@kindex C-r +@kindex C-s +@kindex M-C-s +@kindex M-C-r +@kbd{C-s} や @kbd{C-r}、あるいは @kbd{M-C-s} や @kbd{M-C-r} でインクリメ +ンタル・サーチを起動すると、インクリメンタル・サーチを起動したバッファの +入力モードと同一の入力モードで、キーとなる文字の入力が可能となります。 + +@node skk-isearchと入力モード +@subsection skk-isearchと入力モード + +@vindex skk-isearch-mode-string-alist + +入力モードに合わせて、インクリメンタル・サーチのプロンプトが表示されます。 +プロンプトの種類は、以下の 6 つです@footnote{変数 @code{skk-isearch-mode-string-alist} を適宜設定することにより変更が可能です。}。 + +@table @samp + +@item I-search: [か] +かなモード + +@item I-search: [カ] +カナモード + +@item I-search: [英] +全英モード + +@item I-search: [aa] +アスキーモード + +@item I-search: [aあ] +Abbrev モード + +@item I-search: [--] +インクリメンタル・サーチモードで @kbd{C-x C-j} などをタイプして DDSKK を +終了した場合は、このプロンプトが表示されます。 + +@end table + +@node チュートリアル +@section チュートリアル + +@cindex チュートリアル +@vindex skk-tut-file +@findex skk-tutorial +@kindex M-x skk-tutorial +DDSKK には、基本的な操作方法を学習できるチュートリアルが附属しています。 +日本語版チュートリアルは @kbd{M-x skk-tutorial} で、英語版チュートリアルは +@kbd{C-u M-x skk-tutorial @key{RET} English @key{RET}} で実行します。 + +@defvr {ユーザ変数} skk-tut-file + +チュートリアルファイルが標準の場所に置かれていない場合は、 @file{~/.emacs.d/init.el} で + +@lisp +(setq skk-tut-file "/usr/local/share/skk/SKK.tut") +@end lisp + +@noindent +と書くことにより、指定したチュートリアルファイルを使用させることが +できます。英語版のチュートリアルファイルは、 @samp{skk-tut-file} に @file{.E} +が付いたファイル名です。この場合であれば、 +@file{/usr/local/share/skk/SKK.tut.E} になります。 + +@end defvr + +@defvr {ユーザ変数} skk-tut-lang +チュートリアルで用いる言語を文字列(@code{"Japanese"} 又 +は @code{"English"})で指定します。 +この変数よりも @kbd{C-u M-x skk-tutorial} による言語指定が優先されます。 + +@end defvr + +@defvr {ユーザ変数} skk-tut-use-face + +@code{Non-nil} であれば、チュートリアルで face を利用して表示する。 + +@end defvr + +@node 便利な応用機能 +@chapter 便利な応用機能 + +@menu +予備知識 +* ファイル構成:: 応用機能を使いこなすための予備知識。 +* ユーザオプションの設定方法:: + +@noindent +入力関係 +* カタカナ、英字入力の便法:: これと次の項は絶対、便利です。 +* 補完:: 「かしたん」 + Tab -> 「かしたんぽせきにん」 +* 便利な変換、その他の変換:: 単漢字、接頭辞、漢数字、等々。 + +@noindent +様々な設定 +* キー設定:: ローマ字のルールなども変更できます。 +* 変換、確定の前後:: 誤変換の訂正、一発確定、確定のタイミングなど +* 送り仮名関連:: 送り仮名の処理について。 +* 候補の順序:: 関連のある語は上位に表示など、効率を求めて +* 辞書関連:: 辞書にまつわる設定及び機能。 + +@noindent +他 +* 注釈 (アノテーション):: +* 文字コード関連:: 文字コードにまつわる機能。 +* DDSKK 以外のツールを用いた辞書変換:: +* 飾りつけ:: 様々な表示の設定。 +* ユーザガイダンス関連:: +* I-search関連:: インクリメンタル・サーチにまつわる機能。 +* VIP/VIPERとの併用:: +* picture-modeとの併用:: picture-mode との併用の際の問題点。 +@end menu + +@node ファイル構成 +@section ファイル構成 +@cindex @file{ccc.el} +@cindex @file{leim-list.el} +@cindex @file{skk.el} + +SKK の基本的な機能は、@file{skk.el} に収められています。一方、 +DDSKK で応用機能を提供するプログラムのほとんどは @file{skk.el} と +は別のファイルに収めています。これらは、必要に応じてオートロードするよう +に設計されています。各応用機能の概略と該当のファイル名について説明します。 + +@cindex @file{skk-vars.el} +また、DDSKK の変数は @file{skk-vars.el} に集約されていますので、カスタマ +イズしたい場合などには、このファイルを見ると参考になるかもしれません。 + +@table @file + +@item ccc.el + +@item cdb.el + +@item context-skk.el +@cindex @file{context-skk.el} + +編集の文脈に応じて自動的に skk のモードを切り替えたり、SKK の各種設定を変 +更する機能を提供します。 + +@xref{文脈に応じた自動モード切り替え}. + +@item ddskk-pkg.el + +@item skk-abbrev.el +@cindex @file{skk-abbrev.el} + +SKK abbrev モードの機能を提供するプログラムを集めたファイル。 + +@xref{アスキー文字を見出し語とした変換, , SKK abbrev mode}. + +@item skk-act.el +@cindex @file{skk-act.el} + +dvorak 配列での拡張ローマ字入力 "ACT" を SKK で使うための設定を提供しま +す。 + +@xref{ACT}. + +@item skk-annotation.el +@cindex @file{skk-annotation.el} + +個人辞書に付けたアノテーション (注釈) を活用するプログラムを集めたファイ +ル。 + +@xref{注釈 (アノテーション)}. + +@item skk-auto.el +@cindex @file{skk-auto.el} + +送り仮名の自動処理を行うプログラムを集めたファイル。 + +@xref{送り仮名の自動処理}. + +@item skk-autoloads.el +@cindex @file{skk-autoloads.el} + +make 時に自動生成されるファイル。オートロードの設定のほか、@code{register-input-method} も行う。 + +@xref{はじめの設定}. + +XEmacs で DDSKK をパッケージとしてインストールした場合 +は @file{auto-autoloads.el} というファイルがこれに相当します。 + +@item skk-azik.el +@cindex @file{skk-azik.el} + +拡張ローマ字入力 "AZIK" の設定を提供します。 + +@xref{AZIK}. + +@item skk-bayesian.el +@cindex @file{bayesian/skk-bayesian.el} + +SKK の学習機能のひとつで、ユーザの過去の入力から変換候補を予測します。 + +@xref{ベイズ統計を用いた学習}. + +@item skk-cdb.el +@cindex @file{skk-cdb.el} + +CDB 形式辞書ファイルを辞書サーバなしに直接利用できるプログラム。 + +@xref{最も基本的な設定}. + +@item skk-comp.el +@cindex @file{skk-comp.el} + +見出し語の補完を行うプログラムを集めたファイル。 + +@xref{補完}. + +@item skk-cursor.el +@cindex @file{skk-cursor.el} + +カーソルの色を制御するプログラムを集めたファイル。 + +@xref{入力モードを示すカーソル色に関する設定}. + +@item skk-cus.el +@cindex @file{skk-cus.el} +@kbd{M-x customize-group} による対話的な設定変更機能の簡易版を提供します。 + +@xref{Customize による設定変更}. + +@item skk-dcomp.el +@cindex @file{skk-dcomp.el} + +skk-comp による補完を自動的に実行して見出し語入力を支援します。 + +@xref{動的補完}. + +@item skk-develop.el +@cindex @file{skk-develop.el} + +おもに開発者向けのプログラムを集めたファイル。 + +@kbd{M-x skk-submit-bug-report} バグレポートのメールバッファを用意する + +@kbd{M-x skk-get} 辞書ファイルを一括ダウンロードする + +font-lock 関係 + +@item skk-emacs.el +@cindex @file{skk-emacs.el} + +(DDSKK 14.1 以前のファイル名: @file{skk-e21.el}) + +GNU Emacs 21 以降の拡張機能を利用するプログラムを集めたファイル。 +インジケータのカラー化や画像表示、ツールティップ利用など。 + +@item skk-gadget.el +@cindex @file{skk-gadget.el} + +プログラム実行変換を行うプログラムを集めたファイル。 + +@xref{プログラム実行変換}. + +@item skk-hint.el +@cindex @file{skk-hint.el} + +SKK の変換候補が多いときにヒントを与えて絞りこむ機能を提供します。 + +@xref{候補の絞り込み}. + +@item skk-inline.el +@cindex @file{skk-inline.el} + +変換候補のインライン表示機能を集めたファイル。 + +@xref{変換候補一覧の表示方法}. + +@item skk-isearch.el +@cindex @file{skk-isearch.el} + +DDSKK を併用したインクリメンタル・サーチ機能を提供します。 + +@xref{I-search関連}. + +@item skk-jisx0201.el +@cindex @file{skk-jisx0201.el} + +JIS X 0201 カナ@footnote{いわゆる半角カナ。以下、このマニュアルでは「半角 +カナ」と記述します。}を利用する機能を提供します。 + +@item skk-jisx0213.el +@cindex @file{skk-jisx0213.el} + +JIS X 0213 文字集合を扱うプログラムです。 + +@item skk-jisyo-edit-mode.el +@cindex @file{skk-jisyo-edit-mode.el} + +SKK 辞書を編集するためのメジャーモードを提供します。 + +@item skk-kakasi.el +@cindex @file{skk-kakasi.el} + +KAKASI インターフェイスプログラムを集めたファイル。 + +@xref{領域の操作}. + +@item skk-kanagaki.el +@cindex @file{skk-kanagaki.el} + +キーボードのかな配列などに対応する枠組みを提供します。 +現段階では旧 JIS 配列のかなキーボード及び NICOLA 規格の親指シフト配 +列に対応しています。 + +@xref{かな入力と親指シフト}. + +@item skk-kcode.el +@cindex @file{skk-kcode.el} + +文字コードまたはメニューによる文字入力を行うプログラムを集めたファイル。 + +@xref{文字コードまたはメニューによる文字入力}. + +@item skk-leim.el +@cindex @file{skk-leim.el} + +LEIM 関連プログラムファイル。DDSKK を Emacs の input method として利用で +きるようにします。 + +@xref{DDSKK を Emacs の Input Method とする}. + +@item skk-look.el +@cindex @file{skk-look.el} + +@command{look} コマンドとのインターフェイスプログラムを集めたファイル。 + +@xref{skk-look}. + +@item skk-lookup.el +@cindex @file{skk-lookup.el} + +Lookup で検索できる辞書を使って単語の候補を出力するプログラム。 + +@xref{skk-lookup}. + +@item skk-macs.el +@cindex @file{skk-macs.el} + +他のファイルで共通して使用するマクロなどを中心にまとめたファイル。 + +@item skk-num.el +@cindex @file{skk-num.el} + +数値変換を行うプログラムを集めたファイル。 + +@xref{数値変換}. + +@item skk-search-web.el + +Google CGI API for Japanese Input を利用したかな漢字変換。 + +辞書登録モードに Google サジェスト を初期表示する。 + +@xref{Google CGI API for Japanese Input を利用したかな漢字変換}. + +@item skk-server-completion.el +@cindex @file{skk-server-completion.el} + +拡張された辞書サーバによる見出し語補完機能を利用できます。 + +@xref{サーバコンプリージョン}. + +@item skk-server.el +@cindex @file{skk-server.el} + +辞書サーバと通信して変換する機能を提供します。 + +@xref{サーバ関連}. + +@item skk-setup.el +@cindex @file{skk-setup.el} + +自動的に個人設定を行うためのファイル。 + +@xref{はじめの設定}. + +@item skk-show-mode.el +@cindex @file{skk-show-mode.el} + +カーソル付近に入力モードを表示する機能を提供します。 + +@xref{入力モードを切り替えるキー}. + +@item skk-sticky.el +@cindex @file{skk-sticky.el} + +変換開始位置及び送り開始位置の指定方法を変更可能にする。 + +@xref{変換位置の指定方法}. + +@item skk-study.el +@cindex @file{skk-study.el} + +直前に確定したいくつかの語との関連性を確認し、候補順を操作する学習効果 +を提供するプログラム。 + +@xref{変換の学習}. + +@item skk-tankan.el +@cindex @file{skk-tankan.el} + +SKK を使って単漢字変換を行うプログラムです。 + +@xref{単漢字変換}. + +@item skk-tut.el +@cindex @file{skk-tut.el} + +SKK チュートリアルプログラム。 + +@xref{チュートリアル}. + +@item skk-tutcode.el +@cindex @file{skk-tutcode.el} + +SKK で TUT-code 入力を実現します。 + +@xref{TUT-code}. + +@item skk-vars.el + +@item skk-version.el +@cindex @file{skk-version.el} + +DDSKK のバージョン情報を提供するプログラムファイル。 + +@item skk-viper.el +@cindex @file{skk-viper.el} + +VIPER インターフェイスプログラムを集めたファイル。 + +@xref{VIP/VIPERとの併用}. + +@item skk-xemacs.el +@cindex @file{skk-xemacs.el} + +XEmacs の拡張機能を利用するプログラムを集めたファイル。 +インジケータのカラー化や画像表示、ツールティップ利用など。 + +@item tar-util.el + +@end table + +@node ユーザオプションの設定方法 +@section ユーザオプションの設定方法 + +@cindex @file{~/.emacs.d/init.el} +@cindex @file{~/.xemacs/init.el} +@cindex @file{~/.skk} +DDSKK のカスタマイズは、@file{~/.emacs.d/init.el} あるいは @file{~/.skk} に記述し +ます。また、各ファイルの提供するフックも利用します。上記のファイルやフッ +クを利用した設定がいつ有効になるのか、という点についてここで説明します。 + +@menu +* 設定ファイル:: +* フック:: +* Customize による設定変更:: このマニュアルで解説されていない変数も設定できます。 +* skk-customize による設定変更:: +@end menu + +@node 設定ファイル +@subsection 設定ファイル + +@table @file +@item ~/.emacs.d/init.el +@itemx ~/.xemacs/init.el + +Emacs を起動したときに一度だけ読み込まれます。 +このマニュアルは @file{~/.emacs.d/init.el} という記述で統一しています。 + +@xref{Init File, ,Emacs Initialization File, emacs, GNU Emacs Manual}. + +@item ~/.skk + +DDSKK を起動した最初の一度だけ読み込まれます。ファイル名のデフォルトは、OS +の種類により異なりますが、実際は Emacs の関数 +@code{convert-standard-filename} により加工されます。 +@findex convert-standard-filename +@file{~/.skk} のファイル名は変数 @code{skk-init-file} で変更することがで +きます。また、DDSKK にはこのファイルを自動的にバイトコンパイルする機能が +あります。 + +@xref{skk-init-fileの自動コンパイル}. +@end table + +@defvr {ユーザ変数} skk-user-directory +DDSKK は、@file{~/.skk} や @file{~/.skk-jisyo} といった複数のファイルを +使用します。これらのファイルをひとつのディレクトリにまとめて置きたい場合 +は、変数 @code{skk-user-directory} にそのディレクトリ名を設定します。 + +この変数のデフォルトは @code{nil} です。この変数は @file{~/.emacs.d/init.el} で設定 +してください。DDSKK 起動時に @code{skk-user-directory} が指すディレクトリ +が存在しない場合は、自動的に作られます。 + +@lisp +(setq skk-user-directory "~/.ddskk") +@end lisp + +この変数を設定した場合(例えば上記 @code{~/.ddskk})、以下に挙げる各変 +数のデフォルト値が変更されます。 + +@example +@group +影響を受ける変数 デフォルト値 変更後のデフォルト値 +skk-init-file ~/.skk ~/.ddskk/init +skk-jisyo ~/.skk-jisyo ~/.ddskk/jisyo +skk-backup-jisyo ~/.skk-jisyo.BAK ~/.ddskk/jisyo.bak +skk-emacs-id-file ~/.skk-emacs-id ~/.ddskk/emacs-id +skk-record-file ~/.skk-record ~/.ddskk/record +skk-study-file ~/.skk-study ~/.ddskk/study +skk-study-backup-file ~/.skk-study.BAK ~/.ddskk/study.bak +skk-bayesian-history-file ~/.skk-bayesian ~/.ddskk/bayesian +skk-bayesian-corpus-file ~/.skk-corpus ~/.ddskk/corpus +@end group +@end example + +なお、@code{skk-user-directory} を設定した場合でも、各変数を個別に設定し +ている場合はその個別の設定が優先されます。 + +@end defvr + +@menu +* skk-init-fileの自動コンパイル:: +@end menu + +@node skk-init-fileの自動コンパイル +@subsubsection skk-init-fileの自動コンパイル + +@defvr {ユーザ変数} skk-byte-compile-init-file + +@cartouche +@smallformat +ここでは +@itemize @minus +@item 「DDSKK の設定ファイル」を @code{el} と、 +@item 「DDSKK の設定ファイルをバイトコンパイルしたファイル」を @code{elc} と +@end itemize + +それぞれ呼ぶこととします。 +@end smallformat +@end cartouche + +DDSKK の起動時に、 + +@itemize @bullet +@item この変数の値が @code{non-nil} であれば、 + +@itemize @minus +@item @code{elc} が存在しないか、又は +@item @code{elc} よりも @code{el} が新しいとき +@end itemize + +は、@code{el} をバイトコンパイルした @code{elc} を生成します。 + +@item この変数の値が @code{nil} であれば、 + +@code{elc} よりも @code{el} が新しいときは、@code{elc} を消去します。 +@end itemize + +以上の機能を有効にしたい場合は、@file{~/.emacs.d/init.el} に + +@lisp +(setq skk-byte-compile-init-file t) +@end lisp + +@noindent +と記述します。この変数は @file{~/.skk} が読み込まれる前に調べられるた +め、@file{~/.skk} に上記の設定を記述してもこの機能は有効になりません。 +@end defvr + +@node フック +@subsection フック + +@table @code +@item skk-mode-hook +@vindex skk-mode-hook + +@kbd{C-x C-j} と入力して SKK モードに入る度に呼ばれます。主にバッファロー +カルの設定などを行います。 + +@item skk-auto-fill-mode-hook +@vindex skk-auto-fill-mode-hook + +@kbd{C-x j} と入力してオートフィルモード付きで SKK モードに入る度に呼ば +れます。主にバッファローカルの設定などを行います。 + +@item skk-load-hook +@vindex skk-load-hook + +@file{skk.el} の読み込みを完了した時点で呼ばれます。@file{~/.skk} は SKK +モードを起動しなければ読み込まれないのに対し、このフックは、 +@file{skk.el} を読み込んだら SKK モードを起動しなくとも呼ばれます。 + +@item skk-act-load-hook +@itemx skk-auto-load-hook +@itemx skk-azik-load-hook +@itemx skk-comp-load-hook +@itemx skk-gadget-load-hook +@itemx skk-kakasi-load-hook +@itemx skk-kcode-load-hook +@itemx skk-num-load-hook +@itemx skk-server-load-hook +@c @itemx skk-viper-load-hook +@vindex skk-act-load-hook +@vindex skk-auto-load-hook +@vindex skk-azik-load-hook +@vindex skk-comp-load-hook +@vindex skk-gadget-load-hook +@vindex skk-kakasi-load-hook +@vindex skk-kcode-load-hook +@vindex skk-num-load-hook +@vindex skk-server-load-hook +@c @vindex skk-viper-load-hook + +@file{skk-act.el}, @file{skk-auto.el}, @file{skk-azik.el}, @file{skk-comp.el}, +@file{skk-gadget.el}, @file{skk-kakasi.el}, @file{skk-kcode.el}, +@file{skk-num.el}, @file{skk-server.el} +@c , @file{skk-viper.el} +の各ファイルの読み込みが完了した直後に呼ばれるフック。 +@end table + +@findex eval-after-load +@code{load-hook} が提供されていないプログラムであっても、ロード完了後に何らか +の設定を行いたい場合は、関数 @code{eval-after-load} を使用します。例え +ば、 + +@lisp +@group +(eval-after-load "skk-look" + '( + @dots{} + )) +@end group +@end lisp + +@noindent +のように記述します。 + +@node Customize による設定変更 +@subsection Customize による設定変更 +@cindex Customize + +Emacs 標準の Customize 機能を使って SKK を設定することもできます。 +ただし、 Customize での設定は @file{~/.emacs.d/init.el} での設定と同様、 +@file{~/.skk} による設定で上書きされてしまいますので注意してください。 + +@kindex M-x customize-group +@kindex M-x skk-emacs-customize + +@kbd{M-x customize-group} を実行すると skk の設定を対話的に変更することができます。ミニバッファに ``Customize group:'' とプロンプトが表示されます。 + +@example +@group +------ Minibuffer ------- +Customize group: (default emacs) @point{} +------ Minibuffer ------- +@end group +@end example + +ここで ``skk'' と答えると、SKK グループの画面へ展開します。 + +@kbd{M-x skk-emacs-customize} と実行するのも同様です。 + +あるいは、モードラインの SKK インジケータをマウスの右ボタン(第3ボタン) +でクリックすると表示されるメニューから ``SKKをカスタマイズ'' を選んでも同 +じ画面となります。 + +カスタマイズの使い方は以下を参照してください。 + +@display +@xref{Easy Customization, , Easy Customization, emacs, GNU Emacs Manual}. +@end display + +skk で設定できる変数の中には、まだこのマニュアルで解説されていないものも +あります。 Customize を使うと、それらについても知ることができます。 + +@node skk-customize による設定変更 +@subsection skk-customize による設定変更 + +@kindex M-x skk-customize + +前述の「Emacs 標準の Customize 機能 (@kbd{M-x customize-group}) 」による +設定が複雑すぎると感じるユーザのために、簡易版として @kbd{M-x skk-customize} を +用意しています。これは SKK グループのユーザオプションのうち、よく使うもの +だけ抜粋して設定できるようにしたものです。 + +これは、モードラインの SKK インジケータをマウスの右ボタン(第3ボタン)で +クリックして表示されるメニューから ``SKK をカスタマイズ (簡易版)'' を選ん +で呼び出すこともできます。 + +@node カタカナ、英字入力の便法 +@section カタカナ、英字入力の便法 + +この節では、カタカナや全英文字を入力するための、便利な方法を説明します。 +単純に各モードを用いる方法については前述しました。 +(@w{@pxref{入力モード, , カナモード、全英モード}}) + +@menu +* かなモードからカタカナを入力:: +* 全英文字の入力:: +* 領域の操作:: 領域の中の文字種を変換 +* カタカナの見出し語:: +* 文脈に応じた自動モード切り替え:: プログラムでは、コメントの中だけ skk +@end menu + +@node かなモードからカタカナを入力 +@subsection かなモードからカタカナを入力 +@kindex q +@cindex トグル変換 + +まず、かなモードに入ります。@kbd{Q} キーでいったん▽モードにして何かひらがなを入力し、 +最後に @kbd{q} をタイプすると、カタカナに変換され確定されます。 + +実際には、ひらがな以外からも変換できます。以下のようになります。 + +@itemize @bullet +@item カタカナはひらがなへ +@item ひらがなはカタカナへ +@item 全英文字はアスキー文字へ +@item アスキー文字は全英文字へ +@end itemize + +細かく言えば、@samp{▽} とポイント間の文字列の +種類@footnote{正確には @samp{▽} の次の位置にある文字列によって文字種を +判別しているので、途中で文字種類の違う文字が混在していても無視されます。} を +キーとして変換が行われます。 +かなモード、カナモード、どちらでも同じです。 + +このような変換を、トグル変換と呼びます。以下はトグル変換の例です。 + +@example +@kbd{K a t a k a n a} + +@group +------ Buffer: foo ------ +▽かたかな@point{} +------ Buffer: foo ------ +@end group + +@kbd{q} + +@group +------ Buffer: foo ------ +カタカナ@point{} +------ Buffer: foo ------ +@end group +@end example + +このトグル変換を上手く利用することにより、かなモードのまま一時的にカタカ +ナを入力したり、またその逆を行うことができます。こうすると、例えばひらが +な/カタカナが混在した文章を書くときに、その都度 @kbd{q} キーを押して入力 +モードを切り換える必要がありません +@footnote{全英文字とアスキー文字のトグルでの変換を行うこともできます。 +ただし、全英モードやアスキーモードでは @kbd{Q} やその他の大文字により▽ +モードに入ることができないので、かな ⇔ カナ のときと同様にトグル変換で +きるわけではありません。かなモード/カナモードにおいて、既に入力さ +れた全英文字、アスキー文字に対してトグル変換をするような設計になっていま +す。}。 + +領域を対象としたコマンドでも「かな←→カナ」のトグル変換を行うことができ +ます。(@w{@pxref{領域の操作}}) + +@node 全英文字の入力 +@subsection 全英文字の入力 +@kindex / +@kindex C-q + +まず、かなモードに入ります。次に @kbd{/} をタイプすると SKK abbrev モー +ド@footnote{SKK abbrev モードでは @samp{is} @result{} @samp{インクリメン +タル・サーチ} のような変換を行うことができます。他の変換と同様、 +@key{SPC} を押すと変換モードに入ってしまいますので、 SKK abbrev モードか +らアスキー文字を入力するのは、一語のみの場合以外は不便です。 +(@w{@pxref{アスキー文字を見出し語とした変換}})} +に入りますのでアルファベット (アスキー文字) を入力します。 +アルファベットの入力後に +@kbd{C-q} @footnote{@kbd{C-q} は @code{skk-abbrev-mode-map} にて +特別な動作をするように定義されています。 +@xref{アスキー文字を見出し語とした変換}.}をタイプすることで @samp{▽}マー +クから @kbd{C-q} をタイプした位置までの間にあるアルファベットが全角アルフ +ァベットに変換されて確定されます。 + +@example +@kbd{/ f i l e} + +@group +------ Buffer: foo ------ +▽file@point{} +------ Buffer: foo ------ +@end group + +@kbd{C-q} + +@group +------ Buffer: foo ------ +file@point{} +------ Buffer: foo ------ +@end group +@end example + +なお、この変換を行うために、 + +@example +file /file/ +@end example + +@noindent +のような辞書エントリを持つ必要はありません。なぜなら、辞書を参照せずにア +スキー文字を 1 文字ずつ全英文字に変換しているからです。 + +@node 領域の操作 +@subsection 領域の操作 + +以下のコマンドを @kbd{M-x} により呼ぶことで、領域内の文字列を一括変換する +ことができます +@cindex Menu Bars +@cindex メニューバー +@footnote{メニューバーが使用できる環境では、メニューバーを使ってこれらの一括変換 +コマンドを呼び出すことができます。ただし @command{kakasi} がインストールされていない +場合は @command{kakasi} を利用する機能が灰色になり使用できません。 +@w{@xref{Menu Bars, ,メニューバー, emacs, GNU Emacs Manual}.}}。 + +@table @kbd +@item M-x skk-hiragana-region +@kindex M-x skk-hiragana-region +@findex skk-hiragana-region + +カタカナをひらがなへ変換。 + +@item M-x skk-katakana-region +@kindex M-x skk-katakana-region +@findex skk-katakana-region + +ひらがなをカタカナへ変換。 + +@item M-x skk-latin-region +@kindex M-x skk-latin-region +@findex skk-latin-region + +全英文字をアスキー文字へ変換。 + +@item M-x skk-jisx0208-latin-region +@kindex M-x skk-jisx0208-latin-region +@findex skk-jisx0208-latin-region + +アスキー文字を全英文字へ変換。 +@end table + +@cindex 逆引き +以下に紹介する「漢字から読みを求めるコマンド」は、外部プログラム @command{KAKASI} +@footnote{@uref{http://kakasi.namazu.org/, KAKASI - 漢字→かな(ローマ字)変換プログラム}} が必要です。 +@command{KAKASI} がインストールされていなければ使用することができません。 + +@table @kbd +@item M-x skk-gyakubiki-region +@kindex M-x skk-gyakubiki-region +@findex skk-gyakubiki-region + +漢字をひらがなへ変換。具体的な変換例をあげると、 + +@example +``漢字をひらがなへ変換。''@expansion{}``かんじをひらがなへへんかん。'' +@end example + +@noindent +のようになります。引数を渡して、 + +@kbd{C-u M-x skk-gyakubiki-region} + +のようにすると、複数の候補がある場合に、`@{@}' で囲って表示します。例え +ば + +@example +``中島''@expansion{}``@{なかしま|なかじま@}'' +@end example + +@noindent +のようになります。 + +送り仮名がある語は、送り仮名まで含めて領域に指定します (さもないと誤変換 +の原因となります)。 例えば、@samp{五月蝿い} について、送り仮名 @samp{い} +を含めずにこのコマンドを実行すると、@samp{ごがつはえ} に変換されてしまい +ます。 + +@item M-x skk-gyakubiki-and-henkan +@kindex M-x skk-gyakubiki-and-henkan +@findex skk-gyakubiki-and-henkan + +領域の漢字をひらがなへ変換し、これで得たひらがなを見出し語として +漢字変換を実行します。 + +@item M-x skk-gyakubiki-katakana-region +@kindex M-x skk-gyakubiki-katakana-region +@findex skk-gyakubiki-katakana-region + +漢字をカタカナへ変換。 + +引数を渡して、@kbd{C-u M-x skk-gyakubiki-katakana-region} のようにすると、 +複数の候補がある場合に、`@{@}' で囲って表示します。 + +@item M-x skk-hurigana-region +@kindex M-x skk-hurigana-region +@findex skk-hurigana-region + +漢字にふりがなを付ける。例えば、 + +@example +``漢字の脇に''@expansion{}``漢字[かんじ]の脇[わき]に'' +@end example + +@noindent +のようになります。引数を渡して @kbd{C-u M-x skk-hurigana-region} のよう +にすると、複数の候補がある場合に、`@{@}' で囲って表示します。 + +@item M-x skk-hurigana-katakana-region +@kindex M-x skk-hurigana-katakana-region +@findex skk-hurigana-katakana-region + +漢字にカタカナのふりがなを付ける。 + +引数を渡して、@kbd{C-u M-x skk-hurigana-katakana-region} のようにすると、 +複数の候補がある場合に、`@{@}' で囲って表示します。 + +@item M-x skk-romaji-region +@kindex M-x skk-hurigana-region +@findex skk-romaji-region + +漢字、ひらがな、カタカナをローマ字へ、全英文字をアスキー文字へ変換。標準 +では、ローマ字への変換様式はヘボン式です。例えば、 + +@example +``し'' @expansion{} ``shi'' +@end example + +@noindent +となります。 + +@end table + +以下のコマンドは、領域内の文字列を置き換える代わりに、変換結果をエコーエ +リアに表示します。 + +@itemize @bullet +@item @kbd{M-x skk-gyakubiki-message} +@kindex M-x skk-gyakubiki-message +@findex skk-gyakubiki-message +@item @kbd{M-x skk-gyakubiki-katakana-message} +@kindex M-x skk-gyakubiki-katakana-message +@findex skk-gyakubiki-katakana-message +@item @kbd{M-x skk-hurigana-message} +@kindex M-x skk-hurigana-message +@findex skk-hurigana-message +@item @kbd{M-x skk-hurigana-katakana-message} +@kindex M-x skk-hurigana-katakana-message +@findex skk-hurigana-katakana-message +@item @kbd{M-x skk-romaji-message} +@kindex M-x skk-romaji-message +@findex skk-romaji-message +@end itemize + +@c http://mail.ring.gr.jp/skk/200110/msg00005.html +@defvr {ユーザ変数} skk-gyakubiki-jisyo-list + +関数 @code{skk-gyakubiki-region} はコマンド @command{kakasi} を呼び出し +ています。 +@command{kakasi} には漢字をひらがなへ変換する機能があり、この変換には環 +境変数 @env{KANWADICTPATH} で指定されている辞書を利用しています。 + +変数 @code{skk-gyakubiki-jisyo-list} を設定することによっ +て @command{kakasi} へ与える辞書を任意に追加することができます。 +以下のように設定して @command{kakasi} へ個人辞書 @code{skk-jisyo} を与え +ることによって辞書登録モードで登録したばかりの単語も @command{kakasi} に +よる逆引き変換の対象とすることができます。 + +@lisp +(setq skk-gyakubiki-jisyo-list (list skk-jisyo)) +@end lisp +@end defvr + +@defvr {ユーザ変数} skk-romaji-*-by-hepburn + +この変数の値を @code{nil} に設定すると、 +コマンド @code{skk-romaji-@{region|message@}} によるローマ字への変換様式 +に訓令式を用います。デフォルトは @code{t} です。 + +例えば、 + +@example +``し'' @expansion{} ``si'' +@end example + +@noindent +のようになります +@footnote{昭和 29 年 12 月 9 日付内閣告示第一号によれば、原則的に訓令式 +(日本式) を用いるかのように記載されていますが、今日一般的な記載方法は、 +むしろヘボン式であるようです。}。 + +@end defvr + +@node カタカナの見出し語 +@subsection カタカナの見出し語 + +@kbd{q} のタイプでかなモード、カナモードを度々切り替えて入力を続けていると、 +カナモードで誤って▼モードに入ってしまうことがあります。そのため、カナ +モードで▼モードに入った場合は、まず見出し語をひらがなに変換してから辞 +書の検索に入るよう設計されています。なお、この場合の送りあり変換での送 +り仮名は、カタカナになります。 + +@node 文脈に応じた自動モード切り替え +@subsection 文脈に応じた自動モード切り替え +@cindex 文脈に応じた自動モード切り替え +@cindex @file{context-skk.el} +@kindex M-x context-skk-mode + +@file{context-skk.el} は、編集中の文脈に応じて SKK の入力モードを自動的に +アスキーモードに切り替える等の機能を提供します。 + +@file{context-skk.el} をロードするには、@file{~/.emacs.d/init.el} に + +@lisp +@group +(add-hook 'skk-load-hook + (lambda () + (require 'context-skk))) +@end group +@end lisp + +と書いてください。 + +あるプログラミング言語のプログラムを書いているとき、日本語入力の必要があ +るのは一般に、そのプログラミング言語の文字列中かコメント中に限られます。 +たとえば Emacs Lisp で日本語入力の必要があるのは +@lisp +@group +"文字列" +;; コメント +@end group +@end lisp +といった個所だけでしょう。 +文字列・コメントの「外」を編集するときは、多くの場合は日本語入力は必要あ +りません。 + +現在の文字列・コメントの「外」で編集開始と同時に(skk がオンであれば) +skk の入力モードをアスキーモードに切り替えます。 +エコーエリアに + +@example +@group +-------------------- Echo Area -------------------- +[context-skk] 日本語入力 off +-------------------- Echo Area -------------------- +@end group +@end example + +と表示され、アスキーモードに切り替わったことが分かります。 +これにより、文字列・コメントの「外」での編集を開始するにあたって、日本語 +入力が on になっていたために発生する入力誤りとその修正操作を回避すること +ができます。 + +上記の機能は context-skk-mode というマイナーモードとして実装されており +@kbd{M-x context-skk-mode} でオン/オフを制御できます。 +オンの場合、モードラインのメジャーモード名の隣に「;▽」と表示されます。 + +@defvr {ユーザ変数} context-skk-programming-mode +context-skk が「プログラミングモード」と見做すメジャーモード。 +@end defvr + +@defvr {ユーザ変数} context-skk-mode-off-message +アスキーモードに切り替わった瞬間にエコーエリアに表示するメッセージ。 +@end defvr + +@node 補完 +@section 補完 +@cindex 見出し語の補完 +@cindex 読みの補完 +@cindex 補完 + +読みの前半だけを入力して @key{TAB} を押せば残りを自動的に補ってくれる、 +これが補完です。 Emacs ユーザにはおなじみの機能が DDSKK でも使えます。 + +@menu +* 読みの補完:: 「かか」 + Tab -> 「かかみがはらし」 ! +* 補完しながら変換:: 「かしたん」 + M-SPC -> 「瑕疵担保責任」 !! +* 動的補完:: 入力しながら候補を表示 +@end menu + +よく使う長い語を効率良く入力するには、アルファベットの略語を登録する方法もあります。 +(@w{@pxref{アスキー文字を見出し語とした変換}}) + +@node 読みの補完 +@subsection 読みの補完 + +@kindex @key{TAB} +▽モードで @key{TAB} を押すと、見出し語(▽マークから、ポイントまでの文字 +列)に対する補完が行われます@footnote{細かい説明です。 @key{TAB} を押す直 +前に▽モードで入力された文字列を X と呼ぶことにします。このとき、個人辞書 +の送りなしエントリの中から「先頭が X と一致し」かつ「長さが X よりも長い +見出し語」を検索して、そのような語が該当すれば X の代わりに表示します。}。 +見出し語補完は、個人辞書の内、送りなしエントリに対して行われます。 +個人辞書に限っているのは、共有辞書では先頭の文字を共通にする見出し語が多すぎて、 +望みの補完が行える確率が低いためです。 + +@kindex , +@kindex . +次の読みの候補を表示するには、@kbd{.} (ピリオド) を、戻る時には @kbd{,} +(コンマ)を押します。その読みで別の語を出すには、いつものように @key{SPC} を +押します。 + +例を見てみましょう。実際の動作は、個人辞書の内容によって異なります。 + +@example +@kbd{S a} + +@group +------ Buffer: foo ------ +▽さ@point{} +------ Buffer: foo ------ +@end group + +@key{TAB} + +@group +------ Buffer: foo ------ +▽さとう@point{} +------ Buffer: foo ------ +@end group + +@kbd{.} + +@end example + +@example +@group +------ Buffer: foo ------ +▽さいとう@point{} +------ Buffer: foo ------ +@end group + +@kbd{,} + +@group +------ Buffer: foo ------ +▽さとう@point{} +------ Buffer: foo ------ +@end group + +@key{SPC} + +@group +------ Buffer: foo ------ +▼佐藤@point{} +------ Buffer: foo ------ +@end group + +@kbd{C-j} + +@group +------ Buffer: foo ------ +佐藤@point{} +------ Buffer: foo ------ +@end group +@end example + +補完される見出し語がどのような順で表示されるかと言うと「最近使われた語から」 +となります。例えば、@samp{斉藤}、@samp{佐藤} の順で変換した後、@samp{さ} をキー +にして見出し語の補完を行うと、最初に @samp{さとう} が、その次に +@samp{さいとう} が補完されます。これは、個人辞書では、最近使われたエントリほど +上位に来るようになっているためです。@footnote{@ref{辞書の書式}} + +いったん @key{SPC} を入力して▼モードに入ると、以後は見出し語補完は行われません。 + +@kindex @kbd{C-u @key{TAB}} +また、@kbd{.} の代わりに @kbd{C-u @key{TAB}} を入力 +すると、現在の候補に対して補完をします。上の例では @samp{さ} に対し、 +@samp{さとう} が補完された時に @kbd{C-u @key{TAB}} を押すと、 +以後の補完は、@samp{さとう} を含む語 (例えば、@samp{さとうせんせい}など) +について行われます。 + +@defvr {ユーザ変数} skk-completion-prog-list +補完関数、補完対象の辞書を決定するためのリスト。 +デフォルトは以下のとおり。 + +@lisp +@group + '((skk-comp-by-history) + (skk-comp-from-jisyo skk-jisyo) + (skk-look-completion)) +@end group +@end lisp + +@end defvr + +@defvr {ユーザ変数} skk-comp-circulate +@kbd{.} (ピリオド)で次の見出し語候補を、@kbd{,} (コンマ)で前の見出し +語候補を表示するところ、候補が尽きていればデフォルト @code{nil} では「○ +○で補完すべき見出し語は他にありません」とエコーエリアに表示して動作が止 +まります。この変数が @code{non-nil} であれば当初の見出し語を再び表示して +見出し語補完を再開します。 +@end defvr + +@defvr {ユーザ変数} skk-try-completion-char +見出し語補完を開始するキーキャラクタです。デフォルトは @key{TAB} です。 +@end defvr + +@defvr {ユーザ変数} skk-next-completion-char +次の見出し語候補へ移るキーキャラクタです。デフォルトはピリオド @kbd{.} です。 +@end defvr + +@defvr {ユーザ変数} skk-previous-completion-char +前の見出し語候補へ戻るキーキャラクタです。デフォルトはコンマ @kbd{,} です。 +@end defvr + +@cindex backtab +@kindex SHIFT TAB +@defvr {ユーザ変数} skk-previous-completion-use-backtab +@code{Non-nil} であれば、前の見出し語候補へ戻る動作を @kbd{@key{SHIFT}+@key{TAB}} で +も可能とします。デフォルトは @code{t} です。 +この機能の有効化/無効化の切り替えは、ファイル @file{~/.skk} を書き換えて Emacs を +再起動してください。 +@end defvr + +@defvr {ユーザ変数} skk-previous-completion-backtab-key +@kbd{@key{SHIFT}+@key{TAB}} が発行する key event です。Emacs の種類/実行環境 +によって異なります。 +@end defvr + +@defun skk-comp-lisp-symbol &optional PREDICATE +この関数をリスト @code{skk-completion-prog-list} へ追加すると、Lisp symbol 名 +の補完を行います。 + +@lisp +@group +(add-to-list 'skk-completion-prog-list + '(skk-comp-lisp-symbol) t) +@end group +@end lisp + +@end defun + +@node 補完しながら変換 +@subsection 補完しながら変換 +@kindex M-@key{SPC} + +前節で見出し語の補完について述べました。本節では、見出し語の補完動作を行 +った後、@key{SPC} を入力し、▼モードに入るまでの動作を一回の操作で行 +う方法について説明します。 + +やり方は簡単。@key{TAB}・@key{SPC} と打鍵していたところを @kbd{M-@key{SPC}} に +換えると、見出し語を補完した上で変換を開始します。 + +この方法によると、補完される見出し語があらかじめ分かっている状況では、キー +入力を一回分省略できるので、読みが長い見出し語の単語を連続して入力する場合 +などに威力を発揮します。 + +@example +@group +@kbd{K a s i t a n n p o s e k i n i n n} + +------ Buffer: foo ------ +▽かしたんぽせきにん@point{} +------ Buffer: foo ------ +@end group + +@group +@key{SPC}, @key{RET} + +------ Buffer: foo ------ +瑕疵担保責任@point{} +------ Buffer: foo ------ +@end group + +@group +@kbd{K a} + +------ Buffer: foo ------ +▽か@point{} +------ Buffer: foo ------ +@end group + +@group +@kbd{M-@key{SPC}} + +------ Buffer: foo ------ +▼瑕疵担保責任@point{} +------ Buffer: foo ------ +@end group +@end example + +@defvr {ユーザ変数} skk-start-henkan-with-completion-char + +デフォルトは @kbd{M-@key{SPC}} です。 + +@end defvr + +@node 動的補完 +@subsection 動的補完 +@cindex @file{skk-dcomp.el} + +▽モードでは、@key{TAB} を押さなくとも、文字を入力する都度、自動的に見 +出し語補完の読みを表示させる事ができます。この機能を以下「動的補完」と呼 +びます。類似の機能としては、ウェブブラウザの URL の入力や、Microsoft Excel の +セル入力の自動補完@footnote{同じ列に既に入力している文字列があったときに +それを参照して補完しようとする機能}をイメージすると分かりやすいかも知れ +ません。動的補完も、個人辞書の送りなしエントリに対してのみ行なわれます。 + +動的補完を利用するには @file{~/.skk} に次の式を書きましょう。 + +@lisp +(setq skk-dcomp-activate t) +@end lisp + +例を見てみましょう。実際の動作は、個人辞書の内容によって左右されます。 @point{} は +ポイント位置を表します。 + +@example +@group + +@kbd{H o} + +---------------- Buffer: foo ------------------ +▽ほ@point{}んとう +---------------- Buffer: foo ------------------ + +@end group +@end example + +face が使える環境では、@samp{んとう}の部分が異なる face で表示され、動的 +補完機能によって補完された部分であることを示します。 + +自動的に補完された見出し語が自分の意図したものであれば、 @key{TAB} を押 +すことでポイント位置を動かし、補完された見出し語を選択することができます。 + +@example +@group +@key{TAB} + +---------------- Buffer: foo ------------------ +▽ほんとう@point{} +---------------- Buffer: foo ------------------ +@end group +@end example + +この状態から @key{SPC} を押して変換するなり、@kbd{q} を押してカタカナに +するなり、DDSKK 本来の動作を何でも行うことができます。 + +補完された見出し語が自分の意図したものでない場合は、かまわず次の入力を続 +けて下さい。補完された部分を無視したかのように動作します。 + +@example +@group + +@kbd{H o} + +---------------- Buffer: foo ------------------ +▽ほ@point{}んとう +---------------- Buffer: foo ------------------ + +@kbd{k a} + +---------------- Buffer: foo ------------------ +▽ほか@point{}ん +---------------- Buffer: foo ------------------ + +@end group +@end example + +補完されない状態が自分の意図したものである場合も、補完された部分を単に無 +視するだけで OK です。下記の例では、@samp{ほ} を見出し語とした変換を行っ +ています。 + +@example +@group + +@kbd{H o} + +---------------- Buffer: foo ------------------ +▽ほ@point{}んとう +---------------- Buffer: foo ------------------ + +@key{SPC} + +---------------- Buffer: foo ------------------ +▼保 +---------------- Buffer: foo ------------------ +@end group +@end example + +補完された状態から @key{BS} を押すと、消された補完前の見出し語から再度補 +完動作を行います。 + +@example +@group + +@kbd{H o} + +---------------- Buffer: foo ------------------ +▽ほ@point{}んとう +---------------- Buffer: foo ------------------ + +@kbd{k a} + +---------------- Buffer: foo ------------------ +▽ほか@point{}ん +---------------- Buffer: foo ------------------ + +@key{BS} + +---------------- Buffer: foo ------------------ +▽ほ@point{}んとう +---------------- Buffer: foo ------------------ +@end group +@end example + + +@defvr {ユーザ変数} skk-dcomp-activate + +この変数の値が @code{Non-nil} であれば、カーソル位置に関わらず常に動的補完が有効となります。 +値がシンボル @code{eolp} であれば、カーソルが行末にあるときに限って動的補完が有効となります。 +値が @code{nil} であれば、動的補完機能は無効となります。 + +@end defvr + +@defvr {ユーザ変数} skk-dcomp-face + +この変数の値はフェイスであり、このフェイスによって動的に補完された部分が +装飾されます。標準は ``DarkKhaki'' です。 + +@end defvr + +@defvr {ユーザ変数} skk-dcomp-multiple-activate + +@b{XEmacs では動作しません。} + +@code{Non-nil} であれば、動的補完の候補をインラインに複数表示します +@footnote{現在は候補群の右側1カラムのフェイスがデフォルトに戻る、という制約があります。}。 + +@example +@group +---------------- Buffer: foo ------------------ +▽ほ@point{}んとう + ほんとう + ほかん + ほっかいどう + ほうほう + @dots{} +---------------- Buffer: foo ------------------ +@end group +@end example + +@kindex @key{TAB} +@kindex , +@kindex . +@kindex SHIFT TAB + +候補の選択には @key{TAB} 又は @kbd{@key{SHIFT}+@key{TAB}} を押します。また、 +普通の補完と同様に @kbd{.} (ピリオド) と @kbd{,} (コンマ) も利用できま +す。@w{@ref{読みの補完}} + +@end defvr + +@defvr {ユーザ変数} skk-dcomp-multiple-rows + +動的補完の候補を複数表示する場合の表示行数。標準は 7。 + +@end defvr + +@defvr {ユーザ変数} skk-dcomp-multiple-face + +動的補完の複数表示群のフェイス。上記例では「ほ」のフェイス。 + +@end defvr + +@defvr {ユーザ変数} skk-dcomp-multiple-trailing-face + +動的補完の複数表示群の補完部分のフェイス。上記例では「んとう」、「かん」 +「っかいどう」、「うほう」のフェイス。 + +@end defvr + +@defvr {ユーザ変数} skk-dcomp-multiple-selected-face + +動的補完の複数表示群の選択対象のフェイス。上記例では @key{TAB} を押すたび +に「ほんとう」、「ほかん」、「ほっかいどう」と選択位置が移ります。その現在 +選択位置に適用するフェイスです。 + +@end defvr + +@node 便利な変換、その他の変換 +@section 便利な変換、その他の変換 + +@menu +* 単漢字変換:: 一文字だけ漢字に変換 +* 候補の絞り込み:: 「わ」だけど「魏志倭人伝」の「倭」が欲しい +* 接頭辞・接尾辞:: 接頭辞・接尾辞だけを変換 +* 数値変換:: 数を含む文字列の変換。 +* アスキー文字を見出し語とした変換:: 「wg」 -> 「ワーキンググループ」 +* 今日の日付の入力:: 今日の日付を一発入力。 +* プログラム実行変換:: Emacs Lisp プログラムを使った変換。 +* 空白・改行・タブを含んだ見出し語の変換:: +* カタカナ変換:: 個人辞書でカタカナ語を育てられます。 +* サ変動詞変換:: サ行変格活用動詞の送りあり変換が可能です +* 異体字へ変換する:: +* ファンクションキーの使い方:: +@end menu + +@node 単漢字変換 +@subsection 単漢字変換 +@cindex @file{skk-tankan.el} +@cindex 単漢字 + +ファイル @file{skk-tankan.el} を読み込むことによって単漢字変換が可能とな +ります。候補は総画数の昇順でソートして表示します。 + +@menu +* 検索キーの設定:: +* 辞書の設定:: +* 総画数による単漢字変換:: +* 部首による単漢字変換:: +* 部首の読みによる単漢字変換:: +@end menu + +単漢字変換を使うには設定が必要ですが、先に例を見てみましょう。 + +▽モードの最後の文字に @kbd{@@} を付加してから変換を開始してください。 + +@example +T a n @@ + +@group +----- Buffer: foo ----- +▽たん@@@point{} +----- Buffer: foo ----- +@end group + +@key{SPC} + +@group +----- Buffer: foo ----- +▼丹@point{} +----- Buffer: foo ----- +@end group + +@group +----- Echo Area ----- +4画(丶部3画) +----- Echo Area ----- +@end group + +@key{SPC} + +@group +----- Buffer: foo ----- +▼反@point{} +----- Buffer: foo ----- +@end group + +@group +----- Echo Area ----- +4画(又部2画) +----- Echo Area ----- +@end group + +@key{SPC} + +@group +----- Buffer: foo ----- +▼旦@point{} +----- Buffer: foo ----- +@end group + +@group +----- Echo Area ----- +5画(日部1画) +----- Echo Area ----- +@end group + +@key{SPC} + +@group +----- Buffer: foo ----- +▼但@point{} +----- Buffer: foo ----- +@end group + +@group +----- Echo Area ----- +7画(人部5画) +----- Echo Area ----- +@end group + +@key{SPC} + +@group +----- Buffer: foo ----- +▼@point{} +----- Buffer: foo ----- +@end group + +@group +----- Buffer: *候補* ----- +A:坦;8画(土部5画) +S:担;8画(手部5画) +D:単;9画(十部7画) +F:彖;9画(彑部6画) +J:炭;9画(火部5画) +K:眈;9画(目部4画) +L:胆;9画(肉部5画) +[残り 50+++++] +----- Buffer: *候補* ----- +@end group +@end example + +以上のとおり、総画数の昇順でソートされた候補が次々に表示されます。 + +@node 検索キーの設定 +@subsubsection 検索キーの設定 + +デフォルトの検索キーは @kbd{@@} です。 +DDSKK の標準設定ではキー @kbd{@@} は関数 @code{skk-today} の実行に割り +当てられていますが、DDSKK 14.2 からは特段の設定なしに▽モードで @kbd{@@} の +タイプが可能となりました。 + +@defvr {ユーザ変数} skk-tankan-search-key +単漢字変換の検索キーは、変数 @code{skk-tankan-search-key} で変更できます。 +以下は、検索キーを @kbd{!} へと変更する例です。 + +@lisp +(setq skk-tankan-search-key ?!) +@end lisp + +@end defvr + +@node 辞書の設定 +@subsubsection 辞書の設定 + +@findex skk-tankan-search + +DDSKK 14.2 からは、標準で変数 @code{skk-search-prog-list} に +@code{skk-tankan-search} が含まれています。 +DDSKK 14.1 を利用の方、ご自身で @code{skk-search-prog-list} を設定する方は +以下の解説を参考にしてください。 + +@file{skk-tankan.el} には、漢字の部首とその中での画数の +データのみが入っています。読みのデータは、普通の辞書ファイルを使います。 + +単漢字変換の辞書の設定は、変数 @code{skk-search-prog-list} に以下の形式で +要素を追加します。 + +@lisp +(skk-tankan-search 'function . args) +@end lisp + +@b{「確定変換」}を併用する場合は、@code{skk-search-prog-list} の +先頭の要素は @code{skk-search-kakutei-jisyo-file} でなければいけませんので、 +@code{skk-search-prog-list} の2番目の要素に @code{skk-tankan-search} を追加します。 + +@lisp +@group +;; skk-search-prog-list の2番目の要素に skk-tankan-search を追加する +(setq skk-search-prog-list + (cons (car skk-search-prog-list) + (cons '(skk-tankan-search 'skk-search-jisyo-file + skk-large-jisyo 10000) + (cdr skk-search-prog-list)))) +@end group +@end lisp + +なお、確定変換を使用しない場合は、 @code{skk-search-prog-list} の要素 +の先頭が @code{skk-tankan-search} でも大丈夫です。 + +@lisp +@group +(add-to-list 'skk-search-prog-list + '(skk-tankan-search 'skk-search-jisyo-file + skk-large-jisyo 10000)) +@end group +@end lisp + +@xref{辞書の検索方法の設定}. + +@node 総画数による単漢字変換 +@subsubsection 総画数による単漢字変換 +@cindex 画数変換 +@kindex C-u 総画数 M-x skk-tankan + +▽モードで総画数を入力して最後に @kbd{@@} を付加してから変換を開始します +@footnote{@kbd{C-u 総画数 M-x skk-tankan} でも可。}。 + +@example +Q 1 0 @@ + +@group +----- Buffer: foo ----- +▽10@@@point{} +----- Buffer: foo ----- +@end group + +@key{SPC} + +@group +----- Buffer: *候補* ----- +A:倹;10画(人部8画) +S:倦;10画(人部8画) +D:個;10画(人部8画) +F:候;10画(人部8画) +J:倖;10画(人部8画) +K:借;10画(人部8画) +L:修;10画(人部8画) +[残り 532+++++++] +----- Buffer: *候補* ----- +@end group + +@end example + +@node 部首による単漢字変換 +@subsubsection 部首による単漢字変換 +@cindex 部首変換 +@kindex M-x skk-tankan + +▽モードで @kbd{@@} を2つ重ねて変換を開始すると、部首による単漢字変換が +できます@footnote{@kbd{M-x skk-tankan} でも可。}。 + +@example +Q @@ @@ + +@group +----- Buffer: foo ----- +▽@@@@@point{} +----- Buffer: foo ----- +@end group + +@key{SPC} + +@group +------ Minibuffer ------- +部首を番号で選択(TABで一覧表示): @point{} +------ Minibuffer ------- +@end group + +@key{TAB} + +@group +------ *Completions* ------- +Click on a completion to select it. +In this buffer, type RET to select the completion near point. + +Possible completions are: +001 一 (いち) 002 | (ぼう、たてぼう) +003 丶 (てん) 004 丿 (の) +005 乙 (おつ) 006 亅 (はねぼう) + : : +------ *Completions* ------- +@end group + +@kindex M-v +@kbd{0 1 8 @key{RET}} @footnote{@kbd{M-v} の打鍵で、カーソルを *Completions* バッファへ移すこともできます。} + +@group +----- Buffer: *候補* ----- +A:切;4画(刀部2画) +S:刈;4画(刀部2画) +D:刊;5画(刀部3画) +F:刋;5画(刀部3画) +J:刎;6画(刀部4画) +K:刑;6画(刀部4画) +L:刔;6画(刀部4画) +[残り 51+++++++] +----- Buffer: *候補* ----- +@end group + +@end example + +@defvr {ユーザ変数} skk-tankan-face + +@kbd{M-x skk-tankan} を実行したときに表示される「単漢字バッファ」で使用 +するフェイスです。 + +@end defvr + +@defvr {ユーザ変数} skk-tankan-radical-name-face + +部首の読みに適用するフェイスです。 + +@end defvr + +@node 部首の読みによる単漢字変換 +@subsubsection 部首の読みによる単漢字変換 + +直前の小々節「部首による単漢字変換」にて、部首番号を入力するプロンプトで +単に @key{RET} をタイプすると、部首の読みを入力するプロンプトに替わります。 + +@example + +@group +------ Minibuffer ------- +部首を読みで選択(TABで一覧表示): @point{} +------ Minibuffer ------- +@end group + +@key{TAB} + +@group +------ Completion List ------- +In this buffer, type RET to select the completion near point. + +Possible completions are: +あいくち (021) 匕 あお (174) 青 +あか (155) 赤 あくび (076) 欠 +あさ (200) 麻 あさかんむり (200) 麻 + : : +------ Completion List ------- +@end group + +@end example + +@node 候補の絞り込み +@subsection 候補の絞り込み +@cindex @file{skk-hint.el} + +@file{skk-hint.el} は、2つの読みの積集合みたいなものを取ることによって +候補の絞り込みを行うプログラムです。 +インストールは @file{~/.skk} に以下を記入します。 + +@lisp +(require 'skk-hint) +@end lisp + +例えば、読み ``かんどう'' に対する変換は L 辞書によると + +@example +感動、勘当、完動、間道、官道、貫道 +@end example + +と複数の候補があります。 + +一方、これに ``あいだ'' という「他の読み」(ヒント)を与えると候補は +``間道'' に一意に決まります。 +ヒントは @kbd{;} に続けて入力します。 + +@example +@kbd{K a n d o u ; a i d a} + +※ @samp{;} 自体は表示されません。 + +----- Buffer: foo ----- +▽かんどうあいだ +----- Buffer: foo ----- + +@key{SPC} + +----- Buffer: foo ----- +▼間道 +----- Buffer: foo ----- +@end example + +@file{skk-hint.el} は、2つの読みの厳密な積集合を取っているわけではなく、 +通常の変換候補のなかでヒントとして与えられた読みを含んだ漢字を持つものに +候補を絞ります。この実例として ``感動'' と ``感圧'' を挙げます。 + +@example +@kbd{K a n d o u ; k a n n a t u} + +----- Buffer: foo ----- +▽かんどうかんあつ +----- Buffer: foo ----- + +@key{SPC} + +----- Buffer: foo ----- +▼感動 +----- Buffer: foo ----- +@end example + +@file{skk-hint.el} は単漢字の候補がたくさんある場合に、そこから候補を絞 +りこむ手段としても非常に有効です。例えば + +@example +▽わ +@end example + +を変換すると、輪、環、話、和、羽、@dots{}と大量に候補が出てきます。 +この中から ``和'' を選びたいとします。普通に変換していても +そのうち ``和'' が表示されますが、これを @kbd{W a ; h e i w a} と入力し +変換すると、「▼へいわ」の候補である「平和」に含まれる + +@example +▼和 +@end example + +が唯一の候補となります。 + +@example +@kbd{W a ; h e i w a} + +----- Buffer: foo ----- +▽わへいわ +----- Buffer: foo ----- + +@key{SPC} + +----- Buffer: foo ----- +▼和 +----- Buffer: foo ----- +@end example + +@defvr {ユーザ変数} skk-hint-start-char +ヒント変換を開始するキーを character で指定します。 +@end defvr + +@node 接頭辞・接尾辞 +@subsection 接頭辞・接尾辞 +@cindex 接頭辞 +@cindex 接尾辞 + +接頭辞 (prefix)、接尾辞 (suffix)の入力のために特別な方法が用意されていま +す。たとえば、「し」の候補は沢山あり、「し」から「氏」を変換するのは、そのままでは +効率が悪いです。接尾辞の「し」ならば、「氏」や「市」が優先されるでしょう。 + +接頭辞・接尾辞は辞書の中では、@samp{>} などで示されます。 + +@example +>し /氏/ +@end example + +@noindent +というエントリがあるとき、@samp{小林氏}を接尾辞入力を用いて、以下のよう +に入力することができます。 + +@example +@kbd{K o b a y a s h i} + +@group +------ Buffer: foo ------ +▽こばやし@point{} +------ Buffer: foo ------ +@end group + +@key{SPC} + +@group +------ Buffer: foo ------ +▼小林@point{} +------ Buffer: foo ------ +@end group + +@kbd{>} + +@group +------ Buffer: foo ------ +小林▽>@point{} +------ Buffer: foo ------ +@end group + +@kbd{s i} + +@group +------ Buffer: foo ------ +小林▽>し@point{} +------ Buffer: foo ------ +@end group + +@key{SPC} + +@group +------ Buffer: foo ------ +小林▼氏@point{} +------ Buffer: foo ------ +@end group + +@kbd{C-j} + +@group +------ Buffer: foo ------ +小林氏@point{} +------ Buffer: foo ------ +@end group +@end example + +接頭辞も同様です。辞書に + +@example +ちょう> /超/ +@end example + +@noindent +というエントリがあるとき、@samp{超大型} を接頭辞入力を用いて、以下のよう +に入力することができます。 + +@example +@kbd{T y o u} + +@group +------ Buffer: foo ------ +▽ちょう@point{} +------ Buffer: foo ------ +@end group + +@kbd{>} + +@group +------ Buffer: foo ------ +▼超@point{} +------ Buffer: foo ------ +@end group + +@kbd{O o g a t a} + +@group +------ Buffer: foo ------ +超▽おおがた@point{} +------ Buffer: foo ------ +@end group + +@key{SPC} + +@group +------ Buffer: foo ------ +超▼大型@point{} +------ Buffer: foo ------ +@end group + +@kbd{C-j} + +@group +------ Buffer: foo ------ +超大型@point{} +------ Buffer: foo ------ +@end group +@end example + +キー @kbd{>} を押しただけで、@key{SPC} が押されたかのように変換されます。 +他の接頭辞を選びたいときは、@key{SPC} を押して下さい。 + +@defvr {ユーザ変数} skk-special-midashi-char-list + +▽モードまたは▼モードにおいて、この変数の値に含まれる文字の入力があった +場合、接頭辞・接尾辞の入力を開始します。この変数のデフォルトは、 + +@lisp +(?> ?< ??) +@end lisp + +@noindent +です。つまり、@samp{>} と @samp{<} と @samp{?} を入力した時に接頭辞・接尾辞入 +力を行います。@samp{?} を入力したときに接頭辞・接尾辞入力を行わない場合は +@samp{?} を外して + +@lisp +(setq skk-special-midashi-char-list '(?> ?<)) +@end lisp + +@noindent +とします。 + +L 辞書の接頭・接尾辞は、昔は @samp{<}, @samp{?} も使われていましたが、 +現在は @samp{>} に統一されています。 +@end defvr + +@node 数値変換 +@subsection 数値変換 +@cindex #0 +@cindex #1 +@cindex #2 +@cindex #3 +@cindex #4 +@cindex #5 +@cindex #8 +@cindex #9 +@cindex 数をパラメータとする語の変換 +@cindex 数値再変換 +@cindex 大字 +@cindex 漢数字 +@cindex 金額 + +DDSKK は、@b{数字を含む見出し語}を様々な候補に変換することができます。 +例えば、見出し語 @samp{だい12かい} を変換すると @samp{第12回}、 +@samp{第一二回}、@samp{第十二回} といった候補を挙げます。 + +この節では、このような候補を辞書に登録する方法を説明します。基本は、 +数字の部分を @samp{#} で置き替えることです。辞書 @file{SKK-JISYO.L} のエ +ントリーから具体例を見てみましょう。 + +@example +だい#かい /第#1回/第#0回/第#2回/第#3回/第 #0 回/ +@end example + +@noindent +@samp{だい12かい} のような@b{数字を含む見出し語}を変換した場合、見出し +語の中の数字の部分は自動的に @samp{#} に置き換えられますの +で、辞書エントリーの左辺(つまり見出し語) @samp{だい#かい} にマッチします。 + +辞書エントリーの右辺の @samp{#1}、@samp{#2} などは「どのように数字を加工 +するか」のタイプを表します。以下、各タイプについて説明します。 + +@table @samp +@item #0 + +タイプ 0。無変換。入力されたアスキー文字をそのまま出力します。例えば、 +@samp{第12回} のような変換を得るために使います。 + +@item #1 + +タイプ 1。全角文字の数字。@samp{12} を @samp{12} に変換します。 + +@item #2 + +タイプ 2。漢数字で位取りあり。@samp{1024} を @samp{一〇二四} に変換しま +す。 + +@item #3 + +タイプ 3。漢数字で位取りなし。@samp{1024} を @samp{千二十四} に変換しま +す。 + +@item #4 + +タイプ 4。数値再変換。見出し語中の数字そのもの +@footnote{@samp{p125} という見出し語であれば、その数値部分である +@samp{125} が再変換の見出し語となります。}をキーとして辞書を再検索し、 +@samp{#4} の部分を再検索の結果の文字列で入れ替えます。これについては後で +例を挙げて説明します。 + +@item #5 + +タイプ 5。小切手や手形の金額記入の際用いられる表記で変換します。例えば、 +@samp{1995} を @samp{壱阡九百九拾伍} に変換します。(これを大字と言います。) + +@item #8 + +タイプ 8。桁区切り。@samp{1234567} を @samp{1,234,567} に変換します。 + +@item #9 + +タイプ 9。将棋の棋譜の入力用。@samp{全角数字 + 漢数字} に変換します。こ +れについては後で例を挙げて説明します。 +@end table + +以下にいくつか例を示します。辞書に + +@example +# /#3/ +@end example + +@noindent +というエントリがあるときに、 + +@example +@group +@kbd{Q 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 @key{SPC}} +@end group +@end example + +@noindent +と入力@footnote{または @kbd{/ 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 @key{SPC}}} +すれば、@samp{百兆二千三億四十万五百} と変換されます +@footnote{SHIFT キーを伴って数字を入力し始めることはできないので、@kbd{Q} または +@kbd{/} で▽モードに入る必要があります。}。 + +辞書に + +@example +#m#d /#0月#0日/ +@end example + +@noindent +というエントリがあるときに、@kbd{/ 2 m 2 5 d @key{SPC}} と入力すれば、 +@samp{2月25日}と変換されます +@footnote{@samp{m} や @samp{d} などアスキー文字を見出し語として入 +力する場合は @kbd{/} キーを最初に入力して SKK abbrev モードに入ってから +入力する必要があります。 +@w{@xref{アスキー文字を見出し語とした変換, , SKK abbrev mode}.}}。 + +辞書に + +@example +#kin /#9金/ +@end example + +@noindent +というエントリがあるときに、@kbd{/ 3 4 k i n @key{SPC}} と入力すれば、 +@samp{3四金}と変換されます。 + +辞書に + +@example +@group +p# /#4/ +125 /東京都葛飾区/ +@end group +@end example + +@noindent +というエントリがあるときに、@kbd{/ p 1 2 5 @key{SPC}} と入力すれば、見出 +し語 @samp{p125} の候補が @samp{#4} なので、見出し語の数字部分の +@samp{125} に対し辞書が再検索され、@samp{東京都葛飾区} と変換されます。 + +最後に、実際に登録する例を 1 つ挙げます。@samp{2月25日}を得るために、 + +@example +@kbd{Q 2 g a t u 2 5 n i t i @key{SPC}} +@end example + +@noindent +と入力したときに、辞書に見出し語 + +@example +#がつ#にち /#1月#1日/ +@end example + +@noindent +がないときは、辞書登録モードのプロンプトは、@w{@samp{#がつ#にち}}となります。 +全角数字のタイプは、@samp{#1} なので、 @w{@samp{#1月#1日}} をミニバッファで作り登 +録します。 + +タイプを覚えている必要はありません。ちゃんと、ウィンドウが開かれて説明が +表示されます。 + +@defvr {ユーザ変数} skk-num-convert-float + +この変数の値を @code{non-nil} に設定すると、浮動小数点数を使った見出し語 +に対応して数値変換を行います。ただし、辞書において + +@example +#.# /#1.#1/#0月#0日/ +@end example + +などの見出し語が使用できなくなります。 + +@end defvr + +@defvr {ユーザ変数} skk-show-num-type-info + +@code{Non-nil} であれば、辞書登録モードに入るのと同時に変換タイプの案内を +表示する。デフォルトは @code{t} です。 + +@end defvr + +@defvr {ユーザ変数} skk-num-grouping-separator + +タイプ 8 (@samp{#8}) で使用する記号。デフォルトは @samp{,}。 + +@end defvr + +@defvr {ユーザ変数} skk-num-grouping-places + +タイプ 8 (@samp{#8}) について、何桁毎に区切るのかを数値で指定する。デフォルトは 3。 + +@end defvr + +@defvr {ユーザ変数} skk-use-numeric-conversion + +この変数を @code{nil} に設定すると、本節で説明した数値変換の機能を全て +無効にします。 + +@end defvr + +@node アスキー文字を見出し語とした変換 +@subsection アスキー文字を見出し語とした変換 + +@cindex SKK abbrev mode +かなモードで @kbd{/} をタイプすると @dfn{SKK abbrev mode} に入り、以後の +入力はアスキー文字になります。普通に @key{SPC} を押すと、その見出し語に係 +る変換が得られます。 + +仮に、辞書に + +@example +is /インクリメンタル・サーチ/ +@end example + +@noindent +というエントリがあるとして、以下に例を示します。 + +@example +@kbd{/} + +@group +------ Buffer: foo ------ +▽@point{} +------ Buffer: foo ------ +@end group + +@kbd{i s} + +@group +------ Buffer: foo ------ +▽is@point{} +------ Buffer: foo ------ +@end group + +@key{SPC} + +@group +------ Buffer: foo ------ +▼インクリメンタル・サーチ@point{} +------ Buffer: foo ------ +@end group + +@kbd{C-j} + +@group +------ Buffer: foo ------ +インクリメンタル・サーチ@point{} +------ Buffer: foo ------ +@end group +@end example + +候補を確定すると SKK abbrev モードを抜けてかなモードに戻ります。 + +SKK abbrve モードで使われる辞書は、普通のかな漢字変換と同じです。見出し語 +がアスキー文字で書かれているだけで、特殊な点はありません。 + +上記の例において @key{SPC} の代わりに @kbd{C-q} をタイプすることで、入力 +したアスキー文字をそのまま全角アルファベットに変換することもできます。 +(@w{@ref{全英文字の入力}}) + +なお、SKK abbrev モードにおいても @key{TAB} による「見出し語の補完」を行 +うことができます。(@w{@pxref{補完}}) + +@node 今日の日付の入力 +@subsection 今日の日付の入力 +@kindex @@ +@cindex プログラム実行変換 + +かな/カナモードで @kbd{@@} を入力すれば、今日の日付が入力されます。 + +日付の形式は以下の変数により決定されます。 + +@defvr {ユーザ変数} skk-date-ad + +この変数の値が @code{non-nil} であれば西暦で、@code{nil} であれば元号で +表示します。デフォルトは @code{nil} です。 + +@end defvr + +@defvr {ユーザ変数} skk-number-style + +この変数の値は以下のように解釈されます。デフォルトは @samp{1} です。 + +@table @code +@item 0 +@itemx nil + +ASCII 数字。@samp{1996年7月21日(日)} のようになります。 + +@item 1 +@itemx t + +全角数字。@samp{1996年7月21日(日)} のようになります。 + +@item 2 + +漢数字(位取)。@samp{一九九六年七月二一日(日)} のようになります。 + +@item 3 + +漢数字。@samp{千九百九十六年七月二十一日(日)} のようになります。 +@end table + +上記の @samp{1996年}、@samp{1996年}、@samp{一九九六年} の部分は、変 +数 @code{skk-date-ad} の値が @code{nil} であれば @samp{平成8年} のよう +に元号で表示されます。 +@end defvr + +辞書 @file{SKK-JISYO.lisp} には、見出し語 @samp{today} の候補 +として、@code{skk-date-ad} と @code{skk-number-style} の全ての組み合わせが +プログラム実行変換機能@footnote{@ref{プログラム実行変換}.} を用いて登録さ +れています。従って、@kbd{/ t o d a y @key{SPC}} と入力すると、今日の日付 +が上記の形式で順次候補として表示されます。 + +関数 @code{skk-relative-date} を利用すると、昨日、一昨日、明後日など任意 +の日付を求めることができます。詳細は @file{skk-gadget.el} のコメントを参 +照してください。 + +なお、@kbd{@@} のタイプで日付を挿入するのではなく、文字どおり @samp{@@} を +挿入したい場合は次のとおり。 + +@lisp +@group +(setq skk-rom-kana-rule-list + (append skk-rom-kana-rule-list + '(("@@" nil "@@")))) +@end group +@end lisp + +全角文字の @samp{@} を挿入したい場合は次のとおり。 + +@lisp +@group +(setq skk-rom-kana-rule-list + (append skk-rom-kana-rule-list + '(("@@" nil "@")))) +@end group +@end lisp + +@node プログラム実行変換 +@subsection プログラム実行変換 +@cindex @file{skk-gadget.el} + +辞書の候補に Emacs Lisp のプログラムが書いてあれば、そのプログラムを +Emacs に実行させ、返り値をカレントバッファに挿入します。これを @b{「プロ +グラム実行変換」}と呼んでいます。例えば、辞書に + +@example +now /(current-time-string)/ +@end example + +@noindent +というエントリがあるとします。このとき @kbd{/ n o w @key{SPC}} と入力す +れば、現在のバッファに @code{current-time-string} の返り値である + +@example +Sun Jul 21 06:40:34 1996 +@end example + +@noindent +のような文字列が挿入されます。 + +ここで、プログラムの返り値は文字列である必要があります。また、プログラム +実行変換の辞書登録は通常の単語と同様に行うことができますが、その中に改 +行を含まないように書く必要があります +@footnote{通常の単語では、改行を含むことが可能です。それは、評価するとその位置に +改行を挿入するような実行変換プログラムに変換して辞書に書き込んでいるからです。 +@w{@xref{辞書の種類}.} + +しかし、実行変換されるプログラムを辞書登録する際にはこの機能を利用できないため、 +改行を含むことができません。}。 + +今日の日付の入力 +@footnote{@xref{今日の日付の入力}.} で説明した @samp{today} の辞書エント +リは、実際は下記のようなプログラムを候補にもっています。 + +@lisp +@group +today /(let ((skk-date-ad) (skk-number-style t)) (skk-today))/@dots{}/ +@end group +@end lisp + +@file{skk-gadget.el} には、西暦/元号変換や簡単な計算などプログラム実行変 +換用の関数が集められています。 + +@defun skk-calc operator + +skk-calc は、引数を 1 つ取り、見出し語の数字に対しその演算を行う簡単な計算 +プログラムです。 + +@lisp +@group +(defun skk-calc (operator) + ;;@r{2つの引数を取って operator の計算をする。} + ;;@r{注意: '/ は引数として渡せないので (defalias 'div '/) などとし、別の形で} + ;;@r{skk-calc に渡す。} + ;;@r{辞書見出し例; #*# /(skk-calc '*)/} + (number-to-string (apply operator + (mapcar 'string-to-number + skk-num-list)))) +@end group +@end lisp + +この関数を実際にプログラム実行変換で利用するには、辞書に以下のようなエン +トリを追加します +@footnote{@ref{数値変換}.}。 + +@example +#*# /(skk-calc '*)/ +@end example + +@noindent +@kbd{Q 1 1 1 * 4 5 @key{SPC}} と入力します。ここで、@samp{111} と +@samp{45} の 2 つの数字は、変換時に @w{@code{("111" "45")}} のような文字 +列のリストにまとめられ、変数 @code{skk-num-list} の値として保存されます。 +次に関数 @code{skk-calc} が呼ばれます。この中で、@code{skk-num-list} の +各要素に対し演算を行うため、各要素は数に変換されます。その上で、 +@code{skk-calc} に与えられた引数 (この場合は @samp{*}) を演算子として演 +算を行います。 +@end defun + +@defun skk-gadget-units-conversion 基準単位 数値 変換単位 + +数値について、基準単位から変換単位への変換を行います。 + +@example +@kbd{/ 1 3 m i l e} + +@group +------ Buffer: foo ------ +▽13mile@point{} +------ Buffer: foo ------ +@end group + +@key{SPC} + +@group +------ Buffer: foo ------ +▼20.9209km@point{} +------ Buffer: foo ------ +@end group + +@key{RET} + +@group +------ Buffer: foo ------ +20.9209km@point{} +------ Buffer: foo ------ +@end group +@end example + +単位変換の情報は、変数 @code{skk-units-alist} で定義されています。 +@end defun + +@defvr {ユーザ変数} skk-units-alist + +この変数は以下の形式の連想リストです。 + +@example +(基準となる単位 (変換する単位 . 変換時の倍率) + (… . …)) +@end example + +関数 @code{skk-gadget-units-conversion} で利用されています。デフォルトで +は、以下の単位変換の情報を定義しています。 + +@lisp +@group +("mile" ("km" . 1.6093) + ("yard" . 1760)) + +("yard" ("feet" . 3) + ("cm" . 91.44)) + +("feet" ("inch" . 12) + ("cm" . 30.48)) + +("inch" ("feet" . 0.5) + ("cm" . 2.54)) +@end group +@end lisp +@end defvr + +@defun skk-relative-date pp-function format and-time &key (yy 0) (mm 0) (dd 0) + +@code{skk-current-date} の拡張版。@code{PP-FUNCTION}, @code{FORMAT}, @code{AND-TIME} の +意味は @code{skk-current-date} の docstring を参照のこと。 +キーワード変数 @code{:yy}, @code{:mm}, @code{:dd} に正または負の数値を指定することで +明日、明後日、一昨日などの日付を求めることができる。 +詳細は @file{skk-gadget.el} のコメントを参照のこと。 + +@end defun + +@node 空白・改行・タブを含んだ見出し語の変換 +@subsection 空白・改行・タブを含んだ見出し語の変換 + +変換の際、見出し語の中の空白、改行、タブは無視されます。 + +@example +@group +---------------- Buffer: foo ------------------ +▽じんじょうしょ +うがっこう@point{} +---------------- Buffer: foo ------------------ +@end group + +@key{SPC} + +@group +---------------- Buffer: foo ------------------ +▼尋常小学校@point{} +---------------- Buffer: foo ------------------ +@end group +@end example + +オートフィルモードで折り返された文字列に対し、折り返された状 +態のまま変換することもできます。 + +@example +@group +---------------- Buffer: foo ------------------ +仮名漢字変換プログラムをさ +くせいしました。@point{} +---------------- Buffer: foo ------------------ +@end group + +@kbd{C-u 10 C-b Q} + +@group +---------------- Buffer: foo ------------------ +仮名漢字変換プログラムを▽@point{}さ +くせいしました。 +---------------- Buffer: foo ------------------ +@end group + +@kbd{C-u 5 C-f} + +@group +---------------- Buffer: foo ------------------ +仮名漢字変換プログラムを▽さ +くせい@point{}しました。 +---------------- Buffer: foo ------------------ +@end group + +@key{SPC} + +@group +---------------- Buffer: foo ------------------ +仮名漢字変換プログラムを▼作成@point{}しました。 +---------------- Buffer: foo ------------------ +@end group +@end example + +ここでは改行を越えて見出し語を探し、変換する例を示しました。同様に、空白、 +タブ文字を中間に含む文字列に対しても変換を行うことができます。 + +@defvr {ユーザ変数} skk-allow-spaces-newlines-and-tabs + +この変数を @code{nil} に設定すると、本節で説明したような2行以上にまたが +る文字列に対する変換を禁止します。 + +@end defvr + +@node カタカナ変換 +@subsection カタカナ変換 + +@defvr {ユーザ変数} skk-search-katakana + +通常、SKK でカタカナ語を入力するには、 +@itemize @bullet +@item @kbd{q} でカナモードに移ってからカタカナを入力する +@item ▽モードで @kbd{q} によりカタカナへ変換する@footnote{@ref{かなモードからカタカナを入力}} +@end itemize +のどちらかです。これらの方法は手軽ですが、個人辞書に登録されないため見出 +し語の補完候補にも現れず、何度でも入力しなければいけません。 + +そこで、ここに紹介する方法ではカタカナ語が普通の変換候補として現れ、個人 +辞書にも登録されます。設定するには以下を @file{~/.skk} に記述します +@footnote{@code{skk-search-prog-list} の設定をユーザが変更している場合は +期待どおりに動作しない場合があります。その場合は@code{skk-search-prog-list} の +設定に関数 @code{skk-search-katakana} の呼び出しがあることを確認してくだ +さい。またこの機能の設定は DDSKK 14.1 以前では異なります。詳しくはソース +に付属のドキュメント、設定例をご覧ください。}。 + +@lisp +(setq skk-search-katakana t) +@end lisp + +また、値をシンボル@code{'jisx0201-kana} とすると、カタカナ候補に加え半角 +カタカナ候補も変換候補に現れます。 + +@lisp +(setq skk-search-katakana 'jisx0201-kana) +@end lisp +@end defvr + +@node サ変動詞変換 +@subsection サ変動詞変換 + +@defvr {ユーザ変数} skk-search-sagyo-henkaku + +通常、SKK では諸般の事情によりサ行変格活用の動詞は送りなし変換をする前提 +になっています。このことは共有辞書のメンテナンスにおける便宜上やむをえな +いのですが、個人辞書が育たない (サ変動詞と名詞の区別ができない) という弱 +点もあります。(@w{@pxref{サ変動詞の辞書登録に関する注意}}) + +しかし、ここに紹介する方法では任意の送りなし候補を利用してサ行の送りプレ +フィックスに限定して送りあり変換が可能になり、個人辞書を育てることが可能 +になります。設定するには以下を @file{~/.skk} に記述します。 +@footnote{@code{skk-search-prog-list} の設定をユーザが変更している場合は +期待どおりに動作しない場合があります。その場合は @code{skk-search-prog-list} +の設定に関数 @code{skk-search-sagyo-henkaku} の呼び出しがあることを確認 +してください。またこの機能の設定は DDSKK 14.1 以前では異なります。詳しく +はソースに付属のドキュメント、設定例をご覧ください。} + +@lisp +(setq skk-search-sagyo-henkaku t) +@end lisp + +例えば @samp{お茶する} の変換は以下のように変化します。 + +@itemize @bullet +@item 従来 … @kbd{O c h a @key{SPC} s u r u} +@item サ変 … @kbd{O c h a S u r u} +@end itemize + +変数の値を @code{anything} に設定すると、サ行に限らず任意の送り仮名を許 +可し、送りあり変換をします。これにより、送りあり変換の利用範囲を形容詞・ +動詞の変換のみならず、あらゆるひらがな開始点の指定に拡張することができま +す。 + +このサ変動詞送りあり変換機能は、カタカナ変換機能と組み合わせるとさらに有 +効です。(@w{@pxref{カタカナ変換}}) +@end defvr + +@node 異体字へ変換する +@subsection 異体字へ変換する +@samp{辺} (42区53点) の異体字である @samp{邊} (78区20点) や @samp{邉} (78 +区21点) を入力したいときがあります@footnote{辞書が充実していればかな漢字 +変換で見出し語 @samp{へん} から @samp{邊} や @samp{邉} を求めることができ +ます。もちろん、文字コードを指定して @samp{邊} や @samp{邉} を直接挿入す +ることもできます。}。 + +@example +@point{}辺 + +@kbd{Q} + +▽@point{}辺 + +@kbd{C-f} + +▽辺@point{} + +@key{SPC} + +▼邊@point{} + +@key{SPC} + +▼邉@point{} + +@end example + +@defvr {ユーザ変数} skk-itaiji-jisyo + +辞書ファイル @file{SKK-JISYO.itaiji} 又は @file{SKK-JISYO.itaiji.JIS3_4} へ +のパスを指定する。 + +他の辞書ファイルと異なり、この 2 つの辞書ファイルは見出し語が漢字です。 + +@end defvr + +@defun skk-search-itaiji + +not documented + +@url{http://mail.ring.gr.jp/skk/200303/msg00071.html} + +@end defun + +@node ファンクションキーの使い方 +@subsection ファンクションキーの使い方 + +@defvr {ユーザ変数} skk-j-mode-function-key-usage + +シンボル @code{conversion} ならば、@code{skk-search-prog-list-1} 〜 @code{skk-search-prog-list-9} および @code{skk-search-prog-list-0} を +実行するよう自動設定します。これらのプログラムは▽モード限定でファンクション +キー (@key{[F1]} 〜 @key{[F10]}) に割り当てられます。@key{[F5]} 〜 @key{[F10]} に +ついては本オプションの設定により自動的に割り当てられます。 +これらの割り当てはユーザオプション @code{skk-verbose} を設定するとエコー +エリアに表示されるようになります。(@w{@pxref{冗長な案内メッセージの表示}}) + +@itemize @bullet +@item @key{[F5]} … 単漢字 +@item @key{[F6]} … 無変換 +@item @key{[F7]} … カタカナ +@item @key{[F8]} … 半角カナ +@item @key{[F9]} … 全角ローマ +@item @key{[F10]} … ローマ +@end itemize + +シンボル @code{kanagaki} ならば、かなキーボード入力用に自動設定します。 + +@code{nil} ならば、自動設定しません。 + +@end defvr + +@node キー設定 +@section キー設定 +@cindex キー設定 + +@menu +文字の入力 +* かなモード/カナモードのキー設定:: +* 全英モードのキー設定:: +* 閉じ括弧の自動入力:: +* リージョンを括弧で囲む:: + +@noindent +変換、確定など +* 確定するキー:: RET 以外で確定されるには +* 候補の選択に用いるキー:: asdfjkl 以外 +* ▼モードでのRET:: 改行も同時にする? しない? +* ▼モードでのBS:: 削除 vs 前候補 +* 送りあり変換中のC-g:: +* 変換位置の指定方法:: 大文字以外でも変換位置を指定可能に。 + +@noindent +他 +* 1回の取り消し操作(undo)の対象:: +@end menu + +関連項目: @w{@ref{ローマ字入力以外の入力方式}} + +@node かなモード/カナモードのキー設定 +@subsection かなモード/カナモードのキー設定 + +@menu +* ローマ字のルールの設定:: +* ローマ字ルールの変更例:: 略号なども設定できます。 +* ■モードに関連するその他の変数:: +* 数字や記号文字の入力:: +@end menu + +@node ローマ字のルールの設定 +@subsubsection ローマ字のルールの設定 + +@table @code +@item skk-rom-kana-base-rule-list +@vindex skk-rom-kana-base-rule-list +@item skk-rom-kana-rule-list +@vindex skk-rom-kana-rule-list +@end table + +DDSKK の■モードにおける文字変換は、これら2つの変数を用いて行われます。 +@code{skk-rom-kana-base-rule-list} には基本的なローマ字かな変換のルールが +定められています。一方、@code{skk-rom-kana-rule-list} はユーザが独自のルールを +定めるために用意されており、@code{skk-rom-kana-base-rule-list} よりも優先されます。 + +これらは「入出力の状態がいかに移り変わるべきか」を決定します。その内容は、 + +@lisp +@example +(入力される文字列 出力後に自動的に入力に追加される文字列 出力) +@end example +@end lisp + +@noindent +という形のリストを列挙したものです。 + +@itemize @bullet +@item 入力される文字列…変換される前のアスキー文字の文字列をいいます。 + +@item 出力…次の入力状態に移るときにバッファに挿入される文字列の組み合 +わせであり、 @w{@code{("ア" . "あ")}} のようなコンスセルです。 + +@end itemize + +@code{skk-rom-kana-base-rule-list} の一部を見てみましょう。 + +@lisp +@example +("a" nil ("ア" . "あ")) +("ki" nil ("キ" . "き")) +("tt" "t" ("ッ" . "っ")) +("nn" nil ("ン" . "ん")) +("n'" nil ("ン" . "ん")) +@end example +@end lisp + +@noindent +のような規則があります。これによると + +@example +a @expansion{}あ +ki @expansion{}き +tt @expansion{}っt +nn @expansion{}ん +n' @expansion{}ん +@end example + +@noindent +のようになります。 + +@code{skk-rom-kana-base-rule-list} には、次のような便利な変換ルールも定め +られています。 + +@example +z @expansion{} □ (全角スペース) +z* @expansion{} ※ +z, @expansion{} ‥ +z- @expansion{} 〜 +z. @expansion{} … +z/ @expansion{} ・ +z0 @expansion{} ○ +z@@ @expansion{} ◎ +z[ @expansion{} 『 +z] @expansion{} 』 +z@{ @expansion{} 【 +z@} @expansion{} 】 +z( @expansion{} ( +z) @expansion{} ) +zh @expansion{} ← +zj @expansion{} ↓ +zk @expansion{} ↑ +zl @expansion{} → +zL @expansion{} ⇒ +@end example + +@node ローマ字ルールの変更例 +@subsubsection ローマ字ルールの変更例 + +@code{skk-rom-kana-base-rule-list} の規則に従うと + +@example +hannou @expansion{}はんおう +han'ou @expansion{}はんおう +hannnou @expansion{}はんのう +@end example + +@noindent +のようになります。ここで + +@lisp +@group +(setq skk-rom-kana-rule-list + (append skk-rom-kana-rule-list + '(("nn" "n" ("ン" . "ん"))))) +@end group +@end lisp + +@noindent +のような設定にすることで + +@example +hannou @expansion{}はんのう +@end example + +@noindent +のようにローマ字かな変換が行われるようになります。 + +他の例として、略号を設定することもできます。 + +@example +tp @expansion{}東北大学 +skk @expansion{}skk +skK @expansion{}SKK +@end example + +@noindent +といった変換は、 + +@lisp +@group +("tp" nil ("東北大学" . "東北大学")) +("sk" nil ("" . "")) +("skk" nil ("skk" . "skk")) +("skK" nil ("SKK" . "SKK")) +@end group +@end lisp + +@noindent +のような規則を追加することで実現されます。自分の名前を入力することはよく +あるので、適当な省略形を用いて、このリストに追加しておく、といった利用を +お勧めします。 + +更に @code{skk-rom-kana-rule-list} を用いれば TUT-code による日本語入力を +実現することもできます。TUT-code による入力についてはソースアーカイブ +の @samp{tut-code} ディレクトリに収録されている各ファイルを参照してくださ +い。@w{(@pxref{ローマ字入力以外の入力方式})} + +@node ■モードに関連するその他の変数 +@subsubsection ■モードに関連するその他の変数 + +@defvr {ユーザ変数} skk-kana-input-search-function + +ルールリストの中に記せない変換ルールを処理する関数。 +これは @code{skk-rom-kana-base-rule-list} と @code{skk-rom-kana-rule-list} の +要素を全て検索した後にコールされます。引数はありません。バッファの文字を、 +直接 @code{preceding-char} などで調べて下さい。 + +初期設定では @kbd{h} で、長音を表すために使われています。次の例を見て下さい。 + +@example +ohsaka @expansion{} おおさか +ohta @expansion{} おおた +@end example + +@noindent +一方で、@kbd{hh} は「っ」になります。 + +@example +ohhonn @expansion{} おっほん +ohhira @expansion{} おっひら +@end example + +@noindent +これは @code{skk-rom-kana-rule-list} のデフォルトに + +@lisp +("hh" "h" ("ッ" . "っ")) +@end lisp + +@noindent +が入っているためです。これを削除すれば + +@example +ohhonn @expansion{} おおほん +ohhira @expansion{} おおひら +@end example + +@noindent +となります。 +@end defvr + +@kindex M-x skk-toggle-kutouten +@defvr {ユーザ変数} skk-kutouten-type +■モードの標準では、キーボードの @kbd{.} をタイプすると「。」が、 +@kbd{,} をタイプすると「、」がバッファに入力されます。 +変数 @code{skk-kutouten-type} に適切なシンボルを設定することにより、この +組み合せを変更することができます +@footnote{変数 @code{skk-use-kana-keyboard} が @code{non-nil} ならば無効 +である。}。そのシンボルとは、次の4つです。 + +@example +'jp@ @ @ @ @expansion{} 「。」「、」 (デフォルト) +'en@ @ @ @ @expansion{} 「.」「,」 +'jp-en @expansion{} 「。」「,」 +'en-jp @expansion{} 「.」「、」 +@end example + +または、変数 @code{skk-kutouten-type} にはコンスセルを指定することも可 +能です。その場合は、 + +@example +(句点を示す文字列 . 読点を示す文字列) +@end example + +のように指定します。例として、次のように設定するとキーボード +の @kbd{.} で @code{abc} が、@kbd{,} で @code{def} がバッファに入力され +ます。 +@c ↓実用的な例が思い付きませんでした +@lisp +(setq skk-kutouten-type '("abc" . "def")) +@end lisp + +なお、変数 @code{skk-kutouten-type} はバッファローカル変数です。すべての +バッファで統一した設定としたい場合は、 + +@lisp +(setq-default skk-kutouten-type 'en) +@end lisp + +のように関数 @code{setq-default} を用いてください。 +@end defvr + +@defvr {ユーザ変数} skk-use-auto-kutouten + +デフォルトは @code{nil}。@code{Non-nil} であれば、カーソル直前の文字種に +応じて句読点を動的に変更します。 + +@end defvr + +@node 数字や記号文字の入力 +@subsubsection 数字や記号文字の入力 + +かなモード/カナモードにおける次のキーは、関数 @code{skk-insert} にバインドされています。 + +@example +@group +! # % & ' * + + +- 0 1 2 3 4 5 + +6 7 8 9 : ; < + += > ? " ( ) [ + +] @{ @} ^ _ ` | + +~ +@end group +@end example + +これらの数字や記号文字のキーに対応し挿入される文字をカスタマイズするため +には、変数 @code{skk-rom-kana-rule-list} を利用します。 + +@lisp +@group +(setq skk-rom-kana-rule-list + (append skk-rom-kana-rule-list + '(("!" nil "!") + ("," nil ",") + ("." nil ".") + (":" nil ":") + (";" nil ";") + ("?" nil "?")))) +@end group +@end lisp + +@code{skk-insert} は、Emacs のオリジナル関数 @code{self-insert-command} +をエミュレートしています。具体的には、引数を渡すことによって同じ文字を複 +数、一度に挿入することが可能です。 + +@example +@group + +@kbd{C-u 2 !} + +------ Buffer: foo ------ +!! +------ Buffer: foo ------ +@end group +@end example + +@node 全英モードのキー設定 +@subsection 全英モードのキー設定 + +全英モードにおける印字可能な全てのキーはコマンド +@code{skk-jisx0208-latin-insert} に割り付けられています。また、変数 +@code{skk-jisx0208-latin-vector} の値により挿入される文字が決定され、 +そのデフォルトは以下のようになっています。 + +@lisp +@group +[nil nil nil nil nil nil nil nil + nil nil nil nil nil nil nil nil + nil nil nil nil nil nil nil nil + nil nil nil nil nil nil nil nil + " " "!" "”" "#" "$" "%" "&" "’" + "(" ")" "*" "+" "," "−" "." "/" + "0" "1" "2" "3" "4" "5" "6" "7" + "8" "9" ":" ";" "<" "=" ">" "?" + "@" "A" "B" "C" "D" "E" "F" "G" + "H" "I" "J" "K" "L" "M" "N" "O" + "P" "Q" "R" "S" "T" "U" "V" "W" + "X" "Y" "Z" "[" "\" "]" "^" "_" + "‘" "a" "b" "c" "d" "e" "f" "g" + "h" "i" "j" "k" "l" "m" "n" "o" + "p" "q" "r" "s" "t" "u" "v" "w" + "x" "y" "z" "{" "|" "}" "〜" nil] +@end group +@end lisp + +挿入される文字を変更したい場合は、@w{@ref{数字や記号文字の入力}} を参照し +てください。 + +@code{skk-jisx0208-latin-insert} も Emacs オリジナルの関数 +@code{self-insert-command} をエミュレートしています。つまり、引数を渡す +ことにより同じ文字を複数、一度に挿入することができます。 +@code{skk-insert} における動作と同じですから、 +@w{@ref{数字や記号文字の入力}} の例を参考にしてください。 + +@node 閉じ括弧の自動入力 +@subsection 閉じ括弧の自動入力 + +@c 次の行、今は当てはまらない? ChangeLog を見たが記述なし。(2009-11-19) +@c @samp{「}や@samp{」}が上手く処理されない...。 +通常、`「' を入力したら、`」' を後で入力する必要があります。`「' の入 +力時点で、対になる文字を自動挿入してくれると打鍵数を減らすことができます +し、同時に入力忘れの防止にもなるでしょう。 + +@vindex skk-auto-insert-paren +そのために変数 @code{skk-auto-insert-paren} が用意されています。この値を +@code{non-nil} にすると、上記の自動挿入を行います。 + +@example +@group +------ Buffer: foo ------ +彼はこう言った@point{} +------ Buffer: foo ------ + +@kbd{[} + +------ Buffer: foo ------ +彼はこう言った「@point{}」 +------ Buffer: foo ------ +@end group +@end example + +@noindent +@c @samp{「}や@samp{」}が上手く処理されない...。 +上記のように `「' の入力時点で対となる`」'を自動挿入し、`「'と`」'の間に +ポイントを再配置するので、その位置からかぎかっこに囲まれた文字列を即始め +ることができます。 + +@defvr {ユーザ変数} skk-auto-paren-string-alist +自動挿入すべきペアの文字列を指定します。デフォルトは下記のとおり。 + +@lisp +@group +(("「" . "」") ("『" . "』") ("(" . ")") ("(" . ")") ("@{" . "@}") + ("{" . "}") ("〈" . "〉") ("《" . "》") ("[" . "]") ("[" . "]") + ("〔" . "〕") ("【" . "】") ("\"" . "\"") ("“" . "”") ("`" . "'")) +@end group +@end lisp + +これは、ひと言でまとめると、「開き括弧と閉じ括弧とのコンスセルを集めたリ +スト」です。各コンスセルの @code{car} にある文字列を挿入したときに、 +@code{cdr} にある文字列が自動挿入されます。 +@vindex skk-rom-kana-rule-list +@footnote{このリストの各要素の @code{car} の文字列は、必ず変数 +@code{skk-rom-kana-rule-list} の規則によって入力されなければなりません。 +例えば、@samp{(} に対する @samp{)} を自動挿入するには + +@lisp +@group +(setq skk-rom-kana-rule-list + (append skk-rom-kana-rule-list + '(("(" nil "(")))) +@end group +@end lisp + +@noindent +のように設定する必要があります。} +@footnote{既に SKK モードになっているバッファで変数 +@code{skk-auto-paren-string-alist} を変更した場合は、@kbd{C-x C-j} もし +くは @kbd{C-x j} を 2 度タイプして @code{skk-mode} もしくは +@code{skk-auto-fill-mode} を起動し直す必要があります。} + +@end defvr + +キーとなる文字が挿入されても、その挿入後のポイントに自動挿入すべき文字が +既に存在している場合には、自動挿入されないように設計されています。 + +@example +@group +------ Buffer: foo ------ +@point{}」 +------ Buffer: foo ------ + +@kbd{[} + +------ Buffer: foo ------ +「@point{}」 +------ Buffer: foo ------ + +@end group +@end example + +対になる文字を複数挿入したい場合は、引数を渡して文字を指定します。 + +@example +@group + +@kbd{C-u 2 [} + +------ Buffer: foo ------ +「「@point{}」」 +------ Buffer: foo ------ +@end group +@end example + +@vindex yatex-mode +@code{yatex-mode} など、既に同様の機能が付いているモードがあります。その +ようなモードにおいてもこの自動挿入の機能が邪魔になることはないでしょうが、 +特定のモードに限って自動入力機能をオフにしたい場合は、当該モードに入った +ときにコールされるフック変数を利用して設定することができます。 + +@lisp +@group +(add-hook 'yatex-mode-hook + (lambda () + (when skk-auto-insert-paren + (make-local-variable 'skk-auto-insert-paren) + (setq skk-auto-insert-paren nil)))) +@end group +@end lisp + +特定のモードにおいて、自動挿入すべき文字を変更したい場合にも同様にフック +変数を用いて操作できます。 + +@vindex tex-mode-hook +@lisp +@group +(add-hook 'tex-mode-hook + (lambda () + (when skk-auto-insert-paren + (make-local-variable 'skk-auto-paren-string-alist) + (setq skk-auto-paren-string-alist + (cons '("$" . "$") skk-auto-paren-string-alist))))) +@end group +@end lisp + +@noindent +同様に、特定のペアを削除したい場合は、例えば下記のように設定します。 +@c @footnote{何故関数 @code{copy-sequence} を使用するのかについては、 +@c @w{@ref{数字や記号文字の入力}} を参照してください。}。 + +@lisp +@group +(add-hook 'tex-mode-hook + (lambda () + (when skk-auto-insert-paren + (make-local-variable 'skk-auto-paren-string-alist) + (setq skk-auto-paren-string-alist + (delete + '("$" . "$") + (copy-sequence skk-auto-paren-string-alist)))))) +@end group +@end lisp + +@node リージョンを括弧で囲む +@subsection リージョンを括弧で囲む + +「閉じ括弧の自動入力」の応用として、リージョンを括弧で囲むことができます。 + +@example +@group +------ Buffer: foo ------ +このマニュアルにおいて@point{}DDSKK@point{}と呼びます +------ Buffer: foo ------ + +@kbd{`} + +------ Buffer: foo ------ +このマニュアルにおいて`DDSKK'と呼びます +------ Buffer: foo ------ +@end group +@end example + +@defvr {ユーザ変数} skk-use-auto-enclose-pair-of-region +@code{non-nil} であれば、上記の機能が有効になります。 +当然に @code{skk-auto-insert-paren} も @code{non-nil} である必要があります。 + +なお、@code{delete-selection-mode} の方が優先されます。 +@end defvr + +@node 確定するキー +@subsection 確定するキー +@kindex C-j + +@defvr {ユーザ変数} skk-kakutei-key + +この変数の値は、明示的な確定動作を行うキーを指定します。 +標準設定では @kbd{C-j} となっています。 + +@end defvr + +関連事項: @w{@ref{暗黙の確定のタイミング}} + +@node 候補の選択に用いるキー +@subsection 候補の選択に用いるキー + +変換において、候補が5つ以上あるときは、5番目以降の候補は7つずつ +まとめてエコーエリアに下記のように表示されます +@footnote{@ref{▼モード}.}。 + +@example +@group +-------------------- Echo Area -------------------- +A:嘘 S:拒 D:拠 F:虚 J:挙 K:許 L:渠 [残り 2] +-------------------- Echo Area -------------------- +@end group +@end example + +この際、候補の選択に用いるキーは、次の変数によって決定されます。 + +@defvr {ユーザ変数} skk-henkan-show-candidates-keys + +7つの異なる文字のリスト。文字は必ず小文字とする +@footnote{@kbd{x}, @key{SPC} 及び @kbd{C-g} は、それぞれ候補選択中に +おける前候補群の表示、次候補群の表示、取り止めのために割り付けられている +ので、@code{skk-henkan-show-candidates-keys} の中に含めてはいけません。}。 +デフォルトは、以下のとおり。 + +@lisp +(?a ?s ?d ?f ?j ?k ?l) +@end lisp +@end defvr + +@c メニューによる文字入力 +@c @footnote{@w{@ref{文字コードまたはメニューによる文字入力}}.}の際に候補の選択 +@c に用いられるキーは、次の2つの変数により変更されます。 +@c +@c @defvr {ユーザ変数} skk-input-by-code-menu-keys1 +@c +@c 第1段階のメニューにおける候補の選択キー。デフォルトは、 +@c +@c @lisp +@c (?a ?s ?d ?f ?g ?h ?q ?w ?e ?r ?t ?y) +@c @end lisp +@c +@c @noindent +@c です。このリストには 12 個の異なる文字を含む必要があります。 +@c +@c @end defvr +@c +@c @defvr {ユーザ変数} skk-input-by-code-menu-keys2 +@c +@c 第2段階のメニューにおける候補の選択キー。デフォルトは、 +@c +@c @lisp +@c (?a ?s ?d ?f ?g ?h ?j ?k ?l ?q ?w ?e ?r ?t ?y ?u) +@c @end lisp +@c +@c @noindent +@c です。このリストには 16 個の異なる文字を含む必要があります。 +@c @end defvr +@c +@c 上記の2つの変数の要素は@b{全て小文字で指定すること}を強くお勧めします +@c @footnote{小文字が指定された場合は、候補の選択の際に対応する大文字キーが +@c 入力されても候補の選択が可能となるように設計されています。その一方で、大 +@c 文字が指定された場合、候補の選択の際に対応する小文字キーが入力されても候 +@c 補の選択ができません。これは現在の仕様です。}。 +@c +@defvr {ユーザ変数} skk-henkan-show-candidates-keys-face +選択キーを表示する際のフェイスを指定します。 +@end defvr + +@defvr {ユーザ変数} skk-henkan-rest-indicator +デフォルトは @code{nil}。@code{Non-nil} であれば @samp{[残り 99++]} の表示を右寄せ配置する。 +@end defvr + +@defvr {ユーザ変数} skk-henkan-rest-indicator-face +@samp{[残り 99++]} の face 属性。デフォルトは @code{default}。 +@end defvr + +@node ▼モードでのRET +@subsection ▼モードでのRET + +標準設定では、 + +@example +@kbd{K a k u t e i @key{SPC}} + +@group +------ Buffer: foo ------ +▼確定@point{} +------ Buffer: foo ------ +@end group + +@key{RET} + +@group +------ Buffer: foo ------ +確定 +@point{} +------ Buffer: foo ------ +@end group +@end example + +@noindent +のように、▼モードで @key{RET} を入力すると、確定し、かつ改行を行います。 +この挙動を変えるためのユーザオプションが用意されています。 + +@defvr {ユーザ変数} skk-egg-like-newline + +この変数の値を @code{non-nil} にすると、▼モードで @key{RET} を入力した +ときに確定のみ行い、改行はしません@footnote{従って、辞書登録モードにおいて▼モードであるときの @key{RET} +入力時の挙動も変化します。標準の確定、登録の動作については、 +@w{@ref{辞書登録モード}} を参照してください。}。 + +@end defvr + +@example +@kbd{K a k u t e i @key{SPC}} + +@group +------ Buffer: foo ------ +▼確定@point{} +------ Buffer: foo ------ +@end group + +@key{RET} + +@group +------ Buffer: foo ------ +確定@point{} +------ Buffer: foo ------ +@end group +@end example + +@node ▼モードでのBS +@subsection ▼モードでのBS +@kindex @key{BS} + +標準設定では、▼モードで @key{BS} を押すと、前の一文字を削除した上で確定 +します。 + +@example +@kbd{D e n k i y a @key{SPC}} + +@group +------ Buffer: foo ------ +▼電気屋@point{} +------ Buffer: foo ------ +@end group + +@key{BS} + +@group +------ Buffer: foo ------ +電気@point{} +------ Buffer: foo ------ +@end group +@end example + +@defvr {ユーザ変数} skk-delete-implies-kakutei + +この変数の値を @code{nil} に設定すると、▼モードで @key{BS} を押した時 +に一つ前の候補を表示します。例えば、 + +@example +でんき /電気/伝記/ +@end example + +@noindent +という辞書エントリがあるとき、以下のようになります。 + +@example +@kbd{D e n k i} + +@group +------ Buffer: foo ------ +▽でんき@point{} +------ Buffer: foo ------ +@end group + +@key{SPC} + +@group +------ Buffer: foo ------ +▼電気@point{} +------ Buffer: foo ------ +@end group + +@key{SPC} + +@group +------ Buffer: foo ------ +▼伝記@point{} +------ Buffer: foo ------ +@end group + +@key{BS} + +@group +------ Buffer: foo ------ +▼電気@point{} +------ Buffer: foo ------ +@end group + +@key{BS} + +@group +------ Buffer: foo ------ +▽でんき@point{} +------ Buffer: foo ------ +@end group +@end example +@end defvr + +変数 @code{skk-delete-implies-kakutei} がシンボル @code{dont-update} で +あれば、@code{non-nil} 時と同じ動作のうえで個人辞書を更新しません。 + +なお、変数 @code{skk-delete-implies-kakutei} の値にかかわらず、*候補*バッファ +を表示している場合は一つ前の候補表示に戻る動作となります。 + +@node 送りあり変換中のC-g +@subsection 送りあり変換中のC-g +@kindex C-g + +送りありの変換中に @kbd{C-g} を入力すると、▼モードを抜け、その見出し語 +と送り仮名を現在のバッファに挿入し、▽モードに入ります。 + +@example +@kbd{N a K u} + +@group +------ Buffer: foo ------ +▼泣く@point{} +------ Buffer: foo ------ +@end group + +@kbd{C-g} + +@group +------ Buffer: foo ------ +▽なく@point{} +------ Buffer: foo ------ +@end group +@end example + +@defvr {ユーザ変数} skk-delete-okuri-when-quit + +この変数の値を @code{non-nil} に設定すると、送りありの変換中に @kbd{C-g} を +入力したときの挙動が変化します。▽モードに入るのは同じですが、同時に +送り仮名を消します。送り仮名の入力間違いを修正するのには便利です。 +例えば、以下のようになります。 +@end defvr + +@example +@kbd{N a K u} + +@group +------ Buffer: foo ------ +▼泣く@point{} +------ Buffer: foo ------ +@end group + +@kbd{C-g} + +@group +------ Buffer: foo ------ +▽な@point{} +------ Buffer: foo ------ +@end group +@end example + +@node 変換位置の指定方法 +@subsection 変換位置の指定方法 +@cindex @file{skk-sticky.el} +@kindex ; + +SKK では通常、「漢字変換の開始位置」と「送り仮名の開始位置」を大文字で指定します +が、これらを任意のキーで指定することで sticky-shift ライクな操作 +@footnote{あくまでも「任意のキーで変換開始位置を指定する」ものであり、 +sticky-shift そのものではありません。したがって、アスキーモードや +abbrev モード、また SKK 以外でも sticky-shift を使いたい場合は前述のような +設定を併用する必要があります。}も可能です。 + +@lisp +(setq skk-sticky-key ";") +@end lisp + +@noindent +と設定すると @kbd{;} キーで +@footnote{@file{skk-hint.el} を併用する場合は @code{skk-hint-start-char} +のデフォルトも @kbd{;} であるため、どちらかを別のキーに割り当てる必要が +あります。@w{@pxref{候補の絞り込み}}} 漢字変換位置が指定できるようになり +ます。 + +例えば @samp{有る} という単語を入力するには + +@example +@kbd{; a ; r u} +@end example + +というキー入力で可能となり、シフトキーを押す必要がなくなります。 + +操作上は +@w{@pxref{Q3-4 左手の小指を SHIFT で酷使したくありません。}} などにある通 +常の sticky-shift と変わりませんが、画面表示は + +@display +@group +@multitable {打鍵 } {通常の@tie{}sticky} {skk-sticky} +@item 打鍵 +@tab 通常の@tie{}sticky +@tab skk-sticky +@item @kbd{;} +@tab 変化なし +@tab ▽ +@item @kbd{a} +@tab ▽あ +@tab ▽あ +@item @kbd{;} +@tab ▽あ +@tab ▽あ* +@item @kbd{r} +@tab ▽あ*r +@tab ▽あ*r +@end multitable +@end group +@end display + +@noindent +と遷移します。通常の sticky と比べて skk-sticky は @kbd{;} を押した時点で +画面表示が変化するので若干分かり易いと思います。 + +キーの設定方法は、割り当てるキーの種類によって異なります。 + +@enumerate +@item +表示を伴うキー + +@kbd{;} などの表示を伴うキーの場合は + +@lisp +(setq skk-sticky-key ";") +@end lisp + +のように @code{string} を設定して下さい。@code{skk-sticky-key} に設定した +文字そのものを入力したい場合は2回続けて打つと入力できます。 + +@item +表示を伴わないキー + +【@key{無変換}】のような表示を伴わないキーの場合は + +@lisp +(setq skk-sticky-key [muhenkan]) ;Microsoft Windows では [noconvert] +@end lisp + +のようにそのキーを表わす @code{vector} を設定して下さい。 + +@item +同時打鍵 + +2つのキーを同時に打鍵することでも漢字変換位置を指定できます。例えば +@kbd{f} と @kbd{j} の同時打鍵で指定する場合は + +@lisp +(setq skk-sticky-key '(?f ?j)) +@end lisp + +のように @code{character} のリストを設定して下さい。 + +Dvorak 配列のような、押しやすい場所に適当なキーがない環境でもこの機能を使 +いたい場合に便利かもしれません。 +@end enumerate + +@defvr {ユーザ変数} skk-sticky-double-interval + +この変数が指定する秒数以内に打鍵されたものを同時打鍵と判定する。 +デフォルトは 0.1 秒。 + +@end defvr + +@node 1回の取り消し操作(undo)の対象 +@subsection 1回の取り消し操作(undo)の対象 +@cindex @file{keyboard.c} +@findex self-insert-command +@findex skk-abbrev-comma +@findex skk-abbrev-period +@findex skk-kana-input +@findex skk-insert +@findex skk-set-henkan-point +@findex skk-jisx0208-latin-insert +@vindex skk-self-insert-non-undo-count + +Emacs では本来、連続する 20 文字の挿入が一回の取り消し操作 (アンドゥ) の +対象となっています。そこで DDSKK のかな・カナ・全英モードにおける入力も、 +これと同様の動作をするように設計されています +@footnote{@code{buffer-undo-list} に Emacs が挿入したアンドゥの境目の目印を +取り除く方法でエミュレートしています。}。正確に言えば、 +@code{skk-insert}, @code{skk-set-henkan-point}, +@code{skk-jisx0208-latin-insert} +@footnote{SKK abbrev モードでは、アスキー文字入力が Emacs 本来の +@code{self-insert-command} により行われているので、エミュレーションの +ための内部変数である @code{skk-self-insert-non-undo-count} をインクリメ +ントすることができず、アンドゥをエミュレートできません。しかも、カンマや +ピリオドを挿入した時点で、コマンド @code{skk-abbrev-comma} や +@code{skk-abbrev-period} を使うことになるので、本来のアンドゥの機能も損 +なってしまいます。ただし、現実問題として、元来 SKK abbrev モードは省略形 +としての見出し語を挿入するためのモードですから、長い見出し語を挿入するこ +とはあまりないと考えられます。}の各関数にバインドされたキー入力について +は、連続して入力された 20 文字を 1 つのアンドゥの対象としています +@footnote{`20' は Emacs のソースファイルの一部である @file{keyboard.c} +に定められたマジックナンバーと一致します。}。 + +ただし、これらの DDSKK のコマンドと Emacs 本来の +@code{self-insert-command} を織り混ぜてキー入力した場合 +@footnote{かなモードでの入力中、アスキーモードに移行して入力した場合など +がこれにあたります。}は、このエミュレーションは正常に動作しませんが、こ +れは現在の仕様です。 + +@example +@group +@kbd{a i u e o k a k i k u k e k o s a s i s u s e s o t a t i t u t e t o} + +------------------------- Buffer: foo ------------------------- +あいうえおかきくけこさしすせそたちつてと@point{} ;@r{連続する20文字。} +------------------------- Buffer: foo ------------------------- +@end group +@group + +@kbd{C-_} + +------------------------- Buffer: foo ------------------------- +@point{} ;@r{20文字全てがアンドゥの対象となる。} +------------------------- Buffer: foo ------------------------- +@end group + +@group +@kbd{a i u e o k a k i k u k e k o s a s i s u s e s o t a t i t u t e t o n a} + +-------------------------- Buffer: foo -------------------------- +あいうえおかきくけこさしすせそたちつてとな@point{} ;@r{連続する21文字。} +-------------------------- Buffer: foo -------------------------- +@end group +@group + +@kbd{C-_} + +-------------------------- Buffer: foo -------------------------- +あいうえおかきくけこさしすせそたちつてと@point{} ;@r{最後の1文字のみがアンドゥの対象となる。} +-------------------------- Buffer: foo -------------------------- +@end group +@end example + +@node 変換、確定の前後 +@section 変換、確定の前後 + +@menu +* ポイントを戻して▽モードへ:: ▽モードに入り忘れた! +* 直前の確定を再変換:: 間違って確定したら、再変換 +* 自動変換開始:: @key{SPC} を押さなくても「を」「。」で変換開始。 +* 暗黙の確定のタイミング:: 変換の後、いつ確定するか。 +* 積極的な確定:: 候補が一つ? じゃ確定でしょ。 +* 確定辞書:: 特定の語は一発確定 +@end menu + +関連事項: +@itemize @bullet +@item @w{@ref{送りあり変換の変換開始のタイミング}} +@item @w{@ref{変換位置の指定方法}} (大文字以外で変換位置を指定する方法を説明) +@end itemize + +@node ポイントを戻して▽モードへ +@subsection ポイントを戻して▽モードへ +@cindex 後から▽モードに入る方法 +@findex skk-backward-and-set-henkan-point +@vindex skk-allow-spaces-newlines-and-tabs + +▽モードに入り忘れた場合に、手動で▽マークを付ける方法については、前述しました +@footnote{@w{@xref{後から▽モードに入る方法}.}}。 +ここで述べる方法では、遡って▽マークを付ける位置を自動的に選び、しかもカーソルは動きません。 + +@kindex M-Q +@kbd{M-Q} +(大文字の @samp{Q} です。) とタイプすると現在位置の直前の文字列について走査し、 +同種の文字 @footnote{ひらがな、カタカナ、全角アルファベット、アルファベットの 4 種 +類のいずれか。}が続く限り後方に戻り、▽マークを付けます。ポイントは動きません。 + +@example +@kbd{k a n j i} + +@group +------ Buffer: foo ------ +かんじ@point{} +------ Buffer: foo ------ +@end group + +@kbd{M-Q} + +@group +------ Buffer: foo ------ +▽かんじ@point{} +------ Buffer: foo ------ +@end group +@end example + +変換開始位置を決定するとき、スペース文字、タブ文字、長音を表わす @samp{ー} +は無条件に無視されます。ただし、ひらがなの場合は @samp{を} が、カタカナ +の場合は @samp{ヲ} が見つかった時点で変換開始位置の走査を止め、▽モードに +入ります。変換開始ポイントを @samp{を}、@samp{ヲ} の直前で止めるのは、たい +ていその直後から単語が始まるからです。 + +以上は @kbd{M-Q} を引数を与えないで実行した場合です。一方で、@kbd{C-u 5 +M-Q} のように引数を渡して実行すると、変換開始位置から現在位置までの文字 +数を指定することができます。この場合は文字種別を問わず、与えられた文字数 +だけ無条件にポイントを戻します。 + +@vindex skk-allow-spaces-newlines-and-tabs +後方にポイントを戻す途中で行頭に到達した場合は、更に上の行について、行末 +の文字列から同様の走査を行い、必要があれば更にポイントを戻します。こうし +た「行を超えての走査」をやめるためには、変数 +@code{skk-allow-spaces-newlines-and-tabs} の値を @code{nil} に設定します。 + +@node 直前の確定を再変換 +@subsection 直前の確定を再変換 +@cindex 確定アンドゥ +@cindex 再変換 +@kindex M-x skk-undo-kakutei + +一番最後(直近)の確定を取り消して、再変換することができます。 +これを@b{「確定アンドゥ」}と呼びます。 + +例えば、辞書エントリが + +@example +こうこう /高校/孝行/航行/ +@end example + +@noindent +のようになっているとします。 + +@example +@kbd{K o u k o u @key{SPC}} + +@group +------ Buffer: foo ------ +▼高校@point{} +------ Buffer: foo ------ +@end group + +@kbd{s u r u} + +@group +------ Buffer: foo ------ +高校する@point{} +------ Buffer: foo ------ +@end group + +@kbd{M-x skk-undo-kakutei} + +@group +------ Buffer: foo ------ +▼孝行@point{}する +------ Buffer: foo ------ +@end group +@end example + +@noindent +この例では、@samp{高校} の確定を取り消しています。すると、辞書の第 +一候補である @samp{高校} をとばして、次候補である @samp{孝行} が現れます。 +ここで更に @key{SPC} を押せば次候補である @samp{航行} が現れ、更にもう一 +度 @key{SPC} を押せば候補が尽きて辞書登録モードに入ります。 + +この例のとおり、確定アンドゥは、確定した直後でなくとも有効です。 +より正確には、次の新たな確定 +@footnote{@kbd{C-j} をタイプして明示的に確定した場合は勿論、「暗黙の確定 +」を行った場合も同様です。}を行うまでは確定に関する情報が保持されている +ので、確定アンドゥすることができます。 + +また、変換、確定に関連しない文字列は、確定アンドゥを行っても削除されな +いように設計されています。上記の例では、@samp{する} がそのままカレントバ +ッファに残っています。 + +@defvr {ユーザ変数} skk-undo-kakutei-return-previous-point + +この変数の値が @code{non-nil} であれば、確定アンドゥ処理が完了した後に、 +確定アンドゥ処理の直前の位置にカーソルが戻ります。 + +上の例の場合、確定アンドゥ処理が完了した後のカーソル位置は、デフォル +ト @code{nil} では @samp{孝行} の直後のままですが、@code{non-nil} であれ +ば @samp{する} の直後に復帰します。 + +@end defvr + +@node 自動変換開始 +@subsection 自動変換開始 + +▽モードで見出し語を入力しているときに「を」や「。」などの文字を打鍵する +と、@key{SPC} を押したかのように変換を開始@footnote{▽マークからポイント +の直前の文字までを見出し語とします。最後に入力された文字(「を」や「。」 +)は見出し語には含まれません。}し、▼モードに入るようになっています。 + +@example +@kbd{K a n j i} + +@group +------ Buffer: foo ------ +▽かんじ@point{} +------ Buffer: foo ------ +@end group + +@group + +@kbd{w o} +------ Buffer: foo ------ +▼漢字を@point{} +------ Buffer: foo ------ +@end group +@end example + +@vindex skk-auto-okuri-process +変数 @code{skk-auto-okuri-process} の値を @code{non-nil} に設定して 送り +仮名の自動処理 @w{(@pxref{送り仮名の自動処理})} を行っている場合は、以下 +のような変換も可能です。ただし、個人辞書に @samp{できr /出来/[る/出来/]/} +というようなエントリがあると仮定します。 + +@example +@kbd{D e k i r u n n d e s u} + +@group +------ Buffer: foo ------ +▽できるんです +------ Buffer: foo ------ +@end group +@group + +@kbd{.} +------ Buffer: foo ------ +▼出来るんです。 +------ Buffer: foo ------ +@end group +@end example + +@defvr {ユーザ変数} skk-auto-start-henkan-keyword-list + +この変数の値は、単語や文節の区切りとなるような文字列のリストです。 +デフォルトは以下のようになっています。 +@end defvr + +@lisp +@group +("を" "、" "。" "." "," "?" "」" "!" ";" ":" ")" ";" + ":" ")" "”" "】" "』" "》" "〉" "}" "]" "〕" "@}" + "]" "?" "." "," "!" ) +@end group +@end lisp + +@defvr {ユーザ変数} skk-auto-start-henkan + +この変数の値を @code{nil} に設定すると、本節で説明した自動変換開始機能 +を無効にします。デフォルトは @code{t} です。 +@end defvr + +@node 暗黙の確定のタイミング +@subsection 暗黙の確定のタイミング +@cindex 暗黙の確定 +@vindex skk-process-okuri-early + +標準の設定では、確定が済む前に次の文字を入力すると、 +直ちに確定されます +@footnote{正確には、印字可能な文字または @key{RET} が入力されたときです。}。 +これを「暗黙の確定」と呼んでいます。具体的には以下のようになります。 + +@example +@kbd{K a k u t e i} + +@group +------ Buffer: foo ------ +▽かくてい@point{} +------ Buffer: foo ------ +@end group + +@key{SPC} + +@group +------ Buffer: foo ------ +▼確定@point{} +------ Buffer: foo ------ +@end group + +@kbd{s} + +@group +------ Buffer: foo ------ +確定s@point{} ; 暗黙の確定 +------ Buffer: foo ------ +@end group + +@kbd{u} + +@group +------ Buffer: foo ------ +確定す@point{} +------ Buffer: foo ------ +@end group +@end example + +@defvr {ユーザ変数} skk-kakutei-early + +この変数の値を @code{nil} にすると、「暗黙の確定」を遅らせます。 +具体的には、 + +@itemize @bullet +@item 括弧 @kbd{(} @kbd{)} @kbd{[} @kbd{]} の入力時 +@item 句読点 @kbd{,} @kbd{.} の入力時 +@item 次の変換開始時 (@kbd{A} から @kbd{Z} までの大文字の入力時) +@item @key{RET} 入力時 +@end itemize + +まで暗黙の確定が遅延されます +@footnote{@code{skk-kakutei-early} の機能と +@code{skk-process-okuri-early} の機能を同時に有効にすることはできません。 +@code{skk-kakutei-early} の 値を @code{non-nil} にする場合は +@code{skk-process-okuri-early} の値を @code{nil} にする必要がありま +す。}。 +@end defvr + +@example +@kbd{K a k u t e i} + +@group +------ Buffer: foo ------ +▽かくてい@point{} +------ Buffer: foo ------ +@end group + +@key{SPC} + +@group +------ Buffer: foo ------ +▼確定@point{} +------ Buffer: foo ------ +@end group + +@kbd{s} + +@group +------ Buffer: foo ------ +▼確定s@point{} +------ Buffer: foo ------ +@end group + +@kbd{u r u} + +@group +------ Buffer: foo ------ +▼確定する@point{} +------ Buffer: foo ------ +@end group + +@kbd{.} + +@group +------ Buffer: foo ------ +確定する。@point{} ; 暗黙の確定 +------ Buffer: foo ------ +@end group +@end example + +@node 積極的な確定 +@subsection 積極的な確定 + +変換候補が一つしか見つからない場合は自動的に確定する、という設定ができます。 + +@defvr {ユーザ変数} skk-kakutei-when-unique-candidate + +この値が @code{non-nil} の場合、この機能が有効になります。 + +@code{t} であれば送りあり変換、送りなし変換、abbrev モードでの変換、全て +でこの機能が有効になります。 + +また、@samp{okuri-ari}, @samp{okuri-nasi}, @samp{abbrev} を要素とするリス +トであることもできます。その場合は変換対象がその条件に合致した場合のみ確 +定変換が機能します。 + +例: @samp{'(okuri-nasi abbrev)} + +この機能は、全ての辞書を検索した上で変換候補が唯一か否かを調べます。その +ため、@code{skk-search-prog-list} の内容によってはレスポンスが悪くなる可 +能性があります。(@w{@pxref{辞書の検索方法の設定}} + +@end defvr + +@defvr {ユーザ変数} skk-kakutei-search-prog-limit + +この値が数値であった場合、積極的な確定(@code{skk-kakutei-when-unique-candidate}) に +おける「変換候補が唯一か否か」の判定を @code{skk-search-prog-list} の先頭か +ら数えてこの個数までの辞書に制限します。 + +数値以外であれば、無制限に全ての辞書を検索対象とします。 +@end defvr + +@node 確定辞書 +@subsection 確定辞書 +@cindex 確定変換 +@cindex 確定辞書 +@findex skk-search-kakutei-jisyo-file +@vindex skk-kakutei-jisyo + +特定の語は、変換したら即座に確定させる事ができます。これを@b{確定変換}と +呼び、利用するには「確定辞書」を用意します。例えば、 + +@example +じしょ /辞書/ +@end example + +@noindent +というエントリが確定辞書にあったとします。このとき、 + +@example +@group +@kbd{Z i s h o} + +@group +------ Buffer: foo ------ +▽じしょ@point{} +------ Buffer: foo ------ +@end group + +@key{SPC} + +@group +------ Buffer: foo ------ +辞書@point{} +------ Buffer: foo ------ +@end group +@end group +@end example + +@cindex 暗黙の確定 +@noindent +のように、@key{SPC} を押しただけでいきなり確定します。エントリの候補がひ +とつだけだからです。 + +確定辞書以外の辞書に登録されているであろう同音異義語を得るには、確定変換 +の直後に @kbd{x} をタイプします。すると、▼モードに戻って次の候補を検索す +ることができます。 + +次の例では、確定辞書に @samp{辞書} が、個人辞書(や共有辞書)に @samp{自署} が +登録されているとします。 + +@example +@group +@kbd{Z i s y o @key{SPC}} + +@group +------ Buffer: foo ------ +辞書@point{} +------ Buffer: foo ------ +@end group + +@kbd{x} + +@group +------ Buffer: foo ------ +▼自署@point{} +------ Buffer: foo ------ +@end group + +@end group +@end example + +確定辞書の単語は、優先的に変換されます。 + +@defvr {ユーザ変数} skk-kakutei-jisyo + +確定変換用の辞書ファイルを指定します +@footnote{確定変換用辞書の見出し語の配列については、サイズが大きい場合は +、共有辞書と同様、ソートして二分検索を行い、サイズが小さければ適当な配置 +で直線的検索を行うことをお勧めします。次も参照してください。@* +@w{@ref{辞書検索のための関数}}@* +@w{@ref{エントリの配列}} +}。 +この辞書は、標準の配布パッケージには含まれていないので、使用するのであれ +ばユーザ側で用意する必要があります。@* +(@w{@pxref{辞書の書式}}) + +@code{nil} であれば、確定変換は行われません。 + +@end defvr + +@node 送り仮名関連 +@section 送り仮名関連 + +SKK の送り仮名の処理は、好みが分かれるところです。色々な +対策が用意されていますので、試してみて下さい。 + +@menu +* 送り仮名の厳密なマッチ:: 「多きい」対策、その 1 +* 送り仮名の優先的なマッチ:: 「多きい」対策、その 2 +* 送り仮名の自動処理:: 送り仮名があっても、後から SPC +* 送りあり変換の変換開始のタイミング:: +@end menu + +@node 送り仮名の厳密なマッチ +@subsection 送り仮名の厳密なマッチ +@vindex minibuffer-exit-hook +@vindex minibuffer-setup-hook + +今、個人辞書に + +@example +おおk /大/多/[く/多/]/[き/大/]/ +@end example + +@noindent +という送りありエントリがあると仮定します。 + +ここで @kbd{O o K i i @key{SPC}} と入力した場合、普通は @samp{大きい} と +@samp{多きい} という 2 通りの候補が出力されますが、このうち @samp{多きい} +は現代の日本語として正しくありません。このような場合に、出力される候補を +正しい表現のみに絞りこむ方法について、説明します。 + + +@defvr {ユーザ変数} skk-henkan-okuri-strictly +@vindex skk-process-okuri-early + +この変数の値を @code{non-nil} に設定すると、見出し語がマッチするかどう +かのチェックの上に、送り仮名がマッチするかどうかのチェックが行われま +す。結果として送り仮名がマッチしない候補は出力されません。上記の例では、 +送り仮名 @samp{き} がマッチする @samp{大きい} は出力されますが、 +@samp{多きい} は出力されません +@footnote{この機能は、変数 @code{skk-process-okuri-early} の値を +@code{non-nil} に設定した状態と共存できません。この理由を知りたい場合は +@ref{送りあり変換の変換開始のタイミング}を参照してください。}。 + +個人辞書の送りありエントリが充実していれば、標準の設定よりも候補が絞り込 +まれるので変換効率がアップしますが、さもなければ、すぐに辞書登録モードに +入ってしまうため逆に不便になります。 +@end defvr + +変数 @code{skk-henkan-okuri-strictly} の値を @code{non-nil} にすると、 +辞書登録モードに入っても送り仮名のマッチが厳密に行われます。これは辞 +書登録の際希望する候補を得るためには障害となります。そのような障害を避 +けるためには、下記のようにフック変数を設定します。これにより、辞書登録 +時だけは、一時的に送り仮名の厳密なマッチをしないようになります +@footnote{実は変数 @code{skk-henkan-okuri-strictly} の値は辞書バッファで +参照されるので、ミニバッファのバッファローカル値を変更してもうまくいきま +せん。将来のバージョンでは、これを改良し、辞書バッファでの動作に影響する +ユーザ変数をバッファローカル化できるようにする予定です。 +@w{@xref{最新情報}.}}。 + +@lisp +@group +(add-hook 'minibuffer-setup-hook + (lambda () + (when (and (boundp 'skk-henkan-okuri-strictly) + skk-henkan-okuri-strictly + (not (eq last-command 'skk-purge-jisyo))) + (setq skk-henkan-okuri-strictly nil) + (put 'skk-henkan-okuri-strictly 'temporary-nil t)))) + +@end group +@group +(add-hook 'minibuffer-exit-hook + (lambda () + (when (and (get 'skk-henkan-okuri-strictly 'temporary-nil) + (<= (minibuffer-depth) 1)) + (put 'skk-henkan-okuri-strictly 'temporary-nil nil) + (setq skk-henkan-okuri-strictly t)))) +@end group +@end lisp + +@node 送り仮名の優先的なマッチ +@subsection 送り仮名の優先的なマッチ + +@ref{送り仮名の厳密なマッチ} では、見出し語と送り仮名が一致した場合のみ +候補を表示します。ここでは、その条件を緩めて優先的に表示する方法を紹介し +ます@footnote{@samp{大く}などの候補は鬱陶しいが、すぐに単語登録に入って +しまうのも嫌な人におすすめです。}。 + +今、個人辞書に + +@example +おおk /大/多/[く/多/]/[き/大/]/ +@end example + +@noindent +という送りありエントリがあると仮定します。 + +ここで @kbd{O o K i i @key{SPC}} と入力した場合、普通は @samp{大きい} と +@samp{多きい} という 2 通りの候補が出力されますが、このうち @samp{多きい} +は現代の日本語として正しくありません。このような場合に、出力される候補を +正しい表現が優先的にする設定を紹介します。 + +@defvr {ユーザ変数} skk-henkan-strict-okuri-precedence +@vindex skk-henkan-okuri-strictly +@vindex skk-process-okuri-early + +この変数の値を @code{non-nil} に設定すると、見出し語と送り仮名がマッチ +した候補を優先して表示します。 + +上記の例では @samp{▽おお*く} を変換したとき、まず @samp{多く} を出力し、 +次に @samp{大く} を出力します。 + +この変数の値が @code{non-nil} の時は、変数 +@code{skk-process-okuri-early} の値は @code{nil} でなければなりません +@footnote{理由を知りたい場合は、@ref{送りあり変換の変換開始のタイミング} +を参照してください。}。また変数 @code{skk-henkan-okuri-strictly} が +@code{non-nil} のときは、この変数は無視されます。 +@end defvr + +@node 送り仮名の自動処理 +@subsection 送り仮名の自動処理 + +この節では、「あげる」と入力してから @key{SPC} を押しても「上げる」と変換 +する機能を紹介します。 + +@menu +* どのように変換されるか:: +* 辞書登録の際に注意すべきこと:: +@end menu + +@node どのように変換されるか +@subsubsection どのように変換されるか + +@defvr {ユーザ変数} skk-auto-okuri-process +この変数の値を @code{non-nil} に設定すると、送り仮名の自動処理が行わ +れます。 +@end defvr + +例えば、@kbd{T a t i a g e r u @key{SPC}} と入力した場合を考えます。 +このとき、検索される見出し語の変化を追うと、 + +@example +@samp{たちあげる} @result{} @samp{たちあげr} @result{} @samp{たちあg} +@result{} @samp{たちa} @result{} @samp{たt} +@end example + +@noindent +のようになります。仮に個人辞書エントリが、 + +@example +@group +たちあg /立ち上/[げ/立ち上/]/[が/立ち上/]/ +たt /建/断/経/立/[つ/建/断/経/立/]/[ち/建/断/経/立/]/[て/経/立/建/]/ +@end group +@end example + +@noindent +の 2 つのエントリを含むとすると、見出し語を後方から順に切り詰める過程で +@samp{たちあg} と @samp{たt} の 2 つの見出し語の検索時にこれらの辞書エン +トリがマッチします。 + +@noindent +つまり、@samp{たちあげる} という見出し語に対し、見出し語を最後尾から1文 +字ずつ切り詰め、「切り詰めの結果残った文字列」と、「切り捨てられた先頭の +文字のローマ字プレフィックス」を連結した文字列を送りあり変換の見出し語と +して、 +検索します。@footnote{実際には、普通の送りなし変換として最初は検索されます。 +個人辞書まで調べて候補が見つからないときは、その後、送り仮名の自動処理の検索に +移ります。} + +@noindent +次に、マッチしたエントリの各候補に対し、切り捨てられた先頭の文字を送り仮 +名として取るかどうかをチェックします。この判断には、個人辞書の送り仮名ブロッ +ク部分 +@footnote{@ref{送りありエントリのブロック形式}.}を利用します。 + +@samp{たちあg} の場合の送り仮名チェックの対象は、切り捨てられた最初の文 +字の @samp{げ} です。個人辞書に + +@example +[げ/立ち上/] +@end example + +@noindent +の部分があることから、送り仮名として取るべきと判断します。また、@samp{た +t} の場合の送り仮名チェックの対象は、@samp{ち} です。個人辞書に + +@example +[ち/建/断/経/立/] +@end example + +@noindent +の部分があることから、送り仮名として取るべきと判断します。 + +@noindent +こうして、送り仮名がマッチする候補が @samp{立ち上}、@samp{建}、@samp{断}、 +@samp{経}、@samp{立} の5つに絞られます。これらは文字列の長さ順に昇順に +ソートされ +@footnote{長さ順にソートするのは、変換された部分がより長い候補を先順位 +として出力するためです。}、それぞれの候補と該当の見出し語から切り捨てら +れた文字列と連結したもの +@footnote{@samp{該当の見出し語から切り捨てられた文字列} を送り仮名とみな +して処理しています。}を、送り仮名の自動処理の最終候補として返します。上 +記の例は、@samp{立ち上げる}、@samp{建ちあげる}、@samp{断ちあげる}、 +@samp{経ちあげる}、@samp{立ちあげる} の5つが最終候補になります。 + +自動送り機能は、個人辞書のみを検索します。 + +ここで、自動送り機能の長所を考えてみると、 + +@itemize @bullet +@item 送り仮名の最初のローマ字表現を大文字で始める必要がない。 +@item 送り仮名を正確に思い出せない場合に送り仮名を指定しなくとも変換でき +る。 +@end itemize + +などがあります。一方短所としては、 + +@itemize @bullet +@item 意図しない変換をされる割合が増える。 +@item 個人辞書の送りありエントリが貧弱な場合は、自動処理ができない可能性 +が高い。 +@end itemize + +などが考えられます。変数 @code{skk-auto-okuri-process} の値を +@code{non-nil} に設定しても、従来通りの送りあり変換も同時にできますから、 +一度この機能を試してみることをお勧めします +@footnote{専ら補完的に自動送り処理を利用するのであれば、 +@code{(skk-okuri-search)} を @code{skk-search-prog-list} の最後にもってく +るという手もあります。(@w{@pxref{辞書の検索方法の設定}})}。 + +@node 辞書登録の際に注意すべきこと +@subsubsection 辞書登録の際に注意すべきこと + +送り仮名の自動処理を行っている場合@footnote{変数 +@code{skk-auto-okuri-process} の値を @code{non-nil} に設定している。}に +は、辞書登録の際に注意すべきことがあります。 + +個人辞書に見出し語 @samp{わたs} についてのエントリが全くない場合、あるい +は個人辞書のエントリが + +@example +わたs /渡/[し/渡/]/ +@end example + +@noindent +のような送り仮名のブロックを持たない場合を考えてみます。ここで、@kbd{W a +t a s i t a @key{SPC}}と入力すると、送り仮名の自動処理においては送り仮名 +がマッチしないので、候補が見つからずに辞書登録モードに入ります。 + +@example +@group +@kbd{W a t a s i t a @key{SPC}} + +------ Buffer: foo ------ +▼わたした +------ Buffer: foo ------ + +------ Minibuffer ------- +[辞書登録] わたした@point{} +------ Minibuffer ------- +@end group +@end example + +@noindent +辞書登録モードで @kbd{W a t a S i t a @key{RET}} と送り仮名を明示的に入 +力し、@samp{渡した} と変換して登録したとします。この場合、登録する語の最 +後が平仮名で終わるので、その最後の平仮名の文字列 (上記の例では、@samp{し +た}) が見出し語の最後と一致するかを調べます。一致する場合には、辞書の登 +録を送りありエントリとして行うのかどうかの確認を求めます。 + +@example +@group +@kbd{W a t a S i t a} +------ Minibuffer ------- +[辞書登録] わたした 渡した@point{} +------ Minibuffer ------- +@end group +@group + +@key{RET} + +-------------------------- Echo Area -------------------------- +Shall I register this as okuri-ari word: わたs /渡/ ? (y or n) +-------------------------- Echo Area -------------------------- +@end group +@end example + +@noindent +この確認に対し、@samp{y} と回答した場合は、 + +@example +わたs /渡/[し/渡/]/ +@end example + +@noindent +という辞書エントリが個人辞書の送りありエントリに書き込まれます。一方 +@samp{n} と回答した場合は、個人辞書の送りなしエントリに + +@example +わたした /渡した/ +@end example + +@noindent +というエントリが書き込まれます。本例の場合は、@samp{y} と回答するのが正 +解です。 + +@table @code +@item skk-kana-rom-vector +@vindex skk-kana-rom-vector +@c XXX この変数は定数になった。 + +この変数は、送り仮名部分をローマ字プレフィックスに分解する際に、参照され +ます。 +@end table + +変数 @code{skk-kana-rom-vector} のデフォルトは以下のようになっています。 + +@example +@group +["x" "a" "x" "i" "x" "u" "x" "e" "x" "o" "k" "g" "k" "g" "k" "g" + "k" "g" "k" "g" "s" "z" "s" "j" "s" "z" "s" "z" "s" "z" "t" "d" + "t" "d" "x" "t" "d" "t" "d" "t" "d" "n" "n" "n" "n" "n" "h" "b" + "p" "h" "b" "p" "h" "b" "p" "h" "b" "p" "h" "b" "p" "m" "m" "m" + "m" "m" "x" "y" "x" "y" "x" "y" "r" "r" "r" "r" "r" "x" "w" "x" + "x" "w" "n"] +@end group +@end example + +このベクトルは、それぞれ下記のかな文字をそのローマ字プレフィックスで現し +たものです。 + +@example +@group +ぁ あ ぃ い ぅ う ぇ え ぉ お か が き ぎ く ぐ +け げ こ ご さ ざ し じ す ず せ ぜ そ ぞ た だ +ち ぢ っ つ づ て で と ど な に ぬ ね の は ば +ぱ ひ び ぴ ふ ぶ ぷ へ べ ぺ ほ ぼ ぽ ま み む +め も ゃ や ゅ ゆ ょ よ ら り る れ ろ ゎ わ ゐ +ゑ を ん +@end group +@end example + +@noindent +これに従うと、見出し語中の送り仮名がローマ字プレフィックスに分解される際、 +例えば @samp{じ} は @samp{j} に、@samp{ち} は @samp{t} に、@samp{ふ} は +@samp{h} に、それぞれ分解されます。これらをそれぞれ @samp{z}、@samp{c}、 +@samp{f} に変更することもできます。それには変数 +@code{skk-kana-rom-vector} の該当部分を "z"、"c"、"f" に変更します。 + +@lisp +@group +(setq skk-rom-kana-vector + ["x" "a" "x" "i" "x" "u" "x" "e" "x" "o" "k" "g" "k" "g" "k" "g" + "k" "g" "k" "g" "s" "z" "s" "z" "s" "z" "s" "z" "s" "z" "t" "d" + "c" "d" "x" "t" "d" "t" "d" "t" "d" "n" "n" "n" "n" "n" "h" "b" + "p" "h" "b" "p" "f" "b" "p" "h" "b" "p" "h" "b" "p" "m" "m" "m" + "m" "m" "x" "y" "x" "y" "x" "y" "r" "r" "r" "r" "r" "x" "w" "x" + "x" "w" "n"]) +@end group +@end lisp + +次にもうひとつ例を挙げます。 @samp{ありがさつき} に対し @samp{有賀さつき} +を登録したい場合は、上記と同様に辞書登録をし、 + +@example +@group +Shall I register this as okuri-ari entry: ありがs /有賀/ ? (y or n) +@end group +@end example + +@noindent +の確認に対し @samp{n} と回答します。この結果、個人辞書の送りなしエントリ +には、 + +@example +ありがさつき /有賀さつき/ +@end example + +@noindent +というエントリが書き込まれます。 + +@node 送りあり変換の変換開始のタイミング +@subsection 送りあり変換の変換開始のタイミング +@kindex C-x C-j +@kindex C-x j + +@defvr {ユーザ変数} skk-process-okuri-early +@vindex skk-auto-okuri-process +@vindex skk-henkan-okuri-strictly +@vindex skk-kakutei-early + +この変数の値を @code{non-nil} に設定すると、送りあり変換の変換開始のタ +イミングが早められます。つまり、送り仮名のローマ字プレフィックスの入力 +時点で変換を開始します。 + +@example +@group +@kbd{U g o K} + +------ Buffer: foo ------ +▼動k +------ Buffer: foo ------ +@end group +@end example + +送り仮名が分からないまま変換しているため、個人辞書が送り仮名に対応した形に +成長しません。つまり @samp{うごk /動/} のような形態のままとなります。た +だし、 + +@example +@group +うごk /動/[く/動/]/[か/動/]/[け/動/]/[き/動/]/[こ/動/]/ +@end group +@end example + +@noindent +のようなエントリが既に個人辞書にある場合、それを破壊することはありません +@footnote{@ref{辞書の書式}を参照してください。}。 + +このユーザオプションを @code{non-nil} に設定して SKK モードを起動する +と、両立できないオプションである下記オプションは自動的に @code{nil} に +設定されます。 + +@itemize @bullet +@item @code{skk-kakutei-early} +@item @code{skk-auto-okuri-process} +@item @code{skk-henkan-okuri-strictly} +@end itemize + +既に SKK モードに入った後でこの変数の設定を変更した場合は、カレントバッ +ファで @kbd{C-x C-j} もしくは @kbd{C-x j} を 2 回タイプして SKK モードを +起動し直すことで、これらの変数間の衝突を調整します。 + +@display +@xref{暗黙の確定のタイミング, , skk-kakutei-early}. +@xref{送り仮名の自動処理, , skk-auto-okuri-process}. +@xref{送り仮名の厳密なマッチ, , skk-henkan-okuri-strictly}. +@end display + +@end defvr + +@node 候補の順序 +@section 候補の順序 + +skk の初期設定では、変換で確定された単語は、次の変換時では最初に表示され +ます。この動作を変更して、効率良く変換する方法があります。 + +@menu +* 変換の学習:: 関連のある語は上位に表示 +* 候補の順序の固定:: いつも同じ順序で候補を表示 +* ベイズ統計を用いた学習:: +@end menu + +ここで解説するほか、確定辞書 (@w{@pxref{確定辞書}}) を用いた変換も、候補の順序に影響を与えます。 + +@node 変換の学習 +@subsection 変換の学習 +@cindex @file{skk-study.el} +@vindex skk-study-associates-number +@vindex skk-study-search-times + +@file{skk-study.el} は、ある語 A を確定した場合に、A 及びその見出し +語 A' に対して、直前に変換した語 B とその見出し語 B' を関連語として登 +録しておき、再度見出し語 A' の変換を行ったときに、B 及び B' のペアが直 +前の何回かに確定した語の中に見つかれば、A を優先して出力する単純な学習 +効果を提供するプログラムです。 + +@file{~/.skk} に @code{(require 'skk-study)} と書いて DDSKK を起動して下 +さい。以降、かな漢字変換の学習を始めます。 + +例えば、@samp{梅雨には雨が降る} と変換した場合、 + +@itemize @bullet +@item +@samp{雨} (@samp{あめ}) の関連語 @expansion{} @samp{梅雨} (@samp{つゆ})、 + +@item +@samp{降る} (@samp{ふr}) の関連語 @expansion{} @samp{雨} (@samp{あめ})、 +@end itemize + +@noindent +という風に「直前に確定した語」を関連語として、語と語の関連性を学習します。 + +ここで続けて、@samp{傘を振る} と変換すると、個人辞書がアップデートされ +てしまい、見出し語 @samp{ふr} の第一候補は @samp{振る} になってしまい +ます。 + +しかし、更に続けて @kbd{A m e @key{SPC} g a H u R u} と type すると、 +@kbd{H u R u} (@samp{ふr}) に対して @samp{雨} (@samp{あめ}) が関 +連語になっているため、@samp{ふr} と対で記憶されている @samp{降る} に変 +換されるというわけです。 + +では、またここで @samp{傘を振る} と変換し、個人辞書の第一候補が +@samp{振る} になった状態で、 + +@display +@kbd{A m e @key{SPC} g a T a i r y o u @key{SPC} n i H u R u} +@end display + +@noindent +と変換すれば @kbd{ふr} はどう変換されるでしょうか? + 今度は @samp{雨} @w{(@samp{あめ})} と @kbd{ふr} の間に @samp{大量} @w{(@samp{たいりょう})} +が入っています@footnote{@samp{ふr} に対して @samp{大量} @w{(@samp{たいりょう})} が +関連語として保存されます。勿論 @w{(@samp{ふr})} に対する @samp{雨} @w{(@samp{あめ})} の学習も +まだ生きています。}。 + +実はちゃんと + +@display +@samp{雨が大量に降る} +@end display + +@noindent +と変換されます。何故なら @w{@samp{ふr}} の関連語を探す際、 +@code{skk-study-search-times} @footnote{デフォルト値は 5 です。} に +指定された回数分だけ遡って、以前に確定した語の中に関連語がないか探すの +です。従って、この場合だと、2つ前の確定情報を探した際に @samp{雨} +@w{(@samp{あめ})} 見つけ、これを関連語として、@w{@samp{ふr}} の値を +決めようとするのです。 + +@file{skk-study.el} に関するその他のオプションを説明します。 + +@defvr {ユーザ変数} skk-study-max-distance +この変数には integer を指定します。直前に確定したポイントと今回の変換ポ +イントがこの距離以上離れていると学習データを蓄積しないようにします。 +この変数は、必ずしも文章がバッファの @code{point-min} か +ら @code{point-max} へ流れるように書かれるものではなく、ポイントを前に戻 +したり後へ移動したりして書かれることを想定しています。 +この変数に integer を設定すると、直前の変換よりも前のポイントで変換した +場合に学習データを蓄積しないようにします。この変数に @code{nil} を指定す +ると直前に確定したポイントとの距離を考慮せずに学習します。この変数のデフ +ォルト値は 30 です。 + +なお、この変数の値にかかわらず、直前の変換バッファと現在変換を行っている +バッファが異なる場合は学習データを蓄積しません。 +@end defvr + +@defvr {ユーザ変数} skk-study-first-candidate +この変数が @code{non-nil} であれば、第一候補 +で確定した際も学習します。@code{nil} であれば、第一候補で確定したとき +のみ学習データを蓄積しません。学習データをできるだけ小さくしたい場合、 +この変数を @code{nil} にすると効果があるかもしれません。 +この変数のデフォルト値は @code{t} です。 +@end defvr + +@defvr {ユーザ変数} skk-study-file +学習結果を保存するファイル名です。 +この変数のデフォルト値は @file{~/.skk-study} です。 +変数 @code{skk-user-directory} からも設定ができます。 +(@w{@pxref{設定ファイル}}) +@end defvr + +@defvr {ユーザ変数} skk-study-backup-file +@file{~/.skk-study} のバックアップファイルです。 +この変数のデフォルト値は @file{~/.skk-study.BAK} です。 +@end defvr + +@defvr {ユーザ変数} skk-study-sort-saving +学習データのデータ構造に関するものです。この変数の値が @code{non-nil} で +あれば学習結果をソートしてセーブします。この変数が影響を及ぼすのは学習デ +ータの単なる見映えの問題だけです。 +この変数のデフォルト値は @code{nil} です。 +@end defvr + +@defvr {ユーザ変数} skk-study-check-alist-format +学習データのデータ構造に関するものです。この変数の値が @code{non-nil} で +あれば、学習結果の読み込み時に連想リストのフォーマットをチェックします。 +これは主に debug の目的で使います。 +この変数のデフォルト値は @code{nil} です。 +@end defvr + +@table @kbd + +@kindex M-x skk-study-switch-current-theme +@item M-x skk-study-switch-current-theme +そのバッファで利用する学習テーマを切り替えます。 +プロンプト @samp{Theme of current buffer: } に対して学習テーマ名を入力し +てください。例えば、科学の話題を書くバッファでは science と、法律の話題 +を書くバッファでは law などと入力してください。 + +@kindex M-x skk-study-remove-theme +@item M-x skk-study-remove-theme +不要な学習テーマを消去します。 + +@kindex M-x skk-study-copy-theme +@item M-x skk-study-copy-theme +学習テーマを複製します。 + +@end table + +@node 候補の順序の固定 +@subsection 候補の順序の固定 + +skk の初期設定では、変換、選択された候補は、次回の変換では最初に表示されます。 +これに対し、毎回同じ順序で候補を表示させることができます。 + +@defvr {ユーザ変数} skk-jisyo-fix-order + +@code{non-nil} であれば、確定の際に個人辞書の同音語の順序を変更せず、 +個人辞書に新規追加する際は既出語の後に追加する。標準は @code{nil}。 +@end defvr + +これは、個人辞書のエントリの中の各候補の順序を変更しないことで実現されて +いますから、@file{skk-study.el} を用いた学習 @w{(@pxref{変換の学習})} と +併用できます。 + +@code{skk-jisyo-fix-order} が @code{non-nil} の時、個人辞書の候補を手軽に並べ替 +える方法は、現時点ではありません。個人辞書ファイルを直接編集するか、 +コマンド @kbd{M-x skk-edit-private-jisyo} を実行して下さい。 +(@w{@pxref{個人辞書ファイルの編集}}) + +直前に変換したばかりの単語は、個人辞書の送りあり/なしエントリの一番上に +ありますので、すぐに見つけることができます。 + +@node ベイズ統計を用いた学習 +@subsection ベイズ統計を用いた学習 + +@file{skk-bayesian.el} は、直前の履歴のみ使用する @file{skk-study.el} に比べて、 +更に拡張された学習機能です。ベイズ統計を用いて文脈から変換候補が選択される確率を +計算して候補順をソートします。なお、機能が重なることから @file{skk-study.el} と +の併用はお勧めできません。 + +動作の枠組みは emacs lisp の @file{skk-bayesian.el} と ruby@footnote{@url{http://www.ruby-lang.org}} スクリプト +の @file{bskk} が連携することで実現しています。 + +@file{skk-bayesian.el} のインストールについては @file{bayesian/README.ja.md} を +参照してください。 + +@cartouche + +Ruby 2.4 以降を使用する場合は、DDSKK 16.2 以降に付属する @file{bayesian/bskk} を +使用してください。 + +@end cartouche + +@defvr {ユーザ変数} skk-bayesian-debug + +@code{non-nil} ならば、以下のとおりデバッグ用のメッセージを表示します。 + +@itemize @bullet + +@item @file{skk-bayesian.el} が吐き出すメッセージを *Messages* バッファに表示します。 + +@item @file{bskk} サブプロセスを @code{-d} オプションで起動させます。@file{bskk} は @file{$HOME/tmp/bskk.log} にメッセージを吐き出します。 + +@item 普段は非表示である *skk-bayesian* バッファを表示するようにします。このバッファには @file{bskk} の出力が表示されます。 + +@end itemize + +@end defvr + +@defvr {ユーザ変数} skk-bayesian-prefer-server + +@code{non-nil} ならば @code{skk-bayesian-host} の @code{skk-bayesian-port} に接 +続します。 +@code{nil} であれば @file{bskk} を emacs のサブプロセスとして起動します。 + +@end defvr + +@defvr {ユーザ変数} skk-bayesian-host + +@file{bskk} サーバが稼動しているホスト名 + +@end defvr + +@defvr {ユーザ変数} skk-bayesian-port + +@file{bskk} サーバのポート番号 + +@end defvr + +@defvr {ユーザ変数} skk-bayesian-history-file +@c ~/.skk-bayesian or ~/.ddskk/bayesian +not documented +@end defvr + +@defvr {ユーザ変数} skk-bayesian-corpus-make +not documented +@end defvr + +@defvr {ユーザ変数} skk-bayesian-corpus-file +@c ~/.skk-corpus or ~/.ddskk/corpus +not documented +@end defvr + +@kindex M-x skk-bayesian-kill-process +@defun {コマンド} skk-bayesian-kill-process +not documented +@end defun + +@node 辞書関連 +@section 辞書関連 + +本節では、辞書の種別と形式、設定方法、その他辞書にまつわる動作や設定を説明しま +す。 + +@menu +辞書の設定 +* 辞書の種類:: +* 辞書ファイルの指定:: +* 辞書の検索方法の設定:: 検索対象と検索順序の設定。 +* Emacs 付属の辞書:: +* サーバ関連:: +* サーバコンプリージョン:: + +@noindent +辞書の管理 +* 辞書の書式:: +* 強制的に辞書登録モードへ入る:: +* 誤った登録の削除:: 削除も登録みたいにできます。 +* 個人辞書ファイルの編集:: 個人辞書を編集するコマンドがあります。 +* 個人辞書の保存動作:: いつ個人辞書が更新、保存されるか。 +* 変換及び個人辞書に関する統計:: + +@noindent +他 +* 辞書バッファ:: +* 辞書バッファの文字コードの設定:: +* 辞書バッファのbuffer-file-name:: +@end menu + +@node 辞書の種類 +@subsection 辞書の種類 + +@table @b +@item 共有辞書 +@cindex 共有辞書 +@cindex L 辞書 +@cindex M 辞書 +@cindex S 辞書 +@cindex @file{SKK-JISYO.L} +@cindex @file{SKK-JISYO.ML} +@cindex @file{SKK-JISYO.M} +@cindex @file{SKK-JISYO.S} + +@file{SKK-JISYO.S} (S 辞書)、 @file{SKK-JISYO.M} (M 辞書)、 +@file{SKK-JISYO.ML} (ML 辞書)、 @file{SKK-JISYO.L} (L 辞書) などがありま +す。通常、個人辞書よりもサイズが大きく、省資源の面からユーザ間で共有して +参照されます。 + +ユーザの変換操作によって内容が書き替えられることはありません。 + +これら以外にも、共有辞書として使えるファイルが配布されています。 +それぞれの辞書の詳細については @url{http://openlab.jp/skk/dic.html} を +ご参照下さい。 + +@item 個人辞書 +@cindex 個人辞書 +@vindex skk-jisyo + +変数 @code{skk-jisyo} で指定されるファイル。DDSKK を一番最初に使い始めた +ときにホームディレクトリに自動的に作られます。その後の使用により日々刻々 +とエントリが追加され、更新されていきます。 + +なお、最初の個人辞書として S 辞書をリネームして使用するのも良いかもしれ +ません。 + +@item @code{skk-initial-search-jisyo} +@itemx @code{skk-kakutei-jisyo} +@vindex skk-initial-search-jisyo +@vindex skk-kakutei-jisyo + +これらは共有辞書、個人辞書という区分のいずれにも属しません。これらは個人 +毎に持つものを使用するか、ユーザ間で共有しているものを使用します。その性 +格から、辞書内容の更新は行われず、参照のみ行われます。また使用目的から、 +通常は小さい辞書を使用します。 +@end table + +個人辞書、@code{skk-initial-search-jisyo}, @code{skk-kakutei-jisyo} は +Emacs のバッファに読み込んで検索を行います。 + +共有辞書は設定により Emacs のバッファに読み込んで使用するか、または辞書 +サーバ経由で使用します。 + +@node 辞書ファイルの指定 +@subsection 辞書ファイルの指定 + +この節では、辞書ファイルを指定する変数を説明します。 +個人辞書とバックアップのディレクトリは、変数 @code{skk-user-directory} で +も変更できます。(@w{@pxref{設定ファイル}}) + +@defvr {ユーザ変数} skk-kakutei-jisyo +確定変換(@w{@pxref{確定辞書}})のための辞書です。一番最初に参照されます。 +確定変換をしない時は、初期設定の @code{nil} のままで良いです。 +@end defvr + +@defvr {ユーザ変数} skk-initial-search-jisyo +確定辞書の後、かつ、個人辞書の前に検索を行う辞書です。 + +この辞書を適当に指定することにより、最初に出てくる候補を操作することがで +きます。例えば、複数の専門用語毎の辞書を用意しておい +て @code{skk-initial-search-jisyo} の値を切り替えることにより、専門分野 +毎の専門用語を切り替えて入力することができます。 + +この辞書は、標準の配布パッケージには含まれていないので、使用するのであれ +ばユーザ側で用意する必要があります。 + +不要ならば、初期設定の @code{nil} のままで良いです。 +@end defvr + +@defvr {ユーザ変数} skk-jisyo +個人辞書。DDSKK を一番最初に起動したとき、変数 @code{skk-jisyo} が指すフ +ァイルが存在しなければ自動的に作られます。 +@end defvr + +@defvr {ユーザ変数} skk-backup-jisyo +個人辞書の予備 (バックアップ) です。検索の対象ではなく、あくまで個人辞書 +のバックアップとして指定してください。 +@end defvr + +@defvr {ユーザ変数} skk-cdb-large-jisyo +共有辞書のうち CDB 形式に変換した辞書です。指定した場合は @code{skk-large-jisyo} よ +りも先に検索されます。DDSKK 14.1 からは辞書サーバを経由せずとも CDB 形式 +辞書ファイルを直接検索できるようになりました。 +@end defvr + +@defvr {ユーザ変数} skk-large-jisyo +共有辞書のひとつ。バッファに読み込んで検索を行います。 + +例えば @code{skk-large-jisyo} に S 辞書か M 辞書を指定し、 +@code{skk-aux-large-jisyo} に L 辞書を指定する、という選択肢もあります。 + +また、辞書サーバ経由のアクセスも決して遅くはないので「共有辞書はバッファには +読み込まない」という設定も自然であり、これには @code{skk-large-jisyo} を +@code{nil} に設定します。 +@end defvr + +@defvr {ユーザ変数} skk-aux-large-jisyo +共有辞書のひとつ。辞書サーバに接続できない時にバッファに読み込んで検索を行う +辞書です。 +@end defvr + +@defvr {ユーザ変数} skk-extra-jisyo-file-list +SKK では個人辞書の他に、共有辞書 (@code{skk-large-jisyo}、 +@code{skk-cdb-large-jisyo}) または辞書サーバを設定して利用するのが一般的 +ですが、郵便番号辞書 @file{SKK-JISYO.zipcode} をはじめとした多彩な辞書も +メンテナンスされています。 + +これらの辞書を利用するために変数 @code{skk-search-prog-list} を手動で編集 +することもできますが、この変数は厳密にはユーザ変数に分類されていないため、 +予期しない問題が起こることもあります。 + +DDSKK 14.2 以降では追加の辞書を簡単に設定する方法を提供します。以下の例 +を参考に変数 @code{skk-extra-jisyo-file-list} の設定を @file{~/.skk} に +記述します。 + +@lisp +@group +(setq skk-extra-jisyo-file-list + (list '("/usr/share/skk/SKK-JISYO.JIS3_4" . euc-jisx0213) + "/usr/share/skk/SKK-JISYO.zipcode")) +@end group +@end lisp + +このように、辞書のファイル名のリストを指定します +@footnote{@code{skk-search-prog-list} に登録されている関 +数 @code{skk-search-extra-jisyo-files} が、@code{skk-extra-jisyo-file-list} の +各要素を逐次処理します。}。 +ただし、変数 @code{skk-jisyo-code} (@w{@pxref{辞書バッファの文字コードの設定}}) と +は異なる文字コードのファイルについては、上記の例中の @file{SKK-JISYO.JIS3_4} の +ように「ファイル名と文字コードのペア」を記述します。 +@end defvr + +これらの変数の意味するところは初期設定でのものですが、 +@code{skk-search-prog-list} の設定で変更することもできます。 +(@w{@pxref{辞書検索のための関数}}) + +@node 辞書の検索方法の設定 +@subsection 辞書の検索方法の設定 + +辞書の検索方法の指定は、変数 @code{skk-search-prog-list} で行われます。 +特に必要が無ければ、読み飛ばして下さい。 + +@menu +* 辞書検索の設定の具体例:: +* 辞書検索のための関数:: +@end menu + +@node 辞書検索の設定の具体例 +@subsubsection 辞書検索の設定の具体例 +@vindex skk-search-prog-list + +この節では、@code{skk-search-prog-list} の初期設定を示し、大体 +の流れを説明します。 + +DDSKK では、複数の辞書を扱うことが可能です。複数の辞書が同時に +検索されるのではなく、指定した順番に検索します。 +@code{skk-search-prog-list} はリストであり、大雑把に言えば、 +確定されるまで、先頭の要素から順に lisp として評価されます。 + +@lisp +@group +((skk-search-kakutei-jisyo-file skk-kakutei-jisyo 10000 t) + (skk-search-jisyo-file skk-initial-search-jisyo 10000 t) + (skk-search-jisyo-file skk-jisyo 0 t) + (skk-okuri-search) + (skk-search-cdb-jisyo skk-cdb-large-jisyo) + (skk-search-jisyo-file skk-large-jisyo 10000) + (skk-search-server skk-aux-large-jisyo 10000) + (skk-search-ja-dic-maybe) + (skk-search-extra-jisyo-files) + (skk-search-katakana-maybe) + (skk-search-sagyo-henkaku-maybe))) +@end group +@end lisp + +この例では、 + +@enumerate +@item +@code{skk-kakutei-jisyo} (@w{@pxref{確定辞書}}), +@code{skk-initial-search-jisyo}, @code{skk-jisyo} (個人辞書) の順に検索を +行い、 + +@item +次に送り仮名の自動処理を行い、(@w{@pxref{送り仮名の自動処理}}) + +@item +その後、@code{skk-cdb-large-jisyo} と @code{skk-large-jisyo} の検索を順 +に行い、 + +@item +最後に @code{skk-aux-large-jisyo} に辞書サーバ経由でアクセスしています。 +@end enumerate + +これらの辞書の意味については、@w{@pxref{辞書ファイルの指定}} 参照。 + +もし確定辞書で候補が見つかったらそのまま自動的に確定されます。1 回 +@key{SPC} を押す動作に対し、プログラム側では新たな候補を見つけるまで上記 +の動作を進めます。例えば、 + +@enumerate +@item +確定辞書では候補は見つけられなかったが @code{skk-initial-search-jisyo} +に候補がある場合、そこでいったん止まりユーザにその候補を表示します。 + +@item +更に @key{SPC} が押されると、次は個人辞書を検索します。そこで候補が見つ +かり、しかもその候補が @code{skk-initial-search-jisyo} で見つけた候補とは +異なるものであったときは、そこでまた止まりその候補をユーザに表示し +ます。 +@end enumerate + +以降、共有辞書についても同様の繰り返しを行います。最後まで候補が +見つからなかった時は、辞書登録モードに入ります。 + +@c DDSKK 14.1 では、以下はあてはまらない。 +@c +@c @footnote{@file{skk-auto.el} を読みこむと、 +@c +@c @lisp +@c (skk-okuri-search) +@c @end lisp +@c +@c @noindent +@c というリストが @code{skk-search-prog-list} に自動的に追加されます。実際 +@c には、@file{skk-auto.el} は必要に応じてオートロードされるので明示的に読みこむ必 +@c 要はありません。オートロードされるのは、具体的には +@c @code{skk-auto-okuri-process} を @code{non-nil} に設定したとき、 あるいは +@c +@c @lisp +@c (skk-okuri-search) +@c @end lisp +@c +@c @noindent +@c というリストを @code{skk-search-prog-list} に明示的に指定したときなどで +@c す。} +@c +@c @footnote{@file{skk-server.el} を読みこむと、 +@c +@c @lisp +@c (skk-search-server skk-aux-large-jisyo 10000) +@c @end lisp +@c +@c @noindent +@c というリストが @code{skk-search-prog-list} に自動的に追加されます。実際 +@c には、@file{skk-server.el} は必要に応じてオートロードされるので明示的に読みこむ +@c 必要はありません。オートロードされるのは、具体的には +@c @code{skk-server-host} または @code{skk-servers-list} を @code{non-nil} +@c に設定したとき、あるいは +@c +@c @lisp +@c (skk-search-server skk-aux-large-jisyo 10000) +@c @end lisp +@c +@c @noindent +@c というリストを @code{skk-search-prog-list} に明示的に指定したときなどで +@c す。} + +@node 辞書検索のための関数 +@subsubsection 辞書検索のための関数 + +前節で見たとおり、変数 @code{skk-search-prog-list} を適切に定義することによ +って辞書の検索方法を指定します。 +そこで使われる辞書検索のための関数を使いこなすことで、 +より細かい辞書検索の方法を指定することができます。 + +@defun skk-search-jisyo-file FILE LIMIT &optional NOMSG +通常の検索を行うプログラム。変数 @code{skk-henkan-key} を見出し語(検索文 +字列)として、 FILE を被検索対象として変換検索を実施します。個人辞書、共 +有辞書又は辞書サーバを使わずに検索を行いたい場合はこの関数を使用します。 + +第1引数 @code{FILE} は、被検索対象となる辞書ファイルを指定します。 +@code{nil} を指定したときは、検索を行いません。 +@code{FILE} で指定した辞書ファイルは Emacs のバッファに読み込まれます。 + +@cindex 二分検索 +@cindex 直線的検索 +第2引数 @code{LIMIT} は二分検索(バイナリ・サーチ)が行なわれる領域の大 +きさを指定します。一つの見出し語に対する変換動作に対し、検索対象の領域の +大きさ@footnote{「検索領域の先頭ポイント」と「同末尾ポイント」の差}が第2 +引数に指定された数値より小さくなるまでは二分検索が行われ、最後に直線的検 +索(リニア・サーチ, search-forward)が1回行われます。 + +第2引数に 0 を指定すると、常に直線的検索のみが行われます。 +個人辞書 @code{skk-jisyo} はソートされておらず二分検索が不可能であるため @code{LIMIT} を 0 にして下さい。 + +第3引数 @code{NOMSG} が @code{nil} ならば、辞書ファイルをバッファに +読み込む関数 @code{skk-get-jisyo-buffer} のメッセージをミニバッファに出力し +ます。@code{non-nil} を与えると出力しません。 +@end defun + +@defun skk-search-cdb-jisyo CDB-PATH + +not documented + +@end defun + +@defun skk-search-kakutei-jisyo-file FILE LIMIT &optional NOMSG +@cindex 確定変換 +@vindex skk-kakutei-henkan-flag +@b{「確定変換」}を行う検索プログラム。検索対象の辞書ファイルは Emacs の +バッファに読み込まれます。検索対象のファイルから候補を見つけると、内部 +変数 @code{skk-kakutei-henkan-flag} を立てて、いきなり確定します。このため +ユーザが確定操作を行う必要はありません。 + +引数の意味はいずれも @code{skk-search-jisyo-file} の場合と同様です。 +@end defun + +@w{@xref{確定辞書}.} + +@defun skk-okuri-search +形式: (skk-okuri-search) + +自動送り処理を行うプログラム。変数 @code{skk-auto-okuri-process} の値 +が @code{non-nil} のときだけ機能します。 + +個人辞書の送りありエントリを検索対象としているので、個人辞書のバッファを +流用します。そのため、専用の辞書バッファは作りません。 + +@w{@xref{送り仮名の自動処理}.} +@end defun + +@defun skk-search-server FILE LIMIT &optional NOMSG +辞書サーバ経由で検索するプログラム。 + +辞書サーバが使用不能になると辞書ファイルを Emacs のバッファに読み込んで +検索を行います。引数の意味はいずれも @code{skk-search-jisyo-file} と +同じですが、これらは辞書を Emacs のバッファに読み込んだときのみ利用されます。 + +辞書サーバが使う辞書ファイルの設定については、 + +@itemize @bullet +@item @w{@pxref{辞書サーバを使いたいときの設定}} +@item @w{@pxref{サーバ関連}} +@end itemize + +をご覧下さい。 +@end defun + +@node Emacs 付属の辞書 +@subsection Emacs 付属の辞書 + +GNU Emacs には、 @file{SKK-JISYO.L} を元に変換された @file{leim/ja-dic/ja-dic.el} とい +う辞書が付属しています。 + +DDSKK 14.2 からは、この @file{ja-dic.el} を利用したかな漢字変換 (送りあり、 +送りなし、接頭辞、接尾辞) が可能となりました。 +つまり、@file{SKK-JISYO.L} などの辞書ファイルを別途準備しなくても一応 +は DDSKK の使用が可能、ということです。 + +DDSKK 14.2 から追加された「ja-dic.el 検索機能」(@code{skk-search-ja-dic}) は、 + +@itemize @bullet +@item @code{skk-large-jisyo} +@item @code{skk-aux-large-jisyo} +@item @code{skk-cdb-large-jisyo} +@item @code{skk-server-host} +@end itemize + +の全てが無効な場合に有効となります。 + +ただし、@file{SKK-JISYO.L} を利用する場合と比べて英数変換や数値変換などが +できません。可能な限り @file{SKK-JISYO.L} などの辞書を利用することを推奨 +します。 + +関連項目: @w{@ref{辞書の入手}} + +@defvr {ユーザ変数} skk-inhibit-ja-dic-search + +この変数を @code{Non-nil} に設定すると、@code{skk-large-jisyo} 等の値にか +かわらず、あらゆる場面で @code{skk-search-ja-dic} を無効とします。 + +@end defvr + +@defun skk-search-ja-dic + +GNU Emacs に付属するかな漢字変換辞書 @file{ja-dic.el} を用いて検索する。 +現在の Emacs には @file{SKK-JISYO.L} を基に変換された @file{ja-dic.el} が付属している。 +この辞書データを用いて送りあり、送りなし、接頭辞、接尾辞の変換を行う。 +ただし、@file{SKK-JISYO.L} のような英数変換、数値変換などはできず、また「大丈夫」 +のように複合語とみなしうる語彙が大幅に削除されている。 + +@end defun + +@node サーバ関連 +@subsection サーバ関連 + +辞書サーバの基本的な設定は、@w{@pxref{辞書サーバを使いたいときの設定}} を +ご覧下さい。 + +@defvr {ユーザ変数} skk-servers-list + +この変数を使うと、複数のホスト上の辞書サーバを使い分けることができます。 + +この変数の値は、辞書サーバ毎の情報リストです。各リストは次の 4 つの要素か +ら成ります。 + +@itemize @bullet +@item ホスト名 +@item 辞書サーバ名 (フルパス) +@item 辞書サーバが読み込む辞書ファイル名 +@item 辞書サーバが使用するポート番号 +@end itemize + +ただし、辞書ファイル名及びポート番号は、辞書サーバ自身が決定することもあるため、そのような場合は @code{nil} として構いません。 + +例えば、以下のように設定します。 + +@lisp +@group +(setq skk-servers-list + '(("host1" "/your/path/to/skkserv" nil nil) + ("host2" "/your/path/to/skkserv" nil nil))) +@end group +@end lisp + +上記の設定の場合、まず host1 上の辞書サーバと接続します。接続できなくなると、 +次に host2 上の辞書サーバと接続します。 +@end defvr + +@defvr {ユーザ変数} skk-server-report-response + +この変数の値が @code{non-nil} であれば、変換時に、辞書サーバの送出する文字を +受け取るまでに関数 @code{accept-process-output} が実行された回数をエコーエリ +アに報告します。 + +@example +@group +-------------------- Echo Area -------------------- +辞書サーバの応答を 99 回待ちました +-------------------- Echo Area -------------------- +@end group +@end example + +@end defvr + +@defvr {ユーザ変数} skk-server-inhibit-startup-server + +デフォルト値は @code{t} です。この変数を @code{nil} に設定すると、辞書サ +ーバと接続できない場合に @code{call-process} で辞書サーバプログラムの起動 +を試みます。 + +inetd 経由で起動する多くの辞書サーバは @code{call-process} で起動するこ +とができませんが、@file{skkserv} のように @code{call-process} で起動する +ことができる辞書サーバを利用している場合には、この変数を @code{nil} に設 +定するのが良いかもしれません。 + +@end defvr + +@defvr {ユーザ変数} skk-server-remote-shell-program + +この変数には、リモートシェルのプログラム名を指定します。デフォルトは、システ +ム依存性を考慮する必要があるため、以下の Emacs Lisp コードを評価すること +により決定されています。 + +@lisp +@group +(or (getenv "REMOTESHELL") + (and (boundp 'remote-shell-program) remote-shell-program) + (cond + ((eq system-type 'berkeley-unix) + (if (file-exists-p "/usr/ucb/rsh") "/usr/ucb/rsh" "/usr/bin/rsh")) + ((eq system-type 'usg-unix-v) + (if (file-exists-p "/usr/ucb/remsh") "/usr/ucb/remsh" "/bin/rsh")) + ((eq system-type 'hpux) "/usr/bin/remsh") + ((eq system-type 'EWS-UX/V) "/usr/ucb/remsh") + ((eq system-type 'pcux) "/usr/bin/rcmd") + (t "rsh"))) +@end group +@end lisp +@end defvr + +@defun {コマンド} skk-server-version +辞書サーバから得たバージョン文字列とホスト名文字列を表示する。 + +@example +(skk-server-version) +@print{} SKK SERVER version (wceSKKSERV) 0.2.0.0 (ホスト名 foo:192.168.0.999: ) +@end example + +@end defun + +@node サーバコンプリージョン +@subsection サーバコンプリージョン + +Server completion に対応した辞書サーバであれば、見出し語から始まる全ての語句 +の検索が可能です。 + +@defun skk-comp-by-server-completion +この関数を @code{skk-completion-prog-list} の要素に追加すると、▽モードにお +いて見出し語補完を実行します。 + +@lisp +@group +(add-to-list 'skk-completion-prog-list + '(skk-comp-by-server-completion) t) +@end group +@end lisp + +@end defun + +@defun skk-server-completion-search +この関数を @code{skk-search-prog-list} の要素に追加すると、 +変換を実行する際に @code{skk-server-completion-search-char} を付すことに +よって見出し語で始まるすべての候補を掲げます。 + +@lisp +@group +(add-to-list 'skk-search-prog-list + '(skk-server-completion-search) t) +@end group +@end lisp + +@example + +@group +------ Buffer: foo ------ +▽おおさか~@point{} +------ Buffer: foo ------ +@end group + +@key{SPC} + +@group +------ Buffer: *候補* ------ +A:おおさかいかだいがく +S:大阪医科大学 +D:おおさかいがい +F:大阪以外 +J:おおさかいだい +K:大阪医大 +L:おおさかいちりつだいがく +------ Buffer: *候補* ------ +@end group + +@end example + +@end defun + +@defvr {ユーザ変数} skk-server-completion-search-char + +デフォルトは @samp{~}(チルダ、#x7e)です。 + +@end defvr + +@node 辞書の書式 +@subsection 辞書の書式 + +@menu +* 送りありエントリと送りなしエントリ:: +* 送りありエントリのブロック形式:: +* エントリの配列:: +@end menu + +@node 送りありエントリと送りなしエントリ +@subsubsection 送りありエントリと送りなしエントリ + +以下は個人辞書の一例です。 + +@cindex ;; okuri-ari entries. +@cindex ;; okuri-nasi entries. +@example +@group +;; okuri-ari entries. +たとe /例/[え/例/]/ +もt /持/[つ/持/]/[って/持/]/[た/持/]/[て/持/]/[ち/持/]/[と/持/]/ +たすk /助/[け/助/]/ +うごk /動/[く/動/]/[か/動/]/[け/動/]/[き/動/]/[こ/動/]/ +ふくm /含/[め/含/]/[む/含/]/[ま/含/]/[み/含/]/[も/含/]/ +@dots{} +;; okuri-nasi entries. +てん /点/・/天/ +ひつよう /必要/ +さくじょ /削除/ +へんこう /変更/ +じゅんじょ /順序/ +ぐん /群/郡/ +こうほ /候補/ +いち /位置/一/壱/ +@dots{} +@end group +@end example + +@noindent +@samp{てん /点/・/天/} を例にして説明します。これは @samp{てん} が見出し +語であり、その候補が、@samp{点}、@samp{・}、@samp{天} です。候補はそれぞ +れ、@samp{/} によって区切られています。SKK では、見出し語と候補群を合わ +せた @w{@samp{てん /点/・/天/}} の一行を@b{「エントリ」}と呼びます。 +@cindex エントリ + +辞書は単純なテキストファイルで、必ず下記の 2 つの行を持っています。 + +@example +@group +;; okuri-ari entries. +;; okuri-nasi entries. +@end group +@end example + +@noindent +この 2 つの行は、それぞれ送り仮名あり、送り仮名なしのエントリの開始地点 +を示すマークです。 @samp{;; okuri-ari entries.} までの行で @samp{;} を行 +頭に持つ行はコメント行として無視されます。@samp{;; okuri-ari entries.} +以降にコメント行を含むことはできません。 + +@w{@samp{;; okuri-ari entries.}} と @w{@samp{;; okuri-nasi entries.}} の +間に囲まれた上半分の部分が送り仮名ありのエントリです。これを@b{「送りあ +りエントリ」}と呼びます。 +@cindex 送りありエントリ +@w{@samp{;; okuri-nasi entries.}}以下の下半分部分が送り仮名なしのエント +リです。これを@b{「送りなしエントリ」}と呼びます。 +@cindex 送りなしエントリ + +@cindex 送りあり変換 +@cindex 送りなし変換 +送りありエントリを検索する変換を@b{「送りあり変換」}、送りなしエントリを +検索する変換を@b{「送りなし変換」}と呼びます。SKK では送り仮名の有無が変 +換方法の 1 つの種別となっています。送り仮名がある変換では送りありエント +リのみが検索され、送り仮名がない変換では送りなしエントリのみが検索されま +す。 + +1 つの見出し語についてのエントリは 1 行内に書かれます。2 行以上にまたが +ることはできません。改行を含む候補については、@code{(concat "改\n行")} +のように、評価すると改行を該当個所に挿入するような Lisp プログラム +(@w{@pxref{プログラム実行変換}}) に候補を変換して辞書に収めています。 + +@cindex ローマ字プレフィックス +送りありエントリは、基本的には @samp{もt /持/} のようになっています。送 +り仮名部分は、送り仮名をローマ字表現したときの 1 文字目 +@footnote{あるかな文字をローマ字表現したときの 1 文字目を@b{「ローマ字プ +レフィックス」}と呼びます。}で表現されています。 +この 1 エントリで @samp{持た}、@samp{持ち}、@samp{持つ}、@samp{持て}、 +@samp{持と} の5つの候補に対応します。その5つの候補の送り仮名をローマ +字プレフィックスで表現すれば、いずれも @samp{t} になります。 + +@node 送りありエントリのブロック形式 +@subsubsection 送りありエントリのブロック形式 + +個人辞書の送りありエントリには @samp{[} と @samp{]} に囲まれたブロックが +あります。これは、そのブロックの先頭にある平仮名を送り仮名に取る候補群で +す。 + +@example +@group +たとe /例/[え/例/]/ +@dots{} +ふくm /含/[め/含/]/[む/含/]/[ま/含/]/[み/含/]/[も/含/]/ +@end group +@end example + +この例で見ると、見出し語 @samp{たとe} の場合は @samp{え} を送り仮名とす +る 1 つのブロックから構成されています。見出し語 @samp{ふくm} の場合は、 +@samp{ま}、@samp{み}、@samp{む}、@samp{め}、@samp{も} を送り仮名とする5 +ブロックに分けられています。 + +@vindex skk-auto-okuri-process +@vindex skk-henkan-okuri-strictly +この送り仮名毎のブロック部分は、@code{skk-henkan-okuri-strictly} あるい +は @code{skk-auto-okuri-process} のいずれかの変数が @code{non-nil} で +ある場合に使用されます。その場合、検索において、見出し語の一致に加えて、 +更に送り仮名もマッチするかどうかをテストします。例えば、 + +@example +おおk /大/多/[く/多/]/[き/大/]/ +@end example + +@noindent +というエントリがあるとします。同じ見出し語 @samp{おおk} であっても、送り +仮名が @samp{き} であれば、候補は @samp{大} のみで @samp{多} は無視されま +す。 +@footnote{@xref{送り仮名の自動処理, , skk-henkan-okuri-strictly}. +@xref{送り仮名の厳密なマッチ, , skk-auto-okuri-process}. +@xref{送り仮名の優先的なマッチ, , skk-henkan-strict-okuri-precedence}. +} + +@vindex skk-process-okuri-early +現在 @url{http://openlab.jp/skk/dic.html} で配布されている共有辞書では、 +@samp{[} と @samp{]} を使用した送り仮名毎のブロックの形式に対応していません。 +個人辞書のみがこの形式で書き込まれていきます。 +@code{skk-henkan-okuri-strictly} が @code{nil} であっても送り仮名のブロッ +ク形式で書き込まれます。@footnote{ただし @code{skk-process-okuri-early} +の値が @code{non-nil} であれば、送り仮名を決定する前に変換を開始すること +になるので、送り仮名を明示的に入力していても個人辞書にはブロック形式は作 +られません。} + +@node エントリの配列 +@subsubsection エントリの配列 + +@cindex 辞書のソート方法 +共有辞書は、送りありエントリは @w{@samp{;; okuri-ari entries.}} から順 +に下方向に見出し語をキーとして@b{降順}に配置され、送りなしエントリ +は @w{@samp{;; okuri-nasi entries.}} から順に下方向に見出し語をキーと +して@b{昇順}に配置されます。 +降順/昇順に配置されるのは、辞書サイズが大きいことに配慮して二分検索 +を行うためです +@footnote{ソートする際には、見出し語を unsigned-char と見なします。 +この順序は Emacs が 関数 @code{string<} で文字列を比較するときの順序であ +り、UNIX の @command{sort} コマンドでの標準の順序とは異なります。 +Emacs のコマンド @code{sort-lines}を用いればファイルをこの順序でソートす +ることができます。Emacs のコマンド @code{sort-columns} は内部的に UNIX コ +マンドの @command{sort} を使っているので、辞書のソートには使えません。}。 + +一方、個人辞書は、一番最後に変換された語が最も手前に置かれます。 +つまり、送りなし/送りあり、それぞれのエントリが +@w{@samp{;; okuri-ari entries.}}, @w{@samp{;; okuri-nasi entries.}} を +基点として最小ポイントに挿入されて辞書が +更新されます @footnote{正確に言えば、送りあり変換では @w{@code{skk-okuri-ari-min}+ 1} +の位置、送りなし変換では @w{@code{skk-okuri-nasi-min}+ 1} の位置。}。 +個人辞書は、通常は共有辞書ほどはサイズが大きくないので、検索時にはそれぞ +れの基点から直線的に検索が行われます。 + +最後に確定された語は、一つのエントリの中の最初の位置に置かれます。 + +@node 強制的に辞書登録モードへ入る +@subsection 強制的に辞書登録モードへ入る +@kindex . +▼モードにて、エコーエリアに変換候補が表示されているときに @kbd{.} をタイ +プすると、強制的に辞書登録モードへ入ります。 + +@defvr {ユーザ変数} skk-force-registration-mode-char +強制的に辞書登録モードへ入るためのキーキャラクタをこの変数で定義します。 +標準設定は @kbd{.} です。 +@end defvr + +@node 誤った登録の削除 +@subsection 誤った登録の削除 +@cindex 個人辞書エントリの削除 +@cindex 誤登録 +@kindex X + +誤って個人辞書に登録した単語は削除できます。 + +削除したい単語を変換により求め、その単語が表示された時点で @kbd{X} を入力 +します。ミニバッファに確認プロンプトが出るので @kbd{y e s} と答えると、個 +人辞書の対応するエントリが削除されます。現在のバッファに先程入力した「誤 +りの変換結果」も削除されます。 + +例えば、 + +@example +さいきてき /再起的/ +@end example + +@noindent +というエントリを誤って登録してしまったという仮定で、この誤登録を削除する +場合を説明します。 + +@example +@kbd{S a i k i t e k i @key{SPC}} + +@group +------ Buffer: foo ------ +▼再起的@point{} +------ Buffer: foo ------ +@end group + +@kbd{X} + +@group +------------------ MiniBuffer ------------------ +Really purge ``さいきてき /再起的/''?(yes or no) @point{} +------------------ MiniBuffer ------------------ +@end group + +@kbd{y e s @key{RET}} + +@group +------ Buffer: foo ------ +@point{} +------ Buffer: foo ------ +@end group + +@end example + +@node 個人辞書ファイルの編集 +@subsection 個人辞書ファイルの編集 +@kindex M-x skk-edit-private-jisyo + +@b{構文チェックが十分ではありません。個人辞書ファイルの編集は、自己責任 +のもと行ってください。} + +コマンド @kbd{M-x skk-edit-private-jisyo} を使うと、個人辞書ファイルが +開かれます@footnote{前置引数を伴って実行 (@kbd{C-u M-x skk-edit-private-jisyo}) す +ることで、コーディングシステムを指定して個人辞書を開くことができます。}。 + +個人辞書ファイルを開いて編集している最中も skk を使えますが、 +skk からの単語の登録、削除はできません。(他にも少し制限がありますが、 +気にならないでしょう。) + +編集が終わったら、@kbd{C-c C-c} と押すと個人辞書ファイルをセーブしてバッ +ファを閉じます。 + +@node 個人辞書の保存動作 +@subsection 個人辞書の保存動作 +@cindex 個人辞書 +@cindex 個人辞書のオートセーブ +@kindex C-x C-c +@vindex skk-save-jisyo-instantly + +個人辞書の保存動作について説明します。 + +個人辞書の保存が行われる場合として、次の4通りがあります。 + +@enumerate +@item +@kbd{C-x C-c} (または @kbd{M-x save-buffers-kill-emacs}) によって Emacs を +終了する場合。 + +@item +@kbd{M-x skk-save-jisyo} と入力したか、メニューバーの @samp{Save Jisyo} を +選択した場合。 + +@item +個人辞書の更新回数が、変数 @code{skk-jisyo-save-count} で指定された値に +達した結果として、自動保存 (オートセーブ) 機能が働くとき。 + +@item +変数 @code{skk-save-jisyo-instantly} が @code{non-nil} であれば、 +単語登録(単語削除)のたびに個人辞書を保存する。 +@end enumerate + +保存動作を分析して考えます。まず、 Emacs に読み込んだ個人辞書が更新され +ているかどうかを調べます。更新されていたら保存動作に入ります。Emacs の個 +人辞書バッファを一時ファイルに保存して、そのファイルサイズが現存の (セー +ブ前の) 個人辞書より小さくないかどうかをチェックします。個人辞書より小さ +いときは、保存動作を継続するかどうか、確認のための質問がされます +@footnote{通常の使用の範囲では @kbd{M-x skk-purge-from-jisyo} した場合、あ +るいは個人辞書をユーザが意図的に編集した場合、複数の Emacs で DDSKK を +使用した場合などに、個人辞書が小さくなることがあります。他の場合はバグの +可能性があります。}。 + +@example +@group + +--------------------------- Minibuffer ----------------------------- +New ~/.skk-jisyo will be 11bytes smaller. Save anyway?(yes or no) +--------------------------- Minibuffer ----------------------------- + +@end group +@end example + +@noindent +ここで @kbd{n o @key{RET}} と答えた場合は、そこで保存動作が中止され、個 +人辞書は以前の状態のままになります。@kbd{y e s @key{RET}} と答えた場合は +元の個人辞書を退避用の辞書 @file{~/.skk-jisyo.BAK} に退避し、一時ファイ +ルに保存した新しい個人辞書を @code{skk-jisyo} に保存します。 + +もし、一時ファイルのサイズが 0 である場合は、なんらかの異常と考えられる +ため保存動作は直ちに中止されます。その場合は + +@kindex M-x skk-kill-emacs-without-saving-jisyo + +@kbd{M-x skk-kill-emacs-without-saving-jisyo} + +@noindent +で Emacs を終了させ、個人辞書 (@code{skk-jisyo}) 及び個人辞書の退避用辞 +書 (@code{skk-backup-jisyo}) をチェックするよう強くお勧めします +@footnote{@code{skk-jisyo} が既に壊れていても、変数 @code{skk-backup-jisyo} が +指し示すファイルにそれ以前の個人辞書が残っている可能性があります。}。 + +@defvr {ユーザ変数} skk-compare-jisyo-size-when-saving +この変数の値を @code{nil} に設定すると、保存前の個人辞書とのサイズを比較 +しません。 +@end defvr + +@defvr {ユーザ変数} skk-jisyo-save-count + +この変数で指定された回数、個人辞書が更新された場合に個人辞書が自動保存さ +れます。デフォルトは 50 です。また、この値を @code{nil} にすると、個人辞 +書の自動保存機能が無効になります。 + +ここで、個人辞書の更新回数は確定回数と一致します。また、同じ候補について +確定した場合でもそれぞれ 1 回と数えられます +@footnote{これは、個人辞書の最小ポイントに、常に最後に変換を行ったエン +トリを移動させるために、エントリ数、候補数が全く増えていなくとも、確定に +より個人辞書が更新されているからです。}。 +@end defvr + +@defvr {ユーザ変数} skk-save-jisyo-instantly +この変数が @code{non-nil} であれば、単語を登録するたび(削除するたび)に +個人辞書を保存します。 +@end defvr + +@defvr {ユーザ変数} skk-share-private-jisyo +@code{Non-nil} であれば、複数の SKK による個人辞書の共有を考慮して辞書を +更新する。 SKK 起動後にこの変数を変更した場合は @kbd{M-x skk-restart} で +反映させること。 +@end defvr + +@node 変換及び個人辞書に関する統計 +@subsection 変換及び個人辞書に関する統計 + +DDSKK は、かな漢字変換及び個人辞書に関する統計を取っており、Emacs の終了 +時にファイル @file{~/.skk-record} に保存します。保存する内容は、以下の形 +式です。 + +@cartouche +Sun Jul 28 09:38:59 1996 登録: 4 確定: 285 確定率: 98% 語数: 3042 +@end cartouche + +上記の「語数:」の数は個人辞書 @file{skk-jisyo} に登録されている候補数です +が、ここでは 1 行を 1 語として数えています。そのため、1 つの見出し語に対 +して複数の候補を持っている場合は、2 つ目以降の候補を無視しています。 + +@defvr {ユーザ変数} skk-record-file + +統計情報を保存するファイル名を指定します。 +(@w{@pxref{設定ファイル}}) + +@end defvr + +@defvr {ユーザ変数} skk-keep-record + +この変数の値を @code{nil} に設定すると、本節で説明した統計機能を無効に +します。数値を設定すると、@code{skk-record-file} を指定数値の行数よ +り大きくしません。 + +@end defvr + +@defvr {ユーザ変数} skk-count-private-jisyo-candidates-exactly + +この変数の値を @code{non-nil} に設定すると、「語数」の数え方を変更します。 +具体的には、 1 行を 1 語として数えるのではなく、正確に語数を数えます。 +なお、その分時間がかかります。また、この場合でも @samp{[} と @samp{]} +に囲まれた送り仮名毎のブロック形式内は数えません。 + +@end defvr + +@cindex Menu Bars +@cindex メニューバー +@findex skk-count-jisyo-candidates +@kindex M-x skk-count-jisyo-candidates + +@noindent +@kbd{M-x skk-count-jisyo-candidates} + +このコマンドを使うと、辞書の候補数を数えることができます。 + +@example +@group +@kbd{M-x skk-count-jisyo-candidates} + +--------------- MiniBuffer -------------- +Jisyo file: (default: /your/home/.skk-jisyo) ~/@point{} +--------------- MiniBuffer -------------- +@end group + +@group +@kbd{. s k k - j i s y o @key{RET}} + +-------------- Echo Area -------------- +Counting jisyo candidates@dots{} 100% done +-------------- Echo Area -------------- +@end group + +@group +------ Echo Area ------ +3530 candidates +------ Echo Area ------ +@end group +@end example + +ただし、@samp{[} と @samp{]} に囲まれた送り仮名毎のブロック形式内は数えませ +ん。 + +また、メニューバーが使用できる環境では、メニューバーを使ってこのコマンド +を呼び出すことができます。@w{@xref{Menu Bars, ,メニューバー, emacs, GNU Emacs Manual}.} + +@node 辞書バッファ +@subsection 辞書バッファ +@cindex @file{dabbrev.el} +@cindex @samp{ *SKK-JISYO.L*} +@findex fundamental-mode +@vindex major-mode +@vindex mode-name +@vindex skk-large-jisyo +@cindex 辞書バッファの名付け規則 + +辞書検索プログラムを実行すると、必要ならば辞書が Emacs のバッファに読み +込まれます。このバッファを@b{辞書バッファ}と呼びます。 + +辞書バッファの名前は、 + +「空白+@samp{*}+辞書ファイル名(ディレクトリ抜き)+@samp{*}」 + +@noindent +という規則に基づいて付けられます。例えば、変数 @code{skk-large-jisyo} の +値が + +@file{/usr/local/share/skk/SKK-JISYO.L} + +@noindent +であるとき、これに対する辞書バッファ名は、 + +@samp{ *SKK-JISYO.L*} + +@noindent +となります。 + +このバッファのメジャーモードは @code{fundamental-mode} です。しかし、諸 +般の事情により、変数 @code{major-mode} の値をシンボル @code{skk-jisyo-mode} と、 +変数 @code{mode-name} の値を文字列 @samp{SKK dic} としています +@footnote{これは、Emacs の @file{dabbrev.el} の機能との調和を考えての措 +置です。 +Dabbrev においては、現在のバッファと同じモードの他のバッファを検索して +abbreviation の展開を行うように設定することができるのですが、仮に辞書 +バッファにおける変数 @code{major-mode} の値が @code{fundamental-mode} のま +まだとすると、 Dabbrev が辞書バッファを検索してしまう可能性があります。 +この措置によって、そのような事態を回避しています。}。 + +@node 辞書バッファの文字コードの設定 +@subsection 辞書バッファの文字コードの設定 +@vindex skk-coding-system-alist +@findex skk-find-coding-system +@findex describe-coding-system +@findex list-coding-systems +@findex coding-system-p +@findex find-coding-system + +@defvr {ユーザ変数} skk-jisyo-code + +この変数は、辞書ファイルの文字コードを決定し、以下のような値を取ります。 + +@itemize @bullet + +@item @code{nil} + +@item Emacs の coding system (コード系) +@footnote{coding system は GNU Emacs の場合 @code{euc-jp}, @code{shift_jis}, +@code{junet} などのシンボルで表され、@kbd{M-x describe-coding-system} や +@kbd{M-x list-coding-systems} で調べることができます。 +XEmacs の場合、シンボルは coding system そのものでは +なく coding system object を指示するためのシンボルとして扱われます。 +具体的には GNU Emacs では @code{(coding-system-p 'euc-jp)} が @code{t} を +返すのに対し、 XEmacs では @code{nil} を返しますが、代わりにシンボルが示 +す coding system object を返す @code{find-coding-system} 関数が存在します。} + +@item @samp{euc}, @samp{ujis}, @samp{sjis}, @samp{jis} の文字列。@code{skk-coding-system-alist} に従って、順に @code{euc-jisx0213}, @code{euc-jisx0213}, @code{shift_jisx0213}, @code{iso-2022-jp-3-strict} の各シンボルへ変換されます。 + +@end itemize + +デフォルトは @code{nil} です。この場合、シンボル @code{euc-jis-2004} が使われます +@footnote{関数 @code{skk-find-coding-system} を参照のこと。} +。 + +@end defvr + +@node 辞書バッファのbuffer-file-name +@subsection 辞書バッファのbuffer-file-name +@vindex buffer-file-name +@findex save-some-buffers + +Emacs には @code{save-some-buffers} という関数があります。この関数は、ファ +イルに関連付けられている各バッファについて、変更があればファイルに保存し +ますが、実際に保存するかどうかをユーザに質問します。 + +Emacs のコマンドには @kbd{M-x compile} のように、 +@code{save-some-buffers} を呼び出すものがあります。もし、個人辞書の辞書 +バッファがファイル名と関連付けられていたとしたら、こうしたコマンドを +実行するたびに個人辞書を保存するかどうか質問されるので、面倒です。 + +DDSKK では、このような事態を避けるため、辞書バッファにおける変数 +@code{buffer-file-name} の値を @code{nil} に設定しています。 + +@node 注釈 (アノテーション) +@section 注釈 (アノテーション) + +かな漢字変換の際に、候補に注釈 (アノテーション) が登録されていれば、それ +を表示することができます。 + +@menu +* アノテーションの基礎:: 予備知識 +* アノテーションの使用:: +* アノテーションの登録:: +* アノテーションとして EPWING 辞書を表示する:: +* Apple OS X 「辞書」サービスからアノテーションを取得する:: +* Wikipedia/Wiktionary からアノテーションを取得する:: +* 外部コマンドからアノテーションを取得する:: +* 各種アノテーション機能を SKK の枠をこえて活用する:: +@end menu + +@node アノテーションの基礎 +@subsection アノテーションの基礎 + +この節では、辞書の中でのアノテーションの取り扱いを説明します。 + +アノテーションは、ユーザが登録したものと、共有辞書に元々登録されている +もの、それ以外の情報源から取得されるものの 3 つに大別されます。 + +ユーザが付けたアノテーションを「ユーザアノテーション」 +と呼びます。ユーザアノテーションは、次の形式で個人辞書に登録されます。 + +@example +「きかん /期間/機関;*機関投資家/基幹;*基幹業務/」 +@end example + +上記のとおり、@code{;} の直後に @code{*} が自動的に振られる +@footnote{@code{*} の文字は変換時には表示されません}ことによってユーザが +独自に登録したアノテーションであることが分かります。 + +一方、共有辞書に元々登録されているアノテーションを「システムアノテー +ション」と呼び、これは @code{;} の直後に @code{*} の文字を伴いません。 +システムアノテーションは、次の形式で辞書に登録されています。 + +@example +「いぜん /以前;previous/依然;still/」 +@end example + +システムアノテーションは、L 辞書等に採用されています。 + +上記のいずれでもなく、外部の辞典その他の情報源から得られるものを「外部ア +ノテーション」といいます。外部アノテーションは Emacs Lisp パッケージであ +る lookup.el、 Apple OS X 付属の辞書、Wiktionary/Wikipedia などから取得可能 +です。 + +@node アノテーションの使用 +@subsection アノテーションの使用 + +@defvr {ユーザ変数} skk-show-annotation + +この変数の値を @code{non-nil} に設定するとアノテーションを表示します +@footnote{Viper 対策はまだ行われていません。@file{~/.viper} に次のように +書いて下さい。 + +@lisp +(viper-harness-minor-mode "skk-annotation") +@end lisp +}。 + +@table @code + +@item (setq skk-show-annotation t) + +アノテーションを常に表示します。 + +@item (setq skk-show-annotation '(not list)) + + *候補*バッファ@footnote{@code{skk-show-candidates-always-pop-to-buffer}}では、アノテーションを表示しません。 + +@item (setq skk-show-annotation '(not minibuf)) + +ミニバッファにおけるかな漢字変換(単語登録時)では、アノテーションを表示しません。 + +@item (setq skk-show-annotation '(not list minibuf)) + + *候補*バッファ及びミニバッファでは、アノテーションを表示しません。 + +@item (setq skk-show-annotation nil) + +いかなる場合もアノテーションを表示しません。 + +@end table + +@end defvr + +@defvr {ユーザ変数} skk-annotation-delay + +アノテーションを表示するまでの遅延を秒で指定する。デフォルトは 1.0 秒。 + +@end defvr + +@kindex C-w +@defvr {ユーザ変数} skk-annotation-copy-key + +@kbd{C-w} をタイプすると、現在表示されているアノテーションを kill ring に +保存します。保存した内容を Emacs 以外のアプリケーションで利用したい場合は +変数 @code{interprogram-cut-function} を設定してください。 + +@end defvr + +@defvr {ユーザ変数} skk-annotation-show-as-message + +@code{Non-nil} (デフォルト) であれば、アノテーションをエコーエリアに表示します。 + +@code{nil} であれば、other-window を一時的に開いてアノテーションを表示します。 +other-window は、その候補を確定するか、その候補の選択を止める (次の +候補の表示又は quit) と自動的に閉じます。 + +この変数の値にかかわらず、変数@code{skk-show-tooltip} が @code{non-nil} の +場合はアノテーションをツールティップで表示します。 + +@end defvr + +@kindex ^ +@defvr {ユーザ変数} skk-annotation-toggle-display-char + +「*候補*バッファ」で変換候補を一覧表示しているときにアノテーションの +表示/非表示を動的に切り替えるキーを設定します。 +デフォルトは @kbd{^} です。 + +@example +@group +----- Buffer: *候補* ----- +A:射 +S:亥;[十二支](12)いのしし +D:夷;夷狄 +F:姨;おば +J:洟;はな +K:痍;満身創痍 +L:維;維持 +----- Buffer: *候補* ----- +@end group + +@kbd{^} + +@group +----- Buffer: *候補* ----- +A:射 +S:亥; +D:夷; +F:姨; +J:洟; +K:痍; +L:維; +----- Buffer: *候補* ----- +@end group +@end example + +@end defvr + +@defvr {ユーザ変数} skk-annotation-function + +ユーザアノテーションとシステムアノテーションを区別することで、ユーザアノ +テーションだけを表示したり、あるいはその逆を行うことが可能です。 + +変数 @code{skk-annotation-function} に「表示したいアノテーション +を @code{non-nil} と判定する関数」を定義します。 +アノテーション文字列を引数にして変数 @code{skk-annotation-function} が +指し示す関数が @code{funcall} されて、戻り値が @code{non-nil} である場合に +限ってアノテーションが表示されます。 + +@lisp +@group +(setq skk-annotation-function + (lambda (annotation) + (eq (aref annotation 0) ?*))) +@end group +@end lisp + +@noindent +上記の例では、アノテーションの先頭が @code{*} で始まる「ユーザアノテー +ション」の場合に @code{t} を返すλ式を @code{skk-annotation-function} に +定義しました。これによってユーザアノテーションだけが表示されます。 + +@end defvr + +@node アノテーションの登録 +@subsection アノテーションの登録 +@findex skk-annotation-add +@findex skk-annotation-kill +@findex skk-annotation-remove +@kindex M-x skk-annotation-add +@kindex M-x skk-annotation-kill +@kindex M-x skk-annotation-remove + +@defun {コマンド} skk-annotation-add &optional NO-PREVIOUS-ANNOTATION + +アノテーションを登録/修正するには、アノテーションを付けたい単語を確定し +た直後に同じバッファで @kbd{M-x skk-annotation-add} と実行します。 + +アノテーションを編集するバッファ(*SKK annotation*)が開いてカレントバッファ +になりますので、アノテーションとして表示する文章を編集してください。 +編集が終わったら @kbd{C-c C-c} とタイプします。 + +その単語に既にアノテーションが付いている場合は、あらかじめ当該アノテーショ +ンを挿入して *SKK annotation* を開きます。 + +@end defun + +@defun {コマンド} skk-annotation-kill + +上記 @kbd{M-x skk-annotation-add} を実行したもののアノテーションを付けず +に *SKK annotation* を閉じたいときは、@kbd{C-c C-k} とタイプするか +@kbd{M-x skk-annotation-kill} を実行してください。 + +@end defun + +@defun {コマンド} skk-annotation-remove + +最後に確定した候補からアノテーションを取り去りたいとき +は @kbd{M-x skk-annotation-remove} と実行します。 + +@end defun + +@node アノテーションとして EPWING 辞書を表示する +@subsection アノテーションとして EPWING 辞書を表示する + +@file{skk-lookup.el} に含まれる関数 @code{skk-lookup-get-content} を活用 +することにより、EPWING 辞書から得た内容をアノテーション表示することが可能 +です。 + +辞書検索ツールの Lookup (@url{http://openlab.jp/edict/lookup/}) が正常に +インストールされていることが前提です。Lookup を新規にインストールした場 +合は、SKK をインストールし直す必要があります。 + +EPWING 辞書の内容をアノテーション表示するには、2つの方法があります。 + +@enumerate +@item +@code{skk-treat-candidate-appearance-function} を設定する方法 + +候補の表示を装飾する関数を指定する変数 +@code{skk-treat-candidate-appearance-function} を設定する場合は、 +@file{etc/dot.skk} に示されている設定例を以下のように変更してください。 + +@lisp +@group ++ (require 'skk-lookup) + (setq skk-treat-candidate-appearance-function + #'(lambda (candidate listing-p) + (let* ((value (skk-treat-strip-note-from-word candidate)) + (cand (car value)) ;候補 +- (note (cdr value)) ;注釈 ++ (note (skk-lookup-get-content cand listing-p)) + (sep (if note ;セパレータ + : +@end group +@end lisp + +@defun skk-lookup-get-content 単語 listing-p + +単語の意味を EPWING 辞書から取得します。オプション引数 listing-p が +@code{non-nil} なら候補一覧用に一行の短い文字列を返しますが、@code{nil} な +らば全体を返します。 + +@end defun + +@defvr {ユーザ変数} skk-lookup-get-content-nth-dic + +関数 @code{skk-lookup-get-content} が「どの EPWING 辞書から単語の意味を +取得するのか」を、ゼロを起点とした数値で指定します。 + +docstring に例示した S 式を評価してみてください。 + +@end defvr + +@noindent +@kbd{M-x skk-lookup-get-content-setup-dic} +@kindex M-x skk-lookup-get-content-setup-dic + + +@b{DDSKK の起動後に変数 @code{skk-lookup-get-content-nth-dic} の数値を変 +更した場合は、このコマンドを必ず実行してください。} + +@item +@code{skk-annotation-lookup-lookup} を設定する方法 + +次に変数 @code{skk-annotation-lookup-lookup} について説明します。この変 +数は EPWING 経由アノテーションの設定を簡単にします。 + +@defvr {ユーザ変数} skk-annotation-lookup-lookup + +@code{Non-nil} ならば @file{lookup.el} を利用してアノテーションを取得する。 + +@lisp +(setq skk-annotation-lookup-lookup t) +@end lisp + +この値を @code{always} に設定すると、候補一覧でも辞書サービスを引く。 +@footnote{この設定は変数 @code{skk-treat-candidate-appearance-function} +の値を上書きします。@code{skk-treat-candidate-appearance-function} を +自分で設定する場合は @code{skk-annotation-lookup-lookup} には @code{t} +または @code{nil} を必要に応じて設定します。} + +@lisp +(setq skk-annotation-lookup-lookup 'always) +@end lisp + +@end defvr + +@end enumerate + +@node Apple OS X 「辞書」サービスからアノテーションを取得する +@subsection Apple OS X 「辞書」サービスからアノテーションを取得する + +Mac OS X 10.5 以降に標準で入っている国語辞典などからアノテーションが取得 +できます。@footnote{この機能を利用するには、python の拡張機能として +readline と pyobject-framework-DictionaryServices が必要です。後者につい +ては OS X 10.5 (Leopard) 以降の OS 標準の python に初めからインストール +されています。readline については OS X 10.7 (Lion) 標準の python ではイ +ンストールする必要がありません。OS X 10.6 以前の場合は + +@example +% easy_install readline +@end example + +@noindent +などの方法でインストールします。} + +@defvr {ユーザ変数} skk-annotation-lookup-DictionaryServices + +@code{Non-nil} ならば OS X の辞書サービスを利用してアノテーションを取得 +する。 + +@lisp +(setq skk-annotation-lookup-DictionaryServices t) +@end lisp + +この値を @code{always} に設定すると候補一覧でも辞書サービスを引く。 +@footnote{この設定は変数 @code{skk-treat-candidate-appearance-function} +の値を上書きします。@code{skk-treat-candidate-appearance-function} を +自分で設定したい場合は @code{skk-annotation-lookup-DictionaryServices} +には @code{t} または @code{nil} を必要に応じて設定します。} + +@lisp +(setq skk-annotation-lookup-DictionaryServices 'always) +@end lisp + +@end defvr + +@defvr {ユーザ変数} skk-annotation-python-program + +アノテーション取得のために呼びだす python のプログラム名。 + +@lisp +(setq skk-annotation-python-program "/usr/bin/python") +@end lisp + +@end defvr + +今のところ、アノテーションを取得する辞典を選択することはできません。 +OS X の「辞書」アプリ (Dictionary.app) を起動し、環境設定から辞書の検索 +順を指定してください。国語辞典を上位に指定すれば使いやすくなります。 + +@node Wikipedia/Wiktionary からアノテーションを取得する +@subsection Wikipedia/Wiktionary からアノテーションを取得する + +候補にアノテーションの登録がない場合、アノテーションに代えて +@uref{http://ja.wiktionay.org/, Wiktionary}, +@uref{http://ja.wikipedia.org/, Wikipedia} +による解説を表示することができます。他のアノテーションが変換時に自動的に +表示されるのに対し、 Wikipedia/Wiktionary アノテーションは基本的にユーザ +の指示によって取得される点で異なります。 + +▼モードで候補を表示しているときに @kbd{C-i} を押すと、 +@code{skk-annotation-other-sources} で指定された順で解説を取得して +エコーエリアに表示@footnote{変数@code{skk-show-tooltip} が @code{non-nil} の +場合、ツールティップで表示します。} します。 + +@example +B o k u j o u + +@group +----- Buffer: foo ----- +▽ぼくじょう@point{} +----- Buffer: foo ----- +@end group + +@key{SPC} + +@group +----- Buffer: foo ----- +▼牧場@point{} +----- Buffer: foo ----- +@end group + +@kbd{C-i} + +@group +----------------------------- Echo Area ------------------------------ +牧場(ぼくじょう)とは、ウシ、ウマなどの家畜を飼養する施設。訓読みされ +てまきばと呼ばれることもある。 +----------------------------- Echo Area ------------------------------ +@end group +@end example + +エコーエリアに解説が表示されている最中に @kbd{C-o} を押すと、 +関数 @code{browse-url} を用いて、その解説の元となった URL をブラウズしま +す。 + +@kindex C-i +@defvr {ユーザ変数} skk-annotation-wikipedia-key + +デフォルトは @kbd{C-i} です。 + +@end defvr + +@kindex C-o +@defvr {ユーザ変数} skk-annotation-browse-key + +デフォルトは @kbd{C-o} です。eww で閲覧したい場合は、次のとおり設定して +ください。 + +@lisp +(setq browse-url-browser-function 'eww-browse-url) +@end lisp + +@end defvr + +@defvr {ユーザ変数} skk-annotation-other-sources + +アノテーションを取得する SKK 辞書以外のソースを指定します。 + +@end defvr + +@node 外部コマンドからアノテーションを取得する +@subsection 外部コマンドからアノテーションを取得する + +外部コマンドからアノテーションを取得できます。 + +@defvr {ユーザ変数} skk-annotation-lookup-dict + +@code{Non-nil} ならば、@code{skk-annotation-dict-program} に指定された外 +部コマンドからアノテーションを指定します。 + +@end defvr + +@defvr {ユーザ変数} skk-annotation-dict-program + +アノテーションを取得するための外部コマンド名を指定します。 + +@end defvr + +@defvr {ユーザ変数} skk-annotation-dict-program-arguments + +アノテーションを取得に使う外部コマンドに渡す引数を指定します。 + +@end defvr + +@node 各種アノテーション機能を SKK の枠をこえて活用する +@subsection 各種アノテーション機能を SKK の枠をこえて活用する + +前述した各種外部アノテーション (lookup.el + EPWING 辞書、 Apple OS X 辞書、 +Wikipedia/Wiktionary) は、SKK の変換モードだけでなく Emacs のあらゆる状 +況で辞書引き機能として使うことができます。そのためには、コマンド +@code{skk-annotation-lookup-region-or-at-point} を任意にキー定義します。 + +@defun {コマンド} skk-annotation-lookup-region-or-at-point &optional PREFIX-ARG START END + +このコマンドは、領域が指定されていればその領域の文字列をキーワードとして +Lookup.el, OS X 辞書サービス、または Wikipedia/Wiktionary アノテーション +を探し、表示します。領域が指定されていなければ、可能な範囲でその位置にあ +る単語 (始点と終点) を推測します。 +@end defun + +一例として、以下のキー割当を紹介します。 + +@lisp +(global-set-key "\M-i" 'skk-annotation-lookup-region-or-at-point) +@end lisp + +@noindent +このようにしておくと、何かの意味が調べたくなったとき、領域選択して +@kbd{M-i} とタイプすればその場で辞書を引くことができます。 + +@noindent +さらに、ユーザオプション @code{skk-annotation-other-sources} の 3 番 +目 (Apple OS X では 4 番目) は標準で @code{en.wiktionary} になっています。 +例えば、英文を読んでいて buffer という語の正確な意味を参照したくなったと +します。そのときは 単語 buffer にポイントを合わせ、@kbd{M-3 M-i} +(Max OS X では @kbd{M-4 M-i}) とプレフィックス付でコマンドを実行してみて +ください。@footnote{@code{skk-annotation-other-sources} の標準の値は環境 +によって異なります。@file{lookup.el} と @file{skk-lookup.el} の設定が有 +効になっている場合は @code{en.wiktionary} は 4 番目 (Apple OS X では5番 +目) になります。} + +@example +@group +----- Buffer: *scratch* ----- +;; This buffer@point{} is for notes you don't want to save, and for @dots{} +----- Buffer: *scratch* ----- +@end group + +@kbd{M-3 M-i} (Max OS X では @kbd{M-4 M-i}) +@end example + +@noindent +すると SKK モードでのアノテーションと同様、以下のような説明が表示されま +す。 + +@example +@group +-------------------- Echo Area -------------------- + English, Noun +buffer (plural buffers) + 1: Someone or something that buffs. + 2: (chemistry) A solution used to stabilize the pH (acidity) of a + liquid. + 3: (computing) A portion of memory set aside to store data, often + before it is sent to an external device or as it is received from an + external device. +[@dots{}] +-------------------- Echo Area -------------------- +@end group +@end example + +@node 文字コード関連 +@section 文字コード関連 + +@menu +* 文字コードまたはメニューによる文字入力:: +* メニューによる文字入力:: +* 文字コード一覧:: +* 文字コードを知る方法:: +@end menu + +関連項目 @w{@xref{辞書バッファの文字コードの設定}.} + +@node 文字コードまたはメニューによる文字入力 +@subsection 文字コードまたはメニューによる文字入力 + +@cindex JISコード +@cindex EUCコード +@kindex \ +@kindex C-u \ +@vindex skk-kcode-charset + +かなモードで @kbd{\} キーを入力すると、ミニバッファに +@example +@group +---------------------------- Minibuffer ----------------------------- +○○の文字を指定します。7/8 ビット JIS コード (00nn), 区点コード (00-00), +UNICODE (U+00nn), または [RET] (文字一覧): @point{} +---------------------------- Minibuffer ----------------------------- +@end group +@end example + +@noindent +というプロンプトが表示され、文字コード(JIS コード、EUC コードまたは区点番号) +またはメニューによる文字入力が促されます。 + +上記例示の○○部分は 変数 @code{skk-kcode-charset} の値であり、 +その初期値は @code{japanese-jisx0208} 又は @code{japanese-jisx0213-1} です。 +初期値は環境によって自動的に設定されます。 +キー @kbd{\} の代わりに @kbd{C-u \} と入力すると、異なる文字集合 (charset) を指定す +る事ができます。 + +ここで、文字コードがあらかじめ分かっている場合には、その文字コードを入力 +します。例えば @samp{℃} の文字コードは、JIS コードでは @samp{216e}、EUC +コードでは @samp{a1ee} なので、いずれかの文字コードを入力すれば @samp{℃} +が現在のバッファに挿入されます。 + +区点番号で入力するには @samp{01-78} のように区と点の間にハイフン @samp{-} を +入れる必要があります。ハイフン @samp{-} で区切った3組の数字は JIS X 0213 の +2面を指定したとみなします。例えば @samp{2-93-44} で「魚花」(ほっけ)が入力 +できます。 + +@node メニューによる文字入力 +@subsection メニューによる文字入力 + +文字コードが不明の文字を入力するには、文字コードを入力せずにそのまま +@key{RET} キーを入力します。するとミニバッファに以下のような表示が現れま +す。 + +@c 次の例示中では空欄となっているが、実行時は W: は U+ff0d (-), +@c R: は U+2295 (⊕), Y: は U+2194 (↔) である。 +@example +@group +---------------------------- Minibuffer ----------------------------- +A:  S: ̄ D:〜 F:} G:= H:¢ Q:◆ W:  E:∩ R:  T:≡ Y:  +---------------------------- Minibuffer ----------------------------- +@end group +@end example + +@kindex x +これを@b{「第1段階のメニュー」}と呼びます。第1段階のメニューでは、JIS 漢字を +コードの順に 16 文字毎に1文字抽出し、ミニバッファに一度に 12 文字ずつ +表示しています +@footnote{上記の例では、JIS コード 2121 (全角スペース)、2131、2141、2151、 +@dots{} の文字がそれぞれ表示されています。}。ここで @key{SPC} を入力する +と次の候補群を表示します +@footnote{文字コードの値を @w{16x12 @equiv{}192} ずつ増やします。}。 +@kbd{x} を入力すると1つ前の候補群に戻ります。 + +キー @kbd{a}, @kbd{s}, @kbd{d}, @kbd{f}, @kbd{g}, @kbd{h}, +@kbd{q}, @kbd{w}, @kbd{e}, @kbd{r}, @kbd{t}, @kbd{y} のいずれかを +入力すると +@footnote{大文字でも小文字でも構いません。なお、第1段階・第2段階とも +に、メニューのキーを変更することができます。 +@w{@ref{候補の選択に用いるキー}} を参照してください。} +、そのキーに対応する文字から始まる 16 個の文字が文字コード順に表示されま +す。これを@b{「第2段階のメニュー」}と呼びます。例えば、第1段階のメニュ +ーが上記の状態のときに @kbd{d} を入力すると 第2段階のメニューは以下のよ +うになります。 + +@smallexample +@group +--------------------------------- Minibuffer ---------------------------------- +A:〜 S:‖ D:| F:… G:‥ H:‘ J:’ K:“ L:” Q:( W:) E:〔 R:〕 T:[ Y:] U:{ +--------------------------------- Minibuffer ---------------------------------- +@end group +@end smallexample + +ここで、キー @kbd{a}, @kbd{s}, @kbd{d}, @kbd{f}, @kbd{g}, @kbd{h}, @kbd{j}, +@kbd{k}, @kbd{l}, @kbd{q}, @kbd{w}, @kbd{e}, @kbd{r}, @kbd{t}, @kbd{y}, +@kbd{u}, のいずれかを +入力すると、対応する文字がカレントバッファに挿入されてメニューによる入力 +が終了します。 + +第2段階のメニューが表示されているときも @key{SPC} と @kbd{x} キーによ +り第2段階のメニューが前進、後退します。 + +@kindex < +@kindex > +@kindex ? +また @kbd{<}、@kbd{>} によりメニューを1文字分だけ移動します。例えば、 +第2段階のメニューが上記の状態のときに @kbd{<} を入力すると、メニューは +以下のようになります。 + +@smallexample +@group +--------------------------------- Minibuffer ---------------------------------- +A:\ S:〜 D:‖ F:| G:… H:‥ J:‘ K:’ L:“ Q:” W:( E:) R:〔 T:〕 Y:[ U:] +--------------------------------- Minibuffer ---------------------------------- +@end group +@end smallexample + +第1段階あるいは第2段階のメニューが表示されているときに @kbd{?} を入 +力すると、そのときのキー @kbd{A} に対応する文字 (上記の例では、@samp{\}) +の文字コードが表示されます。 + +@defvr {ユーザ変数} skk-kcode-method + +@kbd{\} の打鍵で起動する @code{skk-input-by-code-or-menu} の挙動を調節します。 + +@table @code +@item 'char-list +@kbd{\} の打鍵で「文字コード一覧」(skk-list-chars)を起動します。 + +@item 'code-or-char-list +@kbd{\} の打鍵で「文字コード」(skk-input-by-code)を起動します。 +JIS コード/区点コード入力プロンプトの表示に対して単に @key{RET} をタイプした場合、 +「文字コード一覧」(skk-list-chars)を起動します。 + +@item 'this-key +@kbd{\} の打鍵で @samp{\} を挿入します。 + +@item 上記シンボル以外 +@kbd{\} の打鍵で「文字コード」(skk-input-by-code)を起動します。 +JIS コード/区点コード入力プロンプトの表示に対して単に @key{RET} をタイプした場合、 +「メニュー入力」を起動します。 + +@end table + +@end defvr + +@node 文字コード一覧 +@subsection 文字コード一覧 +@kindex M-x skk-list-chars +@kindex M-x list-charset-chars +@kindex C-x 8 RET +@vindex skk-kcode-charset + +@kbd{M-x skk-list-chars} と実行すると、変数 @code{skk-kcode-charset} が指 +す文字集合に従ってバッファ @code{*skk-list-chars*} に文字の JIS コード一 +覧が表示されます。 + +プレフィックス付きで、つまり @kbd{C-u M-x skk-list-chars} と実行すると、 +カーソル位置の文字に照準をあわすようコード一覧を表示します。 + +@example +@group +-------------------- *skk-list-chars* -------------------- +variable skk-kcode-charset's value is `japanese-jisx0208'. + +01-#x--- 0-- 1-- 2-- 3-- 4-- 5-- 6-- 7-- 8-- 9-- A-- B-- C-- D-- E-- F +  2120     、 。 , . ・ : ; ? ! ゛ ゜ ´ ` ¨ +  2130 ^  ̄ _ ヽ ヾ ゝ ゞ 〃 仝 々 〆 〇 ー — ‐ / +  2140 \ 〜 ‖ | … ‥ ‘ ’ “ ” ( ) 〔 〕 [ ] +  2150 { } 〈 〉 《 》 「 」 『 』 【 】 + − ± × +  2160 ÷ = ≠ < > ≦ ≧ ∞ ∴ ♂ ♀ ° ′ ″ ℃ ¥ +  2170 $ ¢ £ % # & * @ § ☆ ★ ○ ● ◎ ◇ +-------------------- *skk-list-chars* -------------------- +@end group +@end example + +@table @kbd +@item f +@itemx C-f +@itemx l +カーソル移動 + +@item b +@itemx C-b +@itemx h +カーソル移動 + +@item n +@itemx C-n +@itemx j +カーソル移動 + +@item p +@itemx C-p +@itemx k +カーソル移動 + +@item C-x C-x +カーソル移動 + +@item \ +@itemx o +文字集合の切り替え + +@item c +文字コード入力 + +@item i +@itemx RET +文書バッファへ文字を挿入 + +@item q +skk-list-chars を抜ける。 + +@item $ +カーソル位置の文字の文字コードを表示 + +@end table + +ほか、Emacs のコマンド @kbd{M-x list-charset-chars} や @kbd{C-x 8 RET} も有用でしょう。 + +@defvr {ユーザ変数} skk-list-chars-table-header-face +コード一覧の枠線などに適用するフェイスです。 +@end defvr + +@defvr {ユーザ変数} skk-list-chars-face +プレフィックス付きで実行したときの照準のフェイスです。 +@end defvr + +@node 文字コードを知る方法 +@subsection 文字コードを知る方法 +@kindex $ +@cindex JISコード +@cindex EUCコード +@kindex M-x skk-display-code-for-char-at-point + +かな/カナモードで @kbd{$} を入力する +@footnote{リードオンリーなバッファでは @kbd{M-x skk-display-code-for-char-at-point} を実行してください。} +と、現在のポイント位置の直後にある +文字の文字コードをエコーエリア@footnote{変数 @code{skk-show-tooltip} が +@code{non-nil} であればツールティップで表示します。 +変数 @code{skk-show-candidates-always-pop-to-buffer} が @code{non-nil} で +あれば other-window に表示します。@code{skk-show-tooltip} が優先します。} +に表示します。 + +例えば、カーソルを文字 @samp{А} の上に置いて @kbd{$} を入力すると、 + +@example +@group +-------------------- Echo Area -------------------- +`А',KUTEN:07-01, JIS:#x2721, EUC:#xa7a1, SJIS:#x8440, UNICODE:U+0410, キリール大文字A,CYRILLIC CAPITAL LETTER A +-------------------- Echo Area -------------------- +@end group +@end example + +@noindent +とエコーエリアに表示され、この文字がキリル文字であることがわかります。 + +@c プレフィックス付きで @kbd{\}(つまり @kbd{C-u \})とタイプすると、 +@c ポイント直後の文字について文字コード一覧が表示されます。 +@c +@c @example +@c @group +@c -------------------- *skk-list-chars* -------------------- +@c 07-#x--- 0-- 1-- 2-- 3-- 4-- 5-- 6-- 7-- 8-- 9-- A-- B-- C-- D-- E-- F +@c   2720   А Б В Г Д Е Ё Ж З И Й К Л М Н +@c   2730 О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э +@c -------------------- *skk-list-chars* -------------------- +@c @end group +@c @end example +@c +ほか、 Emacs のコマンド @kbd{M-x describe-char} も@footnote{Emacs 21 では @kbd{M-x describe-char-after} です。}有用でしょう。 + +@defvr {ユーザ変数} skk-display-code-prompt-face +エコーエリアに表示されるメッセージ中 @samp{KUTEN:}、@samp{JIS:}@samp{EUC:}、@samp{SJIS:} 及び @samp{UNICODE:} に適用するフェイスです。 +@end defvr + +@defvr {ユーザ変数} skk-display-code-char-face +エコーエリアに表示されるメッセージ中の当該文字に適用するフェイスです。 +@end defvr + +@defvr {ユーザ変数} skk-display-code-tankan-radical-face +エコーエリアに表示されるメッセージ中の総画数表示に適用するフェイスです。 +@end defvr + +@defvr {ユーザ変数} skk-display-code-tankan-annotation-face +エコーエリアに表示されるメッセージ中の文字名表示に適用するフェイスです。 +@end defvr + +@node DDSKK 以外のツールを用いた辞書変換 +@section DDSKK 以外のツールを用いた辞書変換 + +@menu +* skk-lookup:: Lookup を用いた辞書変換 +* skk-look:: look コマンドを用いた辞書変換 +* Lisp シンボル名の補完検索変換:: +* Google CGI API for Japanese Input を利用したかな漢字変換:: +@end menu + +@node skk-lookup +@subsection skk-lookup +@cindex @file{skk-lookup.el} +@cindex Lookup +@vindex skk-lookup-search-agents +@findex skk-lookup-search + +@file{skk-lookup.el} を使用すると、辞書検索ツールの Lookup +(@url{http://openlab.jp/edict/lookup/}) で検索できる辞書を用いて単語 +の候補を出すことができるようになります @footnote{@file{skk-lookup.el} +は @file{skk-look.el} とは別ものです。}。 + +DDSKK のインストール過程で @code{(require 'lookup)} が成功する場合は +@file{skk-lookup.el} も自動的にインストールされます。 +まずは @samp{make what-where} を実行して、@samp{SKK modules:} 欄 +に @samp{skk-lookup} が含まれていることを確認してください。 + +Lookup がインストールされているにも関わらず、うまく @file{skk-lookup.el} が +インストールされない場合は、@file{SKK-CFG} を編集して @file{lookup.el} +が置かれているパスを @code{ADDITIONAL_LISPDIR} に設定し、再度 DDSKK をイ +ンストールして下さい +@footnote{関数 @code{skk-lookup-search} が @file{skk-autoloads.el} に +追加されます (@pxref{辞書検索のための関数}).}。 + +@file{~/.skk} に以下のように設定します。 + +@lisp +@group +(setq skk-search-prog-list + (append skk-search-prog-list + (list + '(skk-lookup-search)))) +@end group +@end lisp + +@noindent +@code{skk-lookup-search} は、 DDSKK が用意している検索プログラムの中で最 +も遅いものです。したがって、@code{skk-search-prog-list} の設定にあっては +辞書サーバの検索 (@code{skk-search-server}) よりも後方に置くよう設定します。 + +Lookup の agent で利用するのは、 @code{lookup-search-agents} から @code{ndkks}, +@code{ndcookie} 及び @code{ndnmz} を取り去ったものです +@footnote{@code{skk-lookup-search-agents} にセットして検索するように +しています。Lookup とは異なる設定をする場合、この変数の設定を変更すれば +可能です}。 + +@node skk-look +@subsection skk-look +@cindex @file{skk-look.el} + +@file{skk-look.el} は、 @command{look} コマンドを使って次の 3 つの機能を提供します +@footnote{@file{skk-look.el} は @file{skk-lookup.el} とは名前が似てい +ますが全くの別ものです}。 + +@menu +* 英単語の補完:: +* 英単語をあいまいに変換して取り出す:: +* 英単語をあいまいに変換して取り出した後、更に再帰的な英和変換を行う:: +@end menu + +@node 英単語の補完 +@subsubsection 英単語の補完 +@vindex skk-use-look + +@code{skk-use-look} を @code{non-nil} に設定すると @file{skk-look.el} +が使用できるようになります。 + +例えば、 @file{~/.skk} で以下のように設定します。 + +@lisp +(setq skk-use-look t) +@end lisp + +@noindent +SKK abbrev モードが拡張されて、@command{look} コマンドを使用した補完が有効 +になります。 + +@example +@kbd{/ a b s t r} + +@group +------ Buffer: foo ------ +▽abstr@point{} +------ Buffer: foo ------ +@end group + +@kbd{@key{TAB}} + +@group +------ Buffer: foo ------ +▽abstract@point{} +------ Buffer: foo ------ +@end group + +@end example + +と補完してくれます。通常の補完と同様に @kbd{.} で次の補完候補に、@kbd{,} で +ひとつ前の補完候補に移動できます。 + +SKK 形式の英和辞書@footnote{SKK 形式の英和辞書 edict が提供されています。 +@xref{辞書の入手}.}があれば、ここから @key{SPC} を押して英和変換ができます。 + +@node 英単語をあいまいに変換して取り出す +@subsubsection 英単語をあいまいに変換して取り出す +@vindex skk-search-excluding-word-pattern-function + +見出し語にアスタリスク @samp{*} を入れて @key{SPC} を押すと英単語をあいまい +にして変換できます。 + +@example + +@group +------ Buffer: foo ------ +▽abstr@point{} +------ Buffer: foo ------ +@end group + +@key{SPC} + +@group +------ Buffer: foo ------ +▼abstract@point{} +------ Buffer: foo ------ +@end group + +@end example + +確定すると、@samp{abstr*} を見出し語と、@samp{abstract} を候補とする +エントリが個人辞書に追加されます。このようなエントリを追加したくない場合、 +ユーザ変数 @code{skk-search-excluding-word-pattern-function} を適切に +設定します。 + +例えば次のような設定です。 + +@lisp +@group +(add-hook 'skk-search-excluding-word-pattern-function + ;; 返り値が non-nil の時、個人辞書に取り込まない。 + ;; KAKUTEI-WORD を引数にしてコールされるので、不要でも引数を取る + ;; 必要あり + (lambda (kakutei-word) + (and skk-abbrev-mode + (save-match-data + ;; SKK-HENKAN-KEY が "*" で終わるとき + (string-match "\\*$" skk-henkan-key))))) +@end group +@end lisp + + +@node 英単語をあいまいに変換して取り出した後、更に再帰的な英和変換を行う +@subsubsection 英単語をあいまいに変換して取り出した後、更に再帰的な英和変換を行う +@vindex skk-look-recursive-search +@vindex skk-look-expanded-word-only + +SKK 辞書に + +@example + abstract /アブストラクト/抽象/ + abstraction /アブストラクション/ +@end example + +@noindent +というエントリがあるとして解説します +@footnote{edict 辞書 @file{SKK-JISYO.edict} があれば、例えば、 + +@lisp +@group +(setq skk-search-prog-list + (append skk-search-prog-list + (list + '(skk-search-jisyo-file "/your-path/SKK-JISYO.edict" 0 t)))) +@end group +@end lisp + +@noindent +のように設定することにより、 edict 辞書を使用できます。}。 + +変数 @code{skk-look-recursive-search} の値を @code{non-nil} にセットして +下さい。 + +@example +▽abstr* + +@key{SPC} + +▼abstract + +@key{SPC} + +▼アブストラクト + +@key{SPC} + +▼抽象 + +@key{SPC} + +▼abstraction + +@key{SPC} + +▼アブストラクション +@end example + +@noindent +このように英単語 + その英単語を見出し語にした候補の「セット」を変換 +結果として出力することができます。 + +@defvr {ユーザ変数} skk-look-expanded-word-only + +この変数の値が @code{non-nil} であれば、再帰検索に成功した英単語の「セッ +ト」だけを出力することができます。再帰検索で検出されなかった英単語は無視 +して出力しません。 + +@end defvr + +@node Lisp シンボル名の補完検索変換 +@subsection Lisp シンボル名の補完検索変換 + +SKK abbrev モードにて、Lisp シンボル名を補完して検索し、検索結果を候補と +して返すことができます。英文字の後ろに @samp{~} を付加してから変換を開始 +してください。 + +まずは動作例を示します。 + +@example +/ d e f i ~ + +@group +----- Buffer: foo ----- +▽defi~@point{} +----- Buffer: foo ----- +@end group + +@key{SPC} + +@group +----- Buffer: foo ----- +▽defimage@point{} +----- Buffer: foo ----- +@end group + +@key{SPC} + +@group +----- Buffer: foo ----- +▽define-abbrev@point{} +----- Buffer: foo ----- +@end group + +@key{SPC} + +@group +----- Buffer: foo ----- +▽define-abbrev-table@point{} +----- Buffer: foo ----- +@end group + +@key{SPC} + +@group +----- Buffer: foo ----- +▽define-abbrevs@point{} +----- Buffer: foo ----- +@end group + +@key{SPC} + +@group +----- Buffer: *候補* ----- +A:define-auto-insert +S:define-category +D:define-ccl-codepoint-translation-table +F:define-ccl-constant-translation-table +J:define-ccl-identity-translation-table +K:define-ccl-program +L:define-ccl-slide-translation-table +----- Buffer: *候補* ----- +@end group +@end example + +この機能を有効とするには、リスト @code{skk-search-prog-list} の要素に +関数 @code{skk-search-lisp-symbol} を加えてください。 + +@lisp +@group +(add-to-list 'skk-search-prog-list + '(skk-search-lisp-symbol) t) +@end group +@end lisp + +なお、見出し語に @samp{~} を含む辞書もあります。例えば @file{SKK-JISYO.JIS3_4} には +@lisp +A~ /チルド付きA(LATIN CAPITAL LETTER A WITH TILDE)/ +@end lisp +と登録@footnote{実際には JIS X 0213 の1面9区26点の1文字が登録されています。 +この文字を @file{skk.texi} に直接記載するのは避けました。}されています。 +したがって、▽A~ @key{SPC} と変換したときに「チルド付きA」が表示されるか、Lisp シンボル名が補完されるかは、リスト @code{skk-search-prog-list} 内の要素の順によります。 + +@defun skk-search-lisp-symbol &optional PREDICATE NOT-ABBREV-ONLY WITHOUT-CHAR-MAYBE +オプション @code{PREDICATE} で補完検索する範囲(関数名、変数名、コマンド名)を限定することができます。 +詳細は docstring を参照してください。 +@end defun + +@defvr {ユーザ変数} skk-completion-search-char +@code{skk-completion-search} による変換機能を指示するキーキャラクタ。 +デフォルトは @kbd{~} です。 + +@end defvr + +@node Google CGI API for Japanese Input を利用したかな漢字変換 +@subsection Google CGI API for Japanese Input を利用したかな漢字変換 +@cindex Google CGI API for Japanese Input +@vindex skk-use-search-web +@findex skk-search-web +@vindex skk-search-prog-list +@vindex skk-read-from-minibuffer-function + +かな漢字変換に Google CGI API for Japanese Input を利用することができます。 +連文節変換も可能となります。 + +Google CGI API for Japanese Input については、次の URL を参照してください。 + +@url{http://www.google.co.jp/ime/cgiapi.html} + +まず、@file{~/.skk} にて、変数 @code{skk-use-search-web} を @code{non-nil} に +設定します。これにより、skk-mode を起動した際に @file{skk-search-web.el} を require す +るようになります。 + +同じく @file{~/.skk} にて、リスト @code{skk-search-prog-list} の一番最後 +の要素として、関数 @code{skk-search-web} を追加します。 + +@lisp +@group +(add-to-list 'skk-search-prog-list + '(skk-search-web 'skk-google-cgi-api-for-japanese-input) + t) +@end group +@end lisp + +以上の設定によって、通常のかな漢字変更の候補が尽きたときに関数 @code{skk-search-web} が +実行され、Google CGI API for Japanese Input による変換結果が表示されます。 + +そのほか、変数 @code{skk-read-from-minibuffer-function} を以下のように設 +定することで、辞書登録モードへの突入時の初期値に Google サジェストを表示す +ることもできます。 + +@lisp +@group +(setq skk-read-from-minibuffer-function + (lambda () + (car (skk-google-suggest skk-henkan-key)))) +@end group +@end lisp + +@node 飾りつけ +@section 飾りつけ + +@menu +* 仮名文字のローマ字プレフィックスのエコー:: +* 入力モードを示すモードラインの文字列の変更:: +* 入力モードを示すカーソル色に関する設定:: +* 変換候補一覧の表示方法:: +* ▼モードにおける変換候補のハイライト表示:: +* 変換候補の更なる装飾:: +* モードラインの装飾:: +@end menu + +@node 仮名文字のローマ字プレフィックスのエコー +@subsection 仮名文字のローマ字プレフィックスのエコー + +@defvr {ユーザ変数} skk-echo + +この変数の値は、仮名文字のローマ字プレフィックス +@footnote{@xref{送りありエントリと送りなしエントリ, ローマ字プレフィックス}.} +のエコーの有無を制御します。 +@end defvr + +変数 @code{skk-echo} の値が @code{non-nil} であれば、仮名文字のローマ字 +プレフィックスが、入力時点でいったん現在のバッファに挿入され、続く母音の入 +力の際に、かな文字に変換された時点で現在のバッファから消去されます。 + +@example +@group +@kbd{t} + +------ Buffer: foo ------ +t@point{} +------ Buffer: foo ------ + +@end group +@group +@kbd{a} + +------ Buffer: foo ------ +た@point{} +------ Buffer: foo ------ +@end group +@end example + +変数 @code{skk-echo} の値が @code{nil} であれば、仮名文字のローマ字プレ +フィックスのエコーは行われません。これを上記の例で考えると、@samp{t} が現 +在のバッファに挿入されず、続く母音 (@kbd{a}) が入力されたとき @samp{た} +の文字が挿入されます。 + +@defvr {ユーザ変数} skk-prefix-hiragana-face + +かなモードにおけるローマ字プレフィックスのフェイスを指定します。 + +@end defvr + +@defvr {ユーザ変数} skk-prefix-katakana-face + +カナモードにおけるローマ字プレフィックスのフェイスを指定します。 + +@end defvr + +@defvr {ユーザ変数} skk-prefix-jisx0201-face + +JIS X 0201 モードにおけるローマ字プレフィックスのフェイスを指定します。 + +@end defvr + +@node 入力モードを示すモードラインの文字列の変更 +@subsection 入力モードを示すモードラインの文字列の変更 + +下記の変数の値を変更することによって、モードライン上の「入力モードを示す文字 +列」を変更することができます@footnote{skk-show-mode の表示も連動します。}。 + +@defvr {ユーザ変数} skk-latin-mode-string +アスキーモードを示す文字列。標準は、``SKK''。 +@end defvr + +@defvr {ユーザ変数} skk-hiragana-mode-string +かなモードを示す文字列。標準は、``かな''。 +@end defvr + +@defvr {ユーザ変数} skk-katakana-mode-string +カナモードを示す文字列。標準は、``カナ''。 +@end defvr + +@defvr {ユーザ変数} skk-jisx0208-latin-mode-string +全英モードを示す文字列。標準は、``全英''。 +@end defvr + +@defvr {ユーザ変数} skk-abbrev-mode-string +SKK abbrev モードを示す文字列。標準は、``aあ''。 +@end defvr + +@node 入力モードを示すカーソル色に関する設定 +@subsection 入力モードを示すカーソル色に関する設定 + +@defvr {ユーザ変数} skk-use-color-cursor +この変数が @code{non-nil} ならば、カーソルを色付けします。@code{nil} +ならば、この機能を無効にします。 + +標準では、ウィンドウシステムを使用して、かつ、色表示が可能な場合に限 +って、この機能が有効になります。 +@end defvr + +この機能が有効になっているとき、以下の変数の値を変更することで、各モード +におけるカーソルの色を変更できます。 + +@defvr {ユーザ変数} skk-cursor-default-color +SKK モードがオフであることを示すカーソル色。標準では、カーソルのある該当 +フレームにおける標準のカーソル色を使います。 +@end defvr + +@defvr {ユーザ変数} skk-cursor-hiragana-color +かなモードであることを示すカーソル色。標準は、背景の明暗により coral4 また +は pink です。 +@end defvr + +@defvr {ユーザ変数} skk-cursor-katakana-color +カナモードであることを示すカーソル色。標準は、背景の明暗により forestgreen また +は green です。 +@end defvr + +@defvr {ユーザ変数} skk-cursor-jisx0201-color +JIS X 0201 モードであることを示すカーソル色。標準は、背景の明暗により blueviolet また +は thistle です。 +@end defvr + +@defvr {ユーザ変数} skk-cursor-jisx0208-latin-color +全英モードであることを示すカーソル色。標準は、gold です。 +@end defvr + +@defvr {ユーザ変数} skk-cursor-latin-color +アスキーモードであることを示すカーソル色。標準は、背景の明暗により ivory4 また +は gray です。 +@end defvr + +@defvr {ユーザ変数} skk-cursor-abbrev-color +skk abbrev モードであることを示すカーソル色。標準は、royalblue です。 + +@end defvr + +@page + +@node 変換候補一覧の表示方法 +@subsection 変換候補一覧の表示方法 + +変換候補一覧の表示方法は、次の4つに大別されます。 + +@itemize @bullet +@item 現在のウィンドウにインライン表示する +@item ツールティップで表示する +@item 現在のウィンドウの隣に別なウィンドウを開いて表示する (ポップアップ) +@item エコーエリアに表示する +@end itemize + +ここではその表示方法の制御について解説します。 + +@defvr {ユーザ変数} skk-show-inline + +@b{XEmacs ではこの機能はサポートされません。} + +この変数の値が @code{non-nil} であれば、候補一覧を現在のポイント位置でインライン表 +示します。 +値が シンボル @code{'vertical} であれば、各候補を縦方向にインライン表示します。 + +@cartouche +@defvr {ユーザ変数} skk-inline-show-face +インライン表示する変換候補を装飾するフェイスを指定します。デフォルト +は @code{'underline} です。 + +@lisp +(setq skk-inline-show-face 'font-lock-doc-face) +@end lisp + +@code{skk-treat-candidate-appearance-function} による装飾を優先するには +@code{nil} に設定して下さい。 +@end defvr + +@defvr {ユーザ変数} skk-inline-show-background-color +インライン表示する変換候補の背景色を指定します。 + +@code{skk-inline-show-face} または +@code{skk-treat-candidate-appearance-function} にて、背景色が指定されてい +ない文字に対してのみ作用します。 +@end defvr + +@defvr {ユーザ変数} skk-inline-show-background-color-odd +インライン表示する変換候補の背景色(奇数ライン)を指定します。 +@end defvr + +@end cartouche +@end defvr + +@page + +@defvr {ユーザ変数} skk-show-tooltip +この変数の値が @code{non-nil} であれば、候補一覧をツールティップで表示し +ます。同時に、「注釈 (アノテーション) の表示方法」と「文字コードの表示方 +法」も制御します。 + +@xref{注釈 (アノテーション)}. + +@xref{文字コードまたはメニューによる文字入力}. + +@cartouche +@defvr {ユーザ変数} skk-tooltip-face +ツールティップ表示する文字列に適用するフェイスを指定する変数です。 + +@lisp +(setq skk-tooltip-face 'font-lock-doc-face) +;; (make-face 'skk-tooltip-face) ではないことに注意 +@end lisp + +候補文字列のフェイス属性(@code{skk-treat-candidate-appearance-function} による加工など)をそのまま使いたい場合は @code{nil} に設定して下さい。 +@end defvr + +@defvr {ユーザ変数} skk-tooltip-mouse-behavior + +ツールティップを表示する位置及びマウスポインタの挙動を指定します。 +下記に掲げるシンボル以外のシンボルを指定した場合は @code{nil} となります。 + +@table @code +@item 'follow +マウスポインタをカーソル位置へ移動させてツールティップを表示します。 +ツールティップの表示を終えるとマウスポインタは元の位置へ戻ります。ただし、元のマウスポインタが Emacs フレーム外であったならばツールティップの表示を終えてもマウスポインタはカーソル位置のままです。 + +@item 'banish +マウスポインタを Emacs フレーム右上隅へ移動させてツールティップを表示します。 +ツールティップの表示を終えもてマウスポインタは Emacs フレーム右上隅のままです。 + +@item 'avoid +マウスポインタを Emacs フレーム右上隅へ移動させてツールティップを表示します。 +ツールティップの表示を終えるとマウスポインタは元の位置へ戻ります。ただし、元のマウスポインタが Emacs フレーム外であったならばツールティップの表示を終えてもマウスポインタは Emacs フレーム右上隅のままです。 + +@item 'avoid-maybe +マウスポインタが Emacs フレーム内であれば @code{'avoid} と同じ動作です。 +マウスポインタが Emacs フレーム外であればマウスポインタ位置を変更せず、その位置にツールティップを表示します。 + +@item nil +マウスポインタを一切移動せず、その位置にツールティップを表示します。 +ツールティップのテキストとマウスポインタが重なったり、うまくツールティップが表示できなかったりする場合があります。 + +@end table + +@end defvr + +@defvr {ユーザ変数} skk-tooltip-hide-delay + +ツールティップを表示する秒数。デフォルトは 1,000秒。この時間が経過すると、 +ツールティップは自動的に消える。 + +@end defvr + +@defvr {ユーザ変数} skk-tooltip-parameters + +デフォルトは @code{nil}。SKK 独自のフレームパラメータを設定する。 +@code{nil} の場合、@code{tooltip-frame-parameters} が適用される。 + +@end defvr + +@end cartouche +@end defvr + +@page + +@defvr {ユーザ変数} skk-show-candidates-always-pop-to-buffer +この値が @code{non-nil} であれば、画面を上下に分割したうえで、変換一覧を専用 +の「*候補*バッファ」で表示します。 + +候補一覧表示中に、この値を動的に切り換える手段が用意されています。 + +@cartouche +@defvr {ユーザ変数} skk-show-candidates-toggle-display-place-char +@kindex C-f +デフォルトは @kbd{C-f} です。このキーを候補一覧表示時にタイプすると、候補 +一覧の表示位置をエコーエリアとバッファとで切り替えます。 +@end defvr + +@defvr {ユーザ変数} skk-candidate-buffer-background-color + *候補*バッファの背景色を指定します。 +背景色を付けたくない場合は @code{nil} を指定すること(デフォルト)。 +@end defvr + +@defvr {ユーザ変数} skk-candidate-buffer-background-color-odd + *候補*バッファの背景色(奇数ライン)を指定します。 +@end defvr + +@defvr {ユーザ変数} skk-candidate-buffer-delete-other-windows + nil であれば、*候補*バッファ表示に際して window 配置を変更しない。 +@end defvr + +@end cartouche +@end defvr + +@noindent +デフォルトでは3つの変数 + +@itemize @bullet +@item @code{skk-show-inline} +@item @code{skk-show-tooltip} +@item @code{skk-show-candidates-always-pop-to-buffer} +@end itemize + +とも @code{nil} であり、この状態では候補一覧はエコーエリアに表示 +@footnote{@code{frame-width} が不足する場合は *候補*バッファに表示します。} +します。 + +もしも、これら変数のうち2つ以上が @code{non-nil} の場合、優先順位は上記 +の解説の順です。 + +@page + +@node ▼モードにおける変換候補のハイライト表示 +@subsection ▼モードにおける変換候補のハイライト表示 +@cindex @file{canna.el} +@cindex @file{rgb.txt} + +@defvr {ユーザ変数} skk-use-face + +この変数の値が @code{non-nil} であれば、Emacs のフェイス機能を使って変換 +候補をハイライト表示します。 + +@cindex Overlays +@cindex Extents +@cindex Text Properties +このハイライト表示には Emacs のオーバーレイ (overlay) の機能を使います +@footnote{以前のバージョンではテキスト属性 (text property) を使用してい +ました。 + +オーバーレイ属性はテキスト属性と異なり、テキストの一部とは見なされません。 +そのため、テキストのコピーの際にオーバーレイ属性は保存されません。その他 +にも、オーバーレイの移動やその属性の変更はバッファの変更とは見なされない +こと、オーバーレイの変更はバッファのアンドゥリストに記録されないこと、な +どが特徴として挙げられます。 + +なお、XEmacs にはオーバーレイ機能はありません。代わりに extent というも +のが用意されているのでそれを利用します。}。 +@end defvr + +@defvr {ユーザ変数} skk-henkan-face + +この変数の値はフェイスであり、このフェイスによって変換候補がハイライト表 +示されます。標準では、背景の明暗により ``black/darkseagreen2'' 又は +``white/darkolivegreen'' を用います。 + +なお、この変数よりも @code{skk-treat-candidate-appearance-function} の設 +定が優先されます。 +@end defvr + +変数 @code{skk-henkan-face} には、既存のフェイス +@footnote{Emacs 標準 では @code{default}, @code{modeline}, @code{region}, +@code{secondary-selection}, @code{highlight}, @code{underline}, +@code{bold}, @code{italic}, @code{bold-italic} があります。}を指定できま +すが、新たにフェイスを作ることもできます。そのために、以下の関数が用意さ +れています。 + +@defun skk-make-face FACE + +形式: (skk-make-face FACE) + +この関数は、引数 FACE と同じ名前のフェイスを作成して、そのフェイスを返し +ます。フェイスの前景色・背景色は、引数 FACE にスラッシュを含めることよっ +て、例えば以下の例のように決定されます。 + +@lisp +(setq skk-henkan-face (skk-make-face 'DimGray/PeachPuff1)) +@end lisp + +この場合、前景色は DimGray に、背景色は PeachPuff1 になります。 + +もうひとつ例を挙げます。 + +@lisp +(setq skk-henkan-face (skk-make-face 'RosyBrown1)) +@end lisp + +この場合、前景色は RosyBrown1 になります。背景色が無指定の場合はバッファ +の背景色がそのまま見えます。 +@end defun + +@node 変換候補の更なる装飾 +@subsection 変換候補の更なる装飾 + +変換候補についてユーザの任意の加工を施すための変数を用意してあります。 + +@defvr {ユーザ変数} skk-treat-candidate-appearance-function + +この変数に適切な形式で関数を収めることによって、変換候補をユーザの任意に +加工することができます。「適切な形式」とは、次のとおりです。 + +@cartouche +@enumerate +@item +引数を2つ取ること。 + +@item +第1引数は文字列として扱うこと。これは加工前の文字列に相当する。 + +@item +第2引数が @code{nil} の時は通常の変換時、@code{non-nil} の時は候補一覧表 +示時を表すものとして扱うこと。 + +@item +返り値は次のいずれかとすること。 + +@table @samp +@item 文字列 + +この場合、この文字列は候補と注釈を両方含みうるものとして処理される。 + +@item (候補 . 注釈) + +この場合、候補はもう注釈を含まないものとして処理される。注釈については先 +頭が @samp{;} かどうかを調べた上で処理される。 + +@item (候補 . (セパレータ . 注釈)) + +この場合、候補はもう注釈を含まないものとして処理される。セパレータは通常 +の @samp{;} の代わりに利用される。注釈はもうセパレータを含まないものとして処 +理される。 +@end table + +@end enumerate +@end cartouche + +ファイル @file{etc/dot.skk} に設定例があるほか、サンプルとして関数 +@code{skk-treat-candidate-sample1} と @code{skk-treat-candidate-sample2} +を用意してあります。 +ファイル @file{~/.skk} に次のいずれかを書いてみて変換候補の装飾を試して +ください。 + +@lisp +(setq skk-treat-candidate-appearance-function + 'skk-treat-candidate-sample1) +@end lisp + +@lisp +(setq skk-treat-candidate-appearance-function + 'skk-treat-candidate-sample2) +@end lisp + +@end defvr + +@node モードラインの装飾 +@subsection モードラインの装飾 + +XEmacs 及び Emacs 21 以降では、以下の機能が使用できます。 + +@menu +* インジケータ:: +* アイコン:: +@end menu + +@node インジケータ +@subsubsection インジケータ + +@defvr {ユーザ変数} skk-indicator-use-cursor-color + +DDSKK のインジケータをモードラインの左に表示 +@footnote{デフォルトでは、左です。@w{@xref{起動と終了}.}} +している場合、インジケータの色がカーソルの色と同期します。 +インジケータに色を付けたくない場合は、この変数を @code{nil} にします。 + +@end defvr + +@xref{入力モードを示すカーソル色に関する設定}. + +インジケータに独自色を使いたい場合は、以下のフェイス@footnote{ +変数 @code{window-system} が @code{nil} の場合は、これらフェイスは未定義と +なります。} を設定します。この場合カーソルの色は参照されません。 + +Emacs 21 以上 @footnote{変数 @code{mule-version} の値が 5.0 以上の Emacs} の場合 + +@vindex skk-emacs-hiragana-face +@vindex skk-emacs-katakana-face +@vindex skk-emacs-jisx0208-latin-face +@vindex skk-emacs-jisx0201-face +@vindex skk-emacs-abbrev-face + +@itemize @bullet +@item @code{skk-emacs-hiragana-face} +@item @code{skk-emacs-katakana-face} +@item @code{skk-emacs-jisx0208-latin-face} +@item @code{skk-emacs-jisx0201-face} +@item @code{skk-emacs-abbrev-face} +@end itemize + +XEmacs の場合 + +@vindex skk-xemacs-hiragana-face +@vindex skk-xemacs-katakana-face +@vindex skk-xemacs-jisx0208-latin-face +@vindex skk-xemacs-latin-face +@vindex skk-xemacs-jisx0201-face +@vindex skk-xemacs-abbrev-face + +@itemize @bullet +@item @code{skk-xemacs-hiragana-face} +@item @code{skk-xemacs-katakana-face} +@item @code{skk-xemacs-jisx0208-latin-face} +@item @code{skk-xemacs-latin-face} +@item @code{skk-xemacs-jisx0201-face} +@item @code{skk-xemacs-abbrev-face} +@end itemize + +なお、インジケータを右クリックするとポップアップメニューが表示されます。 + +@node アイコン +@subsubsection アイコン +@cindex @file{skk-icon} + +@defvr {ユーザ変数} skk-show-icon + +変数 @code{skk-show-icon} の値を @code{non-nil} と設定することにより、モー +ドラインに SKK のアイコンが表示されます@footnote{@code{(image-type-available-p 'xpm)} が @code{t} を返す必要があるため、Emacsen の実行環境に依存します。}。 + +@end defvr + +@defvr {ユーザ変数} skk-icon + +アイコンの画像ファイル @file{skk.xpm} へのパス。 +関数 @code{skk-emacs-prepare-modeline-properties} で定義しています。 + +@end defvr + +@node ユーザガイダンス関連 +@section ユーザガイダンス関連 + +@menu +* エラーなどの日本語表示:: +* 冗長な案内メッセージの表示:: +@end menu + +@node エラーなどの日本語表示 +@subsection エラーなどの日本語表示 + +標準では、エラー、メッセージ及びミニバッファでのプロンプトは、英語で表示 +されます。 + +@defvr {ユーザ変数} skk-japanese-message-and-error + +この変数の値を @code{non-nil} に設定すると、エラー、メッセージ及びミニバ +ッファでのプロンプトを日本語で表示します。標準では @code{nil} です。 +@end defvr + +@defvr {ユーザ変数} skk-show-japanese-menu + +この変数の値を @code{non-nil} に設定すると、メニューバーを日本語で表示します。 +@end defvr + +@defvr {ユーザ変数} skk-version-codename-ja + +この変数の値を @code{non-nil} に設定すると、関数 @code{skk-version} を評価したと +きのコードネームを日本語で表示します。 + +@end defvr + +@node 冗長な案内メッセージの表示 +@subsection 冗長な案内メッセージの表示 + +@c http://mail.ring.gr.jp/skk/200704/msg00036.html +@defvr {ユーザ変数} skk-verbose + +この変数の値を @code{non-nil} に設定すると、入力中/変換中に冗長なメッセ +ージを表示します。 + +@lisp +(setq skk-verbose t) +@end lisp +@end defvr + +@table @asis +@item ▽モード + +ファンクションキー (@key{F1} 〜 @key{F10}) に割り当てられている機能を表示 +します。変数 @code{skk-verbose} の設定と同時に変数 @code{skk-j-mode-function-key-usage} を以下のように設定してみてください。 +@vindex skk-j-mode-function-key-usage + +@lisp +(setq skk-j-mode-function-key-usage 'conversion) +@end lisp + +@noindent +▽モードにおいてキー入力が一定時間 (標準では 1.5 秒) なされなかったとき、 +エコーエリアに以下のようなメッセージが表示されます。 + +@smallexample +@group +-------------------- Echo Area -------------------- +[F5]単漢字 [F6]無変換 [F7]カタカナ [F8]半角カナ [F9]全角ローマ [F10]ローマ +-------------------- Echo Area -------------------- +@end group +@end smallexample + +@noindent +この案内に従ってファンクションキーを押すことで、一時的に単漢字変換やカタ +カナ変換を行うことができます。 + +@item ▼モード + +Wikipedia アノテーション機能の使い方をメッセージで案内します。 +変数 @code{skk-verbose} の設定と同時に変数 @code{skk-show-annotation} を @code{non-nil} に設定してみてください。 +@vindex skk-show-annotation + +@lisp +(setq skk-show-annotation t) +@end lisp + +@noindent +▼モードにおいてキー入力が一定時間 (標準では 1.5 秒) なされなかったとき、 +エコーエリアに以下のようなメッセージが表示されます。 + +@smallexample +@group +-------------------- Echo Area -------------------- +@b{@{どれを参照?@}}[C-1 C-i]ja.wikipedia [C-2 C-i]en.wiktionary +[C-3 C-i]simple.wikipedia [C-4 C-i]en.wikipedia [C-5 C-i]ja.wiktionary +-------------------- Echo Area -------------------- +@end group +@end smallexample + +@noindent +この案内に従って、例えば @kbd{C-1 C-i} をタイプすると日本語 Wikipedia の該当記 +事を調べて、あればその一部をアノテーションとして表示します。 + +一方、現在の変換候補に対するアノテーションが既に表示されているときは、 +以下のメッセージが上記のものと交互に表示されます。 + +@smallexample +@group +-------------------- Echo Area -------------------- +@b{@{アノテーション@}}[C-w]コピー [C-o]URLブラウズ [C-i]デフォルトのソースを参照 +-------------------- Echo Area -------------------- +@end group +@end smallexample + +@noindent +この案内に従って @kbd{C-w} をタイプすればアノテーションの全文を kill ring に +保存して利用することができます。また @kbd{C-o} を押した場合には、もし現 +在のアノテーションが Wikipedia アノテーションであればその出典となる +Wikipedia/Wiktionary のページをウェブブラウザで表示します。 +@end table + +@defvr {ユーザ変数} skk-verbose-wait +冗長なメッセージを表示するまでの待ち時間 (秒)。標準は 1.5 秒です。 +@end defvr + +@defvr {ユーザ変数} skk-verbose-message-interval +冗長なメッセージが複数ある場合の1メッセージあたり表示時間を秒で指定する。 +標準は 5.0 秒です。 +この時間が経過したら表示を次の冗長なメッセージに切り替えます。 +@end defvr + +@defvr {ユーザ変数} skk-verbose-intention-face +「どれを参照?」と「アノテーション」に適用するフェイスです。 +@end defvr + +@defvr {ユーザ変数} skk-verbose-kbd-face +@samp{[F5]} や @samp{[C-1 C-i]} に適用するフェイスです。 +@end defvr + +@node I-search関連 +@section I-search関連 +@cindex I-search +@cindex Incremental search +@cindex @file{~/.skk} + +@menu +* 起動時の入力モードの指定:: +* 間に空白等を含む文字列の検索:: +@end menu + +@node 起動時の入力モードの指定 +@subsection 起動時の入力モードの指定 + +@defvr {ユーザ変数} skk-isearch-start-mode + +インクリメンタル・サーチを起動したときの入力モードをこの変数で指定できます。 +以下のいずれかのシンボルを指定できますが、変数 @code{skk-isearch-use-previous-mode} の +設定が優先されます。 + +@table @code + +@item nil +カレントバッファで SKK モードが起動されていれば、そのモードを。 +起動されていなければアスキーモード。 + +@item hiragana + +かなモード + +@item jisx0208-latin + +全英モード + +@item latin + +アスキーモード + +@end table + +@end defvr + +@defvr {ユーザ変数} skk-isearch-use-previous-mode + +この変数の値が @code{non-nil} であれば、次のインクリメンタル・サーチ起動 +時の入力モードは、前回のインクリメンタル・サーチでの入力モードになります。 +@code{nil} であれば、変数 @code{skk-isearch-start-mode} の設定が優先され +ます。 + +@end defvr + +@node 間に空白等を含む文字列の検索 +@subsection 間に空白等を含む文字列の検索 +@cindex Incremental regexp search + +@samp{検索} という文字列をインクリメンタル・サーチにより検索する場合に、 +バッファが以下のような状態になっていることがあります。 + +@example +@group +-------- Buffer: foo -------- +この行末から始まる文字列を検 +索して下さい。 +-------- Buffer: foo -------- +@end group +@end example + +このような場合のために、Emacs は正規表現によるインクリメンタル・サーチを +提供しています。DDSKK はこの正規表現によるインクリメンタル・サーチにも対 +応しているため、空白や改行を含んだ検索も可能です。 + +@table @kbd + +@item M-x isearch-forward-regexp + +@findex isearch-forward-regexp +@kindex M-x isearch-forward-regexp +@kindex C-u C-s +@kindex M-C-s + +前方への正規表現によるインクリメンタル・サーチ。 +@kbd{C-u C-s} または @kbd{M-C-s} で起動します。 + +@item M-x isearch-backward-regexp + +@findex isearch-backward-regexp +@kindex M-x isearch-backward-regexp +@kindex C-u C-r +@kindex M-C-r + +後方への正規表現によるインクリメンタル・サーチ。 +@kbd{C-u C-r} または @kbd{M-C-r} で起動します。 + +@end table + +@c 以下は空白や改行の処理を制御する変数です。 + +@defvr {ユーザ変数} skk-isearch-whitespace-regexp + +この変数の値は正規表現です。この正規表現にマッチする要素は「正規表現によ +るインクリメンタル・サーチにおいては、単語を区切る要素ではない」と判断さ +れます。この変数のデフォルトは以下のようになっています。 + +@example +"\\(\\s \\|[ \t\n\r\f]\\)*" +@end example + +この変数の値を変更することで、正規表現 +によるインクリメンタル・サーチを拡張することができます。例えば、電子メー +ルの引用部分を検索する場合を考えます。 + +@example +> 引用部分も検 +> 索できる。 +@end example + +上記のうち、「検索」という語は 2 行に渡っている上、引用マークが挿入さ +れています。ここで + +@lisp +(setq skk-isearch-whitespace-regexp "\\(\\s \\|[ \t\n\r\f<>|]\\)*") +@end lisp + +と設定することにより、「検索」を検索できるようになります。 + +@end defvr + +@node VIP/VIPERとの併用 +@section VIP/VIPERとの併用 +@cindex VIP +@cindex VIPER +@cindex @file{vip.el} +@cindex @file{viper.el} + +@defvr {ユーザ変数} skk-use-viper +@c XXX VIP 3.7 について言及する。 + +この変数の値を @code{non-nil} に設定すると、VIPER に対応します。 +@end defvr + +VIPER については @ref{Top, , VIPER, viper, VIPER Manual}. を参照してください。 + +また、VIPER の前身である VIP にも対応します。ただし、正式に対応している +バージョンは 3.5 のみです。これは Mule 2.3 に標準添付します +@footnote{ちなみに、VIP 3.5 の作者は、SKK の原作者でもある佐藤雅彦氏(京 +都大学名誉教授)です。VIP 3.5 の発展版である VIPER は現在もメンテナンスさ +れています。Emacs19, 20 には、VIP 、VIPER とも標準添付します。}。 + +@node picture-modeとの併用 +@section picture-modeとの併用 +@cindex @key{BS} +@cindex move-to-column +@cindex move-to-column-force +@cindex @file{picture.el} +@cindex picture-mode + +SKK モードを @code{picture-mode} において使用した場合は、以下のような問 +題点があります。ただし、これらは @code{picture-mode} の問題なので、現在 +のところ DDSKK 側では対処していません。 + +@enumerate +@item +SKK モードで全角文字を入力した場合に、@key{BS} で全角文字を消すことができ +ません。現状では、後方にある文字を消したい場合は、その文字にポイントを合 +わせ、@kbd{C-c C-d} で一文字ずつ消す必要があります。 + +@item +コマンド @code{picture-movement-up} や @code{picture-movement-down} によ +り上下に全角文字を挿入した場合に、桁がずれる場合があります。 +@end enumerate + +関数 @code{move-to-column-force} の中で使用されている関数 +@code{move-to-column} の引数として、全角文字を無視した桁数が与えられるこ +とがあり、そのときカーソル移動ができないため、これらの問題が生じます。 + +@node ローマ字入力以外の入力方式 +@chapter ローマ字入力以外の入力方式 + +DDSKK は、SKK 旧来のローマ字式かな入力 (訓令式、ヘボン式) 方式のほか、各 +種キー配列と入力方式に対応しています。 + +@menu +* AZIK:: +* ACT:: +* TUT-code:: +* かな入力と親指シフト:: +@end menu + +@node AZIK +@section AZIK +@cindex AZIK + +AZIK (エイズィック) は QWERTY 配列をベースとした拡張ローマ字入力です。 +一般のローマ字入力がそのまま使える上での拡張であることが特徴です。 + +@uref{http://hp.vector.co.jp/authors/VA002116/azik/azikindx.htm, 拡張ローマ字入力『AZIK』・『ACT』で快適な日本語入力を!} + +azik と skk で仕様が重なる部分があるため、@file{skk-azik.el} では以下のと +おり対応しています。 +@table @b +@item @kbd{q} + +AZIK では撥音「ん」を入力するには @kbd{q} を使うこととされていますが、skk で +は既に @kbd{q} に @code{skk-toggle-kana} を割り当てています。 + +そのため @file{skk-azik.el} では @code{skk-toggle-kana} の実行を +@itemize @bullet +@item 日本語キーボードであれば @kbd{@@} を、 +@item 英語キーボードであれば @kbd{[} を +@end itemize +それぞれ使用します。 + +@item @kbd{@@} + +上記のとおり、@code{skk-toggle-kana} の実行に +は @kbd{@@} (日本語キーボード) や @kbd{[} (英語キーボード) を使用しますが、 +skk では既に @kbd{@@} には「今日の日付の入力」(プログラム実行変換)を割 +り当てています。 + +そのため、skk 本来の動作には @kbd{x} を付けて、それぞれ @kbd{x@@} と、 +@kbd{x[} で代用できるようにしてあります。 + +@item @kbd{l} +@itemx @kbd{xx} + +AZIK では単独の拗音「ゃゅょぁぃぅぇぉゎ」を入力するには @kbd{l} を前置す +ることとされていますが、skk では既に @kbd{l} に「アスキーモードへの切り +替え」を割り当てています。 + +そのため @file{skk-azik.el} では、拗音のうち「ぁぃぅぇぉ」の入力について +は @kbd{xx} を前置することとしています。 + +@itemize @bullet +@item @kbd{xxa} @expansion{} ぁ +@item @kbd{xxi} @expansion{} ぃ +@item @kbd{xxu} @expansion{} ぅ +@item @kbd{xxe} @expansion{} ぇ +@item @kbd{xxo} @expansion{} ぉ +@end itemize + +なお、拗音のうち「ゃゅょゎ」の単独入力は、AZIK 拡張 @file{skk-azik.el} で +はなく、標準 @file{skk-vars.el} です。 +@itemize @bullet +@item @kbd{xya} @expansion{} ゃ +@item @kbd{xyu} @expansion{} ゅ +@item @kbd{xyo} @expansion{} ょ +@item @kbd{xwa} @expansion{} ゎ +@end itemize + +@item @kbd{X} +@itemx 誤った登録の削除 +skk では、▼モードでの @kbd{X} は 関数 @code{skk-purge-from-jisyo} を実行 +しますが、AZIK では X は「シャ行」の入力に使われます。 +そのため、@file{skk-azik.el} での「誤った登録の削除」は、 +▼モードで @kbd{M-x skk-purge-from-jisyo} を実行してください。 + +関連項目: @w{@ref{誤った登録の削除}} + +@end table + +@defvr {ユーザ変数} skk-use-azik + +この値が @code{non-nil} であれば AZIK 拡張が有効となります。 +@file{~/.skk} に + +@lisp +(setq skk-use-azik t) +@end lisp + +@noindent +と書きます。 + +@end defvr + +@defvr {ユーザ変数} skk-azik-keyboard-type + +AZIK で使うときのキーボードのタイプを、シンボルで指定する。 + +@itemize @bullet +@item @code{'jp106} @expansion{} 日本語 106 キーボード (デフォルト) +@item @code{'jp-pc98} @expansion{} NEC PC-98 キーボード +@item @code{'us101} @expansion{} 英語キーボード +@item @code{nil} @expansion{} キーボード依存処理を無効にする + +@end itemize +@end defvr + +@node ACT +@section ACT +@cindex ACT + +ACT は AZIK の考え方を Dvorak 配列に適用し、Dvorak 配列でかなを快適にタ +イプできるように考案された方式です。 + +@uref{http://www1.vecceed.ne.jp/~bemu/act/act_index.html, ACT (AZIK on Dvorak)} + +@defvr {ユーザ変数} skk-use-act + +この値が @code{non-nil} であれば ACT 拡張が有効となります。@file{~/.skk} +に + +@lisp +(setq skk-use-act t) +@end lisp + +@noindent +と書きます。 +@end defvr + +@node TUT-code +@section TUT-code +@cindex TUT-code + +TUT-code は 2 ストローク系の日本語直接入力方式の一つです。 + +@url{http://plone.crew.sfc.keio.ac.jp/groups/tut-code} + +使用するには、SKK のインストール時にいくつかのファイルをインストールする +必要があります。SKK ソースの @file{tut-code} ディレクトリにある +@file{skk-tutcdef.el} と @file{skk-tutcode.el} を、SKK ソースのトップディレクトリにコピーして、SKK のインストールを再度行います。 + +@xref{DDSKK のインストール}. + +その後、@file{~/.skk} に + +@lisp +(require 'skk-tutcdef) +@end lisp + +@noindent +と書きます。 + +@node かな入力と親指シフト +@section かな入力と親指シフト +@cindex かな入力 +@cindex 親指シフト +@cindex NICOLA + +DDSKK はローマ字式ではない、いわゆるかな入力方式をサポートします。具体的 +には + +@itemize @bullet +@item 旧 JIS 配列でのかな入力 +@item 親指シフト方式でのかな入力 +@end itemize + +@noindent +に対応しています。これを使うにはまず、nicola-ddskk 拡張パッケージをイン +ストールする必要があります。SKK ソースディレクトリの @file{nicola} ディ +レクトリに移動し、ドキュメントに従ってインストールしてください。 + +@url{https://github.com/skk-dev/ddskk/blob/master/nicola/README.ja} + +続いて設定をします。 + +@defvr {ユーザ変数} skk-use-kana-keyboard + +この変数を @code{non-nil} に設定すると、かな入力サポートが SKK 起動時に有効に +なります。 + +@lisp +(setq skk-use-kana-keyboard t) +@end lisp + +@end defvr + +@defvr {ユーザ変数} skk-kanagaki-keyboard-type + +この変数で、かな入力サポートの種類を切換えます。適切なシンボルを設定してください。 + +@table @samp +@item 106-jis + +日本語 106 キーボード (旧 JIS 配列) でのかな入力に対応します。 + +@lisp +(setq skk-kanagaki-keyboard-type '106-jis) +@end lisp + +@item nicola-jis + +日本語 106 キーボード (旧 JIS 配列) での親指シフトエミュレーションに対応 +します。 + +@lisp +(setq skk-kanagaki-keyboard-type 'nicola-jis) +@end lisp + +@item nicola-us + +@item nicola-dvorak + +@item nicola-colemak + +@item omelet-jis + +@code{nicola-jis} と同様ですが、より入力しやすい配列が考慮されています。 + +@lisp +(setq skk-kanagaki-keyboard-type 'omelet-jis) +@end lisp + +@item omelet-us + +@item omelet-dvorak + +@item omelet-colemak + +@item oasys + +@end table + +@end defvr + +かな入力方式使用時の■モードでは以下のコマンドなどが役に立ちます。 + +@table @kbd +@item F1 1 +@kindex F1 1 + +かな入力方式での特殊キー定義の一覧を表示します。 + +@item F1 2 +@kindex F1 2 + +かな入力方式でのかなキー配列を表示します。 + +@item F12 +@itemx M-x skk-kanagaki-toggle-rom-kana +@kindex F12 +@kindex M-x skk-kanagaki-toggle-rom-kana + +かな入力方式とローマ字入力方式とを切り換えます。 +@end table + +なお、親指シフト方式については @uref{http://nicola.sunicom.co.jp/, NICOLA 日本語入力コンソーシアム} が参考になります。 + +@node そのほかの拡張機能 +@chapter そのほかの拡張機能 + +十分にテストされていない等の理由がありますが、便利・有益と思われる拡張機 +能を紹介します。 + +@menu +* 交ぜ書き変換:: +@end menu + +@node 交ぜ書き変換 +@section 交ぜ書き変換 + +@file{skk-mazegaki.el} をインストールすると、交ぜ書き変換が可能となります。 + +@itemize @bullet +@item き車 @expansion{} 汽車 +@item き者 @expansion{} 記者 +@item き社 @expansion{} 貴社 +@end itemize + +インストール方法などは、次の投稿を参考にしてください。 + +@url{http://mail.ring.gr.jp/skk/201111/msg00037.html} + +@node SKKに関する情報 +@chapter SKKに関する情報 + +@menu +* 最新情報:: +* SKKメーリングリスト:: +* SKK関連ソフトウェア:: +* SKK辞書について:: +* 辞書ツール:: +* SKKの作者:: +* SKKの歴史:: +* このマニュアルについて:: +* 謝辞:: +@end menu + +@node 最新情報 +@section 最新情報 + +DDSKK についての最新情報は、 + +@display +@url{http://openlab.jp/skk/} +@end display + +@noindent +から得ることができます。 + +SKK の開発は、 GitHub を利用して行われています。 + +@display +@url{https://github.com/skk-dev/ddskk} +@end display + +最新版 DDSKK の変更内容と更に過去の変更点については以下のリソースを参照 +してください。 + +@display +@url{https://github.com/skk-dev/ddskk/blob/master/READMEs/NEWS.ja} +@end display + +また、将来のバージョンにおける拡張アイディアについては、TODO としてまと +められています。 + +@display +@url{https://github.com/skk-dev/ddskk/blob/master/READMEs/TODO.ja} +@end display + +SKK Openlab では、開発者、文章の整備にご協力いただける方、テスター、よろ +ずものを言う人などなど、常に募集しています。また要望、拡張の具体的アイディ +アがあれば、メーリングリストに連絡いただけることを期待します。 + +@display +@xref{SKKメーリングリスト}. +@end display + +@node SKKメーリングリスト +@section SKKメーリングリスト + +SKK Openlab メーリングリストは、統一された一つの ML です。利用者用、開発 +者用などと分かれていない他、SKK 辞書、DDSKK の開発議論が中心ですが、辞書 +サーバやフロントエンド、 SKK 辞書ツールの話題なども議論の範囲に入ります。 + +@table @asis +@item メーリングリストに参加する + +アドレス @email{skk-subscribe@@ring.gr.jp} 宛てに空のメールを送って下さい。 +確認の為のメッセージが指定されたアドレス宛に送信されます。その確認の為の +メッセージに対して返信することで加入手続きは終了します。 + +@item メーリングリストから脱会する + +アドレス @email{skk-unsubscribe@@ring.gr.jp} 宛てに空のメールを送って下さ +い。確認の為のメッセージが指定されたアドレス宛に送信されます。その確認の +為のメッセージに対して返信することで脱退手続きは終了します。 + +@item 登録したアドレスを変更する + +古いアドレスについていったん unsubscribe して、新しいアドレスから再度 +subscribe して下さい。 + +@item 記事の投稿 + +アドレス @email{skk@@ring.gr.jp} へ送ります。メーリングリストに登録されて +いる人全員にメールが配信されます。 + +@item 過去ログの閲覧 + +@url{http://mail.ring.gr.jp/skk} + +@url{news://news.ring.gr.jp/ring.openlab.skk} +@end table + +@node SKK関連ソフトウェア +@section SKK関連ソフトウェア + +SKK 関連ソフトウェアに関しては、次の URL にリンクをまとめてありますの +で参照してください。 + +@uref{http://openlab.jp/skk/wiki/wiki.cgi?page=%A5%EA%A5%F3%A5%AF%BD%B8, SKK 辞書 Wiki におけるリンク集} + +@node SKK辞書について +@section SKK辞書について + +SKK 辞書は多くのユーザの方々から提供された辞書によりコピーフリーの辞書と +しては最大規模の辞書になっています。今後もこの方式により SKK 辞書をより +充実したものにしていきたいと思います。 + +@url{http://openlab.jp/skk/registdic.cgi} にて Web/cgi を利用 +した登録・削除希望フォームを運用しています。 +SKK 辞書に追加したい単語、誤登録として削除したい単語がありましたら、 +是非ご利用下さい。 + +@node 辞書ツール +@section 辞書ツール + +SKK 辞書に関するツールには、Perl, C, Ruby の各言語により書かれたツールがありますが、Perl によるツールは現在十分メンテナンスされていません。 +現在は C, Ruby のツールが開発・メンテナンスされています。 + +@uref{http://openlab.jp/skk/wiki/wiki.cgi?page=%BC%AD%BD%F1%A5%E1%A5%F3%A5%C6%A5%CA%A5%F3%A5%B9%A5%C4%A1%BC%A5%EB, 辞書メンテナンスツール} + +@node SKKの作者 +@section SKKの作者 + +SKK の原作者は、現京都大学名誉教授の +@uref{http://www.ist.i.kyoto-u.ac.jp/organization/ex-professor.html#Sato, +佐藤雅彦氏}です。 + +現在の DDSKK は、大勢のボランティアの貢献により成立しています。 +ファイル @file{READMEs/Contributors} に貢献者名の一覧がありますので、ご覧ください。 + +@node SKKの歴史 +@section SKKの歴史 + +SKK の成り立ちと歴史に関しては以下の URL を参照してください。 + +@uref{http://openlab.jp/skk/born-ja.html, SKK の誕生秘話} + +@uref{http://openlab.jp/skk/SKK.html, ``SKK = I''} + +@uref{http://openlab.jp/skk/history-ja.html, SKK の歴史 (付 Emacs の歴史の一部)} + +@uref{http://mail.ring.gr.jp/skk/201212/msg00007.html, SKK の 25年} + +@node このマニュアルについて +@section このマニュアルについて + +本マニュアルは、SKK オープンラボの有志の貢献により、従来のマニュアルに加 +筆修正したものです。 + +@node 謝辞 +@section 謝辞 + +DDSKK の開発は、@uref{http://openlab.jp, Ring Server Open +Laboratory} (オープンラボラトリ) に @samp{SKK Openlab} として参加する形 +で行われています。@samp{SKK Openlab} は Ring から共有ディスク、CVS 及び +ML の提供を受けています。オープンラボラトリの運営は、完全にボランティア +により行われております。Ring 並びにオープンラボラトリにかかわる皆さんに +深く感謝いたします。 + +(以降の記載は、SKK の原作者、佐藤雅彦教授により記載された旧来のマニュア +ルのものですが、歴史的意義を踏まえて、そのまま掲載します。) + +SKK の設計方針は TAO/ELIS 上の日本語入力システム Kanzen の影響を受けてい +ます。Kanzen のデモを行ってくださり、また Kanzen を使う機会を与えてくだ +さった NTT の竹内郁雄さんに感謝します。 + +第 1 版の辞書作成のための読みの入力を行ってくださった東北大学電気通信研 +究所佐藤研究室の 安藤大君、猪岡美紀さん、奥川淳一君、佐々木昭彦君、佐藤 +克志君、山岸信寛君に感謝します。 + +SKK 辞書第 2, 3, 4, 5, 6, 7, 8 版作成のためのデータを提供してくださっ +た方々に感謝します。 + +SKK 辞書第 6, 7 版作成にあたり協力してくださった高橋裕信氏に感謝します。 + +@node よくある質問とその回答(FAQ) +@chapter よくある質問とその回答(FAQ) + +これは SKK に対するよくある質問と、それに対する回答集です。 + +@menu +* Introduction:: SKK のなぜなに。 +* Installation:: SKK の入手から導入まで。 +* Customization:: SKK の基本設定からお好みのカスタマイズまで。 +* Dictionaries:: SKK 辞書関連。 +* Miscellaneous:: SKK の活用法その他。 +@end menu + +@node Introduction +@section SKK のなぜなに + +@menu +* Q1-1 Daredevil SKK って SKK とは違うのですか?:: +* Q1-2 SKK はシンプルなのが長所だったのでは?:: +* Q1-3 DDSKK はどの Emacs で使えますか?:: +* Q1-4 DDSKK はどんなオペレーティングシステムで使えますか?:: +* Q1-5 APEL って何? 必要ですか?:: +@end menu + +@node Q1-1 Daredevil SKK って SKK とは違うのですか? +@unnumberedsubsec Q1-1 Daredevil SKK って SKK とは違うのですか? + +SKK Openlab で開発、リリースされる SKK は、京大の佐藤先生が中心になっ +て開発していた SKK と区別するために、@samp{Daredevil SKK} と呼ぶことに +しました。その略称は @samp{DDSKK} で、SKK Openlab で最初に +@samp{Daredevil SKK} としてリリースされた version は 11.1 です (オリジ +ナルの version を継承しました)。 + +なお、@samp{Daredevil} の名前の採択は、開発陣の一人が講読している某ラ +ジオ英会話講座の、ある日のスキット名が「Daredevil なんとか」で、その内 +容は「とにかくやってみよう。うぎゃぁぁぁ、やられたぁ」というものでした。 +これがあまりに自分の開発ポリシーに合致していた、ということに由来します。 + +@node Q1-2 SKK はシンプルなのが長所だったのでは? +@unnumberedsubsec Q1-2 SKK はシンプルなのが長所だったのでは? + +かような議論は 10 年来行われてきており、結論は出ていませんが、事実として +現在まで開発が続けられています。 + +@display +「シンプルな操作性の維持と多機能化・高機能化は両立できる」 +@end display + +@noindent +というのが現在の開発陣の考えであるようです。 + +SKK が Simple Kana to Kanji conversion program の略であるとおり、かなを漢 +字に変換するルーチンの簡単さが SKK を定義付けています。その周辺の拡張に +関する制約は基本的にはありません。 + +多機能化と言っても多くはユーザオプションによって無効にすることができま +すし、@file{skk.el} 本体が複雑化しないようにモジュール化されています。 + +@node Q1-3 DDSKK はどの Emacs で使えますか? +@unnumberedsubsec Q1-3 DDSKK はどの Emacs で使えますか? + +基本的には、GNU Emacs と Mule 機能付きの XEmacs で使えます。 + +対応する Emacs のバージョンについては以下をご覧ください。 + +@display +@xref{このバージョンのSKKについて}. +@end display + +@node Q1-4 DDSKK はどんなオペレーティングシステムで使えますか? +@unnumberedsubsec Q1-4 DDSKK はどんなオペレーティングシステムで使えますか? + +SKK がサポートしている Emacs がその OS で動いているなら、SKK の基本的 +な機能は動くはずです。 Microsoft Windows でも Apple OS X でも使えます。 + +拡張機能については、UNIX の各種コマンドを前提としているものがいくつか +あります (@command{look} や @command{ispell} など)。これらのコマンドがお使いの OS にも +存在すれば該当の拡張機能も基本的には使えるでしょう。 + +Apple OS X 版 Emacs に特化した情報については、以下のファイルを参照してください。 +@display +@url{https://github.com/skk-dev/ddskk/blob/master/READMEs/README.MacOSX.ja} +@end display + +@node Q1-5 APEL って何? 必要ですか? +@unnumberedsubsec Q1-5 APEL って何? 必要ですか? + +APEL は A Portable Emacs Library の略です。APEL の主な機能は異なる Emacs +間の非互換性を吸収することです。 + +XEmacs では APEL が必要です。 + +GNU Emacs 22 以上では APEL は不要となりました。この変更は 2010 年 9 月に CVS に commit され、2011 年 1 月に DDSKK 14.2 としてリリースされました。 + +@node Installation +@section SKK の入手から導入まで + +@menu +* Q2-1 SKK を使うのに何が必要ですか?:: +* Q2-2 SKK 辞書はどこにありますか?:: +* Q2-3 SKK サーバはどこにありますか?:: +@end menu + +@node Q2-1 SKK を使うのに何が必要ですか? +@unnumberedsubsec Q2-1 SKK を使うのに何が必要ですか? + +SKK 本体と SKK 辞書が必要です。オプションで辞書サーバを用意す +ることができます。 +XEmacs では事前に APEL をインストールしてください。 + +@display +@xref{XEmacs へのインストール}. +@end display + +SKK 本体は以下から入手できます。 + +@display +@url{http://openlab.jp/skk/maintrunk} +@end display + +@node Q2-2 SKK 辞書はどこにありますか? +@unnumberedsubsec Q2-2 SKK 辞書はどこにありますか? + +以下を参照してください。 + +@display +@xref{SKK辞書について}. +@end display + +@node Q2-3 SKK サーバはどこにありますか? +@unnumberedsubsec Q2-3 SKK サーバはどこにありますか? + +DDSKK は辞書サーバの種類、バージョンには依存していません。 + +@display +@url{http://openlab.jp/skk/skkserv-ja.html} +@end display + +@noindent +からお好きな辞書サーバを入手して下さい。 + +@node Customization +@section SKK の基本設定からお好みのカスタマイズまで + +@menu +* Q3-1 「.」、「,」 が入力できるようにカスタマイズしたいのですが。:: +* Q3-2 「ゐ」や「ヰ」 が入力できるようにカスタマイズしたいのですが。:: +* Q3-3 検索する辞書を増やしたいのですが。:: +* Q3-4 左手の小指を SHIFT で酷使したくありません。:: +* Q3-5 全く漢字が出てきません。:: +* Q3-6 チュートリアルが起動できません。:: +* Q3-7 C-x C-j で dired が起動してしまいます。:: +@end menu + +@node Q3-1 「.」、「,」 が入力できるようにカスタマイズしたいのですが。 +@unnumberedsubsec Q3-1 「.」、「,」 が入力できるようにカスタマイズしたいのですが。 + +3通りの方法を紹介します。 + +@enumerate +@item +通常 @samp{.} で「.」、@samp{,} で「,」を入力したい場合 + +@file{~/.skk} に以下を設定します。 + +@lisp +(setq skk-kutouten-type 'en) +@end lisp + +@item +一時的に @samp{.} で「.」、@samp{,} で「,」を入力したい場合 + +@kbd{M-x skk-toggle-kutouten} を実行すると、その場で「,」「.」に切り替える +ことができます。「、」「。」に戻すには、もう一度 +@kbd{M-x skk-toggle-kutouten} を実行を実行します。 +特定のバッファでのみ「,」「.」に切り替えたい場合は、 File Variables +(@pxref{File Variables, , File Variables, emacs, GNU Emacs Manual}) +を参照下さい。 +例えば、 tex モードでのみ「,」「.」に切り替えたい場合は、つぎの設定を +tex ファイルの最後に追加します。 + +@example +% Local Variables: +% skk-kutouten-type: en +% end: +@end example + +@item +常に @samp{.} で「.」、@samp{,} で「,」を入力したい場合 + +@code{skk-rom-kana-rule-list} を直接変更します。 +なお、この設定をすると、@kbd{M-x skk-toggle-kutouten} での切り替えが +効かなくなるので、注意して下さい。 + +@file{~/.skk} に以下を追加します。 + +@lisp +@group +(setq skk-rom-kana-rule-list + (append '(("." nil ".") ("," nil ",")) + skk-rom-kana-rule-list)) +@end group +@end lisp + +この設定方法は応用が効き、細かく制御することが可能です。 +@samp{.} と @samp{,} のところをそれぞれ、@samp{.} と @samp{,} とすることで、 +「かなモード」「カナモード」でも、@samp{.} と@samp{,} を直接入力することが +できます。 +@end enumerate + +@node Q3-2 「ゐ」や「ヰ」 が入力できるようにカスタマイズしたいのですが。 +@unnumberedsubsec Q3-2 「ゐ」や「ヰ」 が入力できるようにカスタマイズしたいのですが。 + +一つ前の Q の変形問題ですね。かな/カナモードでそれぞれ出力する文字 +を変えるやり方です。 + +@file{~/.skk} に + +@lisp +@group +(setq skk-rom-kana-rule-list + (append '(("wi" nil ("ヰ" . "ゐ"))) + skk-rom-kana-rule-list)) +@end group +@end lisp + +@noindent +と書いてみましょう。 + +一番内側の cons cell は car がカナモード、cdr がかなモー +ドでの入力文字を表しています。 + +一つ前の Q に対する答えのように、カナモード、かなモードともに入力す +る文字が変わらなければ、cons cell の代りに文字列を書くことができます。 + +@node Q3-3 検索する辞書を増やしたいのですが。 +@unnumberedsubsec Q3-3 検索する辞書を増やしたいのですが。 + +@code{skk-search-prog-list} で設定をしましょう。 +@vindex skk-search-prog-list + +まず、現在の設定を確認しましょうね。*scratch* バッファに +@code{skk-search-prog-list} と書いてそのシンボルの末尾にポイントを置いて +@kbd{C-j} してみましょう。例えば次のように出力されます。 + +@lisp +@group +((skk-search-jisyo-file skk-jisyo 0 t) + (skk-search-server skk-aux-large-jisyo 10000)) +@end group +@end lisp + +上記の例は 2 つの要素を持ったリストになっています。設定によりもっと多 +くの要素があるかもしれません。 + +各要素は検索する関数と辞書を指定したリストです。要素の順番に検索がなさ +れます。上記の例だとまず最初に @code{skk-jisyo} (個人辞書) を +@code{skk-search-jisyo} という関数を使ってリニアサーチ、次に +@code{skk-search-server} という関数を使って @code{skk-aux-large-jisyo} +をサーチします。 + +変換の際、@key{SPC} を押しますよね? 1 回 @key{SPC} を押すと、SKK は候 +補が見つかるまでの間、@code{skk-search-prog-list} の要素を前から読んでいっ +て検索を行い、見つかればそこでいったん検索を止めてユーザに候補を提示します。 + +ユーザが @key{SPC} を更に押してゆき最初の要素のプログラムが見つけた候補が尽 +きると、SKK は中断していた個所から再び @code{skk-search-prog-list} の次 +の要素を見つけ、ここで指定されている関数を使って検索する、で新しい候補が +見つかればまた提示する、というシステムになっています。 + +では、辞書サーバを使って検索した後に、JIS 第 2 水準の単漢字辞書、 +@file{SKK-JISYO.JIS2} を検索したい場合はどうすれば良いでしょう? もう分 +かりますよね? 辞書サーバを使った検索式の次に第 2 水準辞書の検索式を書いた +リストを @code{skk-search-prog-list} に指定すれば良いのです。 +@file{~/.skk} に次のように書きましょう。 + +@lisp +@group +(setq skk-search-prog-list + '((skk-search-jisyo-file skk-jisyo 0 t) + (skk-search-server skk-aux-large-jisyo 10000) + (skk-search-jisyo-file "~/dic/SKK-JISYO.JIS2" 0))) +@end group +@end lisp + +@code{skk-search-jisyo-file} の第 2 引数、0 の数字はリニアサーチにて検索 +するよう指定しています。第 2 水準辞書はあまり大きくないので、リニアサー +チで十分でしょう。大きな辞書を検索する場合などは、 + +@lisp +(skk-search-jisyo-file "~/dic/SKK-JISYO.L" 10000) +@end lisp + +@noindent +のようにすると良いでしょう。SKK は Emacs のバッファに読み込まれた +@file{~/dic/SKK-JISYO.L} の検索リージョンのポイント差が 10,000 未満にな +るまではバイナリサーチを行い、その後リニアサーチを行います。大きな辞 +書ではバイナリサーチを行う方がはるかに効率が良いです。嘘だと思うなら、 +@file{SKK-JISYO.L} を読み込んでリニアサーチするような設定にして試してみ +て下さい。 + +ちなみに、@file{SKK-JISYO.JIS2} は、最大でもリージョン間のポイント差が +8,500 程度です。 + +@node Q3-4 左手の小指を SHIFT で酷使したくありません。 +@unnumberedsubsec Q3-4 左手の小指を SHIFT で酷使したくありません。 + +SKK を標準の状態で使っている場合、変換のためにシフトキーを多用しますの +で小指への負担が大きくなります。 +@footnote{このため、ある人々は SKK を小指キラーと呼びます。} + +この苦しみを回避するためにここでは 4 つの方法を紹介します。 + +@enumerate +@item +親指の近くにあるキーを利用してシフトキーの代用とする。 + +日本語 106 キーボードのように無変換、変換などのキーがある場合は、これ +らをシフトキーの代用とすることが可能です。こうすると、例えば + +@display +@key{SHIFT} を押しながら @kbd{a} を押す +@end display + +@noindent +というキー操作は + +@display +@key{無変換} を押して、その後で @kbd{a} を押す +@end display + +@noindent +という操作で置き換えることができるようになります。 + +それでは具体的なやり方を説明しましょう。まず、使用中の Emacs が無変換 +キーを何という名前で認識しているか調べます。それには + +@example +@kbd{M-x describe-key} +@end example + +@noindent +というコマンドを実行し、続いて 無変換キーを押してみます。XFree86 上で +なら、おそらく + +@example +muhenkan is undefined +@end example + +@noindent +という答えが返ってくるでしょう。次に、この名前を使って @file{~/.emacs.d/init.el} +に設定を書きこみます。以下は @key{無変換} = @key{muhenkan} の場合の例で +す。 + +@lisp +@group +(unless (keymapp key-translation-map) + (setq key-translation-map (make-sparse-keymap))) + +(let ((i ?a)) + (while (<= i ?z) + (define-key key-translation-map + (vector 'muhenkan i) (vector (- i 32))) + (setq i (1+ i)))) +@end group +@end lisp +@vindex key-translation-map + +この設定を終えると、@kbd{@key{muhenkan}-a} で @kbd{A} が入力できるように +なります。続いて SKK を起動してみましょう。@kbd{@key{muhenkan}-a} で +@samp{▽あ} となります。送りの開始点も、もちろん同様の操作で指定できます。 +@footnote{変数 @code{key-translation-map} の意味を調べてみてください。 + +@kbd{M-x describe-variable} @key{RET} key-translation-map} + +@item +xmodmap を使う。 + +X Window System 上では、@command{xmodmap} というプログラムを使ってキー配列を変更で +きます。例えば、無変換キーをシフトキーとして使いたければ +@cindex xmodmap + +@example +% xmodmap -e 'add Shift = Muhenkan' +@end example + +@noindent +とします。これで無変換キーは通常のシフトキーと同じような感じで使えるよ +うになります。 + +@item +@file{skk-sticky.el} を使う。 + +@w{@xref{変換位置の指定方法}.} + +@item +親指シフト入力のエミュレーション機能を利用する。 +@cindex 親指シフト入力 + +これは 1, 2 とはかなり違ったアプローチです。SKK 本来のローマ字的入力を捨 +てて、富士通のワープロ OASYS のような親指シフト入力を修得します。 +@footnote{親指シフト入力の詳細については、ここでは述べません。興味がある +場合は、日本語入力コンソーシアムの Web サイト + +@display +@url{http://nicola.sunicom.co.jp/} +@end display + +@noindent +を訪れてください。} +@cindex OASYS +@cindex NICOLA +@cindex 日本語入力コンソーシアム + +DDSKK には NICOLA-DDSKK というプログラムが付属しており、これをインストー +ルすると親指シフト入力が可能になります。インストール自体は簡単で、 + +@example +% cd nicola +% make install +@end example + +@noindent +とした後に、@file{~/.skk} に + +@lisp +@group +(setq skk-use-kana-keyboard t) +(setq skk-kanagaki-keyboard-type 'omelet-jis) +@end group +@end lisp + +@noindent +と書くだけです。詳しいことは、NICOLA-DDSKK 付属のドキュメントを参照し +てください。 + +NICOLA 配列は、特別に日本語入力のために考えられた配列なので、慣れれば +非常に効率的な日本語入力ができるようになると期待されます。一方で、ロー +マ字的入力方式に慣れてしまっている人にとっては、NICOLA 配列に慣れるま +でかなり練習を要することは確かです。 +@end enumerate + +@node Q3-5 全く漢字が出てきません。 +@unnumberedsubsec Q3-5 全く漢字が出てきません。 + +恐らく辞書の設定ができていないのでしょう。 + +@file{SKK-JISYO.L} というファイルがインストールされている場所を確認して +ください。普通は + +@display +@file{/usr/local/share/skk} +@file{/usr/share/skk} +@end display + +@noindent +といった場所にインストールされています。XEmacs のパッケージならば + +@display +@file{/usr/local/lib/xemacs/mule-packages/etc/skk} +@end display + +@noindent +などを確認します。その後で @file{~/.skk} に + +@lisp +(setq skk-large-jisyo "/usr/local/share/skk/SKK-JISYO.L") +@end lisp + +@noindent +のように設定します。 + +なお、辞書サーバを使っている場合はこの設定は必要ありません。その場合は、 +辞書サーバの設定や、それがちゃんと起動しているかどうかを確認してくださ +い。 + +また、どこにも辞書がインストールされていない場合は + +@display +@url{http://openlab.jp/skk/dic/} +@end display + +@noindent +から取得します。 + +@node Q3-6 チュートリアルが起動できません。 +@unnumberedsubsec Q3-6 チュートリアルが起動できません。 +@cindex チュートリアル + +@file{SKK.tut} というファイルがインストールされている場所を確認してくだ +さい。普通は + +@display +@file{/usr/local/share/skk} +@file{/usr/share/skk} +@end display + +@noindent +といった場所にインストールされています。XEmacs のパッケージならば +@cindex パッケージ + +@display +@file{/usr/local/lib/xemacs/mule-packages/etc/skk} +@end display + +@noindent +などを確認します。その後で @file{~/.emacs.d/init.el} に + +@lisp +(setq skk-tut-file "/usr/local/share/skk/SKK.tut") +@end lisp +@vindex skk-tut-file + +@noindent +のように設定します。 + +@node Q3-7 C-x C-j で dired が起動してしまいます。 +@unnumberedsubsec Q3-7 C-x C-j で dired が起動してしまいます。 + +@code{dired-x} を読み込むと @kbd{C-x C-j} が @code{dired-jump} にバインドされます。 +この状態でも SKK を @kbd{C-x C-j} で起動したいときは、変数 @code{dired-bind-jump} に +@code{nil} を設定します。 + +@lisp +(setq dired-bind-jump nil) +@end lisp + +なお、この設定は @code{dired-x} を読み込む前である必要があります。 + +@node Dictionaries +@section SKK 辞書関連 + +@menu +* Q4-1 SKK には郵便番号辞書がありますか?:: +* Q4-2 SKK の辞書には、品詞情報がないんですね。:: +* Q4-3 複数の SKK 辞書を結合できますか?:: +* Q4-4 SKK 形式の英和辞書があると聞いたのですが。:: +@end menu + +@node Q4-1 SKK には郵便番号辞書がありますか? +@unnumberedsubsec Q4-1 SKK には郵便番号辞書がありますか? + +CVS から辞書を取得した場合は、@file{zipcode} というディレクトリに入って +います。WWW では、 + +@display +@url{http://openlab.jp/skk/dic/} +@end display + +@noindent +より入手できます。使用方法は + +@display +@url{http://openlab.jp/skk/skk/dic/zipcode/README.ja} +@end display + +@noindent +を御覧下さい。 + +@node Q4-2 SKK の辞書には、品詞情報がないんですね。 +@unnumberedsubsec Q4-2 SKK の辞書には、品詞情報がないんですね。 +@cindex 品詞情報 + +SKK は漢字とかなとの区切りをユーザが指定する方式により、品詞情報を使っ +た解析を用いることなく効率的入力ができます。 + +TODO としては、辞書に品詞情報を持たせることで更なる入力の効率化ができ +るという提案がなされており、そのような辞書の作成が既に試みられています。 +興味のある方は + +@display +@url{http://openlab.jp/skk/wiki/wiki.cgi?page=SKK%BC%AD%BD%F1} +@end display + +における @file{SKK-JISYO.notes} の項目をご覧ください。 + +@node Q4-3 複数の SKK 辞書を結合できますか? +@unnumberedsubsec Q4-3 複数の SKK 辞書を結合できますか? +@cindex 辞書のマージ + +SKK 本体のパッケージには同封されていませんが、skk-tools という別パッケー +ジがあります。以下をご覧ください。 + +@display +@xref{辞書ツール}. +@end display + +@node Q4-4 SKK 形式の英和辞書があると聞いたのですが。 +@unnumberedsubsec Q4-4 SKK 形式の英和辞書があると聞いたのですが。 +@cindex @file{edict2skk.awk} +@cindex @code{skkdic-expr} +@cindex @code{skkdic-sort} +@cindex edict +@cindex 英和辞書 + +edict は和英辞書ですが、これを SKK 辞書形式の英和辞書に変換したものを + +@display +@url{http://openlab.jp/skk/dic/SKK-JISYO.edict} +@end display + +@noindent +として置いています。これは edict を単純に機械的に変換した後、バグの修正 +や、エントリ・候補の追加が SKK Openlab で独自に行われているものです。 + +edict を自分で加工して上記と同等のものを作成することもできます。edict は + +@display +@url{ftp://ftp.u-aizu.ac.jp:/pub/SciEng/nihongo/ftp.cc.monash.edu.au/} +@end display + +@noindent +などから入手できます。 + +加工には日本語の通る @command{gawk} と skk-tools の中のプログラムを使い、下 +記のように行います。 + +@example +% jgawk -f edict2skk.awk edict > temp +% skkdic-expr temp | skkdic-sort > SKK-JISYO.E2J +% rm temp +@end example + +できた @file{SKK-JISYO.E2J} の利用方法は色々ありますが、 + +@example +% skkdic-expr SKK-JISYO.E2J + /usr/local/share/skk/SKK-JISYO.L | \ + skkdic-sort > SKK-JISYO.L +@end example + +@noindent +などとして、@file{SKK-JISYO.L} とマージして使うのが手軽です。 + +なお、edict の配布条件は GNU GPL (General Public License) ではありません。 + +@display +@url{http://www.csse.monash.edu.au/groups/edrdg/newlic.html} +@end display + +@noindent +をご覧下さい。@file{SKK-JISYO.edict} のヘッダー部分にもそのダイジェスト +が記載されています。 + +@node Miscellaneous +@section SKK の活用法その他 + +@menu +* Q5-1 SKK abbrev モードでもっと英単語を利用した変換ができませんか?:: +* Q5-2 市販の CD-ROM 辞書やネットワークの辞書サーバが利用できますか?:: +* Q5-3 他の FEP を使用中にも SHIFT を押してしまいます。:: +@end menu + +@node Q5-1 SKK abbrev モードでもっと英単語を利用した変換ができませんか? +@unnumberedsubsec Q5-1 SKK abbrev モードでもっと英単語を利用した変換ができませんか? +@cindex @code{look} +@cindex @file{skk-look.el} +@cindex edict +@cindex 英単語の検索 +@cindex 和英変換 +@kindex , +@kindex . +@vindex skk-look-expanded-word-only +@vindex skk-look-recursive-search +@vindex skk-look-use-ispell +@vindex skk-use-look + +UNIX @command{look} コマンドと @file{skk-look.el} を利用すると、色々できま +すよ。まず、 @file{~/.skk} で @code{skk-use-look} を @code{t} にセットして Emacs/SKK を立ち上げ直して下さい。 + +さぁ、下記のような芸当が可能になりました。 + +@enumerate +@item +英単語の補完ができます。 + +@example + ▽abstr(@key{TAB}) @expansion{} ▽abstract +@end example + +通常の補完機能と同様に @kbd{.} で次の補完候補に、@kbd{,} でひとつ前の補完候補 +に移動できます。SKK 形式の英和辞書があれば、ここから @key{SPC} を押して +英和変換ができますね。また、@code{skk-look-use-ispell} の値が +@code{non-nil} であれば、@command{look} で検索する前に @command{ispell} でス +ペルチェック・修正をします。 + +@item +英単語をあいまいに変換して取り出すことができます。上記同様、 +@code{skk-look-use-ispell} の値が @code{non-nil} であれば、@command{look} +で検索する前に @command{ispell} でスペルチェック・修正をします。 + +@example + ▽abstr* (@key{SPC}) @expansion{} ▼abstract +@end example + +見出し語に @samp{*} を入れるのをお忘れなく。 + +@item +あいまいに変換した後、更に再帰的な英和変換を行うことができます。 + +まず、@code{skk-look-recursive-search} の値を @code{non-nil} にセット +して下さい。Emacs/SKK を再起動する必要はありません。すると、例えば、 + +@example + ▽abstr* (@key{SPC}) + @expansion{} ▼abstract (@key{SPC}) + @expansion{} ▼アブストラクト (@key{SPC}) + @expansion{} ▼抽象 (@key{SPC}) + @expansion{} ▼abstraction (@key{SPC}) + @expansion{} ▼アブストラクション +@end example + +このように英単語 + その英単語を見出し語にした候補の「セット」を変換結果 +として出力することができます。 + +この際、@code{skk-look-expanded-word-only} の値が @code{non-nil} であ +れば、再帰検索に成功した英単語の「セット」だけを出力することができます +(再帰検索で検出されなかった英単語は無視して出力しません) 。 + +もちろん、SKK 辞書に + +@example + abstract /アブストラクト/抽象/ + abstraction /アブストラクション/ +@end example + +@noindent +というエントリがあることを前提としています。edict を SKK 辞書形式に変換 +すると良いですね。 +@end enumerate + +なお、@file{skk-look.el} を使った補完・変換が期待するスピードよりも遅 +い、補完・変換で余分な候補が出る、とお感じの貴方は、 +@code{skk-look-use-ispell} の値を @code{nil} にして @command{ispell} によ +るスペルチェック・修正をオフにしてお試し下さい。 + +@node Q5-2 市販の CD-ROM 辞書やネットワークの辞書サーバが利用できますか? +@unnumberedsubsec Q5-2 市販の CD-ROM 辞書やネットワークの辞書サーバが利用できますか? +@cindex @file{skk-lookup.el} +@cindex Lookup +@vindex skk-search-prog-list +@findex skk-lookup-search + +Lookup が扱える辞書はほとんど使えます。Lookup がインストールされている +状態で SKK をインストールすると、SKK と Lookup のゲートウェイプログラ +ム @file{skk-lookup.el} がインストールされます。 + +インストールで注意すべきは、@command{make} で呼び出される Emacs は +@option{-q -no-site-file} フラグ付きで呼ばれるので、@file{~/.emacs.d/init.el} や +@file{site-start.el} などは読み込まれないことです。デフォルトで +@code{load-path} の通っているディレクトリに lookup をインストールするか、 +@file{SKK-CFG} の中で @var{VERSION_SPECIFIC_LISPDIR} などにディレクトリ +を明示することで解決できます。 + +さぁ、@file{~/.skk} で @code{skk-search-prog-list} の +要素に @code{(skk-lookup-search)} を追加しましょう。他の検索エンジンより +も検索は比較的遅いので、最後の方が良いと思います。 + +こんな感じです。 + +@lisp +@group +(setq skk-search-prog-list + '((skk-search-jisyo-file skk-jisyo 0 t) + (skk-search-server skk-aux-large-jisyo 10000) + (skk-lookup-search))) +@end group +@end lisp + +Lookup については、 + +@display +@url{http://openlab.jp/edict/lookup/} +@end display + +@noindent +をご参照下さい。 + +@node Q5-3 他の FEP を使用中にも SHIFT を押してしまいます。 +@unnumberedsubsec Q5-3 他の FEP を使用中にも SHIFT を押してしまいます。 + +治すには SKK をやめるしかありません :-) + +Emacs 上以外でも SKK みたいな操作性を実現するソフトウェアがあります。 +@ref{SKK関連ソフトウェア} をご覧になってください。 + +@node 事項索引 +@unnumbered 事項索引 + +@printindex cp + +@node 変数索引 +@unnumbered 変数索引 + +@printindex vr + +@node 関数索引 +@unnumbered 関数索引 + +@printindex fn + +@node キー索引 +@unnumbered キー索引 + +@printindex ky + +@summarycontents +@contents +@bye + +@c Local Variables: +@c fill-column: 72 +@c skk-kutouten-type: jp +@c End: diff -Nru ddskk-16.2/doc/obsolete-doc/txi-ja.tex ddskk-16.2+0.20190423/doc/obsolete-doc/txi-ja.tex --- ddskk-16.2/doc/obsolete-doc/txi-ja.tex 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/obsolete-doc/txi-ja.tex 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,65 @@ +% txi-ja.tex -- adaptation to Japanese for texinfo.tex. +% This is read when a source document says @documentlanguage ja +% (which might happen after another @documentlanguage). +% +% Copyright 1999, 2007, 2008 Free Software Foundation. +% +% 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 3 of the License, 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 this program. If not, see . + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% for dvipdfmx + +\def\csdef#1{\expandafter\def\csname#1\endcsname} + +\gdef\usedvipdfmx{ + + \ifnum 42146=\euc"A4A2 \special{pdf:tounicode EUC-UCS2}\else + \special{pdf:tounicode 90ms-RKSJ-UCS2}\fi + + \global\pdfmakepagedesttrue + \gdef\pdfdest name##1 xyz{% + \iffinishedtitlepage\else + \special{pdf:dest (name##1) [\@thispage /XYZ \@xpos \@ypos]}% + \fi + } + + \gdef\dopdfoutline##1##2##3##4{% + \special{pdf:out [] ##2 << /Title (##1) /A << /S /GoTo /D (name##4) >> >> }% + } + + \gdef\entryaddpdfoutline##1##2{% + \global\cslet{orig##1}{##1}% + \csdef{##1}####1####2####3####4{% + \expandafter\empty\csname orig##1\endcsname{####1}{####2}{####3}{####4}% + \dopdfoutline{####1}{##2}{####3}{####4}% + } + } + + \entryaddpdfoutline{numchapentry}{1} + \entryaddpdfoutline{numsecentry}{2} + \entryaddpdfoutline{numsubsecentry}{3} + \entryaddpdfoutline{numsubsubsecentry}{4} + + \entryaddpdfoutline{unnchapentry}{1} + \entryaddpdfoutline{unnsecentry}{2} + \entryaddpdfoutline{unnsubsecentry}{3} + \entryaddpdfoutline{unnsubsubsecentry}{4} + + \entryaddpdfoutline{appentry}{1} + \let\appsecentry=\numsecentry + \let\appsubsecentry=\numsubsecentry + \let\appsubsubsecentry=\numsubsubsecentry + +} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff -Nru ddskk-16.2/doc/ox-texinfo+.el ddskk-16.2+0.20190423/doc/ox-texinfo+.el --- ddskk-16.2/doc/ox-texinfo+.el 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/ox-texinfo+.el 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,307 @@ +;;; ox-texinfo+.el --- add @deffn support to the Texinfo Back-End + +;; Copyright (C) 2012-2015 Free Software Foundation, Inc. +;; Copyright (C) 2015-2017 Jonas Bernoulli + +;; Author: Jonas Bernoulli +;; Package-Requires: ((dash "2.10.0") (org "8.3")) +;; Homepage: https://github.com/tarsius/ox-texinfo-plus +;; Keywords: outlines, hypermedia, calendar, wp + +;; This file is not part of GNU Emacs. + +;; This file 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 3, or (at your option) +;; any later version. + +;; This file 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. + +;; For a full copy of the GNU General Public License +;; see . + +;;; Commentary: + +;; This package patches the `texinfo' exporter defined in `ox-texinfo' +;; to support `@deffn' and similar definition items. To enable this +;; add: +;; +;; #+TEXINFO_DEFFN: t +;; +;; to your Org file. Then you can create definition items by writing +;; something that looks similar to how the corresponding items look in +;; Info, for example: +;; +;; - Command: magit-section-show +;; - Function: magit-git-exit-code &rest args +;; - Macro: magit-insert-section &rest args +;; - Variable: magit-display-buffer-noselect +;; - User Option: magit-display-buffer-function +;; - Key: q, magit-mode-bury-buffer +;; +;; As you might have guessed this package was written to be used by +;; Magit's manual. You might want to check that out. + +;; Additionally this package works around `ox-texinfo's misguided +;; handling of unnumbered vs. numbered sections. You might have +;; something like this in your Org file: +;; +;; #+OPTIONS: H:4 num:3 toc:2 +;; +;; This works as long as you have no level-4 sections. If you do, +;; then the use of `num:3' causes an error when exporting the `texi' +;; file to `info'. `num' cannot actually be used for its intended +;; purpose with this exporter, because otherwise it produces invalid +;; output. So it is useless, but to add insult to injury, it also +;; affects how links to sections look, i.e. it makes all links look +;; like: "Also see [1.2.3]" instead of the much more useful: "Also +;; see [Title of the section this links to].". + +;; To fix this this package defines the `TEXINFO_CLASS' `info+', which +;; is like `info' but for levels one through three it always uses the +;; numbered variant, even when `num' calls for the unnumbered variant: +;; +;; * level-1 => `@chapter' +;; ** level-2 => `@section' +;; *** level-3 => `@subsection' +;; **** level-4 => `@unnumberedsubsubsec' +;; +;; To enable to use this you need: +;; +;; #+TEXINFO_CLASS: info+ + +;; It's possible to force a level-4 section to get its own node +;; by setting its `:texinfo-node' property to `t', for example: +;; +;; **** Risk of Reverting Automatically +;; :PROPERTIES: +;; :texinfo-node: t +;; :END: + +;; This package hard-codes which sections get their own node and which +;; have to share it with their parent. Sections at levels one through +;; three get their own node, while those at level four don't. + +;; This package does not disable the effect `num' has on how links are +;; formatted, you have to explicitly set `num' to `nil' if you want to +;; use descriptive links, for example: +;; +;; #+OPTIONS: H:4 num:nil toc:2 + +;;; Code: + +(eval-and-compile + (require 'cl) + (require 'dash (expand-file-name "dash")) + (require 'ox-texinfo)) + +(setq org-texinfo-info-process '("makeinfo --no-split %f")) + +;;; Nodes and Sections + +(add-to-list 'org-texinfo-classes + '("info+" + "@documentencoding AUTO\n@documentlanguage AUTO" + ("@chapter %s" . "@chapter %s") + ("@section %s" . "@section %s") + ("@subsection %s" . "@subsection %s") + ("@subsubsection %s" . "@unnumberedsubsubsec %s"))) + +(let* ((exporter (org-export-get-backend 'texinfo)) + (options (org-export-backend-options exporter))) + (unless (assoc :texinfo-deffn options) + (setf (org-export-backend-options exporter) + (cons (list :texinfo-deffn "TEXINFO_DEFFN" nil nil t) + options)))) + +(defun org-texinfo-headline--nonode (fn headline contents info) + (let ((string (funcall fn headline contents info))) + (if (and (not (equal (org-element-property :TEXINFO-NODE headline) "t")) + (> (org-element-property :level headline) 3)) + (let ((n (string-match-p "\n" string))) + (substring string (1+ n))) + string))) +(advice-add 'org-texinfo-headline :around + 'org-texinfo-headline--nonode) + +(defun org-texinfo--menu-entries (scope info) + "List direct children in SCOPE needing a menu entry. +SCOPE is a headline or a full parse tree. INFO is a plist +holding contextual information." + (let* ((cache (or (plist-get info :texinfo-entries-cache) + (plist-get (plist-put info :texinfo-entries-cache + (make-hash-table :test #'eq)) + :texinfo-entries-cache))) + (cached-entries (gethash scope cache 'no-cache))) + (if (not (eq cached-entries 'no-cache)) cached-entries + (puthash + scope + (org-element-map (org-element-contents scope) 'headline + (lambda (h) + (and (or (equal (org-element-property :TEXINFO-NODE h) "t") + (and (not (> (org-element-property :level h) 3)) + (not (org-not-nil (org-element-property :COPYING h))) + (not (org-element-property :footnote-section-p h)) + (not (org-export-low-level-p h info)))) + h)) + info nil 'headline) + cache)))) + +;;; Definition Items + +(defun org-texinfo-plain-list--texinfo+ (fn plain-list contents info) + (if (equal (plist-get info :texinfo-deffn) "t") + (org-texinfo+plain-list plain-list contents info) + (funcall fn plain-list contents info))) +(advice-add 'org-texinfo-plain-list :around + 'org-texinfo-plain-list--texinfo+) + + +(defun org-texinfo-item--texinfo+ (fn item contents info) + (if (equal (plist-get info :texinfo-deffn) "t") + (org-texinfo+item item contents info) + (funcall fn item contents info))) +(advice-add 'org-texinfo-item :around + 'org-texinfo-item--texinfo+) + +(defconst org-texinfo+item-regexp + (format "\\`%s: \\(.*\\)\n" + (regexp-opt '("deffn" ; CATEGORY NAME ARGUMENTS + "Command" ; deffn Command NAME ARGUMENTS + "defun" "Function" ; NAME ARGUMENTS + "defmac" "Macro" ; NAME ARGUMENTS + "defspec" ; NAME ARGUMENTS + "defvr" ; CATEGORY NAME + "defvar" "Variable" ; NAME + "defopt" "User Option" ; NAME + "Face" ; NAME + "Key" ; KEY COMMAND + ) t))) + +(defun org-texinfo+get-list-type (item) + (plist-get (cadr (plist-get (cadr item) :parent)) :previous-list-type)) + +(defun org-texinfo+set-list-type (item value) + (let ((parent (plist-get (cadr item) :parent))) + (setf (cadr parent) + (plist-put (cadr parent) :previous-list-type value)))) + +(defun org-texinfo+maybe-begin-list (this type) + (prog1 (pcase (list (org-texinfo+get-list-type this) type) + (`(list table) "@end itemize\n\n@table @asis\n") + (`(,(or `nil `single) table) "@table @asis\n") + (`(table list) "@end table\n\n@itemize\n") + (`(,(or `nil `single) list) "@itemize\n")) + (org-texinfo+set-list-type this type))) + +(defun org-texinfo+maybe-end-list (this type) + (prog1 (pcase (list (if (eq (car this) 'item) + (org-texinfo+get-list-type this) + (plist-get (cadr this) :previous-list-type)) + type) + (`(list ,_) "@end itemize\n\n") + (`(table ,_) "@end table\n\n")) + (org-texinfo+set-list-type this type))) + +(defun org-texinfo+plain-list (plain-list contents info) + (concat contents (org-texinfo+maybe-end-list plain-list nil))) + +(defun org-texinfo+item (item contents info) + (if (let ((case-fold-search nil)) + (string-match org-texinfo+item-regexp contents)) + (pcase (match-string 1 contents) + ("Face" (org-texinfo+face-item item contents info)) + ("Key" (org-texinfo+key-item item contents info)) + (_ (org-texinfo+def-item item contents info))) + (let* ((plain-list (plist-get (cadr item) :parent)) + (attr (org-export-read-attribute :attr_texinfo plain-list)) + (indic (or (plist-get attr :indic) + (plist-get info :texinfo-def-table-markup))) + (table-type (plist-get attr :table-type)) + (type (org-element-property :type plain-list)) + (list-type (cond + ((eq type 'ordered) "enumerate") + ((eq type 'unordered) "itemize") + ((member table-type '("ftable" "vtable")) table-type) + (t "table")))) + (concat (--when-let (org-texinfo+maybe-begin-list + item (if (equal type "table") 'table 'list)) + (concat (substring it 0 -1) + (and (eq type 'descriptive) (concat " " indic)))) + "\n@item\n" + (--when-let (org-element-property :tag item) + (concat " " (org-export-data it info))) + contents)))) + +(defun org-texinfo+face-item (item contents info) + (concat (org-texinfo+maybe-begin-list item 'table) + (format "@item @w{ }--- Face: %s\n%s" + (match-string 2 contents) + (substring contents (match-end 0))))) + +(defun org-texinfo+key-item (item contents info) + (concat (org-texinfo+maybe-begin-list item 'table) + (let ((head (match-string 2 contents)) + (body (substring contents (match-end 0)))) + (if (string-match ", " head) + (let ((key (substring head 0 (match-beginning 0))) + (cmd (substring head (match-end 0)))) + (format "\ +@kindex %s +@cindex %s +@item @kbd{%s} @tie{}@tie{}@tie{}@tie{}(@code{%s}) +%s" key cmd key cmd body)) + (error "Bad Key item %s" head))))) + +(defun org-texinfo+def-item (item contents info) + (let ((type (match-string 1 contents)) + (head (match-string 2 contents)) + (body (substring contents (match-end 0))) + (prefix "")) + (pcase type + ("Command" + (setq prefix (format "@cindex %s\n" head)) + (setq type "deffn") + (setq head (concat "Command " head))) + ("Function" (setq type "defun")) + ("Macro" (setq type "defmac")) + ("Variable" (setq type "defvar")) + ("User Option" (setq type "defopt"))) + (format "%s%s@%s %s\n%s@end %s\n\n" + (or (org-texinfo+maybe-end-list item 'single) "") + prefix type head body type))) + +;;; Advices for `ox.el'. + +(defun ox-texinfo+--disable-indent-tabs-mode + (fn backend file-or-buffer + &optional async subtreep visible-only body-only ext-plist post-process) + (let ((saved-indent-tabs-mode (default-value 'indent-tabs-mode))) + (when (equal backend 'texinfo) + (setq-default indent-tabs-mode nil)) + (unwind-protect + (funcall fn backend file-or-buffer + async subtreep visible-only body-only ext-plist post-process) + (setq-default indent-tabs-mode saved-indent-tabs-mode)))) + +(advice-add 'org-export-to-file :around 'ox-texinfo+--disable-indent-tabs-mode) +(advice-add 'org-export-to-buffer :around 'ox-texinfo+--disable-indent-tabs-mode) + +;;; Redefine `org-texinfo-example-block'. + +(defun org-texinfo-example-block (example-block _contents info) + "Transcode an EXAMPLE-BLOCK element from Org to Texinfo. +CONTENTS is nil. INFO is a plist holding contextual +information." + (format "@example\n%s@end example" + (org-export-format-code-default example-block info))) + +;;; ox-texinfo+.el ends soon +(provide 'ox-texinfo+) +;; Local Variables: +;; indent-tabs-mode: nil +;; End: +;;; ox-texinfo+.el ends here diff -Nru ddskk-16.2/doc/README.org ddskk-16.2+0.20190423/doc/README.org --- ddskk-16.2/doc/README.org 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/README.org 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,297 @@ +#+STARTUP: showeverything + +* SKK Manual の texinfo 形式から org 形式への移行 + +** きっかけ + +SKK Manual は、長らく texinfo 形式 (ファイル名 ~skk.texi~) で保守されてき +たところです。 ~skk.texi~ から html 版を生成するためには ~texi2html~ や ~texi2any~ な +どといったアプリケーションを利用する必要があり、実行プラットフォームやバ +ージョンによって生成される html が異なる場合が生じるなど、運用が難しくなっ +てききました。 + +そこで、 ~skk.texi~ を org 形式 (ファイル名 ~skk.org~) へ全面移行することとし、 +2017.6.30 に git push しました。 + +** doc/ ディレクトリ + +- ~ChangeLog~ + + org 移行前から存在します。 + +- ~README.org~ + + このファイルです。 + +- ~obsolete-doc/~ + + + ~makepdf.bat~ + + ファイル中のコメント参照のこと + + + ~makepdf.sh~ + + ファイル中のコメント参照のこと + + + ~txi-ja.tex~ + + ~makepdf.{bat|sh}~ で「しおり付きPDF」を生成するためのもの + + + ~obsolete-skk.texi~ + + 従前から保守していた skk.texi です。今後は保守しません。 + +- ~ox-texinfo+.el~ + + org 標準の ox-texinfo.el を機能拡張するものです。 + + https://github.com/tarsius/ox-texinfo-plus (GNU GPL v3) + +- ~dash.el~ + + ~ox-texinfo+.el~ が必要とします。 + + https://github.com/magnars/dash.el (GNU GPL v3) + +- ~htmlize.el~ (v1.43) + + `make html' 実行時に org が必要とします。 + + http://orgmode.org/cgit.cgi/org-mode.git/tree/contrib/lisp/htmlize.el から取得しました。 + (GNU GPL v2) + +- ~skk.css~ + + 生成された ~skk.html~ を装飾するものです。 + +- ~skk.org~ + + 従前の ~skk.texi~ を全面的に書き換えたものであり、今後保守するマニュアルです。 + +- ~skk.texi~ + + ~skk.org~ を基に `make texi', `make info' 又は `make pdf' の過程で自動 + 生成されるものです。 Melpa インストール時には必須であるため、git リポジ + トリに含める必要があります。そのため、 ~skk.org~ 編集後は必ず `make texi' を + 実行してから ~git push~ すること。 + +- ~texinfo-ja.tex~ + + `make pdf' 実行時に texi2pdf が読み込みます。 + + http://www.trueroad.jp/2016/05/14-01.html から取得しました。 (GNU GPL v3) + +- ~texinfo.tex~ + + `make pdf' 実行時に texi2pdf が読み込みます。 + + http://www.trueroad.jp/2016/05/14-01.html から取得しました。 (GNU GPL v3) + +- ~txi-ja.tex~ + + `make pdf' 実行時に ~texi2pdf~ が読み込みます。 + + http://www.trueroad.jp/2016/05/14-01.html から取得しました。 (GNU GPL v3) + +- ~mobi.xsl~ + + `make mobi' 実行時に ~dbtoepub~ が読み込みます。 + + https://kanru.info/blog/archives/2010/11/18/convert-texinfo-to-mobi/ から取得しました。 + + ファイル冒頭にライセンスが記載されており、再配布可能なようですので含めました。 + +** skk.org の運用方法 + +*** 外観 + +#+BEGIN_EXAMPLE + --------- + obsolete-skk.texi ※ 旧 skk.texi です。 + --------- + + ========= Emacs のバージョンと同梱版 org-mode のバージョン + skk.org e23. ?.? + ========= e24.5 o8.2.10 + │ │ e25.2 o8.2.10 + │ │ e26.0.50 o9.0.9 + │ │ + │ │make html ( SKK-MK-export-to-html ) + │ │ o 索引を生成することはできない? + │ │ + │ =↓======= + │ skk.html ---> www 公開など + │ ========== + │ + │make texi ( SKK-MK-export-to-texinfo ) + │ * org export の拡張 ox-texinfo+.el を利用 [ https://github.com/tarsius/ox-texinfo-plus ] + │ * ox-texinfo+.el は dash.el 必須 [ https://github.com/magnars/dash.el ] + │ + │ なお、 C-c C-e i t はサポートしない。必ず make texi であること。 + │ + =↓============= + skk.texi + ================ + │ │ │ + │ │ │make info ( SKK-MK-compile-info ) + │ │ │ 注) M-x org-texinfo-export-to-info で org から info へ変換する + │ │ │ こともできるが、内部で /usr/bin/makeinfo コマンドを呼び出す + │ │ =↓======= ため window では実行できない。 + │ │ skk.info なお、make info ( SKK-MK-compile-info() ) は emacs-lisp で + │ │ ========== 完結している。 + │ │ + │ │make pdf ( texi2pdf, luatex ) + │ │ * texinfo-ja.tex [ http://www.trueroad.jp/2016/05/14-01.html ] + │ │ * texinfo.tex [ http://www.trueroad.jp/2016/05/14-01.html ] + │ │ * txi-ja.tex [ http://www.trueroad.jp/2016/05/14-01.html ] + │ │ + │ │ なお、 org-latex-export-to-pdf [C-c C-e l p] はサポートしない。 + │ │ + │ =↓====== + │ skk.pdf + │ ========= + │ + │make mobi ( makeinfo, dbtoepub, kindlegen ) + │ * mobi.xsl [ https://kanru.info/blog/archives/2010/11/18/convert-texinfo-to-mobi/ ] + │ * kindlegen [ https://www.amazon.com/gp/feature.html?docId=1000765211 ] + =↓======= + skk.mobi + ========== +#+END_EXAMPLE + +*** info + +#+BEGIN_SRC shell-script + ddskk-src]$ make info + ddskk-src]$ su + ddskk-src]# make install-info +#+END_SRC + +*** html + +#+BEGIN_SRC shell-script + ddskk-src]$ make html +#+END_SRC + +*** pdf + +#+BEGIN_SRC shell-script + ddskk-src]$ make pdf +#+END_SRC + +*** mobi (for Amazon Kindle 端末) + +#+BEGIN_SRC shell-script + ddskk-src]$ make mobi +#+END_SRC + +*** git リポジトリの運用 + +ファイル ~skk.org~ は正式マニュアルであり、当然に git リポジトリに含めます。 + +パッケージインストール melpa で ~skk.texi~ が必要となるため ~skk.org~ か +ら生成される ~skk.texi~ も git リポジトリに含める必要があります。すなわち、 +~skk.org~ を編集したら ~make texi~ を実行して (~skk.texi~ を再生成して) +git push してください。 + +なお、 ~skk.info~ 、 ~skk.html~ 及び ~skk.pdf~ は、ユーザがローカルで生成 +するものですので *git リポジトリに含めてはいけません* 。 + +** texi から org への移行作業で判明したこと + +- インライン形式の footnote は使わないこと + + github 上のレンダリングで脚注にならないので読みづらい。 + +- ~#+BEGIN_VERSE ... #+END_VERSE~ は使わないこと + + github 上でレンダリングされない。 + +- ~.~ は @code{.} に変換されるのに、 ~,~ は @code{,} に変換されず ~,~ の + まま出力されてしまう。 + +- org 上の下線 _STRING_ は、texinfo への export で全欠落する。 + +- 「footnote の中での箇条書きリスト」を export した texi は、tex でエラーとなる。 + +- org のマクロ展開が分からない。 + + export の際、本文中の {{{version}}} は上手く展開されているが、 + + 等幅 = ... = の中の {{{version}}} + は展開されない [fn:version] 。 + +- #+TEXINFO_DIR_CATEGORY: はひとつしか効かない? + + オリジナル ~skk.texi~ にはふたつの ~@dircategory~ がある。 + - ~@dircategory Emacs~ + - ~@dircategory GNU Emacs Lisp~ + + ~skk.org~ にふたつの ~#+TEXINFO_DIR_CATEGORY:~ を記載しても、 + ~org-texinfo-export-to-texinfo~ で生成される ~skk.texi~ にはひとつしか出力 + されない。 + +- url エンコードがそのまま export されない + + ~skk.org~ に記載した url は http://openlab.jp/skk/wiki/wiki.cgi?page=SKK%BC%AD%BD%F1 + export すると http://openlab.jp/skk/wiki/wiki.cgi?page=SKK%C2%BC%C2%AD%C2%BD%C3%B1 + と変換されてしまう。 + +- リンク + + 生成される種類 (html, info, pdf) によって見栄えが異なる。 + + + http リンク + + 日本語文脈の間に挿入しても不自然ではない。 + + | org | [[http://git.chise.org/elisp/apel/][APEL]] | + | html | APEL | + | texi | @uref{http://git.chise.org/elisp/apel/, APEL} | + | info | APEL (http://git.chise.org/elisp/apel/) | + | pdf | APEL (http://git.chise.org/elisp/apel/) | + + + 内部リンク + + info と pdf の見栄えを考慮すると、日本語文脈の間に挿入してしまっては不自然であるため、 + footnote 化が望ましいか。 + + | org | [[チュートリアル][チュートリアル]] | 付属の チュートリアル が | + | html | チュートリアル | 付属の チュートリアル が | + | texi | @ref{チュートリアル} | | + | info | see チュートリアル | 付属の see チュートリアル が | + | pdf | Section 4.5 [チュートリアル], p. 22 | 付属の Section 4.5 [チュートリアル], 22ページ が | + + + Info リンク + + 内部リンクと同様に footnote 化が望ましいか。 + PDF は、それが info であると見た目分かりづらい。しかもクリッカブル。 + + | org | [[info:emacs#Auto Fill][Auto Fill Mode in GNU Emacs Manual]] | + | html | Auto Fill Mode in GNU Emacs Manual | + | texi | @ref{Auto Fill,Auto Fill Mode in GNU Emacs Manual,,emacs,} | + | info | see Auto Fill Mode in GNU Emacs Manual(emacs) | + | pdf | Section “Auto Fill” in emacs | + +** 将来 + +今回は org 形式を選択しましたが、更なる将来には他の形式への移行も考えられ +ます。 + +- markdown 形式 + + github の標準形式として採用されているなど、今後も広い普及が見込まれます。 + +- reStructuredText 形式 + + reStructuredText 形式で作成すれば、 [[http://www.sphinx-doc.org][Sphinx]] を + 利用して多様な形式へ変換できる。 + +* Footnotes + +[fn:version] GNU Emacs 26 未満で標準同梱の Org mode 8.2.10 では #+SUBTITLE: の +中の {{{version}}} も展開されない。GNU Emacs 26 以降で標準同梱の Org mode 9 で +は展開される。 + +# Local Variables: +# buffer-invisibility-spec: nil +# End: diff -Nru ddskk-16.2/doc/skk.css ddskk-16.2+0.20190423/doc/skk.css --- ddskk-16.2/doc/skk.css 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/skk.css 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,97 @@ +/* -*- mode: css; coding: utf-8 -*- */ + +html { + scroll-behavior: smooth; /* Firefox は効く */ +} + +#table-of-contents { + position: fixed; + right: 0em; + top: 0em; + font-size: small; + background: #F2F2F2; + border-radius: 1em; + padding: 0 0.5em 0 0.5em; + max-height: 80%; + overflow: auto; + z-index: 200; +} + +#table-of-contents #text-table-of-contents { + display: none; +} + +#table-of-contents:hover #text-table-of-contents { + display: block; +} + +h2, h3, h4, h5 { + padding: 0.2em; + color: white; +} + +h2 { + background-color: #00b300; +} + +#table-of-contents h2 { + color: black; + background-color: #F2F2F2; +} + +h3 { + background-color: #009900; +} + +h4 { + background-color: #008000; +} + +h5 { + background-color: #006600; + font-size: medium; +} + +p { + line-height: 1.5em; +} + +li { + line-height: 1.5em; +} + +pre { + background: #EEE; +} + +code { + font-weight: bold; + background: Gainsboro; + padding: 0 0.2em 0 0.2em; +} + +code.symbol { + background: none; +} + +.KEY, .key { + padding: 0.1em 0.2em 0.1em 0.2em; + border: 1px solid black; + border-radius: 5px; +} + +a.footref { + text-decoration: none; + padding: 0 0.2em 0 0.2em; + border: 1px dashed red; + border-radius: 3px; +} + +a { + transition: background-color 0.2s; +} + +a:hover { + background-color: salmon; +} + diff -Nru ddskk-16.2/doc/skk.org ddskk-16.2+0.20190423/doc/skk.org --- ddskk-16.2/doc/skk.org 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/skk.org 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,9274 @@ +#+TITLE: SKK Manual +#+AUTHOR: +#+EMAIL: +#+DATE: 2017 +#+LANGUAGE: ja + +# ### このファイル (skk.org) を編集する方へ ### +# - skk.org 編集した場合は、info, html 及び pdf への反映度合いを必ず確認してください。 +# - make info を実行して skk.info が正しく生成されているか確認 +# - make html を実行して skk.html が正しく生成されているか確認 +# - makepdf を実行して skk.pdf が正しく生成されているか確認 + +# - 編集の際は M-x visible-mode が分かりやすいと思われます。 + +#+HTML_DOCTYPE: html5 +#+HTML_HEAD: + +#+TEXINFO_DIR_CATEGORY: Emacs +#+TEXINFO_DIR_TITLE: SKK: (skk) +#+TEXINFO_DIR_DESC: Simple Kana to Kanji conversion program. + +#+MACRO: version 16.2.50 +#+SUBTITLE: This edition is for SKK version {{{version}}} +#+SUBTITLE: Date 2017.07.07 21:11:51 + +# ### Use ox-texinfo+.el ### +#+TEXINFO_DEFFN: t +#+TEXINFO_CLASS: info+ +#+OPTIONS: H:5 num:4 toc:2 + +#+TEXINFO_HEADER: @paragraphindent 1 + +#+TEXINFO_POST_HEADER: @synindex pg cp +#+TEXINFO_POST_HEADER: @footnotestyle end +#+TEXINFO_POST_HEADER: @iftex +#+TEXINFO_POST_HEADER: @afourpaper +#+TEXINFO_POST_HEADER: @end iftex + +# *Copying から *はじめに までが @copying .. @end copying で囲まれて、 +# @titlepage +# @title SKK Manual +# @subtitle This edition is for SKK version ... +# @subtitle Date ... +# @insertcopying <---- ここに挿入される +# @end titlepage + +* Copying +:PROPERTIES: +:COPYING: t +:END: + +#+TEXINFO: @sp 10 + +# The following two commands start the copyright page. +# #+TEXINFO: @page # ox-texinfo が自動生成 +# #+TEXINFO: @vskip 0pt plus 1filll # するのでコメント化 + +#+BEGIN_EXPORT texinfo +@ifinfo +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries a copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). +@end ignore + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation approved +by the author. +@end ifinfo +#+END_EXPORT + +Copyright @@texinfo:@copyright{}@@ 1991-2007 Masahiko Sato(佐藤雅彦), +Yukiyoshi Kameyama(亀山幸義), NAKAJIMA Mikio(中島幹夫), +IRIE Tetsuya(入江), Kitamoto Tsuyoshi(北本剛), +Teika Kazura(定家), Tsukamoto Tetsuo(塚本徹雄) +and Tsuyoshi AKIHO(秋保強). +Revised by Kiyotaka Sakai(酒井清隆) and Satoshi Harauchi(原内聡). + +#+BEGIN_QUOTE +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation +approved by the author. +#+END_QUOTE + +* はじめに + +** このバージョンの SKK について + +Daredevil SKK (以下、このマニュアルにおいて DDSKK と呼びます。)は、動作 +が早くて効率的な日本語入力環境を提供するソフトウェアです。 + +GNU General Public License に基づいて配布されているフリー・ソフトウェアで +す。DDSKK {{{version}}} が動作すると思われる Emacsen のバージョンは、次の +とおりです。 + +- GNU Emacs 23.1 以降 +- GNU Emacs 24.1 以降 +- GNU Emacs 25.1 以降 +- Mule 機能付きでコンパイルされた XEmacs 21.4 の最新版 +- Mule 機能付きでコンパイルされた XEmacs 21.5 の最新版 + +XEmacs に関しては、XEmacs 本体とは別に配布されているパッケージ群は最新版 +が要求されます。少なくとも ~xemacs-base~ パッケージが最新であることに加え +て ~fsf-compat~ パッケージが必須です。 + +総論として、現在は XEmacs よりも GNU Emacs での動作がよくテストされており、 +最近では XEmacs でのテストは充分行われていません。GNU Emacs 23 以上での利 +用が最も推奨されます。 + +現時点で Emacs のバージョンごとに少なくとも以下の制限があります。 + +- GNU Emacs 20.x + + DDSKK 14.2 以降は GNU Emacs 20 はサポート対象外です。GNU Emacs 20 のユ + ーザは DDSKK 14.1 をお使いください。 + +- GNU Emacs 21.4 + + DDSKK 15.1 以降は GNU Emacs 21 はサポート対象外です。GNU Emacs 21 のユ + ーザは DDSKK 14.4 をお使いください。 + +- GNU Emacs 22.3 + + DDSKK 16.2 以降は GNU Emacs 22 はサポート対象外です。GNU Emacs 22 のユ + ーザは DDSKK 16.1 をお使いください。 + +- GNU Emacs 23.3 + + - X Window System 上でのメニューバーの日本語表示は GTK 対応版のみです。 + - MELPA を利用してインストールするには、先に ~package.el~ をインスト + ールする必要があります。 + +- GNU Emacs 24.3 + + GNU Emacs 24.3 と DDSKK 14 の組み合わせで isearch 使用時の不具合が発見 + されています。GNU Emacs 24.3 のユーザは DDSKK 15 以降をお使いください。 + - http://mail.ring.gr.jp/skk/201211/msg00000.html + - http://mail.ring.gr.jp/skk/201212/msg00000.html + +- GNU Emacs 24.4 + + - coding tag を明示していないファイルは utf-8 と取り扱われます [fn:codingtag] 。 + DDSKK 15.2 で対策済みです。 + - NTEmacs は 24.3 と比べてディレクトリ構成 が異なります [fn:ntemacs244] 。 + DDSKK 15.2 で対策済みです。 + +- GNU Emacs 25.1 + + DDSKK 15.2 以降をお使いください(DDSKK 16 を推奨します)。 + +- XEmacs 21.4 + + - ~skk-kcode.el~ の機能を含む JIS X 0213 対応が機能しません。 + - インライン候補表示は機能しません。 + - 動的補完における複数候補表示は機能しません。 + - ツールティップ表示が機能しません。 + - 日本語メニュー表示は X リソースによる方法のみテストされています。 + - GNU Emacs 標準添付辞書 ja-dic は利用できません。 + +- XEmacs 21.5 (beta) + + - ~skk-kcode.el~ の機能を含む JIS X 0213 対応が機能しません。 + - インライン候補表示は機能しません。 + - 動的補完における複数候補表示は機能しません。 + - 日本語メニュー表示は X リソースによる方法のみテストされています。 + - GNU Emacs 標準添付辞書 ja-dic は利用できません。 + +[fn:codingtag] 2013-06-11 international/mule-conf.el (file-coding-system-alist) + +[fn:ntemacs244] Emacs News: Changes in Emacs 24.4 on Non-Free Operating Systems + +** SKK とはなにか + +SKK は、かな漢字変換プログラムです。 +Simple Kana to Kanji conversion program にちなんで名付けられ、その名 +は Combinatory Logic での有名な等式 @@texinfo:@math{@@SKK = I@@texinfo:}@@ に +も由来 [fn:skki] しています。 + +Daredevil SKK は、SKK の更なる拡張版です [fn:ddskk] 。 + +ただし、SKK モード、SKK 辞書、SKK サーバ といった歴史的な用語は引き続き使 +用しており、DDSKK と呼ばない場合もあります。また、SKK 方式の入力方法を採 +用したプログラムなど、広く SKK family を意味する場合も同様です。 + +DDSKK の主な特徴は、次のとおりです。 + +- 多彩な入力方式をサポート。ローマ/かな 両対応のかな入力のほか、AZIK、ACT、 + TUT-code の各方式による入力も可能。 +- 文法的知識を用いない高速な「かな→漢字」変換。 +- シームレスかつ再帰的な単語登録モード。 +- 確定語を個人辞書へ自動登録することによって、変換候補を効率的に表示する。 +- マイナーモードとして実装されているので、メジャーモードにほとんど影響を + 与えない。つまり、Emacs との親和性が高い。 +- DDSKK 本体 (Emacs Lisp) と辞書ファイルのみで動作可能。つまり、辞書サー + バは必須ではなく、辞書サーバがダウンしていても使用できる。 +- 辞書サーバを使うことで、使用メモリの削減が可能。 +- ディスク容量に応じて選べる辞書ファイル。 +- 辞書ファイルの一括ダウンロード機能。 +- Emacs のオリジナル操作と同様に行える日本語インクリメンタル・サーチ。 +- Emacs Lisp で書かれたプログラムが返す値を変換候補に挙げることができる。 +- 入力モードの自動切り替え ~context-skk.el~ +- 多彩なアノテーション表示 + + ユーザ・アノテーション + + EPWING 辞書 + + Apple macOS 辞書 + + Wikipedia/Wiktionary +- 「見出し語」の動的補完 +- 総画数変換、部首変換、文字コード入力 + +[fn:skki] @@texinfo:@math{@@SKK = I@@texinfo:}@@ について詳しくは http://openlab.jp/skk/SKK.html をご参照下さい。 + +[fn:ddskk] Daredevil の名の由来は [[Q1-1 Daredevil SKK って SKK とは違うのですか?][Q1-1 Daredevil SKK って SKK とは違うのですか?]]. + +* インストール + +** APEL のインストール + +#+CINDEX: APEL +DDSKK 14.2 からは、GNU Emacs 22 以上を利用する場合においては APEL を別途 +インストールする必要がなくなりました。APEL に依存している他の elisp プロ +グラムを使用していなければ、インストール済の APEL は削除することが可能で +す。 + +XEmacs をお使いの場合は、 DDSKK をインストールする前に APEL (APEL 10.8 以 +上を推奨)をインストールして下さい。APEL は次のサイトから入手できます。 + +- [[http://git.chise.org/elisp/apel/][APEL]] + +** DDSKK のインストール + +ここでは、UNIX 上で ~make~ コマンドが利用できる環境を想定します [fn:other] 。 + +まず、DDSKK のアーカイブ ~ddskk-VERSION.tar.gz~ を ~tar~ コマンドと ~gzip~ コ +マンドを使用して展開します。 + +#+BEGIN_SRC shell-script +% gzip -cd ddskk-VERSION.tar.gz | tar xvf - +#+END_SRC + +次に、DDSKK のトップディレクトリ [fn:topdir] をカレントディレクトリにしま +す。 + +#+BEGIN_SRC shell-script +% cd ddskk-VERSION +#+END_SRC + +[fn:other] Microsoft Windows 環境では ~makeit.bat~ を使用することで、UNIX +と同様の操作でインストールできます。 ~READMEs/README.w32.ja~ を参照してく +ださい。 + +cygwin 環境をインストールされている方は ~make~ コマンドが使用できるので、 +本文の解説がそのまま当てはまります。 + +Apple macOS 環境の方は ~READMEs/README.MacOSX.ja~ を参照してください。 + +[fn:topdir] ~ChangeLog~ や ~Makefile~ が置かれているディレクトリです。 + +*** GNU Emacs へのインストール + +まずは、DDSKK がどのディレクトリにインストールされるのか確認するため +に ~what-where~ を引数に ~make~ コマンドを実行しましょう。 + +#+BEGIN_EXAMPLE +% make what-where +-| emacs -batch -q -no-site-file -l SKK-MK -f SKK-MK-what-where +-| Loading /home/USER/temp/ddskk-VERSION/SKK-CFG... + +-| Running in: +-| GNU Emacs 26.0.50 (build1, x86_64-pc-linux-gnu, GTK+ Version ... + +-| SKK modules: +-| skk-cursor, skk-viper, ... +-| -> /path/to/emacs/site-lisp/skk + +-| SKK infos: +-| skk.info +-| -> /path/to/share/info + +-| SKK tutorials: +-| SKK.tut, SKK.tut.E, NICOLA-SKK.tut, skk.xpm +-| -> /path/to/share/skk +#+END_EXAMPLE + +emacs の実体ファイルを特定することもできます。 + +#+BEGIN_SRC shell-script +$ make what-where EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs +#+END_SRC + +#+CINDEX: SKK-CFG +また、DDSKK のインストール先ディレクトリを変更したい場合は ~SKK-CFG~ ファ +イルを編集してください。編集後は必ず ~make what-where~ を実行して表示内容 +を確認してください。 + +次にスーパーユーザになって、 + +#+BEGIN_SRC shell-script +$ su +% make install +#+END_SRC + +#+TEXINFO: @noindent +と実行すると、実際に DDSKK がインストールされます。 + +あるいは、一般ユーザが自分の home directory を root directory として DDSKK を +インストールするには、 + +#+BEGIN_SRC shell-script +% make install PREFIX=~/ +#+END_SRC + +#+TEXINFO: @noindent +と、 ~PREFIX~ を指定して ~make~ を実行します。 + +特定の Emacs を指定する場合は、 + +#+BEGIN_SRC shell-script +% make install EMACS=mule +#+END_SRC + +#+TEXINFO: @noindent +と指定します。 + +*** XEmacs へのインストール + +XEmacs でパッケージとしてインストールする場合は、まず ~what-where-package~ を +引数に ~make~ コマンドを実行してパッケージのインストール先を確認しましょう。 + +#+BEGIN_EXAMPLE +$ make what-where-package XEMACS=/usr/bin/xemacs +-| /usr/bin/xemacs -batch -q -no-site-file -l SKK-MK \ +-| -f SKK-MK-what-where-package +-| Loading /home/user/temp/ddskk-SKK-VERSION/SKK-CFG... + +-| Running in: +-| XEmacs 21.5 (beta34) "kale" [Lucid] (x86_64-redhat-linux, Mule) of ... + +-| SKK modules: +-| skk-cursor, skk-viper, ... +-| -> /usr/share/xemacs/site-packages/lisp/skk + +-| SKK infos: +-| skk.info +-| -> /usr/share/xemacs/site-packages/info + +-| SKK tutorials: +-| SKK.tut, SKK.tut.E, NICOLA-SKK.tut, skk.xpm +-| -> /usr/share/xemacs/site-packages/etc/skk +#+END_EXAMPLE + +次に、スーパーユーザになって ~install-package~ を引数に ~make~ を実行す +ると、実際にインストールされます。 + +#+BEGIN_EXAMPLE +$ su +% make install-package XEMACS=/usr/bin/xemacs +-| xemacs -batch -q -no-site-file -l SKK-MK -f SKK-MK-install-package +-| Loading /home/user/temp/ddskk-VERSION/SKK-CFG ... +#+END_EXAMPLE + +*** 対話的なインストール + +DDSKK 14.3 では「対話的インストーラ」が追加されました。 + +#+CINDEX: dired +まず ~M-x dired~ とキー入力して ~dired~ を起動してください。このとき、デ +ィレクトリを問われますので、先に述べた「DDSKK のアーカイブを展開したディ +レクトリ」を指定してください。 + +#+BEGIN_EXAMPLE +------ Minibuffer ------- +Dired (directory): ~/temp/ddskk-VERSION RET +------ Minibuffer ------- +#+END_EXAMPLE + +次に、表示されたディレクトリ一覧の ~SKK-MK~ にカーソルをあわせて ~L~ (ア +ルファベットのエルの大文字)を打鍵してください。 + +#+BEGIN_EXAMPLE +------ Dired ------- +-rw-r--r-- 1 user user 99999 2011-00-00 00:00 SKK-CFG +-rw-r--r-- 1 user user 99999 2011-00-00 00:00*SKK-MK "L" +drwxr-xr-x 1 user user 99999 2011-00-00 00:00 bayesian +------ Dired ------- +#+END_EXAMPLE + +プロンプト ~Load SKK-MK?~ には ~y~ を打鍵してください。 + +以降、インストーラが表示する質問に答えながら DDSKK のインストールを進めて +ください。なお、パーミッションは一切考慮していませんので、インストール先 +は書き込み権限を有するディレクトリを指定してください。 + +*** MELPA によるインストール + +#+CINDEX: MELPA +#+CINDEX: package.el +#+VINDEX: package-archives +#+FINDEX: package-initialize +2014年12月、MELPA [fn:melpa] に DDSKK が登録されたことにより、 GNU Emacs で +も ~package.el~ [fn:package] によるインストールが可能となりました。 + +詳細については、次のドキュメントを参照してください。 + +https://github.com/skk-dev/ddskk/blob/master/READMEs/INSTALL.MELPA.md + +[fn:melpa] [[http://melpa.org/][Milkypostman's Emacs Lisp Package Archive]] + +[fn:package] GNU Emacs 24 以降で標準で搭載されています。GNU Emacs 23 以 +前では手動でインストール必要があります。 http://wikemacs.org/wiki/Package.el + +** 辞書について + +DDSKK を使用するには、いわゆる辞書(主にかなと漢字の対応を記述したデータ) +が必要です。 + +#+CINDEX: ja-dic +DDSKK 14.2 からは、 GNU Emacs 同梱の辞書データ ~ja-dic~ を利用したかな漢 +字変換に対応しましたので、SKK 辞書ファイルを別途インストールしなくても最 +低限の使用ができます(XEmacs では ~ja-dic~ は利用できませんので、後述す +る SKK 辞書をインストールする必要があります)。 + +#+CINDEX: LEIM +しかし、 ~ja-dic~ は、 GNU Emacs の入力メソッド ~LEIM~ のために ~SKK-JISYO.L~ か +ら変換して生成されたものであり、英数変換や数値変換などのエントリ、および +「大丈夫」など複合語とみなし得る語が大幅に削除されています。 +そのため、 ~SKK-JISYO.L~ を利用したかな漢字変換と同等の結果は得られません。 + +有志の知恵を結集して作られている各種 SKK 辞書は便利ですから、是非入手して +インストールしましょう。 + +** 辞書の入手 + +次のサイトには、様々な辞書が用意されています。 + +[[http://openlab.jp/skk/wiki/wiki.cgi?page=SKK%BC%AD%BD%F1][SKK 各辞書の解説とダウンロード]] + +以下は、その一例です。 + +- ~SKK-JISYO.S~ + + S 辞書(主に単漢字が登録。最小限必要な語を収録) + +- ~SKK-JISYO.M~ + + M 辞書(普通に使う分には足りる程度) + +- ~SKK-JISYO.ML~ + + M 辞書と L 辞書の中間のサイズの辞書。L 辞書収録語の内、EPWING 辞書やオ + ンライン辞書で正しいと判別された語をベースにして加除。 + +- ~SKK-JISYO.L~ + + L 辞書(あらゆる単語を収録) + +- ~zipcode~ + + 郵便番号辞書 + +- ~SKK-JISYO.JIS2~ + + JIS X 0208 で定められている第2水準の文字を、部首の読みを見出し語として + 単漢字を収録した辞書 + +- ~SKK-JISYO.JIS3_4~ + + JIS 第3水準、第4水準の文字に代表される、JIS X 0208 には含まれないが + JIS X 0213 には含まれる文字及びそれらを含む語録を収録した辞書 + +- ~SKK-JISYO.public+~ + + public+ 辞書 + +- ~SKK-JISYO.edict~ + + edict 辞書(英和辞書) + +- ~SKK-JISYO.lisp~ + + 候補に Emacs Lisp 関数を含むエントリーを集めた辞書。見出し語を変換する + 過程で Emacs Lisp 関数を評価し、その値を候補として表示します。 + + [[プログラム実行変換][プログラム実行変換]]. + +- ~SKK-JISYO.wrong~ + + S, M, L 辞書に既に登録されていたが、間違いであったことが判明したため削 + 除された単語を収録 + +一部の辞書は、著作権が GNU GPL v2 ではありませんのでご注意下さい。詳細は、 +次の資料を参照して下さい。 + +http://openlab.jp/skk/skk/dic/READMEs/committers.txt + +- Key: M-x skk-get, skk-get + + Emacs の使用中に ~M-x skk-get~ と実行すると、辞書ファイルを一括ダウンロ + ードすることができます。 + +- Function: skk-get &optional DIRECTORY + + skk-get を関数として使用することで、ユーザプログラムの中からでも辞書フ + ァイルを一括ダウンロードすることができます。 + + #+BEGIN_SRC emacs-lisp + (skk-get "~/jisyofiles") + #+END_SRC + +** 辞書を DDSKK と同時にインストールする + +DDSKK のソースを展開すると、中に ~dic~ というディレクトリが存在します。 +~SKK-JISYO.L~ などをこのディレクトリにコピーしてから ~make install~ を +実行すると、辞書ファイルがチュートリアル (~SKK.tut~) と同じディレクト +リ (~/usr/share/skk~ や ~c:/emacs-24.5/etc/skk~ など) にインストールされ +ます。具体的なインストール先は ~make what-where~ を実行すると表示されます。 + +#+BEGIN_EXAMPLE +-| SKK dictionaries: +-| SKK-JISYO.lisp, SKK-JISYO.zipcode, SKK-JISYO.office.zipcode, ... +-| -> c:/emacs-24.5/share/emacs/24.5/etc/skk +#+END_EXAMPLE + +~dic~ ディレクトリに辞書ファイルを置くためには ~make get~ と実行するのが +簡単です [fn:makeit] 。 + +[fn:makeit] Microsoft Windows 環境では ~makeit.bat get~ と実行します。 + +** 辞書サーバの入手 + +辞書サーバはオプションです。辞書サーバが無くても DDSKK は動作しますが、特 +に辞書のサイズが大きい場合は辞書サーバを利用することで省メモリ効果を得ら +れます。また、辞書サーバによっては複数辞書の検索、EPWING 辞書の検索ができ +たりするものもあります。 + +DDSKK は特定の辞書サーバの実装に依存していませんので、下記の辞書サーバの +いずれでも動作可能です。ソースやバイナリの入手、インストールについてはそ +れぞれのウェブサイトをご参照下さい。 + +- [[http://openlab.jp/skk/skkserv-ja.html][辞書サーバの説明とリンク]] + +* はじめの設定 + +#+CINDEX: skk-setup.el +#+CINDEX: leim-list.el +#+CINDEX: skk-autoloads.el +#+FINDEX: normal-top-level +#+FINDEX: register-input-method +#+KINDEX: C-x C-j +標準的にインストールした場合は、特段の設定なしに Emacs を起動するだけ +で DDSKK が使える状態になります。自動的に ~skk-setup.el~ というファイルが +読み込まれ、設定されます [fn:leim-list] 。この自動設定によらずに手動で設 +定したい場合は、以下の説明を参照してください。 + +[fn:leim-list] Emacs が起動する過程の関数 ~normal-top-level~ で ~SKK_LISPDIR/leim-list.el~ が +読み込まれます。 ~leim-list.el~ は ~skk-autoloads.el~ と ~skk-setup.el~ を ~require~ し +ます。 ~skk-autoloads.el~ は DDSKK の ~make~ 時に自動的に生成されるファイ +ルであり、各関数を自動ロード (autoload) するよう定義するほか ~register-input-method~ も +行います。 ~skk-setup.el~ はキーバインド( ~C-x C-j~ → ~skk-mode~ )の定 +義、変数 ~skk-tut-file~ の定義及びインクリメンタル・サーチの定義を行って +います。 + +** 最も基本的な設定 + +#+CINDEX: init.el +#+KINDEX: C-x C-j +#+KINDEX: C-x j +#+KINDEX: C-x t +自動設定によらず手動で設定する場合は、次の内容を ~~/.emacs.d/init.el~ に書きま +す [fn:samplefile]。 + +#+BEGIN_SRC emacs-lisp +(require 'skk-autoloads) ; XEmacs でパッケージとしてインストールした場合は不要 +(global-set-key "\C-x\C-j" 'skk-mode) +(global-set-key "\C-xj" 'skk-auto-fill-mode) +(global-set-key "\C-xt" 'skk-tutorial) +#+END_SRC + +辞書サーバを使わない場合は、辞書ファイルを指定する必要があります。 + +#+BEGIN_SRC emacs-lisp +(setq skk-large-jisyo "/your/path/to/SKK-JISYO.L") +#+END_SRC + +辞書サーバを使わない場合は Emacs のバッファに ~skk-large-jisyo~ が指すフ +ァイルを取り込んで使用するためメモリ使用量が増加します。これが支障となる +場合は、上記の ~SKK-JISYO.L~ を ~SKK-JISYO.M~ 、 ~SKK-JISYO.ML~ 又 +は ~SKK-JISYO.S~ に変更してください。 + +#+CINDEX: CDB 形式辞書ファイル +DDSKK 14.1 以降は辞書サーバを経由せずとも CDB 形式 [fn:cdb] の辞書ファイ +ルを直接利用できるようになりました。CDB 形式辞書ファイル [fn:cdbdic] を利 +用する場合は、以下のように指定してください。 + +#+BEGIN_SRC emacs-lisp +(setq skk-cdb-large-jisyo "/your/path/to/SKK-JISYO.L.cdb") +#+END_SRC + +変数 ~skk-large-jisyo~ と 変数 ~skk-cdb-large-jisyo~ を同時に指定した場合 +は、標準では CDB 形式辞書ファイルの方が先に検索 [fn:order] されます。 + +[fn:samplefile] 配布物にサンプルファイル ~etc/dot.emacs~ と ~etc/dot.skk~ が +あります。参考にして下さい。 + +[fn:cdb] constant database のこと。詳しくは http://cr.yp.to/cdb.html 又 +は http://ja.wikipedia.org/wiki/Cdb を参照のこと。 + +[fn:cdbdic] SKK 辞書 の ~Makefile~ 中の ~cdb~ ターゲットを実行すること +で ~SKK-JISYO.L~ に基づく ~SKK-JISYO.L.cdb~ を生成することができます。 + +[fn:order] [[辞書検索の設定の具体例][辞書検索の設定の具体例]]. + +** インクリメント検索の設定 + +#+VINDEX: isearch-mode-hook +#+VINDEX: isearch-mode-end-hook +基本的な設定は ~skk-setup.el~ が読み込まれた時点で完了しています [fn:skksetup]。 + +- User Option: skk-isearch-mode-enable + + この変数は ~~/.emacs.d/init.el~ か ~M-x customize-variable~ で設定して + ください。 ~Non-nil~ であれば、SKK が ON になっているバッファで skk-isearch を + 有効にします。標準設定は ~t~ です。 ~nil~ に設定すると skk-isearch を + 無効にすることができます。シンボル ~always~ に設定すると、SKK が ON に + なっていないバッファでも skk-isearch を有効にします。 + +[fn:skksetup] ~skk-setup.el~ では、 ~isearch-mode-hook~ に ~skk-isearch-setup-maybe~ を、 +~isearch-mode-end-hook~ に ~skk-isearch-cleanup-maybe~ をそれぞれ追加して +います。 ~skk-isearch-{setup|cleanup}-maybe~ も ~skk-setup.el~ で定義され +ており、その実態は、関数 ~skk-isearch-mode-{setup|cleanup}~ です。 + +** 辞書サーバを使いたいときの設定 + +辞書サーバを使いたいときは、 ~~/.skk~ で以下のように設定します。 + +#+BEGIN_SRC emacs-lisp +(setq skk-server-host "example.org") +(setq skk-server-portnum 1178) +#+END_SRC + +- Variable: skk-server-host + + 辞書サーバが起動しているホスト名又は IP アドレス。 + +- Variable: skk-server-portnum + + 辞書サーバが使うポート番号。 ~/etc/services~ に ~skkserv~ のエントリが + 記述されていれば、この変数を指定する必要は無い。 + +- User Option: skk-server-inhibit-startup-server + + この変数が ~nil~ であれば、辞書サーバが起動していなかったときに Emacs か + ら ~skkserv~ プロセスを起動することができます。 + + Emacs から立ち上げて利用する事ができる辞書サーバは、 + + #+BEGIN_EXAMPLE + skkserv [-p port] [jisyo] + #+END_EXAMPLE + + のようなオプションを受け付け、 ~inetd~ などを経由せず直接起動するものに + 限られます。辞書サーバプログラムと辞書ファイルは、次のように設定します。 + + #+BEGIN_SRC emacs-lisp + (setq skk-server-prog "/your/path/to/skkserv") + (setq skk-server-jisyo "/your/path/to/SKK-JISYO.L") + #+END_SRC + +- Variable: skk-server-prog + + 辞書サーバプログラムをフルパスで指定する。 + +- Variable: skk-server-jisyo + + 辞書サーバに渡す辞書をフルパスで指定する。辞書サーバによっては独自の方 + 法で辞書ファイルを指定して emacs からの指定を無視するものもあります。 + 詳しくは各辞書サーバの説明書を読んで下さい。 + +#+CINDEX: SKKSERVER +#+CINDEX: SKKSERV +#+CINDEX: SKK_JISYO +これらの設定は、環境変数を利用して下記のようにすることもできます。 + +- B シェルの場合(sh, bash, ksh, zsh など) + + #+BEGIN_SRC shell-script + export SKKSERVER=example.org + export SKKSERV=/your/path/to/skkserv + export SKK_JISYO=/your/path/to/SKK-JISYO.L + #+END_SRC + +- C シェルの場合(csh, tcsh など) + + #+BEGIN_SRC shell-script + setenv SKKSERVER example.org + setenv SKKSERV /your/path/to/skkserv + setenv SKK_JISYO /your/path/to/SKK-JISYO.L + #+END_SRC + +関連項目: + + + [[辞書サーバの入手][辞書サーバの入手]]. + + + [[サーバ関連][サーバ関連]]. + +** DDSKK を Emacs の Input Method とする + +#+CINDEX: skk-leim.el +#+KINDEX: C-\ +#+KINDEX: M-x toggle-input-method +Emacs の標準キーバインドでは ~C-\~ を打鍵すると、関数 ~toggle-input-method~ を +実行します。この関数は、変数 ~default-input-method~ が指す input method を +トグル切り替えします。 + +#+VINDEX: default-input-method +#+CINDEX: LEIM +変数 ~default-input-method~ の値はおそらく "~Japanese~" であり、結果として ~C-\~ の +打鍵で LEIM (Library of Emacs Input Method) を on / off します。 + +#+KINDEX: M-x list-input-methods +#+KINDEX: M-x set-input-method +#+KINDEX: C-x RET C-\ +使用可能な input method は ~M-x list-input-methods~ で確認することができ、 +コマンド ~M-x set-input-method~ 又は ~C-x RET C-\~ を実行することで input method を +切り替えることができます。 + +ファイル ~skk-leim.el~ から生成されるファイル ~skk-autoloads.el~ で input method を +ふたつ追加しています。 + + 1. "~japanese-skk~" ... 内容は ~(skk-mode 1)~ です。 + 2. "~japanese-skk-auto-fill~" ... 内容は ~(skk-auto-fill-mode 1)~ です。 + +#+CINDEX: input method +- User Option: default-input-method + + Emacs 起動時の input method を DDSKK とするには、 ~~/.emacs.d/init.el~ に + + #+BEGIN_SRC emacs-lisp + (setq default-input-method "japanese-skk") + #+END_SRC + + と記述してください。 + +* 基本的な使い方 + +本章では、DDSKK の基本的な使用方法を説明します。これを読めば、とりあえず +DDSKK を使ってみるには充分です。 + +DDSKK を使った入力方法に慣れるには、付属のチュートリアル [fn:tutorial] が +最適なので、お試しください。 + +なお、次章の「便利な応用機能」 [fn:app] は、興味のある個所のみをピックア +ップしてお読みになるのがいいでしょう。 + +[fn:tutorial] [[チュートリアル][チュートリアル]]. + +[fn:app] [[便利な応用機能][便利な応用機能]]. + +** 起動と終了 + +SKK モードに入るには ~C-x C-j~ もしくは ~C-x j~ とキー入力します。モード +ラインの左端には、下記のように "~--かな:~" が追加されます [fn:modeline] 。 +また、カーソルの色が変化 [fn:cursor] します。 + +#+BEGIN_EXAMPLE +--かな:MULE/7bit----- Buffer-name (Major-mode)--- +#+END_EXAMPLE + +再び ~C-x C-j~ もしくは ~C-x j~ をキー入力することで、SKK モードに入る前 +のモードに戻り [fn:exit] 、カーソル色も元に戻ります。 + +- User Option: skk-status-indicator + + 標準設定はシンボル ~left~ です。この変数をシンボル ~minor-mode~ と設 + 定すれば、インジケータはモードラインのマイナーモードの位置に表示されま + す。 + +- User Option: skk-preload + + ~~/.emacs.d/init.el~ にて変数 ~skk-preload~ を ~non-nil~ と設定すること + により、DDSKK の初回起動を速くすることができます。 + + #+BEGIN_SRC emacs-lisp + (setq skk-preload t) + #+END_SRC + + これは、SKK 本体プログラムの読み込みと、変数 ~skk-search-prog-list~ に + 指定された辞書の読み込みを Emacs の起動時に済ませてしまうことにより実現 + しています。そのため、Emacs の起動そのものは遅くなりますが、DDSKK を使 + い始めるときのレスポンスが軽快になります。 + +- Key: M-x skk-restart, skk-restart + + ~M-x skk-restart~ と実行すると SKK を再起動します。 ~~/.skk~ は再ロード + しますが、 ~~/.emacs.d/init.el~ は再ロードしません。 + +- Key: M-x skk-version, skk-version + + ~M-x skk-version~ と実行するとエコーエリアに SKK のバージョンを表示 [fn:ver] しま + す。 + + #+BEGIN_EXAMPLE + -------------------- Echo Area -------------------- + Daredevil SKK/16.2.50 (CODENAME) + -------------------- Echo Area -------------------- + #+END_EXAMPLE + + + +[fn:modeline] ~skk.el~ の ~skk-setup-modeline~ にて、 ~mode-line-format~ に ~skk-icon~ と ~skk-modeline-input-mode~ を追加しています。 + +[fn:cursor] カラーディスプレイを使用し、カラー表示をサポートしている Window System 下 +で対応する Emacs を使用している場合。 + +[[入力モードを示すカーソル色に関する設定][入力モードを示すカーソル色に関する設定]]. + +[fn:exit] ただし、「アスキーモード」を利用すれば SKK モードから抜ける必要 +はほとんどありません。 + +[[入力モード][アスキーモード]]. + +[fn:ver] [[エラーなどの日本語表示][エラーなどの日本語表示]]. + +*** SKK オートフィルモード + +#+CINDEX: オートフィル +#+KINDEX: C-x j +~C-x j~ とキー入力すれば、SKK モードに入ると同時にオートフィルモード [fn:autofill] を +オンにします。 + +既にオートフィルモードがオンになっているバッファで ~C-x j~ をキー入力する +と、オートフィルモードは逆にオフになるので注意してください。 + +#+KINDEX: M-1 C-x j +#+KINDEX: C-u C-x j +バッファの状態にかかわらず強制的にオートフィルモード付で SKK モードに入り +たい場合は ~M-1 C-x j~ や ~C-u C-x j~ などとキー入力し、このコマンドに正 +の引数 [fn:args] を渡します。 + +#+KINDEX: M-- C-x j +#+KINDEX: C-u -1 C-x j +オートフィルモードをオフにし、かつ SKK モードも終了したい場合には +~M-- C-x j~ や ~C-u -1 C-x j~ などとキー入力し、このコマンドに負の引数を +渡します。 + +[fn:autofill] [[info:emacs#Auto Fill][Auto Fill Mode in GNU Emacs Manual]]. + +[fn:args] [[info:emacs#Arguments][Arguments in GNU Emacs Manual]]. + +*** 辞書の保存 + +#+VINDEX: skk-backup-jisyo +#+VINDEX: skk-jisyo +Emacs を終了するときは、保存前の個人辞書を ~~/.skk-jisyo.BAK~ に退避して +から、個人辞書 [fn:skkjisyo] の内容を ~~/.skk-jisyo~ に保存 [fn:save] し +ます。 + +~~/.skk-jisyo~ や ~~/.skk-jisyo.BAK~ のファイル名を変更したければ、それぞ +れ ~skk-jisyo~ や ~skk-backup-jisyo~ の値を変更して下さい。 + +- Key: M-x skk-kill-emacs-without-saving-jisyo, skk-kill-emacs-without-saving-jisyo + + 個人辞書を保存せずに Emacs を終了させたい場合には、このコマンドをキー入 + 力します。 + +[fn:skkjisyo] [[辞書の種類][個人辞書]]. + +[fn:save] [[個人辞書の保存動作][個人辞書の保存動作]]. + +** 入力モード + +SKK モードは、文字種類による4種類の *入力モード* [fn:color] と、辞書を +用いた変換の状態により3つの *変換モード* を持ちます。 + +*** 入力モードの説明 + +- かなモード + + + アスキー小文字をひらがなに変換するモード。 + + + マイナーモードの表示: *かな* + + + カーソル色: 赤系 + +- カナモード + + + アスキー小文字をカタカナに変換するモード + + + マイナーモードの表示: *カナ* + + + カーソル色: 緑系 + +- 全英モード + + + アスキー小文字/大文字を全角アルファベット [fn:jisx0208] に変換する + モード。 + + + マイナーモードの表示: *全英* + + + カーソル色: 黄系 + +- アスキーモード + + + 文字を変換しないモード。入力されたキーは ~C-j~ を除いて通常の Emacs の + コマンドとして解釈される。 + + + マイナーモードの表示: *SKK* + + + カーソル色: 背景によりアイボリーかグレイ。 + +[fn:color] [[入力モードを示すカーソル色に関する設定][入力モードを示すカーソル色に関する設定]]. + +[fn:jisx0208] JIS X 0208 英字のこと。このマニュアルでは「全角アルファベッ +ト」と表記する。 + +*** 入力モードを切り替えるキー + +- Key: q, skk-toggle-kana + + 「かなモード」、「カナモード」間をトグルする。 + +- Key: l, skk-latin-mode + + 「かなモード」又は「カナモード」から「アスキーモード」へ。 + +- Key: L, skk-jisx0208-latin-mode + + 「かなモード」又は「カナモード」から「全英モード」へ。 + +- Key: C-j, skk-kakutei + + 「アスキーモード」又は「全英モード」から「かなモード」へ。 + +実際にはカナモードや全英モードで長時間入力を続けることはほとんどないの +で、かなモードのままでカナ文字や全英文字を入力する便法が用意されています。 + + - [[かなモードからカタカナを入力][かなモードからカタカナを入力]]. + + - [[全英文字の入力][全英文字の入力]]. + +- User Option: skk-show-mode-show + + 現在の入力モードは、モードラインに表示されています。この変数を ~Non-nil~ と + すると、入力モードを切り替えたときにカーソル付近にも一瞬表示するように + なります。 + +- Key: M-x skk-show-mode, skk-show-mode + + ~skk-show-mode-show~ の値をトグル切り替えします。 + +- User Option: skk-show-mode-style + + 標準設定は、シンボル ~inline~ です。シンボル ~tooltip~ を指定すること + も可能です。 + +- User Option: skk-show-mode-inline-face + + ~inline~ 利用時の face + +** 変換モード + +変換モードは、次の3種類のいずれかです。 + +- ■モード(確定入力モード) + + あるキー入力に対応する文字列を、辞書を用いた文字変換を行わずに直接バッ + ファへ入力するモード。入力モードに応じてローマ字からひらがなへ、ローマ + 字からカタカナへ、あるいはアスキー文字から全角アルファベットへ文字を変 + 換する。 + +- ▽モード + + 辞書変換の対象となる文字列 *見出し語* を入力するモード。 + +- ▼モード + + 見出し語について、辞書変換を行うモード。 + +また、▽モードの変種として *SKK abbrev モード* があり、▼モードのサブモード +として *辞書登録モード* があります。 + +*** ■モード + +#+CINDEX: 確定入力 +#+CINDEX: 確定入力モード +#+CINDEX: ■モード +確定入力モードを *■モード* と呼びます。■モードでは、あるキー入力に対応 +した特定の文字列への変換を行うだけで、辞書変換は行いません。アスキー文字 +列から、入力モードに応じて、ひらがな、カタカナ、あるいは全角アルファベッ +トへ文字を変換します。カレントバッファにこのモード特有のマークは表示され +ません。 + +#+CINDEX: ローマ字入力 +かなモード、カナモードで、かつ ■モードである場合、標準設定の入力方法は +いわゆるローマ字入力です。訓令式、ヘボン式のどちらによっても入力すること +ができます。主な注意点は以下のとおりです。 + + + 「ん」 は ~n n~ 又は n ' で入力する。直後に ~n~ 及び ~y~ 以外の子音が + 続くときは ~n~ だけで入力できる。 + + + 促音は ~c h o t t o~ ⇒ 「ちょっと」 や ~m o p p a r a~ ⇒ 「もっぱら」 + のように次の子音を重ねて入力する。 + + + 促音や拗音(ひらがなの小文字)を単独で入力するときは ~x a~ ⇒ 「ぁ」 + や ~x y a~ ⇒ 「ゃ」 などのように ~x~ を用いる。 + + + 長音(ー)は ~-~ で入力する。 + +*** ▽モード + +*▽モード* では、辞書変換の対象となる文字列を入力します。かなモードもしく +はカナモードで [fn:mode] 、かつ■モードであるときに、キー入力を *大文字で開始* する +ことで▽モードに入ります。 + +#+BEGIN_EXAMPLE +K a n j i + + ------ Buffer: foo ------ + ▽かんじ* + ------ Buffer: foo ------ +#+END_EXAMPLE + +~K a n j i~ のように打鍵することで▽モードに入り、続けて辞書変換の対象と +なる文字列「見出し語」を入力します。▽マークは「▽モードである」という表 +示ですが、見出し語の開始点を示す表示でもあります。 + +[fn:mode] [[入力モード][入力モード]]. + +**** 後から▽モードに入る方法 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +#+KINDEX: Q +辞書変換の対象としたい文字列であったにも関わらず、先頭の文字を大文字で入 +力し忘れた場合は、その位置までポイント [fn:point] を戻してから ~Q~ を打鍵 +することで、▽モードに入ることができます。 + +#+BEGIN_EXAMPLE +k a n j i + + ------ Buffer: foo ------ + かんじ* + ------ Buffer: foo ------ + +C-u 3 C-b + + ------ Buffer: foo ------ + *かんじ + ------ Buffer: foo ------ + +Q + + ------ Buffer: foo ------ + ▽*かんじ + ------ Buffer: foo ------ + +C-e + + ------ Buffer: foo ------ + ▽かんじ* + ------ Buffer: foo ------ +#+END_EXAMPLE + +#+CINDEX: 数字から始まる見出し語の入力 +「7がつ24にち」のように大文字から始めることができない文字列を見出し語とし +たい場合は ~Q~ を打鍵して▽モードにしてから「7がつ24にち」の文字列を入力 +します。 + +なお、▽モードでは、文字列の間に空白を含めることはできません。これは、辞 +書エントリの見出し語に空白を含めることができない制限からきています。 + +[fn:point] [[info:emacs#Point][Point in GNU Emacs Manual]]. + +**** ▽モードを抜ける方法 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +#+KINDEX: C-j +#+KINDEX: C-g +誤って▽モードに入ってしまったときは ~C-j~ と打鍵して■モードに戻るか、 +~C-g~ と打鍵して見出し語を消去するか、どちらかの方法があります。 + +#+BEGIN_EXAMPLE +K a n j i + + ------ Buffer: foo ------ + ▽かんじ* + ------ Buffer: foo ------ + +C-j + + ------ Buffer: foo ------ + かんじ* + ------ Buffer: foo ------ +#+END_EXAMPLE + +あるいは、 + +#+BEGIN_EXAMPLE +K a n j i + + ------ Buffer: foo ------ + ▽かんじ* + ------ Buffer: foo ------ + +C-g + + ------ Buffer: foo ------ + * + ------ Buffer: foo ------ +#+END_EXAMPLE + +*** ▼モード + +#+CINDEX: 変換開始 +*▼モード* では、▽モードで入力した見出し語を、辞書に従って変換する作業を +行います。▽モードで見出し語を入力した後に ~SPC~ を打鍵することで▼モード +に入ります。▽マークから ~SPC~ を打鍵したときのポイントまでの文字列が見出 +し語として確定され、 ▽マークは▼マークで置き換えられ、この見出し語が辞書 +の中で検索されます。 + +**** 送り仮名が無い場合 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +仮に、辞書に + +#+BEGIN_EXAMPLE +かんじ /漢字/幹事/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリ [fn:entry] を含むとして、例を示します。 + +#+BEGIN_EXAMPLE +K a n j i + + ------ Buffer: foo ------ + ▽かんじ* + ------ Buffer: foo ------ + +SPC + + ------ Buffer: foo ------ + ▼漢字* + ------ Buffer: foo ------ +#+END_EXAMPLE + +#+CINDEX: Overlays +#+CINDEX: ハイライト +この例では、▽モードにおける▽マークからポイントまでの間の文字列「かんじ」 +を辞書変換の対象文字列として確定し、それについて辞書内での検索を行ってい +ます。実際の変換動作では、候補部分がハイライト [fn:highlight] 表示されま +す。 + +「漢字」が求める語であれば ~C-j~ を打鍵してこの変換を確定します。ハイライ +ト表示も▼マークも消えます。 + +#+CINDEX: 暗黙の確定 +また、 ~C-j~ を打鍵せずに新たな確定入力を続けるか又は新たな変換を開始する +と、直前の変換は自動的に確定されます。これを *暗黙の確定* [fn:ammk] と呼んでいます。 +打鍵することによる副作用として暗黙の確定を伴うキーは、印字可能な文字全て +と ~RET~ です。 + +[fn:entry] 本マニュアルでは、見出し語と候補群を合わせた一行を「エントリ」 +と呼びます。 + +[[送りありエントリと送りなしエントリ][送りありエントリと送りなしエントリ]]. + +[fn:highlight] ハイライト表示は GNU Emacs の Overlays、XEmacs の extent +の機能を使用しています。 + +[fn:ammk] [[暗黙の確定のタイミング][暗黙の確定のタイミング]]. + +**** 次候補・前候補 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +求める語がすぐに表示されなければ、更に続けて ~SPC~ を打鍵することで次候補 +を検索します。 + +#+BEGIN_EXAMPLE + ------ Buffer: foo ------ + ▼漢字* + ------ Buffer: foo ------ + +SPC + + ------ Buffer: foo ------ + ▼幹事* + ------ Buffer: foo ------ +#+END_EXAMPLE + +候補が5つ以上あるときは、5番目以降の候補は7つずつ [fn:shntdc] まとめて +エコーエリアに表示されます。 + +例えば、辞書が + +#+BEGIN_EXAMPLE +きょ /距/巨/居/裾/嘘/拒/拠/虚/挙/許/渠/据/去/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリを含むときに ~K y o~ の後に ~SPC~ を5回 [fn:sscnhc] 続けて +打鍵すれば + +#+BEGIN_EXAMPLE +-------------------- Echo Area -------------------- +A:嘘 S:拒 D:拠 F:虚 J:挙 K:許 L:渠 [残り 2] +-------------------- Echo Area -------------------- +#+END_EXAMPLE + +#+TEXINFO: @noindent +がエコーエリア [fn:echoarea] に表示されます。ここで仮に「許」を選択したけ +れば ~k~ を打鍵します。 + +~A~ , ~S~ , ~D~ , ~F~ , ~J~ , ~K~ , ~L~ の各文字は、押し易さを考慮してキ +ーボードのホームポジションから横方向に一直線に配置されているキーが選ばれ +ています。また、候補の選択のために押すキー [fn:selkey] は、大文字、小文字 +のいずれでも構いません。 + +~SPC~ を連打してしまって求める候補を誤って通過してしまったときは ~x~ を打 +鍵 [fn:x] すれば前候補/前候補群に戻ることができます。 + +次々と候補を探しても求める語がなければ、自動的に辞書登録モード [fn:reg] に +なります(辞書登録モードは▼モードのサブモードです)。 + +- Variable: skk-previous-candidate-keys + + 前候補/前候補群に戻る関数 ~skk-previous-candidate~ を割り当てるオブジ + ェクトのリストを指定する。オブジェクトにはキーを表す文字列または + event vector が指定できます。 + + 標準設定は ~(list "x" "\C-p")~ です。 + +- Variable: skk-search-excluding-word-pattern-function + + 詳しくは docstring を参照のこと。 + +- Variable: skk-show-candidates-nth-henkan-char + + 候補一覧を表示する関数 ~skk-henkan-show-candidates~ を呼び出すまで + の ~skk-start-henkan-char~ を打鍵する回数。2以上の整数である必要。 + +- Variable: skk-henkan-number-to-display-candidates + + いちどに表示する候補の数。 + +[fn:shntdc] ~skk-henkan-number-to-display-candidates~ + +[fn:sscnhc] ~skk-show-candidates-nth-henkan-char~ + +[fn:echoarea] エコーエリアとミニバッファは視覚的には同一の場所にあります +が、エコーエリアが単にユーザへのメッセージを表示するのみであるのに対し、 +ミニバッファは独立したバッファとして機能する点が異なります。 + +[fn:selkey] [[候補の選択に用いるキー][候補の選択に用いるキー]]. + +[fn:x] ~x~ は小文字で入力する必要があります。 + +[fn:reg] [[辞書登録モード][辞書登録モード]]. + +**** 送り仮名が有る場合 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +次に送り仮名のある単語について説明します。 + +「動く」を変換により求めたいときは ~U g o K u~ のように、まず、▽モードに +入るために ~U~ を大文字で入力し、次に、送り仮名の開始を DDSKK に教えるた +めに ~K~ を大文字で入力します。送り仮名の ~K~ を打鍵した時点で▼モードに +入り辞書変換が行われます( ~SPC~ 打鍵は不要)。 + +送り仮名の入力時(ローマ字プレフィックスが挿入された瞬間)にプレフィック +スの直前に一瞬だけ ~*~ が表示されることで送り仮名の開始時点を明示します。 +プレフィックスに続くキー入力で、かな文字が完成した時点で ~*~ は消えます。 + +キー入力を分解して追いながらもう少し詳しく説明します。 + +#+BEGIN_EXAMPLE +U g o + + ------ Buffer: foo ------ + ▽うご* + ------ Buffer: foo ------ + +K + + ------ Buffer: foo ------ + ▽うご*k + ------ Buffer: foo ------ + +u + + ------ Buffer: foo ------ + ▼動く* + ------ Buffer: foo ------ + +#+END_EXAMPLE + +このように、DDSKK では送り仮名の開始地点をユーザが明示的に入力 [fn:okurikana] す +るので、システム側で送り仮名を分解する必要がありません。これにより、高速 +でヒット効率が高い変換が可能になります。 + +ただし、サ変動詞の変換 [fn:sahend] では、サ変動詞の語幹となる名詞 +を *送りなし変換* [fn:okurinasi] として変換し、その後「する」を■モードで +入力した方が効率が良くなります。 + +[fn:okurikana] [[送り仮名の自動処理][送り仮名の自動処理]]. + +[fn:sahend] [[サ変動詞の辞書登録に関する注意][サ変動詞の入力]]. + +[fn:okurinasi] 詳細は [[送り仮名が無い場合][送り仮名が無い場合]]. + +*** 辞書登録モード + +#+CINDEX: 辞書登録 +DDSKK には独立した辞書登録モードはありません。その代わり、辞書にない単語 +に関して変換を行った場合に、自動的に *辞書登録モード* に入ります。例えば +辞書に + +#+BEGIN_EXAMPLE +へんかんちゅう /変換中/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +のエントリがない場合に「変換中」を入力しようとして ~H e n k a n t y u u SPC~ と +キー入力すると、下記のように、カレントバッファは▼モードのまま「へんかん +ちゅう」に対して変換ができない状態で休止し、同時にミニバッファに「へんか +んちゅう」というプロンプトが表示されます。 + +#+BEGIN_EXAMPLE +------ Buffer: foo ------ +▼へんかんちゅう +------ Buffer: foo ------ +#+END_EXAMPLE + +#+BEGIN_EXAMPLE +------ Minibuffer ------- +[辞書登録] へんかんちゅう: * +------ Minibuffer ------- +#+END_EXAMPLE + +もちろん、誤って登録した単語は削除できます。 + + - [[誤った登録の削除][誤った登録の削除]]. + + - [[個人辞書ファイルの編集][個人辞書ファイルの編集]]. + +- Variable: skk-read-from-minibuffer-function + + この変数に「文字列を返す関数」を収めると、その文字列を辞書登録モードに + 入ったときのプロンプトに初期表示します。関数 ~read-from-minibuffer~ の + 引数 ~INITIAL-CONTENTS~ に相当します。 + + #+BEGIN_SRC emacs-lisp + (setq skk-read-from-minibuffer-function + (lambda () skk-henkan-key)) + #+END_SRC + +- Variable: skk-jisyo-registration-badge-face + + 変数 ~skk-show-inline~ が ~non-nil~ であれば、辞書登録モードに移ったこ + とを明示するためにカレントバッファに「↓辞書登録中↓」とインライン表示 + します。この「↓辞書登録中↓」に適用するフェイスです。 + +**** 送り仮名が無い場合の辞書登録 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +辞書登録モードでは、キー入力はミニバッファに対して行われます。仮に辞書に + +#+BEGIN_EXAMPLE +へんかん /変換/ +ちゅう /中/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +のようなエントリがあるとして、ミニバッファで「変換中」の文字列を「変換」 +と「中」とに分けて作ります。 + +#+BEGIN_EXAMPLE +H e n k a n SPC T y u u SPC + + ----------- Minibuffer ------------ + [辞書登録] へんかんちゅう: 変換▼中* + ----------- Minibuffer ------------ +#+END_EXAMPLE + +#+CINDEX: 暗黙の確定 +ここで ~RET~ を打鍵すれば「変換中」が個人辞書に登録され [fn:regist1] 、 +辞書登録モードは終了します [fn:regist2] 。同時に、変換を行っているカレン +トバッファには「変換中」が挿入され確定されます。 + +辞書登録モードを抜けたいときは ~C-g~ を打鍵するか、または何も登録せず ~RET~ を +打鍵すると▽モードに戻ります。 + +[fn:regist1] [[辞書の種類][辞書の種類]]. + +[fn:regist2] ここでは「暗黙の確定」が行われるので ~C-j~ を打鍵する必要はあり +ません。 + +[[▼モードでの RET][▼モードでの RET]]. + +**** 送り仮名が有る場合の辞書登録 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +送り仮名のある単語の登録では、ミニバッファで作る候補に送り仮名そのものを +登録しないように注意しなければいけません。仮に辞書に + +#+BEGIN_EXAMPLE +うごk /動/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリが無いとして、例を挙げて説明します。 + +#+BEGIN_EXAMPLE +U g o K u + + ------ Buffer: foo ------ + ▼うごく + ------ Buffer: foo ------ + + ------ Minibuffer ------- + [辞書登録] うご*く: * + ------ Minibuffer ------- +#+END_EXAMPLE + +ミニバッファで辞書登録すべき文字列は「動」だけであり、送り仮名の「く」は +含めてはいけません。「動く」と登録してしまうと、次に ~U g o K u~ とキー入 +力したときに出力される候補が「動くく」になってしまいます。 + +#+BEGIN_EXAMPLE +D o u SPC + + ------ Minibuffer ------- + [辞書登録] うご*く: 動* + ------ Minibuffer ------- + +RET + + ------ Buffer: foo ------ + 動く* + ------ Buffer: foo ------ +#+END_EXAMPLE + +- Variable: skk-check-okurigana-on-touroku + + 標準設定は ~nil~ です。 ~non-nil~ であれば、辞書登録時に送り仮名のチ + ェックを行います。 + + シンボル ~ask~ を設定すれば、ユーザに確認を求め、送り仮名と認められれば + 送り仮名を取り除いてから登録します。 + + シンボル ~auto~ を設定すれば、ユーザに確認を求めず、勝手に送り仮名を判 + 断して削除してから登録します。 + +**** サ変動詞の辞書登録に関する注意 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +サ変動詞(名詞の後に「する」を付けた形で構成される動詞)については「する」 +を送り仮名とした送りあり変換 [fn:sahen1] をしないで、 +「運動」と「する」とに分けて入力することを前提としています [fn:sahen2] 。 + +例えば「運動する」は ~U n d o u SPC s u r u~ とキー入力することにより入力 +できます。名詞から作られる形容詞等も同様です。 + +[fn:sahen1] [[送り仮名が有る場合][送り仮名が有る場合]]. + +[fn:sahen2] ~SKK-JISYO.L~ など共有辞書のメンテナンス上、原則としてサ変動詞 +を送りありエントリに追加していません。そのため、「する」を送り仮名とした +送りあり変換では、辞書に候補がなく辞書登録モードに入ってしまうので、名詞 +として分解して入力することが一般的です。ただし、DDSKK 13 以降では暫定的に +サ変動詞の送りあり変換を可能にする機能を用意しました。 + +[[サ変動詞変換][サ変動詞変換]]. + +**** 再帰的辞書登録 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +ミニバッファを再帰的に使って辞書登録を再帰的に行うことができます。 + +仮に辞書に + +#+BEGIN_EXAMPLE +さいきてき /再帰的/ +さいき /再帰/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +のようなエントリがなく、かつ + +#+BEGIN_EXAMPLE +さい /再/ +き /帰/ +てき /的/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +のようなエントリがあるとします。 + +ここで ~S a i k i t e k i SPC~ とキー入力すると、見出し語「さいきてき」に +対する候補を見つけられないので、ミニバッファに「さいきてき」というプロン +プトを表示して辞書登録モードに入ります。 + +「さいきてき」に対する辞書エントリを作るため ~S a i k i SPC~ とキー入力す +ると、更にこの候補も見つけられないので、ミニバッファに「さいき」というプ +ロンプトを表示して、再帰的に「さいき」の辞書登録モードに入ります。 + +~S a i SPC K i SPC~ とキー入力すると、ミニバッファは、 + +#+BEGIN_EXAMPLE +------ Minibuffer ------- +[[辞書登録]] さいき: 再▼帰* +------ Minibuffer ------- +#+END_EXAMPLE + +#+TEXINFO: @noindent +となります。プロンプトが ~[ [~ 辞書登録 ~] ]~ となり ~[ ]~ がひとつ増えて +いますが、この ~[ ]~ の数が再帰的な辞書登録モードの深さを表わしています。 +ここで ~RET~ を打鍵すると、個人辞書には + +#+BEGIN_EXAMPLE +さいき /再帰/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリが登録され、ミニバッファは「さいきてき」の辞書登録モードに +戻り、プロンプトは「さいきてき」となります。 + +今度は「再帰」が変換可能なので ~S a i k i SPC T e k i SPC~ とキー入力する +と、 + +#+BEGIN_EXAMPLE +------ Minibuffer ------- +[辞書登録] さいきてき: 再帰▼的* +------ Minibuffer ------- +#+END_EXAMPLE + +#+TEXINFO: @noindent +となります。ここで ~RET~ を打鍵することで「さいきてき」の辞書登録モードか +ら抜け、個人辞書に + +#+BEGIN_EXAMPLE +さいきてき /再帰的/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリが登録されます。カレントバッファのポイントには「再帰的」が +挿入されます。 + +**** 改行文字を含む辞書登録 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +#+KINDEX: C-q C-j +改行文字を含む文字列を辞書に登録するには、辞書登録モードで改行文字を ~C-q C-j~ に +より入力します。例えば、 + +#+BEGIN_EXAMPLE +〒980 +仙台市青葉区片平2-1-1 +東北大学電気通信研究所 +#+END_EXAMPLE + +#+TEXINFO: @noindent +を辞書に登録するには、辞書登録モードで、 + +#+BEGIN_EXAMPLE + 〒980 +C-q C-j + 仙台市青葉区片平2-1-1 +C-q C-j + 東北大学電気通信研究所 +#+END_EXAMPLE + +#+TEXINFO: @noindent +と入力します。 + +** インクリメンタル・サーチ + +#+CINDEX: I-search +#+CINDEX: Incremental search +DDSKK では、専用のインクリメンタル・サーチプログラムを Emacs 添付の +~isearch.el~ のラッパーとして実装しているため、日本語文字列のインクリメン +タル・サーチをアスキー文字と同様の操作で行うことができます。 + +*** skk-isearchの操作性 + +大部分の動作は、Emacs オリジナルのインクリメンタル・サーチのままですから、 +Emacs オリジナルのインクリメンタル・サーチのコマンド [fn:is1] やユーザ変 +数でのカスタマイズ [fn:is2] もそのまま利用できます。 + +インクリメンタル・サーチ中の入力方法は、通常のバッファにおける各入力モー +ド、変換モードでの入力方法と同一です。 + +#+KINDEX: C-r +#+KINDEX: C-s +#+KINDEX: M-C-s +#+KINDEX: M-C-r +~C-s~ や ~C-r~ あるいは ~M-C-s~ や ~M-C-r~ でインクリメンタル・サーチを起 +動すると、インクリメンタル・サーチを起動したバッファの入力モードと同一の +入力モードで、キーとなる文字の入力が可能となります。 + +[fn:is1] ~M-y~ の ~isearch-yank-kill~ 、 ~M-p~ の ~isearch-ring-retreat~ 、 +又は ~M-n~ の ~isearch-ring-advance~ など + +[[info:emacs#Incremental Search][Incremental Search in GNU Emacs Manual]]. + +[fn:is2] ~search-highlight~ など + +*** skk-isearch と入力モード + +入力モードに合わせて、インクリメンタル・サーチのプロンプトが表示されます。 +プロンプトの種類は、以下の6つです。 + + + ~I-search: [か]~ ... かなモード + + + ~I-search: [カ]~ ... カナモード + + + ~I-search: [英]~ ... 全英モード + + + ~I-search: [aa]~ ... アスキーモード + + + ~I-search: [aあ]~ ... Abbrev モード + + + ~I-search: [--]~ ... インクリメンタル・サーチモードで ~C-x C-j~ など + を打鍵して DDSKK を終了した場合は、このプロンプ + トが表示されます。 + +- Variable: skk-isearch-mode-string-alist + + プロンプトとして表示される文字列 + +** チュートリアル + +#+VINDEX: skk-tut-file +#+FINDEX: skk-tutorial +#+KINDEX: M-x skk-tutorial +DDSKK には、基本的な操作方法を学習できるチュートリアルが附属しています。 +日本語版チュートリアルは ~M-x skk-tutorial~ で、英語版チュートリアルは +~C-u M-x skk-tutorial RET English RET~ で実行します。 + +- Variable: skk-tut-file + + チュートリアルファイルが標準の場所に置かれていない場合は、 ~~/.emacs.d/init.el~ で + + #+BEGIN_SRC emacs-lisp + (setq skk-tut-file "/usr/local/share/skk/SKK.tut") + #+END_SRC + + と書くことにより、指定したチュートリアルファイルを使用させることができ + ます。英語版のチュートリアルファイルは、 ~skk-tut-file~ に ~.E~ が付い + たファイル名です。この場合であれば、 ~/usr/local/share/skk/SKK.tut.E~ に + なります。 + +- Variable: skk-tut-lang + + チュートリアルで用いる言語を文字列 "~Japanese~" 又は "~English~" で指定 + します。この変数よりも ~C-u M-x skk-tutorial~ による言語指定が優先され + ます。 + +- Variable: skk-tut-use-face + + ~Non-nil~ であれば、チュートリアルで face を利用して表示します。 + +* 便利な応用機能 + +** ファイル構成 + +SKK の基本的な機能は ~skk.el~ に収められています。一方、DDSKK で応用機能 +を提供するプログラムのほとんどは ~skk.el~ とは別のファイルに収めています。 +これらは、必要に応じてオートロードするように設計されています。各応用機能 +の概略と該当のファイル名について説明します。 + +また、DDSKK の変数は ~skk-vars.el~ に集約されていますので、カスタマイズし +たい場合などには、このファイルを見ると参考になるかもしれません。 + +- ~ccc.el~ + + buffer local cursor color control library + +- ~cdb.el~ + + constant database (cdb) reader for Emacs Lisp + +- ~context-skk.el~ + + 編集の文脈に応じて自動的に skk のモードを切り替えたり、SKK の各種設定を + 変更する機能を提供します。 + + [[文脈に応じた自動モード切り替え][文脈に応じた自動モード切り替え]]. + +- ~ddskk-pkg.el~ + + [[info:elisp#Multi-file Packages][Multi-file Packages in GNU Emacs Lisp Reference Manual]]. + +- ~skk-abbrev.el~ + + SKK abbrev モードの機能を提供するプログラムを集めたファイル。 + + [[アスキー文字を見出し語とした変換][アスキー文字を見出し語とした変換]]. + +- ~skk-act.el~ + + dvorak 配列での拡張ローマ字入力 ACT を SKK で使うための設定を提供しま + す。 + + [[ACT][ACT]]. + +- ~skk-annotation.el~ + + 個人辞書に付けたアノテーション(注釈)を活用するプログラムを集めたファ + イル。 + + [[注釈(アノテーション)][注釈(アノテーション)]]. + +- ~skk-auto.el~ + + 送り仮名の自動処理を行うプログラムを集めたファイル。 + + [[送り仮名の自動処理][送り仮名の自動処理]]. + +- ~skk-autoloads.el~ + + ~make~ 時に自動生成されるファイル。オートロードの設定のほか ~register-input-method~ も + 行う。 XEmacs で DDSKK をパッケージとしてインストールした場合は ~auto-autoloads.el~ と + いうファイルがこれに相当します。 + +- ~skk-azik.el~ + + 拡張ローマ字入力 AZIK の設定を提供します。 + + [[AZIK][AZIK]]. + +- ~skk-bayesian.el~ + + SKK の学習機能のひとつで、ユーザの過去の入力から変換候補を予測します。 + + [[ベイズ統計を用いた学習][ベイズ統計を用いた学習]]. + +- ~skk-cdb.el~ + + CDB 形式辞書ファイルを辞書サーバなしに直接利用できるプログラム。 + +- ~skk-comp.el~ + + 見出し語の補完を行うプログラムを集めたファイル。 + + [[補完][補完]]. + +- ~skk-cursor.el~ + + カーソルの色を制御するプログラムを集めたファイル。 + + [[入力モードを示すカーソル色に関する設定][入力モードを示すカーソル色に関する設定]]. + +- ~skk-cus.el~ + + ~M-x customize-group~ による対話的な設定変更機能の簡易版を提供します。 + + [[Customize による設定変更][Customize による設定変更]]. + +- ~skk-dcomp.el~ + + skk-comp による補完を自動的に実行して見出し語入力を支援します。 + + [[動的補完][動的補完]]. + +- ~skk-develop.el~ + + font-lock 関係のほか、おもに開発者向けのプログラムを集めたファイル。 + + + Key: M-x skk-submit-bug-report, skk-submit-bug-report + + バグレポートのメールバッファを用意する + + + Key: M-x skk-get, skk-get + + 辞書ファイルを一括ダウンロードする + +- ~skk-emacs.el~ + + GNU Emacs の拡張機能を利用するプログラムを集めたファイル。インジケータ + のカラー化や画像表示、ツールティップ利用など。 + +- ~skk-gadget.el~ + + プログラム実行変換を行うプログラムを集めたファイル。 + + [[プログラム実行変換][プログラム実行変換]]. + +- ~skk-hint.el~ + + SKK の変換候補が多いときにヒントを与えて絞りこむ機能を提供します。 + + [[候補の絞り込み][候補の絞り込み]]. + +- ~skk-inline.el~ + + 変換候補のインライン表示機能を集めたファイル。 + + [[変換候補一覧の表示方法][変換候補一覧の表示方法]]. + +- ~skk-isearch.el~ + + DDSKK を併用したインクリメンタル・サーチ機能を提供します。 + + [[I-search 関連][I-search 関連]]. + +- ~skk-jisx0201.el~ + + JIS X 0201 カナ [fn:jisx0201] を利用する機能を提供します。 + +- ~skk-jisx0213.el~ + + JIS X 0213 文字集合を扱うプログラムです。 + +- ~skk-jisyo-edit-mode.el~ + + SKK 辞書を編集するためのメジャーモードを提供します。 + +- ~skk-kakasi.el~ + + KAKASI インターフェイスプログラムを集めたファイル。 + + [[領域の操作][領域の操作]]. + +- ~skk-kanagaki.el~ + + キーボードのかな配列などに対応する枠組みを提供します。現段階では旧 JIS 配 + 列のかなキーボード及び NICOLA 規格の親指シフト配列に対応しています。 + + [[かな入力と親指シフト][かな入力と親指シフト]]. + +- ~skk-kcode.el~ + + 文字コードまたはメニューによる文字入力を行うプログラムを集めたファイル。 + + [[文字コードまたはメニューによる文字入力][文字コードまたはメニューによる文字入力]]. + +- ~skk-leim.el~ + + LEIM 関連プログラムファイル。DDSKK を Emacs の input method として利用 + できるようにします。 + + [[DDSKK を Emacs の Input Method とする][DDSKK を Emacs の Input Method とする]]. + +- ~skk-look.el~ + + ~look~ コマンドとのインターフェイスプログラムを集めたファイル。 + + [[skk-look][skk-look]]. + +- ~skk-lookup.el~ + + Lookup で検索できる辞書を使って単語の候補を出力するプログラム。 + + [[skk-lookup][skk-lookup]]. + +- ~skk-macs.el~ + + 他のファイルで共通して使用するマクロなどを中心にまとめたファイル。 + +- ~skk-num.el~ + + 数値変換を行うプログラムを集めたファイル。 + + [[数値変換][数値変換]]. + +- ~skk-search-web.el~ + + Google CGI API for Japanese Input を利用したかな漢字変換。辞書登録モー + ドに Google サジェストを初期表示する。 + + [[Google CGI API for Japanese Input を利用したかな漢字変換][Google CGI API for Japanese Input を利用したかな漢字変換]]. + +- ~skk-server-completion.el~ + + 拡張された辞書サーバによる見出し語補完機能を利用できます。 + + [[サーバコンプリージョン][サーバコンプリージョン]]. + +- ~skk-server.el~ + + 辞書サーバと通信して変換する機能を提供します。 + + [[サーバ関連][サーバ関連]]. + +- ~skk-setup.el~ + + 自動的に個人設定を行うためのファイル。 + +- ~skk-show-mode.el~ + + カーソル付近に入力モードを表示する機能を提供します。 + +- ~skk-sticky.el~ + + 変換開始位置及び送り開始位置の指定方法を変更可能にする。 + + [[変換位置の指定方法][変換位置の指定方法]]. + +- ~skk-study.el~ + + 直前に確定したいくつかの語との関連性を確認し、候補順を操作する学習効果 + を提供するプログラム。 + + [[変換の学習][変換の学習]]. + +- ~skk-tankan.el~ + + SKK を使って単漢字変換を行うプログラムです。 + + [[単漢字変換][単漢字変換]]. + +- ~skk-tut.el~ + + SKK チュートリアルプログラム。 + + [[チュートリアル][チュートリアル]]. + +- ~skk-tutcode.el~ + + SKK で TUT-code 入力を実現します。 + + [[TUT-code][TUT-code]]. + +- ~skk-vars.el~ + + DDSKK で使われる変数を集約したファイル。 + +- ~skk-version.el~ + + DDSKK のバージョン情報を提供するプログラムファイル。 + +- ~skk-viper.el~ + + VIPER インターフェイスプログラムを集めたファイル。 + + [[VIP/VIPERとの併用][VIP/VIPERとの併用]]. + +- ~skk-xemacs.el~ + + XEmacs の拡張機能を利用するプログラムを集めたファイル。インジケータのカ + ラー化や画像表示、ツールティップ利用など。 + +- ~tar-util.el~ + + utility for tar archive + +[fn:jisx0201] いわゆる半角カナ。以下、このマニュアルでは「半角カナ」と記述します + +** ユーザオプションの設定方法 + +#+CINDEX: ~/.emacs.d/init.el +#+CINDEX: ~/.xemacs/init.el +#+CINDEX: ~/.skk +DDSKK のカスタマイズは、 ~~/.emacs.d/init.el~ あるいは ~~/.skk~ に記述し +ます。また、各ファイルの提供するフックも利用します。上記のファイルやフッ +クを利用した設定がいつ有効になるのか、という点についてここで説明します。 + +*** 設定ファイル + + + ~~/.emacs.d/init.el~ , ~~/.xemacs/init.el~ + + Emacs を起動したときに一度だけ読み込まれます。 + + [[info:emacs#Init File][The Emacs Initialization File in GNU Emacs Manual]]. + + このマニュアルは ~~/.emacs.d/init.el~ という記述で統一しています。 + +#+FINDEX: convert-standard-filename + + ~~/.skk~ + + DDSKK を起動した最初の一度だけ読み込まれます。ファイル名の標準設定 + は OS の種類により異なりますが、実際は Emacs の関数 ~convert-standard-filename~ に + より加工されます。 + + ~~/.skk~ のファイル名は変数 ~skk-init-file~ で変更することができます。 + また、DDSKK にはこのファイルを自動的にバイトコンパイルする機能があり + ます。 + +- Variable: skk-user-directory + + DDSKK は ~~/.skk~ や ~~/.skk-jisyo~ といった複数のファイルを使用します。 + これらのファイルをひとつのディレクトリにまとめて置きたい場合は、変数 ~skk-user-directory~ に + そのディレクトリ名を設定します。標準設定は ~nil~ です。 + + この変数は ~~/.emacs.d/init.el~ で設定してください。DDSKK 起動時に ~skk-user-directory~ が + 指すディレクトリが存在しない場合は、自動的に作られます。 + + #+BEGIN_SRC emacs-lisp + (setq skk-user-directory "~/.ddskk") + #+END_SRC + + この変数を設定した場合(例えば上記 ~~/.ddskk~ )、以下に挙げる各変数の + 標準設定値が変更されます。 + + #+BEGIN_EXAMPLE + 影響を受ける変数 標準設定値 変更後の標準設定値 + skk-init-file ~/.skk ~/.ddskk/init + skk-jisyo ~/.skk-jisyo ~/.ddskk/jisyo + skk-backup-jisyo ~/.skk-jisyo.BAK ~/.ddskk/jisyo.bak + skk-emacs-id-file ~/.skk-emacs-id ~/.ddskk/emacs-id + skk-record-file ~/.skk-record ~/.ddskk/record + skk-study-file ~/.skk-study ~/.ddskk/study + skk-study-backup-file ~/.skk-study.BAK ~/.ddskk/study.bak + skk-bayesian-history-file ~/.skk-bayesian ~/.ddskk/bayesian + skk-bayesian-corpus-file ~/.skk-corpus ~/.ddskk/corpus + #+END_EXAMPLE + + なお、 ~skk-user-directory~ を設定した場合でも、各変数を個別に設定してい + る場合はその個別の設定が優先されます。 + +*** skk-init-file の自動コンパイル + +- Variable: skk-byte-compile-init-file + + ここでは、「DDSKK の設定ファイル」を ~el~ と、「DDSKK の設定ファイルを + バイトコンパイルしたファイル」を ~elc~ とそれぞれ呼ぶこととします。 + + 1. DDSKK の起動時に、この変数の値が ~non-nil~ であれば、 + + 「 ~elc~ が存在しない」又は「 ~elc~ よりも ~el~ が新しい」とき + は、 ~el~ をバイトコンパイルした ~elc~ を生成します。 + + 2. DDSKK の起動時に、この変数の値が ~nil~ であれば、 + + ~elc~ よりも ~el~ が新しいときは、 ~elc~ を消去します。 + + 以上の機能を有効にしたい場合は ~~/.emacs.d/init.el~ に + + #+BEGIN_EXAMPLE + (setq skk-byte-compile-init-file t) + #+END_EXAMPLE + + と記述します。この変数は ~~/.skk~ が読み込まれる前に調べられるた + め、 ~~/.skk~ に上記の設定を記述しても無効です。 + +*** フック + +- Variable: skk-mode-hook + + ~C-x C-j~ と入力して SKK モードに入る度に呼ばれます。主にバッファローカ + ルの設定などを行います。 + +- Variable: skk-auto-fill-mode-hook + + ~C-x j~ と入力してオートフィルモード付きで SKK モードに入る度に呼ばれま + す。主にバッファローカルの設定などを行います。 + +- Variable: skk-load-hook + + ~skk.el~ の読み込みを完了した時点で呼ばれます。 ~~/.skk~ は SKK モード + を起動しなければ読み込まれないのに対し、このフックは ~skk.el~ を読み込 + んだら SKK モードを起動しなくとも呼ばれます。 + +各ファイルの読み込みが完了した直後に呼ばれるフックは以下のとおり。 + +- Variable: skk-act-load-hook + + ~skk-act.el~ + +- Variable: skk-auto-load-hook + + ~skk-auto.el~ + +- Variable: skk-azik-load-hook + + ~skk-azik.el~ + +- Variable: skk-comp-load-hook + + ~skk-comp.el~ + +- Variable: skk-gadget-load-hook + + ~skk-gadget.el~ + +- Variable: skk-kakasi-load-hook + + ~skk-kakasi.el~ + +- Variable: skk-kcode-load-hook + + ~skk-kcode.el~ + +- Variable: skk-num-load-hook + + ~skk-num.el~ + +- Variable: skk-server-load-hook + + ~skk-server.el~ + +#+FINDEX: eval-after-load +~load-hook~ が提供されていないプログラムであっても、ロード完了後に何らか +の設定を行いたい場合は、関数 ~eval-after-load~ を使用します。 + +#+BEGIN_SRC emacs-lisp +(eval-after-load "skk-look" + '( + ... + )) +#+END_SRC + +*** Customize による設定変更 + +Emacs 標準の Customize 機能を使って SKK を設定することもできます。ただし、 +Customize での設定は ~~/.emacs.d/init.el~ での設定と同様に、 ~/.skk~ によ +る設定で上書きされてしまいますので注意してください。 + +#+KINDEX: M-x customize-group +#+KINDEX: M-x skk-emacs-customize +~M-x customize-group~ を実行すると skk の設定を対話的に変更することができ +ます。ミニバッファに ~Customize group:~ とプロンプトが表示されます。 + +#+BEGIN_EXAMPLE +------ Minibuffer ------- +Customize group: (default emacs) * +------ Minibuffer ------- +#+END_EXAMPLE + +ここで ~skk~ と答えると、SKK グループの画面へ展開します。 ~M-x skk-emacs-customize~ と +実行するのも同様です。 + +あるいは、モードラインの SKK インジケータをマウスの右ボタン(第3ボタン) +でクリックすると表示されるメニューから「SKK をカスタマイズ」を選んでも同 +じ画面となります。 + +カスタマイズの使い方は Info ([[info:emacs#Easy Customization][Easy Customization in GNU Emacs Manual]].) を参照してください。 + +skk で設定できる変数の中には、まだこのマニュアルで解説されていないものも +あります。 Customize を使うと、それらについても知ることができます。 + +*** skk-customize による設定変更 + +- Key: M-x skk-customize, skk-customize + + 前述の「Emacs 標準の Customize 機能 ~M-x customize-group~ 」による設定 + が複雑すぎると感じるユーザのために、簡易版として ~M-x skk-customize~ を + 用意しています。これは SKK グループのユーザオプションのうち、よく使うも + のだけ抜粋して設定できるようにしたものです。 + + これは、モードラインの SKK インジケータをマウスの右ボタン(第3ボタン) + でクリックして表示されるメニューから「SKK をカスタマイズ(簡易版)」を選 + んで呼び出すこともできます。 + +** カタカナ、英字入力の便法 + +この節では、カタカナや全英文字を入力するための、便利な方法を説明します。 +単純に各モードを用いる方法については前述 ([[入力モード][入力モード]].) しました。 + +*** かなモードからカタカナを入力 + +#+KINDEX: q +#+CINDEX: トグル変換 +まず、かなモードに入ります。 ~Q~ キーでいったん▽モードにして何かひらがな +を入力し、最後に ~q~ を打鍵すると、カタカナに変換され確定されます。 + +実際には、ひらがな以外からも変換できます。以下のようになります。 + + + カタカナ は ひらがな へ + + ひらがな は カタカナ へ + + 全英文字 は アスキー文字 へ + + アスキー文字 は 全英文字 へ + +細かく言えば、▽マークとポイント間の文字列の種類 [fn:toggle1] をキーとし +て変換が行われます。かなモード、カナモード、どちらでも同じです。 + +このような変換を *トグル変換* と呼びます。以下はトグル変換の例です。 + +#+BEGIN_EXAMPLE +K a t a k a n a + + ------ Buffer: foo ------ + ▽かたかな* + ------ Buffer: foo ------ + +q + + ------ Buffer: foo ------ + カタカナ* + ------ Buffer: foo ------ +#+END_EXAMPLE + +このトグル変換を上手く利用することにより、かなモードのまま一時的にカタカ +ナを入力したり、またその逆を行うことができます。こうすると、例えばひらが +な/カタカナが混在した文章を書くときに、その都度 ~q~ キーを押して入力モー +ドを切り換える必要がありません [fn:toggle2] 。 + +領域を対象としたコマンド ([[領域の操作][領域の操作]].) でも「かな←→カナ」のトグル +変換を行うことができます。 + +[fn:toggle1] 正確には、▽マークの次の位置にある文字列によって文字種を判別 +しているので、途中で文字種類の違う文字が混在していても無視されます。 + +[fn:toggle2] 全英文字とアスキー文字のトグルでの変換を行うこともできます。 +ただし、全英モードやアスキーモードでは ~Q~ やその他の大文字により▽モード +に入ることができないので、かな ⇔ カナ のときと同様にトグル変換できるわけ +ではありません。かなモード/カナモードにおいて、既に入力された全英文字、 +アスキー文字に対してトグル変換をするような設計になっています。 + +*** 全英文字の入力 + +まず、かなモードに入ります。次に ~/~ を打鍵すると SKK abbrev モード [fn:skkabbr] に +入りますのでアルファベット(アスキー文字)を入力します。アルファベットの +入力後に ~C-q~ を打鍵する [fn:C-q] ことで▽マークから ~C-q~ を打鍵した位 +置までの間にあるアルファベットが全角アルファベットに変換されて確定されま +す。 + +#+BEGIN_EXAMPLE +/ f i l e + + ------ Buffer: foo ------ + ▽file* + ------ Buffer: foo ------ + +C-q + + ------ Buffer: foo ------ + file* + ------ Buffer: foo ------ +#+END_EXAMPLE + +なお、この変換を行うために、 + +#+BEGIN_EXAMPLE +file /file/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +のような辞書エントリを持つ必要はありません。なぜなら、辞書を参照せずにア +スキー文字を1文字ずつ全英文字に変換しているからです。 + +[fn:skkabbr] SKK abbrev モードでは ~is~ ⇒ 「インクリメンタル・サーチ」の +ような変換を行うことができます。他の変換と同様に ~SPC~ を押すと変換モード +に入ってしまいますので、 SKK abbrev モードからアスキー文字を入力するのは、 +一語のみの場合以外は不便です。 + +[[アスキー文字を見出し語とした変換][アスキー文字を見出し語とした変換]]. + +[fn:C-q] ~C-q~ は ~skk-abbrev-mode-map~ にて特別な動作をするように定義さ +れています。 + +[[アスキー文字を見出し語とした変換][アスキー文字を見出し語とした変換]]. + +*** 領域の操作 + +以下のコマンドを ~M-x~ により呼ぶことで [fn:menubar] 、領域内の文字列を一 +括変換することができます。 + +- Key: M-x skk-hiragana-region, skk-hiragana-region + + カタカナ を ひらがな へ変換。 + +- Key: M-x skk-katakana-region, skk-katakana-region + + ひらがな を カタカナ へ変換。 + +- Key: M-x skk-latin-region, skk-latin-region + + 全英文字 を アスキー文字 へ変換。 + +- Key: M-x skk-jisx0208-latin-region, skk-jisx0208-latin-region + + アスキー文字 を 全英文字 へ変換。 + +#+CINDEX: 逆引き +以下に紹介する「漢字から読みを求めるコマンド」は、外部プログラム ~KAKASI~ [fn:kakasi]が +必要です。 ~KAKASI~ がインストールされていなければ使用することができません。 + + +- Key: M-x skk-gyakubiki-region, skk-gyakubiki-region + + 漢字をひらがなへ変換。具体的な変換例をあげると、 + + #+BEGIN_EXAMPLE + 漢字をひらがなへ変換。 → かんじをひらがなへへんかん。 + #+END_EXAMPLE + + のようになります。引数を渡して ~C-u M-x skk-gyakubiki-region~ のように + すると、複数の候補がある場合に ~{ }~ で囲って表示します。例えば + + #+BEGIN_QUOTE + ~中島 → {なかしま|なかじま}~ + #+END_QUOTE + + のようになります。 + + 送り仮名がある語は、送り仮名まで含めて領域に指定します(さもないと誤変 + 換の原因となります)。 例えば「五月蝿い」について、送り仮名「い」を含め + ずにこのコマンドを実行すると「ごがつはえ」に変換されてしまいます。 + +- Key: M-x skk-gyakubiki-and-henkan, skk-gyakubiki-and-henkan + + 領域の漢字をひらがなへ変換し、これで得たひらがなを見出し語として漢字変 + 換を実行します。 + +- Key: M-x skk-gyakubiki-katakana-region, skk-gyakubiki-katakana-region + + 漢字をカタカナへ変換。 + + 引数を渡して ~C-u M-x skk-gyakubiki-katakana-region~ のようにすると、 + 複数の候補がある場合に ~{ }~ で囲って表示します。 + +- Key: M-x skk-hurigana-region, skk-hurigana-region + + 漢字にふりがなを付ける。例えば、 + + #+BEGIN_EXAMPLE + 漢字の脇に → 漢字[かんじ]の脇[わき]に + #+END_EXAMPLE + + のようになります。引数を渡して ~C-u M-x skk-hurigana-region~ のようにす + ると、複数の候補がある場合に ~{ }~ で囲って表示します。 + +- Key: M-x skk-hurigana-katakana-region, skk-hurigana-katakana-region + + 漢字にカタカナのふりがなを付ける。 + + 引数を渡して ~C-u M-x skk-hurigana-katakana-region~ のようにすると、複 + 数の候補がある場合に ~{ }~ で囲って表示します。 + +- Key: M-x skk-romaji-region, skk-romaji-region + + 漢字、ひらがな、カタカナをローマ字へ、全英文字をアスキー文字へ変換。標 + 準では、ローマ字への変換様式はヘボン式です。例えば、 + + #+BEGIN_EXAMPLE + し → shi + #+END_EXAMPLE + + となります。 + +以下のコマンドは、領域内の文字列を置き換える代わりに、変換結果をエコーエ +リアに表示します。 + +- Key: M-x skk-gyakubiki-message, skk-gyakubiki-message +- Key: M-x skk-gyakubiki-katakana-message, skk-gyakubiki-katakana-message +- Key: M-x skk-hurigana-message, skk-hurigana-message +- Key: M-x skk-hurigana-katakana-message, skk-hurigana-katakana-message +- Key: M-x skk-romaji-message, skk-romaji-message + +# http://mail.ring.gr.jp/skk/200110/msg00005.html +#+CINDEX: KANWADICTPATH +- Variable: skk-gyakubiki-jisyo-list + + 関数 ~skk-gyakubiki-region~ はコマンド ~kakasi~ を呼び出しています。 + ~kakasi~ には漢字をひらがなへ変換する機能があり、この変換には環境変 + 数 ~KANWADICTPATH~ で指定されている辞書を利用しています。 + + 変数 ~skk-gyakubiki-jisyo-list~ を設定することによって ~kakasi~ へ与え + る辞書を任意に追加することができます。 + 以下のように設定して ~kakasi~ へ個人辞書 ~skk-jisyo~ を与えることによっ + て辞書登録モードで登録したばかりの単語も ~kakasi~ による逆引き変換の対 + 象とすることができます。 + + #+BEGIN_SRC emacs-lisp + (setq skk-gyakubiki-jisyo-list (list skk-jisyo)) + #+END_SRC + +- Variable: skk-romaji-*-by-hepburn + + この変数の値を ~nil~ に設定すると、コマンド ~skk-romaji-{region|message}~ に + よるローマ字への変換様式に訓令式 [fn:roma] を用います。標準設定は ~t~ です。 + + #+BEGIN_EXAMPLE + し → si + #+END_EXAMPLE + +[fn:menubar] メニューバーが使用できる環境では、メニューバーを使ってこれら +の一括変換コマンドを呼び出すことができます。ただし ~kakasi~ がインストー +ルされていない場合は ~kakasi~ を利用する機能が灰色になり使用できません。 + +[[info:emacs#Menu Bars][Menu Bars in GNU Emacs Manual]]. + +[fn:kakasi] [[http://kakasi.namazu.org/][KAKASI - 漢字→かな(ローマ字)変換プログラム]] + +[fn:roma] 昭和29年12月9日付内閣告示第一号によれば、原則的に訓令式(日本式) +を用いるかのように記載されていますが、今日一般的な記載方法は、むしろヘボ +ン式であるようです。 + +*** カタカナの見出し語 + +~q~ の打鍵でかなモード、カナモードを度々切り替えて入力を続けていると、カ +ナモードで誤って▼モードに入ってしまうことがあります。そのため、カナモー +ドで▼モードに入った場合は、まず見出し語をひらがなに変換してから辞書の検 +索に入るよう設計されています。なお、この場合の送りあり変換での送り仮名は、 +カタカナになります。 + +*** 文脈に応じた自動モード切り替え + +#+CINDEX: context-skk.el +#+FINDEX: M-x context-skk-mode +~context-skk.el~ は、編集中の文脈に応じて SKK の入力モードを自動的にアス +キーモードに切り替える等の機能を提供します。 + +~context-skk.el~ をロードするには ~~/.emacs.d/init.el~ に + +#+BEGIN_SRC emacs-lisp +(add-hook 'skk-load-hook + (lambda () + (require 'context-skk))) +#+END_SRC + +#+TEXINFO: @noindent +と書いてください。 + +あるプログラミング言語のプログラムを書いているとき、日本語入力の必要があ +るのは一般に、そのプログラミング言語の文字列中かコメント中に限られます。 +たとえば Emacs Lisp で日本語入力の必要があるのは + +#+BEGIN_SRC emacs-lisp +"文字列" +;; コメント +#+END_SRC + +#+TEXINFO: @noindent +といった個所だけでしょう。文字列・コメントの *外* を編集するときは、多く +の場合は日本語入力は必要ありません。 + +現在の文字列・コメントの *外* で編集開始と同時に(skk がオンであれば) +skk の入力モードをアスキーモードに切り替えます。 +エコーエリアに + +#+BEGIN_EXAMPLE +-------------------- Echo Area -------------------- +[context-skk] 日本語入力 off +-------------------- Echo Area -------------------- +#+END_EXAMPLE + +#+TEXINFO: @noindent +と表示され、アスキーモードに切り替わったことが分かります。これにより、文 +字列・コメントの *外* での編集を開始するにあたって、日本語入力が on にな +っていたために発生する入力誤りとその修正操作を回避することができます。 + +上記の機能は context-skk-mode というマイナーモードとして実装されており +~M-x context-skk-mode~ でオン/オフを制御できます。オンの場合、モードライ +ンのメジャーモード名の隣に「;▽」と表示されます。 + +- Variable: context-skk-programming-mode + + context-skk が「プログラミングモード」と見做すメジャーモード。 + +- Variable: context-skk-mode-off-message + + アスキーモードに切り替わった瞬間にエコーエリアに表示するメッセージ。 + +** 補完 + +読みの前半だけを入力して ~TAB~ を押せば残りを自動的に補ってくれる、これが +補完です。 Emacs ユーザにはおなじみの機能が DDSKK でも使えます。 + +よく使う長い語を効率良く入力するには、アルファベットの略語を登録する方法 +もあります。 + +[[アスキー文字を見出し語とした変換][アスキー文字を見出し語とした変換]]. + +*** 読みの補完 + +#+KINDEX: TAB +▽モードで ~TAB~ を押すと、見出し語(▽マークからポイントまでの文字列)に +対する補完 [fn:abbr] が行われます。見出し語補完は、個人辞書のうち送りなし +エントリに対して行われます。個人辞書に限っているのは、共有辞書では先頭の +文字を共通にする見出し語が多すぎて、望みの補完が行える確率が低いためです。 + +#+KINDEX: , +#+KINDEX: . +次の読みの候補を表示するには ~.~ (ピリオド)を、戻る時には ~,~ (コンマ) +を押します。その読みで別の語を出すには、いつものように ~SPC~ を押します。 + +例を見てみましょう。実際の動作は、個人辞書の内容によって異なります。 +#+BEGIN_EXAMPLE +S a + + ------ Buffer: foo ------ + ▽さ* + ------ Buffer: foo ------ + +TAB + + ------ Buffer: foo ------ + ▽さとう* + ------ Buffer: foo ------ + +. + + ------ Buffer: foo ------ + ▽さいとう* + ------ Buffer: foo ------ + +, + + ------ Buffer: foo ------ + ▽さとう* + ------ Buffer: foo ------ + +SPC + + ------ Buffer: foo ------ + ▼佐藤* + ------ Buffer: foo ------ + +C-j + + ------ Buffer: foo ------ + 佐藤* + ------ Buffer: foo ------ +#+END_EXAMPLE + +補完される見出し語がどのような順で表示されるかと言うと「最近使われた語か +ら」となります。例えば「斉藤」、「佐藤」の順で変換した後、「さ」をキーに +して見出し語の補完を行うと、最初に「さとう」が、その次に「さいとう」が補 +完されます。これは、個人辞書では、最近使われたエントリほど上位に来るよう +になっている ([[辞書の書式][辞書の書式]].) ためです。 + +いったん ~SPC~ を入力して▼モードに入ると、以後は見出し語補完は行われませ +ん。 + +#+KINDEX: C-u TAB +また、 ~.~ の代わりに ~C-u TAB~ を入力すると、現在の候補に対して補完をし +ます。上の例では「さ」に対し「さとう」が補完された時に ~C-u TAB~ を押すと、 +以後の補完は「さとう」を含む語(例えば「さとうせんせい」など)について行 +われます。 + +- Variable: skk-completion-prog-list + + 補完関数、補完対象の辞書を決定するためのリスト。標準設定は以下のとお + り。 + + #+BEGIN_SRC emacs-lisp + '((skk-comp-by-history) + (skk-comp-from-jisyo skk-jisyo) + (skk-look-completion)) + #+END_SRC + +- Variable: skk-comp-circulate + + ~.~ (ピリオド)で次の見出し語候補を、 ~,~ (コンマ)で前の見出し語候補 + を表示するところ、候補が尽きていれば標準設定 ~nil~ では「○○で補完す + べき見出し語は他にありません」とエコーエリアに表示して動作が止まります。 + この変数が ~non-nil~ であれば当初の見出し語を再び表示して見出し語補完を + 再開します。 + +- Variable: skk-try-completion-char + + 見出し語補完を開始するキーキャラクタです。標準設定は ~TAB~ です。 + +- Variable: skk-next-completion-char + + 次の見出し語候補へ移るキーキャラクタです。標準設定はピリオド ~.~ です。 + +- Variable: skk-previous-completion-char + + 前の見出し語候補へ戻るキーキャラクタです。標準設定はコンマ ~,~ です。 + +#+CINDEX: backtab +#+KINDEX: SHIFT TAB +- User Option: skk-previous-completion-use-backtab + + ~Non-nil~ であれば、前の見出し語候補へ戻る動作を ~SHIFT + TAB~ でも可能 + とします。標準設定は ~t~ です。この機能の有効化/無効化の切り替えは、 + ファイル ~~/.skk~ を書き換えて Emacs を再起動してください。 + +- Variable: skk-previous-completion-backtab-key + + ~SHIFT + TAB~ が発行する key event です。Emacs の種類/実行環境によって + 異なります。 + +- Function: skk-comp-lisp-symbol &optional PREDICATE + + この関数をリスト ~skk-completion-prog-list~ へ追加すると、Lisp symbol 名 + の補完を行います。 + + #+BEGIN_SRC emacs-lisp + (add-to-list 'skk-completion-prog-list + '(skk-comp-lisp-symbol) t) + #+END_SRC + +[fn:abbr] 細かい説明です。 ~TAB~ を押す直前に▽モードで入力された文字列を X と +呼ぶことにします。このとき、個人辞書の送りなしエントリの中から「先頭が X と +一致し」かつ「長さが X よりも長い見出し語」を検索して、そのような語が該当 +すれば X の代わりに表示します。 + +*** 補完しながら変換 + +#+KINDEX: M-SPC +前節で見出し語の補完について述べました。本節では、見出し語の補完動作を行 +った後、 ~SPC~ を打鍵し、▼モードに入るまでの動作を一回の操作で行う方法に +ついて説明します。 + +やり方は簡単。 ~TAB~ ・ ~SPC~ と打鍵していたところを ~M-SPC~ に換えると、 +見出し語を補完した上で変換を開始します。 + +この方法によると、補完される見出し語があらかじめ分かっている状況では、キー +入力を一回分省略できるので、読みが長い見出し語の単語を連続して入力する場 +合などに威力を発揮します。 + +#+BEGIN_EXAMPLE +K a s i t a n n p o s e k i n i n n + + ------ Buffer: foo ------ + ▽かしたんぽせきにん* + ------ Buffer: foo ------ + +SPC RET + + ------ Buffer: foo ------ + 瑕疵担保責任* + ------ Buffer: foo ------ + +K a + + ------ Buffer: foo ------ + ▽か* + ------ Buffer: foo ------ + +M-SPC + + ------ Buffer: foo ------ + ▼瑕疵担保責任* + ------ Buffer: foo ------ +#+END_EXAMPLE + +- Variable: skk-start-henkan-with-completion-char + + 標準設定は ~M-SPC~ です。 + +*** 動的補完 + +▽モードでは ~TAB~ を押さなくとも、文字を入力する都度、自動的に見出し語補 +完の読みを表示させる事ができます。この機能を以下「動的補完」と呼びます。 +類似の機能としては、ウェブブラウザの URL の入力や、Microsoft Excel のセル +入力の自動補完 [fn:excel] をイメージすると分かりやすいかも知れません。動 +的補完も、個人辞書の送りなしエントリに対してのみ行なわれます。 + +動的補完を利用するには ~~/.skk~ に次の式を書きましょう。 + +#+BEGIN_SRC emacs-lisp +(setq skk-dcomp-activate t) +#+END_SRC + +例を見てみましょう。実際の動作は、個人辞書の内容によって左右されます。 +~*~ はポイント位置を表します。 + +#+BEGIN_EXAMPLE +H o + + ---------------- Buffer: foo ------------------ + ▽ほ*んとう + ---------------- Buffer: foo ------------------ +#+END_EXAMPLE + +face が使える環境では「んとう」の部分が異なる face で表示され、動的補完機 +能によって補完された部分であることを示します。 + +自動的に補完された見出し語が自分の意図したものであれば ~TAB~ を押すことで +ポイント位置を動かし、補完された見出し語を選択することができます。 + +#+BEGIN_EXAMPLE +TAB + + ---------------- Buffer: foo ------------------ + ▽ほんとう* + ---------------- Buffer: foo ------------------ +#+END_EXAMPLE + +この状態から ~SPC~ を押して変換するなり、 ~q~ を押してカタカナにするなり、 +DDSKK 本来の動作を何でも行うことができます。 + +補完された見出し語が自分の意図したものでない場合は、かまわず次の入力を続 +けて下さい。補完された部分を無視したかのように動作します。 + +#+BEGIN_EXAMPLE +H o + + ---------------- Buffer: foo ------------------ + ▽ほ*んとう + ---------------- Buffer: foo ------------------ + +k a + + ---------------- Buffer: foo ------------------ + ▽ほか*ん + ---------------- Buffer: foo ------------------ +#+END_EXAMPLE + +補完されない状態が自分の意図したものである場合も、補完された部分を単に無 +視するだけで OK です。下記の例では「ほ」を見出し語とした変換を行っていま +す。 + +#+BEGIN_EXAMPLE +H o + + ---------------- Buffer: foo ------------------ + ▽ほ*んとう + ---------------- Buffer: foo ------------------ + +SPC + + ---------------- Buffer: foo ------------------ + ▼保 + ---------------- Buffer: foo ------------------ +#+END_EXAMPLE + +補完された状態から ~BS~ を押すと、消された補完前の見出し語から再度補完動 +作を行います。 + +#+BEGIN_EXAMPLE +H o + + ---------------- Buffer: foo ------------------ + ▽ほ*んとう + ---------------- Buffer: foo ------------------ + +k a + + ---------------- Buffer: foo ------------------ + ▽ほか*ん + ---------------- Buffer: foo ------------------ + +BS + + ---------------- Buffer: foo ------------------ + ▽ほ*んとう + ---------------- Buffer: foo ------------------ +#+END_EXAMPLE + +- Variable: skk-dcomp-activate + + この変数の値が ~Non-nil~ であれば、カーソル位置に関わらず常に動的補完が + 有効となります。値がシンボル ~eolp~ であれば、カーソルが行末にあるとき + に限って動的補完が有効となります。値が ~nil~ であれば、動的補完機能は無 + 効となります。 + +- Variable: skk-dcomp-face + + この変数の値はフェイスであり、このフェイスによって動的に補完された部分が + 装飾されます。標準は DarkKhaki です。 + +- User Option: skk-dcomp-multiple-activate + + *XEmacs では動作しません。* + + ~Non-nil~ であれば、動的補完の候補をインラインに複数表示 [fn:sdma] します。 + + #+BEGIN_EXAMPLE + ---------------- Buffer: foo ------------------ + ▽ほ*んとう +  ほんとう +  ほかん +  ほっかいどう +  ほうほう +  : + ---------------- Buffer: foo ------------------ + #+END_EXAMPLE + + 候補の選択には ~TAB~ 又は ~SHIFT + TAB~ を押します。 + また、普通の補完 ([[読みの補完][読みの補完]].) と同様に ~.~ (ピリオド)と ~,~ (コンマ)も + 利用できます。 + +- Variable: skk-dcomp-multiple-rows + + 動的補完の候補を複数表示する場合の表示行数。標準は 7。 + +- Variable: skk-dcomp-multiple-face + + 動的補完の複数表示群のフェイス。上記例では「ほ」のフェイス。 + +- Variable: skk-dcomp-multiple-trailing-face + + 動的補完の複数表示群の補完部分のフェイス。上記例では「んとう」、「かん」 + 「っかいどう」、「うほう」のフェイス。 + +- Variable: skk-dcomp-multiple-selected-face + + 動的補完の複数表示群の選択対象のフェイス。上記例では ~TAB~ を押すたびに + 「ほんとう」、「ほかん」、「ほっかいどう」と選択位置が移ります。その現 + 在選択位置に適用するフェイスです。 + +[fn:excel] 同じ列に既に入力している文字列があったときにそれを参照して補完 +しようとする機能 + +[fn:sdma] 現在は候補群の右側1カラムのフェイスが標準設定に戻る、という +制約があります。 + +** 便利な変換、その他の変換 + +*** 単漢字変換 + +ファイル ~skk-tankan.el~ を読み込むことによって単漢字変換が可能となります。 +候補は総画数の昇順でソートして表示します。 + +単漢字変換を使うには設定が必要ですが、先に例を見てみましょう。▽モードの +最後の文字に ~@~ を付して変換を開始してください。 + +# #+BEGIN_EXAMPLE .. #+END_EXAMPLE だと、export texinfo で @ が消失する +#+BEGIN_SRC emacs-lisp +T a n @ + + ----- Buffer: foo ----- + ▽たん@* + ----- Buffer: foo ----- + +SPC + + ----- Buffer: foo ----- + ▼丹* + ----- Buffer: foo ----- + + ----- Echo Area ----- + 4画(丶部3画) + ----- Echo Area ----- + +SPC + + ----- Buffer: foo ----- + ▼反* + ----- Buffer: foo ----- + + ----- Echo Area ----- + 4画(又部2画) + ----- Echo Area ----- + +SPC + + ----- Buffer: foo ----- + ▼旦* + ----- Buffer: foo ----- + + ----- Echo Area ----- + 5画(日部1画) + ----- Echo Area ----- + +SPC + + ----- Buffer: foo ----- + ▼但* + ----- Buffer: foo ----- + + ----- Echo Area ----- + 7画(人部5画) + ----- Echo Area ----- + +SPC + + ----- Buffer: foo ----- + ▼* + ----- Buffer: foo ----- + + ----- Buffer: *候補* ----- + A:坦;8画(土部5画) + S:担;8画(手部5画) + D:単;9画(十部7画) + F:彖;9画(彑部6画) + J:炭;9画(火部5画) + K:眈;9画(目部4画) + L:胆;9画(肉部5画) + [残り 50+++++] +----- Buffer: *候補* ----- +#+END_SRC + +以上のとおり、総画数の昇順でソートされた候補が次々に表示されます。 + +**** 検索キーの設定 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +標準設定の検索キーは ~@~ です。DDSKK の標準設定ではキー ~@~ は +関数 ~skk-today~ の実行に割り当てられていますが、DDSKK 14.2 からは特段の +設定なしに▽モードで ~@~ の打鍵が可能となりました。 + +- User Option: skk-tankan-search-key + + 単漢字変換の検索キー。以下は、検索キーを ~!~ へと変更する例です。 + + #+BEGIN_SRC emacs-lisp + (setq skk-tankan-search-key ?!) + #+END_SRC + +**** 辞書の設定 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +DDSKK 14.2 からは標準で変数 ~skk-search-prog-list~ に ~skk-tankan-search~ が +含まれています。DDSKK 14.1 を利用の方、ご自身で ~skk-search-prog-list~ を +設定する方は以下の解説を参考にしてください。 + +~skk-tankan.el~ には、漢字の部首とその中での画数のデータのみが入っていま +す。読みのデータは、普通の辞書ファイルを使います。 + +単漢字変換の辞書の設定は、変数 ~skk-search-prog-list~ に以下の形式で要素 +を追加します。 + +#+BEGIN_SRC emacs-lisp +(skk-tankan-search 'function . args) +#+END_SRC + +*確定変換* を併用する場合は、 ~skk-search-prog-list~ の先頭の要素は + ~skk-search-kakutei-jisyo-file~ でなければいけませんので、 +~skk-search-prog-list~ の2番目の要素に ~skk-tankan-search~ を追加します。 + +#+BEGIN_SRC emacs-lisp +;; skk-search-prog-list の2番目の要素に skk-tankan-search を追加する +(setq skk-search-prog-list + (cons (car skk-search-prog-list) + (cons '(skk-tankan-search 'skk-search-jisyo-file + skk-large-jisyo 10000) + (cdr skk-search-prog-list)))) +#+END_SRC + +なお、確定変換を使用しない場合は、 ~skk-search-prog-list~ の要素の先頭 +が ~skk-tankan-search~ でも大丈夫です。 + +#+BEGIN_SRC emacs-lisp +(add-to-list 'skk-search-prog-list + '(skk-tankan-search 'skk-search-jisyo-file + skk-large-jisyo 10000)) +#+END_SRC + +[[辞書の検索方法の設定][辞書の検索方法の設定]]. + +**** 総画数による単漢字変換 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +#+KINDEX: C-u 総画数 M-x skk-tankan +▽モードで総画数を入力して最後に ~@~ を付してから変換を開始します。 +~C-u 総画数 M-x skk-tankan~ でも可能です。 + +# #+BEGIN_EXAMPLE .. #+END_EXAMPLE だと、export texinfo で @ が消失する +#+BEGIN_SRC emacs-lisp +Q 1 0 @ + + ----- Buffer: foo ----- + ▽10@* + ----- Buffer: foo ----- + +SPC + + ----- Buffer: *候補* ----- + A:倹;10画(人部8画) + S:倦;10画(人部8画) + D:個;10画(人部8画) + F:候;10画(人部8画) + J:倖;10画(人部8画) + K:借;10画(人部8画) + L:修;10画(人部8画) + [残り 532+++++++] + ----- Buffer: *候補* ----- +#+END_SRC + +**** 部首による単漢字変換 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +▽モードで ~@~ を2つ重ねて変換を開始すると、部首による単漢字変換が +できます。 ~M-x skk-tankan~ でも可能です。 + +# #+BEGIN_EXAMPLE .. #+END_EXAMPLE だと、export texinfo で @ が消失する +#+BEGIN_SRC emacs-lisp +Q @ @ + + ----- Buffer: foo ----- + ▽@@* + ----- Buffer: foo ----- + +SPC + + ------ Minibuffer ------- + 部首を番号で選択(TABで一覧表示): * + ------ Minibuffer ------- + +TAB + + ------ *Completions* ------- + Click on a completion to select it. + In this buffer, type RET to select the completion near point. + + Possible completions are: + 001 一 (いち) 002 | (ぼう、たてぼう) + 003 丶 (てん) 004 丿 (の) + 005 乙 (おつ) 006 亅 (はねぼう) + : : + ------ *Completions* ------- + +0 1 8 RET +注) M-v の打鍵で、カーソルを *Completions* バッファへ移すこともできます。 + + ----- Buffer: *候補* ----- + A:切;4画(刀部2画) + S:刈;4画(刀部2画) + D:刊;5画(刀部3画) + F:刋;5画(刀部3画) + J:刎;6画(刀部4画) + K:刑;6画(刀部4画) + L:刔;6画(刀部4画) + [残り 51+++++++] + ----- Buffer: *候補* ----- +#+END_SRC + +- Variable: skk-tankan-face + + ~M-x skk-tankan~ を実行したときに表示される *単漢字バッファ* で使用する + フェイスです。 + +- Variable: skk-tankan-radical-name-face + + 部首の読みに適用するフェイスです。 + +**** 部首の読みによる単漢字変換 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +直前の小々節「部首による単漢字変換」にて、部首番号を入力するプロンプトで +単に ~RET~ を打鍵すると、部首の読みを入力するプロンプトに替わります。 + +#+BEGIN_EXAMPLE + ------ Minibuffer ------- + 部首を読みで選択(TABで一覧表示): * + ------ Minibuffer ------- + +TAB + + ------ Completion List ------- + In this buffer, type RET to select the completion near point. + + Possible completions are: + あいくち (021) 匕 あお (174) 青 + あか (155) 赤 あくび (076) 欠 + あさ (200) 麻 あさかんむり (200) 麻 + : : + ------ Completion List ------- +#+END_EXAMPLE + +*** 候補の絞り込み + +~skk-hint.el~ は、2つの読みの積集合みたいなものを取ることによって候補の +絞り込みを行うプログラムです。インストールは ~~/.skk~ に以下を記入します。 + +#+BEGIN_SRC emacs-lisp +(require 'skk-hint) +#+END_SRC + +例えば、読み「かんどう」に対する変換は L 辞書によると + +#+BEGIN_EXAMPLE +感動、勘当、完動、間道、官道、貫道 +#+END_EXAMPLE + +#+TEXINFO: @noindent +と複数の候補があります。一方、これに「あいだ」という「他の読み」(ヒント) +を与えると候補は「間道」に一意に決まります。 + +ヒントは ~;~ に続けて入力します。 + +#+BEGIN_EXAMPLE +K a n d o u ; a i d a ※ ; 自体は表示されません。 + + ----- Buffer: foo ----- + ▽かんどうあいだ + ----- Buffer: foo ----- + +SPC + + ----- Buffer: foo ----- + ▼間道 + ----- Buffer: foo ----- +#+END_EXAMPLE + +~skk-hint.el~ は、2つの読みの厳密な積集合を取っているわけではなく、通常 +の変換候補のなかでヒントとして与えられた読みを含んだ漢字を持つものに候補 +を絞ります。この実例として「感動」と「感圧」を挙げます。 + +#+BEGIN_EXAMPLE +K a n d o u ; k a n n a t u + + ----- Buffer: foo ----- + ▽かんどうかんあつ + ----- Buffer: foo ----- + +SPC + + ----- Buffer: foo ----- + ▼感動 + ----- Buffer: foo ----- +#+END_EXAMPLE + +~skk-hint.el~ は単漢字の候補がたくさんある場合に、そこから候補を絞りこむ +手段としても非常に有効です。例えば + +#+BEGIN_EXAMPLE +▽わ* +#+END_EXAMPLE + +#+TEXINFO: @noindent +を変換すると、輪、環、話、和、羽、... と大量に候補が出てきます。この中か +ら「和」を選びたいとします。普通に変換していてもそのうち「和」が表示され +ますが、これを ~W a ; h e i w a~ と入力し変換すると、「▼へいわ」の候補で +ある「平和」に含まれる + +#+BEGIN_EXAMPLE +▼和* +#+END_EXAMPLE + +#+TEXINFO: @noindent +が唯一の候補となります。 + +#+BEGIN_EXAMPLE +W a ; h e i w a + + ----- Buffer: foo ----- + ▽わへいわ* + ----- Buffer: foo ----- + +SPC + + ----- Buffer: foo ----- + ▼和* + ----- Buffer: foo ----- +#+END_EXAMPLE + +- User Option: skk-hint-start-char + + ヒント変換を開始するキーを character で指定します。 + +*** 接頭辞・接尾辞 + +接頭辞 (prefix)、接尾辞 (suffix) の入力のために特別な方法が用意されていま +す。たとえば、「し」の候補は沢山あり、「し」から「氏」を変換するのは、そ +のままでは効率が悪いです。接尾辞の「し」ならば、「氏」や「市」が優先され +るでしょう。 + +接頭辞・接尾辞は、辞書の中では ~>~ などで示されます。 + +#+BEGIN_EXAMPLE +>し /氏/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリがあるとき、「小林氏」を接尾辞入力を用いて、以下のように入 +力することができます。 + +#+BEGIN_EXAMPLE +K o b a y a s h i + + ------ Buffer: foo ------ + ▽こばやし* + ------ Buffer: foo ------ + +SPC + + ------ Buffer: foo ------ + ▼小林* + ------ Buffer: foo ------ + +> + + ------ Buffer: foo ------ + 小林▽>* + ------ Buffer: foo ------ + +s i + + ------ Buffer: foo ------ + 小林▽>し* + ------ Buffer: foo ------ + +SPC + + ------ Buffer: foo ------ + 小林▼氏* + ------ Buffer: foo ------ + + +C-j + + ------ Buffer: foo ------ + 小林氏* + ------ Buffer: foo ------ +#+END_EXAMPLE + +接頭辞も同様です。辞書に + +#+BEGIN_EXAMPLE +ちょう> /超/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリがあるとき、「超大型」を接頭辞入力を用いて、以下のように入 +力することができます。 + +#+BEGIN_EXAMPLE +T y o u + + ------ Buffer: foo ------ + ▽ちょう* + ------ Buffer: foo ------ + +> + + ------ Buffer: foo ------ + ▼超* + ------ Buffer: foo ------ + +O o g a t a + + ------ Buffer: foo ------ + 超▽おおがた* + ------ Buffer: foo ------ + +SPC + + ------ Buffer: foo ------ + 超▼大型* + ------ Buffer: foo ------ + +C-j + + ------ Buffer: foo ------ + 超大型* + ------ Buffer: foo ------ +#+END_EXAMPLE + +キー ~>~ を押しただけで ~SPC~ が押されたかのように変換されます。他の接頭 +辞を選びたいときは ~SPC~ を押して下さい。 + +- Variable: skk-special-midashi-char-list + + ▽モードまたは▼モードにおいて、この変数の値に含まれる文字の入力があっ + た場合、接頭辞・接尾辞の入力を開始します。この変数の標準設定は、 + + #+BEGIN_SRC emacs-lisp + (?> ?< ??) + #+END_SRC + + です。つまり、 ~>~ と ~<~ と ~?~ を入力した時に接頭辞・接尾辞入力を行い + ます。 ~?~ を入力したときに接頭辞・接尾辞入力を行わない場合は ~?~ を外 + して + + #+BEGIN_SRC emacs-lisp + (setq skk-special-midashi-char-list '(?> ?<)) + #+END_SRC + + とします。L 辞書の接頭・接尾辞は、昔は ~<~ と ~?~ も使われていましたが、 + 現在は ~>~ に統一されています。 + +*** 数値変換 + +DDSKK は *数字を含む見出し語* を様々な候補に変換することができます。例え +ば、見出し語「だい12かい」を変換すると「第12回」、「第一二回」、「第十 +二回」といった候補を挙げます。 + +この節では、このような候補を辞書に登録する方法を説明します。基本は、数字 +の部分を ~#~ で置き替えることです。辞書 ~SKK-JISYO.L~ のエントリーから具 +体例を見てみましょう。 + +#+BEGIN_EXAMPLE +だい#かい /第#1回/第#0回/第#2回/第#3回/第 #0 回/ +#+END_EXAMPLE + +「だい12かい」のような *数字を含む見出し語* を変換した場合、見出し語の中 +の数字の部分は自動的に ~#~ に置き換えられますので、辞書エントリーの左辺( +つまり見出し語)である "~だい#かい~" にマッチします。 + +辞書エントリーの右辺の ~#1~ 、 ~#2~ などは「どのように数字を加工するか」 +のタイプを表します。以下、各タイプについて説明します。 + +- ~#0~ + + 無変換。入力されたアスキー文字をそのまま出力します。例えば、「第12回」 + のような変換を得るために使います。 + +- ~#1~ + + 全角文字の数字。 ~12~ を「12」に変換します。 + +- ~#2~ + + 漢数字で位取りあり。 ~1024~ を「一〇二四」に変換します。 + +- ~#3~ + + 漢数字で位取りなし。 ~1024~ を「千二十四」に変換します。 + +- ~#4~ + + 数値再変換。見出し語中の数字そのもの [fn:t4] をキーとして辞書を再検索し、 ~#4~ の + 部分を再検索の結果の文字列で入れ替えます。これについては後で例を挙げて + 説明します。 + +- ~#5~ + + 小切手や手形の金額記入の際用いられる表記で変換します。例えば、 ~1995~ を + 「壱阡九百九拾伍」に変換します。これを大字と言います。 + +- ~#8~ + + 桁区切り。 ~1234567~ を ~1,234,567~ に変換します。 + +- ~#9~ + + 将棋の棋譜の入力用。「全角数字+漢数字」に変換します。これについては後 + で例を挙げて説明します。 + +以下にいくつか例を示します。辞書に + +#+BEGIN_EXAMPLE +# /#3/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリがあるときに、 + +#+BEGIN_EXAMPLE +Q 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 SPC + または +/ 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 SPC +#+END_EXAMPLE + +#+TEXINFO: @noindent +とキー入力 [fn:number] すれば「百兆二千三億四十万五百」と変換されます。 + +辞書に + +#+BEGIN_EXAMPLE +#m#d /#0月#0日/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリがあるときに ~/ 2 m 2 5 d SPC~ と入力 [fn:ascii] すれ +ば「2月25日」と変換されます。 + +辞書に + +#+BEGIN_EXAMPLE +#kin /#9金/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリがあるときに ~/ 3 4 k i n SPC~ と入力すれば「3四金」と変換 +されます。 + +辞書に + +#+BEGIN_EXAMPLE +p# /#4/ +125 /東京都葛飾区/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリがあるときに ~/ p 1 2 5 SPC~ と入力すれば、見出し語 ~p125~ の +候補が ~#4~ なので、見出し語の数字部分の ~125~ に対し辞書が再検索さ +れ「東京都葛飾区」と変換されます。 + +最後に、実際に登録する例をひとつ挙げます。「2月25日」を得るために、 + +#+BEGIN_EXAMPLE +Q 2 g a t u 2 5 n i t i SPC +#+END_EXAMPLE + +#+TEXINFO: @noindent +とキー入力したときに、辞書に見出し語 + +#+BEGIN_EXAMPLE +#がつ#にち /#1月#1日/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +がないときは、辞書登録モードのプロンプトは ~「#がつ#にち」~ となります。 +全角数字のタイプは ~#1~ なので ~「#1月#1日」~ をミニバッファで作り登録し +ます。 + +タイプを覚えている必要はありません。ちゃんと、ウィンドウが開かれて説明が +表示されます。 + +- User Option: skk-num-convert-float + + この変数の値を ~non-nil~ に設定すると、浮動小数点数を使った見出し語に対 + 応して数値変換を行います。ただし、辞書において + + #+BEGIN_EXAMPLE + #.# /#1.#1/#0月#0日/ + #+END_EXAMPLE + + などの見出し語が使用できなくなります。 + +- User Option: skk-show-num-type-info + + ~Non-nil~ であれば、辞書登録モードに入るのと同時に変換タイプの案内を表 + 示します。標準設定は ~t~ です。 + +- Variable: skk-num-grouping-separator + + タイプ ~#8~ で使用する記号。標準設定は ~,~ 。 + +- Variable: skk-num-grouping-places + + タイプ ~#8~ について、何桁毎に区切るのかを数値で指定する。標準設定は 3。 + +- User Option: skk-use-numeric-conversion + + この変数を ~nil~ に設定すると、本節で説明した数値変換の機能を全て無効に + します。 + +[fn:t4] ~p125~ という見出し語であれば、その数値部分である ~125~ が再変換 +の見出し語となります。 + +[fn:number] SHIFT キーを伴って数字を入力し始めることはできないので ~Q~ ま +たは ~/~ で▽モードに入る必要があります。 + +[fn:ascii] ~m~ や ~d~ などアスキー文字を見出し語として入力する場合は ~/~ キー +を最初に入力して SKK abbrev モードに入ってから入力する必要があります。 + +[[アスキー文字を見出し語とした変換][アスキー文字を見出し語とした変換]]. + +*** アスキー文字を見出し語とした変換 + +#+CINDEX: SKK abbrev mode +かなモードで ~/~ を打鍵すると *SKK abbrev モード* に入り、以後の入力はアス +キー文字になります。普通に ~SPC~ を押すと、その見出し語に係る変換が得られ +ます。 + +仮に、辞書に + +#+BEGIN_EXAMPLE +is /インクリメンタル・サーチ/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリがあるとして、以下に例を示します。 + +#+BEGIN_EXAMPLE +/ + + ------ Buffer: foo ------ + ▽* + ------ Buffer: foo ------ + +i s + + ------ Buffer: foo ------ + ▽is* + ------ Buffer: foo ------ + +SPC + + ------ Buffer: foo ------ + ▼インクリメンタル・サーチ* + ------ Buffer: foo ------ + +C-j + + ------ Buffer: foo ------ + インクリメンタル・サーチ* + ------ Buffer: foo ------ +#+END_EXAMPLE + +候補を確定すると SKK abbrev モードを抜けて かなモード に戻ります。 + +SKK abbrve モードで使われる辞書は、普通のかな漢字変換と同じです。見出し語 +がアスキー文字で書かれているだけで、特殊な点はありません。 + +上記の例において ~SPC~ の代わりに ~C-q~ を打鍵することで、入力したアスキー +文字をそのまま全角アルファベットに変換することもできます。 + +[[全英文字の入力][全英文字の入力]]. + +なお、SKK abbrev モードにおいても ~TAB~ による「見出し語の補完」 ([[補完][補完]].) を +行うことができます。 + +*** 今日の日付の入力 + +#+CINDEX: プログラム実行変換 +かなモード/カナモードで ~@~ を入力すれば、今日の日付が入力されます。 + +日付の形式は以下の変数により決定されます。 + +- User Option: skk-date-ad + + この変数の値が ~non-nil~ であれば西暦で、 ~nil~ であれば元号で表示しま + す。標準設定は ~nil~ です。 + +- Variable: skk-number-style + + この変数の値は以下のように解釈されます。標準設定は ~1~ です。 + + + ~0~ or ~nil~ + + ASCII 数字。「1996年7月21日(日)」のようになります。 + + + ~1~ or ~t~ + + 全角数字。「1996年7月21日(日)」のようになります。 + + + ~2~ + + 漢数字(位取)。「一九九六年七月二一日(日)」のようになります。 + + + ~3~ + + 漢数字。「千九百九十六年七月二十一日(日)」のようになります。 + +上記の「1996年」、「1996年」、「一九九六年」の部分は、変数 ~skk-date-ad~ の +値が ~nil~ であれば「平成8年」のように元号で表示されます。 + +辞書 ~SKK-JISYO.lisp~ には、見出し語 ~today~ の候補として ~skk-date-ad~ と ~skk-number-style~ の +全ての組み合わせがプログラム実行変換機能を用いて登録されています。従って、 +~/ t o d a y SPC~ と入力すると、今日の日付が上記の形式で順次候補として表 +示されます。 + +関数 ~skk-relative-date~ を利用すると、昨日、一昨日、明後日など任意の日付 +を求めることができます。詳細は ~skk-gadget.el~ のコメントを参照してくださ +い。 + +なお、 ~@~ の打鍵で日付を挿入するのではなく、文字どおり ~@~ を挿入したい +場合は次のとおり。 + +#+BEGIN_SRC emacs-lisp +(setq skk-rom-kana-rule-list + (append skk-rom-kana-rule-list + '(("@" nil "@")))) +#+END_SRC + +*** プログラム実行変換 + +辞書の候補に Emacs Lisp のプログラムが書いてあれば、そのプログラムを Emacs に +実行させ、返り値をカレントバッファに挿入します。これを *プログラム実行変換* と +呼んでいます。例えば、辞書に + +#+BEGIN_EXAMPLE +now /(current-time-string)/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリがあるとします。このとき ~/ n o w SPC~ とキー入力すれば、現 +在のバッファに関数 ~current-time-string~ の返り値である + +#+BEGIN_EXAMPLE +Sun Jul 21 06:40:34 1996 +#+END_EXAMPLE + +#+TEXINFO: @noindent +のような文字列が挿入されます。 + +ここで、プログラムの返り値は文字列である必要があります。また、プログラム +実行変換の辞書登録は通常の単語と同様に行うことができますが、その中に改行 +を含まないように書く必要 [fn:newline] があります。 + +今日の日付の入力 [fn:today] で説明した ~today~ の辞書エントリは、実際は下 +記のようなプログラムを候補にもっています。 + +#+BEGIN_SRC emacs-lisp +today /(let ((skk-date-ad) (skk-number-style t)) (skk-today))/.../ +#+END_SRC + +~skk-gadget.el~ には、西暦/元号変換や簡単な計算などプログラム実行変換用 +の関数が集められています。 + +- Function: skk-calc operator + + ~skk-calc~ は、引数をひとつ取り、見出し語の数字に対しその演算を行う簡単 + な計算プログラムです。 + + #+BEGIN_SRC emacs-lisp + (defun skk-calc (operator) + ;; 2つの引数を取って operator の計算をする。 + ;; 注意: '/ は引数として渡せないので (defalias 'div '/) などとし、別の形で + ;; skk-calc に渡す。 + ;; 辞書エントリの例 -> #*# /(skk-calc '*)/ + (number-to-string (apply operator + (mapcar 'string-to-number + skk-num-list)))) + #+END_SRC + + この関数を実際にプログラム実行変換で利用するには、辞書に以下のようなエ + ントリを追加します [fn:num] 。 + + #+BEGIN_EXAMPLE + #*# /(skk-calc '*)/ + #+END_EXAMPLE + + ~Q 1 1 1 * 4 5 SPC~ とキー入力します。ここで ~111~ と ~45~ の2つの数字 + は、変換時に ~("111" "45")~ のような文字列のリストにまとめられ、 + 変数 ~skk-num-list~ の値として保存されます。次に関数 ~skk-calc~ が呼ば + れます。この中で ~skk-num-list~ の各要素に対し演算を行うため、各要素は + 数に変換されます。その上で ~skk-calc~ に与えられた引数(この場合は ~*~ ) + を演算子として演算を行います。 + +- Function: skk-gadget-units-conversion 基準単位 数値 変換単位 + + 数値について、基準単位から変換単位への変換を行います。 + + #+BEGIN_EXAMPLE + / 1 3 m i l e + + ------ Buffer: foo ------ + ▽13mile* + ------ Buffer: foo ------ + + SPC + + ------ Buffer: foo ------ + ▼20.9209km* + ------ Buffer: foo ------ + + RET + + ------ Buffer: foo ------ + 20.9209km* + ------ Buffer: foo ------ + #+END_EXAMPLE + + 単位変換の情報は、変数 ~skk-units-alist~ で定義されています。 + +- Variable: skk-units-alist + + この変数は以下の形式の連想リストです。 + + #+BEGIN_EXAMPLE + (基準となる単位 (変換する単位 . 変換時の倍率) + (… . …)) + #+END_EXAMPLE + + 関数 ~skk-gadget-units-conversion~ で利用されています。標準設定では、 + 以下の単位変換の情報を定義しています。 + + #+BEGIN_SRC emacs-lisp + ("mile" ("km" . 1.6093) + ("yard" . 1760)) + + ("yard" ("feet" . 3) + ("cm" . 91.44)) + + ("feet" ("inch" . 12) + ("cm" . 30.48)) + + ("inch" ("feet" . 0.5) + ("cm" . 2.54)) + #+END_SRC + +- Function: skk-relative-date pp-function format and-time &key (yy 0) (mm 0) (dd 0) + + ~skk-current-date~ の拡張版。 ~PP-FUNCTION~ , ~FORMAT~ , ~AND-TIME~ の + 意味は ~skk-current-date~ の docstring を参照のこと。 + キーワード変数 ~:yy~ , ~:mm~ , ~:dd~ に正または負の数値を指定することで + 明日、明後日、一昨日などの日付を求めることができる。詳細は ~skk-gadget.el~ の + コメントを参照のこと。 + +[fn:today] [[今日の日付の入力][今日の日付の入力]]. + +[fn:num] [[数値変換][数値変換]]. + +[fn:newline] 通常の単語では、改行を含むことが可能です。それは、評価すると +その位置に改行を挿入するような実行変換プログラムに変換して辞書に書き込ん +でいるからです。 + +[[辞書の種類][辞書の種類]]. + +しかし、実行変換されるプログラムを辞書登録する際にはこの +機能を利用できないため、改行を含むことができません。 + +*** 空白・改行・タブを含んだ見出し語の変換 + +変換の際、見出し語の中の空白、改行、タブは無視されます。 + +#+BEGIN_EXAMPLE + ---------------- Buffer: foo ------------------ + ▽じんじょうしょ + うがっこう* + ---------------- Buffer: foo ------------------ + +SPC + + ---------------- Buffer: foo ------------------ + ▼尋常小学校* + ---------------- Buffer: foo ------------------ +#+END_EXAMPLE + +オートフィルモードで折り返された文字列に対し、折り返された状 +態のまま変換することもできます。 + +#+BEGIN_EXAMPLE + ---------------- Buffer: foo ------------------ + 仮名漢字変換プログラムをさ + くせいしました。* + ---------------- Buffer: foo ------------------ + +C-u 10 C-b Q + + ---------------- Buffer: foo ------------------ + 仮名漢字変換プログラムを*さ + くせいしました。 + ---------------- Buffer: foo ------------------ + +C-u 5 C-f + + ---------------- Buffer: foo ------------------ + 仮名漢字変換プログラムを▽さ + くせい*しました。 +---------------- Buffer: foo ------------------ + +SPC + + ---------------- Buffer: foo ------------------ + 仮名漢字変換プログラムを▼作成*しました。 + ---------------- Buffer: foo ------------------ +#+END_EXAMPLE + +ここでは改行を越えて見出し語を探し、変換する例を示しました。同様に、空白、 +タブ文字を中間に含む文字列に対しても変換を行うことができます。 + +- User Option: skk-allow-spaces-newlines-and-tabs + + この変数を ~nil~ に設定すると、本節で説明したような2行以上にまたがる文 + 字列に対する変換を禁止します。 + +*** カタカナ変換 + +- Variable: skk-search-katakana + + 通常、SKK でカタカナ語を入力するには、 + + + ~q~ でカナモードに移ってからカタカナを入力する + + + ▽モードで ~q~ によりカタカナへ変換する [fn:sktkn1] + + のどちらかです。これらの方法は手軽ですが、個人辞書に登録されないため見 + 出し語の補完候補にも現れず、何度でも入力しなければなりません。 + + そこで、ここに紹介する方法ではカタカナ語が普通の変換候補として現れ、個 + 人辞書にも登録されます。設定するには以下を ~~/.skk~ に記述します [fn:sktkn2] 。 + + #+BEGIN_SRC emacs-lisp + (setq skk-search-katakana t) + #+END_SRC + + また、値をシンボル ~jisx0201-kana~ とすると、カタカナ候補に加え半角カタ + カナ候補も変換候補に現れます。 + + #+BEGIN_SRC emacs-lisp + (setq skk-search-katakana 'jisx0201-kana) + #+END_SRC + +[fn:sktkn1] [[かなモードからカタカナを入力][かなモードからカタカナを入力]]. + +[fn:sktkn2] ~skk-search-prog-list~ の設定をユーザが変更している場合は期待 +どおりに動作しない場合があります。その場合は ~skk-search-prog-list~ の設 +定に関数 ~skk-search-katakana~ の呼び出しがあることを確認してください。 +またこの機能の設定は DDSKK 14.1 以前では異なります。詳しくはソースに付属 +のドキュメント、設定例をご覧ください。 + +*** サ変動詞変換 + +- Variable: skk-search-sagyo-henkaku + + 通常、SKK では諸般の事情によりサ行変格活用の動詞は送りなし変換をする前 + 提になっています。このことは共有辞書のメンテナンスにおける便宜上やむを + えないのですが、個人辞書が育たない(サ変動詞と名詞の区別ができない)と + いう弱点もあります。 + + [[サ変動詞の辞書登録に関する注意][サ変動詞の辞書登録に関する注意]]. + + しかし、ここに紹介する方法では任意の送りなし候補を利用してサ行の送りプ + レフィックスに限定して送りあり変換が可能になり、個人辞書を育てることが + 可能になります。設定するには以下を ~~/.skk~ に記述します [fn:sssh] 。 + + #+BEGIN_SRC emacs-lisp + (setq skk-search-sagyo-henkaku t) + #+END_SRC + + 例えば「お茶する」の変換は以下のように変化します。 + + + 従来 … ~O c h a SPC s u r u~ + + + サ変 … ~O c h a S u r u~ + + 変数の値をシンボル ~anything~ に設定すると、サ行に限らず任意の送り仮名 + を許可し、送りあり変換をします。これにより、送りあり変換の利用範囲を形 + 容詞・動詞の変換のみならず、あらゆるひらがな開始点の指定に拡張すること + ができます。 + + このサ変動詞送りあり変換機能は、カタカナ変換機能 ([[カタカナ変換][カタカナ変換]].) と + 組み合わせるとさらに有効です。 + +[fn:sssh] ~skk-search-prog-list~ の設定をユーザが変更している場合は期待ど +おりに動作しない場合があります。その場合は ~skk-search-prog-list~ の設定 +に関数 ~skk-search-sagyo-henkaku~ の呼び出しがあることを確認してください。 +またこの機能の設定は DDSKK 14.1 以前では異なります。詳しくはソースに付属 +のドキュメント、設定例をご覧ください。 + +*** 異体字へ変換する + +「辺」(42区53点)の異体字である「邊」(78区20点)や「邉」(78区21点)を +入力したいときがあります [fn:itaiji] 。 + +#+BEGIN_EXAMPLE + ---- Buffer: foo ---- + *辺 + ---- Buffer: foo ---- + +Q + + ---- Buffer: foo ---- + ▽*辺 + ---- Buffer: foo ---- + +C-f + + ---- Buffer: foo ---- + ▽辺* + ---- Buffer: foo ---- + +SPC + + ---- Buffer: foo ---- + ▼邊* + ---- Buffer: foo ---- + +SPC + + ---- Buffer: foo ---- + ▼邉* + ---- Buffer: foo ---- +#+END_EXAMPLE + +- Variable: skk-itaiji-jisyo + + 辞書ファイル ~SKK-JISYO.itaiji~ 又は ~SKK-JISYO.itaiji.JIS3_4~ へ + のパスを指定する。他の辞書ファイルと異なり、この2つの辞書ファイルは見 + 出し語が漢字です。 + + +- Function: skk-search-itaiji + + not documented. + + http://mail.ring.gr.jp/skk/200303/msg00071.html + +[fn:itaiji] 辞書が充実していればかな漢字変換で見出し語「へん」から「邊」 +や「邉」を求めることができます。もちろん、文字コードを指定して「邊」や +「邉」を直接挿入することもできます。 + +*** ファンクションキーの使い方 + +- Variable: skk-j-mode-function-key-usage + + シンボル ~conversion~ ならば、 ~skk-search-prog-list-1~ 〜 ~skk-search-prog-list-9~ お + よび ~skk-search-prog-list-0~ を実行するよう自動設定します。これらのプ + ログラムは▽モード限定でファンクションキー ( ~[F1]~ 〜 ~[F10]~ ) に割り + 当てられます。 ~[F5]~ 〜 ~[F10]~ については本オプションの設定により自動 + 的に割り当てられます。これらの割り当てはユーザオプション ~skk-verbose~ を + 設定するとエコーエリアに表示されるようになります。 + + [[冗長な案内メッセージの表示][冗長な案内メッセージの表示]]. + + + ~[F5]~ … 単漢字 + + ~[F6]~ … 無変換 + + ~[F7]~ … カタカナ + + ~[F8]~ … 半角カナ + + ~[F9]~ … 全角ローマ + + ~[F10]~ … ローマ + + シンボル ~kanagaki~ ならば、かなキーボード入力用に自動設定します。 + ~nil~ ならば、自動設定しません。 + +** キー設定 + +*** かなモード/カナモードのキー設定 + +**** ローマ字のルールの設定 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +- ~skk-rom-kana-base-rule-list~ +- ~skk-rom-kana-rule-list~ + +DDSKK の■モードにおける文字変換は、これら2つの変数を用いて行われます。 +~skk-rom-kana-base-rule-list~ には基本的なローマ字かな変換のルールが定め +られています。一方 ~skk-rom-kana-rule-list~ はユーザが独自のルールを定め +るために用意されており、 ~skk-rom-kana-base-rule-list~ よりも優先されます。 + +これらは「入出力の状態がいかに移り変わるべきか」を決定します。その内容は、 + +#+BEGIN_SRC emacs-lisp +(入力される文字列 出力後に自動的に入力に追加される文字列 出力) +#+END_SRC + +#+TEXINFO: @noindent +という形のリストを列挙したものです。 + + + 入力される文字列…変換される前のアスキー文字の文字列をいいます。 + + + 出力…次の入力状態に移るときにバッファに挿入される文字列の組み合わせ + であり、 ~("ア" . "あ")~ のようなコンスセルです。 + +~skk-rom-kana-base-rule-list~ の一部を見てみましょう。 + +#+BEGIN_SRC emacs-lisp +("a" nil ("ア" . "あ")) +("ki" nil ("キ" . "き")) +("tt" "t" ("ッ" . "っ")) +("nn" nil ("ン" . "ん")) +("n'" nil ("ン" . "ん")) +#+END_SRC + +#+TEXINFO: @noindent +のような規則があります。これによると + +#+BEGIN_EXAMPLE +a → あ +ki → き +tt → っt +nn → ん +n' → ん +#+END_EXAMPLE + +#+TEXINFO: @noindent +のようになります。 + +~skk-rom-kana-base-rule-list~ には、次のような便利な変換ルールも定められ +ています。 + +# #+BEGIN_EXAMPLE だと @ が消失する +#+BEGIN_SRC emacs-lisp +z SPC → 全角スペース +z* → ※ +z, → ‥ +z- → 〜 +z. → … +z/ → ・ +z0 → ○ +z@ → ◎ +z[ → 『 +z] → 』 +z{ → 【 +z} → 】 +z( → ( +z) → ) +zh → ← +zj → ↓ +zk → ↑ +zl → → +zL → ⇒ +#+END_SRC + +**** ローマ字ルールの変更例 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +~skk-rom-kana-base-rule-list~ の規則に従うと + +#+BEGIN_EXAMPLE +hannou → はんおう +han'ou → はんおう +hannnou → はんのう +#+END_EXAMPLE + +#+TEXINFO: @noindent +のようになります。ここで + +#+BEGIN_SRC emacs-lisp +(setq skk-rom-kana-rule-list + (append skk-rom-kana-rule-list + '(("nn" "n" ("ン" . "ん"))))) +#+END_SRC + +#+TEXINFO: @noindent +のような設定にすることで + +#+BEGIN_EXAMPLE +hannou → はんのう +#+END_EXAMPLE + +#+TEXINFO: @noindent +のようにローマ字かな変換が行われるようになります。 + +他の例として、略号を設定することもできます。 + +#+BEGIN_EXAMPLE +tp → 東北大学 +skk → skk +skK → SKK +#+END_EXAMPLE + +#+TEXINFO: @noindent +といった変換は、 + +#+BEGIN_SRC emacs-lisp +("tp" nil ("東北大学" . "東北大学")) +("sk" nil ("" . "")) +("skk" nil ("skk" . "skk")) +("skK" nil ("SKK" . "SKK")) +#+END_SRC + +#+TEXINFO: @noindent +のような規則を追加することで実現されます。自分の名前を入力することはよく +あるので、適当な省略形を用いて、このリストに追加しておく、といった利用を +お勧めします。 + +更に ~skk-rom-kana-rule-list~ を用いれば TUT-code による日本語入力を実現 +することもできます。TUT-code による入力についてはソースアーカイブの ~tut-code~ デ +ィレクトリに収録されている各ファイルを参照してください。 + +[[ローマ字入力以外の入力方式][ローマ字入力以外の入力方式]]. + +**** ■モードに関連するその他の変数 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +- Variable: skk-kana-input-search-function + + ルールリストの中に記せない変換ルールを処理する関数。 + これは ~skk-rom-kana-base-rule-list~ と ~skk-rom-kana-rule-list~ の + 要素を全て検索した後にコールされます。引数はありません。バッファの文字 + を、直接 ~preceding-char~ などで調べて下さい。 + + 初期設定では ~h~ で、長音を表すために使われています。次の例を見て下さい。 + + #+BEGIN_EXAMPLE + ohsaka → おおさか + ohta → おおた + #+END_EXAMPLE + + 一方で、 ~hh~ は「っ」になります。 + + #+BEGIN_EXAMPLE + ohhonn → おっほん + ohhira → おっひら + #+END_EXAMPLE + + これは ~skk-rom-kana-rule-list~ の標準設定に + + #+BEGIN_SRC emacs-lisp + ("hh" "h" ("ッ" . "っ")) + #+END_SRC + + が入っているためです。これを削除すれば + + #+BEGIN_EXAMPLE + ohhonn → おおほん + ohhira → おおひら + #+END_EXAMPLE + + となります。 + +#+KINDEX: M-x skk-toggle-kutouten + +- Variable: skk-kutouten-type + + ■モードの標準では、キーボードの ~.~ を打鍵すると「。」が、 ~,~ を打鍵 + すると「、」がバッファに挿入されます。変数 ~skk-kutouten-type~ に適切な + シンボルを設定することにより、この組み合せを変更 [fn:kanakey] すること + ができます。そのシンボルとは、次の4つです。 + + - シンボル ~jp~ → 「。」「、」 (標準設定) + - シンボル ~en~ → 「.」「,」 + - シンボル ~jp-en~ → 「。」「,」 + - シンボル ~en-jp~ → 「.」「、」 + + または、変数 ~skk-kutouten-type~ にはコンスセルを指定することも可能です。 + その場合は、 + + #+BEGIN_EXAMPLE + (句点を示す文字列 . 読点を示す文字列) + #+END_EXAMPLE + + のように指定します。例として、次のように設定するとキーボード + の ~.~ で ~abc~ が、 ~,~ で ~def~ がバッファに入力されます。 + + #+BEGIN_SRC emacs-lisp + (setq skk-kutouten-type '("abc" . "def")) + #+END_SRC + + なお、変数 ~skk-kutouten-type~ はバッファローカル変数です。すべてのバッ + ファで統一した設定としたい場合は、 + + #+BEGIN_SRC emacs-lisp + (setq-default skk-kutouten-type 'en) + #+END_SRC + + のように関数 ~setq-default~ を用いてください。 + +- Variable: skk-use-auto-kutouten + + 標準設定は ~nil~ 。 ~Non-nil~ であれば、カーソル直前の文字種に応じて + 句読点を動的に変更します。 + +[fn:kanakey] 変数 ~skk-use-kana-keyboard~ が ~non-nil~ ならば無効である。 + +**** 数字や記号文字の入力 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +かなモード/カナモードにおける次のキーは、関数 ~skk-insert~ にバインドされています。 + +#+BEGIN_EXAMPLE +! # % & ' * + + +- 0 1 2 3 4 5 + +6 7 8 9 : ; < + += > ? " ( ) [ + +] { } ^ _ ` | + +~ +#+END_EXAMPLE + +これらの数字や記号文字のキーに対応し挿入される文字をカスタマイズするため +には、変数 ~skk-rom-kana-rule-list~ を利用します。 + +#+BEGIN_SRC emacs-lisp +(setq skk-rom-kana-rule-list + (append skk-rom-kana-rule-list + '(("!" nil "!") + ("," nil ",") + ("." nil ".") + (":" nil ":") + (";" nil ";") + ("?" nil "?")))) +#+END_SRC + +関数 ~skk-insert~ は、Emacs のオリジナル関数 ~self-insert-command~ をエミ +ュレートしています。具体的には、引数を渡すことによって同じ文字を複数、一 +度に挿入することが可能です。 + +#+BEGIN_EXAMPLE +C-u 2 ! + + ------ Buffer: foo ------ + !! + ------ Buffer: foo ------ +#+END_EXAMPLE + +*** 全英モードのキー設定 + +全英モードにおける印字可能な全てのキーはコマンド ~skk-jisx0208-latin-insert~ に +割り付けられています。また、変数 ~skk-jisx0208-latin-vector~ の値により挿 +入される文字が決定され、その標準設定は以下のようになっています。 + +#+BEGIN_SRC emacs-lisp +[nil nil nil nil nil nil nil nil + nil nil nil nil nil nil nil nil + nil nil nil nil nil nil nil nil + nil nil nil nil nil nil nil nil + " " "!" "”" "#" "$" "%" "&" "’" + "(" ")" "*" "+" "," "−" "." "/" + "0" "1" "2" "3" "4" "5" "6" "7" + "8" "9" ":" ";" "<" "=" ">" "?" + "@" "A" "B" "C" "D" "E" "F" "G" + "H" "I" "J" "K" "L" "M" "N" "O" + "P" "Q" "R" "S" "T" "U" "V" "W" + "X" "Y" "Z" "[" "\" "]" "^" "_" + "‘" "a" "b" "c" "d" "e" "f" "g" + "h" "i" "j" "k" "l" "m" "n" "o" + "p" "q" "r" "s" "t" "u" "v" "w" + "x" "y" "z" "{" "|" "}" "〜" nil] +#+END_SRC + +挿入される文字を変更したい場合: [[数字や記号文字の入力][数字や記号文字の入力]]. + +関数 ~skk-jisx0208-latin-insert~ も Emacs オリジナルの関数 ~self-insert-command~ を +エミュレートしています。つまり、関数 ~skk-insert~ における動作と同じく、 +引数を渡すことにより同じ文字を複数、一度に挿入することができます。 + +[[数字や記号文字の入力][数字や記号文字の入力]]. + +*** 閉じ括弧の自動入力 + +通常、 *「* を入力したら *」* を後で入力する必要があります。 *「* の入力 +時点で、対になる文字を自動挿入してくれると打鍵数を減らすことができますし、 +同時に入力忘れの防止にもなるでしょう。 + +#+VINDEX: skk-auto-insert-paren +そのために変数 ~skk-auto-insert-paren~ が用意されています。この値を ~non-nil~ に +すると、上記の自動挿入を行います。 + +#+BEGIN_EXAMPLE + ------ Buffer: foo ------ + 彼はこう言った* + ------ Buffer: foo ------ + +[ + + ------ Buffer: foo ------ + 彼はこう言った「*」 + ------ Buffer: foo ------ +#+END_EXAMPLE + +上記のように *「* の入力時点で対となる *」* を自動挿入し、 *「* と *」* の +間にポイントを再配置するので、その位置からかぎかっこに囲まれた文字列を即 +始めることができます。 + + +- Variable: skk-auto-paren-string-alist + + 自動挿入すべきペアの文字列を指定します。標準設定は下記のとおり。 + + #+BEGIN_SRC emacs-lisp + (("「" . "」") ("『" . "』") ("(" . ")") ("(" . ")") ("{" . "}") + ("{" . "}") ("〈" . "〉") ("《" . "》") ("[" . "]") ("[" . "]") + ("〔" . "〕") ("【" . "】") ("\"" . "\"") ("“" . "”") ("`" . "'")) + #+END_SRC + + これは、ひと言でまとめると、「開き括弧と閉じ括弧とのコンスセルを集めた + リスト」です。各コンスセルの ~car~ にある文字列を挿入したときに ~cdr~ に + ある文字列が自動挿入されます。 + + このリストの各要素の ~car~ の文字列は、必ず変数 ~skk-rom-kana-rule-list~ の + 規則によって入力されなければなりません。例えば、 ~(~ に対する ~)~ を自 + 動挿入するには + + #+BEGIN_SRC emacs-lisp + (setq skk-rom-kana-rule-list + (append skk-rom-kana-rule-list + '(("(" nil "(")))) + #+END_SRC + + のように設定する必要があります。 + + 既に SKK モードになっているバッファで変数 ~skk-auto-paren-string-alist~ を + 変更した場合は、 ~C-x C-j~ もしくは ~C-x j~ を2度キー入力して ~skk-mode~ も + しくは ~skk-auto-fill-mode~ を起動し直す必要があります。 + +キーとなる文字が挿入されても、その挿入後のポイントに自動挿入すべき文字が +既に存在している場合には、自動挿入されないように設計されています。 + +#+BEGIN_EXAMPLE + ------ Buffer: foo ------ + *」 + ------ Buffer: foo ------ + +[ + + ------ Buffer: foo ------ + 「*」 + ------ Buffer: foo ------ +#+END_EXAMPLE + +対になる文字を複数挿入したい場合は、引数を渡して文字を指定します。 + +#+BEGIN_EXAMPLE +C-u 2 [ + + ------ Buffer: foo ------ + 「「*」」 + ------ Buffer: foo ------ +#+END_EXAMPLE + +#+CINDEX: yatex-mode +~yatex-mode~ など、既に同様の機能が付いているモードがあります。そのような +モードにおいてもこの自動挿入の機能が邪魔になることはないでしょうが、特定 +のモードに限って自動入力機能をオフにしたい場合は、当該モードに入ったとき +にコールされるフック変数を利用して設定することができます。 + +#+BEGIN_SRC emacs-lisp +(add-hook 'yatex-mode-hook + (lambda () + (when skk-auto-insert-paren + (make-local-variable 'skk-auto-insert-paren) + (setq skk-auto-insert-paren nil)))) +#+END_SRC + +特定のモードにおいて、自動挿入すべき文字を変更したい場合にも同様にフック +変数を用いて操作できます。 + +#+CINDEX: tex-mode-hook +#+BEGIN_SRC emacs-lisp +(add-hook 'tex-mode-hook + (lambda () + (when skk-auto-insert-paren + (make-local-variable 'skk-auto-paren-string-alist) + (setq skk-auto-paren-string-alist + (cons '("$" . "$") skk-auto-paren-string-alist))))) +#+END_SRC + +同様に、特定のペアを削除したい場合は、例えば下記のように設定します。 + +#+BEGIN_SRC emacs-lisp +(add-hook 'tex-mode-hook + (lambda () + (when skk-auto-insert-paren + (make-local-variable 'skk-auto-paren-string-alist) + (setq skk-auto-paren-string-alist + (delete + '("$" . "$") + (copy-sequence skk-auto-paren-string-alist)))))) +#+END_SRC + +*** リージョンを括弧で囲む + +「閉じ括弧の自動入力」の応用として、リージョンを括弧で囲むことができます。 + +#+BEGIN_EXAMPLE + ------ Buffer: foo ------ + このマニュアルにおいて*DDSKK*と呼びます + ------ Buffer: foo ------ + +` + + ------ Buffer: foo ------ + このマニュアルにおいて`DDSKK'*と呼びます + ------ Buffer: foo ------ +#+END_EXAMPLE + + +- User Option: skk-use-auto-enclose-pair-of-region + + ~non-nil~ であれば、上記の機能が有効になります。 + 当然に ~skk-auto-insert-paren~ も ~non-nil~ である必要があります。 + なお、 ~delete-selection-mode~ の方が優先されます。 + +*** 確定するキー + +#+KINDEX: C-j +- Variable: skk-kakutei-key + + この変数の値は、明示的な確定動作を行うキーを指定します。標準設定では ~C-j~ と + なっています。 + + [[暗黙の確定のタイミング][暗黙の確定のタイミング]]. + +*** 候補の選択に用いるキー + +変換において、候補が5つ以上あるときは、5番目以降の候補は7つずつまとめ +てエコーエリアに下記のように表示されます [fn:echo] 。 + +#+BEGIN_EXAMPLE +-------------------- Echo Area -------------------- +A:嘘 S:拒 D:拠 F:虚 J:挙 K:許 L:渠 [残り 2] +-------------------- Echo Area -------------------- +#+END_EXAMPLE + +この際、候補の選択に用いるキーは、次の変数によって決定されます。 + +- Variable: skk-henkan-show-candidates-keys + + 7つの異なる文字のリスト。文字は必ず小文字とする。 ~x~ , ~SPC~ 及び ~C-g~ は、 + それぞれ候補選択中における前候補群の表示、次候補群の表示、取り止めのた + めに割り付けられているので、含めてはならない。標準設定は、以下のとおり。 + + #+BEGIN_SRC emacs-lisp + (?a ?s ?d ?f ?j ?k ?l) + #+END_SRC + +- Variable: skk-henkan-show-candidates-keys-face + + 選択キーを表示する際のフェイスを指定します。 + +- Variable: skk-henkan-rest-indicator + + 標準設定は ~nil~ 。 ~Non-nil~ であれば ~[残り 99++]~ の表示を右寄せ配 + 置する。 + +- Variable: skk-henkan-rest-indicator-face + + ~[残り 99++]~ の face 属性。標準設定は ~default~ 。 + +[fn:echo] [[▼モード][▼モード]]. + +*** ▼モードでの RET + +標準設定では、 + +#+BEGIN_EXAMPLE +K a k u t e i SPC + + ------ Buffer: foo ------ + ▼確定* + ------ Buffer: foo ------ + +RET + + ------ Buffer: foo ------ + 確定 + * + ------ Buffer: foo ------ +#+END_EXAMPLE + +#+TEXINFO: @noindent +のように、▼モードで ~RET~ を入力すると、確定し、かつ改行を行います。この +挙動を変えるためのユーザオプションが用意されています。 + +- User Option: skk-egg-like-newline + + この変数の値を ~non-nil~ にすると、▼モードで ~RET~ を入力したときに確 + 定のみ行い、改行はしません。従って、辞書登録モードにおいて▼モードであ + るときの ~RET~ 打鍵時の挙動も変化 [fn:egg] します。 + + #+BEGIN_EXAMPLE + K a k u t e i SPC + + ------ Buffer: foo ------ + ▼確定* + ------ Buffer: foo ------ + + RET + + ------ Buffer: foo ------ + 確定* + ------ Buffer: foo ------ + #+END_EXAMPLE + +[fn:egg] 辞書登録モードの標準の確定、登録の動作は [[辞書登録モード][辞書登録モード]]. + +*** ▼モードでの BS + +標準設定では、▼モードで ~BS~ を押すと、前の一文字を削除した上で確定しま +す。 + +#+BEGIN_EXAMPLE +D e n k i y a SPC + + ------ Buffer: foo ------ + ▼電気屋* + ------ Buffer: foo ------ + +BS + + ------ Buffer: foo ------ + 電気* + ------ Buffer: foo ------ +#+END_EXAMPLE + +- User Option: skk-delete-implies-kakutei + + この変数の値を ~nil~ に設定すると、▼モードで ~BS~ を押した時にひとつ前 + の候補を表示します。例えば、 + + #+BEGIN_EXAMPLE + でんき /電気/伝記/ + #+END_EXAMPLE + + という辞書エントリがあるとき、以下のようになります。 + +#+BEGIN_EXAMPLE +D e n k i + + ------ Buffer: foo ------ + ▽でんき* + ------ Buffer: foo ------ + +SPC + + ------ Buffer: foo ------ + ▼電気* + ------ Buffer: foo ------ + +SPC + + ------ Buffer: foo ------ + ▼伝記* + ------ Buffer: foo ------ + +BS + + ------ Buffer: foo ------ + ▼電気* + ------ Buffer: foo ------ + +BS + + ------ Buffer: foo ------ + ▽でんき* + ------ Buffer: foo ------ +#+END_EXAMPLE + +変数 ~skk-delete-implies-kakutei~ がシンボル ~dont-update~ であれば、 +~non-nil~ 時と同じ動作のうえで個人辞書を更新しません。 + +なお、変数 ~skk-delete-implies-kakutei~ の値にかかわらず、*候補*バッファ +を表示している場合はひとつ前の候補表示に戻る動作となります。 + +*** 送りあり変換中の C-g + +送りありの変換中に ~C-g~ を入力すると、▼モードを抜け、その見出し語と送り +仮名を現在のバッファに挿入し、▽モードに入ります。 + +#+BEGIN_EXAMPLE +N a K u + + ------ Buffer: foo ------ + ▼泣く* + ------ Buffer: foo ------ + +C-g + + ------ Buffer: foo ------ + ▽なく* + ------ Buffer: foo ------ +#+END_EXAMPLE + +- User Option: skk-delete-okuri-when-quit + + この変数の値を ~non-nil~ に設定すると、送りありの変換中に ~C-g~ を入力 + したときの挙動が変化します。▽モードに入るのは同じですが、同時に送り仮 + 名を消します。送り仮名の入力間違いを修正するのには便利です。例えば、以 + 下のようになります。 + + #+BEGIN_EXAMPLE + N a K u + + ------ Buffer: foo ------ + ▼泣く* + ------ Buffer: foo ------ + + C-g + + ------ Buffer: foo ------ + ▽な* + ------ Buffer: foo ------ + #+END_EXAMPLE + +*** 変換位置の指定方法 + +SKK では通常、「漢字変換の開始位置」と「送り仮名の開始位置」を大文字で指 +定しますが、これらを任意のキーで指定することで sticky-shift ライクな +操作 [fn:sticky] も可能です。 + +#+BEGIN_SRC emacs-lisp +(setq skk-sticky-key ";") +#+END_SRC + +#+TEXINFO: @noindent +と設定すると ~;~ キーで [fn:sticky2] 漢字変換位置が指定できるようになりま +す。 + +例えば「有る」という単語を入力するには + +#+BEGIN_EXAMPLE +; a ; r u +#+END_EXAMPLE + +#+TEXINFO: @noindent +というキー入力で可能となり、シフトキーを押す必要がなくなります。 + +操作上は通常の sticky-shift [fn:q34] と変わりませんが、画面表示は + +#+BEGIN_EXAMPLE +打鍵 通常の sticky skk-sticky +; 変化なし ▽ +a ▽あ ▽あ +; ▽あ ▽あ* +r ▽あ*r ▽あ*r +#+END_EXAMPLE + +#+TEXINFO: @noindent +と遷移します。通常の sticky と比べて skk-sticky は ~;~ を押した時点で画面 +表示が変化するので若干分かり易いと思います。 + +キーの設定方法は、割り当てるキーの種類によって異なります。 + +1. 表示を伴うキー + + ~;~ などの表示を伴うキーの場合は + + #+BEGIN_SRC emacs-lisp + (setq skk-sticky-key ";") + #+END_SRC + + のように ~string~ を設定して下さい。 ~skk-sticky-key~ に設定した文字そ + のものを入力したい場合は2回続けて打鍵すると入力できます。 + +2. 表示を伴わないキー + + 【無変換】のような表示を伴わないキーの場合は + + #+BEGIN_SRC emacs-lisp + (setq skk-sticky-key [muhenkan]) ;Microsoft Windows では [noconvert] + #+END_SRC + + のようにそのキーを表わす ~vector~ を設定して下さい。 + +3. 同時打鍵 + + 2つのキーを同時に打鍵することでも漢字変換位置を指定できます。例えば + ~f~ と ~j~ の同時打鍵で指定する場合は + + #+BEGIN_SRC emacs-lisp + (setq skk-sticky-key '(?f ?j)) + #+END_SRC + + のように ~character~ のリストを設定して下さい。 + + Dvorak 配列のような、押しやすい場所に適当なキーがない環境でもこの機能を + 使いたい場合に便利かもしれません。 + +- Variable: skk-sticky-double-interval + + この変数が指定する秒数以内に打鍵されたものを同時打鍵と判定する。 + 標準設定は 0.1 秒。 + +[fn:sticky] あくまでも「任意のキーで変換開始位置を指定する」ものであり、 +sticky-shift そのものではありません。したがって、アスキーモードや SKK abbrev モード、 +また SKK 以外でも sticky-shift を使いたい場合は、前述のような設定を併用す +る必要があります。 + +[fn:sticky2] ~skk-hint.el~ を併用する場合は ~skk-hint-start-char~ の標準 +設定も ~;~ であるため、どちらかを別のキーに割り当てる必要があります。 + +[[候補の絞り込み][候補の絞り込み]]. + +[fn:q34] [[Q3-4 左手の小指を SHIFT で酷使したくありません。][Q3-4 左手の小指を SHIFT で酷使したくありません。]]. + +*** 1回の取り消し操作 (undo) の対象 + +Emacs では本来、連続する 20 文字の挿入が一回の取り消し操作(アンドゥ)の +対象となっています。そこで DDSKK のかな・カナ・全英モードにおける入力も、 +これと同様の動作をするように設計されています [fn:emu] 。正確に言えば、 +~skk-insert~ , ~skk-set-henkan-point~ , ~skk-jisx0208-latin-insert~ [fn:emu2] の +各関数にバインドされたキー入力については、連続して入力された 20 文字をい +ちどのアンドゥの対象としています [fn:20] 。 + +ただし、これらの DDSKK のコマンドと Emacs 本来の ~self-insert-command~ を +織り混ぜてキー入力した場合 [fn:emu3] は、このエミュレーションは正常に動作 +しませんが、これは現在の仕様です。 + +#+BEGIN_EXAMPLE +a i u e o k a k i k u k e k o s a s i s u s e s o t a t i t u t e t o + + ------------------------- Buffer: foo ------------------------- + あいうえおかきくけこさしすせそたちつてと* ※ 連続する20文字 + ------------------------- Buffer: foo ------------------------- + +C-_ + + ------------------------- Buffer: foo ------------------------- + * ※ 20文字全てがアンドゥの対象 + ------------------------- Buffer: foo ------------------------- + +a i u e o k a k i k u k e k o s a s i s u s e s o t a t i t u t e t o n a + + -------------------------- Buffer: foo -------------------------- + あいうえおかきくけこさしすせそたちつてとな* ※ 連続する21文字 + -------------------------- Buffer: foo -------------------------- + +C-_ + + -------------------------- Buffer: foo -------------------------- + あいうえおかきくけこさしすせそたちつてと* ※ 最後の1文字のみがアンドゥの対象 + -------------------------- Buffer: foo -------------------------- +#+END_EXAMPLE + +[fn:emu] ~buffer-undo-list~ に Emacs が挿入したアンドゥの境目の目印を取り +除く方法でエミュレートしています。 + +[fn:emu2] SKK abbrev モードでは、アスキー文字入力が Emacs 本来の ~self-insert-command~ に +より行われているので、エミュレーションのための内部変数である ~skk-self-insert-non-undo-count~ を +インクリメントすることができず、アンドゥをエミュレートできません。しかも、 +カンマやピリオドを挿入した時点で、コマンド ~skk-abbrev-comma~ や ~skk-abbrev-period~ を +使うことになるので、本来のアンドゥの機能も損なってしまいます。ただし、現 +実問題として、元来 SKK abbrev モードは省略形としての見出し語を挿入するた +めのモードですから、長い見出し語を挿入することはあまりないと考えられます。 + +[fn:20] 20 は Emacs のソースファイルの一部である ~keyboard.c~ に定められ +たマジックナンバーと一致します。 + +[fn:emu3] かなモードでの入力中、アスキーモードに移行して入力した場合など +がこれにあたります。 + +** 変換、確定の前後 + +関連事項: + +- [[送りあり変換の変換開始のタイミング][送りあり変換の変換開始のタイミング]]. + +- [[変換位置の指定方法][変換位置の指定方法]]. + +*** ポイントを戻して▽モードへ + +▽モードに入り忘れた場合に、手動で▽マークを付ける方法 ([[後から▽モードに入る方法][後から▽モードに入る方法]].) に +ついては、前述しました。 + +ここで述べる方法では、遡って▽マークを付ける位置を自動的に選び、しかもポ +イントは動きません。 + +- Key: M-Q, skk-backward-and-set-henkan-point + + ~M-Q~ (大文字の ~Q~ です。)と打鍵すると、現在位置の直前の文字列につい + て走査し、同種の文字(ひらがな、カタカナ、全角アルファベット、アルファ + ベットの4種類のいずれか)が続く限り後方に戻って▽マークを付けます。ポ + イントは動きません。 + + #+BEGIN_EXAMPLE + k a n j i + + ------ Buffer: foo ------ + かんじ* + ------ Buffer: foo ------ + + M-Q + + ------ Buffer: foo ------ + ▽かんじ* + ------ Buffer: foo ------ + #+END_EXAMPLE + + 変換開始位置を決定するとき、スペース文字、タブ文字、長音を表わす「ー」 + は無条件に無視されます。ただし、ひらがなの場合は「を」が、カタカナの場 + 合は「ヲ」が見つかった時点で変換開始位置の走査を止めて▽モードに入りま + す。変換開始ポイントを「を」又は「ヲ」の直前で止めるのは、たいていその + 直後から単語が始まるからです。 + +以上は、引数を与えないで ~M-Q~ を実行した場合です。一方で、 ~C-u 5 M-Q~ の +ように引数を渡して実行すると、変換開始位置から現在位置までの文字数を指定 +することができます。この場合は文字種別を問わず、与えられた文字数だけ無条 +件にポイントを戻します。 + +- User Option: skk-allow-spaces-newlines-and-tabs + + 後方にポイントを戻す途中で行頭に到達した場合は、更に上の行について、行 + 末の文字列から同様の走査を行い、必要があれば更にポイントを戻します。こ + うした「行を超えての走査」をやめるためには、この変数の値を ~nil~ に設定 + します。 + +*** 直前の確定を再変換 + +一番最後(直近)の確定を取り消して、再変換することができます。 +これを *確定アンドゥ* と呼びます。 + +例えば、辞書エントリが + +#+BEGIN_EXAMPLE +こうこう /高校/孝行/航行/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +のようになっているとします。 + +#+BEGIN_EXAMPLE +K o u k o u SPC + + ------ Buffer: foo ------ + ▼高校* + ------ Buffer: foo ------ + +s u r u + + ------ Buffer: foo ------ + 高校する* + ------ Buffer: foo ------ + +M-x skk-undo-kakutei + + ------ Buffer: foo ------ + ▼孝行* + ------ Buffer: foo ------ +#+END_EXAMPLE + +この例では、「高校」の確定を取り消しています。すると、辞書の第一候補であ +る「高校」をとばして、次候補である「孝行」が現れます。ここで更に ~SPC~ を +押せば次候補である「航行」が現れ、更にもう一度 ~SPC~ を押せば候補が尽きて +辞書登録モードに入ります。 + +この例のとおり、確定アンドゥは、確定した直後でなくとも有効です。より正確 +には、次の新たな確定を行うまで [fn:kakutei] は確定に関する情報が保持され +ているので、確定アンドゥすることができます。 + +また、変換、確定に関連しない文字列は、確定アンドゥを行っても削除されない +ように設計されています。上記の例では「する」がそのままカレントバッファに +残っています。 + +- User Option: skk-undo-kakutei-return-previous-point + + この変数の値が ~non-nil~ であれば、確定アンドゥ処理が完了した後に、確定 + アンドゥ処理の直前の位置にカーソルが戻ります。上の例の場合、確定アンド + ゥ処理が完了した後のカーソル位置は、標準設定 ~nil~ では「孝行」の直後 + のままですが、 ~non-nil~ であれば「する」の直後に復帰します。 + +[fn:kakutei] ~C-j~ を打鍵して明示的に確定した場合は勿論、「暗黙の確定」を +行った場合も同様です。 + +*** 自動変換開始 + +▽モードで見出し語を入力しているときに「を」や「。」などの文字を打鍵する +と、 ~SPC~ を押したかのように変換を開始 [fn:autohenkan] し、▼モードに入 +るようになっています。 + +#+BEGIN_EXAMPLE +K a n j i + + ------ Buffer: foo ------ + ▽かんじ* + ------ Buffer: foo ------ + +w o + + ------ Buffer: foo ------ + ▼漢字を* + ------ Buffer: foo ------ +#+END_EXAMPLE + +- User Option: skk-auto-okuri-process + + この変数を ~non-nil~ に設定して送り仮名の自動処理 [fn:saop] を行ってい + る場合は、以下のような変換も可能です。ただし、個人辞書に + + #+BEGIN_EXAMPLE + できr /出来/[る/出来/]/ + #+END_EXAMPLE + + というようなエントリがあると仮定します。 + + #+BEGIN_EXAMPLE + D e k i r u n n d e s u + + ------ Buffer: foo ------ + ▽できるんです + ------ Buffer: foo ------ + + . + + ------ Buffer: foo ------ + ▼出来るんです。 + ------ Buffer: foo ------ + #+END_EXAMPLE + +- Variable: skk-auto-start-henkan-keyword-list + + この変数の値は、単語や文節の区切りとなるような文字列のリストです。標準 + 設定は以下のようになっています。 + + #+BEGIN_SRC emacs-lisp + ("を" "、" "。" "." "," "?" "」" "!" ";" ":" ")" ";" + ":" ")" "”" "】" "』" "》" "〉" "}" "]" "〕" "}" + "]" "?" "." "," "!" ) + #+END_SRC + +- Variable: skk-auto-start-henkan + + この変数の値を ~nil~ に設定すると、本節で説明した自動変換開始機能を無効 + にします。標準設定は ~t~ です。 + +[fn:autohenkan] ▽マークからポイントの直前の文字までを見出し語とします。 +打鍵に入力された文字(「を」や「。」)は見出し語には含まれません。 + +[fn:saop] [[送り仮名の自動処理][送り仮名の自動処理]]. + +*** 暗黙の確定のタイミング + +標準の設定では、確定が済む前に次の文字 [fn:ammoku] を入力すると、直ちに確 +定されます。これを「暗黙の確定」と呼んでいます。具体的には以下のようにな +ります。 + +#+BEGIN_EXAMPLE +K a k u t e i + + ------ Buffer: foo ------ + ▽かくてい* + ------ Buffer: foo ------ + +SPC + + ------ Buffer: foo ------ + ▼確定* + ------ Buffer: foo ------ + +s + + ------ Buffer: foo ------ + 確定s* ; 暗黙の確定 + ------ Buffer: foo ------ + +u + + ------ Buffer: foo ------ + 確定す* + ------ Buffer: foo ------ +#+END_EXAMPLE + +- User Option: skk-kakutei-early + + この変数の値を ~nil~ にすると、「暗黙の確定」を遅らせます。具体的には、 + + + 括弧 ~(~ ~)~ ~[~ ~]~ の入力時 + + 句読点 ~,~ ~.~ の入力時 + + 次の変換開始時( ~A~ から ~Z~ までの大文字の入力時) + + ~RET~ 入力時 + + まで暗黙の確定が遅延されます [fn:ammoku2] 。 + + #+BEGIN_EXAMPLE + K a k u t e i + + ------ Buffer: foo ------ + ▽かくてい* + ------ Buffer: foo ------ + + SPC + + ------ Buffer: foo ------ + ▼確定* + ------ Buffer: foo ------ + + s + + ------ Buffer: foo ------ + ▼確定s* + ------ Buffer: foo ------ + + u r u + + ------ Buffer: foo ------ + ▼確定する* + ------ Buffer: foo ------ + + . + + ------ Buffer: foo ------ + 確定する。* ; 暗黙の確定 + ------ Buffer: foo ------ + #+END_EXAMPLE + +[fn:ammoku] 正確には、印字可能な文字または ~RET~ が入力されたときです。 + +[fn:ammoku2] ~skk-kakutei-early~ の機能と ~skk-process-okuri-early~ の +機能を同時に有効にすることはできません。 ~skk-kakutei-early~ の値を ~non-nil~ に +する場合は ~skk-process-okuri-early~ の値を ~nil~ にする必要があります。 + +*** 積極的な確定 + +変換候補がひとつしか見つからない場合は自動的に確定する、という設定ができ +ます。 + +- User Option: skk-kakutei-when-unique-candidate + + この値が ~non-nil~ であれば、この機能が有効になります。 + + ~t~ であれば送りあり変換、送りなし変換、SKK abbrev モードでの変換、全て + でこの機能が有効になります。 + + また、 ~okuri-ari~ , ~okuri-nasi~ , ~abbrev~ を要素とするリストであるこ + ともできます。この場合は変換対象がその条件に合致した場合のみ確定変換が + 機能します。 + + #+BEGIN_EXAMPLE + '(okuri-nasi abbrev) + #+END_EXAMPLE + + この機能は、全ての辞書を検索した上で変換候補が唯一か否かを調べます。そ + のため、 ~skk-search-prog-list~ の内容によってはレスポンスが悪くなる可 + 能性があります。 + + [[辞書の検索方法の設定][辞書の検索方法の設定]]. + +- Variable: skk-kakutei-search-prog-limit + + この変数の値が数値であれば、積極的な確定 ~skk-kakutei-when-unique-candidate~ に + おける「変換候補が唯一か否か」の判定を ~skk-search-prog-list~ の先頭か + ら数えて当該数値の個数までの辞書に制限します。 + + 数値以外であれば、無制限に全ての辞書を検索対象とします。 + +*** 確定辞書 + +特定の語は、変換したら即座に確定させる事ができます。これを *確定変換* と +呼び、利用するには *確定辞書* を用意します。例えば、 + +#+BEGIN_EXAMPLE +じしょ /辞書/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリが確定辞書にあったとします。このとき、 + +#+BEGIN_EXAMPLE +Z i s h o + + ------ Buffer: foo ------ + ▽じしょ* + ------ Buffer: foo ------ + +SPC + + ------ Buffer: foo ------ + 辞書* + ------ Buffer: foo ------ +#+END_EXAMPLE + +#+TEXINFO: @noindent +のように ~SPC~ を押しただけでいきなり確定します。エントリの候補がひとつだ +けだからです。 + +確定辞書以外の辞書に登録されているであろう同音異義語を得るには、確定変換 +の直後に ~x~ を打鍵します。すると、▼モードに戻って次の候補を検索すること +ができます。 + +次の例では、確定辞書に「辞書」が、個人辞書(や共有辞書)に「自署」が登録 +されているとします。 + +#+BEGIN_EXAMPLE +Z i s y o SPC + + ------ Buffer: foo ------ + 辞書* + ------ Buffer: foo ------ + +x + + ------ Buffer: foo ------ + ▼自署* + ------ Buffer: foo ------ +#+END_EXAMPLE + +確定辞書の単語は、優先的に変換されます。 + +- Variable: skk-kakutei-jisyo + + 確定変換用の辞書ファイル [fn:kakuteijisyo] を指定します。 ~nil~ であれ + ば、確定変換は行われません。この辞書は、標準の配布パッケージには含まれ + ていないので、使用するのであればユーザ側で用意する必要があります。 + + [[辞書の書式][辞書の書式]]. + +[fn:kakuteijisyo] 確定変換用辞書の見出し語の配列については、サイズが大き +い場合は、共有辞書と同様、ソートして二分検索(バイナリサーチ)を行い、サ +イズが小さければ適当な配置で直線的検索(リニアサーチ)を行うことをお勧め +します。次も参照してください。 + +[[辞書検索のための関数][辞書検索のための関数]]. + +[[エントリの配列][エントリの配列]]. + +** 送り仮名関連 + +SKK の送り仮名の処理は、好みが分かれるところです。色々な対策が用意されて +いますので、試してみて下さい。 + +*** 送り仮名の厳密なマッチ + +今、個人辞書に + +#+BEGIN_EXAMPLE +おおk /大/多/[く/多/]/[き/大/]/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +という送りありエントリがあると仮定します。 + +ここで ~O o K i i SPC~ と入力した場合、普通は「大きい」と「多きい」という +2通りの候補が出力されますが、このうち「多きい」は現代の日本語として正し +くありません。このような場合に、出力される候補を正しい表現のみに絞りこむ +方法について、説明します。 + +- User Option: skk-henkan-okuri-strictly + + この変数の値を ~non-nil~ に設定すると、見出し語がマッチするかどうかのチ + ェックの上に、送り仮名がマッチするかどうかのチェックが行われます。結果 + として送り仮名がマッチしない候補は出力されません。上記の例では、送り仮 + 名「き」がマッチする「大きい」は出力されますが、「多きい」は出力されま + せん [fn:okuristrictly] 。 + + 個人辞書の送りありエントリが充実していれば、標準の設定よりも候補が絞り + 込まれるので変換効率がアップしますが、さもなければ、すぐに辞書登録モー + ドに入ってしまうため逆に不便になります。 + +変数 ~skk-henkan-okuri-strictly~ の値を ~non-nil~ にすると、辞書登録モー +ドに入っても送り仮名のマッチが厳密に行われます。これは辞書登録の際希望す +る候補を得るためには障害となります。そのような障害を避けるためには、下記 +のようにフック変数を設定します。これにより、辞書登録時だけは、一時的に送 +り仮名の厳密なマッチをしないようになります [fn:okuristrictly2] 。 + +#+BEGIN_SRC emacs-lisp +(add-hook 'minibuffer-setup-hook + (lambda () + (when (and (boundp 'skk-henkan-okuri-strictly) + skk-henkan-okuri-strictly + (not (eq last-command 'skk-purge-jisyo))) + (setq skk-henkan-okuri-strictly nil) + (put 'skk-henkan-okuri-strictly 'temporary-nil t)))) +#+END_SRC + +#+BEGIN_SRC emacs-lisp +(add-hook 'minibuffer-exit-hook + (lambda () + (when (and (get 'skk-henkan-okuri-strictly 'temporary-nil) + (<= (minibuffer-depth) 1)) + (put 'skk-henkan-okuri-strictly 'temporary-nil nil) + (setq skk-henkan-okuri-strictly t)))) +#+END_SRC + +[fn:okuristrictly] この機能は、変数 ~skk-process-okuri-early~ の値を +~non-nil~ に設定した状態と共存できません。 + +[[送りあり変換の変換開始のタイミング][送りあり変換の変換開始のタイミング]]. + +[fn:okuristrictly2] 実は変数 ~skk-henkan-okuri-strictly~ の値は辞書バッフ +ァで参照されるので、ミニバッファのバッファローカル値を変更してもうまくい +きません。将来のバージョンでは、これを改良し、辞書バッファでの動作に影響 +するユーザ変数をバッファローカル化できるようにする予定です。 + +*** 送り仮名の優先的なマッチ + +「送り仮名の厳密なマッチ」では、見出し語と送り仮名が一致した場合のみ候 +補を表示します。 + +[[送り仮名の厳密なマッチ][送り仮名の厳密なマッチ]]. + +ここでは、その条件を緩めて優先的に表示する方法を紹介します [fn:okuriprecedence] 。 + +今、個人辞書に + +#+BEGIN_EXAMPLE +おおk /大/多/[く/多/]/[き/大/]/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +という送りありエントリがあると仮定します。 + +ここで ~O o K i i SPC~ と入力した場合、普通は「大きい」と「多きい」という +2通りの候補が出力されますが、このうち「多きい」は現代の日本語として正し +くありません。このような場合に、出力される候補を正しい表現が優先的にする +設定を紹介します。 + +- User Option: skk-henkan-strict-okuri-precedence + + この変数の値を ~non-nil~ に設定すると、見出し語と送り仮名がマッチした候 + 補を優先して表示します。上記の例では「▽おお*く」を変換したとき、まず + 「多く」を出力し、次に「大く」を出力します。 + + この変数の値が ~non-nil~ の時は、変数 ~skk-process-okuri-early~ の値は ~nil~ で + なければなりません [fn:okuriprecedence2] 。 + また、変数 ~skk-henkan-okuri-strictly~ が ~non-nil~ のときは、この変数 + は無視されます。 + +[fn:okuriprecedence] 「大く」などの候補は鬱陶しいが、すぐに単語登録に入っ +てしまうのも嫌な人におすすめです。 + +[fn:okuriprecedence2] [[送りあり変換の変換開始のタイミング][送りあり変換の変換開始のタイミング]]. + +*** 送り仮名の自動処理 + +この節では、「あげる」と入力してから ~SPC~ を押しても「上げる」と変換する +機能を紹介します。 + +**** どのように変換されるか +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +- User Option: skk-auto-okuri-process + + この変数の値を ~non-nil~ に設定すると、送り仮名の自動処理が行われます。 + +例えば ~T a t i a g e r u SPC~ とキー入力した場合を考えます。このとき、検 +索される見出し語の変化を追うと、 + + - たちあげる + - たちあげr + - たちあg + - たちa + - たt + +#+TEXINFO: @noindent +のようになります。仮に個人辞書エントリが、 + +#+BEGIN_EXAMPLE +たちあg /立ち上/[げ/立ち上/]/[が/立ち上/]/ +たt /建/断/経/立/[つ/建/断/経/立/]/[ち/建/断/経/立/]/[て/経/立/建/]/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +の2つのエントリを含むとすると、見出し語を後方から順に切り詰める過程で +「たちあg」と「たt」の2つの見出し語の検索時にこれらの辞書エントリがマッ +チします。 + +つまり、「たちあげる」という見出し語に対し、見出し語を最後尾から1文字ず +つ切り詰め、「切り詰めの結果残った文字列」と、「切り捨てられた先頭の文字 +のローマ字プレフィックスを連結した文字列」を送りあり変換の見出し語として +検索します [fn:autookuri1] 。 + +次に、マッチしたエントリの各候補に対し、切り捨てられた先頭の文字を送り仮 +名として取るかどうかをチェックします。この判断には、個人辞書の送り仮名ブ +ロック部分 [fn:autookuri2] を利用します。 + +「たちあg」の場合の送り仮名チェックの対象は、切り捨てられた最初の文字の +「げ」です。個人辞書に + +#+BEGIN_EXAMPLE +[げ/立ち上/] +#+END_EXAMPLE + +#+TEXINFO: @noindent +の部分があることから、送り仮名として取るべきと判断します。また、「たt」の +場合の送り仮名チェックの対象は「ち」です。個人辞書に + +#+BEGIN_EXAMPLE +[ち/建/断/経/立/] +#+END_EXAMPLE + +#+TEXINFO: @noindent +の部分があることから、送り仮名として取るべきと判断します。 + +こうして、送り仮名がマッチする候補が「立ち上」、「建」、「断」、「経」、 +「立」の5つに絞られます。これらは文字列の長さ順に昇順にソートされ [fn:autookuri3] 、 +それぞれの候補と該当の見出し語から切り捨てられた文字列と連結したもの [fn:autookuri4] を、 +送り仮名の自動処理の最終候補として返します。上記の例は、「立ち上げる」、 +「建ちあげる」、「断ちあげる」、「経ちあげる」、「立ちあげる」 の5つが +最終候補になります。 + +自動送り機能は、個人辞書のみを検索します。 + +ここで、自動送り機能の特徴を考えてみると、 + +- 長所 + + 送り仮名の最初のローマ字表現を大文字で始める必要がない。 + + 送り仮名を正確に思い出せない場合に送り仮名を指定しなくとも変換できる。 +- 短所 + + 意図しない変換をされる割合が増える。 + + 個人辞書の送りありエントリが貧弱な場合は、自動処理ができない可能性が高い。 + +#+TEXINFO: @noindent +となります。 + +変数 ~skk-auto-okuri-process~ の値を ~non-nil~ に設定したとしても、従来 +どおりの送りあり変換も同時にできますので、一度この機能を試してみることを +お勧めします [fn:autookuri5] 。 + +[fn:autookuri1] 実際には、普通の送りなし変換として最初は検索されます。個 +人辞書まで調べて候補が見つからないときは、その後、送り仮名の自動処理の検 +索に移ります。 + +[fn:autookuri2] [[送りありエントリのブロック形式][送りありエントリのブロック形式]]. + +[fn:autookuri3] 長さ順にソートするのは、変換された部分がより長い候補を先 +順位として出力するためです。 + +[fn:autookuri4] 「該当の見出し語から切り捨てられた文字列」を送り仮名とみ +なして処理しています。 + +[fn:autookuri5] 専ら補完的に自動送り処理を利用するのであれば + ~(skk-okuri-search)~ を ~skk-search-prog-list~ の最後に設定するという方 +法もあります。 + +[[辞書の検索方法の設定][辞書の検索方法の設定]]. + +**** 辞書登録の際に注意すべきこと +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +送り仮名の自動処理を行っている場合 [fn:autookuri6] には、辞書登録の際に注 +意すべきことがあります。 + +個人辞書に見出し語「わたs」についてのエントリが全くない場合、あるいは個人 +辞書のエントリが + +#+BEGIN_EXAMPLE +わたs /渡/[し/渡/]/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +のような送り仮名のブロックを持たない場合を考えてみます。 +ここで ~W a t a s i t a SPC~ と入力すると、送り仮名の自動処理においては +送り仮名がマッチしないので、候補が見つからずに辞書登録モードに入ります。 + +#+BEGIN_EXAMPLE +W a t a s i t a SPC + + ------ Buffer: foo ------ + ▼わたした + ------ Buffer: foo ------ + + ------ Minibuffer ------- + [辞書登録] わたした* + ------ Minibuffer ------- +#+END_EXAMPLE + +#+TEXINFO: @noindent +辞書登録モードで ~W a t a S i t a RET~ と送り仮名を明示的に入力して「渡し +た」と変換して登録したとします。この場合、登録する語の最後が平仮名で終わ +るので、その最後の平仮名の文字列(上記の例では「した」)が見出し語の最後 +と一致するかを調べます。一致する場合には、辞書の登録を送りありエントリと +して行うのかどうかの確認を求めます。 + +#+BEGIN_EXAMPLE +W a t a S i t a + + ------ Minibuffer ------- + [辞書登録] わたした 渡した* + ------ Minibuffer ------- + +RET + + -------------------------- Echo Area -------------------------- + Shall I register this as okuri-ari word: わたs /渡/ ? (y or n) + -------------------------- Echo Area -------------------------- +#+END_EXAMPLE + +#+TEXINFO: @noindent +この確認に対して ~y~ と回答した場合は、 + +#+BEGIN_EXAMPLE +わたs /渡/[し/渡/]/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +という辞書エントリが個人辞書の送りありエントリに書き込まれます。一方 ~n~ と +回答した場合は、個人辞書の送りなしエントリに + +#+BEGIN_EXAMPLE +わたした /渡した/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリが書き込まれます。本例の場合は ~y~ と回答するのが正解です。 + +- Variable: skk-kana-rom-vector + + この変数は、送り仮名部分をローマ字プレフィックスに分解する際に、参照さ + れます。 + +変数 ~skk-kana-rom-vector~ の標準設定は以下のようになっています。 + +#+BEGIN_EXAMPLE +["x" "a" "x" "i" "x" "u" "x" "e" "x" "o" "k" "g" "k" "g" "k" "g" + "k" "g" "k" "g" "s" "z" "s" "j" "s" "z" "s" "z" "s" "z" "t" "d" + "t" "d" "x" "t" "d" "t" "d" "t" "d" "n" "n" "n" "n" "n" "h" "b" + "p" "h" "b" "p" "h" "b" "p" "h" "b" "p" "h" "b" "p" "m" "m" "m" + "m" "m" "x" "y" "x" "y" "x" "y" "r" "r" "r" "r" "r" "x" "w" "x" + "x" "w" "n"] +#+END_EXAMPLE + +このベクトルは、それぞれ下記のかな文字をそのローマ字プレフィックスで現し +たものです。 + +#+BEGIN_EXAMPLE +ぁ あ ぃ い ぅ う ぇ え ぉ お か が き ぎ く ぐ +け げ こ ご さ ざ し じ す ず せ ぜ そ ぞ た だ +ち ぢ っ つ づ て で と ど な に ぬ ね の は ば +ぱ ひ び ぴ ふ ぶ ぷ へ べ ぺ ほ ぼ ぽ ま み む +め も ゃ や ゅ ゆ ょ よ ら り る れ ろ ゎ わ ゐ +ゑ を ん +#+END_EXAMPLE + +これに従うと、見出し語中の送り仮名がローマ字プレフィックスに分解される際、 +例えば「じ」は ~j~ に、「ち」は ~t~ に、「ふ」は ~h~ に、それぞれ分解され +ます。これらをそれぞれ ~z~ 、 ~c~ 、 ~f~ に変更することもできます。それに +は変数 ~skk-kana-rom-vector~ の該当部分を ~z~ 、 ~c~ 、 ~f~ に変更します。 + +#+BEGIN_SRC emacs-lisp +(setq skk-rom-kana-vector + ["x" "a" "x" "i" "x" "u" "x" "e" "x" "o" "k" "g" "k" "g" "k" "g" + "k" "g" "k" "g" "s" "z" "s" "z" "s" "z" "s" "z" "s" "z" "t" "d" + "c" "d" "x" "t" "d" "t" "d" "t" "d" "n" "n" "n" "n" "n" "h" "b" + "p" "h" "b" "p" "f" "b" "p" "h" "b" "p" "h" "b" "p" "m" "m" "m" + "m" "m" "x" "y" "x" "y" "x" "y" "r" "r" "r" "r" "r" "x" "w" "x" + "x" "w" "n"]) +#+END_SRC + +次にもうひとつ例を挙げます。「ありがさつき」に対して「有賀さつき」を登録 +したい場合は、上記と同様に辞書登録をし、 + +#+BEGIN_EXAMPLE +-------------------------- Echo Area -------------------------- +Shall I register this as okuri-ari entry: ありがs /有賀/ ? (y or n) +-------------------------- Echo Area -------------------------- +#+END_EXAMPLE + +#+TEXINFO: @noindent +の確認に対して ~n~ と回答します。この結果、個人辞書の送りなしエントリには、 + +#+BEGIN_EXAMPLE +ありがさつき /有賀さつき/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリが書き込まれます。 + +[fn:autookuri6] 変数 ~skk-auto-okuri-process~ の値を ~non-nil~ に設定している。 + +*** 送りあり変換の変換開始のタイミング + +- User Option: skk-process-okuri-early + + この変数の値を ~non-nil~ に設定すると、送りあり変換の変換開始のタイミン + グが早められます。つまり、送り仮名のローマ字プレフィックスの入力時点で + 変換を開始します。 + + #+BEGIN_EXAMPLE + U g o K + + ------ Buffer: foo ------ + ▼動k + ------ Buffer: foo ------ + #+END_EXAMPLE + + 送り仮名が分からないまま変換しているため、個人辞書が送り仮名に対応した + 形に成長しません。つまり ~うごk /動/~ のような形態のままとなります。た + だし、 + + #+BEGIN_EXAMPLE + うごk /動/[く/動/]/[か/動/]/[け/動/]/[き/動/]/[こ/動/]/ + #+END_EXAMPLE + + のようなエントリが既に個人辞書にある場合、それを破壊することはありませ + ん [fn:spoe] 。 + + このユーザオプションを ~non-nil~ に設定して SKK モードを起動すると、両 + 立できないオプションである下記オプションは自動的に ~nil~ に設定されます。 + + + ~skk-kakutei-early~ + + ~skk-auto-okuri-process~ + + ~skk-henkan-okuri-strictly~ + + 既に SKK モードに入った後でこの変数の設定を変更した場合は、カレントバッ + ファで ~C-x C-j~ もしくは ~C-x j~ を2回打鍵して SKK モードを起動し直す + ことで、これらの変数間の衝突を調整します。 + + + [[暗黙の確定のタイミング][暗黙の確定のタイミング]]. + + + [[送り仮名の自動処理][送り仮名の自動処理]]. + + + [[送り仮名の厳密なマッチ][送り仮名の厳密なマッチ]]. + +[fn:spoe] [[辞書の書式][辞書の書式]]. + +** 候補の順序 + +skk の初期設定では、変換で確定された単語は、次の変換時では最初に表示され +ます。この動作を変更して、効率良く変換する方法があります。 + +ここで解説するほか、確定辞書を用いた変換も、候補の順序に影響を与えます。 + +[[確定辞書][確定辞書]]. + +*** 変換の学習 + +~skk-study.el~ は、ある語 A を確定した場合に、A 及びその見出し語 A' に対 +して、直前に変換した語 B とその見出し語 B' を関連語として登録しておき、 +再度見出し語 A' の変換を行ったときに、B 及び B' のペアが直前の何回かに確 +定した語の中に見つかれば、A を優先して出力する単純な学習効果を提供するプ +ログラムです。 + +~~/.skk~ に ~(require 'skk-study)~ と書いて DDSKK を起動して下さい。以降、 +かな漢字変換の学習を始めます。 + +例えば「梅雨には雨が降る」と変換した場合、 + +- 雨(あめ)の関連語 → 梅雨(つゆ) + +- 降る(ふr)の関連語 → 雨(あめ) + +#+TEXINFO: @noindent +という風に「直前に確定した語」を関連語として、語と語の関連性を学習します。 + +ここで続けて「傘を振る」と変換すると、個人辞書が更新されてしまい、見出し +語「ふr」の第一候補は「振る」になってしまいます。 + +しかし、更に続けて ~A m e SPC g a H u R u~ とキー入力すると、 +~H u R u~ (ふr)に対して「雨」(あめ)が関連語になっているため、 +「ふr」と対で記憶されている「降る」に変換されるというわけです。 + +では、またここで「傘を振る」と変換し、個人辞書の第一候補が「振る」に更新 +された状態で、 + +#+BEGIN_EXAMPLE +A m e SPC g a T a i r y o u SPC n i H u R u +#+END_EXAMPLE + +#+TEXINFO: @noindent +と変換すれば、「ふr」はどう変換されるでしょうか? 今度は「雨」(あめ)と +「ふr」の間に「大量」(たいりょう)が入っています [fn:study1] 。 + +実はちゃんと「雨が大量に降る」と変換されます。何故なら「ふr」の関連語を探 +す際、 ~skk-study-search-times~ に指定された回数分だけ遡って、以前に確定 +した語の中に関連語がないか探すのです。従って、この場合だと、2つ前の確定 +情報を探した際に「雨」(あめ)を見つけ、これを関連語として「ふr」の値を決 +めようとするのです。 + +~skk-study.el~ に関するその他のオプションを説明します。 + +- Variable: skk-study-sesearch-times + + 現在の変換キーに対する関連変換キーをいくつまで遡って検索するか。標準設 + 定は 5 です。 + +- Variable: skk-study-max-distance + + この変数には integer を指定します。標準設定値は 30 です。直前に確定し + たポイントと今回の変換ポイントがこの距離以上離れていると学習データを蓄 + 積しないようにします。この変数は、必ずしも文章がバッファの ~point-min~ か + ら ~point-max~ へ流れるように書かれるものではなく、ポイントを前に戻した + り後へ移動したりして書かれることを想定しています。この変数に integer を + 設定すると、直前の変換よりも前のポイントで変換した場合に学習データを蓄 + 積しないようにします。 + + この変数に ~nil~ を指定すると、直前に確定したポイントとの距離を考慮せず + に学習します。 + + なお、この変数の値にかかわらず、直前の変換バッファと現在変換を行ってい + るバッファが異なる場合は学習データを蓄積しません。 + +- Variable: skk-study-first-candidate + + この変数が ~non-nil~ であれば、第一候補で確定した際も学習します。 ~nil~ で + あれば、第一候補で確定したときのみ学習データを蓄積しません。学習データ + をできるだけ小さくしたい場合、この変数を ~nil~ にすると効果があるかもし + れません。この変数の標準設定値は ~t~ です。 + +- Variable: skk-study-file + + 学習結果を保存するファイル名です。この変数の標準設定値は ~~/.skk-study~ です。 + 変数 ~skk-user-directory~ からも設定ができます。 + + [[設定ファイル][設定ファイル]]. + +- Variable: skk-study-backup-file + + ~~/.skk-study~ のバックアップファイルです。 + この変数の標準設定値は ~~/.skk-study.BAK~ です。 + +- Variable: skk-study-sort-saving + + 学習データのデータ構造に関するものです。この変数の値が ~non-nil~ であれ + ば、学習結果をソートしてセーブします。この変数が影響を及ぼすのは学習デ + ータの単なる見映えの問題だけです。この変数の標準設定値は ~nil~ です。 + +- Variable: skk-study-check-alist-format + + 学習データのデータ構造に関するものです。この変数の値が ~non-nil~ であれ + ば、学習結果の読み込み時に連想リストのフォーマットをチェックします。 + これは主に debug の目的で使います。この変数の標準設定値は ~nil~ です。 + +- Key: M-x skk-study-switch-current-theme, skk-study-switch-current-theme + + そのバッファで利用する学習テーマを切り替えます。プロンプト + + #+BEGIN_EXAMPLE + ------ Minibuffer ------- + Theme of current buffer: * + ------ Minibuffer ------- + #+END_EXAMPLE + + に対して学習テーマ名を入力してください。例えば、科学の話題を書くバッフ + ァでは "~science~" と、法律の話題を書くバッファでは "~law~" などと入力 + してください。 + +- Key: M-x skk-study-remove-theme, skk-study-remove-theme + + 不要な学習テーマを消去します。 + +- Key: M-x skk-study-copy-theme, skk-study-copy-theme + + 学習テーマを複製します。 + +[fn:study1] 「ふr」に対して「大量」(たいりょう)が関連語として保存されま +す。勿論、「ふr」に対する「雨」(あめ)の学習もまだ生きています。 + +*** 候補の順序の固定 + +skk の初期設定では、変換、選択された候補は、次回の変換では最初に表示され +ます。これに対し、毎回同じ順序で候補を表示させることができます。 + +- Variable: skk-jisyo-fix-order + + ~non-nil~ であれば、確定の際に個人辞書の同音語の順序を変更せず、個人辞 + 書に新規追加する際は既出語の後に追加する。標準は ~nil~ 。 + +これは、個人辞書のエントリの中の各候補の順序を変更しないことで実現されて +いますので、 ~skk-study.el~ による変換の学習と併用できます。 + +[[変換の学習][変換の学習]]. + +~skk-jisyo-fix-order~ が ~non-nil~ の時、個人辞書の候補を手軽に並べ替える +方法は、現時点ではありません。個人辞書ファイルを直接編集する +コマンド ~M-x skk-edit-private-jisyo~ を実行して下さい。 + +[[個人辞書ファイルの編集][個人辞書ファイルの編集]]. + +直前に変換したばかりの単語は、個人辞書の送りあり/なしエントリの一番上に +ありますので、すぐに見つけることができます。 + +*** ベイズ統計を用いた学習 + +~skk-bayesian.el~ は、直前の履歴のみ使用する ~skk-study.el~ に比べて、 +更に拡張された学習機能です。ベイズ統計を用いて文脈から変換候補が選択され +る確率を計算して候補順をソートします。なお、機能が重なることから ~skk-study.el~ と +の併用はお勧めできません。 + +動作の枠組みは emacs lisp の ~skk-bayesian.el~ と ruby スクリプト [fn:ruby] の ~bskk~ [fn:bskk] が +連携することで実現しています。 + +~skk-bayesian.el~ のインストールについては ~bayesian/README.ja.md~ を参照 +してください。 + +- User Option: skk-bayesian-debug + + ~non-nil~ ならば、以下のとおりデバッグ用のメッセージを表示します。 + + - ~skk-bayesian.el~ が吐き出すメッセージを ~*Messages*~ バッファに表示します。 + + - ~bskk~ サブプロセスを ~-d~ オプションで起動させます。 ~bskk~ は ~$HOME/tmp/bskk.log~ に + メッセージを吐き出します。 + + - 普段は非表示である ~*skk-bayesian*~ バッファを表示するようにします。 + このバッファには ~bskk~ の出力が表示されます。 + +- User Option: skk-bayesian-prefer-server + + ~non-nil~ ならば ~skk-bayesian-host~ の ~skk-bayesian-port~ に接続しま + す。 ~nil~ であれば ~bskk~ を emacs のサブプロセスとして起動します。 + +- Variable: skk-bayesian-host + + ~bskk~ サーバが稼動しているホスト名 + +- Variable: skk-bayesian-port + + ~bskk~ サーバのポート番号 + +- Variable: skk-bayesian-history-file + + not documented + +- Variable: skk-bayesian-corpus-make + + not documented + +- Variable: skk-bayesian-corpus-file + + not documented + +- Key: M-x skk-bayesian-kill-process, skk-bayesian-kill-process + + not documented + +[fn:ruby] http://www.ruby-lang.org + +[fn:bskk] Ruby 2.4 以降を使用する場合は、DDSKK 16.2 以降に付属する ~bayesian/bskk~ を +使用してください。 + +** 辞書関連 + +本節では、辞書の種別と形式、設定方法、その他辞書にまつわる動作や設定を説明しま +す。 + +*** 辞書の種類 + +- 共有辞書 + + ユーザの変換操作によって内容が書き替えられることはありません。 + + ~SKK-JISYO.S~ (S 辞書)、 ~SKK-JISYO.M~ (M 辞書)、 ~SKK-JISYO.ML~ (ML 辞書)、 + ~SKK-JISYO.L~ (L 辞書) などがあります。通常、個人辞書よりもサイズが大き + く、省資源の面からユーザ間で共有して参照されます。 + + これら以外にも、共有辞書として使えるファイルが配布されています。それぞ + れの辞書の詳細については http://openlab.jp/skk/dic.html をご参照下さい。 + +- 個人辞書 + + 変数 ~skk-jisyo~ で指定されるファイル。DDSKK を一番最初に使い始めたとき + にホームディレクトリに自動的に作られます。その後の使用により日々刻々と + エントリが追加され、更新されていきます。なお、最初の個人辞書として S 辞 + 書をリネームして使用するのも良いかもしれません。 + +- ~skk-initial-search-jisyo~ +- ~skk-kakutei-jisyo~ + + これらは共有辞書、個人辞書という区分のいずれにも属しません。これらは個 + 人毎に持つものを使用するか、ユーザ間で共有しているものを使用します。そ + の性格から、辞書内容の更新は行われず、参照のみ行われます。また使用目的 + から、通常は小さい辞書を使用します。 + +個人辞書、 ~skk-initial-search-jisyo~, ~skk-kakutei-jisyo~ は Emacs のバ +ッファに読み込んで検索を行います。 + +共有辞書は設定により Emacs のバッファに読み込んで使用するか、または辞書サ +ーバ経由で使用します。 + +*** 辞書ファイルの指定 + +この節では、辞書ファイルを指定する変数を説明します。個人辞書とバックアッ +プのディレクトリは、変数 ~skk-user-directory~ でも変更できます。 + +[[設定ファイル][設定ファイル]]. + +- Variable: skk-kakutei-jisyo + + 確定変換のための辞書です。 + + [[確定辞書][確定辞書]]. + + 一番最初に参照されます。確定変換をしない時は、初期設定の ~nil~ のままで + 良いです。 + +- Variable: skk-initial-search-jisyo + + 確定辞書の後、かつ、個人辞書の前に検索を行う辞書です。この辞書を適当に + 指定することにより、最初に出てくる候補を操作することができます。例えば、 + 複数の専門用語毎の辞書を用意しておいて ~skk-initial-search-jisyo~ の値 + を切り替えることにより、専門分野毎の専門用語を切り替えて入力することが + できます。 + + この辞書は、標準の配布パッケージには含まれていないので、使用するのであ + ればユーザ側で用意する必要があります。不要ならば、初期設定の ~nil~ のま + まで良いです。 + +- Variable: skk-jisyo + + 個人辞書。DDSKK を一番最初に起動したとき、変数 ~skk-jisyo~ が指すファイ + ルが存在しなければ自動的に作られます。 + +- Variable: skk-backup-jisyo + + 個人辞書の予備(バックアップ)です。検索の対象ではなく、あくまで個人辞 + 書のバックアップとして指定してください。 + +- Variable: skk-cdb-large-jisyo + + 共有辞書のうち CDB 形式に変換した辞書です。指定した場合は ~skk-large-jisyo~ よ + りも先に検索されます。DDSKK 14.1 からは辞書サーバを経由せずとも CDB 形 + 式辞書ファイルを直接検索できるようになりました。 + +- Variable: skk-large-jisyo + + 共有辞書のひとつ。バッファに読み込んで検索を行います。例えば ~skk-large-jisyo~ に S 辞書 + か M 辞書を指定し、 ~skk-aux-large-jisyo~ に L 辞書を指定する、という + 選択肢もあります。 + + また、辞書サーバ経由のアクセスも決して遅くはないので「共有辞書はバッフ + ァには読み込まない」という設定も自然であり、これには ~skk-large-jisyo~ を ~nil~ に + 設定します。 + +- Variable: skk-aux-large-jisyo + + 共有辞書のひとつ。辞書サーバに接続できない時にバッファに読み込んで検索 + を行う辞書です。 + +- Variable: skk-extra-jisyo-file-list + + SKK では個人辞書の他に、共有辞書または辞書サーバを設定して利用するのが + 一般的ですが、郵便番号辞書 ~SKK-JISYO.zipcode~ をはじめとした多彩な辞書 + もメンテナンスされています。 + + これらの辞書を利用するために変数 ~skk-search-prog-list~ を手動で編集す + ることもできますが、この変数は厳密にはユーザ変数に分類されていないため、 + 予期しない問題が起こることもあります。 + + DDSKK 14.2 以降では追加の辞書を簡単に設定する方法を提供します。以下の例 + を参考に変数 ~skk-extra-jisyo-file-list~ の設定を ~~/.skk~ に記述します。 + + #+BEGIN_SRC emacs-lisp + (setq skk-extra-jisyo-file-list + (list '("/usr/share/skk/SKK-JISYO.JIS3_4" . euc-jisx0213) + "/usr/share/skk/SKK-JISYO.zipcode")) + #+END_SRC + + このように、辞書のファイル名のリストを指定します [fn:extrajisyo] 。 + + ただし、変数 ~skk-jisyo-code~ [fn:sjc] とは異なる文字コードのファイルに + ついては、上記の例中の ~SKK-JISYO.JIS3_4~ のように「ファイル名と文字コー + ドのペア」を記述します。 + +これらの変数の意味するところは初期設定でのものですが、 ~skk-search-prog-list~ の +設定で変更することもできます。 + +[[辞書検索のための関数][辞書検索のための関数]]. + +[fn:extrajisyo] ~skk-search-prog-list~ に登録されている関 +数 ~skk-search-extra-jisyo-files~ が、 ~skk-extra-jisyo-file-list~ の +各要素を逐次処理します。 + +[fn:sjc] [[辞書バッファの文字コードの設定][辞書バッファの文字コードの設定]]. + +*** 辞書の検索方法の設定 + +辞書の検索方法の指定は、変数 ~skk-search-prog-list~ で行われます。特に必 +要が無ければ、読み飛ばして下さい。 + +**** 辞書検索の設定の具体例 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +この節では ~skk-search-prog-list~ の初期設定を示し、大体の流れを説明しま +す。 + +DDSKK では、複数の辞書を扱うことが可能です。複数の辞書が同時並列に検索さ +れるのではなく、指定した順番に検索します。 ~skk-search-prog-list~ はリス +トであり、大雑把に言えば、確定されるまで先頭の要素から順に lisp として評 +価されます。 + +#+BEGIN_SRC emacs-lisp +((skk-search-kakutei-jisyo-file skk-kakutei-jisyo 10000 t) + (skk-search-jisyo-file skk-initial-search-jisyo 10000 t) + (skk-search-jisyo-file skk-jisyo 0 t) + (skk-okuri-search) + (skk-search-cdb-jisyo skk-cdb-large-jisyo) + (skk-search-jisyo-file skk-large-jisyo 10000) + (skk-search-server skk-aux-large-jisyo 10000) + (skk-search-ja-dic-maybe) + (skk-search-extra-jisyo-files) + (skk-search-katakana-maybe) + (skk-search-sagyo-henkaku-maybe)) +#+END_SRC + +この例では、 + +- ~skk-kakutei-jisyo~ ([[確定辞書][確定辞書]].) +- ~skk-initial-search-jisyo~ +- ~skk-jisyo~ (個人辞書) + +#+TEXINFO: @noindent +の順に検索を行い、次に + +- 送り仮名の自動処理 ([[送り仮名の自動処理][送り仮名の自動処理]].) + +#+TEXINFO: @noindent +を行い、その後 + +- ~skk-cdb-large-jisyo~ と + +- ~skk-large-jisyo~ の + +#+TEXINFO: @noindent +検索を順に行い、最後に ~skk-aux-large-jisyo~ に辞書サーバ経由でアクセスし +ています。 + +これらの辞書の意味について: [[辞書ファイルの指定][辞書ファイルの指定]]. + +もし確定辞書で候補が見つかったらそのまま自動的に確定されます。1回 ~SPC~ を +押す動作に対し、プログラム側では新たな候補を見つけるまで上記の動作を進め +ます。例えば、 + +- 確定辞書では候補は見つけられなかったが ~skk-initial-search-jisyo~ に候 + 補がある場合、そこでいったん止まりユーザにその候補を表示します。 + +- 更に ~SPC~ が押されると、次は個人辞書を検索します。そこで候補が見つかり、 + しかもその候補が ~skk-initial-search-jisyo~ で見つけた候補とは異なるも + のであったときは、そこでまた止まりその候補をユーザに表示します。 + +以降、共有辞書についても同様の繰り返しを行います。最後まで候補が見つから +なかった時は、辞書登録モードに入ります。 + +**** 辞書検索のための関数 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +前節で見たとおり、変数 ~skk-search-prog-list~ を適切に定義することによっ +て辞書の検索方法を指定します。そこで使われる辞書検索のための関数を使いこ +なすことで、より細かい辞書検索の方法を指定することができます。 + +#+CINDEX: 二分検索 +#+CINDEX: 直線的検索 +- Function: skk-search-jisyo-file FILE LIMIT &optional NOMSG + + 通常の検索を行うプログラム。変数 ~skk-henkan-key~ を見出し語(検索文字 + 列)として、 ~FILE~ を被検索対象として変換検索を実施します。個人辞書、 + 共有辞書又は辞書サーバを使わずに検索を行いたい場合はこの関数を使用しま + す。 + + 第1引数 ~FILE~ は、被検索対象となる辞書ファイルを指定します。 ~nil~ を + 指定したときは、検索を行いません。 ~FILE~ で指定した辞書ファイルは Emacs の + バッファに読み込まれます。 + + 第2引数 ~LIMIT~ は二分検索(バイナリ・サーチ)が行なわれる領域の大きさ + を指定します。ひとつの見出し語に対する変換動作に対し、検索対象の領域の + 大きさ [fn:bsearch] が第2引数に指定された数値より小さくなるまでは二分 + 検索が行われ、最後に直線的検索(リニア・サーチ、 ~search-forward~ )が + 1回行われます。 + + 第2引数に 0 を指定すると、常に直線的検索のみが行われます。個人辞書 ~skk-jisyo~ は + ソートされておらず二分検索が不可能であるため ~LIMIT~ を 0 にして下さい。 + + 第3引数 ~NOMSG~ が ~nil~ ならば、辞書ファイルをバッファに読み込む関 + 数 ~skk-get-jisyo-buffer~ のメッセージをエコーエリアに出力します。 ~non-nil~ を + 与えると出力しません。 + + +- Function: skk-search-cdb-jisyo CDB-PATH + + not documented + +#+CINDEX: 確定変換 +#+VINDEX: skk-kakutei-henkan-flag +- Function: skk-search-kakutei-jisyo-file FILE LIMIT &optional NOMSG + + 確定変換を行う検索プログラム。検索対象の辞書ファイルは Emacs のバッファ + に読み込まれます。検索対象のファイルから候補を見つけると、内部変数 ~skk-kakutei-henkan-flag~ を + 立てて、いきなり確定します。このためユーザが確定操作を行う必要はありま + せん。引数の意味はいずれも ~skk-search-jisyo-file~ の場合と同様です。 + +- Function: skk-okuri-search + + 自動送り処理を行うプログラム。変数 ~skk-auto-okuri-process~ の値が ~non-nil~ の + ときだけ機能します。個人辞書の送りありエントリを検索対象としているので、 + 個人辞書のバッファを流用します。そのため、専用の辞書バッファは作りません。 + + [[送り仮名の自動処理][送り仮名の自動処理]]. + +- Function: skk-search-server FILE LIMIT &optional NOMSG + + 辞書サーバ経由で検索するプログラム。辞書サーバが使用不能になると辞書フ + ァイルを Emacs のバッファに読み込んで検索を行います。引数の意味はいずれ + も ~skk-search-jisyo-file~ と同じですが、これらは辞書を Emacs のバッフ + ァに読み込んだときのみ利用されます。 + + 辞書サーバが使う辞書ファイルの設定については、 + + - [[辞書サーバを使いたいときの設定][辞書サーバを使いたいときの設定]]. + + - [[サーバ関連][サーバ関連]]. + + をご覧下さい。 + +[fn:bsearch] 検索領域の先頭ポイントと末尾ポイントの差 + +*** Emacs 付属の辞書 + +GNU Emacs には、 ~SKK-JISYO.L~ を元に変換された ~leim/ja-dic/ja-dic.el~ と +いう辞書が付属しています。 + +DDSKK 14.2 からは、この ~ja-dic.el~ を利用したかな漢字変換(送りあり、送 +りなし、接頭辞、接尾辞)が可能となりました。つまり、 ~SKK-JISYO.L~ などの +辞書ファイルを別途準備しなくても一応は DDSKK の使用が可能、ということです。 + +DDSKK 14.2 から追加された「ja-dic.el 検索機能」(~skk-search-ja-dic~) は、 + +- ~skk-large-jisyo~ +- ~skk-aux-large-jisyo~ +- ~skk-cdb-large-jisyo~ +- ~skk-server-host~ + +の全てが無効な場合に有効となります。 + +ただし、 ~SKK-JISYO.L~ を利用する場合と比べて英数変換や数値変換などができ +ません。可能な限り ~SKK-JISYO.L~ などの辞書を利用することを推奨します。 + +[[辞書の入手][辞書の入手]]. + +- User Option: skk-inhibit-ja-dic-search + + この変数を ~Non-nil~ に設定すると、 ~skk-large-jisyo~ 等の値にかかわら + ず、あらゆる場面で ~skk-search-ja-dic~ を無効とします。 + +- Function: skk-search-ja-dic + + GNU Emacs に付属するかな漢字変換辞書 ~ja-dic.el~ を用いて検索する。現在 + の GNU Emacs には ~SKK-JISYO.L~ を基に変換された ~ja-dic.el~ が付属して + いる。この辞書データを用いて送りあり、送りなし、接頭辞、接尾辞の変換を + 行う。ただし、 ~SKK-JISYO.L~ のような英数変換、数値変換などはできず、ま + た「大丈夫」のように複合語とみなしうる語彙が大幅に削除されている。 + +*** サーバ関連 + +辞書サーバの基本的な設定: [[辞書サーバを使いたいときの設定][辞書サーバを使いたいときの設定]]. + +- Variable: skk-servers-list + + この変数を使うと、複数のホスト上の辞書サーバを使い分けることができます。 + この変数の値は、辞書サーバ毎の情報リストです。各リストは次の4つの要素 + から成ります。 + + - ホスト名 + - 辞書サーバ名(フルパス) + - 辞書サーバが読み込む辞書ファイル名 + - 辞書サーバが使用するポート番号 + + ただし、辞書ファイル名及びポート番号は、辞書サーバ自身が決定することも + あるため、そのような場合は ~nil~ として構いません。 + + 例えば、以下のように設定します。 + + #+BEGIN_SRC emacs-lisp + (setq skk-servers-list + '(("host1" "/your/path/to/skkserv" nil nil) + ("host2" "/your/path/to/skkserv" nil nil))) + #+END_SRC + + 上記の設定の場合、まず host1 上の辞書サーバと接続します。接続できなくな + ると、次に host2 上の辞書サーバと接続します。 + +- Variable: skk-server-report-response + + この変数の値が ~non-nil~ であれば、変換時に、辞書サーバの送出する文字を + 受け取るまでに関数 ~accept-process-output~ が実行された回数をエコーエリ + アに報告します。 + + #+BEGIN_EXAMPLE + -------------------- Echo Area -------------------- + 辞書サーバの応答を 99 回待ちました + -------------------- Echo Area -------------------- + #+END_EXAMPLE + +- Variable: skk-server-inhibit-startup-server + + 標準設定値は ~t~ です。この変数を ~nil~ に設定すると、辞書サーバと接 + 続できない場合に ~call-process~ で辞書サーバプログラムの起動を試みます。 + + ~inetd~ 経由で起動する多くの辞書サーバは ~call-process~ で起動すること + ができませんが、 ~skkserv~ のように ~call-process~ で起動することができ + る辞書サーバを利用している場合には、この変数を ~nil~ に設定するのが良い + かもしれません。 + +- Variable: skk-server-remote-shell-program + + この変数には、リモートシェルのプログラム名を指定します。標準設定は、 + システム依存性を考慮する必要があるため、以下の Emacs Lisp コードを評価 + することにより決定されています。 + + #+BEGIN_SRC emacs-lisp + (or (getenv "REMOTESHELL") + (and (boundp 'remote-shell-program) remote-shell-program) + (cond + ((eq system-type 'berkeley-unix) + (if (file-exists-p "/usr/ucb/rsh") "/usr/ucb/rsh" "/usr/bin/rsh")) + ((eq system-type 'usg-unix-v) + (if (file-exists-p "/usr/ucb/remsh") "/usr/ucb/remsh" "/bin/rsh")) + ((eq system-type 'hpux) "/usr/bin/remsh") + ((eq system-type 'EWS-UX/V) "/usr/ucb/remsh") + ((eq system-type 'pcux) "/usr/bin/rcmd") + (t "rsh"))) + #+END_SRC + +- Function: skk-server-version + + 辞書サーバから得たバージョン文字列とホスト名文字列を表示する。 + + #+BEGIN_EXAMPLE + (skk-server-version) + -| SKK SERVER version (wceSKKSERV) 0.2.0.0 (ホスト名 foo:192.168.0.999: ) + #+END_EXAMPLE + +*** サーバコンプリージョン + +Server completion に対応した辞書サーバであれば、見出し語から始まる全ての +語句の検索が可能です。 + +- Function: skk-comp-by-server-completion + + この関数を ~skk-completion-prog-list~ の要素に追加すると、▽モードにお + いて見出し語補完を実行します。 + + #+BEGIN_SRC emacs-lisp + (add-to-list 'skk-completion-prog-list + '(skk-comp-by-server-completion) t) + #+END_SRC + +- Function: skk-server-completion-search + + この関数を ~skk-search-prog-list~ の要素に追加すると、変換を実行する際 + に ~skk-server-completion-search-char~ を付すことによって見出し語で始ま + るすべての候補を掲げます。 + + + #+BEGIN_SRC emacs-lisp + (add-to-list 'skk-search-prog-list + '(skk-server-completion-search) t) + #+END_SRC + + #+BEGIN_EXAMPLE + ------ Buffer: foo ------ + ▽おおさか~* + ------ Buffer: foo ------ + + SPC + + ------ Buffer: *候補* ------ + A:おおさかいかだいがく + S:大阪医科大学 + D:おおさかいがい + F:大阪以外 + J:おおさかいだい + K:大阪医大 + L:おおさかいちりつだいがく + ------ Buffer: *候補* ------ + #+END_EXAMPLE + +- Variable: skk-server-completion-search-char + + 標準設定は ~~~ (チルダ、 ~#x7e~ )です。 + +*** 辞書の書式 + +**** 送りありエントリと送りなしエントリ +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +以下は個人辞書の一例です。 + +#+CINDEX: ;; okuri-ari entries. +#+CINDEX: ;; okuri-nasi entries. +#+BEGIN_EXAMPLE +;; okuri-ari entries. +たとe /例/[え/例/]/ +もt /持/[つ/持/]/[って/持/]/[た/持/]/[て/持/]/[ち/持/]/[と/持/]/ +たすk /助/[け/助/]/ +うごk /動/[く/動/]/[か/動/]/[け/動/]/[き/動/]/[こ/動/]/ +ふくm /含/[め/含/]/[む/含/]/[ま/含/]/[み/含/]/[も/含/]/ +: +;; okuri-nasi entries. +てん /点/・/天/ +ひつよう /必要/ +さくじょ /削除/ +へんこう /変更/ +じゅんじょ /順序/ +ぐん /群/郡/ +こうほ /候補/ +いち /位置/一/壱/ +#+END_EXAMPLE + +#+CINDEX: エントリ +~てん /点/・/天/~ を例にして説明します。これは「てん」が見出し語であり、 +その候補が「点」、「・」、「天」です。候補はそれぞれ ~/~ によって区切られ +ています。SKK では、見出し語と候補群を合わせた ~てん /点/・/天/~ の一行 +を *エントリ* と呼びます。 + +辞書は単純なテキストファイルで、必ず下記の2つの行を持っています。 + +- ~;; okuri-ari entries.~ +- ~;; okuri-nasi entries.~ + +この2つの行は、それぞれ送り仮名あり、送り仮名なしのエントリの開始地点を +示すマークです。 ~;; okuri-ari entries.~ までの行で ~;~ を行頭に持つ行は +コメント行として無視されます。 ~;; okuri-ari entries.~ 以降にコメント行を +含むことはできません。 + +~;; okuri-ari entries.~ と ~;; okuri-nasi entries.~ の間に囲まれた上半分 +の部分が送り仮名ありのエントリです。これを *送りありエントリ* と呼びます。 + +~;; okuri-nasi entries.~ 以下の下半分部分が送り仮名なしのエントリです。 +これを *送りなしエントリ* と呼びます。 + +#+CINDEX: 送りあり変換 +#+CINDEX: 送りなし変換 +送りありエントリを検索する変換を *送りあり変換* 、送りなしエントリを検索 +する変換を *送りなし変換* と呼びます。SKK では送り仮名の有無が変換方法の +ひとつの種別となっています。送り仮名がある変換では送りありエントリのみが +検索され、送り仮名がない変換では送りなしエントリのみが検索されます。 + +ひとつの見出し語についてのエントリは1行内に書かれます。2行以上にまたが +ることはできません。改行を含む候補については ~(concat "改\n行")~ のように、 +評価すると改行を該当個所に挿入するような Lisp プログラムに変換して辞書に +収めています。 + +[[プログラム実行変換][プログラム実行変換]]. + +#+CINDEX: ローマ字プレフィックス +送りありエントリは、基本的には ~もt /持/~ のようになっています。送り仮名 +部分は、送り仮名をローマ字表現したときの1文字目 [fn:rp] で表現されていま +す。この1エントリで「持た」「持ち」「持つ」「持て」「持と」の5つの候補 +に対応します。その5つの候補の送り仮名をローマ字プレフィックスで表現すれば、 +いずれも ~t~ になります。 + +[fn:rp] あるかな文字をローマ字表現したときの1文字目を *ローマ字プレフィックス* と +呼びます。 + +**** 送りありエントリのブロック形式 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +個人辞書の送りありエントリには ~[~ と ~]~ に囲まれたブロックがあります。 +これは、そのブロックの先頭にある平仮名を送り仮名に取る候補群です。 + +#+BEGIN_EXAMPLE +たとe /例/[え/例/]/ +: +ふくm /含/[め/含/]/[む/含/]/[ま/含/]/[み/含/]/[も/含/]/ +#+END_EXAMPLE + +この例で見ると、見出し語「たとe」の場合は「え」を送り仮名とするひとつブロ +ックから構成されています。見出し語「ふくm」の場合は「ま」「み」「む」「め」「も」 +を送り仮名とする5ブロックに分けられています。 + +#+VINDEX: skk-auto-okuri-process +#+VINDEX: skk-henkan-okuri-strictly +この送り仮名毎のブロック部分は、 ~skk-henkan-okuri-strictly~ あるい +は ~skk-auto-okuri-process~ のいずれかの変数が ~non-nil~ である場合に使用 +されます。その場合、検索において、見出し語の一致に加えて、更に送り仮名も +マッチするかどうかをテストします。例えば、 + +#+BEGIN_EXAMPLE +おおk /大/多/[く/多/]/[き/大/]/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリがあるとします。同じ見出し語「おおk」であっても、送り仮名が +「き」であれば、候補は「大」のみで「多」は無視されます [fn:okuri] 。 + +#+VINDEX: skk-process-okuri-early +http://openlab.jp/skk/dic.html で配布されている共有辞書では、 ~[~ と ~]~ を +使用した送り仮名毎のブロックの形式に対応していません。個人辞書のみがこの +形式で書き込まれていきます。 ~skk-henkan-okuri-strictly~ が ~nil~ であっ +ても送り仮名のブロック形式で書き込まれます [fn:okuri2] 。 + +[fn:okuri] [[送り仮名の自動処理][送り仮名の自動処理]]. + +[[送り仮名の厳密なマッチ][送り仮名の厳密なマッチ]]. + +[[送り仮名の優先的なマッチ][送り仮名の優先的なマッチ]]. + +[fn:okuri2] ただし ~skk-process-okuri-early~ の値が ~non-nil~ であれば、 +送り仮名を決定する前に変換を開始することになるので、送り仮名を明示的に入 +力していても個人辞書にはブロック形式は作られません。 + +**** エントリの配列 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +#+CINDEX: 辞書のソート方法 +共有辞書は、送りありエントリは ~;; okuri-ari entries.~ から順に下方向に見 +出し語をキーとして *降順* に配置され、送りなしエントリ +は ~;; okuri-nasi entries.~ から順に下方向に見出し語をキーとして *昇順* に +配置されます。降順/昇順に配置されるのは、辞書サイズが大きいことに配慮して +二分検索(バイナリサーチ)を行うためです [fn:sort] 。 + +一方、個人辞書は、一番最後に変換された語が最も手前に置かれます。つまり、 +送りなしエントリは ~;; okuri-ari entries.~ を、送りありエントリは ~;; okuri-nasi entries.~ を +基点として最小ポイントに挿入されて辞書が更新されます [fn:ins] 。 +個人辞書は、通常は共有辞書ほどはサイズが大きくないので、検索時にはそれぞ +れの基点から直線的検索(リニアサーチ)が行われます。最後に確定された語は、 +ひとつのエントリの中の最初の位置に置かれます。 + +[fn:sort] ソートする際には、見出し語を unsigned-char と見なします。この順 +序は Emacs が 関数 ~string<~ で文字列を比較するときの順序であり、UNIX の ~sort~ コマンド +での標準の順序とは異なります。Emacs のコマンド ~sort-lines~ を用いればフ +ァイルをこの順序でソートすることができます。Emacs のコマンド ~sort-columns~ は +内部的に UNIX コマンドの ~sort~ を使っているので、辞書のソートには使えません。 + +[fn:ins] 正確に言えば、送りあり変換では ~skk-okuri-ari-min + 1~ の位置、 +送りなし変換では ~skk-okuri-nasi-min + 1~ の位置 + +*** 強制的に辞書登録モードへ入る + +▼モードにて、エコーエリアに変換候補が表示されているときに ~.~ を打鍵する +と、強制的に辞書登録モードへ入ります。 + +- Variable: skk-force-registration-mode-char + + 強制的に辞書登録モードへ入るためのキーキャラクタをこの変数で定義します。 + 標準設定は ~.~ です。 + +*** 誤った登録の削除 + +誤って個人辞書に登録した単語は削除できます。 + +削除したい単語を変換により求め、その単語が表示された時点 [fn:wrong] で ~X~ (大文字のエックス) +を打鍵します。ミニバッファに確認プロンプトが出るので ~y e s~ と答えると、 +個人辞書の対応するエントリが削除されます。現在のバッファに先程入力した +「誤りの変換結果」も削除されます。 + +例えば、 + +#+BEGIN_EXAMPLE +さいきてき /再起的/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリを誤って登録してしまったという仮定で、この誤登録を削除する +場合を説明します。 + +#+BEGIN_EXAMPLE +S a i k i t e k i SPC + + ------ Buffer: foo ------ + ▼再起的* + ------ Buffer: foo ------ + +X + + ------------------ MiniBuffer ------------------ + Really purge "さいきてき /再起的/" ? (yes or no) * + ------------------ MiniBuffer ------------------ + +y e s RET + + ------ Buffer: foo ------ + * + ------ Buffer: foo ------ +#+END_EXAMPLE + +[fn:wrong] 確定する前の▼モードの状態 + +*** 個人辞書ファイルの編集 + +*構文チェックが十分ではありません。個人辞書ファイルの編集は、自己責任のもと行ってください。* + +#+KINDEX: C-c C-c +- Key: M-x skk-edit-private-jisyo, skk-edit-private-jisyo + + このコマンドを使うと、個人辞書ファイルが開かれます [fn:sepj] 。個人辞書 + ファイルを開いて編集している最中も skk を使えますが、skk からの単語の登 + 録、削除はできません。他にも少し制限がありますが、気にならないでしょう。 + + 編集が終わったら ~C-c C-c~ とキー入力と、個人辞書ファイルを保存してバッ + ファを閉じます。 + +[fn:sepj] 前置引数を伴って実行する( ~C-u M-x skk-edit-private-jisyo~ ) +ことで、コーディングシステムを指定して個人辞書を開くことができます。 + +*** 個人辞書の保存動作 + +個人辞書の保存動作について説明します。個人辞書の保存が行われる場合として、 +次の4通りがあります。 + +- ~C-x C-c~ または ~M-x save-buffers-kill-emacs~ によって Emacs を終了す + る場合 + +- ~M-x skk-save-jisyo~ と入力したか、メニューバーの ~Save Jisyo~ を選択し + た場合 + +- 個人辞書の更新回数が、変数 ~skk-jisyo-save-count~ で指定された値に達し + た結果として、自動保存(オートセーブ)機能が働くとき。 + +- 変数 ~skk-save-jisyo-instantly~ が ~non-nil~ であれば、単語登録(単語削 + 除)のたびに個人辞書を保存する。 + +保存動作を分析して考えます。まず、 Emacs に読み込んだ個人辞書が更新されて +いるかどうかを調べます。更新されていたら保存動作に入ります。Emacs の個人 +辞書バッファを一時ファイルに保存して、そのファイルサイズが現存の(セーブ +前の)個人辞書より小さくないかどうかをチェックします。個人辞書より小さい +ときは、保存動作を継続するかどうか、確認のための質問がされます [fn:save1] 。 + +#+BEGIN_EXAMPLE +--------------------------- Minibuffer ----------------------------- +New ~/.skk-jisyo will be 11bytes smaller. Save anyway?(yes or no) +--------------------------- Minibuffer ----------------------------- +#+END_EXAMPLE + +#+TEXINFO: @noindent +ここで ~n o RET~ と答えた場合は、そこで保存動作が中止され、個人辞書は以前 +の状態のままになります。 ~y e s RET~ と答えた場合は、元の個人辞書を退避用 +の辞書 ~~/.skk-jisyo.BAK~ に退避し、一時ファイルに保存した新しい個人辞書 +を ~skk-jisyo~ に保存します。 + +もし、一時ファイルのサイズが 0 である場合は、なんらかの異常と考えられるた +め保存動作は直ちに中止されます。 +その場合は ~M-x skk-kill-emacs-without-saving-jisyo~ で Emacs を終了させ、 +個人辞書 (~skk-jisyo~) 及び個人辞書の退避用辞書 (~skk-backup-jisyo~) をチ +ェックするよう強くお勧めします [fn:save2] 。 + +- User Option: skk-compare-jisyo-size-when-saving + + この変数の値を ~nil~ に設定すると、保存前の個人辞書とのサイズを比較しま + せん。 + +- Variable: skk-jisyo-save-count + + この変数で指定された回数、個人辞書が更新された場合に個人辞書が自動保存 + されます。標準設定は 50 です。この値を ~nil~ にすると、個人辞書の自動 + 保存機能が無効になります。 + + ここで、個人辞書の更新回数は確定回数と一致します。また、同じ候補につい + て確定した場合でもそれぞれ1回と数えられます [fn:save3] 。 + +- User Option: skk-save-jisyo-instantly + + この変数が ~non-nil~ であれば、単語を登録するたび(削除するたび)に個人 + 辞書を保存します。 + +- User Option: skk-share-private-jisyo + + ~Non-nil~ であれば、複数の SKK による個人辞書の共有を考慮して辞書を更新 + する。 SKK 起動後にこの変数を変更した場合は ~M-x skk-restart~ で反映さ + せること。 + +[fn:save1] 通常の使用の範囲では ~M-x skk-purge-from-jisyo~ した場合、あ +るいは個人辞書をユーザが意図的に編集した場合、複数の Emacs で DDSKK を +使用した場合などに、個人辞書が小さくなることがあります。他の場合はバグの +可能性があります。 + +[fn:save2] ~skk-jisyo~ が既に壊れていても、変数 ~skk-backup-jisyo~ が指し +示すファイルにそれ以前の個人辞書が残っている可能性があります。 + +[fn:save3] これは、個人辞書の最小ポイントに、常に最後に変換を行ったエン +トリを移動させるために、エントリ数、候補数が全く増えていなくとも、確定に +より個人辞書が更新されているからです。 + +*** 変換及び個人辞書に関する統計 + +DDSKK は、かな漢字変換及び個人辞書に関する統計を取っており、Emacs の終了 +時にファイル ~~/.skk-record~ に保存します。保存する内容は、以下の形式です。 + +#+BEGIN_EXAMPLE +Sun Jul 28 09:38:59 1996 登録: 4 確定: 285 確定率: 98% 語数: 3042 +#+END_EXAMPLE + +上記の「語数:」の数は個人辞書 ~skk-jisyo~ に登録されている候補数ですが、 +ここでは1行を1語として数えています。そのため、ひとつの見出し語に対して +複数の候補を持っている場合は、2つ目以降の候補を無視しています。 + +- Variable: skk-record-file + + 統計情報を保存するファイル名を指定します。 + + [[設定ファイル][設定ファイル]]. + +- Variable: skk-keep-record + + この変数の値を ~nil~ に設定すると、本節で説明した統計機能を無効にします。 + 数値を設定すると、 ~skk-record-file~ を指定数値の行数より大きくしません。 + +- Variable: skk-count-private-jisyo-candidates-exactly + + この変数の値を ~non-nil~ に設定すると、「語数」の数え方を変更します。 + 具体的には、1行を1語として数えるのではなく、正確に語数を数えます。 + なお、その分時間がかかります。また、この場合でも ~[~ と ~]~ に囲まれた + 送り仮名毎のブロック形式内は数えません。 + +- Key: M-x skk-count-jisyo-candidates, skk-count-jisyo-candidates + +このコマンドを使うと、辞書の候補数を数えることができます。 + + #+BEGIN_EXAMPLE + M-x skk-count-jisyo-candidates + + --------------- MiniBuffer -------------- + Jisyo file: (default: /your/home/.skk-jisyo) ~/* + --------------- MiniBuffer -------------- + + . s k k - j i s y o RET + + -------------- Echo Area -------------- + Counting jisyo candidates... 100% done + -------------- Echo Area -------------- + + ------ Echo Area ------ + 3530 candidates + ------ Echo Area ------ + #+END_EXAMPLE + + ただし、 ~[~ と ~]~ に囲まれた送り仮名毎のブロック形式内は数えません。 + + また、メニューバーが使用できる環境では、メニューバーを使ってこのコマン + ドを呼び出すことができます。 + + [[info:emacs#Menu Bars][Menu Bars in GNU Emacs Manual]]. + +*** 辞書バッファ + +#+CINDEX: dabbrev.el +#+CINDEX: *SKK-JISYO.L* +#+FINDEX: fundamental-mode +#+VINDEX: major-mode +#+VINDEX: mode-name +#+VINDEX: skk-large-jisyo +#+CINDEX: 辞書バッファの名付け規則 + +辞書検索プログラムを実行すると、必要ならば辞書が Emacs のバッファに読み込 +まれます。このバッファを *辞書バッファ* と呼びます。辞書バッファの命名規 +則は、 + +#+BEGIN_EXAMPLE +空白 + * + 辞書ファイル名(ディレクトリ抜き) + * +#+END_EXAMPLE + +#+TEXINFO: @noindent +です。例えば、変数 ~skk-large-jisyo~ の値が ~/usr/local/share/skk/SKK-JISYO.L~ で +あるとき、これに対する辞書バッファ名は "~_*SKK-JISYO.L*~" (アンダーバーは SPACE の +意)となります。 + +このバッファのメジャーモードは ~fundamental-mode~ です。しかし、諸般の事 +情により、変数 ~major-mode~ の値をシンボル ~skk-jisyo-mode~ と、 +変数 ~mode-name~ の値を文字列 ~SKK dic~ としています [fn:skkjisyomode] 。 + +[fn:skkjisyomode] これは、Emacs の ~dabbrev.el~ の機能との調和を考えての +措置です。Dabbrev においては、現在のバッファと同じモードの他のバッファを +検索して abbreviation の展開を行うように設定することができるのですが、仮 +に辞書バッファにおける変数 ~major-mode~ の値が ~fundamental-mode~ のまま +だとすると、 Dabbrev が辞書バッファを検索してしまう可能性があります。この +措置によって、そのような事態を回避しています。 + +*** 辞書バッファの文字コードの設定 + +#+VINDEX: skk-coding-system-alist +#+FINDEX: skk-find-coding-system +#+FINDEX: describe-coding-system +#+FINDEX: list-coding-systems +#+FINDEX: coding-system-p +#+FINDEX:find-coding-system +- Variable: skk-jisyo-code + + この変数は、辞書ファイルの文字コードを決定し、以下のような値を取ります。 + + + ~nil~ (標準設定)この場合、シンボル ~euc-jis-2004~ が使われます [fn:ej2004] 。 + + + Emacs の coding system (コード系) [fn:codingsystem] + + + ~euc~, ~ujis~, ~sjis~, ~jis~ の文字列。 ~skk-coding-system-alist~ に + 従って、順に ~euc-jisx0213~, ~euc-jisx0213~, ~shift_jisx0213~, ~iso-2022-jp-3-strict~ の + 各シンボルへ変換されます。 + +[fn:codingsystem] coding system は GNU Emacs の場合 ~euc-jp~, ~shift_jis~, ~junet~ な +どのシンボルで表され、 ~M-x describe-coding-system~ や ~M-x list-coding-systems~ で +調べることができます。XEmacs の場合、シンボルは coding system そのもので +はなく coding system object を指示するためのシンボルとして扱われます。 +具体的には GNU Emacs では ~(coding-system-p 'euc-jp)~ が ~t~ を返すのに対 +し、 XEmacs では ~nil~ を返しますが、代わりにシンボルが示す coding system object を +返す関数 ~find-coding-system~ が存在します。 + +[fn:ej2004] 関数 ~skk-find-coding-system~ を参照のこと。 + +*** 辞書バッファの buffer-file-name + +#+VINDEX: buffer-file-name +#+FINDEX: save-some-buffers +#+KINDEX: M-x compile +Emacs には ~save-some-buffers~ という関数があります。この関数は、ファイル +に関連付けられている各バッファについて、変更があればファイルに保存します +が、実際に保存するかどうかをユーザに質問します。 + +Emacs のコマンドには ~M-x compile~ のように ~save-some-buffers~ を呼び出 +すものがあります。もし、個人辞書の辞書バッファがファイル名と関連付けられ +ていたとしたら、こうしたコマンドを実行するたびに個人辞書を保存するかどう +か質問されるので、面倒です。 + +DDSKK では、このような事態を避けるため、辞書バッファにおける変数 ~buffer-file-name~ の +値を ~nil~ に設定しています。 + +** 注釈(アノテーション) + +かな漢字変換の際に、候補に注釈(アノテーション)が登録されていれば、それ +を表示することができます。 + +*** アノテーションの基礎 + +この節では、辞書の中でのアノテーションの取り扱いを説明します。 + +アノテーションは、ユーザが登録したものと、共有辞書に元々登録されているも +の、それ以外の情報源から取得されるものの3つに大別されます。 + +ユーザが付けたアノテーションを「ユーザアノテーション」と呼びます。ユーザ +アノテーションは、次の形式で個人辞書に登録されます。 + +#+BEGIN_EXAMPLE +きかん /期間/機関;*機関投資家/基幹;*基幹業務/ +#+END_EXAMPLE + +上記のとおり、 ~;~ の直後に ~*~ が自動的に振られる [fn:ast] ことによって +ユーザが独自に登録したアノテーションであることが分かります。 + +一方、共有辞書に元々登録されているアノテーションを「システムアノテーショ +ン」と呼び、これは ~;~ の直後に ~*~ の文字を伴いません。システムアノテー +ションは、次の形式で辞書に登録されています。 + +#+BEGIN_EXAMPLE +いぜん /以前;previous/依然;still/ +#+END_EXAMPLE + +システムアノテーションは L 辞書等に採用されています。 + +上記のいずれでもなく、外部の辞典その他の情報源から得られるものを「外部ア +ノテーション」といいます。外部アノテーションは Emacs Lisp パッケージであ +る lookup.el、 Apple macOS 付属の辞書、Wiktionary/Wikipedia などから取得可 +能です。 + +[fn:ast] ~*~ の文字は変換時には表示されません。 + +*** アノテーションの使用 + +- Variable: skk-show-annotation + + この変数の値を ~non-nil~ に設定するとアノテーションを表示します [fn:viper] 。 + + + ~(setq skk-show-annotation t)~ + + アノテーションを常に表示します。 + + + ~(setq skk-show-annotation '(not list))~ + + 候補バッファ [fn:candbuf] ではアノテーションを表示しません。 + + + ~(setq skk-show-annotation '(not minibuf))~ + + ミニバッファにおけるかな漢字変換(単語登録時)では、アノテーションを + 表示しません。 + + + ~(setq skk-show-annotation '(not list minibuf))~ + + *候補バッファ及びミニバッファでは、アノテーションを表示しません。 + + + ~(setq skk-show-annotation nil)~ + + いかなる場合もアノテーションを表示しません。 + +- Variable: skk-annotation-delay + + アノテーションを表示するまでの遅延を秒で指定する。標準設定は 1.0 秒。 + +#+CINDEX: kill ring +#+VINDEX: interprogram-cut-function +- Key: C-w, skk-annotation-copy-key + + ~C-w~ をタイプすると、現在表示されているアノテーションを kill ring に保 + 存します [fn:killring] 。 + +- Variable: skk-annotation-show-as-message + + ~Non-nil~ (標準設定)であれば、アノテーションをエコーエリアに表示し + ます。 ~nil~ であれば、other-window を一時的に開いてアノテーションを表 + 示します。 ~other-window~ は、その候補を確定するか、その候補の選択を止 + める(次の候補の表示又は quit)と自動的に閉じます。 + + この変数の値にかかわらず、変数 ~skk-show-tooltip~ が ~non-nil~ の場合は + アノテーションをツールティップで表示します。 + +- Key: ^, skk-annotation-toggle-display-char + + 候補バッファで変換候補を一覧表示しているときにアノテーションの表示/非 + 表示を動的に切り替えるキーを設定します。標準設定は ~^~ です。 + + #+BEGIN_EXAMPLE + ----- Buffer: *候補* ----- + A:射 + S:亥;[十二支](12)いのしし + D:夷;夷狄 + F:姨;おば + J:洟;はな + K:痍;満身創痍 + L:維;維持 + ----- Buffer: *候補* ----- + + ^ + + ----- Buffer: *候補* ----- + A:射 + S:亥; + D:夷; + F:姨; + J:洟; + K:痍; + L:維; + ----- Buffer: *候補* ----- + #+END_EXAMPLE + +- Variable: skk-annotation-function + + ユーザアノテーションとシステムアノテーションを区別することで、ユーザア + ノテーションだけを表示したり、あるいはその逆を行うことが可能です。 + + 変数 ~skk-annotation-function~ に「表示したいアノテーションを ~non-nil~ と + 判定する関数」を定義します。アノテーション文字列を引数にして変数 ~skk-annotation-function~ が + 指し示す関数が ~funcall~ されて、戻り値が ~non-nil~ である場合に限って + アノテーションが表示されます。 + + #+BEGIN_SRC emacs-lisp + (setq skk-annotation-function + (lambda (annotation) + (eq (aref annotation 0) ?*))) + #+END_SRC + + 上記の例では、アノテーションの先頭が ~*~ で始まる「ユーザアノテーション」 + の場合に ~t~ を返すλ式を ~skk-annotation-function~ に定義しました。こ + れによってユーザアノテーションだけが表示されます。 + +[fn:viper] Viper 対策はまだ行われていません。 ~~/.viper~ に次のように書い +て下さい。 ~(viper-harness-minor-mode "skk-annotation")~ + +[fn:candbuf] ~skk-show-candidates-always-pop-to-buffer~ + +[fn:killring] kill ring については info を参照。 + +[[info:emacs#Kill Ring][The Kill Ring in GNU Emacs Manual]]. + +保存した内容を Emacs 以外のアプリケーションで利用したい場合は変数 ~interprogram-cut-function~ を +設定してください。 + +*** アノテーションの登録 + +- Key: M-x skk-annotation-add, skk-annotation-add + + アノテーションを登録/修正するには、アノテーションを付けたい単語を確定 + した直後に同じバッファで ~M-x skk-annotation-add~ と実行します。アノテー + ションを編集するバッファ ~*SKK annotation*~ が開いてカレントバッファに + なりますので、アノテーションとして表示する文章を編集してください。編集 + が終わったら ~C-c C-c~ とタイプします。 + + その単語に既にアノテーションが付いている場合は、あらかじめ当該アノテー + ションを挿入して ~*SKK annotation*~ バッファを開きます。 + +- Key: M-x skk-annotation-kill, skk-annotation-kill + + 上記 ~M-x skk-annotation-add~ を実行したもののアノテーションを付けず + に ~*SKK annotation*~ バッファを閉じたいときは ~C-c C-k~ とタイプする + か ~M-x skk-annotation-kill~ を実行してください。 + +- Key: M-x skk-annotation-remove, skk-annotation-remove + + 特定の語からアノテーションを取り去りたいときは、まず、かな漢字変換で当該 + 語を確定し、続けて ~M-x skk-annotation-remove~ と実行します。 + +*** アノテーションとして EPWING 辞書を表示する + +~skk-lookup.el~ に含まれる関数 ~skk-lookup-get-content~ を活用することに +より、EPWING 辞書から得た内容をアノテーション表示することが可能です。辞書 +検索ツールの Lookup [fn:lookup] が正常にインストールされていることが前提 +です。Lookup を新規にインストールした場合は、SKK をインストールし直す必要 +があります。 + +EPWING 辞書の内容をアノテーション表示するには、2つの方法があります。 + +[fn:lookup] http://openlab.jp/edict/lookup/ + +**** skk-treat-candidate-appearance-function を設定する方法 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +候補の表示を装飾する関数を指定する変数 ~skk-treat-candidate-appearance-function~ を +設定する場合は、 ~etc/dot.skk~ に示されている設定例を以下のように変更して +ください。 + +#+BEGIN_SRC emacs-lisp ++ (require 'skk-lookup) + (setq skk-treat-candidate-appearance-function + #'(lambda (candidate listing-p) + (let* ((value (skk-treat-strip-note-from-word candidate)) + (cand (car value)) ;候補 +- (note (cdr value)) ;注釈 ++ (note (skk-lookup-get-content cand listing-p)) + (sep (if note ;セパレータ + : +#+END_SRC + +- Function: skk-lookup-get-content 単語 listing-p + + *単語* の意味を EPWING 辞書から取得します。オプション引数 ~listing-p~ が + ~non-nil~ ならば候補一覧用に一行の短い文字列を返しますが、 ~nil~ な + らば全体を返します。 + +- Variable: skk-lookup-get-content-nth-dic + + 関数 ~skk-lookup-get-content~ が「どの EPWING 辞書から単語の意味を取得 + するのか」を、ゼロを起点とした数値で指定します。docstring に例示した S 式 + を評価してみてください。 + +- Key: M-x skk-lookup-get-content-setup-dic, skk-lookup-get-content-setup-dic + + DDSKK の起動後に変数 ~skk-lookup-get-content-nth-dic~ の数値を変更した + 場合は、このコマンドを必ず実行してください。 + +**** skk-annotation-lookup-lookup を設定する方法 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +次に変数 ~skk-annotation-lookup-lookup~ について説明します。この変数は EPWING 経 +由アノテーションの設定を簡単にします。 + +- Variable: skk-annotation-lookup-lookup + + ~Non-nil~ ならば ~lookup.el~ を利用してアノテーションを取得する。 + + #+BEGIN_SRC emacs-lisp + (setq skk-annotation-lookup-lookup t) + #+END_SRC + + この値をシンボル ~always~ に設定 [fn:sall] すると、候補一覧でも辞書サー + ビスを引く。 + + #+BEGIN_SRC emacs-lisp + (setq skk-annotation-lookup-lookup 'always) + #+END_SRC + +[fn:sall] この設定は変数 ~skk-treat-candidate-appearance-function~ の値を +上書きします。 ~skk-treat-candidate-appearance-function~ を自分で設定する +場合は ~skk-annotation-lookup-lookup~ には ~t~ または ~nil~ を必要に応じ +て設定します。 + +*** Apple macOS 「辞書」サービスからアノテーションを取得する + +Apple Mac OS X 10.5 (Leopard) 以降に標準で入っている国語辞典などからアノ +テーションが取得できます。 + +この機能を利用するには、python の拡張機能として ~readline~ と ~pyobject-framework-DictionaryServices~ が必要です。 +後者については Apple Mac OS X 10.5 (Leopard) 以降の OS 標準の python に初 +めからインストールされています。 ~readline~ については Apple Mac OS X 10.7 (Lion) 標 +準の python ではインストールする必要がありません。Apple Mac OS X 10.6 (Snow Leopard) 以 +前の場合は + +#+BEGIN_SRC shell-script +% easy_install readline +#+END_SRC + +#+TEXINFO: @noindent +などの方法でインストールします。 + +今のところ、アノテーションを取得する辞典を選択することはできません。 +Apple macOS (OS X) の「辞書」アプリ (~Dictionary.app~) を起動し、環境設定 +から辞書の検索順を指定してください。国語辞典を上位に指定すれば使いやすく +なります。 + +- User Option: skk-annotation-lookup-DictionaryServices + + ~Non-nil~ ならば Apple macOS (OS X) の辞書サービスを利用してアノテーシ + ョンを取得する。 + + #+BEGIN_SRC emacs-lisp + (setq skk-annotation-lookup-DictionaryServices t) + #+END_SRC + + この値をシンボル ~always~ に設定すると、候補一覧でも辞書サービスを引く [fn:sald] 。 + + #+BEGIN_SRC emacs-lisp + (setq skk-annotation-lookup-DictionaryServices 'always) + #+END_SRC + +- Variable: skk-annotation-python-program + + アノテーション取得のために呼びだす python のプログラム名。 + + #+BEGIN_SRC emacs-lisp + (setq skk-annotation-python-program "/usr/bin/python") + #+END_SRC + +[fn:sald] この設定は変数 ~skk-treat-candidate-appearance-function~ の値を +上書きします。 ~skk-treat-candidate-appearance-function~ を自分で設定した +い場合は ~skk-annotation-lookup-DictionaryServices~ には ~t~ または ~nil~ を +必要に応じて設定します。 + +*** Wikipedia/Wiktionary からアノテーションを取得する + +候補にアノテーションの登録がない場合、アノテーションに代えて + +- [[http://ja.wiktionay.org/][Wiktionary]] + +- [[http://ja.wikipedia.org/][Wikipedia]] + +による解説を表示することができます。他のアノテーションが変換時に自動的に +表示されるのに対し、 Wikipedia/Wiktionary アノテーションは基本的にユーザ +の指示によって取得される点が異なります。 + +▼モードで候補を表示しているときに ~C-i~ を押すと、 ~skk-annotation-other-sources~ で +指定された順で解説を取得してエコーエリアに表示 [fn:tooltip] します。 + +#+BEGIN_EXAMPLE +B o k u j o u + + ----- Buffer: foo ----- + ▽ぼくじょう* + ----- Buffer: foo ----- + +SPC + + ----- Buffer: foo ----- + ▼牧場* + ----- Buffer: foo ----- + +C-i + + ----------------------------- Echo Area ------------------------------ + 牧場(ぼくじょう)とは、ウシ、ウマなどの家畜を飼養する施設。訓読みされ + てまきばと呼ばれることもある。 + ----------------------------- Echo Area ------------------------------ +#+END_EXAMPLE + +エコーエリアに解説が表示されている最中に ~C-o~ を押すと、関数 ~browse-url~ を +用いて、その解説の元となった URL をブラウズします。 + +- Variable: skk-annotation-wikipedia-key + + 標準設定は ~C-i~ です。 + +- Variable: skk-annotation-browse-key + + 標準設定は ~C-o~ です。EWW (Emacs Web Wowser) で閲覧したい場合は、次 + のとおり設定してください。 [[info:eww#Top]]. + + #+BEGIN_SRC emacs-lisp + (setq browse-url-browser-function 'eww-browse-url) + #+END_SRC + +- Variable: skk-annotation-other-sources + + アノテーションを取得する SKK 辞書以外のソースを指定します。 + +[fn:tooltip] 変数 ~skk-show-tooltip~ が ~non-nil~ の場合、ツールティップ +で表示します。 + +*** 外部コマンドからアノテーションを取得する + +外部コマンドからアノテーションを取得できます。 + +- Variable: skk-annotation-lookup-dict + + ~Non-nil~ ならば、 ~skk-annotation-dict-program~ に指定された外部コマン + ドからアノテーションを指定します。 + +- Variable: skk-annotation-dict-program + + アノテーションを取得するための外部コマンド名を指定します。 + +- Variable: skk-annotation-dict-program-arguments + + アノテーションを取得に使う外部コマンドに渡す引数を指定します。 + +*** 各種アノテーション機能を SKK の枠をこえて活用する + +前述した各種外部アノテーション (lookup.el + EPWING 辞書、 Apple macOS 辞書、 +Wikipedia/Wiktionary) は、SKK の変換モードだけでなく Emacs のあらゆる状 +況で辞書引き機能として使うことができます。そのためには、コマンド +~skk-annotation-lookup-region-or-at-point~ を任意にキー定義します。 + +- Function: skk-annotation-lookup-region-or-at-point &optional PREFIX-ARG START END + + このコマンドは、領域が指定されていればその領域の文字列をキーワードとし + て Lookup.el, Apple macOS 辞書サービス、または Wikipedia/Wiktionary ア + ノテーションを探し、表示します。領域が指定されていなければ、可能な範囲 + でその位置にある単語(始点と終点)を推測します。 + +一例として、以下のキー割当を紹介します。 + +#+BEGIN_SRC emacs-lisp +(global-set-key "\M-i" 'skk-annotation-lookup-region-or-at-point) +#+END_SRC + +このようにしておくと、何かの意味が調べたくなったとき、領域選択して ~M-i~ と +打鍵すればその場で辞書を引くことができます。 + +さらに、ユーザオプション ~skk-annotation-other-sources~ の3番目 (Apple macOS で +は4番目) は標準で ~en.wiktionary~ になっています。例えば、英文を読んでい +て buffer という語の正確な意味を参照したくなったとします。そのときは単語 buffer に +ポイントを合わせて ~M-3 M-i~ (Apple macOS では ~M-4 M-i~) とプレフィック +ス付でコマンドを実行してみてください [fn:saos] 。 + +#+BEGIN_EXAMPLE +----- Buffer: *scratch* ----- +;; This buffer* is for notes you don't want to save, and for ... +----- Buffer: *scratch* ----- + +M-3 M-i (Apple macOS では M-4 M-i) +#+END_EXAMPLE + +#+TEXINFO: @noindent +すると SKK モードでのアノテーションと同様、以下のような説明が表示されます。 + +#+BEGIN_EXAMPLE +-------------------- Echo Area -------------------- + English, Noun +buffer (plural buffers) + 1: Someone or something that buffs. + 2: (chemistry) A solution used to stabilize the pH (acidity) of a + liquid. + 3: (computing) A portion of memory set aside to store data, often + before it is sent to an external device or as it is received from an + external device. +-------------------- Echo Area -------------------- +#+END_EXAMPLE + +[fn:saos] ~skk-annotation-other-sources~ の標準の値は環境によって異なりま +す。 ~lookup.el~ と ~skk-lookup.el~ の設定が有効になっている場合は ~en.wiktionary~ は +4番目 (Apple macOS では5番目) になります。 + +** 文字コード関連 + +*** 文字コードまたはメニューによる文字入力 + +#+CINDEX: JISコード +#+CINDEX: EUCコード +#+KINDEX: \ +#+KINDEX: C-u \ +#+KINDEX: skk-kcode-charset +かなモードで ~\~ キーを打鍵すると、ミニバッファに + +#+BEGIN_EXAMPLE +---------------------------- Minibuffer ----------------------------- +○○の文字を指定します。7/8 ビット JIS コード (00nn), 区点コード (00-00), +UNICODE (U+00nn), または [RET] (文字一覧): * +---------------------------- Minibuffer ----------------------------- +#+END_EXAMPLE + +#+TEXINFO: @noindent +というプロンプトが表示され、文字コード(JIS コード、EUC コードまたは区点 +番号)またはメニューによる文字入力が促されます。 + +プロンプト中の○○部分は、変数 ~skk-kcode-charset~ の値であり、その初期値 +は ~japanese-jisx0208~ 又は ~japanese-jisx0213-1~ です。初期値は環境によ +って自動的に設定されます。キー ~\~ の代わりに ~C-u \~ と入力すると、異な +る文字集合 (charset) を指定する事ができます。 + +ここで、文字コードがあらかじめ分かっている場合には、その文字コードを入力 +します。例えば *℃* の文字コードは、JIS コードでは ~216e~ 、EUCコードで +は ~a1ee~ なので、いずれかの文字コードを入力すれば ℃ が現在のバッファに +挿入されます。 + +区点番号で入力するには ~01-78~ のように区と点の間にハイフン ~-~ を入れる +必要があります。ハイフン ~-~ で区切った3組の数字は JIS X 0213 の2面を指 +定したとみなします。例えば ~2-93-44~ で「魚花」(ほっけ U+29e3d)が入力で +きます。 + +*** メニューによる文字入力 + +文字コードが不明の文字を入力するには、文字コードを入力せずにそのまま +~RET~ キーを入力します。するとミニバッファに以下のような表示が現れま +す。 + +# 次の例示中では空欄となっているが、実行時は W: は U+ff0d (-), +# R: は U+2295 (⊕), Y: は U+2194 (↔) である。 + +#+BEGIN_EXAMPLE +---------------------------- Minibuffer ----------------------------- +A:  S: ̄ D:〜 F:} G:= H:¢ Q:◆ W:  E:∩ R:  T:≡ Y:  +---------------------------- Minibuffer ----------------------------- +#+END_EXAMPLE + +これを *第1段階のメニュー* と呼びます。第1段階のメニューでは、JIS 漢字 +をコードの順に 16 文字毎に1文字抽出し、ミニバッファに一度に 12 文字ずつ +表示しています(上記の例では、JIS コード 2121(全角スペース)、2131、2141、 +2151... の文字がそれぞれ表示されています)。ここで ~SPC~ を打鍵すると次の +候補群を表示します(文字コードの値を 16 * 12 = 192 ずつ増やします)。 +キー ~x~ を打鍵するとひとつ前の候補群に戻ります。 + +キー ~a~, ~s~, ~d~, ~f~, ~g~, ~h~, ~q~, ~w~, ~e~, ~r~, ~t~, ~y~ のいずれ +かを打鍵する [fn:asdfgh] と、そのキーに対応する文字から始まる 16 個の文字 +が文字コード順に表示されます。これを *第2段階のメニュー* と呼びます。例 +えば、第1段階のメニューが上記の状態のときに ~d~ を打鍵すると 第2段階の +メニューは以下のようになります。 + +#+BEGIN_EXAMPLE +--------------------------------- Minibuffer ----------------------------- +A:〜 S:‖ D:| F:… G:‥ H:‘ J:’ K:“ L:” Q:( W:) E:〔 R:〕 T:[ Y:] U:{ +--------------------------------- Minibuffer ----------------------------- +#+END_EXAMPLE + +ここで、キー ~a~, ~s~, ~d~, ~f~, ~g~, ~h~, ~j~, ~k~, ~l~, ~q~, ~w~, ~e~, ~r~, ~t~, ~y~, ~u~ の +いずれかを打鍵すると、対応する文字がカレントバッファに挿入されてメニュー +による入力が終了します。 + +第2段階のメニューが表示されているときも ~SPC~ と ~x~ キーにより第2段階 +のメニューが前進、後退します。 + +また、キー ~<~ 及び ~>~ により、メニューを1文字分だけ移動します。例えば、 +第2段階のメニューが上記の状態のときにキー ~<~ を打鍵すると、メニューは以 +下のようになります。 + +#+BEGIN_EXAMPLE +--------------------------------- Minibuffer ----------------------------- +A:\ S:〜 D:‖ F:| G:… H:‥ J:‘ K:’ L:“ Q:” W:( E:) R:〔 T:〕 Y:[ U:] +--------------------------------- Minibuffer ----------------------------- +#+END_EXAMPLE + +第1段階あるいは第2段階のメニューが表示されているときにキー ~?~ を打鍵す +ると、そのときのキー ~A~ に対応する文字(上記の例では *\* )の文字コード +が表示されます。 + +- Variable: skk-kcode-method + + キー ~\~ の打鍵で起動する ~skk-input-by-code-or-menu~ の挙動を調節しま + す。 + + + シンボル ~char-list~ + + キー ~\~ の打鍵で「文字コード一覧」 (~skk-list-chars~) を起動します。 + + + シンボル ~code-or-char-list~ + + キー ~\~ の打鍵で「文字コード」 (~skk-input-by-code~) を起動します。 + JIS コード/区点コード入力プロンプトの表示に対して単に ~RET~ をタイプ + した場合、「文字コード一覧」 (~skk-list-chars~) を起動します。 + + + シンボル ~this-key~ + + キー ~\~ の打鍵で ~\~ を挿入します。 + + + 上記シンボル以外 + + キー ~\~ の打鍵で「文字コード」 (~skk-input-by-code~) を起動します。 + JIS コード/区点コード入力プロンプトの表示に対して単に ~RET~ をタイプ + した場合、「メニュー入力」を起動します。 + +[fn:asdfgh] 大文字でも小文字でも構いません。なお、第1段階・第2段階とも +に、メニューのキーを変更することができます。 + +[[候補の選択に用いるキー][候補の選択に用いるキー]]. + +*** 文字コード一覧 + +#+KINDEX: M-x skk-list-chars +#+KINDEX: M-x list-charset-chars +#+KINDEX: C-x 8 RET +#+VINDEX: skk-kcode-charset + +~M-x skk-list-chars~ と実行すると、変数 ~skk-kcode-charset~ が指す文字集 +合に従ってバッファ ~*skk-list-chars*~ に文字の JIS コード一覧が表示されま +す。プレフィックス付きで、つまり ~C-u M-x skk-list-chars~ と実行すると、 +カーソル位置の文字に照準をあわすようコード一覧を表示します。 + +#+BEGIN_EXAMPLE +-------------------- *skk-list-chars* -------------------- +variable skk-kcode-charset's value is `japanese-jisx0208'. + +01-#x--- 0-- 1-- 2-- 3-- 4-- 5-- 6-- 7-- 8-- 9-- A-- B-- C-- D-- E-- F +  2120     、 。 , . ・ : ; ? ! ゛ ゜ ´ ` ¨ +  2130 ^  ̄ _ ヽ ヾ ゝ ゞ 〃 仝 々 〆 〇 ー — ‐ / +  2140 \ 〜 ‖ | … ‥ ‘ ’ “ ” ( ) 〔 〕 [ ] +  2150 { } 〈 〉 《 》 「 」 『 』 【 】 + − ± × +  2160 ÷ = ≠ < > ≦ ≧ ∞ ∴ ♂ ♀ ° ′ ″ ℃ ¥ +-------------------- *skk-list-chars* -------------------- +#+END_EXAMPLE + +- Key: C-f, next-completion +- Key: f, next-completion +- Key: l, next-completion + + カーソル移動 + +- Key: C-b, previous-completion +- Key: b, previous-completion +- Key: h, previous-completion + + カーソル移動 + +- Key: C-n, skk-list-chars-next-line +- Key: n, skk-list-chars-next-line +- Key: j, skk-list-chars-next-line + + カーソル移動 + +- Key: C-p, skk-list-chars-previous-line +- Key: p, skk-list-chars-previous-line +- Key: k, skk-list-chars-previous-line + + カーソル移動 + +- Key: C-x C-x, skk-list-chars-goto-point + + カーソル移動 + +- Key: RET, skk-list-chars-insert +- Key: i, skk-list-chars-insert + + 文書バッファへ文字を挿入 + +- Key: g, skk-list-chars-jump + +- Key: \, skk-list-chars-other-charset +- Key: o, skk-list-chars-other-charset + + 文字集合の切り替え + +- Key: c, skk-list-chars-code-input + + 文字コード入力 + +- Key: $, skk-list-chars-display-code + + カーソル位置の文字の文字コードを表示 + +- Key: w, skk-list-chars-copy + +- Key: q, skk-list-chars-quit + + skk-list-chars を抜ける + +ほか、Emacs のコマンド ~M-x list-charset-chars~ や ~C-x 8 RET~ も有用でしょう。 + +- Variable: skk-list-chars-table-header-face + + コード一覧の枠線などに適用するフェイスです。 + +- Variable: skk-list-chars-face + + プレフィックス付きで実行したときの照準のフェイスです。 + +*** 文字コードを知る方法 + +#+KINDEX: $ +#+KINDEX: M-x skk-display-code-for-char-at-point +#+CINDEX: JISコード +#+CINDEX: EUCコード + +かなモード/カナモードでキー ~$~ を打鍵する [fn:sdcfcap] と、現在のポイン +ト位置の直後にある文字の文字コードをエコーエリア [fn:sdcfcap2] に表示します。 + +例えば、カーソルを文字 ~А~ の上に置いて ~$~ を入力すると、 + +#+BEGIN_EXAMPLE +-------------------- Echo Area -------------------- +`А',KUTEN:07-01, JIS:#x2721, EUC:#xa7a1, SJIS:#x8440, UNICODE:U+0410, +キリール大文字A,CYRILLIC CAPITAL LETTER A +-------------------- Echo Area -------------------- +#+END_EXAMPLE + +#+TEXINFO: @noindent +とエコーエリアに表示され、この文字がキリル文字であることがわかります。 + +ほか、 Emacs のコマンド ~M-x describe-char~ も有用でしょう。 + +- Variable: skk-display-code-prompt-face + + エコーエリアに表示されるメッセージ中 ~KUTEN:~ 、 ~JIS:~ 、 ~EUC:~ 、 ~SJIS:~ 及 + び ~UNICODE:~ に適用するフェイスです。 + +- Variable: skk-display-code-char-face + + エコーエリアに表示されるメッセージ中の当該文字に適用するフェイスです。 + +- Variable: skk-display-code-tankan-radical-face + + エコーエリアに表示されるメッセージ中の総画数表示に適用するフェイスです。 + +- Variable: skk-display-code-tankan-annotation-face + + エコーエリアに表示されるメッセージ中の文字名表示に適用するフェイスです。 + +[fn:sdcfcap] リードオンリーなバッファでは ~M-x skk-display-code-for-char-at-point~ を +実行してください。 + +[fn:sdcfcap2] 変数 ~skk-show-tooltip~ が ~non-nil~ であればツールティップ +で表示します。変数 ~skk-show-candidates-always-pop-to-buffer~ が ~non-nil~ で +あれば other-window に表示します。 ~skk-show-tooltip~ が優先します。 + +** DDSKK 以外のツールを用いた辞書変換 + +*** skk-lookup + +#+CINDEX: skk-lookup.el +#+CINDEX: Lookup +#+VINDEX: skk-lookup-search-agents +#+FINDEX: skk-lookup-search + +~skk-lookup.el~ を使用すると、辞書検索ツールの [[http://openlab.jp/edict/lookup/][Lookup]] で +検索できる辞書を用いて単語の候補を出すことができるようになります。 + +DDSKK のインストール過程で ~(require 'lookup)~ が成功する場合は ~skk-lookup.el~ も +自動的にインストールされます。まずは ~make what-where~ を実行して ~SKK modules:~ 欄 +に ~skk-lookup~ が含まれていることを確認してください。 + +Lookup がインストールされているにも関わらず、うまく ~skk-lookup.el~ が +インストールされない場合は、 ~SKK-CFG~ を編集して ~lookup.el~ が置かれて +いるパスを ~ADDITIONAL_LISPDIR~ に設定し、再度 DDSKK をインストールして下 +さい [fn:sls] 。 + +~~/.skk~ に以下のように設定します。 + +#+BEGIN_SRC emacs-lisp +(setq skk-search-prog-list + (append skk-search-prog-list + (list + '(skk-lookup-search)))) +#+END_SRC + +~skk-lookup-search~ は、 DDSKK が用意している検索プログラムの中で最も遅い +ものです。したがって、 ~skk-search-prog-list~ の設定にあっては辞書サーバ +の検索 (~skk-search-server~) よりも後方に置くよう設定します。 + +Lookup の agent で利用するのは、 ~lookup-search-agents~ から ~ndkks~, +~ndcookie~ 及び ~ndnmz~ を取り去ったものです [fn:lookup] 。 + +[fn:sls] 関数 ~skk-lookup-search~ が ~skk-autoloads.el~ に追加されます。 + +[[辞書検索のための関数][辞書検索のための関数]]. + +[fn:lookup] ~skk-lookup-search-agents~ にセットして検索するようにしていま +す。Lookup とは異なる設定をする場合、この変数の設定を変更すれば可能です。 + +*** skk-look + +~skk-look.el~ は、 ~look~ コマンドを使って3つの機能を提供します。 + +**** 英単語の補完 +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +- Variable: skk-use-look + + ~non-nil~ に設定すると ~skk-look.el~ が使用できるようになります。例え + ば ~~/.skk~ で以下のように設定します。 + + #+BEGIN_SRC emacs-lisp + (setq skk-use-look t) + #+END_SRC + +SKK abbrev モードが拡張されて ~look~ コマンドを使用した補完が有効になりま +す。 + +#+BEGIN_EXAMPLE +/ a b s t r + + ------ Buffer: foo ------ + ▽abstr* + ------ Buffer: foo ------ + +TAB + + ------ Buffer: foo ------ + ▽abstract* + ------ Buffer: foo ------ +#+END_EXAMPLE + +#+TEXINFO: @noindent +と補完してくれます。通常の補完と同様に ~.~ (ピリオド)で次の補完候補 +に、 ~,~ (コンマ)でひとつ前の補完候補に移動できます。 + +SKK 形式の英和辞書 edict [fn:edict] があれば、ここから ~SPC~ を押して英和 +変換ができます。 + +[fn:edict] [[辞書の入手][辞書の入手]]. + +**** 英単語をあいまいに変換して取り出す +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +見出し語にアスタリスク ~*~ を入れて ~SPC~ を押すと、英単語をあいまいにし +て変換できます。 + +#+BEGIN_EXAMPLE + ------ Buffer: foo ------ + ▽abstr* + ------ Buffer: foo ------ + +SPC + + ------ Buffer: foo ------ + ▼abstract* + ------ Buffer: foo ------ +#+END_EXAMPLE + +確定すると、 ~abstr*~ を見出し語と、 ~abstract~ を候補とするエントリが個 +人辞書に追加されます。このようなエントリを追加したくない場合、 +ユーザ変数 ~skk-search-excluding-word-pattern-function~ を適切に設定しま +す。例えば次のような設定です。 + +- Variable: skk-search-excluding-word-pattern-function + + #+BEGIN_SRC emacs-lisp + (add-hook 'skk-search-excluding-word-pattern-function + ;; 返り値が non-nil の時、個人辞書に取り込まない。 + ;; KAKUTEI-WORD を引数にしてコールされるので、不要でも引数を取る + ;; 必要あり + (lambda (kakutei-word) + (and skk-abbrev-mode + (save-match-data + ;; SKK-HENKAN-KEY が "*" で終わるとき + (string-match "\\*$" skk-henkan-key))))) + #+END_SRC + +**** 英単語をあいまいに変換して取り出した後、更に再帰的な英和変換を行う +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +SKK 辞書に + +#+BEGIN_EXAMPLE +abstract /アブストラクト/抽象/ +abstraction /アブストラクション/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +というエントリがあるとして解説します [fn:edict辞書] 。 + +- Variable: skk-look-recursive-search + + ~non-nil~ であれば、英単語 + その英単語を見出し語にした候補の「セット」 + を変換結果として出力することができます。 + + #+BEGIN_EXAMPLE + ▽abstr* + + SPC + + ▼abstract + + SPC + + ▼アブストラクト + + SPC + + ▼抽象 + + SPC + + ▼abstraction + + SPC + + ▼アブストラクション + #+END_EXAMPLE + +- Variable: skk-look-expanded-word-only + + この変数の値が ~non-nil~ であれば、再帰検索に成功した英単語の「セット」 + だけを出力することができます。再帰検索で検出されなかった英単語は無視し + て出力しません。 + +[fn:edict辞書] edict 辞書 ~SKK-JISYO.edict~ があれば、例えば、 +#+BEGIN_SRC emacs-lisp +(setq skk-search-prog-list + (append skk-search-prog-list + (list + '(skk-search-jisyo-file "/your-path/SKK-JISYO.edict" 0 t)))) +#+END_SRC +のように設定することにより、 edict 辞書を使用できます。 + +*** Lisp シンボル名の補完検索変換 + +SKK abbrev モードにて、Lisp シンボル名を補完して検索し、検索結果を候補と +して返すことができます。英文字の後ろに *~* を付加してから変換を開始してく +ださい。 + +まずは動作例を示します。 + +#+BEGIN_EXAMPLE +/ d e f i ~ + + ----- Buffer: foo ----- + ▽defi~* + ----- Buffer: foo ----- + +SPC + + ----- Buffer: foo ----- + ▽defimage* + ----- Buffer: foo ----- + +SPC + + ----- Buffer: foo ----- + ▽define-abbrev* + ----- Buffer: foo ----- + +SPC + + ----- Buffer: foo ----- + ▽define-abbrev-table* + ----- Buffer: foo ----- + +SPC + + ----- Buffer: foo ----- + ▽define-abbrevs* + ----- Buffer: foo ----- + +SPC + + ----- Buffer: *候補* ----- + A:define-auto-insert + S:define-category + D:define-ccl-codepoint-translation-table + F:define-ccl-constant-translation-table + J:define-ccl-identity-translation-table + K:define-ccl-program + L:define-ccl-slide-translation-table + ----- Buffer: *候補* ----- +#+END_EXAMPLE + +この機能を有効とするには、リスト ~skk-search-prog-list~ の要素に +関数 ~skk-search-lisp-symbol~ を加えてください。 + +#+BEGIN_SRC emacs-lisp +(add-to-list 'skk-search-prog-list + '(skk-search-lisp-symbol) t) +#+END_SRC + +なお、見出し語に *~* を含む辞書もあります。例えば ~SKK-JISYO.JIS3_4~ には + +#+BEGIN_EXAMPLE +A~ /チルド付きA(LATIN CAPITAL LETTER A WITH TILDE)/ +#+END_EXAMPLE + +#+TEXINFO: @noindent +と登録されています。したがって、 + +#+BEGIN_EXAMPLE +▽A~ SPC +#+END_EXAMPLE + +#+TEXINFO: @noindent +と変換したときに「チルド付きA」が表示されるか、Lisp シンボル名が補完され +るかは、リスト ~skk-search-prog-list~ 内の要素の順によります。 + +- Function: skk-search-lisp-symbol &optional PREDICATE NOT-ABBREV-ONLY WITHOUT-CHAR-MAYBE + + オプション ~PREDICATE~ で補完検索する範囲(関数名、変数名、コマンド名) + を限定することができます。詳細は docstring を参照してください。 + +- Variable: skk-completion-search-char + + ~skk-completion-search~ による変換機能を指示するキーキャラクタ。 + 標準設定は *~* です。 + +*** Google CGI API for Japanese Input を利用したかな漢字変換 + +#+CINDEX: Google CGI API for Japanese Input + +かな漢字変換に [[http://www.google.co.jp/ime/cgiapi.html][Google CGI API for Japanese Input]] を利用することができます。 +連文節変換も可能となります。 + +まず、 ~~/.skk~ にて、変数 ~skk-use-search-web~ を ~non-nil~ に設定します。 +これにより、skk-mode を起動した際に ~skk-search-web.el~ を require するよ +うになります。 + +同じく ~~/.skk~ にて、リスト ~skk-search-prog-list~ の一番最後の要素とし +て、関数 ~skk-search-web~ を追加します。 + +#+BEGIN_SRC emacs-lisp +(add-to-list 'skk-search-prog-list + '(skk-search-web 'skk-google-cgi-api-for-japanese-input) + t) +#+END_SRC + +以上の設定によって、通常のかな漢字変換の *候補が尽きたとき* に関数 ~skk-search-web~ が +実行され、Google CGI API for Japanese Input による変換結果が表示されます。 + +そのほか、変数 ~skk-read-from-minibuffer-function~ を以下のように設定する +ことで、辞書登録モードへの突入時の初期値に Google サジェストを表示するこ +ともできます。 + +#+BEGIN_SRC emacs-lisp +(setq skk-read-from-minibuffer-function + (lambda () + (car (skk-google-suggest skk-henkan-key)))) +#+END_SRC + +** 飾りつけ + +*** 仮名文字のローマ字プレフィックスのエコー + +- Variable: skk-echo + + この変数の値は、仮名文字のローマ字プレフィックスのエコーの有無を制御し + ます。 + + [[送りありエントリと送りなしエントリ][送りありエントリと送りなしエントリ]]. + +変数 ~skk-echo~ の値が ~non-nil~ であれば、仮名文字のローマ字プレフィック +スが、入力時点でいったん現在のバッファに挿入され、続く母音の入力の際に、 +かな文字に変換された時点で現在のバッファから消去されます。 + +#+BEGIN_EXAMPLE +t + + ------ Buffer: foo ------ + t* + ------ Buffer: foo ------ + +a + + ------ Buffer: foo ------ + た* + ------ Buffer: foo ------ +#+END_EXAMPLE + +変数 ~skk-echo~ の値が ~nil~ であれば、仮名文字のローマ字プレフィックスの +エコーは行われません。これを上記の例で考えると、 ~t~ が現在のバッファに挿 +入されず、続く母音 ~a~ が入力された瞬間に「た」の文字が挿入されます。 + +- Variable: skk-prefix-hiragana-face + + かなモードにおけるローマ字プレフィックスのフェイスを指定します。 + + +- Variable: skk-prefix-katakana-face + + カナモードにおけるローマ字プレフィックスのフェイスを指定します。 + +- Variable: skk-prefix-jisx0201-face + + JIS X 0201 モードにおけるローマ字プレフィックスのフェイスを指定します。 + +*** 入力モードを示すモードラインの文字列の変更 + +下記の変数の値を変更することによって、モードライン上の「入力モードを示す文字 +列」を変更することができます。skk-show-mode の表示も連動します。 + +- Variable: skk-latin-mode-string + + アスキーモードを示す文字列。標準は *SKK* 。 + +- Variable: skk-hiragana-mode-string + + かなモードを示す文字列。標準は *かな* 。 + +- Variable: skk-katakana-mode-string + + カナモードを示す文字列。標準は *カナ* 。 + +- Variable: skk-jisx0208-latin-mode-string + + 全英モードを示す文字列。標準は *全英* 。 + +- Variable: skk-abbrev-mode-string + + SKK abbrev モードを示す文字列。標準は *aあ* 。 + +*** 入力モードを示すカーソル色に関する設定 + +- User Option: skk-use-color-cursor + + この変数が ~non-nil~ ならば、カーソルを色付けします。標準では、ウィンド + ウシステムを使用して、かつ、色表示が可能な場合に限って、この機能が有効 + になります。 + +この機能が有効になっているとき、以下の変数の値を変更することで、各モード +におけるカーソルの色を変更できます。 + +- Variable: skk-cursor-default-color + + SKK モードがオフであることを示すカーソル色。標準では、カーソルのある該 + 当フレームにおける標準のカーソル色を使います。 + +- Variable: skk-cursor-hiragana-color + + かなモードであることを示すカーソル色。標準は、背景の明暗により coral4 ま + たは pink です。 + +- Variable: skk-cursor-katakana-color + + カナモードであることを示すカーソル色。標準は、背景の明暗により forestgreen ま + たは green です。 + +- Variable: skk-cursor-jisx0201-color + + JIS X 0201 モードであることを示すカーソル色。標準は、背景の明暗により blueviolet ま + たは thistle です。 + +- Variable: skk-cursor-jisx0208-latin-color + + 全英モードであることを示すカーソル色。標準は、gold です。 + +- Variable: skk-cursor-latin-color + + アスキーモードであることを示すカーソル色。標準は、背景の明暗により ivory4 ま + たは gray です。 + +- Variable: skk-cursor-abbrev-color + + SKK abbrev モードであることを示すカーソル色。標準は、royalblue です。 + +*** 変換候補一覧の表示方法 + +変換候補一覧の表示方法は、次の4つに大別されます。 + +- 現在のウィンドウにインライン表示する + +- ツールティップで表示する + +- 現在のウィンドウの隣に別なウィンドウを開いて表示する(ポップアップ) + +- エコーエリアに表示する + +**** 現在のウィンドウにインライン表示する +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +*XEmacs ではインライン表示はサポートされません。* + +- Variable: skk-show-inline + + この変数の値が ~non-nil~ であれば、候補一覧を現在のポイント位置でインラ + イン表示します。値がシンボル ~vertical~ であれば、各候補を縦方向にイン + ライン表示します。 + +- Variable: skk-inline-show-face + + インライン表示する変換候補を装飾するフェイスを指定します。標準設定 + は ~underline~ です。 + + #+BEGIN_SRC emacs-lisp + (setq skk-inline-show-face 'font-lock-doc-face) + #+END_SRC + + ~skk-treat-candidate-appearance-function~ による装飾を優先するには ~nil~ に + 設定して下さい。 + +- Variable: skk-inline-show-background-color + + インライン表示する変換候補の背景色を指定します。 + + ~skk-inline-show-face~ または ~skk-treat-candidate-appearance-function~ に + て、背景色が指定されていない文字に対してのみ作用します。 + +- Variable: skk-inline-show-background-color-odd + + インライン表示する変換候補の背景色(奇数ライン)を指定します。 + +**** ツールティップで表示する +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +- Variable: skk-show-tooltip + + この変数の値が ~non-nil~ であれば、候補一覧をツールティップで表示します。 + 同時に、「注釈(アノテーション)の表示方法」と「文字コードの表示方法」 + も制御します。 + + + [[注釈(アノテーション)][注釈(アノテーション)]]. + + + [[文字コードまたはメニューによる文字入力][文字コードまたはメニューによる文字入力]]. + +- Variable: skk-tooltip-face + + ツールティップ表示する文字列に適用するフェイスのシンボルを指定する変数 + です。 + + #+BEGIN_SRC emacs-lisp + (setq skk-tooltip-face 'font-lock-doc-face) + ;; (make-face 'skk-tooltip-face) ではないことに注意 + #+END_SRC + + 候補文字列のフェイス属性( ~skk-treat-candidate-appearance-function~ に + よる加工など)をそのまま使いたい場合は ~nil~ に設定して下さい。 + +- Variable: skk-tooltip-mouse-behavior + + ツールティップを表示する位置及びマウスポインタの挙動を指定します。下記 + に掲げるシンボル以外のシンボルを指定した場合は ~nil~ となります。 + + + シンボル ~follow~ + + マウスポインタをカーソル位置へ移動させてツールティップを表示します。 + ツールティップの表示を終えるとマウスポインタは元の位置へ戻ります。た + だし、元のマウスポインタが Emacs フレーム外であったならばツールティッ + プの表示を終えてもマウスポインタはカーソル位置のままです。 + + + シンボル ~banish~ + + マウスポインタを Emacs フレーム右上隅へ移動させてツールティップを表示 + します。ツールティップの表示を終えもてマウスポインタは Emacs フレーム + 右上隅のままです。 + + + シンボル ~avoid~ + + マウスポインタを Emacs フレーム右上隅へ移動させてツールティップを表示 + します。ツールティップの表示を終えるとマウスポインタは元の位置へ戻り + ます。ただし、元のマウスポインタが Emacs フレーム外であったならばツー + ルティップの表示を終えてもマウスポインタは Emacs フレーム右上隅のまま + です。 + + + シンボル ~avoid-maybe~ + + マウスポインタが Emacs フレーム内であれば ~avoid~ と同じ動作です。マ + ウスポインタが Emacs フレーム外であればマウスポインタ位置を変更せず、 + その位置にツールティップを表示します。 + + + ~nil~ + + マウスポインタを一切移動せず、その位置にツールティップを表示します。 + ツールティップのテキストとマウスポインタが重なったり、うまくツールテ + ィップが表示できなかったりする場合があります。 + +- Variable: skk-tooltip-hide-delay + + ツールティップを表示する秒数。標準設定は 1,000秒。この時間が経過する + と、ツールティップは自動的に消える。 + +- Variable: skk-tooltip-parameters + + 標準設定は ~nil~ 。SKK 独自のフレームパラメータを設定する。 ~nil~ の + 場合、 ~tooltip-frame-parameters~ が適用される。 + +**** 現在のウィンドウの隣に別なウィンドウを開いて表示する(ポップアップ) +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +- Variable: skk-show-candidates-always-pop-to-buffer + + この値が ~non-nil~ であれば、画面を上下に分割したうえで、候補一覧を専用 + の *候補*バッファで表示します。 + +候補一覧表示中に、この値を動的に切り換える手段が用意されています。 + +#+KINDEX: C-f +- Variable: skk-show-candidates-toggle-display-place-char + + 候補一覧表示中に、候補一覧の表示位置をエコーエリアとバッファとで動的に + 切り換えることができます。標準設定は ~C-f~ です。 + +- Variable: skk-candidate-buffer-background-color + + *候補*バッファの背景色を指定します。背景色を付けたくない場合は ~nil~ を + 指定すること(標準設定)。 + +- Variable: skk-candidate-buffer-background-color-odd + + *候補*バッファの背景色(奇数ライン)を指定します。 + +- Variable: skk-candidate-buffer-delete-other-windows + + ~nil~ であれば、*候補*バッファ表示に際して window 配置を変更しない。 + window 配置を popwin や shackle にまかせている場合は ~nil~ とすべき。 + + + [[https://github.com/m2ym/popwin-el][Popup Window Manager for Emacs]] + + + [[https://github.com/wasamasa/shackle][Enforce rules for popup windows]] + +**** エコーエリアに表示する +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +標準設定では3つの変数 + +- ~skk-show-inline~ +- ~skk-show-tooltip~ +- ~skk-show-candidates-always-pop-to-buffer~ + +#+TEXINFO: @noindent +とも ~nil~ であり、この状態では候補一覧はエコーエリアに表示 [fn:fw] しま +す。もしも、これら変数のうち2つ以上が ~non-nil~ の場合、優先順位は上記の +解説の順です。 + +[fn:fw] ただし、 ~frame-width~ が不足する場合は、*候補*バッファに表示しま +す。 + +*** ▼モードにおける変換候補のハイライト表示 + +#+CINDEX: canna.el +#+CINDEX: rgb.txt +#+CINDEX: Overlays +#+CINDEX: Extents +#+CINDEX: Text Properties + +- Variable: skk-use-face + + この変数の値が ~non-nil~ であれば、Emacs のフェイス機能を使って変換候補 + をハイライト表示します。このハイライト表示には GNU Emacs のオーバーレイ (overlay) の + 機能を使います [fn:overlay] 。 + +- Variable: skk-henkan-face + + この変数の値はフェイスであり、このフェイスによって変換候補がハイライト + 表示されます。標準では、背景の明暗により black/darkseagreen2 又は + white/darkolivegreen を用います。 + + なお、この変数よりも ~skk-treat-candidate-appearance-function~ の設定が + 優先されます。 + +変数 ~skk-henkan-face~ には、既存のフェイス [fn:face] を指定できますが、 +新たにフェイスを作ることもできます。そのために次の関数が用意されています。 + +- Function: skk-make-face FACE + + この関数は、引数 ~FACE~ と同じ名前のフェイスを作成して、そのフェイスを + 返します。フェイスの前景色・背景色は、引数 ~FACE~ にスラッシュ ~/~ を含 + めることよって、例えば以下の例のように決定されます。 + + #+BEGIN_SRC emacs-lisp + (setq skk-henkan-face (skk-make-face 'DimGray/PeachPuff1)) + #+END_SRC + + この場合、前景色は DimGray に、背景色は PeachPuff1 になります。もうひと + つ例を挙げます。 + + #+BEGIN_SRC emacs-lisp + (setq skk-henkan-face (skk-make-face 'RosyBrown1)) + #+END_SRC + + この場合、前景色は RosyBrown1 になります。背景色が無指定の場合はバッフ + ァの背景色がそのまま見えます。 + +[fn:overlay] 以前のバージョンではテキスト属性 (text property) を使用して +いました。オーバーレイ属性はテキスト属性と異なり、テキストの一部とは見な +されません。そのため、テキストのコピーの際にオーバーレイ属性は保持されま +せん。その他にも、オーバーレイの移動やその属性の変更はバッファの変更とは +見なされないこと、オーバーレイの変更はバッファのアンドゥリストに記録され +ないこと、などが特徴として挙げられます。なお、XEmacs にはオーバーレイ機能 +はありません。代わりに extent というものが用意されているのでそれを利用し +ます。 + +[fn:face] Emacs 標準 では ~default~, ~modeline~, ~region~, ~secondary-selection~, +~highlight~, ~underline~, ~bold~, ~italic~, ~bold-italic~ があります。 + +*** 変換候補の更なる装飾 + +変換候補についてユーザの任意の加工を施すための変数を用意してあります。 + +- Variable: skk-treat-candidate-appearance-function + + この変数に適切な形式で関数を収めることによって、変換候補をユーザの任意 + に加工することができます。「適切な形式」とは、次のとおりです。 + + + 引数を2つ取ること。 + + + 第1引数は文字列として扱うこと。これは加工前の文字列に相当する。 + + + 第2引数が ~nil~ の時は通常の変換時、 ~non-nil~ の時は候補一覧表示時 + を表すものとして扱うこと。 + + + 返り値は次のいずれかとすること。 + + * 文字列 + + この場合、この文字列は候補と注釈を両方含みうるものとして処理される。 + + * ~(候補 . 注釈)~ + + この場合、候補はもう注釈を含まないものとして処理される。注釈について + は先頭が ~;~ かどうかを調べた上で処理される。 + + * ~(候補 . (セパレータ . 注釈))~ + + この場合、候補はもう注釈を含まないものとして処理される。セパレータ + は通常の ~;~ の代わりに利用される。注釈はもうセパレータを含まないも + のとして処理される。 + +ファイル ~etc/dot.skk~ に設定例があるほか、サンプルとして関数 +~skk-treat-candidate-sample1~ と ~skk-treat-candidate-sample2~ を用意して +あります。ファイル ~~/.skk~ に次のいずれかを書いてみて変換候補の装飾を試 +してください。 + +#+BEGIN_SRC emacs-lisp +(setq skk-treat-candidate-appearance-function + 'skk-treat-candidate-sample1) +#+END_SRC + +#+BEGIN_SRC emacs-lisp +(setq skk-treat-candidate-appearance-function + 'skk-treat-candidate-sample2) +#+END_SRC + +*** モードラインの装飾 + +XEmacs 及び GNU Emacs 21 以降では、以下の機能が使用できます。 + +**** インジケータ +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +- Variable: skk-indicator-use-cursor-color + + DDSKK のインジケータをモードラインの左 [fn:indi] に表示している場合、 + インジケータの色がカーソルの色と同期します。インジケータに色を付けたく + ない場合は、この変数を ~nil~ にします。 + +[[入力モードを示すカーソル色に関する設定][入力モードを示すカーソル色に関する設定]]. + +インジケータに独自色を使いたい場合は、以下のフェイス [fn:face2] を設定し +ます。この場合カーソルの色は参照されません。 + +#+VINDEX: skk-emacs-hiragana-face +#+VINDEX: skk-emacs-katakana-face +#+VINDEX: skk-emacs-jisx0208-latin-face +#+VINDEX: skk-emacs-jisx0201-face +#+VINDEX: skk-emacs-abbrev-face +- GNU Emacs 21 以上(変数 ~mule-version~ の値が 5.0 以上の GNU Emacs)の場合 + + + ~skk-emacs-hiragana-face~ + + ~skk-emacs-katakana-face~ + + ~skk-emacs-jisx0208-latin-face~ + + ~skk-emacs-jisx0201-face~ + + ~skk-emacs-abbrev-face~ + +#+VINDEX: skk-xemacs-hiragana-face +#+VINDEX: skk-xemacs-katakana-face +#+VINDEX: skk-xemacs-jisx0208-latin-face +#+VINDEX: skk-xemacs-latin-face +#+VINDEX: skk-xemacs-jisx0201-face +#+VINDEX: skk-xemacs-abbrev-face +- XEmacs の場合 + + + ~skk-xemacs-hiragana-face~ + + ~skk-xemacs-katakana-face~ + + ~skk-xemacs-jisx0208-latin-face~ + + ~skk-xemacs-latin-face~ + + ~skk-xemacs-jisx0201-face~ + + ~skk-xemacs-abbrev-face~ + +なお、インジケータを右クリックするとポップアップメニューが表示されます。 + +[fn:indi] 標準設定では左です。 + +[[起動と終了][起動と終了]]. + +[fn:face2] 変数 ~window-system~ が ~nil~ の場合は、これらフェイスは未定義となります。 + +**** アイコン +:PROPERTIES: +:TEXINFO-NODE: t +:END: + +- Variable: skk-show-icon + + 変数 ~skk-show-icon~ の値を ~non-nil~ と設定することにより、モードライ + ンに SKK のアイコンが表示されます。なお、アイコン表示は ~(image-type-available-p 'xpm)~ が ~t~ を + 返す必要があるため、Emacs の種類/実行環境に依存します。 + +- Variable: skk-icon + + アイコンの画像ファイル ~skk.xpm~ へのパス。関数 ~skk-emacs-prepare-modeline-properties~ で + 定義しています。 + +** ユーザガイダンス関連 + +*** エラーなどの日本語表示 + +標準では、エラー、メッセージ及びミニバッファでのプロンプトは、英語で表示 +されます。 + +- Variable: skk-japanese-message-and-error + + この変数の値を ~non-nil~ に設定すると、エラー、メッセージ及びミニバッフ + ァでのプロンプトを日本語で表示します。標準では ~nil~ です。 + +- Variable: skk-show-japanese-menu + + この変数の値を ~non-nil~ に設定すると、メニューバーを日本語で表示します。 + +- Variable: skk-version-codename-ja + + この変数の値を ~non-nil~ に設定すると、関数 ~skk-version~ を評価したと + きのコードネームを日本語で表示します。 + +*** 冗長な案内メッセージの表示 + +- Variable: skk-verbose + + この変数の値を ~non-nil~ に設定すると、入力中/変換中に冗長なメッセージ + を表示します。 + + #+BEGIN_SRC emacs-lisp + (setq skk-verbose t) + #+END_SRC + +#+VINDEX: skk-j-mode-function-key-usage +- ▽モード + + ファンクションキー (~F1~ 〜 ~F10~) に割り当てられている機能を表示します。 + 変数 ~skk-verbose~ の設定と同時に変数 ~skk-j-mode-function-key-usage~ を + 以下のように設定してみてください。 + + #+BEGIN_SRC emacs-lisp + (setq skk-j-mode-function-key-usage 'conversion) + #+END_SRC + + ▽モードにおいてキー入力が一定時間(標準では 1.5 秒)なされなかったとき、 + エコーエリアに以下のようなメッセージが表示されます。 + + #+BEGIN_EXAMPLE + -------------------- Echo Area -------------------- + [F5]単漢字 [F6]無変換 [F7]カタカナ [F8]半角カナ [F9]全角ローマ [F10]ローマ + -------------------- Echo Area -------------------- + #+END_EXAMPLE + + この案内に従ってファンクションキーを押すことで、一時的に単漢字変換やカ + タカナ変換を行うことができます。 + +#+VINDEX: skk-show-annotation +#+CINDEX: kill ring +#+VINDEX: interprogram-cut-function +- ▼モード + + Wikipedia アノテーション機能の使い方をメッセージで案内します。変数 ~skk-verbose~ の + 設定と同時に変数 ~skk-show-annotation~ を ~non-nil~ に設定してみてください。 + + #+BEGIN_SRC emacs-lisp + (setq skk-show-annotation t) + #+END_SRC + + ▼モードにおいてキー入力が一定時間 (標準では 1.5 秒) なされなかったとき、 + エコーエリアに以下のようなメッセージが表示されます。 + + #+BEGIN_EXAMPLE + -------------------- Echo Area -------------------- + どれを参照?[C-1 C-i]ja.wikipedia [C-2 C-i]en.wiktionary + [C-3 C-i]simple.wikipedia [C-4 C-i]en.wikipedia [C-5 C-i]ja.wiktionary + -------------------- Echo Area -------------------- + #+END_EXAMPLE + + この案内に従って、例えば ~C-1 C-i~ を打鍵すると、日本語 Wikipedia の該 + 当記事を調べて、あればその一部をアノテーションとして表示します。 + + 一方、現在の変換候補に対するアノテーションが既に表示されているときは、 + 以下のメッセージが上記のものと交互に表示されます。 + + #+BEGIN_EXAMPLE + -------------------- Echo Area -------------------- + {アノテーション}[C-w]コピー [C-o]URLブラウズ [C-i]標準設定のソースを参照 + -------------------- Echo Area -------------------- + #+END_EXAMPLE + + この案内に従って ~C-w~ を打鍵すれば、アノテーションの全文を kill ring に + 保存して利用することができます [fn:killring2] 。また、キー ~C-o~ を押した場合には、もし + 現在のアノテーションが Wikipedia アノテーションであればその出典となる + Wikipedia/Wiktionary のページをウェブブラウザで表示します。 + +- Variable: skk-verbose-wait + + 冗長なメッセージを表示するまでの待ち時間(秒)。標準は 1.5 秒です。 + +- Variable: skk-verbose-message-interval + + 冗長なメッセージが複数ある場合の1メッセージあたり表示時間を秒で指定す + る。標準は 5.0 秒です。この時間が経過したら表示を次の冗長なメッセージ + に切り替えます。 + +- Variable: skk-verbose-intention-face + + 「どれを参照?」と「アノテーション」に適用するフェイスです。 + +- Variable: skk-verbose-kbd-face + + ~[F5]~ や ~[C-1 C-i]~ に適用するフェイスです。 + +[fn:killring2] kill ring については info を参照。 + +[[info:emacs#Kill Ring][The Kill Ring in GNU Emacs Manual]]. + +保存した内容を Emacs 以外のアプリケーションで利用したい場合は変数 ~interprogram-cut-function~ を +設定してください。 + +** I-search 関連 + +*** 起動時の入力モードの指定 + +- Variable: skk-isearch-start-mode + + インクリメンタル・サーチを起動したときの入力モードをこの変数で指定でき + ます。以下のいずれかのシンボルを指定できますが、変数 ~skk-isearch-use-previous-mode~ の + 設定が優先されます。 + + + ~nil~ + + カレントバッファで SKK モードが起動されていれば、そのモードを。起動さ + れていなければアスキーモード。 + + + シンボル ~hiragana~ + + かなモード + + + シンボル ~jisx0208-latin~ + + 全英モード + + + シンボル ~latin~ + + アスキーモード + +- Variable: skk-isearch-use-previous-mode + + この変数の値が ~non-nil~ であれば、次のインクリメンタル・サーチ起動時の + 入力モードは、前回のインクリメンタル・サーチでの入力モードになります。 + ~nil~ であれば、変数 ~skk-isearch-start-mode~ の設定が優先されます。 + +*** 間に空白等を含む文字列の検索 + +「検索」という文字列をインクリメンタル・サーチにより検索する場合に、バッ +ファが以下のような状態になっていることがあります。 + +#+BEGIN_EXAMPLE +-------- Buffer: foo -------- +この行末から始まる文字列を検 +索して下さい。 +-------- Buffer: foo -------- +#+END_EXAMPLE + +このような場合のために、Emacs は正規表現によるインクリメンタル・サーチを +提供しています。DDSKK はこの正規表現によるインクリメンタル・サーチにも対 +応しているため、空白や改行を含んだ検索も可能です。 + +#+KINDEX: C-u C-s +#+KINDEX: M-C-s +- Key: M-x isearch-forward-regexp, isearch-forward-regexp + + 前方への正規表現によるインクリメンタル・サーチ。 ~C-u C-s~ または ~M-C-s~ で + 起動します。 + +#+KINDEX: C-u C-r +#+KINDEX: M-C-r +- Key: M-x isearch-backward-regexp, isearch-backward-regexp + + 後方への正規表現によるインクリメンタル・サーチ。 ~C-u C-r~ または ~M-C-r~ で + 起動します。 + +- Variable: skk-isearch-whitespace-regexp + + この変数の値は正規表現です。この正規表現にマッチする要素は「正規表現に + よるインクリメンタル・サーチにおいては、単語を区切る要素ではない」と判 + 断されます。この変数の標準設定は以下のようになっています。 + + #+BEGIN_EXAMPLE + "\\(\\s \\|[ \t\n\r\f]\\)*" + #+END_EXAMPLE + + この変数の値を変更することで、正規表現によるインクリメンタル・サーチを + 拡張することができます。例えば、電子メールの引用部分を検索する場合を考 + えます。 + + #+BEGIN_EXAMPLE + > 引用部分も検 + > 索できる。 + #+END_EXAMPLE + + 上記のうち、「検索」という語は 2 行に渡っている上、引用マークが挿入され + ています。ここで + + #+BEGIN_SRC emacs-lisp + (setq skk-isearch-whitespace-regexp "\\(\\s \\|[ \t\n\r\f<>|]\\)*") + #+END_SRC + +#+TEXINFO: @noindent +と設定することにより、「検索」を検索できるようになります。 + +** VIP/VIPERとの併用 + +VIPER については Info を参照してください。 + +[[info:viper#Top][VIPER Manual]]. + +また、VIPER の前身である VIP にも対応します。ただし、正式に対応しているバ +ージョンは 3.5 のみです。これは Mule 2.3 に標準添付します [fn:viper] 。 + +# XXX VIP 3.7 について言及する。 +- Variable: skk-use-viper + + この変数の値を ~non-nil~ に設定すると、VIPER に対応します。 + +[fn:viper] ちなみに、VIP 3.5 の作者は、SKK の原作者でもある佐藤雅彦氏(京 +都大学名誉教授)です。VIP 3.5 の発展版である VIPER は現在もメンテナンスさ +れています。GNU Emacs 19, 20 には、VIP 、VIPER とも標準添付します。 + +** picture-modeとの併用 + +#+CINDEX: BS +#+CINDEX: move-to-column +#+CINDEX: move-to-column-force +#+CINDEX: picture.el +#+CINDEX: picture-mode + +SKK モードを ~picture-mode~ において使用した場合は、以下のような問題点が +あります。ただし、これらは ~picture-mode~ の問題なので、現在のところ DDSKK 側 +では対処していません。 + +- SKK モードで全角文字を入力した場合に、 ~BS~ で全角文字を消すことができ + ません。現状では、後方にある文字を消したい場合は、その文字にポイントを + 合わせ、 ~C-c C-d~ で一文字ずつ消す必要があります。 + +- コマンド ~picture-movement-up~ や ~picture-movement-down~ により上下に + 全角文字を挿入した場合に、桁がずれる場合があります。 + +関数 ~move-to-column-force~ の中で使用されている関数 ~move-to-column~ の +引数として、全角文字を無視した桁数が与えられることがあり、そのときカーソ +ル移動ができないため、これらの問題が生じます。 + +* ローマ字入力以外の入力方式 + +DDSKK は、SKK 旧来のローマ字式かな入力(訓令式、ヘボン式)方式のほか、各 +種キー配列と入力方式に対応しています。 + +** AZIK + +#+CINDEX: AZIK + +AZIK (エイズィック)は QWERTY 配列をベースとした拡張ローマ字入力です。 +一般のローマ字入力がそのまま使える上での拡張であることが特徴です。 + +[[http://hp.vector.co.jp/authors/VA002116/azik/azikindx.htm][拡張ローマ字入力『AZIK』・『ACT』で快適な日本語入力を!]] + +- Variable: skk-use-azik + + この値が ~non-nil~ であれば AZIK 拡張が有効となります。 ~~/.skk~ に + + #+BEGIN_SRC emacs-lisp + (setq skk-use-azik t) + #+END_SRC + + と書きます。 + +- Variable: skk-azik-keyboard-type + + AZIK で使うときのキーボードのタイプを、シンボルで指定する。 + + + シンボル ~jp106~ → 日本語 106 キーボード(標準設定) + + + シンボル ~jp-pc98~ → NEC PC-98 キーボード + + + シンボル ~us101~ → 英語キーボード + + + ~nil~ → キーボード依存処理を無効にする + +azik と skk で仕様が重なる部分があるため、 ~skk-azik.el~ では以下のとおり +対応しています。 + +- キー ~q~ + + AZIK では撥音「ん」を入力するには ~q~ を使うこととされていますが、skk で + は既に ~q~ に ~skk-toggle-kana~ を割り当てています。そのため ~skk-azik.el~ で + は ~skk-toggle-kana~ の実行を + + + 日本語キーボードであれば ~@~ を、 + + + 英語キーボードであれば ~[~ を + + それぞれ使用します。 + +- キー ~@~ + + 上記のとおり、 ~skk-toggle-kana~ の実行には ~@~ (日本語キーボード) + や ~[~ (英語キーボード)を使用しますが、skk では既に ~@~ には「今日の + 日付の入力」(プログラム実行変換)を割り当てています。そのため、skk 本 + 来の動作には ~x~ を付けて、それぞれ ~x@~ と ~x[~ で代用できるようにして + あります。 + +- キー ~l~ +- キー ~xx~ + + AZIK では単独の拗音「ゃゅょぁぃぅぇぉゎ」を入力するには ~l~ を前置する + こととされていますが、skk では既に ~l~ に「アスキーモードへの切り替え」 + を割り当てています。そのため ~skk-azik.el~ では、拗音のうち「ぁぃぅぇぉ」 + の入力については ~xx~ を前置することとしています。 + + + ~xxa~ → ぁ + + + ~xxi~ → ぃ + + + ~xxu~ → ぅ + + + ~xxe~ → ぇ + + + ~xxo~ → ぉ + + なお、拗音のうち「ゃゅょゎ」の単独入力は、AZIK 拡張 ~skk-azik.el~ では + なく、標準 ~skk-vars.el~ です。 + + + ~xya~ → ゃ + + + ~xyu~ → ゅ + + + ~xyo~ → ょ + + + ~xwa~ → ゎ + +- キー ~X~ + + skk では、▼モードでの ~X~ は 関数 ~skk-purge-from-jisyo~ を実行します + が、AZIK では ~X~ は「シャ行」の入力に使われます。そのため、 ~skk-azik.el~ で + の「誤った登録の削除」は、▼モードで ~M-x skk-purge-from-jisyo~ を実行してください。 + + [[誤った登録の削除][誤った登録の削除]]. + +** ACT + +ACT は AZIK の考え方を Dvorak 配列に適用し、Dvorak 配列でかなを快適にタイ +プできるように考案された方式です。 + +[[http://www1.vecceed.ne.jp/~bemu/act/act_index.html][ACT (AZIK on Dvorak)]] + +- Variable: skk-use-act + + この値が ~non-nil~ であれば ACT 拡張が有効となります。 ~~/.skk~ に + + #+BEGIN_SRC emacs-lisp + (setq skk-use-act t) + #+END_SRC + + と書きます。 + +** TUT-code + +TUT-code は、2ストローク系の日本語直接入力方式の一つです。 + +[[http://plone.crew.sfc.keio.ac.jp/groups/tut-code][TUT-code]] + +使用するには、SKK のインストール時にいくつかのファイルをインストールする +必要があります。SKK ソースの ~tut-code~ ディレクトリにある ~skk-tutcdef.el~ と ~skk-tutcode.el~ を +SKK ソースのトップディレクトリにコピーしてから、あらためて SKK をインスト +ールします。 + +[[DDSKK のインストール][DDSKK のインストール]]. + +その後、 ~~/.skk~ に + +#+BEGIN_SRC emacs-lisp +(require 'skk-tutcdef) +#+END_SRC + +#+TEXINFO: @noindent +と書きます。 + +** かな入力と親指シフト + +#+CINDEX: かな入力 +#+CINDEX: 親指シフト +#+CINDEX: NICOLA + +DDSKK はローマ字式ではない、いわゆるかな入力方式をサポートします。具体的 +には + +- 旧 JIS 配列でのかな入力 +- 親指シフト方式でのかな入力 + +#+TEXINFO: @noindent +に対応しています。これを使うにはまず、nicola-ddskk 拡張パッケージをインス +トールする必要があります。SKK ソースの ~nicola~ ディレクトリに移動し、ド +キュメントに従ってインストールしてください。 + +https://github.com/skk-dev/ddskk/blob/master/nicola/README.ja + +- Variable: skk-use-kana-keyboard + + この変数を ~non-nil~ に設定すると、かな入力サポートが SKK 起動時に有効 + になります。 + + #+BEGIN_SRC emacs-lisp + (setq skk-use-kana-keyboard t) + #+END_SRC + +- Variable: skk-kanagaki-keyboard-type + + この変数で、かな入力サポートの種類を切換えます。適切なシンボルを設定し + てください。 + + + シンボル ~106-jis~ + + 日本語 106 キーボード (旧 JIS 配列) でのかな入力に対応します。 + + #+BEGIN_SRC emacs-lisp + (setq skk-kanagaki-keyboard-type '106-jis) + #+END_SRC + + + シンボル ~nicola-jis~ + + 日本語 106 キーボード (旧 JIS 配列) での親指シフトエミュレーションに + 対応します。 + + #+BEGIN_SRC emacs-lisp + (setq skk-kanagaki-keyboard-type 'nicola-jis) + #+END_SRC + + + シンボル ~nicola-us~ + + + シンボル ~nicola-dvorak~ + + + シンボル ~nicola-colemak~ + + + シンボル ~omelet-jis~ + + ~nicola-jis~ と同様ですが、より入力しやすい配列が考慮されています。 + + #+BEGIN_SRC emacs-lisp + (setq skk-kanagaki-keyboard-type 'omelet-jis) + #+END_SRC + + + シンボル ~omelet-us~ + + + シンボル ~omelet-dvorak~ + + + シンボル ~omelet-colemak~ + + + シンボル ~oasys~ + +かな入力方式使用時の■モードでは、以下のコマンドなどが役に立ちます。 + +- Key: F1 1, skk-nicola-help? + + かな入力方式での特殊キー定義の一覧を表示します。 + +- Key: F1 2, skk-nicola-2nd-help? + + かな入力方式でのかなキー配列を表示します。 + +- Key: F12, skk-kanagaki-toggle-rom-kana + + かな入力方式とローマ字入力方式とを切り換えます。 + +なお、親指シフト方式については次の url が参考になります。 + +[[http://nicola.sunicom.co.jp/][NICOLA 日本語入力コンソーシアム]] + +* そのほかの拡張機能 + +十分にテストされていない等の理由がありますが、便利・有益と思われる拡張機 +能を紹介します。 + +** 交ぜ書き変換 + +~skk-mazegaki.el~ をインストールすると、交ぜ書き変換が可能となります。 + +- き車 → 汽車 +- き者 → 記者 +- き社 → 貴社 + +インストール方法などは、次の投稿を参考にしてください。 + +http://mail.ring.gr.jp/skk/201111/msg00037.html + +* SKK に関する情報 + +** 最新情報 + +DDSKK についての最新情報は http://openlab.jp/skk/ から得ることができます。 + +SKK の開発は、 GitHub を利用して行われています。 + +- https://github.com/skk-dev/ddskk + +最新版 DDSKK の変更内容と更に過去の変更点については以下のリソースを参照 +してください。 + +- https://github.com/skk-dev/ddskk/blob/master/READMEs/NEWS.ja + +また、将来のバージョンにおける拡張アイディアについては、TODO としてまと +められています。 + +- https://github.com/skk-dev/ddskk/blob/master/READMEs/TODO.ja + +SKK Openlab では、開発者、文章の整備にご協力いただける方、テスター、よろ +ずものを言う人などなど、常に募集しています。また要望、拡張の具体的アイデ +ィアがあれば、メーリングリストに連絡いただけることを期待します。 + +** SKKメーリングリスト + +SKK Openlab メーリングリストは、統一された一つの ML です。利用者用、開発 +者用などと分かれていない他、SKK 辞書、DDSKK の開発議論が中心ですが、辞書 +サーバやフロントエンド、 SKK 辞書ツールの話題なども議論の範囲に入ります。 + +- メーリングリストに参加する + + アドレス ~skk-subscribe@ring.gr.jp~ 宛てに空のメールを送って下さい。確 + 認の為のメッセージが指定されたアドレス宛に送信されます。その確認の為の + メッセージに対して返信することで加入手続きは終了します。 + +- メーリングリストから脱会する + + アドレス ~skk-unsubscribe@ring.gr.jp~ 宛てに空のメールを送って下さい。 + 確認の為のメッセージが指定されたアドレス宛に送信されます。その確認の為 + のメッセージに対して返信することで脱退手続きは終了します。 + +- 登録したアドレスを変更する + + 古いアドレスについていったん unsubscribe して、新しいアドレスから再度 + subscribe して下さい。 + +- 記事の投稿 + + アドレス ~skk@ring.gr.jp~ へ送ります。メーリングリストに登録されている + 人全員にメールが配信されます。 + +- 過去ログの閲覧 + + + http://mail.ring.gr.jp/skk + +** SKK 関連ソフトウェア + +SKK 関連ソフトウェアに関しては、次の URL にリンクをまとめてありますの +で参照してください。 + +- [[http://openlab.jp/skk/wiki/wiki.cgi?page=%A5%EA%A5%F3%A5%AF%BD%B8][SKK 辞書 Wiki におけるリンク集]] + +** SKK 辞書について + +SKK 辞書は多くのユーザの方々から提供された辞書によりコピーフリーの辞書と +しては最大規模の辞書になっています。今後もこの方式により SKK 辞書をより +充実したものにしていきたいと思います。 + +http://openlab.jp/skk/registdic.cgi にて Web/cgi を利用した登録・削除希望 +フォームを運用しています。SKK 辞書に追加したい単語、誤登録として削除した +い単語がありましたら、是非ご利用下さい。 + +** 辞書ツール + +SKK 辞書に関するツールには、Perl, C, Ruby の各言語により書かれたツールが +ありますが、Perl によるツールは現在十分メンテナンスされていません。 +現在は C, Ruby のツールが開発・メンテナンスされています。 + +- [[http://openlab.jp/skk/wiki/wiki.cgi?page=%BC%AD%BD%F1%A5%E1%A5%F3%A5%C6%A5%CA%A5%F3%A5%B9%A5%C4%A1%BC%A5%EB][辞書メンテナンスツール]] + +** SKK の作者 + +SKK の原作者は、現京都大学名誉教授の佐藤雅彦氏です。 + +- http://www.ist.i.kyoto-u.ac.jp/organization/ex-professor.html#Sato + +現在の DDSKK は、大勢のボランティアの貢献により成立しています。 +ファイル ~READMEs/Contributors~ に貢献者名の一覧がありますので、ご覧ください。 + +** SKKの歴史 + +SKK の成り立ちと歴史に関しては以下の URL を参照してください。 + +- [[http://openlab.jp/skk/born-ja.html][SKK の誕生秘話]] + +- [[http://openlab.jp/skk/SKK.html][@@texinfo:@math{@@SKK = I@@texinfo:}@@]] + +- [[http://openlab.jp/skk/history-ja.html][SKK の歴史(付 Emacs の歴史の一部)]] + +- [[http://mail.ring.gr.jp/skk/201212/msg00007.html][SKK の 25年]] + +** このマニュアルについて + +本マニュアルは、SKK オープンラボの有志の貢献により、従来のマニュアルに加 +筆修正したものです。 + +** 謝辞 + +DDSKK の開発は、[[http://openlab.jp][Ring Server Open Laboratory]] (オープンラボラトリ)に SKK Openlab と +して参加する形で行われています。SKK Openlab は Ring から共有ディスク、CVS 及 +び ML の提供を受けています。オープンラボラトリの運営は、完全にボランティ +アにより行われております。Ring 並びにオープンラボラトリにかかわる皆さんに +深く感謝いたします。 + +以降の記載は、SKK の原作者、佐藤雅彦教授により記載された旧来のマニュア +ルのものですが、歴史的意義を踏まえて、そのまま掲載します。 + +#+BEGIN_QUOTE +SKK の設計方針は TAO/ELIS 上の日本語入力システム Kanzen の影響を受けてい +ます。Kanzen のデモを行ってくださり、また Kanzen を使う機会を与えてくだ +さった NTT の竹内郁雄さんに感謝します。 + +第 1 版の辞書作成のための読みの入力を行ってくださった東北大学電気通信研 +究所佐藤研究室の 安藤大君、猪岡美紀さん、奥川淳一君、佐々木昭彦君、佐藤 +克志君、山岸信寛君に感謝します。 + +SKK 辞書第 2, 3, 4, 5, 6, 7, 8 版作成のためのデータを提供してくださっ +た方々に感謝します。 + +SKK 辞書第 6, 7 版作成にあたり協力してくださった高橋裕信氏に感謝します。 +#+END_QUOTE + +* よくある質問とその回答 (FAQ) + +これは SKK に対するよくある質問と、それに対する回答集です。 + +** Introduction + +*** Q1-1 Daredevil SKK って SKK とは違うのですか? + +SKK Openlab で開発、リリースされる SKK は、京大の佐藤先生が中心になって開 +発していた SKK と区別するために、 ~Daredevil SKK~ と呼ぶことにしました。 +その略称は ~DDSKK~ で、SKK Openlab で最初に ~Daredevil SKK~ としてリリー +スされた version は 11.1 です(オリジナルの version を継承しました)。 + +なお、 ~Daredevil~ の名前の採択は、開発陣の一人が講読している某ラジオ英会 +話講座の、ある日のスキット名が「Daredevil なんとか」で、その内容は「とに +かくやってみよう。うぎゃぁぁぁ、やられたぁ」というものでした。これがあま +りに自分の開発ポリシーに合致していた、ということに由来します。 + +*** Q1-2 SKK はシンプルなのが長所だったのでは? + +かような議論は 10 年来行われてきており、結論は出ていませんが、事実として +現在まで開発が続けられています。「シンプルな操作性の維持と多機能化・高機 +能化は両立できる」というのが現在の開発陣の考えであるようです。 + +SKK が Simple Kana to Kanji conversion program の略であるとおり、かなを漢 +字に変換するルーチンの簡単さが SKK を定義付けています。その周辺の拡張に関 +する制約は基本的にはありません。 + +多機能化と言っても多くはユーザオプションによって無効にすることができます +し、 ~skk.el~ 本体が複雑化しないようにモジュール化されています。 + +*** Q1-3 DDSKK はどの Emacs で使えますか? + +基本的には、GNU Emacs と Mule 機能付きの XEmacs で使えます。対応する Emacs の +バージョンについては以下をご覧ください。 + +[[このバージョンの SKK について][このバージョンの SKK について]]. + +*** Q1-4 DDSKK はどんなオペレーティングシステムで使えますか? + +SKK がサポートしている Emacs がその OS で動いているなら、SKK の基本的な機 +能は動くはずです。 Microsoft Windows でも Apple macOS でも使えます。 + +拡張機能については、UNIX の各種コマンドを前提としているものがいくつかあり +ます( ~look~ や ~ispell~ など)。これらのコマンドがお使いの OS にも存在 +すれば該当の拡張機能も基本的には使えるでしょう。 + +Apple macOS 版 Emacs に特化した情報については、以下のファイルを参照してください。 + +- https://github.com/skk-dev/ddskk/blob/master/READMEs/README.MacOSX.ja + +*** Q1-5 APEL って何? 必要ですか? + +APEL は A Portable Emacs Library の略です。APEL の主な機能は、異なる Emacs 間 +の非互換性を吸収することです。 + +- XEmacs では APEL が必要です。 + +- GNU Emacs 22 以上では APEL は不要となりました。この変更は 2010 年 9 月 + に CVS に commit され、2011 年 1 月に DDSKK 14.2 としてリリースされました。 + +** Installation + +*** Q2-1 SKK を使うのに何が必要ですか? + +SKK 本体と SKK 辞書が必要です。オプションで辞書サーバを用意することができ +ます。XEmacs では事前に APEL をインストールしてください。 + +[[XEmacs へのインストール][XEmacs へのインストール]]. + +*** Q2-2 SKK 辞書はどこにありますか? + +[[SKK 辞書について][SKK 辞書について]]. + +*** Q2-3 SKK サーバはどこにありますか? + +DDSKK は辞書サーバの種類、バージョンには依存していません。 +http://openlab.jp/skk/skkserv-ja.html からお好きな辞書サーバを入手して下さい。 + +** Customization + +*** Q3-1 「.」、「,」 が入力できるようにカスタマイズしたいのですが。 + +3通りの方法を紹介します。 + +- 通常 ~.~ で「.」を、 ~,~ で「,」を入力したい場合 + + ~~/.skk~ に以下を設定します。 + + #+BEGIN_SRC emacs-lisp + (setq skk-kutouten-type 'en) + #+END_SRC + +- 一時的に ~.~ で「.」を、 ~,~ で「,」を入力したい場合 + + ~M-x skk-toggle-kutouten~ を実行すると、その場で「,」「.」に切り替え + ることができます。「、」「。」に戻すには、もう一度 ~M-x skk-toggle-kutouten~ を + 実行します。 + + 特定のバッファでのみ「,」「.」に切り替えたい場合は Info を参照下さい。 + + [[info:emacs#File Variables][Local Variables in Files in GNU Emacs Manual]]. + + 例えば、 tex モードでのみ「,」「.」に切り替えたい場合は、次の設定 + を tex 文書ファイルの最後に追加します。 + + #+BEGIN_EXAMPLE + % Local Variables: + % skk-kutouten-type: en + % end: + #+END_EXAMPLE + +- 常に ~.~ で「.」を、 ~,~ で「,」を入力したい場合 + + ~skk-rom-kana-rule-list~ を直接変更します。なお、この設定をすると、 ~M-x skk-toggle-kutouten~ で + の切り替えが効かなくなるので、注意して下さい。 ~~/.skk~ に以下を追加します。 + + #+BEGIN_SRC emacs-lisp + (setq skk-rom-kana-rule-list + (append '(("." nil ".") ("," nil ",")) + skk-rom-kana-rule-list)) + #+END_SRC + + この設定方法は応用が効き、細かく制御することが可能です。「.」と「,」 + のところをそれぞれ ~.~ と ~,~ とすることで、「かなモード」「カナモード」 + でも ~.~ と ~,~ を直接入力することができます。 + +*** Q3-2 「ゐ」や「ヰ」 が入力できるようにカスタマイズしたいのですが。 + +一つ前の Q の変形問題ですね。かなモード/カナモードでそれぞれ出力する文字 +を変えるやり方です。 ~~/.skk~ に + +#+BEGIN_SRC emacs-lisp +(setq skk-rom-kana-rule-list + (append '(("wi" nil ("ヰ" . "ゐ"))) + skk-rom-kana-rule-list)) +#+END_SRC + +#+TEXINFO: @noindent +と書いてみましょう。一番内側の cons cell は car がカナモード、cdr がかな +モードでの入力文字を表しています。 + +一つ前の Q に対する答えのように、カナモード、かなモードともに入力する文字 +が変わらなければ、cons cell の代りに文字列を書くことができます。 + +*** Q3-3 検索する辞書を増やしたいのですが。 + +#+VINDEX: skk-search-prog-list +~skk-search-prog-list~ で設定をしましょう。 + +まず、現在の設定を確認しましょうね。*scratch*バッファに ~skk-search-prog-list~ と +書いてそのシンボルの末尾にポイントを置いて ~C-j~ してみましょう。例えば次 +のように出力されます。 + +#+BEGIN_SRC emacs-lisp +((skk-search-jisyo-file skk-jisyo 0 t) + (skk-search-server skk-aux-large-jisyo 10000)) +#+END_SRC + +上記の例は2つの要素を持ったリストになっています。設定によりもっと多くの +要素があるかもしれません。 + +各要素は検索する関数と辞書を指定したリストです。要素の順番に検索がなされ +ます。上記の例だとまず最初に ~skk-jisyo~ (個人辞書)を ~skk-search-jisyo~ と +いう関数を使ってリニアサーチし、次に ~skk-search-server~ という関数を +使って ~skk-aux-large-jisyo~ をサーチします。 + +変換の際、 ~SPC~ を押しますよね? 1回 ~SPC~ を押すと、SKK は候補が見つ +かるまでの間、 ~skk-search-prog-list~ の要素を前から読んでいって検索を行 +い、見つかればそこでいったん検索を止めてユーザに候補を提示します。 + +ユーザが ~SPC~ を更に押してゆき最初の要素のプログラムが見つけた候補が尽き +ると、SKK は中断していた個所から再び ~skk-search-prog-list~ の次の要素を +見つけ、ここで指定されている関数を使って検索する、で新しい候補が見つかれ +ばまた提示する、というシステムになっています。 + +では、辞書サーバを使って検索した後に、JIS 第2水準の単漢字辞書 ~SKK-JISYO.JIS2~ を +検索したい場合はどうすれば良いでしょう? もう分かりますよね? 辞書サーバ +を使った検索式の次に第2水準辞書の検索式を書いたリストを ~skk-search-prog-list~ に +指定すれば良いのです。 ~~/.skk~ に次のように書きましょう。 + +#+BEGIN_SRC emacs-lisp +(setq skk-search-prog-list + '((skk-search-jisyo-file skk-jisyo 0 t) + (skk-search-server skk-aux-large-jisyo 10000) + (skk-search-jisyo-file "~/dic/SKK-JISYO.JIS2" 0))) +#+END_SRC + +~skk-search-jisyo-file~ の第2引数である 0 の数字でリニアサーチにて検索 +するよう指定しています。第2水準辞書はあまり大きくないので、リニアサーチ +で十分でしょう。大きな辞書を検索する場合などは、 + +#+BEGIN_SRC emacs-lisp +(skk-search-jisyo-file "~/dic/SKK-JISYO.L" 10000) +#+END_SRC + +#+TEXINFO: @noindent +のようにすると良いでしょう。SKK は Emacs のバッファに読み込まれた辞書の検 +索リージョンのポイント差が 10,000 未満になるまではバイナリサーチを行い、 +その後リニアサーチを行います。大きな辞書ではバイナリサーチを行う方がはる +かに効率が良いです。 + +ちなみに、 ~SKK-JISYO.JIS2~ は、最大でもリージョン間のポイント差が 8,500 程 +度です。 + +*** Q3-4 左手の小指を SHIFT で酷使したくありません。 + +SKK を標準の状態で使っている場合、変換のためにシフトキーを多用しますので +小指への負担が大きくなります。この苦しみを回避するためにここでは4つの方 +法を紹介します。 + +#+VINDEX: key-translation-map +- 親指の近くにあるキーを利用してシフトキーの代用とする。 + + 日本語 106 キーボードのように「無変換」、「変換」などのキーがある場合は、 + これらをシフトキーの代用とすることが可能です。こうすると、例えば + + #+BEGIN_EXAMPLE + SHIFT を押しながら a を押す + #+END_EXAMPLE + + というキー操作は + + #+BEGIN_EXAMPLE + 「無変換」を押して、その後で a を押す + #+END_EXAMPLE + + という操作で置き換えることができるようになります。 + + それでは具体的なやり方を説明しましょう。まず、使用中の Emacs が「無変換 + キー」を何という名前で認識しているか調べます。それには + + #+BEGIN_EXAMPLE + M-x describe-key + #+END_EXAMPLE + + というコマンドを実行し、続いて「無変換キー」を押してみます。X Window System 上 + であれば、おそらく + + #+BEGIN_EXAMPLE + muhenkan is undefined + #+END_EXAMPLE + + という答えが返ってくるでしょう。次に、この名前を使って ~~/.emacs.d/init.el~ + に設定を書きこみます。以下は「無変換キー」 = ~muhenkan~ の場合の例です。 + + #+BEGIN_SRC emacs-lisp + (unless (keymapp key-translation-map) + (setq key-translation-map (make-sparse-keymap))) + (let ((i ?a)) + (while (<= i ?z) + (define-key key-translation-map + (vector 'muhenkan i) (vector (- i 32))) + (setq i (1+ i)))) + #+END_SRC + + この設定を終えると、 ~muhenkan-a~ で ~A~ が入力できるようになります。 + 続いて SKK を起動してみましょう。 ~muhenkan-a~ で + + #+BEGIN_EXAMPLE + ▽あ* + #+END_EXAMPLE + + となります。送りの開始点も、もちろん同様の操作で指定できます。 + +#+CINDEX: xmodmap +- xmodmap を使う。 + + X Window System 上では、 ~xmodmap~ というプログラムを使ってキー配列を変 + 更できます。例えば、「無変換キー」をシフトキーとして使いたければ + + #+BEGIN_EXAMPLE + % xmodmap -e 'add Shift = Muhenkan' + #+END_EXAMPLE + + とします。これで「無変換キー」は通常のシフトキーと同じような感じで使えるよ + うになります。 + +- ~skk-sticky.el~ を使う。 + + [[変換位置の指定方法][変換位置の指定方法]]. + +#+CINDEX: 親指シフト入力 +#+CINDEX: OASYS +#+CINDEX: NICOLA +#+CINDEX: 日本語入力コンソーシアム +- 親指シフト入力のエミュレーション機能を利用する。 + + これは前述した方法とはかなり違ったアプローチです。SKK 本来のローマ字的 + 入力を捨てて、富士通のワープロ OASYS のような親指シフト入力 [fn:nicola] を + 修得します 。 + + DDSKK には NICOLA-DDSKK というプログラムが付属しており、これをインストー + ルすると親指シフト入力が可能になります。インストール自体は簡単で、 + + #+BEGIN_SRC shell-script + % cd nicola + % make install + #+END_SRC + + とした後に、 ~~/.skk~ に + + #+BEGIN_SRC emacs-lisp + (setq skk-use-kana-keyboard t) + (setq skk-kanagaki-keyboard-type 'omelet-jis) + #+END_SRC + + と書くだけです。詳しいことは、NICOLA-DDSKK 付属のドキュメントを参照して + ください。 + + NICOLA 配列は、特別に日本語入力のために考えられた配列なので、慣れれば非 + 常に効率的な日本語入力ができるようになると期待されます。一方で、ローマ + 字的入力方式に慣れてしまっている人にとっては、NICOLA 配列に慣れるまでか + なり練習を要することは確かです。 + +[fn:nicola] 親指シフト入力の詳細については、ここでは述べません。興味がある +場合は、Web サイトを訪れてください。 + +[[http://nicola.sunicom.co.jp/][日本語入力コンソーシアム]] + +*** Q3-5 全く漢字が出てきません。 + +恐らく辞書の設定ができていないのでしょう。 + +~SKK-JISYO.L~ というファイルがインストールされている場所を確認してくださ +い。普通は + +#+BEGIN_EXAMPLE +/usr/local/share/skk +/usr/share/skk +#+END_EXAMPLE + +#+TEXINFO: @noindent +といった場所にインストールされています。XEmacs のパッケージならば + +#+BEGIN_EXAMPLE +/usr/local/lib/xemacs/mule-packages/etc/skk +#+END_EXAMPLE + +#+TEXINFO: @noindent +などを確認します。その後で ~~/.skk~ に + +#+BEGIN_SRC emacs-lisp +(setq skk-large-jisyo "/usr/local/share/skk/SKK-JISYO.L") +#+END_SRC + +#+TEXINFO: @noindent +のように設定します。 + +なお、辞書サーバを使っている場合はこの設定は必要ありません。その場合は、 +辞書サーバの設定や、それがちゃんと起動しているかどうかを確認してくださ +い。 + +また、どこにも辞書がインストールされていない場合は http://openlab.jp/skk/dic/ か +ら取得します。 + +*** Q3-6 チュートリアルが起動できません。 + +~SKK.tut~ というファイルがインストールされている場所を確認してください。 +普通は + +#+BEGIN_EXAMPLE +/usr/local/share/skk +/usr/share/skk +#+END_EXAMPLE + +#+TEXINFO: @noindent +といった場所にインストールされています。XEmacs のパッケージならば + +#+BEGIN_EXAMPLE +/usr/local/lib/xemacs/mule-packages/etc/skk +#+END_EXAMPLE + +#+TEXINFO: @noindent +などを確認します。その後で ~~/.emacs.d/init.el~ に + +#+BEGIN_SRC emacs-lisp +(setq skk-tut-file "/usr/local/share/skk/SKK.tut") +#+END_SRC + +#+TEXINFO: @noindent +のように設定します。 + +*** Q3-7 C-x C-j で dired が起動してしまいます。 + +~dired-x~ を読み込むと ~C-x C-j~ が ~dired-jump~ にバインドされます。この +状態でも SKK を ~C-x C-j~ で起動したいときは、変数 ~dired-bind-jump~ に ~nil~ を +設定します。 + +#+BEGIN_SRC emacs-lisp +(setq dired-bind-jump nil) +#+END_SRC + +なお、この設定は ~dired-x~ を読み込む前である必要があります。 + +** Dictionaries + +*** Q4-1 SKK には郵便番号辞書がありますか? + +CVS から辞書を取得した場合は、 ~zipcode~ というディレクトリに入って +います。WWW では、 http://openlab.jp/skk/dic/ より入手できます。使用方法 +は http://openlab.jp/skk/skk/dic/zipcode/README.ja を御覧下さい。 + +*** Q4-2 SKK の辞書には、品詞情報がないんですね。 + +SKK は漢字とかなとの区切りをユーザが指定する方式により、品詞情報を使った +解析を用いることなく効率的入力ができます。 + +TODO としては、辞書に品詞情報を持たせることで更なる入力の効率化ができると +いう提案がなされており、そのような辞書の作成が既に試みられています。興味 +のある方は次の url をご覧ください。 + +- [[http://openlab.jp/skk/wiki/wiki.cgi?page=SKK%BC%AD%BD%F1][SKK-JISYO.notes]] + +*** Q4-3 複数の SKK 辞書を結合できますか? + +SKK 本体のパッケージには同封されていませんが、 ~skk-tools~ という別パッケー +ジがあります。 + +[[辞書ツール][辞書ツール]]. + +*** Q4-4 SKK 形式の英和辞書があると聞いたのですが。 + +edict は和英辞書ですが、これを SKK 辞書形式の英和辞書に変換したものを + +http://openlab.jp/skk/dic/SKK-JISYO.edict + +#+TEXINFO: @noindent +として置いています。これは edict を単純に機械的に変換した後、バグの修正 +や、エントリ・候補の追加が SKK Openlab で独自に行われているものです。 + +edict を自分で加工して上記と同等のものを作成することもできます。edict は + +ftp://ftp.u-aizu.ac.jp:/pub/SciEng/nihongo/ftp.cc.monash.edu.au/ + +#+TEXINFO: @noindent +などから入手できます。加工には日本語の通る ~gawk~ と ~skk-tools~ の中のプ +ログラムを使い、下記のように行います。 + +#+BEGIN_SRC shell-script +% jgawk -f edict2skk.awk edict > temp +% skkdic-expr temp | skkdic-sort > SKK-JISYO.E2J +% rm temp +#+END_SRC + +できた ~SKK-JISYO.E2J~ の利用方法は色々ありますが、 + +#+BEGIN_SRC shell-script +% skkdic-expr SKK-JISYO.E2J + /usr/local/share/skk/SKK-JISYO.L | \ + skkdic-sort > SKK-JISYO.L +#+END_SRC + +#+TEXINFO: @noindent +などとして、 ~SKK-JISYO.L~ とマージして使うのが手軽です。 + +なお、edict の配布条件は GNU GPL (General Public License) ではありません。 + +http://www.csse.monash.edu.au/groups/edrdg/newlic.html + +#+TEXINFO: @noindent +をご覧下さい。 ~SKK-JISYO.edict~ のヘッダー部分にもそのダイジェスト +が記載されています。 + +** Miscellaneous + +*** Q5-1 SKK abbrev モードでもっと英単語を利用した変換ができませんか? + +UNIX ~look~ コマンドと ~skk-look.el~ を利用すると、色々できますよ。 +まず、 ~~/.skk~ で ~skk-use-look~ を ~t~ にセットして Emacs/SKK を立ち上 +げ直して下さい。 + +さぁ、下記のような芸当が可能になりました。 + +- 英単語の補完ができます。 + + #+BEGIN_EXAMPLE + ▽abstr* + + TAB + + ▽abstract* + #+END_EXAMPLE + + 通常の補完機能と同様に ~.~ で次の補完候補に、 ~,~ でひとつ前の補完候補 + に移動できます。SKK 形式の英和辞書があれば、ここから ~SPC~ を押して英和 + 変換ができますね。また、 ~skk-look-use-ispell~ の値が ~non-nil~ であれ + ば、 ~look~ で検索する前に ~ispell~ でスペルチェック・修正をします。 + +- 英単語をあいまいに変換して取り出す + + 上記同様、 ~skk-look-use-ispell~ の値が ~non-nil~ であれば、 ~look~ で + 検索する前に ~ispell~ でスペルチェック・修正をします。 + + #+BEGIN_EXAMPLE + ▽abstr* + + SPC + + ▼abstract* + #+END_EXAMPLE + + 見出し語に ~*~ を入れるのをお忘れなく。 + +- あいまいに変換した後、更に再帰的な英和変換を行う + + まず、 ~skk-look-recursive-search~ の値を ~non-nil~ にセットして下さい。 + Emacs / SKK を再起動する必要はありません。すると、例えば、 + + #+BEGIN_EXAMPLE + ▽abstr* + + SPC + + ▼abstract + + SPC + + ▼アブストラクト + + SPC + + ▼抽象 + + SPC + + ▼abstraction + + SPC + + ▼アブストラクション + #+END_EXAMPLE + + このように英単語+その英単語を見出し語にした候補の「セット」を変換結果 + として出力することができます。 + + この際、 ~skk-look-expanded-word-only~ の値が ~non-nil~ であれば、再帰 + 検索に成功した英単語の「セット」だけを出力することができます(再帰検索 + で検出されなかった英単語は無視して出力しません)。 + + もちろん、SKK 辞書に + + #+BEGIN_EXAMPLE + abstract /アブストラクト/抽象/ + abstraction /アブストラクション/ + #+END_EXAMPLE + + というエントリがあることを前提としています。edict を SKK 辞書形式に変換 + すると良いですね。 + +なお、 ~skk-look.el~ を使った補完・変換が期待するスピードよりも遅い、補完・変換 +で余分な候補が出る、とお感じの貴方は、 ~skk-look-use-ispell~ の値を ~nil~ に +して ~ispell~ によるスペルチェック・修正をオフにしてお試し下さい。 + +*** Q5-2 市販の CD-ROM 辞書やネットワークの辞書サーバが利用できますか? + +Lookup が扱える辞書はほとんど使えます。Lookup がインストールされている状 +態で SKK をインストールすると、SKK と Lookup のゲートウェイプログラム ~skk-lookup.el~ が +インストールされます。 + +インストールで注意すべきは、 ~make~ で呼び出される Emacs は ~-q -no-site-file~ フ +ラグ付きで呼ばれるので、 ~~/.emacs.d/init.el~ や ~site-start.el~ などは読 +み込まれないことです。標準設定で ~load-path~ の通っているディレクトリに Lookup を +インストールするか、 ~SKK-CFG~ の中で ~VERSION_SPECIFIC_LISPDIR~ などにデ +ィレクトリを明示することで解決できます。 + +さぁ、 ~~/.skk~ で ~skk-search-prog-list~ の要素に ~(skk-lookup-search)~ を +追加しましょう。他の検索エンジンよりも検索は比較的遅いので、最後の方が良 +いと思います。 + +こんな感じです。 +#+BEGIN_SRC emacs-lisp +(setq skk-search-prog-list + '((skk-search-jisyo-file skk-jisyo 0 t) + (skk-search-server skk-aux-large-jisyo 10000) + (skk-lookup-search))) +#+END_SRC + +Lookup については、http://openlab.jp/edict/lookup/ をご参照下さい。 + +*** Q5-3 他の FEP を使用中にも SHIFT を押してしまいます。 + +治すには SKK をやめるしかありません :-) + +Emacs 上以外でも SKK みたいな操作性を実現するソフトウェアがあります。 + +[[SKK 関連ソフトウェア][SKK 関連ソフトウェア]]. + +# CINDEX +* 事項索引 +:PROPERTIES: +:INDEX: cp +:END: + +# VINDEX +* 変数索引 +:PROPERTIES: +:INDEX: vr +:END: + +# FINDEX +* 関数索引 +:PROPERTIES: +:INDEX: fn +:END: + +# KINDEX +* キー索引 +:PROPERTIES: +:INDEX: ky +:END: + +# Local Variables: +# truncate-lines: nil +# End: diff -Nru ddskk-16.2/doc/skk.texi ddskk-16.2+0.20190423/doc/skk.texi --- ddskk-16.2/doc/skk.texi 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/skk.texi 2019-04-23 12:49:58.000000000 +0000 @@ -1,71 +1,28 @@ -\input texinfo @c -*- mode: texinfo; coding: utf-8 -*- -@setfilename skk.info +\input texinfo-ja @c -*- mode: texinfo; coding: utf-8 -*- + +@c ** This file was generated automatically by SKK-MK ** + +@c %**start of header +@setfilename ./skk.info @settitle SKK Manual +@documentencoding UTF-8 @documentlanguage ja -@documentencoding utf-8 -@iftex -@usedvipdfmx -@end iftex @paragraphindent 1 -@c メモ -@c 1 makeinfo でコンパイルすることもできます。一瞬で終わり、リンク切れを含む -@c エラーの検出に便利です。(make info はリンク切れを検出しません) -@c 方法は、このファイルを utf-8 で保存し、makeinfo skk.texi とします。 -@c 生成される info は、make info のそれとは異なります。特に改行は -@c 変になります。 -@c 2 @ref などのコマンドは、改行されると正常に働きません。 @w の中に入れて下さい。 -@c あるいは、3 つ引数を渡すのも良いでしょう。 -@c 3 @footnote は、そのページの一つ目では、texi の改行/非改行がそのまま -@c info の改行/非改行になり、二つ目以降は他の文と同様、自動的に改行されます。 -@c ただし、例外もあるようです。 -@c また、@footnote 以外にも、改行が編集されないケースがあるようです。 -@c -@c Author: Masahiko Sato -@c Yukiyoshi Kameyama -@c NAKAJIMA Mikio -@c IRIE Tetsuya -@c Kitamoto Tsuyoshi -@c Teika Kazura -@c Tsukamoto Tetsuo -@c Tsuyoshi AKIHO -@c SAKAI Kiyotaka -@c Satoshi Harauchi -@c Maintainer: SKK Development Team -@c Keywords: japanese -@c -@set SKK-VERSION 16.2 -@set UPDATED Date: 2017/03/04 - -@dircategory Emacs -@dircategory GNU Emacs Lisp -@direntry -* SKK: (skk). Simple Kana to Kanji conversion program. -@end direntry - -@c Texinfo に追加できたら良いなぁと思う点を述べます。中島は単なる LaTeX -@c ユーザで、Plain TeX マクロの組み方なんて全然知りませんので、ユー -@c ザーの立場でやりたいことを卒直に、また無責任に述べるに留めます。あし -@c からず。実現できる方法をご存知の方がいらっしゃいましたら、是非教えて -@c 下さい。 -@c -@c (1)日本語の用語についてゴシック体でプリントアウトし、info では "「" -@c と "」" を自動的に付けるような@jdfn{}が欲しい。本書では、日本語 -@c の用語定義をとりあえず`「',`」' で囲み、@b コマンドでゴシック体を -@c 出力するようにしている。 -@c -@c (2)アスキー文字と全角文字を連接して書いたとしても pTeX がその間に適切 -@c に空白を挿入して印刷してくれる。一方 info は連接したままで空白は挿 -@c 入されないので少し見にくい気がする。info ではアスキー文字と全角文 -@c 字との間に半角スペースを挿入してはどうか? -@c -@c (3)LaTeX の表を書くコマンドを実装して欲しい (なら Latexinfo を使えと -@c は言わないでね。互換性が大きく損なわれるから嫌なんです)。 +@c %**end of header @synindex pg cp @footnotestyle end @iftex @afourpaper @end iftex +@tex +\global\def\linkcolor{0 0 1} +\global\def\urlcolor{0 0 1} +@end tex + +@copying +@sp 10 + @ifinfo Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -76,8 +33,8 @@ results, provided the printed document carries a copying permission notice identical to this one except for the removal of this paragraph (this paragraph not being relevant to the printed manual). - @end ignore + Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission @@ -88,24 +45,15 @@ except that this permission notice may be stated in a translation approved by the author. @end ifinfo -@titlepage -@sp 10 -@comment The title is printed in a large font. -@title SKK Manual -@subtitle This edition is for SKK version @value{SKK-VERSION} -@c @subtitle @value{UPDATED-MONTH} -@subtitle @value{UPDATED} -@c The following two commands start the copyright page. -@page -@vskip 0pt plus 1filll -Copyright @copyright{}1991-2007 @w{Masahiko Sato}(佐藤雅彦), @* -@w{Yukiyoshi Kameyama}(亀山幸義), @w{NAKAJIMA Mikio}(中島幹夫), -@w{IRIE Tetsuya}(入江), @w{Kitamoto Tsuyoshi}(北本剛), -@w{Teika Kazura}(定家), @w{Tsukamoto Tetsuo}(塚本徹雄) -and @w{Tsuyoshi AKIHO}(秋保強). Revised by @w{Kiyotaka Sakai}(酒井清隆) -and @w{Satoshi Harauchi}(原内聡). +Copyright @copyright{} 1991-2007 Masahiko Sato(佐藤雅彦), +Yukiyoshi Kameyama(亀山幸義), NAKAJIMA Mikio(中島幹夫), +IRIE Tetsuya(入江), Kitamoto Tsuyoshi(北本剛), +Teika Kazura(定家), Tsukamoto Tetsuo(塚本徹雄) +and Tsuyoshi AKIHO(秋保強). +Revised by Kiyotaka Sakai(酒井清隆) and Satoshi Harauchi(原内聡). +@quotation Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. @@ -119,15 +67,31 @@ into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the author. +@end quotation +@end copying -@end titlepage +@dircategory GNU Emacs Lisp +@dircategory Emacs +@direntry +* SKK: (skk). Simple Kana to Kanji conversion program. +@end direntry + +@finalout +@titlepage +@title SKK Manual +@subtitle This edition is for SKK version 16.2.50 Date 2017.07.07 21:11:51 @page -@ifinfo +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@contents + +@ifnottex @node Top -@top SKK +@top SKK Manual +@end ifnottex -この @cite{SKK マニュアル} は SKK のバージョン @value{SKK-VERSION} に対 -応しています。 @menu * はじめに:: @@ -137,72 +101,253 @@ * 便利な応用機能:: * ローマ字入力以外の入力方式:: * そのほかの拡張機能:: -* SKKに関する情報:: -* よくある質問とその回答(FAQ):: +* SKK に関する情報:: +* よくある質問とその回答 (FAQ):: * 事項索引:: * 変数索引:: * 関数索引:: * キー索引:: @detailmenu - --- 以下は各章の項目です。 --- +--- The Detailed Node Listing --- はじめに -* このバージョンのSKKについて:: -* SKKとはなにか:: +* このバージョンの SKK について:: +* SKK とはなにか:: + + インストール +* APEL のインストール:: * DDSKK のインストール:: * 辞書について:: * 辞書の入手:: * 辞書を DDSKK と同時にインストールする:: * 辞書サーバの入手:: + +DDSKK のインストール + +* GNU Emacs へのインストール:: +* XEmacs へのインストール:: +* 対話的なインストール:: +* MELPA によるインストール:: + はじめの設定 * 最も基本的な設定:: * インクリメント検索の設定:: * 辞書サーバを使いたいときの設定:: +* DDSKK を Emacs の Input Method とする:: + + 基本的な使い方 * 起動と終了:: -* 入力モード:: 文字種別毎のモード -* 変換モード:: 辞書を用いた変換の状態毎のモード +* 入力モード:: +* 変換モード:: * インクリメンタル・サーチ:: * チュートリアル:: -便利な応用機能 -- 予備知識 +起動と終了 -* ファイル構成:: 応用機能を使いこなすための予備知識。 -* ユーザオプションの設定方法:: +* SKK オートフィルモード:: +* 辞書の保存:: + + +入力モード + +* 入力モードの説明:: +* 入力モードを切り替えるキー:: -便利な応用機能 -- 入力関係 -* カタカナ、英字入力の便法:: これと次の項は絶対、便利です。 -* 補完:: 「かしたん」 + Tab -> 「かしたんぽせきにん」 -* 便利な変換、その他の変換:: 単漢字、接頭辞、漢数字、等々。 +変換モード -便利な応用機能 -- 様々な設定 +* ■モード:: +* ▽モード:: +* ▼モード:: +* 辞書登録モード:: -* キー設定:: ローマ字のルールなども変更できます。 -* 変換、確定の前後:: 誤変換の訂正、一発確定、確定のタイミングなど -* 送り仮名関連:: 送り仮名の処理について。 -* 候補の順序:: 関連のある語は上位に表示など、効率を求めて -* 辞書関連:: 辞書にまつわる設定及び機能。 -便利な応用機能 -- 他 +インクリメンタル・サーチ -* 注釈 (アノテーション):: -* 文字コード関連:: 文字コードにまつわる機能。 +* skk-isearchの操作性:: +* skk-isearch と入力モード:: + +便利な応用機能 + +* ファイル構成:: +* ユーザオプションの設定方法:: +* カタカナ、英字入力の便法:: +* 補完:: +* 便利な変換、その他の変換:: +* キー設定:: +* 変換、確定の前後:: +* 送り仮名関連:: +* 候補の順序:: +* 辞書関連:: +* 注釈(アノテーション):: +* 文字コード関連:: * DDSKK 以外のツールを用いた辞書変換:: -* 飾りつけ:: 様々な表示の設定。 +* 飾りつけ:: * ユーザガイダンス関連:: -* I-search関連:: インクリメンタル・サーチにまつわる機能。 +* I-search 関連:: * VIP/VIPERとの併用:: -* picture-modeとの併用:: picture-mode との併用の際の問題点。 +* picture-modeとの併用:: + + +ユーザオプションの設定方法 + +* 設定ファイル:: +* skk-init-file の自動コンパイル:: +* フック:: +* Customize による設定変更:: +* skk-customize による設定変更:: + + +カタカナ、英字入力の便法 + +* かなモードからカタカナを入力:: +* 全英文字の入力:: +* 領域の操作:: +* カタカナの見出し語:: +* 文脈に応じた自動モード切り替え:: + + +補完 + +* 読みの補完:: +* 補完しながら変換:: +* 動的補完:: + + +便利な変換、その他の変換 + +* 単漢字変換:: +* 候補の絞り込み:: +* 接頭辞・接尾辞:: +* 数値変換:: +* アスキー文字を見出し語とした変換:: +* 今日の日付の入力:: +* プログラム実行変換:: +* 空白・改行・タブを含んだ見出し語の変換:: +* カタカナ変換:: +* サ変動詞変換:: +* 異体字へ変換する:: +* ファンクションキーの使い方:: + + +キー設定 + +* かなモード/カナモードのキー設定:: +* 全英モードのキー設定:: +* 閉じ括弧の自動入力:: +* リージョンを括弧で囲む:: +* 確定するキー:: +* 候補の選択に用いるキー:: +* ▼モードでの RET:: +* ▼モードでの BS:: +* 送りあり変換中の C-g:: +* 変換位置の指定方法:: +* 1回の取り消し操作 (undo) の対象:: + + +変換、確定の前後 + +* ポイントを戻して▽モードへ:: +* 直前の確定を再変換:: +* 自動変換開始:: +* 暗黙の確定のタイミング:: +* 積極的な確定:: +* 確定辞書:: + + +送り仮名関連 + +* 送り仮名の厳密なマッチ:: +* 送り仮名の優先的なマッチ:: +* 送り仮名の自動処理:: +* 送りあり変換の変換開始のタイミング:: + + +候補の順序 + +* 変換の学習:: +* 候補の順序の固定:: +* ベイズ統計を用いた学習:: + + +辞書関連 + +* 辞書の種類:: +* 辞書ファイルの指定:: +* 辞書の検索方法の設定:: +* Emacs 付属の辞書:: +* サーバ関連:: +* サーバコンプリージョン:: +* 辞書の書式:: +* 強制的に辞書登録モードへ入る:: +* 誤った登録の削除:: +* 個人辞書ファイルの編集:: +* 個人辞書の保存動作:: +* 変換及び個人辞書に関する統計:: +* 辞書バッファ:: +* 辞書バッファの文字コードの設定:: +* 辞書バッファの buffer-file-name:: + + +注釈(アノテーション) + +* アノテーションの基礎:: +* アノテーションの使用:: +* アノテーションの登録:: +* アノテーションとして EPWING 辞書を表示する:: +* Apple macOS 「辞書」サービスからアノテーションを取得する:: +* Wikipedia/Wiktionary からアノテーションを取得する:: +* 外部コマンドからアノテーションを取得する:: +* 各種アノテーション機能を SKK の枠をこえて活用する:: + + +文字コード関連 + +* 文字コードまたはメニューによる文字入力:: +* メニューによる文字入力:: +* 文字コード一覧:: +* 文字コードを知る方法:: + + +DDSKK 以外のツールを用いた辞書変換 + +* skk-lookup:: +* skk-look:: +* Lisp シンボル名の補完検索変換:: +* Google CGI API for Japanese Input を利用したかな漢字変換:: + + +飾りつけ + +* 仮名文字のローマ字プレフィックスのエコー:: +* 入力モードを示すモードラインの文字列の変更:: +* 入力モードを示すカーソル色に関する設定:: +* 変換候補一覧の表示方法:: +* ▼モードにおける変換候補のハイライト表示:: +* 変換候補の更なる装飾:: +* モードラインの装飾:: + + +ユーザガイダンス関連 + +* エラーなどの日本語表示:: +* 冗長な案内メッセージの表示:: + + +I-search 関連 + +* 起動時の入力モードの指定:: +* 間に空白等を含む文字列の検索:: ローマ字入力以外の入力方式 @@ -211,179 +356,323 @@ * TUT-code:: * かな入力と親指シフト:: -SKKに関する情報 + + +そのほかの拡張機能 + +* 交ぜ書き変換:: + + +SKK に関する情報 * 最新情報:: * SKKメーリングリスト:: -* SKK関連ソフトウェア:: -* SKK辞書について:: +* SKK 関連ソフトウェア:: +* SKK 辞書について:: * 辞書ツール:: -* SKKの作者:: +* SKK の作者:: * SKKの歴史:: * このマニュアルについて:: * 謝辞:: -よくある質問とその回答(FAQ) -* Introduction:: SKK のなぜなに。 -* Installation:: SKK の入手から導入まで。 -* Customization:: SKK の基本設定からお好みのカスタマイズまで。 -* Dictionaries:: SKK 辞書関連。 -* Miscellaneous:: SKK の活用法その他。 +よくある質問とその回答 (FAQ) + +* Introduction:: +* Installation:: +* Customization:: +* Dictionaries:: +* Miscellaneous:: + +Introduction + +* Q1-1 Daredevil SKK って SKK とは違うのですか?:: +* Q1-2 SKK はシンプルなのが長所だったのでは?:: +* Q1-3 DDSKK はどの Emacs で使えますか?:: +* Q1-4 DDSKK はどんなオペレーティングシステムで使えますか?:: +* Q1-5 APEL って何? 必要ですか?:: + + +Installation + +* Q2-1 SKK を使うのに何が必要ですか?:: +* Q2-2 SKK 辞書はどこにありますか?:: +* Q2-3 SKK サーバはどこにありますか?:: + + +Customization + +* Q3-1 「.」、「,」 が入力できるようにカスタマイズしたいのですが。:: +* Q3-2 「ゐ」や「ヰ」 が入力できるようにカスタマイズしたいのですが。:: +* Q3-3 検索する辞書を増やしたいのですが。:: +* Q3-4 左手の小指を SHIFT で酷使したくありません。:: +* Q3-5 全く漢字が出てきません。:: +* Q3-6 チュートリアルが起動できません。:: +* Q3-7 C-x C-j で dired が起動してしまいます。:: + + +Dictionaries + +* Q4-1 SKK には郵便番号辞書がありますか?:: +* Q4-2 SKK の辞書には、品詞情報がないんですね。:: +* Q4-3 複数の SKK 辞書を結合できますか?:: +* Q4-4 SKK 形式の英和辞書があると聞いたのですが。:: + + +Miscellaneous + +* Q5-1 SKK abbrev モードでもっと英単語を利用した変換ができませんか?:: +* Q5-2 市販の CD-ROM 辞書やネットワークの辞書サーバが利用できますか?:: +* Q5-3 他の FEP を使用中にも SHIFT を押してしまいます。:: @end detailmenu @end menu -@end ifinfo @node はじめに @chapter はじめに -@cindex はじめに + @menu -* このバージョンのSKKについて:: -* SKKとはなにか:: +* このバージョンの SKK について:: +* SKK とはなにか:: @end menu -@node このバージョンのSKKについて -@section このバージョンのSKKについて +@node このバージョンの SKK について +@section このバージョンの SKK について -Daredevil SKK (以下、このマニュアルにおいて @samp{DDSKK} と呼びます。)は、 -動作が早くて効率的な日本語入力環境を提供するソフトウェアです。 +Daredevil SKK (以下、このマニュアルにおいて DDSKK と呼びます。)は、動作 +が早くて効率的な日本語入力環境を提供するソフトウェアです。 -GNU General Public License に基づいて配布されているフリー・ソフトウェアです。 -DDSKK @value{SKK-VERSION} が動作すると思われる Emacsen のバージョンは、次のと -おりです。 +GNU General Public License に基づいて配布されているフリー・ソフトウェアで +す。DDSKK 16.2.50 が動作すると思われる Emacsen のバージョンは、次の +とおりです。 -@itemize @bullet -@item GNU Emacs 23.1 以降 (推奨) -@item GNU Emacs 24.1 以降 (推奨) -@item GNU Emacs 25.1 以降 (推奨) -@item Mule 機能付きでコンパイルされた XEmacs 21.4 の最新版 -@item Mule 機能付きでコンパイルされた XEmacs 21.5 の最新版 -@end itemize +@itemize +@item +GNU Emacs 23.1 以降 -XEmacs に関しては、XEmacs 本体とは別に配布されているパッケージ群は最新版が要 -求されます。少なくとも xemacs-base パッケージが最新であることに加えて、fsf-compat パ -ッケージが必須です。 +@item +GNU Emacs 24.1 以降 -総論として、現在は XEmacs よりも GNU Emacs での動作がよくテストされてお -り、最近では XEmacs でのテストは充分行われていません。 -GNU Emacs 23 以上での利用が最も推奨されます。 +@item +GNU Emacs 25.1 以降 + +@item +Mule 機能付きでコンパイルされた XEmacs 21.4 の最新版 + +@item +Mule 機能付きでコンパイルされた XEmacs 21.5 の最新版 +@end itemize + +XEmacs に関しては、XEmacs 本体とは別に配布されているパッケージ群は最新版 +が要求されます。少なくとも @code{xemacs-base} パッケージが最新であることに加え +て @code{fsf-compat} パッケージが必須です。 + +総論として、現在は XEmacs よりも GNU Emacs での動作がよくテストされており、 +最近では XEmacs でのテストは充分行われていません。GNU Emacs 23 以上での利 +用が最も推奨されます。 現時点で Emacs のバージョンごとに少なくとも以下の制限があります。 -@table @b -@item GNU Emacs 20.x +@itemize +@item +GNU Emacs 20.x + +DDSKK 14.2 以降は GNU Emacs 20 はサポート対象外です。GNU Emacs 20 のユ +ーザは DDSKK 14.1 をお使いください。 -DDSKK 14.2 以降は GNU Emacs 20 はサポート対象外です。 -GNU Emacs 20 のユーザは DDSKK 14.1 をお使いください。 -@item GNU Emacs 21.4 +@item +GNU Emacs 21.4 + +DDSKK 15.1 以降は GNU Emacs 21 はサポート対象外です。GNU Emacs 21 のユ +ーザは DDSKK 14.4 をお使いください。 -DDSKK 15.1 以降は GNU Emacs 21 はサポート対象外です。 -GNU Emacs 21 のユーザは DDSKK 14.4 をお使いください。 -@item GNU Emacs 22.3 +@item +GNU Emacs 22.3 + +DDSKK 16.2 以降は GNU Emacs 22 はサポート対象外です。GNU Emacs 22 のユ +ーザは DDSKK 16.1 をお使いください。 -DDSKK 16.2 以降は GNU Emacs 22 はサポート対象外です。 -GNU Emacs 22 のユーザは DDSKK 16.1 をお使いください。 -@item GNU Emacs 23.3 +@item +GNU Emacs 23.3 + +@itemize +@item +X Window System 上でのメニューバーの日本語表示は GTK 対応版のみです。 -@itemize @bullet -@item X Window System 上でのメニューバーの日本語表示は GTK 対応版のみです。 -@item MELPA を利用してインストールするには、先に @file{package.el} をインストールする必要があります。 +@item +MELPA を利用してインストールするには、先に @code{package.el} をインスト +ールする必要があります。 @end itemize -@item GNU Emacs 24.3 -GNU Emacs 24.3 と DDSKK 14 の組み合わせで isearch 使用時の不具合が発見されています。 -GNU Emacs 24.3 のユーザは DDSKK 15 以上をお使いください。 +@item +GNU Emacs 24.3 -@url{http://mail.ring.gr.jp/skk/201211/msg00000.html} +GNU Emacs 24.3 と DDSKK 14 の組み合わせで isearch 使用時の不具合が発見 +されています。GNU Emacs 24.3 のユーザは DDSKK 15 以降をお使いください。 +@itemize +@item +@uref{http://mail.ring.gr.jp/skk/201211/msg00000.html} -@url{http://mail.ring.gr.jp/skk/201212/msg00000.html} +@item +@uref{http://mail.ring.gr.jp/skk/201212/msg00000.html} +@end itemize -辞書のダウンロード機能である @kbd{M-x skk-get} と @command{make get} について、 -tar 展開は非対応です。 -@item GNU Emacs 24.4 +@item +GNU Emacs 24.4 -@itemize @bullet -@item coding tag を明示していないファイルは utf-8 と取り扱われます@footnote{@code{2013-06-11 international/mule-conf.el (file-coding-system-alist)}}。DDSKK 15.2 で対策済みです。 -@item NTEmacs は 24.3 と比べてディレクトリ構成が異なります@footnote{Emacs News: Changes in Emacs 24.4 on Non-Free Operating Systems}。DDSKK 15.2 で対策済みです。 +@itemize +@item +coding tag を明示していないファイルは utf-8 と取り扱われます @footnote{2013-06-11 international/mule-conf.el (file-coding-system-alist)} 。 +DDSKK 15.2 で対策済みです。 + +@item +NTEmacs は 24.3 と比べてディレクトリ構成 が異なります @footnote{Emacs News: Changes in Emacs 24.4 on Non-Free Operating Systems} 。 +DDSKK 15.2 で対策済みです。 @end itemize -@item GNU Emacs 25.1 + +@item +GNU Emacs 25.1 DDSKK 15.2 以降をお使いください(DDSKK 16 を推奨します)。 -@item XEmacs 21.4 -@itemize @bullet -@item @file{skk-kcode.el} の機能を含む JIS X 0213 対応が機能しません。 -@item インライン候補表示は機能しません。 -@item 動的補完における複数候補表示は機能しません。 -@item ツールティップ表示が機能しません。 -@item 日本語メニュー表示は X リソースによる方法のみテストされています。 -@item GNU Emacs 標準添付辞書 ja-dic は利用できません。 -@item skk-search-web は利用できません。 -@end itemize - -@item XEmacs 21.5 (beta) - -@itemize @bullet -@item @file{skk-kcode.el} の機能を含む JIS X 0213 対応が機能しません。 -@item インライン候補表示は機能しません。 -@item 動的補完における複数候補表示は機能しません。 -@item 日本語メニュー表示は X リソースによる方法のみテストされています。 -@item GNU Emacs 標準添付辞書 ja-dic は利用できません。 -@item skk-search-web は利用できません。 +@item +XEmacs 21.4 + +@itemize +@item +@code{skk-kcode.el} の機能を含む JIS X 0213 対応が機能しません。 + +@item +インライン候補表示は機能しません。 + +@item +動的補完における複数候補表示は機能しません。 + +@item +ツールティップ表示が機能しません。 + +@item +日本語メニュー表示は X リソースによる方法のみテストされています。 + +@item +GNU Emacs 標準添付辞書 ja-dic は利用できません。 @end itemize -@end table -@node SKKとはなにか -@section SKKとはなにか +@item +XEmacs 21.5 (beta) + +@itemize +@item +@code{skk-kcode.el} の機能を含む JIS X 0213 対応が機能しません。 + +@item +インライン候補表示は機能しません。 + +@item +動的補完における複数候補表示は機能しません。 + +@item +日本語メニュー表示は X リソースによる方法のみテストされています。 + +@item +GNU Emacs 標準添付辞書 ja-dic は利用できません。 +@end itemize +@end itemize + +@node SKK とはなにか +@section SKK とはなにか SKK は、かな漢字変換プログラムです。 Simple Kana to Kanji conversion program にちなんで名付けられ、その名 -は Combinatory Logic での有名な等式 @samp{SKK = I} にも由来していま -す @footnote{@samp{SKK = I} について詳しくは @url{http://openlab.jp/skk/SKK.html} を -ご参照下さい。}。 - -Daredevil SKK (DDSKK) は、 SKK の更なる拡張版です @footnote{@samp{Daredevil} の名の由来については @ref{Q1-1 Daredevil SKK って SKK とは違うのですか?} を参照して下さい。}。 - -ただし、@samp{SKK モード}、@samp{SKK 辞書}、@samp{SKK サーバ} といった歴 -史的な用語は引き続き使用しており、DDSKK と呼ばない場合もあります。また、 -SKK 方式の入力方法を採用したプログラムなど、広く SKK family を意味する場 -合も同様です。 +は Combinatory Logic での有名な等式 @math{SKK = I} に +も由来 @footnote{@math{SKK = I} について詳しくは @uref{http://openlab.jp/skk/SKK.html} をご参照下さい。} しています。 + +Daredevil SKK は、SKK の更なる拡張版です @footnote{Daredevil の名の由来は @ref{Q1-1 Daredevil SKK って SKK とは違うのですか?}.} 。 + +ただし、SKK モード、SKK 辞書、SKK サーバ といった歴史的な用語は引き続き使 +用しており、DDSKK と呼ばない場合もあります。また、SKK 方式の入力方法を採 +用したプログラムなど、広く SKK family を意味する場合も同様です。 DDSKK の主な特徴は、次のとおりです。 -@itemize @bullet -@item 多彩な入力方式をサポート。ローマ/かな 両対応のかな入力のほか、AZIK、ACT、TUT-code の各方式による入力も可能。 -@item 文法的知識を用いない高速な「かな → 漢字」変換。 -@item シームレスかつ再帰的な単語登録モード。 -@item 確定語を個人辞書へ自動登録することによって、変換候補を効率的に表示する。 -@item マイナーモードとして実装されているので、メジャーモードにほとんど影響を与えない。つまり、Emacs との親和性が高い。 -@item DDSKK 本体 (Emacs Lisp) と辞書ファイルのみで動作可能。つまり、辞書サーバは必須ではなく、辞書サーバがダウンしていても使用できる。 -@item 辞書サーバを使うことで、使用メモリの削減が可能。 -@item ディスク容量に応じて選べる辞書ファイル。 -@item 辞書ファイルの一括ダウンロード機能。 -@item Emacs のオリジナル操作と同様に行える日本語インクリメンタル・サーチ。 -@item Emacs Lisp で書かれたプログラムが返す値を変換候補に挙げることができる。 -@item 入力モードの自動切り替え @file{context-skk.el} -@item 多彩なアノテーション表示 (ユーザ・アノテーション、EPWING 辞書、Apple OS X 辞書、Wikipedia/Wiktionary) -@item 見出し語の動的補完 -@item 総画数変換、部首変換、文字コード入力 +@itemize +@item +多彩な入力方式をサポート。ローマ/かな 両対応のかな入力のほか、AZIK、ACT、 +TUT-code の各方式による入力も可能。 + +@item +文法的知識を用いない高速な「かな→漢字」変換。 + +@item +シームレスかつ再帰的な単語登録モード。 + +@item +確定語を個人辞書へ自動登録することによって、変換候補を効率的に表示する。 + +@item +マイナーモードとして実装されているので、メジャーモードにほとんど影響を +与えない。つまり、Emacs との親和性が高い。 + +@item +DDSKK 本体 (Emacs Lisp) と辞書ファイルのみで動作可能。つまり、辞書サー +バは必須ではなく、辞書サーバがダウンしていても使用できる。 + +@item +辞書サーバを使うことで、使用メモリの削減が可能。 + +@item +ディスク容量に応じて選べる辞書ファイル。 + +@item +辞書ファイルの一括ダウンロード機能。 + +@item +Emacs のオリジナル操作と同様に行える日本語インクリメンタル・サーチ。 + +@item +Emacs Lisp で書かれたプログラムが返す値を変換候補に挙げることができる。 + +@item +入力モードの自動切り替え @code{context-skk.el} + +@item +多彩なアノテーション表示 +@itemize +@item +ユーザ・アノテーション + +@item +EPWING 辞書 + +@item +Apple macOS 辞書 + +@item +Wikipedia/Wiktionary +@end itemize + +@item +「見出し語」の動的補完 + +@item +総画数変換、部首変換、文字コード入力 @end itemize @node インストール @chapter インストール -@cindex インストール + @menu +* APEL のインストール:: * DDSKK のインストール:: * 辞書について:: * 辞書の入手:: @@ -391,32 +680,50 @@ * 辞書サーバの入手:: @end menu +@node APEL のインストール +@section APEL のインストール + +@cindex APEL +DDSKK 14.2 からは、GNU Emacs 22 以上を利用する場合においては APEL を別途 +インストールする必要がなくなりました。APEL に依存している他の elisp プロ +グラムを使用していなければ、インストール済の APEL は削除することが可能で +す。 + +XEmacs をお使いの場合は、 DDSKK をインストールする前に APEL (APEL 10.8 以 +上を推奨)をインストールして下さい。APEL は次のサイトから入手できます。 + +@itemize +@item +@uref{http://git.chise.org/elisp/apel/, APEL} +@end itemize + @node DDSKK のインストール @section DDSKK のインストール -ここでは、UNIX 上で @command{make} コマンドが利用できる環境を想定します -@footnote{Microsoft Windows 環境では、@command{makeit.bat} を使用することで -同様の操作でインストールできます。@url{https://github.com/skk-dev/ddskk/blob/master/READMEs/README.w32.ja.org} +ここでは、UNIX 上で @code{make} コマンドが利用できる環境を想定します @footnote{Microsoft Windows 環境では @code{makeit.bat} を使用することで、UNIX +と同様の操作でインストールできます。 @code{READMEs/README.w32.ja} を参照してく +ださい。 -cygwin 環境をインストールされている方は @command{make} コマンドが使用できる -ので、本文の解説がそのまま当てはまります。 +cygwin 環境をインストールされている方は @code{make} コマンドが使用できるので、 +本文の解説がそのまま当てはまります。 -Apple OS X 環境の方は @url{https://github.com/skk-dev/ddskk/blob/master/READMEs/README.MacOSX.ja} を参照してください。 -}。 +Apple macOS 環境の方は @code{READMEs/README.MacOSX.ja} を参照してください。} 。 -まず、DDSKK のアーカイブ @file{ddskk-VERSION.tar.gz} を @command{tar} コ -マンドと @command{gzip} コマンドを使用して展開します。 +まず、DDSKK のアーカイブ @code{ddskk-VERSION.tar.gz} を @code{tar} コマンドと @code{gzip} コ +マンドを使用して展開します。 @example -% gzip -cd ddskk-@value{SKK-VERSION}.tar.gz | tar xvf - +% gzip -cd ddskk-VERSION.tar.gz | tar xvf - @end example -次に、DDSKK のトップディレクトリ@footnote{@file{ChangeLog} や @file{Makefile} が置かれているディレクトリです。}をカレントディレクトリにします。 +次に、DDSKK のトップディレクトリ @footnote{@code{ChangeLog} や @code{Makefile} が置かれているディレクトリです。} をカレントディレクトリにしま +す。 @example -% cd ddskk-@value{SKK-VERSION} +% cd ddskk-VERSION @end example + @menu * GNU Emacs へのインストール:: * XEmacs へのインストール:: @@ -428,29 +735,27 @@ @subsection GNU Emacs へのインストール まずは、DDSKK がどのディレクトリにインストールされるのか確認するため -に @option{what-where} を引数に @command{make} コマンドを実行しましょう。 +に @code{what-where} を引数に @code{make} コマンドを実行しましょう。 @example -@group % make what-where -@print{}emacs -batch -q -no-site-file -l SKK-MK -f SKK-MK-what-where -@print{}Loading /home/USER/temp/ddskk-@value{SKK-VERSION}/SKK-CFG... +-| emacs -batch -q -no-site-file -l SKK-MK -f SKK-MK-what-where +-| Loading /home/USER/temp/ddskk-VERSION/SKK-CFG... -@print{}Running in: -@print{} GNU Emacs 25.0.50.10 (x86_64-unknown-linux-gnu, GTK+ Version 3.10.9) @dots{} +-| Running in: +-| GNU Emacs 26.0.50 (build1, x86_64-pc-linux-gnu, GTK+ Version ... -@print{}SKK modules: -@print{} skk-cursor, skk-viper, @dots{} -@print{} -> /path/to/emacs/site-lisp/skk - -@print{}SKK infos: -@print{} skk.info -@print{} -> /path/to/share/info - -@print{}SKK tutorials: -@print{} SKK.tut, SKK.tut.E, NICOLA-SKK.tut, skk.xpm -@print{} -> /path/to/share/skk -@end group +-| SKK modules: +-| skk-cursor, skk-viper, ... +-| -> /path/to/emacs/site-lisp/skk + +-| SKK infos: +-| skk.info +-| -> /path/to/share/info + +-| SKK tutorials: +-| SKK.tut, SKK.tut.E, NICOLA-SKK.tut, skk.xpm +-| -> /path/to/share/skk @end example emacs の実体ファイルを特定することもできます。 @@ -459,11 +764,12 @@ $ make what-where EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs @end example -また、DDSKK のインストール先ディレクトリを変更したい場合 -は @file{SKK-CFG} ファイルを編集してください。編集後は必ず @command{make what-where} を -実行して表示内容を確認してください。 +@cindex SKK-CFG +また、DDSKK のインストール先ディレクトリを変更したい場合は @code{SKK-CFG} ファ +イルを編集してください。編集後は必ず @code{make what-where} を実行して表示内容 +を確認してください。 -つぎにスーパーユーザになって、 +次にスーパーユーザになって、 @example $ su @@ -481,7 +787,7 @@ @end example @noindent -と、PREFIX を指定して @command{make} を実行します。 +と、 @code{PREFIX} を指定して @code{make} を実行します。 特定の Emacs を指定する場合は、 @@ -494,51 +800,40 @@ @node XEmacs へのインストール @subsection XEmacs へのインストール -@cindex APEL -XEmacs をお使いの場合は、 DDSKK をインストールする前に APEL (APEL 10.8 以 -上を推奨) をインストールして下さい。APEL は次のサイトから入手できます。 - -@uref{http://git.chise.org/elisp/apel/, APEL} - -XEmacs でパッケージとしてインストールする場合は、 -まず、@option{what-where-package} を引数に @command{make} コマンドを実行 -してパッケージのインストール先を確認しましょう。 +XEmacs でパッケージとしてインストールする場合は、まず @code{what-where-package} を +引数に @code{make} コマンドを実行してパッケージのインストール先を確認しましょう。 @example -@group -% make what-where-package XEMACS=/usr/bin/xemacs -@print{}xemacs -batch -q -no-site-file -l SKK-MK -f SKK-MK-what-where-package - -@print{} Loading /home/user/temp/ddskk-@value{SKK-VERSION}/SKK-CFG... +$ make what-where-package XEMACS=/usr/bin/xemacs +-| /usr/bin/xemacs -batch -q -no-site-file -l SKK-MK \ +-| -f SKK-MK-what-where-package +-| Loading /home/user/temp/ddskk-SKK-VERSION/SKK-CFG... -@print{}Running in: -@print{} XEmacs 21.5 (beta29) garbanzo [Lucid] (i386-redhat-linux, Mule) of @dots{} +-| Running in: +-| XEmacs 21.5 (beta34) "kale" [Lucid] (x86_64-redhat-linux, Mule) of ... -@print{}SKK modules: -@print{} skk-cursor, skk-viper, @dots{} -@print{} -> /usr/share/xemacs/site-packages/lisp/skk +-| SKK modules: +-| skk-cursor, skk-viper, ... +-| -> /usr/share/xemacs/site-packages/lisp/skk -@print{}SKK infos: -@print{} skk.info -@print{} -> /usr/share/xemacs/site-packages/info +-| SKK infos: +-| skk.info +-| -> /usr/share/xemacs/site-packages/info -@print{}SKK tutorials: -@print{} SKK.tut, SKK.tut.E, NICOLA-SKK.tut, skk.xpm -@print{} -> /usr/share/xemacs/site-packages/etc/skk -@end group +-| SKK tutorials: +-| SKK.tut, SKK.tut.E, NICOLA-SKK.tut, skk.xpm +-| -> /usr/share/xemacs/site-packages/etc/skk @end example -つぎに、スーパーユーザになって @option{install-package} を引数 -に @command{make} を実行すると、実際にインストールされます。 +次に、スーパーユーザになって @code{install-package} を引数に @code{make} を実行す +ると、実際にインストールされます。 @example -@group +$ su % make install-package XEMACS=/usr/bin/xemacs -@print{}xemacs -batch -q -no-site-file -l SKK-MK -f SKK-MK-install-package -@print{} Loading /home/user/temp/ddskk-@value{SKK-VERSION}/SKK-CFG@dots{} -@dots{} -@end group +-| xemacs -batch -q -no-site-file -l SKK-MK -f SKK-MK-install-package +-| Loading /home/user/temp/ddskk-VERSION/SKK-CFG ... @end example @node 対話的なインストール @@ -546,33 +841,29 @@ DDSKK 14.3 では「対話的インストーラ」が追加されました。 -まず、@kbd{M-x dired} とタイプして dired を起動してください。このとき、デ +@cindex dired +まず @code{M-x dired} とキー入力して @code{dired} を起動してください。このとき、デ ィレクトリを問われますので、先に述べた「DDSKK のアーカイブを展開したディ レクトリ」を指定してください。 @example -@group ------ Minibuffer ------- -Dired (directory): ~/temp/ddskk-@value{SKK-VERSION} @key{RET} +Dired (directory): ~/temp/ddskk-VERSION RET ------ Minibuffer ------- -@end group @end example -次に、表示されたディレクトリ一覧の @file{SKK-MK} にカーソルをあわせ -て @kbd{L} (@key{SHIFT} を押しながらアルファベットのエル)をタイプしてく -ださい。 +次に、表示されたディレクトリ一覧の @code{SKK-MK} にカーソルをあわせて @code{L} (ア +ルファベットのエルの大文字)を打鍵してください。 @example -@group ------ Dired ------- -rw-r--r-- 1 user user 99999 2011-00-00 00:00 SKK-CFG --rw-r--r-- 1 user user 99999 2011-00-00 00:00@point{}SKK-MK @kbd{L} +-rw-r--r-- 1 user user 99999 2011-00-00 00:00*SKK-MK "L" drwxr-xr-x 1 user user 99999 2011-00-00 00:00 bayesian ------ Dired ------- -@end group @end example -プロンプト @samp{Load SKK-MK?} には @kbd{y} をタイプしてください。 +プロンプト @code{Load SKK-MK?} には @code{y} を打鍵してください。 以降、インストーラが表示する質問に答えながら DDSKK のインストールを進めて ください。なお、パーミッションは一切考慮していませんので、インストール先 @@ -580,191 +871,203 @@ @node MELPA によるインストール @subsection MELPA によるインストール + @cindex MELPA -@cindex @file{package.el} +@cindex package.el @vindex package-archives @findex package-initialize - -2014年12月、MELPA@footnote{@uref{https://melpa.org/, Milkypostman's Emacs Lisp Package Archive}} -に DDSKK が登録されたことにより GNU Emacs でも @file{package.el} -@footnote{GNU Emacs 24 以降で標準で搭載されています。GNU Emacs 23 以前では手動でインストール必要があります。@* -@url{http://wikemacs.org/wiki/Package.el}} -によるインストールが可能となりました。 +2014年12月、MELPA @footnote{@uref{http://melpa.org/, Milkypostman's Emacs Lisp Package Archive}} に DDSKK が登録されたことにより、 GNU Emacs で +も @code{package.el} @footnote{GNU Emacs 24 以降で標準で搭載されています。GNU Emacs 23 以 +前では手動でインストール必要があります。 @uref{http://wikemacs.org/wiki/Package.el}} によるインストールが可能となりました。 詳細については、次のドキュメントを参照してください。 -@url{https://github.com/skk-dev/ddskk/blob/master/READMEs/INSTALL.MELPA.md} +@uref{https://github.com/skk-dev/ddskk/blob/master/READMEs/INSTALL.MELPA.md} @node 辞書について @section 辞書について -DDSKK を使用するには、いわゆる辞書 (主にかなと漢字の対応を記述したデータ) +DDSKK を使用するには、いわゆる辞書(主にかなと漢字の対応を記述したデータ) が必要です。 -DDSKK 14.2 からは、 GNU Emacs 同梱の辞書データ @file{ja-dic} を利用した -かな漢字変換に対応しましたので、SKK 辞書ファイルを別途インストールしなく -ても最低限の使用ができます(XEmacs では @file{ja-dic} は利用できませんの -で、後述する SKK 辞書をインストールする必要があります)。 +@cindex ja-dic +DDSKK 14.2 からは、 GNU Emacs 同梱の辞書データ @code{ja-dic} を利用したかな漢 +字変換に対応しましたので、SKK 辞書ファイルを別途インストールしなくても最 +低限の使用ができます(XEmacs では @code{ja-dic} は利用できませんので、後述す +る SKK 辞書をインストールする必要があります)。 -しかし、@file{ja-dic} は、 Emacs の入力メソッド LEIM のために @file{SKK-JISYO.L} か +@cindex LEIM +しかし、 @code{ja-dic} は、 GNU Emacs の入力メソッド @code{LEIM} のために @code{SKK-JISYO.L} か ら変換して生成されたものであり、英数変換や数値変換などのエントリ、および 「大丈夫」など複合語とみなし得る語が大幅に削除されています。 -そのため、@file{SKK-JISYO.L} を利用したかな漢字変換と同等の結果は得られま -せん。 +そのため、 @code{SKK-JISYO.L} を利用したかな漢字変換と同等の結果は得られません。 -有志の知恵を結集して作られている各種 SKK 辞書は便利ですから、是非入手し -てインストールしましょう。 +有志の知恵を結集して作られている各種 SKK 辞書は便利ですから、是非入手して +インストールしましょう。 @node 辞書の入手 @section 辞書の入手 -@table @b -@item SKK 各辞書の解説とダウンロード -@url{http://openlab.jp/skk/wiki/wiki.cgi?page=SKK%BC%AD%BD%F1} +次のサイトには、様々な辞書が用意されています。 -このサイトには様々な辞書が用意されています。以下は一例です。 -@end table +@uref{http://openlab.jp/skk/wiki/wiki.cgi?page=SKK%BC%AD%BD%F1, SKK 各辞書の解説とダウンロード} + +以下は、その一例です。 + +@itemize +@item +@code{SKK-JISYO.S} -@table @code -@item SKK-JISYO.S S 辞書(主に単漢字が登録。最小限必要な語を収録) -@item SKK-JISYO.M + +@item +@code{SKK-JISYO.M} + M 辞書(普通に使う分には足りる程度) -@item SKK-JISYO.ML -M 辞書と L 辞書の中間のサイズの辞書。L 辞書収録語の内、EPWING 辞書やオン -ライン辞書で正しいと判別された語をベースにして加除。 -@item SKK-JISYO.L +@item +@code{SKK-JISYO.ML} + +M 辞書と L 辞書の中間のサイズの辞書。L 辞書収録語の内、EPWING 辞書やオ +ンライン辞書で正しいと判別された語をベースにして加除。 + + +@item +@code{SKK-JISYO.L} + L 辞書(あらゆる単語を収録) -@item zipcode + +@item +@code{zipcode} + 郵便番号辞書 -@item SKK-JISYO.JIS2 + +@item +@code{SKK-JISYO.JIS2} + JIS X 0208 で定められている第2水準の文字を、部首の読みを見出し語として 単漢字を収録した辞書 -@item SKK-JISYO.JIS3_4 -JIS 第3水準、第4水準の文字に代表される、JIS X 0208 には含まれない -が JIS X 0213 には含まれる文字及びそれらを含む語録を収録した辞書 -@item SKK-JISYO.public+ +@item +@code{SKK-JISYO.JIS3_4} + +JIS 第3水準、第4水準の文字に代表される、JIS X 0208 には含まれないが +JIS X 0213 には含まれる文字及びそれらを含む語録を収録した辞書 + + +@item +@code{SKK-JISYO.public+} + public+ 辞書 -@item SKK-JISYO.edict -edict 辞書(英和辞書) -@item SKK-JISYO.lisp -候補に Emacs Lisp 関数を含むエントリーを集めた辞書。見出し語を変換する過 -程で Emacs Lisp 関数を評価し、その値を候補として表示します。 - -@xref{プログラム実行変換}. - -@item SKK-JISYO.wrong -間違い辞書(S, M, L 辞書に既に登録されていたが、間違いであったので削除さ -れた単語を収録) -@end table +@item +@code{SKK-JISYO.edict} -一部の辞書は、著作権が GNU GPL v2 ではありませんのでご注意下さい。 -詳細は、次の資料を参照して下さい。 +edict 辞書(英和辞書) -@url{http://openlab.jp/skk/skk/dic/READMEs/committers.txt} -@kindex M-x skk-get -@defun {コマンド} skk-get +@item +@code{SKK-JISYO.lisp} -Emacs の使用中に @kbd{M-x skk-get} と実行すると、辞書ファイルを一括ダウン -ロードすることができます。 +候補に Emacs Lisp 関数を含むエントリーを集めた辞書。見出し語を変換する +過程で Emacs Lisp 関数を評価し、その値を候補として表示します。 -なお、GNU Emacs 24.3 以下では tar 展開に対応していないため -@file{SKK-JISYO.edict.tar.gz} と @file{zipcode.tar.gz} は処理されません。 +@ref{プログラム実行変換}. -@end defun + +@item +@code{SKK-JISYO.wrong} + +S, M, L 辞書に既に登録されていたが、間違いであったことが判明したため削 +除された単語を収録 +@end itemize + +一部の辞書は、著作権が GNU GPL v2 ではありませんのでご注意下さい。詳細は、 +次の資料を参照して下さい。 + +@uref{http://openlab.jp/skk/skk/dic/READMEs/committers.txt} + +@table @asis +@kindex M-x skk-get +@cindex skk-get +@item @kbd{M-x skk-get} @tie{}@tie{}@tie{}@tie{}(@code{skk-get}) + +Emacs の使用中に @code{M-x skk-get} と実行すると、辞書ファイルを一括ダウンロ +ードすることができます。 + +@end table @defun skk-get &optional DIRECTORY -@code{skk-get} を関数として使用することで、ユーザプログラムの中からでも辞 -書ファイルを一括ダウンロードすることができます +skk-get を関数として使用することで、ユーザプログラムの中からでも辞書フ +ァイルを一括ダウンロードすることができます。 @lisp -@group (skk-get "~/jisyofiles") -@end group @end lisp - @end defun @node 辞書を DDSKK と同時にインストールする @section 辞書を DDSKK と同時にインストールする -DDSKK のソースを展開すると、中に @file{dic} というディレクトリが存在しま -す。@file{SKK-JISYO.L} などをこのディレクトリにコピーしてから @command{make install} を -実行すると、辞書ファイルがチュートリアル (@file{SKK.tut}) と同じディ -レクトリ (@file{/usr/share/skk} や @file{c:/emacs-24.5/etc/skk} など) に -インストールされます。 +DDSKK のソースを展開すると、中に @code{dic} というディレクトリが存在します。 +@code{SKK-JISYO.L} などをこのディレクトリにコピーしてから @code{make install} を +実行すると、辞書ファイルがチュートリアル (@code{SKK.tut}) と同じディレクト +リ (@code{/usr/share/skk} や @code{c:/emacs-24.5/etc/skk} など) にインストールされ +ます。具体的なインストール先は @code{make what-where} を実行すると表示されます。 -@file{dic} ディレクトリに辞書ファイルを置くためには @command{make get} と -実行するのが簡単です@footnote{Microsoft Windows 環境では @command{makeit.bat get} と -実行します。}。 - -@file{dic} ディレクトリに辞書ファイルが置かれている場合、@command{make what-where} 実 -行時に辞書ファイルのインストール先も表示します。 - -@example -@group -@print{}SKK dictionaries: -@print{} SKK-JISYO.lisp, SKK-JISYO.zipcode, SKK-JISYO.office.zipcode, @dots{} -@print{} -> c:/emacs-24.5/share/emacs/24.5/etc/skk -@end group -@end example - -@c さらに、@file{SKK-JISYO.L} を DDSKK ソースの @file{dic} ディレクトリにコ -@c ピーしてから @command{make cdb} を実行すると、CDB 形式辞書ファイル @file{SKK-JISYO.L.cdb} が -@c 生成されます@footnote{CDB 形式辞書ファイルの生成には python スクリプト @file{etc/skk2cdb.py} -@c が実行されるので、あらかじめ python 処理系をインストールしておく必要があ -@c ります。}。 -@c この状態で @command{make install} を実行すると @file{SKK-JISYO.L.cdb} も -@c @file{SKK-JISYO.L} と共にインストールされます。 +@example +-| SKK dictionaries: +-| SKK-JISYO.lisp, SKK-JISYO.zipcode, SKK-JISYO.office.zipcode, ... +-| -> c:/emacs-24.5/share/emacs/24.5/etc/skk +@end example + +@code{dic} ディレクトリに辞書ファイルを置くためには @code{make get} と実行するのが +簡単です @footnote{Microsoft Windows 環境では @code{makeit.bat get} と実行します。} 。 @node 辞書サーバの入手 @section 辞書サーバの入手 -辞書サーバはオプションです。 -辞書サーバが無くても DDSKK は動作しますが、特に辞書のサイズが大きい場合は -辞書サーバを利用することで省メモリ効果を得られます。また、辞書サーバによ -っては複数辞書の検索、EPWING 辞書の検索ができたりするものもあります。 +辞書サーバはオプションです。辞書サーバが無くても DDSKK は動作しますが、特 +に辞書のサイズが大きい場合は辞書サーバを利用することで省メモリ効果を得ら +れます。また、辞書サーバによっては複数辞書の検索、EPWING 辞書の検索ができ +たりするものもあります。 DDSKK は特定の辞書サーバの実装に依存していませんので、下記の辞書サーバの いずれでも動作可能です。ソースやバイナリの入手、インストールについてはそ れぞれのウェブサイトをご参照下さい。 -@table @b -@item 辞書サーバの説明とリンク - -@url{http://openlab.jp/skk/skkserv-ja.html} -@end table +@itemize +@item +@uref{http://openlab.jp/skk/skkserv-ja.html, 辞書サーバの説明とリンク} +@end itemize @node はじめの設定 @chapter はじめの設定 -@cindex @file{leim-list.el} - -標準的にインストールした場合は、特段の設定なしに Emacs を起動するだけ -で DDSKK が使える状態になります。 -自動的に @file{skk-setup.el} というファイルが読み込まれ、設定されます -@footnote{Emacs が起動する過程(関数@code{normal-top-level})で @file{SKK_LISPDIR/leim-list.el} が読み込まれます。 - -@file{leim-list.el} は @file{skk-autoloads.el} と @file{skk-setup.el} を @code{require} します。 +@cindex skk-setup.el +@cindex leim-list.el +@cindex skk-autoloads.el +@findex normal-top-level @findex register-input-method -@file{skk-autoloads.el} は DDSKK の @command{make} 時に自動的に生成されるファイル -であり、各関数を自動ロード(autoload)するよう定義するほか @code{register-input-method} も -行います。 - -@file{skk-setup.el} はキーバインド(@kbd{C-x C-j} @result{} @code{'skk-mode})、変数 @code{skk-tut-file} の定義及びインクリメンタル・サーチの定義を行っています。}。 +@kindex C-x C-j +標準的にインストールした場合は、特段の設定なしに Emacs を起動するだけ +で DDSKK が使える状態になります。自動的に @code{skk-setup.el} というファイルが +読み込まれ、設定されます @footnote{Emacs が起動する過程の関数 @code{normal-top-level} で @code{SKK_LISPDIR/leim-list.el} が +読み込まれます。 @code{leim-list.el} は @code{skk-autoloads.el} と @code{skk-setup.el} を @code{require} し +ます。 @code{skk-autoloads.el} は DDSKK の @code{make} 時に自動的に生成されるファイ +ルであり、各関数を自動ロード (autoload) するよう定義するほか @code{register-input-method} も +行います。 @code{skk-setup.el} はキーバインド( @code{C-x C-j} → @code{skk-mode} )の定 +義、変数 @code{skk-tut-file} の定義及びインクリメンタル・サーチの定義を行って +います。} 。この自動設定によらずに手動で設 +定したい場合は、以下の説明を参照してください。 -この自動設定によらずに手動で設定したい場合は、以下の説明を参照してください。 @menu * 最も基本的な設定:: @@ -775,19 +1078,20 @@ @node 最も基本的な設定 @section 最も基本的な設定 -@vindex skk-cdb-large-jisyo -自動設定によらず手動で設定する場合は、次の内容を @file{~/.emacs.d/init.el} に書きま -す@footnote{サンプルとして、配布物に @file{etc/dot.emacs}、@file{etc/dot.skk} フ -ァイルがあります。参考にして下さい。}。 +@cindex init.el +@kindex C-x C-j +@kindex C-x j +@kindex C-x t +自動設定によらず手動で設定する場合は、次の内容を @code{~/.emacs.d/init.el} に書きま +す @footnote{配布物にサンプルファイル @code{etc/dot.emacs} と @code{etc/dot.skk} が +あります。参考にして下さい。}。 @lisp -@group -(require 'skk-autoloads) ; @b{XEmacs でパッケージとしてインストールした場合は不要} +(require 'skk-autoloads) ; XEmacs でパッケージとしてインストールした場合は不要 (global-set-key "\C-x\C-j" 'skk-mode) (global-set-key "\C-xj" 'skk-auto-fill-mode) (global-set-key "\C-xt" 'skk-tutorial) -@end group @end lisp 辞書サーバを使わない場合は、辞書ファイルを指定する必要があります。 @@ -796,89 +1100,69 @@ (setq skk-large-jisyo "/your/path/to/SKK-JISYO.L") @end lisp -@noindent -辞書サーバを使わない場合は Emacs のバッファに @code{skk-large-jisyo} が指 -すファイルを取り込んで使用するためメモリ使用量が増加します。これが支障と -なる場合は、上記の @file{SKK-JISYO.L} を @file{SKK-JISYO.M}、@file{SKK-JISYO.ML} 又 -は @file{SKK-JISYO.S} に変更してください。 +辞書サーバを使わない場合は Emacs のバッファに @code{skk-large-jisyo} が指すフ +ァイルを取り込んで使用するためメモリ使用量が増加します。これが支障となる +場合は、上記の @code{SKK-JISYO.L} を @code{SKK-JISYO.M} 、 @code{SKK-JISYO.ML} 又 +は @code{SKK-JISYO.S} に変更してください。 @cindex CDB 形式辞書ファイル - -DDSKK 14.1 以降は辞書サーバを経由せずとも CDB 形式@footnote{constant database の -こと。詳しくは @url{http://cr.yp.to/cdb.html} 又は @url{http://ja.wikipedia.org/wiki/Cdb} を参照のこと。} -の辞書ファイルを直接利用できるようになりました。CDB 形式辞書ファイル@footnote{ -SKK 辞書 の @file{Makefile} 中の cdb ターゲットを実行することで @file{SKK-JISYO.L} か -ら @file{SKK-JISYO.L.cdb} を生成することができます。} -を利用する場合は、以下のように指定してください。 +DDSKK 14.1 以降は辞書サーバを経由せずとも CDB 形式 @footnote{constant database のこと。詳しくは @uref{http://cr.yp.to/cdb.html} 又 +は @uref{http://ja.wikipedia.org/wiki/Cdb} を参照のこと。} の辞書ファイ +ルを直接利用できるようになりました。CDB 形式辞書ファイル @footnote{SKK 辞書 の @code{Makefile} 中の @code{cdb} ターゲットを実行すること +で @code{SKK-JISYO.L} に基づく @code{SKK-JISYO.L.cdb} を生成することができます。} を利 +用する場合は、以下のように指定してください。 @lisp (setq skk-cdb-large-jisyo "/your/path/to/SKK-JISYO.L.cdb") @end lisp -@noindent -変数 @code{skk-large-jisyo} と 変数 @code{skk-cdb-large-jisyo} を同時に指 -定した場合は、標準では CDB 形式辞書ファイルの方が先に検索されます。これに関して -は @w{@ref{辞書検索の設定の具体例}} も参照してください。 +変数 @code{skk-large-jisyo} と 変数 @code{skk-cdb-large-jisyo} を同時に指定した場合 +は、標準では CDB 形式辞書ファイルの方が先に検索 @footnote{@ref{辞書検索の設定の具体例}.} されます。 @node インクリメント検索の設定 @section インクリメント検索の設定 + @vindex isearch-mode-hook @vindex isearch-mode-end-hook - -基本的な設定は @file{skk-setup.el} が読み込まれた時点で完了しています -@footnote{@file{skk-setup.el} では、関数 @code{isearch-mode-hook} に @code{skk-isearch-setup-maybe} を、 -関数 @code{isearch-mode-end-hook} に @code{skk-isearch-cleanup-maybe} を -、それぞれ hook に追加しています。 -@code{skk-isearch-@{setup|cleanup@}-maybe} とも @file{skk-setup.el} で定義されており、 -実態は、関数 @code{skk-isearch-mode-@{setup|cleanup@}} です。}。 - -@defvr {ユーザ変数} skk-isearch-mode-enable - -@code{Non-nil} なら SKK が ON になっているバッファで @code{skk-isearch} を有効 -にします。デフォルトは @code{t} です。 - -@code{nil} に設定すると @code{skk-isearch} を無効にすることができます -@footnote{変数 @code{skk-isearch-mode-enable} は @file{~/.emacs.d/init.el} か @kbd{M-x customize-variable} で設定してください。}。 - -@lisp -(setq skk-isearch-mode-enable nil) -@end lisp - -この変数の値をシンボル @code{'always} に設定すると、 SKK が ON になってい -ないバッファでも @code{skk-isearch} を有効にします。 - -@lisp -(setq skk-isearch-mode-enable 'always) -@end lisp -@end defvr +基本的な設定は @code{skk-setup.el} が読み込まれた時点で完了しています @footnote{@code{skk-setup.el} では、 @code{isearch-mode-hook} に @code{skk-isearch-setup-maybe} を、 +@code{isearch-mode-end-hook} に @code{skk-isearch-cleanup-maybe} をそれぞれ追加して +います。 @code{skk-isearch-@{setup|cleanup@}-maybe} も @code{skk-setup.el} で定義され +ており、その実態は、関数 @code{skk-isearch-mode-@{setup|cleanup@}} です。}。 + +@defopt skk-isearch-mode-enable + +この変数は @code{~/.emacs.d/init.el} か @code{M-x customize-variable} で設定して +ください。 @code{Non-nil} であれば、SKK が ON になっているバッファで skk-isearch を +有効にします。標準設定は @code{t} です。 @code{nil} に設定すると skk-isearch を +無効にすることができます。シンボル @code{always} に設定すると、SKK が ON に +なっていないバッファでも skk-isearch を有効にします。 +@end defopt @node 辞書サーバを使いたいときの設定 @section 辞書サーバを使いたいときの設定 -辞書サーバを使いたいときは、@file{~/.skk} で以下のように設定します。 +辞書サーバを使いたいときは、 @code{~/.skk} で以下のように設定します。 @lisp -@group (setq skk-server-host "example.org") (setq skk-server-portnum 1178) -@end group @end lisp -@defvr {ユーザ変数} skk-server-host +@defvar skk-server-host 辞書サーバが起動しているホスト名又は IP アドレス。 -@end defvr +@end defvar + +@defvar skk-server-portnum + +辞書サーバが使うポート番号。 @code{/etc/services} に @code{skkserv} のエントリが +記述されていれば、この変数を指定する必要は無い。 +@end defvar -@defvr {ユーザ変数} skk-server-portnum +@defopt skk-server-inhibit-startup-server -辞書サーバが使うポート番号。@file{/etc/services} に skkserv のエントリが -記述されていれば @code{skk-server-portnum} を指定する必要は無い。 -@end defvr - -@vindex skk-server-inhibit-startup-server -辞書サーバが起動していなかったときに Emacs から skkserv プロセスを立ち上げる -事もできます。@code{skk-server-inhibit-startup-server} を @code{nil} に -する事でこの機能が有効になります。@ref{サーバ関連} も参照してください。 +この変数が @code{nil} であれば、辞書サーバが起動していなかったときに Emacs か +ら @code{skkserv} プロセスを起動することができます。 Emacs から立ち上げて利用する事ができる辞書サーバは、 @@ -886,39 +1170,35 @@ skkserv [-p port] [jisyo] @end example -@noindent -のようなオプションを受け付け、inetd などを経由せず直接起動するものに限ら -れます。 - -辞書サーバプログラムと辞書ファイルは、次のように設定します。 +のようなオプションを受け付け、 @code{inetd} などを経由せず直接起動するものに +限られます。辞書サーバプログラムと辞書ファイルは、次のように設定します。 @lisp -@group (setq skk-server-prog "/your/path/to/skkserv") (setq skk-server-jisyo "/your/path/to/SKK-JISYO.L") -@end group @end lisp +@end defopt -@defvr {ユーザ変数} skk-server-prog +@defvar skk-server-prog 辞書サーバプログラムをフルパスで指定する。 -@end defvr +@end defvar -@defvr {ユーザ変数} skk-server-jisyo +@defvar skk-server-jisyo -辞書サーバに渡す辞書をフルパスで指定する。辞書サーバによっては独自の方法 -で辞書ファイルを指定して emacs からの指定を無視するものもあります。 +辞書サーバに渡す辞書をフルパスで指定する。辞書サーバによっては独自の方 +法で辞書ファイルを指定して emacs からの指定を無視するものもあります。 詳しくは各辞書サーバの説明書を読んで下さい。 -@end defvr +@end defvar -@noindent +@cindex SKKSERVER +@cindex SKKSERV +@cindex SKK_JISYO これらの設定は、環境変数を利用して下記のようにすることもできます。 -@cindex @code{SKKSERVER} -@cindex @code{SKKSERV} -@cindex @code{SKK_JISYO} -@table @b -@item B シェルの場合 (sh, bash, ksh, zsh など) +@itemize +@item +B シェルの場合(sh, bash, ksh, zsh など) @example export SKKSERVER=example.org @@ -926,233 +1206,214 @@ export SKK_JISYO=/your/path/to/SKK-JISYO.L @end example -@item C シェルの場合 (csh, tcsh など) + +@item +C シェルの場合(csh, tcsh など) @example setenv SKKSERVER example.org setenv SKKSERV /your/path/to/skkserv setenv SKK_JISYO /your/path/to/SKK-JISYO.L @end example -@end table +@end itemize -関連項目: @w{@ref{辞書サーバの入手}}、@w{@ref{サーバ関連}} +関連項目: -@node DDSKK を Emacs の Input Method とする -@section DDSKK を Emacs の Input Method とする -@cindex LEIM -@cindex input method -@cindex @file{skk-leim.el} -@kindex C-\ -@kindex M-x list-input-methods -@kindex M-x set-input-method +@itemize +@item +@ref{辞書サーバの入手}. -Emacs の標準キーバインドでは @kbd{C-\} をタイプすると -関数 @code{toggle-input-method} を実行します。 -この関数は、変数 @code{default-input-method} が指す input method をトグル切り替えします。 -変数 @code{default-input-method} の値はおそらく @code{"Japanese"} であり、 -結果として @kbd{C-\} のタイプで LEIM @footnote{Library of Emacs Input Method} を on/off します。 +@item +@ref{サーバ関連}. +@end itemize -使用可能な input method は @kbd{M-x list-input-methods} で確認することができ、 -コマンド @code{set-input-method} を実行する @footnote{@kbd{M-x set-input-method} また -は @kbd{C-x @key{RET} C-\}} ことで input method を切り替えることができます。 +@node DDSKK を Emacs の Input Method とする +@section DDSKK を Emacs の Input Method とする -ファイル @file{skk-leim.el} から生成されるファイル @file{skk-autoloads.el} で input method をふたつ追加しています。 +@cindex skk-leim.el +@kindex C-\ +@kindex M-x toggle-input-method +Emacs の標準キーバインドでは @code{C-\} を打鍵すると、関数 @code{toggle-input-method} を +実行します。この関数は、変数 @code{default-input-method} が指す input method を +トグル切り替えします。 -@table @b -@item "japanese-skk" +@vindex default-input-method +@cindex LEIM +変数 @code{default-input-method} の値はおそらく "@code{Japanese}" であり、結果として @code{C-\} の +打鍵で LEIM (Library of Emacs Input Method) を on / off します。 -内容は @code{(skk-mode 1)} です。 +@kindex M-x list-input-methods +@kindex M-x set-input-method +@kindex C-x RET C-\ +使用可能な input method は @code{M-x list-input-methods} で確認することができ、 +コマンド @code{M-x set-input-method} 又は @code{C-x RET C-\} を実行することで input method を +切り替えることができます。 -@item "japanese-skk-auto-fill" +ファイル @code{skk-leim.el} から生成されるファイル @code{skk-autoloads.el} で input method を +ふたつ追加しています。 -内容は @code{(skk-auto-fill-mode 1)} です。 -@end table +@itemize +@item +"@code{japanese-skk}" @dots{} 内容は @code{(skk-mode 1)} です。 +@item +"@code{japanese-skk-auto-fill}" @dots{} 内容は @code{(skk-auto-fill-mode 1)} です。 +@end itemize -@defvr {ユーザ変数} default-input-method +@cindex input method +@defopt default-input-method -Emacs 起動時の input method を DDSKK とするには、@file{~/.emacs.d/init.el} に +Emacs 起動時の input method を DDSKK とするには、 @code{~/.emacs.d/init.el} に @lisp (setq default-input-method "japanese-skk") @end lisp と記述してください。 +@end defopt -@end defvr - -@node 基本的な使い方, 便利な応用機能, はじめの設定, Top -@comment node-name, next, previous, up +@node 基本的な使い方 @chapter 基本的な使い方 本章では、DDSKK の基本的な使用方法を説明します。これを読めば、とりあえず DDSKK を使ってみるには充分です。 -DDSKK を使った入力方法に慣れるには、付属のチュートリアルが最適なので、お -試しください。 +DDSKK を使った入力方法に慣れるには、付属のチュートリアル @footnote{@ref{チュートリアル}.} が +最適なので、お試しください。 -@xref{チュートリアル}. +なお、次章の「便利な応用機能」 @footnote{@ref{便利な応用機能}.} は、興味のある個所のみをピックア +ップしてお読みになるのがいいでしょう。 -なお、次章の「便利な応用機能」は、興味のある個所のみをピックアップして -お読みになるのがいいでしょう。 @menu * 起動と終了:: -* 入力モード:: 文字種別毎のモード -* 変換モード:: 辞書を用いた変換の状態毎のモード +* 入力モード:: +* 変換モード:: * インクリメンタル・サーチ:: * チュートリアル:: @end menu @node 起動と終了 @section 起動と終了 -@kindex C-x C-j -@kindex C-x j -SKK モードに入るには @kbd{C-x C-j}、もしくは @kbd{C-x j} とタイプします。 -モードラインの左端には、下記のように @w{@samp{--かな:}} が追加されます -@footnote{@file{skk.el} の @code{skk-setup-modeline} にて、@code{mode-line-format} に @code{skk-icon} と @code{skk-modeline-input-mode} を追加しています}。 +SKK モードに入るには @code{C-x C-j} もしくは @code{C-x j} とキー入力します。モード +ラインの左端には、下記のように "@code{--かな:}" が追加されます @footnote{@code{skk.el} の @code{skk-setup-modeline} にて、 @code{mode-line-format} に @code{skk-icon} と @code{skk-modeline-input-mode} を追加しています。} 。 +また、カーソルの色が変化 @footnote{カラーディスプレイを使用し、カラー表示をサポートしている Window System 下 +で対応する Emacs を使用している場合。 + +@ref{入力モードを示すカーソル色に関する設定}.} します。 @example --かな:MULE/7bit----- Buffer-name (Major-mode)--- @end example -また、カーソルの色が変化します -@footnote{カラーディスプレイを使用し、カラー表示をサポートしている -Window System 下で対応する Emacs を使用している場合。 - -@w{@xref{入力モードを示すカーソル色に関する設定}.}}。 +再び @code{C-x C-j} もしくは @code{C-x j} をキー入力することで、SKK モードに入る前 +のモードに戻り @footnote{ただし、「アスキーモード」を利用すれば SKK モードから抜ける必要 +はほとんどありません。 -@kbd{C-x C-j}、もしくは @kbd{C-x j} を再度タイプすることで、SKK モードに -入る前のモードに戻り、カーソル色も元に戻ります -@footnote{ただし、@b{「アスキーモード」}を利用すれば SKK モードから抜ける -必要はほとんどありません。 +@ref{入力モード, , アスキーモード}.} 、カーソル色も元に戻ります。 -@xref{入力モード, , アスキーモード}.}。 +@defopt skk-status-indicator -@defvr {ユーザ変数} skk-status-indicator - -デフォルトはシンボル @code{'left} です。この変数をシンボル @code{'minor-mode} と -設定すれば、インジケータはモードラインのマイナーモードの位置に表示されます。 - -@example --MULE/7bit----- Buffer-name (Major-mode かな)--- -@end example - -@end defvr +標準設定はシンボル @code{left} です。この変数をシンボル @code{minor-mode} と設 +定すれば、インジケータはモードラインのマイナーモードの位置に表示されま +す。 +@end defopt -@defvr {ユーザ変数} skk-preload +@defopt skk-preload -@file{~/.emacs.d/init.el} にて変数 @code{skk-preload} を @code{non-nil} と設定するこ -とにより、DDSKK の初回起動を速くすることができます。 +@code{~/.emacs.d/init.el} にて変数 @code{skk-preload} を @code{non-nil} と設定すること +により、DDSKK の初回起動を速くすることができます。 @lisp (setq skk-preload t) @end lisp -これは、SKK 本体プログラムの読み込みと変数 @code{skk-search-prog-list} に -指定された辞書の読み込みを Emacs の起動時に済ませてしまうことにより実現し -ています。そのため、Emacs の起動そのものは遅くなりますが、DDSKK を使い始 -めるときのレスポンスが軽快になります。 -@end defvr +これは、SKK 本体プログラムの読み込みと、変数 @code{skk-search-prog-list} に +指定された辞書の読み込みを Emacs の起動時に済ませてしまうことにより実現 +しています。そのため、Emacs の起動そのものは遅くなりますが、DDSKK を使 +い始めるときのレスポンスが軽快になります。 +@end defopt -@findex skk-restart +@table @asis @kindex M-x skk-restart +@cindex skk-restart +@item @kbd{M-x skk-restart} @tie{}@tie{}@tie{}@tie{}(@code{skk-restart}) -@defun {コマンド} skk-restart - -@kbd{M-x skk-restart} と実行すると SKK を再起動します。 -@file{~/.skk} は再ロードしますが、@file{~/.emacs.d/init.el} は再ロードしません。 - -@end defun +@code{M-x skk-restart} と実行すると SKK を再起動します。 @code{~/.skk} は再ロード +しますが、 @code{~/.emacs.d/init.el} は再ロードしません。 @kindex M-x skk-version +@cindex skk-version +@item @kbd{M-x skk-version} @tie{}@tie{}@tie{}@tie{}(@code{skk-version}) -@defun {コマンド} skk-version - -@kbd{M-x skk-version} と実行すると エコーエリアに SKK のバージョンを表示します。 -@w{@ref{エラーなどの日本語表示}} +@code{M-x skk-version} と実行するとエコーエリアに SKK のバージョンを表示 @footnote{@ref{エラーなどの日本語表示}.} しま +す。 @example -------------------- Echo Area -------------------- -Daredevil SKK/@value{SKK-VERSION} (CODENAME) +Daredevil SKK/16.2.50 (CODENAME) -------------------- Echo Area -------------------- @end example +@end table -@end defun @menu -* SKKオートフィルモード:: +* SKK オートフィルモード:: * 辞書の保存:: @end menu -@node SKKオートフィルモード -@subsection SKKオートフィルモード +@node SKK オートフィルモード +@subsection SKK オートフィルモード + @cindex オートフィル -@cindex Auto Fill @kindex C-x j +@code{C-x j} とキー入力すれば、SKK モードに入ると同時にオートフィルモード @footnote{@ref{Auto Fill,Auto Fill Mode in GNU Emacs Manual,,emacs,}.} を +オンにします。 -@kbd{C-x j} とタイプすれば、SKK モードに入ると同時にオートフィルモード -(@pxref{Auto Fill, , Auto Fill, emacs, GNU Emacs Manual}) -をオンにします。 - -既にオートフィルモードがオンになっているバッファで @kbd{C-x j} をタイプす -ると、オートフィルモードは逆にオフになるので注意してください。 +既にオートフィルモードがオンになっているバッファで @code{C-x j} をキー入力する +と、オートフィルモードは逆にオフになるので注意してください。 @kindex M-1 C-x j @kindex C-u C-x j -バッファの状態にかかわらず強制的にオートフィルモード付で SKK モードに入 -りたい場合は、@kbd{M-1 C-x j} や @kbd{C-u C-x j} などとタイプし、このコ -マンドに正の引数を渡します -@footnote{「引数」については、 - -@display -@ref{Arguments, , Arguments, emacs, GNU Emacs Manual}. -@end display +バッファの状態にかかわらず強制的にオートフィルモード付で SKK モードに入り +たい場合は @code{M-1 C-x j} や @code{C-u C-x j} などとキー入力し、このコマンドに正 +の引数 @footnote{@ref{Arguments,Arguments in GNU Emacs Manual,,emacs,}.} を渡します。 -@noindent -を参照のこと。}。 - -@kindex C-u -1 C-x j @kindex M-- C-x j +@kindex C-u -1 C-x j オートフィルモードをオフにし、かつ SKK モードも終了したい場合には -@w{@kbd{M-- C-x j}} や @w{@kbd{C-u -1 C-x j}} などとタイプし、このコマン -ドに負の引数を渡します。 +@code{M-- C-x j} や @code{C-u -1 C-x j} などとキー入力し、このコマンドに負の引数を +渡します。 @node 辞書の保存 @subsection 辞書の保存 + @vindex skk-backup-jisyo @vindex skk-jisyo +Emacs を終了するときは、保存前の個人辞書を @code{~/.skk-jisyo.BAK} に退避して +から、個人辞書 @footnote{@ref{辞書の種類, , 個人辞書}.} の内容を @code{~/.skk-jisyo} に保存 @footnote{@ref{個人辞書の保存動作}.} し +ます。 -Emacs を終了するときは、保存前の個人辞書を @file{~/.skk-jisyo.BAK} に退避 -してから、個人辞書 (@pxref{辞書の種類, , 個人辞書})の内容を @file{~/.skk-jisyo} に -保存します。 - -@file{~/.skk-jisyo} や @file{~/.skk-jisyo.BAK} のファイル名を変更したけ -れば、それぞれ @code{skk-jisyo} や @code{skk-backup-jisyo} の値を変更して -下さい。 - -@findex skk-kill-emacs-without-saving-jisyo -@kindex M-x skk-kill-emacs-without-saving-jisyo - -個人辞書を保存せずに Emacs を終了させたい場合には、 - -@example -@kbd{M-x skk-kill-emacs-without-saving-jisyo} -@end example +@code{~/.skk-jisyo} や @code{~/.skk-jisyo.BAK} のファイル名を変更したければ、それぞ +れ @code{skk-jisyo} や @code{skk-backup-jisyo} の値を変更して下さい。 -@noindent -とタイプします。 +@table @asis +@kindex M-x skk-kill-emacs-without-saving-jisyo +@cindex skk-kill-emacs-without-saving-jisyo +@item @kbd{M-x skk-kill-emacs-without-saving-jisyo} @tie{}@tie{}@tie{}@tie{}(@code{skk-kill-emacs-without-saving-jisyo}) -個人辞書の保存動作について更に詳しくは、@ref{個人辞書の保存動作} を参照 -してください。 +個人辞書を保存せずに Emacs を終了させたい場合には、このコマンドをキー入 +力します。 +@end table @node 入力モード @section 入力モード -SKK モードは、文字種類による4種類の@b{「入力モード」}と、辞書を用いた -変換の状態により3つの@b{「変換モード」}を持ちます。 +SKK モードは、文字種類による4種類の @strong{入力モード} @footnote{@ref{入力モードを示すカーソル色に関する設定}.} と、辞書を +用いた変換の状態により3つの @strong{変換モード} を持ちます。 + @menu * 入力モードの説明:: @@ -1162,136 +1423,181 @@ @node 入力モードの説明 @subsection 入力モードの説明 -@table @b -@cindex かなモード -@item 「かなモード」 +@itemize +@item +かなモード +@itemize +@item アスキー小文字をひらがなに変換するモード。 -マイナーモードの表示: @samp{かな} +@item +マイナーモードの表示: @strong{かな} + + +@item カーソル色: 赤系 +@end itemize + -@cindex カナモード -@item 「カナモード」 +@item +カナモード + +@itemize +@item +アスキー小文字をカタカナに変換するモード -アスキー小文字をカタカナに変換するモード。 -マイナーモードの表示: @samp{カナ} +@item +マイナーモードの表示: @strong{カナ} + +@item カーソル色: 緑系 +@end itemize -@cindex 全英モード -@item 「全英モード」 -アスキー小文字/大文字を全角アルファベット@footnote{JIS X 0208 英字のこと。 -このマニュアルでは「全角アルファベット」と表記する。}に変換するモード。 +@item +全英モード + +@itemize +@item +アスキー小文字/大文字を全角アルファベット @footnote{JIS X 0208 英字のこと。このマニュアルでは「全角アルファベッ +ト」と表記する。} に変換する +モード。 -マイナーモードの表示: @samp{全英} +@item +マイナーモードの表示: @strong{全英} + + +@item カーソル色: 黄系 +@end itemize + -@cindex アスキーモード -@item 「アスキーモード」 +@item +アスキーモード -文字を変換しないモード。入力されたキーは @kbd{C-j} を除いて通常の Emacs の +@itemize +@item +文字を変換しないモード。入力されたキーは @code{C-j} を除いて通常の Emacs の コマンドとして解釈される。 -マイナーモードの表示: @samp{SKK} -カーソル色: 背景によりアイボリーかグレイ。 -@end table +@item +マイナーモードの表示: @strong{SKK} -入力モードに伴うカーソル色の変更方法については、 -@ref{入力モードを示すカーソル色に関する設定} を参照してください。 + +@item +カーソル色: 背景によりアイボリーかグレイ。 +@end itemize +@end itemize @node 入力モードを切り替えるキー @subsection 入力モードを切り替えるキー -@table @kbd -@item q +@table @asis +@kindex q +@cindex skk-toggle-kana +@item @kbd{q} @tie{}@tie{}@tie{}@tie{}(@code{skk-toggle-kana}) + 「かなモード」、「カナモード」間をトグルする。 -@item l +@kindex l +@cindex skk-latin-mode +@item @kbd{l} @tie{}@tie{}@tie{}@tie{}(@code{skk-latin-mode}) + 「かなモード」又は「カナモード」から「アスキーモード」へ。 -@item L +@kindex L +@cindex skk-jisx0208-latin-mode +@item @kbd{L} @tie{}@tie{}@tie{}@tie{}(@code{skk-jisx0208-latin-mode}) + 「かなモード」又は「カナモード」から「全英モード」へ。 -@item C-j +@kindex C-j +@cindex skk-kakutei +@item @kbd{C-j} @tie{}@tie{}@tie{}@tie{}(@code{skk-kakutei}) + 「アスキーモード」又は「全英モード」から「かなモード」へ。 @end table 実際にはカナモードや全英モードで長時間入力を続けることはほとんどないの で、かなモードのままでカナ文字や全英文字を入力する便法が用意されています。 -@itemize @bullet +@itemize @item -@w{@pxref{かなモードからカタカナを入力}} +@ref{かなモードからカタカナを入力}. + @item -@w{@pxref{全英文字の入力}} +@ref{全英文字の入力}. @end itemize +@defopt skk-show-mode-show -@kindex M-x skk-show-mode -@defvr {ユーザ変数} skk-show-mode-show - -現在の入力モードは、モードラインに表示されています。 - -@ref{起動と終了} - -この変数を @code{Non-nil} とすると、入力モードを切り替えたときにカーソル -付近にも一瞬表示するようになります。 - -@kbd{M-x skk-show-mode} でトグル可能です。 - -@ref{入力モードを示すモードラインの文字列の変更} - -@end defvr +現在の入力モードは、モードラインに表示されています。この変数を @code{Non-nil} と +すると、入力モードを切り替えたときにカーソル付近にも一瞬表示するように +なります。 +@end defopt -@defvr {ユーザ変数} skk-show-mode-style +@table @asis +@kindex M-x skk-show-mode +@cindex skk-show-mode +@item @kbd{M-x skk-show-mode} @tie{}@tie{}@tie{}@tie{}(@code{skk-show-mode}) -デフォルトは @code{'inline} です。@code{'tooltip} を指定することも可能です。 +@code{skk-show-mode-show} の値をトグル切り替えします。 -@ref{インジケータ} +@end table -@end defvr +@defopt skk-show-mode-style -@defvr {ユーザ変数} skk-show-mode-inline-face +標準設定は、シンボル @code{inline} です。シンボル @code{tooltip} を指定すること +も可能です。 +@end defopt -@code{'inline} 利用時の face +@defopt skk-show-mode-inline-face -@end defvr +@code{inline} 利用時の face +@end defopt @node 変換モード @section 変換モード -変換モードは、次の 3 種類のいずれかです。 +変換モードは、次の3種類のいずれかです。 -@table @b -@item 「■モード(確定入力モード)」 +@itemize +@item +■モード(確定入力モード) あるキー入力に対応する文字列を、辞書を用いた文字変換を行わずに直接バッ -ファへ入力するモード。入力モードに応じてローマ字からひらがな、ローマ字か -らカタカナ、あるいはアスキー文字から全角アルファベットへ文字を変換する。 +ファへ入力するモード。入力モードに応じてローマ字からひらがなへ、ローマ +字からカタカナへ、あるいはアスキー文字から全角アルファベットへ文字を変 +換する。 + + +@item +▽モード -@item 「▽モード」 +辞書変換の対象となる文字列 @strong{見出し語} を入力するモード。 -辞書変換の対象となる文字列「見出し語」を入力するモード。 -@item 「▼モード」 +@item +▼モード 見出し語について、辞書変換を行うモード。 -@end table +@end itemize + +また、▽モードの変種として @strong{SKK abbrev モード} があり、▼モードのサブモード +として @strong{辞書登録モード} があります。 -また、▽モードの変種として @dfn{SKK abbrev mode} があり、▼モードのサブモー -ドとして、@b{「辞書登録モード」}があります。 @menu -* ■モード:: 辞書変換を行わない確定入力のモード。 -* ▽モード:: 辞書変換のため見出し語の入力を行うモード。 -* ▼モード:: 辞書変換を行うモード。 -* 辞書登録モード:: 個人辞書へ単語を登録するモード。 +* ■モード:: +* ▽モード:: +* ▼モード:: +* 辞書登録モード:: @end menu @node ■モード @@ -1300,58 +1606,56 @@ @cindex 確定入力 @cindex 確定入力モード @cindex ■モード -確定入力モードを@b{「■モード」}と呼びます。■モードでは、あるキー入力に -対応した特定の文字列への変換を行うだけで、辞書変換は行いません。アスキー -文字列から、入力モードに応じて、ひらがな、カタカナ、あるいは全角アルファ -ベットへ文字を変換します。カレントバッファにこのモード特有のマークは表示 -されません。 +確定入力モードを @strong{■モード} と呼びます。■モードでは、あるキー入力に対応 +した特定の文字列への変換を行うだけで、辞書変換は行いません。アスキー文字 +列から、入力モードに応じて、ひらがな、カタカナ、あるいは全角アルファベッ +トへ文字を変換します。カレントバッファにこのモード特有のマークは表示され +ません。 @cindex ローマ字入力 -かなモード、カナモードで、かつ ■モードである場合、デフォルトの入力方法 -はいわゆるローマ字入力です。訓令式、ヘボン式のどちらによっても入力するこ -とができます。主な注意点は以下のとおりです。 +かなモード、カナモードで、かつ ■モードである場合、標準設定の入力方法は +いわゆるローマ字入力です。訓令式、ヘボン式のどちらによっても入力すること +ができます。主な注意点は以下のとおりです。 -@itemize @bullet +@itemize @item -@samp{ん} は @kbd{n n} 又は @kbd{n '} で入力する。直後に @samp{n}、 -@samp{y} 以外の子音が続くときは @kbd{n} だけで入力できる。 +「ん」 は @code{n n} 又は @code{n '} で入力する。直後に @code{n} 及び @code{y} 以外の子音が +続くときは @code{n} だけで入力できる。 + @item -促音は、@kbd{c h o t t o} @result{} @samp{ちょっと}、@kbd{m o p p a r a} -@result{} @samp{もっぱら} のように次の子音を重ねて入力する。 +促音は @code{c h o t t o} ⇒ 「ちょっと」 や @code{m o p p a r a} ⇒ 「もっぱら」 +のように次の子音を重ねて入力する。 + @item -促音や拗音(ひらがなの小文字)を単独で入力するときは、@kbd{x a} @result{} -@samp{ぁ}、@kbd{x y a} @result{} @samp{ゃ} などのように @kbd{x} を用いる。 +促音や拗音(ひらがなの小文字)を単独で入力するときは @code{x a} ⇒ 「ぁ」 +や @code{x y a} ⇒ 「ゃ」 などのように @code{x} を用いる。 + @item -長音は、@kbd{-} で入力する。@kbd{-} @result{} @samp{ー}。 +長音(ー)は @code{-} で入力する。 @end itemize @node ▽モード @subsection ▽モード -@cindex 辞書変換対象の文字列の決定 -@cindex ▽モード -@b{「▽モード」}では、辞書変換の対象となる文字列を入力します。かなモード、 -もしくはカナモード@footnote{@xref{入力モード, , かなモード、カナモード}.} -で、かつ、■モードであるときに、キー入力を大文字で開始することで、▽モー -ドに入ります。例えば、 +@strong{▽モード} では、辞書変換の対象となる文字列を入力します。かなモードもしく +はカナモードで @footnote{@ref{入力モード}.} 、かつ■モードであるときに、キー入力を @strong{大文字で開始} する +ことで▽モードに入ります。 @example -@kbd{K a n j i} +K a n j i -@group ------- Buffer: foo ------ -▽かんじ@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽かんじ* + ------ Buffer: foo ------ @end example -@noindent -のようにタイプすることで▽モードに入り、続けて辞書変換の対象となる文字 -列「見出し語」を入力します。@samp{▽}マークは「▽モードである」 -という表示ですが、見出し語の開始点を示す表示でもあります。 +@code{K a n j i} のように打鍵することで▽モードに入り、続けて辞書変換の対象と +なる文字列「見出し語」を入力します。▽マークは「▽モードである」という表 +示ですが、見出し語の開始点を示す表示でもあります。 + @menu * 後から▽モードに入る方法:: @@ -1360,116 +1664,94 @@ @node 後から▽モードに入る方法 @subsubsection 後から▽モードに入る方法 -@cindex 後から▽モードに入る方法 -@kindex Q -辞書変換の対象としたい文字列であったにも関わらず、先頭の文字を大文字で入力し忘れた場 -合は、その位置までポイント@footnote{@xref{Point, ,ポイント, emacs, GNU Emacs Manual}.} -を戻してから @kbd{Q} をタイプすることで、▽モードに入ることができます。例えば、 -下記のように操作します (@point{} の地点にカーソルがあります)。 +@kindex Q +辞書変換の対象としたい文字列であったにも関わらず、先頭の文字を大文字で入 +力し忘れた場合は、その位置までポイント @footnote{@ref{Point,Point in GNU Emacs Manual,,emacs,}.} を戻してから @code{Q} を打鍵 +することで、▽モードに入ることができます。 @example -@kbd{k a n j i} +k a n j i -@group ------- Buffer: foo ------ -かんじ@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + かんじ* + ------ Buffer: foo ------ -@kbd{C-u 3 C-b} +C-u 3 C-b -@group ------- Buffer: foo ------ -@point{}かんじ ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + *かんじ + ------ Buffer: foo ------ -@kbd{Q} +Q -@group ------- Buffer: foo ------ -▽@point{}かんじ ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽*かんじ + ------ Buffer: foo ------ -@kbd{C-e} +C-e -@group ------- Buffer: foo ------ -▽かんじ@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽かんじ* + ------ Buffer: foo ------ @end example @cindex 数字から始まる見出し語の入力 -@samp{7がつ24にち} のように大文字から始めることができない文字列を見出し語 -としたい場合は、 @kbd{Q} をタイプして▽モードにしてから @samp{7がつ24にち} の -文字列を入力します。 +「7がつ24にち」のように大文字から始めることができない文字列を見出し語とし +たい場合は @code{Q} を打鍵して▽モードにしてから「7がつ24にち」の文字列を入力 +します。 -なお、▽モードでは、文字列の間に空白を含めることはできません。 -これは、辞書エントリの見出し語に空白を含めることができない制限からきています。 +なお、▽モードでは、文字列の間に空白を含めることはできません。これは、辞 +書エントリの見出し語に空白を含めることができない制限からきています。 @node ▽モードを抜ける方法 @subsubsection ▽モードを抜ける方法 -@kindex C-g @kindex C-j -誤って▽モードに入ってしまったときは、 @kbd{C-j} とタイプして■モードに戻 -るか、 @kbd{C-g} とタイプして見出し語を消去するか、どちらかの方法があります。 -具体例を下記に示します。 +@kindex C-g +誤って▽モードに入ってしまったときは @code{C-j} と打鍵して■モードに戻るか、 +@code{C-g} と打鍵して見出し語を消去するか、どちらかの方法があります。 @example -@kbd{K a n j i} +K a n j i -@group ------- Buffer: foo ------ -▽かんじ@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽かんじ* + ------ Buffer: foo ------ -@kbd{C-j} +C-j -@group ------- Buffer: foo ------ -かんじ@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + かんじ* + ------ Buffer: foo ------ @end example -@noindent あるいは、 @example -@kbd{K a n j i} +K a n j i -@group ------- Buffer: foo ------ -▽かんじ@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽かんじ* + ------ Buffer: foo ------ -@kbd{C-g} +C-g -@group ------- Buffer: foo ------ -@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + * + ------ Buffer: foo ------ @end example @node ▼モード @subsection ▼モード -@cindex Overlays -@cindex ハイライト -@cindex 暗黙の確定 + @cindex 変換開始 +@strong{▼モード} では、▽モードで入力した見出し語を、辞書に従って変換する作業を +行います。▽モードで見出し語を入力した後に @code{SPC} を打鍵することで▼モード +に入ります。▽マークから @code{SPC} を打鍵したときのポイントまでの文字列が見出 +し語として確定され、 ▽マークは▼マークで置き換えられ、この見出し語が辞書 +の中で検索されます。 -@b{「▼モード」} では、▽モードで入力した見出し語を、辞書に従って変換する作 -業を行います。▽モードで見出し語を入力した後に @key{SPC} をタイプするこ -とで▼モードに入ります。@samp{▽} マークから @key{SPC} をタイプしたとき -のポイントまでの文字列が見出し語として確定され、 @samp{▽} マークは -@samp{▼} マークで置き換えられ、この見出し語が辞書の中で検索されます。 @menu * 送り仮名が無い場合:: @@ -1487,286 +1769,266 @@ @end example @noindent -というエントリ -@footnote{本マニュアルでは、見出し語と候補群を合わせた一行を「エントリ」 -と呼びます。詳細は、@ref{送りありエントリと送りなしエントリ}を参照してく -ださい。}を含むとして、例を示します。 +というエントリ @footnote{本マニュアルでは、見出し語と候補群を合わせた一行を「エントリ」 +と呼びます。 + +@ref{送りありエントリと送りなしエントリ}.} を含むとして、例を示します。 @example -@kbd{K a n j i} +K a n j i -@group ------- Buffer: foo ------ -▽かんじ@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽かんじ* + ------ Buffer: foo ------ -@key{SPC} +SPC -@group ------- Buffer: foo ------ -▼漢字@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼漢字* + ------ Buffer: foo ------ @end example -@noindent -この例では、▽モードにおける @samp{▽} マークからポイントまでの間の文字列 -@samp{かんじ} を辞書変換の対象文字列として確定し、それについて辞書内での -検索を行っています。実際の変換動作では、候補部分がハイライト表示されます -@footnote{ハイライト表示は FSF Emacs の Overlays、XEmacs の extent の機能を使 -用しています。}。 +@cindex Overlays +@cindex ハイライト +この例では、▽モードにおける▽マークからポイントまでの間の文字列「かんじ」 +を辞書変換の対象文字列として確定し、それについて辞書内での検索を行ってい +ます。実際の変換動作では、候補部分がハイライト @footnote{ハイライト表示は GNU Emacs の Overlays、XEmacs の extent +の機能を使用しています。} 表示されま +す。 -@samp{漢字} が求める語であれば @kbd{C-j} をタイプしてこの変換を -確定します。ハイライト表示も @samp{▼} マークも消えます。 +「漢字」が求める語であれば @code{C-j} を打鍵してこの変換を確定します。ハイライ +ト表示も▼マークも消えます。 -また、 @kbd{C-j} をタイプせずに新たな確定入力を続けるか又は新たな変換 -を開始すると、直前の変換は自動的に確定されます。これを @b{「暗黙の確定」} と -呼んでいます。副作用として確定を伴うキーは、印字可能な文字 -全てと @key{RET} です。詳細は @ref{暗黙の確定のタイミング} を参照してく -ださい。 +@cindex 暗黙の確定 +また、 @code{C-j} を打鍵せずに新たな確定入力を続けるか又は新たな変換を開始する +と、直前の変換は自動的に確定されます。これを @strong{暗黙の確定} @footnote{@ref{暗黙の確定のタイミング}.} と呼んでいます。 +打鍵することによる副作用として暗黙の確定を伴うキーは、印字可能な文字全て +と @code{RET} です。 @node 次候補・前候補 @subsubsection 次候補・前候補 -求める語がすぐに表示されなければ、更に続けて @key{SPC} をタイプすることで、 -次候補を検索します。 +求める語がすぐに表示されなければ、更に続けて @code{SPC} を打鍵することで次候補 +を検索します。 @example -@group ------- Buffer: foo ------ -▼漢字@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼漢字* + ------ Buffer: foo ------ -@key{SPC} +SPC -@group ------- Buffer: foo ------ -▼幹事@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼幹事* + ------ Buffer: foo ------ @end example -候補が5つ以上あるときは、5番目以降の候補は7つずつまとめて -@footnote{@code{skk-henkan-number-to-display-candidates}} -エコーエリアに表示されます。例えば、辞書が +候補が5つ以上あるときは、5番目以降の候補は7つずつ @footnote{@code{skk-henkan-number-to-display-candidates}} まとめて +エコーエリアに表示されます。 + +例えば、辞書が @example -@group きょ /距/巨/居/裾/嘘/拒/拠/虚/挙/許/渠/据/去/ -@end group @end example @noindent -というエントリを含むときに @kbd{K y o} の後に @key{SPC} を5回 -@footnote{skk-show-candidates-nth-henkan-char} -続けてタイプすれば - +というエントリを含むときに @code{K y o} の後に @code{SPC} を5回 @footnote{@code{skk-show-candidates-nth-henkan-char}} 続けて +打鍵すれば @example -@group -------------------- Echo Area -------------------- A:嘘 S:拒 D:拠 F:虚 J:挙 K:許 L:渠 [残り 2] -------------------- Echo Area -------------------- -@end group @end example @noindent -がエコーエリア -@footnote{エコーエリアとミニバッファは視覚的には同一の場所にありますが、 -エコーエリアが単にユーザへのメッセージを表示するのみであるのに対し、ミ -ニバッファは独立したバッファとして機能する点が異なります。}に表示されます。 -ここで仮に @samp{許} を選択したければ @kbd{k} を入力します。 +がエコーエリア @footnote{エコーエリアとミニバッファは視覚的には同一の場所にあります +が、エコーエリアが単にユーザへのメッセージを表示するのみであるのに対し、 +ミニバッファは独立したバッファとして機能する点が異なります。} に表示されます。ここで仮に「許」を選択したけ +れば @code{k} を打鍵します。 + +@code{A} , @code{S} , @code{D} , @code{F} , @code{J} , @code{K} , @code{L} の各文字は、押し易さを考慮してキ +ーボードのホームポジションから横方向に一直線に配置されているキーが選ばれ +ています。また、候補の選択のために押すキー @footnote{@ref{候補の選択に用いるキー}.} は、大文字、小文字 +のいずれでも構いません。 -@samp{A}, @samp{S}, @samp{D}, @samp{F}, @samp{J}, @samp{K}, @samp{L} の -各文字は、押し易さを考慮してキーボードのホームポジションから横方向に一直 -線に配置されているキーが選ばれています。また、候補の選択のために押すキー -は、大文字、小文字のいずれでも構いません。候補の選択に用いるキーの変更に -ついては、@w{@ref{候補の選択に用いるキー}} を参照してください。 +@code{SPC} を連打してしまって求める候補を誤って通過してしまったときは @code{x} を打 +鍵 @footnote{@code{x} は小文字で入力する必要があります。} すれば前候補/前候補群に戻ることができます。 -@key{SPC} を連打してしまい求める候補を誤って通過してしまったときは -@kbd{x} をタイプすれば前候補/前候補群に戻ることができます -@footnote{@samp{x} は小文字で入力する必要があります}。 +次々と候補を探しても求める語がなければ、自動的に辞書登録モード @footnote{@ref{辞書登録モード}.} に +なります(辞書登録モードは▼モードのサブモードです)。 -候補を次々と探しても求める語がなければ、自動的に辞書登録モードになります -(辞書登録モードは▼モードのサブモードです) 。 -@ref{辞書登録モード}にて説明します。 +@defvar skk-previous-candidate-keys -@defvr {ユーザ変数} skk-previous-candidate-keys -前候補/前候補群に戻る関数 @code{skk-previous-candidate} を割り当てるオブ -ジェクトのリストを指定する。 -オブジェクトにはキーを表す文字列または event vector が指定できます。 +前候補/前候補群に戻る関数 @code{skk-previous-candidate} を割り当てるオブジ +ェクトのリストを指定する。オブジェクトにはキーを表す文字列または +event vector が指定できます。 -デフォルトは @code{(list "x" "\C-p")} です。 -@end defvr +標準設定は @code{(list "x" "\C-p")} です。 +@end defvar + +@defvar skk-search-excluding-word-pattern-function -@defvr {ユーザ変数} skk-search-excluding-word-pattern-function 詳しくは docstring を参照のこと。 -@end defvr +@end defvar + +@defvar skk-show-candidates-nth-henkan-char -@defvr {ユーザ変数} skk-show-candidates-nth-henkan-char 候補一覧を表示する関数 @code{skk-henkan-show-candidates} を呼び出すまで -の @code{skk-start-henkan-char} を打鍵する回数。2 以上の整数である必要。 -@end defvr +の @code{skk-start-henkan-char} を打鍵する回数。2以上の整数である必要。 +@end defvar + +@defvar skk-henkan-number-to-display-candidates -@defvr {ユーザ変数} skk-henkan-number-to-display-candidates いちどに表示する候補の数。 -@end defvr +@end defvar @node 送り仮名が有る場合 @subsubsection 送り仮名が有る場合 次に送り仮名のある単語について説明します。 -@samp{動く} を変換により求めたいときは @kbd{U g o K u} のように、まず ▽ -モード に入るために @kbd{U} を大文字で入力し、次に送り仮名の開始を DDSKK -に教えるために @kbd{K} を大文字で入力します。送り仮名の @kbd{K} をタイプ -した時点で @key{SPC} をタイプすることなく、▼モード に入り辞書変換が行わ -れます。 - -送り仮名の入力時(ローマ字プレフィックスが挿入された瞬間)、プレフィック -スの直前に @samp{*} を一瞬挿入し、送り仮名の開始時点を明示します。プレ -フィックスに続くキー入力で、かな文字が完成した時点で @samp{*} は消えます。 +「動く」を変換により求めたいときは @code{U g o K u} のように、まず、▽モードに +入るために @code{U} を大文字で入力し、次に、送り仮名の開始を DDSKK に教えるた +めに @code{K} を大文字で入力します。送り仮名の @code{K} を打鍵した時点で▼モードに +入り辞書変換が行われます( @code{SPC} 打鍵は不要)。 + +送り仮名の入力時(ローマ字プレフィックスが挿入された瞬間)にプレフィック +スの直前に一瞬だけ @code{*} が表示されることで送り仮名の開始時点を明示します。 +プレフィックスに続くキー入力で、かな文字が完成した時点で @code{*} は消えます。 キー入力を分解して追いながらもう少し詳しく説明します。 @example -@kbd{U g o} +U g o -@group ------- Buffer: foo ------ -▽うご@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽うご* + ------ Buffer: foo ------ -@kbd{K} +K -@group ------- Buffer: foo ------ -▽うご*k@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽うご*k + ------ Buffer: foo ------ -@kbd{u} +u + + ------ Buffer: foo ------ + ▼動く* + ------ Buffer: foo ------ -@group ------- Buffer: foo ------ -▼動く@point{} ------- Buffer: foo ------ -@end group @end example -このように、DDSKK では送り仮名の開始地点をユーザが明示的に入力するので、 -システム側で送り仮名を分解する必要がありません。これにより、高速でヒット -効率が高い変換が可能になります。@xref{送り仮名の自動処理}. +このように、DDSKK では送り仮名の開始地点をユーザが明示的に入力 @footnote{@ref{送り仮名の自動処理}.} す +るので、システム側で送り仮名を分解する必要がありません。これにより、高速 +でヒット効率が高い変換が可能になります。 -ただし、サ変動詞の変換では、サ変動詞の語幹となる名詞を @b{「送りなし変換」} -@footnote{詳細は、@ref{送り仮名が無い場合}を参照してください。} -として変換し、その後 @samp{する} を■モードで入力した方が効率が良くなり -ます。@xref{サ変動詞の辞書登録に関する注意, , サ変動詞の入力}. +ただし、サ変動詞の変換 @footnote{@ref{サ変動詞の辞書登録に関する注意, , サ変動詞の入力}.} では、サ変動詞の語幹となる名詞 +を @strong{送りなし変換} @footnote{詳細は @ref{送り仮名が無い場合}.} として変換し、その後「する」を■モードで +入力した方が効率が良くなります。 @node 辞書登録モード @subsection 辞書登録モード @cindex 辞書登録 -DDSKK には独立した辞書登録モードはありません。その代わり、辞書にない単語に -関して変換を行った場合に、自動的に辞書登録モードに入ります。例えば辞書に +DDSKK には独立した辞書登録モードはありません。その代わり、辞書にない単語 +に関して変換を行った場合に、自動的に @strong{辞書登録モード} に入ります。例えば +辞書に @example へんかんちゅう /変換中/ @end example @noindent -のエントリがない場合に、@samp{変換中} を入力しようとして、@w{@kbd{H e n -k a n t y u u @key{SPC}}} とタイプすると、下記のように、カレントバッファ -は ▼モード のまま @samp{へんかんちゅう} に対して変換ができない状態で休 -止し、同時にミニバッファに @samp{へんかんちゅう} というプロンプトが表示 -されます。 +のエントリがない場合に「変換中」を入力しようとして @code{H e n k a n t y u u SPC} と +キー入力すると、下記のように、カレントバッファは▼モードのまま「へんかん +ちゅう」に対して変換ができない状態で休止し、同時にミニバッファに「へんか +んちゅう」というプロンプトが表示されます。 @example -@group ------ Buffer: foo ------ ▼へんかんちゅう ------ Buffer: foo ------ +@end example +@example ------ Minibuffer ------- -[辞書登録] へんかんちゅう: @point{} +[辞書登録] へんかんちゅう: * ------ Minibuffer ------- -@end group @end example -@menu -* 送り仮名が無い場合の辞書登録:: -* 送り仮名が有る場合の辞書登録:: -* サ変動詞の辞書登録に関する注意:: -* 再帰的辞書登録:: -* 改行文字を含む辞書登録:: -@end menu - もちろん、誤って登録した単語は削除できます。 -(@w{@pxref{誤った登録の削除}}, @w{@pxref{個人辞書ファイルの編集}}) -@defvr {ユーザ変数} skk-read-from-minibuffer-function -この変数に「文字列を返す関数」を収めると、その文字列を辞書登録モードに入 -ったときのプロンプトに初期表示します。関数 @code{read-from-minibuffer} の -引数 INITIAL-CONTENTS に相当します。 +@itemize +@item +@ref{誤った登録の削除}. + + +@item +@ref{個人辞書ファイルの編集}. +@end itemize +@defvar skk-read-from-minibuffer-function + +この変数に「文字列を返す関数」を収めると、その文字列を辞書登録モードに +入ったときのプロンプトに初期表示します。関数 @code{read-from-minibuffer} の +引数 @code{INITIAL-CONTENTS} に相当します。 @lisp -@group (setq skk-read-from-minibuffer-function (lambda () skk-henkan-key)) -@end group @end lisp +@end defvar -@end defvr +@defvar skk-jisyo-registration-badge-face -@defvr {ユーザ変数} skk-jisyo-registration-badge-face +変数 @code{skk-show-inline} が @code{non-nil} であれば、辞書登録モードに移ったこ +とを明示するためにカレントバッファに「↓辞書登録中↓」とインライン表示 +します。この「↓辞書登録中↓」に適用するフェイスです。 +@end defvar -変数 @code{skk-show-inline} が @code{non-nil} であれば、辞書登録モードに -移ったことを明示するためにカレントバッファに「@b{↓辞書登録中↓}」とイン -ライン表示します。この「↓辞書登録中↓」に適用するフェイスです。 -@end defvr +@menu +* 送り仮名が無い場合の辞書登録:: +* 送り仮名が有る場合の辞書登録:: +* サ変動詞の辞書登録に関する注意:: +* 再帰的辞書登録:: +* 改行文字を含む辞書登録:: +@end menu @node 送り仮名が無い場合の辞書登録 @subsubsection 送り仮名が無い場合の辞書登録 -@noindent 辞書登録モードでは、キー入力はミニバッファに対して行われます。仮に辞書に @example -@group へんかん /変換/ ちゅう /中/ -@end group @end example @noindent -のようなエントリがあるとして、ミニバッファで @samp{変換中} の文字列を -@samp{変換} と @samp{中} とに分けて作ります。 +のようなエントリがあるとして、ミニバッファで「変換中」の文字列を「変換」 +と「中」とに分けて作ります。 @example -@group -@kbd{H e n k a n @key{SPC} T y u u @key{SPC}} +H e n k a n SPC T y u u SPC ------------ Minibuffer ------------ -[辞書登録] へんかんちゅう: 変換▼中@point{} ------------ Minibuffer ------------ -@end group + ----------- Minibuffer ------------ + [辞書登録] へんかんちゅう: 変換▼中* + ----------- Minibuffer ------------ @end example @cindex 暗黙の確定 -@noindent -ここで @key{RET} をタイプすれば @samp{変換中} が個人辞書に登録され、辞書 -登録モードは終了します -@footnote{ここでは「暗黙の確定」が行われるので @kbd{C-j} をタイプする必要 -はありません。ただし、@ref{▼モードでのRET} を参照してください。}。 -同時に、変換を行っているカレントバッファには @samp{変換中} が挿入され確定 -されます。@xref{辞書の種類, , 個人辞書}. +ここで @code{RET} を打鍵すれば「変換中」が個人辞書に登録され @footnote{@ref{辞書の種類}.} 、 +辞書登録モードは終了します @footnote{ここでは「暗黙の確定」が行われるので @code{C-j} を打鍵する必要はあり +ません。 -辞書登録モードを抜けたいときは @kbd{C-g} をタイプするか、または何も登録 -せず @key{RET} をタイプすると▽モードに戻ります。 +@ref{▼モードでの RET}.} 。同時に、変換を行っているカレン +トバッファには「変換中」が挿入され確定されます。 + +辞書登録モードを抜けたいときは @code{C-g} を打鍵するか、または何も登録せず @code{RET} を +打鍵すると▽モードに戻ります。 @node 送り仮名が有る場合の辞書登録 @subsubsection 送り仮名が有る場合の辞書登録 @@ -1779,188 +2041,162 @@ @end example @noindent -というエントリがないとして、例を挙げて説明します。 +というエントリが無いとして、例を挙げて説明します。 @example -@group -@kbd{U g o K u} +U g o K u -@end group -@group ------- Buffer: foo ------ -▼うごく ------- Buffer: foo ------ + ------ Buffer: foo ------ + ▼うごく + ------ Buffer: foo ------ ------- Minibuffer ------- -[辞書登録] うご*く: @point{} ------- Minibuffer ------- -@end group + ------ Minibuffer ------- + [辞書登録] うご*く: * + ------ Minibuffer ------- @end example -@noindent -ミニバッファで辞書登録すべき文字列は @samp{動} だけであり、送り仮名の -@samp{く} は含めてはいけません。 @samp{動く} と登録してしまうと、次に -@kbd{U g o K u} とタイプしたときに出力される候補が @samp{動くく} になっ -てしまいます。 +ミニバッファで辞書登録すべき文字列は「動」だけであり、送り仮名の「く」は +含めてはいけません。「動く」と登録してしまうと、次に @code{U g o K u} とキー入 +力したときに出力される候補が「動くく」になってしまいます。 @example -@group -@kbd{D o u @key{SPC}} +D o u SPC -@end group -@group ------- Minibuffer ------- -[辞書登録] うご*く: 動@point{} ------- Minibuffer ------- + ------ Minibuffer ------- + [辞書登録] うご*く: 動* + ------ Minibuffer ------- -@end group -@key{RET} -@group +RET ------- Buffer: foo ------ -動く@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 動く* + ------ Buffer: foo ------ @end example -@defvr {ユーザ変数} skk-check-okurigana-on-touroku +@defvar skk-check-okurigana-on-touroku -デフォルトは @code{nil} です。@code{non-nil} であれば、辞書登録時に送り仮 -名のチェックを行います。 +標準設定は @code{nil} です。 @code{non-nil} であれば、辞書登録時に送り仮名のチ +ェックを行います。 -シンボル @code{ask} を設定すれば、ユーザに確認を求め、送り仮名と認められ -れば送り仮名を取り除いてから登録します。 +シンボル @code{ask} を設定すれば、ユーザに確認を求め、送り仮名と認められれば +送り仮名を取り除いてから登録します。 -シンボル @code{auto} を設定すれば、ユーザに確認を求めず、勝手に送り仮名を -判断して削除してから登録します。 - -@end defvr +シンボル @code{auto} を設定すれば、ユーザに確認を求めず、勝手に送り仮名を判 +断して削除してから登録します。 +@end defvar @node サ変動詞の辞書登録に関する注意 @subsubsection サ変動詞の辞書登録に関する注意 -@cindex サ変動詞の辞書登録に関する注意 -サ変動詞(名詞の後に @samp{する} を付けた形で構成される動詞)については -@samp{する} を送り仮名とした送りあり変換 (@w{@pxref{送り仮名が有る場合}}) -をしないで、@samp{運動} と @samp{する} とに分けて入力することを前提として -います。@footnote{@file{SKK-JISYO.L} など共有辞書のメンテナンス上、原則と -してサ変動詞を送りありエントリに追加していません。そのため、@samp{する} を -送り仮名とした送りあり変換では、辞書に候補がなく辞書登録モードに入ってし -まうので、名詞として分解して入力することが一般的です。ただし、DDSKK 13 以 -降では暫定的にサ変動詞の送りあり変換を可能にする機能を用意しました。 -(@w{@pxref{サ変動詞変換}})} +サ変動詞(名詞の後に「する」を付けた形で構成される動詞)については「する」 +を送り仮名とした送りあり変換 @footnote{@ref{送り仮名が有る場合}.} をしないで、 +「運動」と「する」とに分けて入力することを前提としています @footnote{@code{SKK-JISYO.L} など共有辞書のメンテナンス上、原則としてサ変動詞 +を送りありエントリに追加していません。そのため、「する」を送り仮名とした +送りあり変換では、辞書に候補がなく辞書登録モードに入ってしまうので、名詞 +として分解して入力することが一般的です。ただし、DDSKK 13 以降では暫定的に +サ変動詞の送りあり変換を可能にする機能を用意しました。 + +@ref{サ変動詞変換}.} 。 -例えば @samp{運動する} は @kbd{U n d o u @key{SPC} s u r u} とタイプする -ことにより入力できます。名詞から作られる形容詞等も同様です。 +例えば「運動する」は @code{U n d o u SPC s u r u} とキー入力することにより入力 +できます。名詞から作られる形容詞等も同様です。 @node 再帰的辞書登録 @subsubsection 再帰的辞書登録 -@cindex 再帰的辞書登録 ミニバッファを再帰的に使って辞書登録を再帰的に行うことができます。 仮に辞書に @example -@group さいきてき /再帰的/ さいき /再帰/ -@end group @end example @noindent のようなエントリがなく、かつ @example -@group さい /再/ き /帰/ てき /的/ -@end group @end example @noindent のようなエントリがあるとします。 -ここで @kbd{S a i k i t e k i @key{SPC}} とタイプすると、見出し語 @samp{さ -いきてき} に対する候補を見つけられないので、ミニバッファに @samp{さいき -てき} というプロンプトを表示して辞書登録モードに入ります。 - -@samp{さいきてき} に対する辞書エントリを作るため @kbd{S a i k i @key{SPC}} -とタイプすると、更にこの候補も見つけられないので、ミニバッファに -@samp{さいき} というプロンプトを表示して、再帰的に @samp{さいき} の辞書 -登録モードに入ります。 +ここで @code{S a i k i t e k i SPC} とキー入力すると、見出し語「さいきてき」に +対する候補を見つけられないので、ミニバッファに「さいきてき」というプロン +プトを表示して辞書登録モードに入ります。 + +「さいきてき」に対する辞書エントリを作るため @code{S a i k i SPC} とキー入力す +ると、更にこの候補も見つけられないので、ミニバッファに「さいき」というプ +ロンプトを表示して、再帰的に「さいき」の辞書登録モードに入ります。 -@kbd{S a i @key{SPC} K i @key{SPC}} とタイプすると、ミニバッファは、 +@code{S a i SPC K i SPC} とキー入力すると、ミニバッファは、 @example ------ Minibuffer ------- -[[辞書登録]] さいき: 再▼帰 +[[辞書登録]] さいき: 再▼帰* ------ Minibuffer ------- @end example @noindent -となります。プロンプトが @samp{[[辞書登録]]} となり、@samp{[]} がひとつ増 -えていますが、この @samp{[]} の数が再帰的な辞書登録モードの深さを表わして -います。ここで @key{RET} をタイプすると、個人辞書には +となります。プロンプトが @code{[ [} 辞書登録 @code{] ]} となり @code{[ ]} がひとつ増えて +いますが、この @code{[ ]} の数が再帰的な辞書登録モードの深さを表わしています。 +ここで @code{RET} を打鍵すると、個人辞書には @example さいき /再帰/ @end example @noindent -というエントリが登録され、ミニバッファは @samp{さいきてき} の辞書登録モー -ドに戻り、プロンプトは @samp{さいきてき} となります。 +というエントリが登録され、ミニバッファは「さいきてき」の辞書登録モードに +戻り、プロンプトは「さいきてき」となります。 -今度は @samp{再帰} が変換可能なので @kbd{S a i k i @key{SPC} T e k i -@key{SPC}} とタイプすると、 +今度は「再帰」が変換可能なので @code{S a i k i SPC T e k i SPC} とキー入力する +と、 @example ------ Minibuffer ------- -[辞書登録] さいきてき: 再帰▼的 +[辞書登録] さいきてき: 再帰▼的* ------ Minibuffer ------- @end example @noindent -となります。ここで @key{RET} をタイプすることで、@samp{さいきてき} の辞 -書登録モードから抜け、個人辞書に +となります。ここで @code{RET} を打鍵することで「さいきてき」の辞書登録モードか +ら抜け、個人辞書に @example さいきてき /再帰的/ @end example @noindent -というエントリが登録されます。カレントバッファのポイントには、@samp{再帰 -的} が挿入されます。 +というエントリが登録されます。カレントバッファのポイントには「再帰的」が +挿入されます。 @node 改行文字を含む辞書登録 @subsubsection 改行文字を含む辞書登録 -@kindex C-q C-j -@cindex 改行文字を含む文字列の辞書登録 -改行文字を含む文字列を辞書に登録するには、辞書登録モードで改行文字を -@kbd{C-q C-j} により入力します。例えば、 +@kindex C-q C-j +改行文字を含む文字列を辞書に登録するには、辞書登録モードで改行文字を @code{C-q C-j} に +より入力します。例えば、 @example -@group 〒980 仙台市青葉区片平2-1-1 東北大学電気通信研究所 -@end group @end example @noindent を辞書に登録するには、辞書登録モードで、 @example -@group -@samp{〒980} -@kbd{C-q C-j} -@samp{仙台市青葉区片平2-1-1} -@kbd{C-q C-j} -@samp{東北大学電気通信研究所} -@key{RET} -@end group + 〒980 +C-q C-j + 仙台市青葉区片平2-1-1 +C-q C-j + 東北大学電気通信研究所 @end example @noindent @@ -1968,30 +2204,28 @@ @node インクリメンタル・サーチ @section インクリメンタル・サーチ -@cindex @file{isearch.el} + @cindex I-search @cindex Incremental search - DDSKK では、専用のインクリメンタル・サーチプログラムを Emacs 添付の -@file{isearch.el} のラッパーとして実装しているため、日本語文字列のイ -ンクリメンタル・サーチをアスキー文字と同様の操作で行うことができます。 +@code{isearch.el} のラッパーとして実装しているため、日本語文字列のインクリメン +タル・サーチをアスキー文字と同様の操作で行うことができます。 + @menu * skk-isearchの操作性:: -* skk-isearchと入力モード:: +* skk-isearch と入力モード:: @end menu @node skk-isearchの操作性 @subsection skk-isearchの操作性 大部分の動作は、Emacs オリジナルのインクリメンタル・サーチのままですから、 -Emacs オリジナルのインクリメンタル・サーチ -@footnote{@w{@ref{Incremental Search, ,Incremental Search, emacs, GNU Emacs Manual}.}} -のコマンド -@footnote{@kbd{M-y} の @code{isearch-yank-kill} や @kbd{M-p} の -@code{isearch-ring-retreat}, @kbd{M-n} の @code{isearch-ring-advance} な -ど}やユーザ変数でのカスタマイズ @footnote{@code{search-highlight} など} -もそのまま利用できます。 +Emacs オリジナルのインクリメンタル・サーチのコマンド @footnote{@code{M-y} の @code{isearch-yank-kill} 、 @code{M-p} の @code{isearch-ring-retreat} 、 +又は @code{M-n} の @code{isearch-ring-advance} など + +@ref{Incremental Search,Incremental Search in GNU Emacs Manual,,emacs,}.} やユーザ変 +数でのカスタマイズ @footnote{@code{search-highlight} など} もそのまま利用できます。 インクリメンタル・サーチ中の入力方法は、通常のバッファにおける各入力モー ド、変換モードでの入力方法と同一です。 @@ -2000,679 +2234,711 @@ @kindex C-s @kindex M-C-s @kindex M-C-r -@kbd{C-s} や @kbd{C-r}、あるいは @kbd{M-C-s} や @kbd{M-C-r} でインクリメ -ンタル・サーチを起動すると、インクリメンタル・サーチを起動したバッファの -入力モードと同一の入力モードで、キーとなる文字の入力が可能となります。 +@code{C-s} や @code{C-r} あるいは @code{M-C-s} や @code{M-C-r} でインクリメンタル・サーチを起 +動すると、インクリメンタル・サーチを起動したバッファの入力モードと同一の +入力モードで、キーとなる文字の入力が可能となります。 -@node skk-isearchと入力モード -@subsection skk-isearchと入力モード - -@vindex skk-isearch-mode-string-alist +@node skk-isearch と入力モード +@subsection skk-isearch と入力モード 入力モードに合わせて、インクリメンタル・サーチのプロンプトが表示されます。 -プロンプトの種類は、以下の 6 つです@footnote{変数 @code{skk-isearch-mode-string-alist} を適宜設定することにより変更が可能です。}。 +プロンプトの種類は、以下の6つです。 + +@itemize +@item +@code{I-search: [か]} @dots{} かなモード -@table @samp -@item I-search: [か] -かなモード +@item +@code{I-search: [カ]} @dots{} カナモード -@item I-search: [カ] -カナモード -@item I-search: [英] -全英モード +@item +@code{I-search: [英]} @dots{} 全英モード + + +@item +@code{I-search: [aa]} @dots{} アスキーモード -@item I-search: [aa] -アスキーモード -@item I-search: [aあ] -Abbrev モード +@item +@code{I-search: [aあ]} @dots{} Abbrev モード -@item I-search: [--] -インクリメンタル・サーチモードで @kbd{C-x C-j} などをタイプして DDSKK を -終了した場合は、このプロンプトが表示されます。 -@end table +@item +@code{I-search: [--]} @dots{} インクリメンタル・サーチモードで @code{C-x C-j} など +を打鍵して DDSKK を終了した場合は、このプロンプ +トが表示されます。 +@end itemize +@defvar skk-isearch-mode-string-alist + +プロンプトとして表示される文字列 +@end defvar @node チュートリアル @section チュートリアル -@cindex チュートリアル @vindex skk-tut-file @findex skk-tutorial @kindex M-x skk-tutorial DDSKK には、基本的な操作方法を学習できるチュートリアルが附属しています。 -日本語版チュートリアルは @kbd{M-x skk-tutorial} で、英語版チュートリアルは -@kbd{C-u M-x skk-tutorial @key{RET} English @key{RET}} で実行します。 +日本語版チュートリアルは @code{M-x skk-tutorial} で、英語版チュートリアルは +@code{C-u M-x skk-tutorial RET English RET} で実行します。 -@defvr {ユーザ変数} skk-tut-file +@defvar skk-tut-file -チュートリアルファイルが標準の場所に置かれていない場合は、 @file{~/.emacs.d/init.el} で +チュートリアルファイルが標準の場所に置かれていない場合は、 @code{~/.emacs.d/init.el} で @lisp (setq skk-tut-file "/usr/local/share/skk/SKK.tut") @end lisp -@noindent -と書くことにより、指定したチュートリアルファイルを使用させることが -できます。英語版のチュートリアルファイルは、 @samp{skk-tut-file} に @file{.E} -が付いたファイル名です。この場合であれば、 -@file{/usr/local/share/skk/SKK.tut.E} になります。 - -@end defvr - -@defvr {ユーザ変数} skk-tut-lang -チュートリアルで用いる言語を文字列(@code{"Japanese"} 又 -は @code{"English"})で指定します。 -この変数よりも @kbd{C-u M-x skk-tutorial} による言語指定が優先されます。 +と書くことにより、指定したチュートリアルファイルを使用させることができ +ます。英語版のチュートリアルファイルは、 @code{skk-tut-file} に @code{.E} が付い +たファイル名です。この場合であれば、 @code{/usr/local/share/skk/SKK.tut.E} に +なります。 +@end defvar -@end defvr +@defvar skk-tut-lang -@defvr {ユーザ変数} skk-tut-use-face +チュートリアルで用いる言語を文字列 "@code{Japanese}" 又は "@code{English}" で指定 +します。この変数よりも @code{C-u M-x skk-tutorial} による言語指定が優先され +ます。 +@end defvar -@code{Non-nil} であれば、チュートリアルで face を利用して表示する。 +@defvar skk-tut-use-face -@end defvr +@code{Non-nil} であれば、チュートリアルで face を利用して表示します。 +@end defvar @node 便利な応用機能 @chapter 便利な応用機能 + @menu -予備知識 -* ファイル構成:: 応用機能を使いこなすための予備知識。 +* ファイル構成:: * ユーザオプションの設定方法:: - -@noindent -入力関係 -* カタカナ、英字入力の便法:: これと次の項は絶対、便利です。 -* 補完:: 「かしたん」 + Tab -> 「かしたんぽせきにん」 -* 便利な変換、その他の変換:: 単漢字、接頭辞、漢数字、等々。 - -@noindent -様々な設定 -* キー設定:: ローマ字のルールなども変更できます。 -* 変換、確定の前後:: 誤変換の訂正、一発確定、確定のタイミングなど -* 送り仮名関連:: 送り仮名の処理について。 -* 候補の順序:: 関連のある語は上位に表示など、効率を求めて -* 辞書関連:: 辞書にまつわる設定及び機能。 - -@noindent -他 -* 注釈 (アノテーション):: -* 文字コード関連:: 文字コードにまつわる機能。 +* カタカナ、英字入力の便法:: +* 補完:: +* 便利な変換、その他の変換:: +* キー設定:: +* 変換、確定の前後:: +* 送り仮名関連:: +* 候補の順序:: +* 辞書関連:: +* 注釈(アノテーション):: +* 文字コード関連:: * DDSKK 以外のツールを用いた辞書変換:: -* 飾りつけ:: 様々な表示の設定。 +* 飾りつけ:: * ユーザガイダンス関連:: -* I-search関連:: インクリメンタル・サーチにまつわる機能。 +* I-search 関連:: * VIP/VIPERとの併用:: -* picture-modeとの併用:: picture-mode との併用の際の問題点。 +* picture-modeとの併用:: @end menu @node ファイル構成 @section ファイル構成 -@cindex @file{ccc.el} -@cindex @file{leim-list.el} -@cindex @file{skk.el} -SKK の基本的な機能は、@file{skk.el} に収められています。一方、 -DDSKK で応用機能を提供するプログラムのほとんどは @file{skk.el} と -は別のファイルに収めています。これらは、必要に応じてオートロードするよう -に設計されています。各応用機能の概略と該当のファイル名について説明します。 +SKK の基本的な機能は @code{skk.el} に収められています。一方、DDSKK で応用機能 +を提供するプログラムのほとんどは @code{skk.el} とは別のファイルに収めています。 +これらは、必要に応じてオートロードするように設計されています。各応用機能 +の概略と該当のファイル名について説明します。 + +また、DDSKK の変数は @code{skk-vars.el} に集約されていますので、カスタマイズし +たい場合などには、このファイルを見ると参考になるかもしれません。 -@cindex @file{skk-vars.el} -また、DDSKK の変数は @file{skk-vars.el} に集約されていますので、カスタマ -イズしたい場合などには、このファイルを見ると参考になるかもしれません。 +@itemize +@item +@code{ccc.el} + +buffer local cursor color control library + + +@item +@code{cdb.el} + +constant database (cdb) reader for Emacs Lisp -@table @file -@item ccc.el +@item +@code{context-skk.el} + +編集の文脈に応じて自動的に skk のモードを切り替えたり、SKK の各種設定を +変更する機能を提供します。 -@item cdb.el +@ref{文脈に応じた自動モード切り替え}. -@item context-skk.el -@cindex @file{context-skk.el} -編集の文脈に応じて自動的に skk のモードを切り替えたり、SKK の各種設定を変 -更する機能を提供します。 +@item +@code{ddskk-pkg.el} -@xref{文脈に応じた自動モード切り替え}. +@ref{Multi-file Packages,Multi-file Packages in GNU Emacs Lisp Reference Manual,,elisp,}. -@item ddskk-pkg.el -@item skk-abbrev.el -@cindex @file{skk-abbrev.el} +@item +@code{skk-abbrev.el} SKK abbrev モードの機能を提供するプログラムを集めたファイル。 -@xref{アスキー文字を見出し語とした変換, , SKK abbrev mode}. +@ref{アスキー文字を見出し語とした変換}. -@item skk-act.el -@cindex @file{skk-act.el} -dvorak 配列での拡張ローマ字入力 "ACT" を SKK で使うための設定を提供しま +@item +@code{skk-act.el} + +dvorak 配列での拡張ローマ字入力 ACT を SKK で使うための設定を提供しま す。 -@xref{ACT}. +@ref{ACT}. -@item skk-annotation.el -@cindex @file{skk-annotation.el} -個人辞書に付けたアノテーション (注釈) を活用するプログラムを集めたファイ -ル。 +@item +@code{skk-annotation.el} + +個人辞書に付けたアノテーション(注釈)を活用するプログラムを集めたファ +イル。 -@xref{注釈 (アノテーション)}. +@ref{注釈(アノテーション)}. -@item skk-auto.el -@cindex @file{skk-auto.el} + +@item +@code{skk-auto.el} 送り仮名の自動処理を行うプログラムを集めたファイル。 -@xref{送り仮名の自動処理}. +@ref{送り仮名の自動処理}. -@item skk-autoloads.el -@cindex @file{skk-autoloads.el} -make 時に自動生成されるファイル。オートロードの設定のほか、@code{register-input-method} も行う。 +@item +@code{skk-autoloads.el} + +@code{make} 時に自動生成されるファイル。オートロードの設定のほか @code{register-input-method} も +行う。 XEmacs で DDSKK をパッケージとしてインストールした場合は @code{auto-autoloads.el} と +いうファイルがこれに相当します。 -@xref{はじめの設定}. -XEmacs で DDSKK をパッケージとしてインストールした場合 -は @file{auto-autoloads.el} というファイルがこれに相当します。 +@item +@code{skk-azik.el} -@item skk-azik.el -@cindex @file{skk-azik.el} +拡張ローマ字入力 AZIK の設定を提供します。 -拡張ローマ字入力 "AZIK" の設定を提供します。 +@ref{AZIK}. -@xref{AZIK}. -@item skk-bayesian.el -@cindex @file{bayesian/skk-bayesian.el} +@item +@code{skk-bayesian.el} SKK の学習機能のひとつで、ユーザの過去の入力から変換候補を予測します。 -@xref{ベイズ統計を用いた学習}. +@ref{ベイズ統計を用いた学習}. -@item skk-cdb.el -@cindex @file{skk-cdb.el} + +@item +@code{skk-cdb.el} CDB 形式辞書ファイルを辞書サーバなしに直接利用できるプログラム。 -@xref{最も基本的な設定}. -@item skk-comp.el -@cindex @file{skk-comp.el} +@item +@code{skk-comp.el} 見出し語の補完を行うプログラムを集めたファイル。 -@xref{補完}. +@ref{補完}. + -@item skk-cursor.el -@cindex @file{skk-cursor.el} +@item +@code{skk-cursor.el} カーソルの色を制御するプログラムを集めたファイル。 -@xref{入力モードを示すカーソル色に関する設定}. +@ref{入力モードを示すカーソル色に関する設定}. + + +@item +@code{skk-cus.el} + +@code{M-x customize-group} による対話的な設定変更機能の簡易版を提供します。 -@item skk-cus.el -@cindex @file{skk-cus.el} -@kbd{M-x customize-group} による対話的な設定変更機能の簡易版を提供します。 +@ref{Customize による設定変更}. -@xref{Customize による設定変更}. -@item skk-dcomp.el -@cindex @file{skk-dcomp.el} +@item +@code{skk-dcomp.el} skk-comp による補完を自動的に実行して見出し語入力を支援します。 -@xref{動的補完}. +@ref{動的補完}. + + +@item +@code{skk-develop.el} + +font-lock 関係のほか、おもに開発者向けのプログラムを集めたファイル。 -@item skk-develop.el -@cindex @file{skk-develop.el} +@table @asis +@kindex M-x skk-submit-bug-report +@cindex skk-submit-bug-report +@item @kbd{M-x skk-submit-bug-report} @tie{}@tie{}@tie{}@tie{}(@code{skk-submit-bug-report}) -おもに開発者向けのプログラムを集めたファイル。 +バグレポートのメールバッファを用意する -@kbd{M-x skk-submit-bug-report} バグレポートのメールバッファを用意する +@kindex M-x skk-get +@cindex skk-get +@item @kbd{M-x skk-get} @tie{}@tie{}@tie{}@tie{}(@code{skk-get}) -@kbd{M-x skk-get} 辞書ファイルを一括ダウンロードする +辞書ファイルを一括ダウンロードする +@end table -font-lock 関係 -@item skk-emacs.el -@cindex @file{skk-emacs.el} +@item +@code{skk-emacs.el} -(DDSKK 14.1 以前のファイル名: @file{skk-e21.el}) +GNU Emacs の拡張機能を利用するプログラムを集めたファイル。インジケータ +のカラー化や画像表示、ツールティップ利用など。 -GNU Emacs 21 以降の拡張機能を利用するプログラムを集めたファイル。 -インジケータのカラー化や画像表示、ツールティップ利用など。 -@item skk-gadget.el -@cindex @file{skk-gadget.el} +@item +@code{skk-gadget.el} プログラム実行変換を行うプログラムを集めたファイル。 -@xref{プログラム実行変換}. +@ref{プログラム実行変換}. + -@item skk-hint.el -@cindex @file{skk-hint.el} +@item +@code{skk-hint.el} SKK の変換候補が多いときにヒントを与えて絞りこむ機能を提供します。 -@xref{候補の絞り込み}. +@ref{候補の絞り込み}. + -@item skk-inline.el -@cindex @file{skk-inline.el} +@item +@code{skk-inline.el} 変換候補のインライン表示機能を集めたファイル。 -@xref{変換候補一覧の表示方法}. +@ref{変換候補一覧の表示方法}. + -@item skk-isearch.el -@cindex @file{skk-isearch.el} +@item +@code{skk-isearch.el} DDSKK を併用したインクリメンタル・サーチ機能を提供します。 -@xref{I-search関連}. +@ref{I-search 関連}. + + +@item +@code{skk-jisx0201.el} -@item skk-jisx0201.el -@cindex @file{skk-jisx0201.el} +JIS X 0201 カナ @footnote{いわゆる半角カナ。以下、このマニュアルでは「半角カナ」と記述します} を利用する機能を提供します。 -JIS X 0201 カナ@footnote{いわゆる半角カナ。以下、このマニュアルでは「半角 -カナ」と記述します。}を利用する機能を提供します。 -@item skk-jisx0213.el -@cindex @file{skk-jisx0213.el} +@item +@code{skk-jisx0213.el} JIS X 0213 文字集合を扱うプログラムです。 -@item skk-jisyo-edit-mode.el -@cindex @file{skk-jisyo-edit-mode.el} + +@item +@code{skk-jisyo-edit-mode.el} SKK 辞書を編集するためのメジャーモードを提供します。 -@item skk-kakasi.el -@cindex @file{skk-kakasi.el} + +@item +@code{skk-kakasi.el} KAKASI インターフェイスプログラムを集めたファイル。 -@xref{領域の操作}. +@ref{領域の操作}. + + +@item +@code{skk-kanagaki.el} -@item skk-kanagaki.el -@cindex @file{skk-kanagaki.el} +キーボードのかな配列などに対応する枠組みを提供します。現段階では旧 JIS 配 +列のかなキーボード及び NICOLA 規格の親指シフト配列に対応しています。 -キーボードのかな配列などに対応する枠組みを提供します。 -現段階では旧 JIS 配列のかなキーボード及び NICOLA 規格の親指シフト配 -列に対応しています。 +@ref{かな入力と親指シフト}. -@xref{かな入力と親指シフト}. -@item skk-kcode.el -@cindex @file{skk-kcode.el} +@item +@code{skk-kcode.el} 文字コードまたはメニューによる文字入力を行うプログラムを集めたファイル。 -@xref{文字コードまたはメニューによる文字入力}. +@ref{文字コードまたはメニューによる文字入力}. + + +@item +@code{skk-leim.el} + +LEIM 関連プログラムファイル。DDSKK を Emacs の input method として利用 +できるようにします。 -@item skk-leim.el -@cindex @file{skk-leim.el} +@ref{DDSKK を Emacs の Input Method とする}. -LEIM 関連プログラムファイル。DDSKK を Emacs の input method として利用で -きるようにします。 -@xref{DDSKK を Emacs の Input Method とする}. +@item +@code{skk-look.el} -@item skk-look.el -@cindex @file{skk-look.el} +@code{look} コマンドとのインターフェイスプログラムを集めたファイル。 -@command{look} コマンドとのインターフェイスプログラムを集めたファイル。 +@ref{skk-look}. -@xref{skk-look}. -@item skk-lookup.el -@cindex @file{skk-lookup.el} +@item +@code{skk-lookup.el} Lookup で検索できる辞書を使って単語の候補を出力するプログラム。 -@xref{skk-lookup}. +@ref{skk-lookup}. + -@item skk-macs.el -@cindex @file{skk-macs.el} +@item +@code{skk-macs.el} 他のファイルで共通して使用するマクロなどを中心にまとめたファイル。 -@item skk-num.el -@cindex @file{skk-num.el} + +@item +@code{skk-num.el} 数値変換を行うプログラムを集めたファイル。 -@xref{数値変換}. +@ref{数値変換}. + -@item skk-search-web.el +@item +@code{skk-search-web.el} -Google CGI API for Japanese Input を利用したかな漢字変換。 +Google CGI API for Japanese Input を利用したかな漢字変換。辞書登録モー +ドに Google サジェストを初期表示する。 -辞書登録モードに Google サジェスト を初期表示する。 +@ref{Google CGI API for Japanese Input を利用したかな漢字変換}. -@xref{Google CGI API for Japanese Input を利用したかな漢字変換}. -@item skk-server-completion.el -@cindex @file{skk-server-completion.el} +@item +@code{skk-server-completion.el} 拡張された辞書サーバによる見出し語補完機能を利用できます。 -@xref{サーバコンプリージョン}. +@ref{サーバコンプリージョン}. -@item skk-server.el -@cindex @file{skk-server.el} + +@item +@code{skk-server.el} 辞書サーバと通信して変換する機能を提供します。 -@xref{サーバ関連}. +@ref{サーバ関連}. -@item skk-setup.el -@cindex @file{skk-setup.el} + +@item +@code{skk-setup.el} 自動的に個人設定を行うためのファイル。 -@xref{はじめの設定}. -@item skk-show-mode.el -@cindex @file{skk-show-mode.el} +@item +@code{skk-show-mode.el} カーソル付近に入力モードを表示する機能を提供します。 -@xref{入力モードを切り替えるキー}. -@item skk-sticky.el -@cindex @file{skk-sticky.el} +@item +@code{skk-sticky.el} 変換開始位置及び送り開始位置の指定方法を変更可能にする。 -@xref{変換位置の指定方法}. +@ref{変換位置の指定方法}. -@item skk-study.el -@cindex @file{skk-study.el} + +@item +@code{skk-study.el} 直前に確定したいくつかの語との関連性を確認し、候補順を操作する学習効果 を提供するプログラム。 -@xref{変換の学習}. +@ref{変換の学習}. -@item skk-tankan.el -@cindex @file{skk-tankan.el} + +@item +@code{skk-tankan.el} SKK を使って単漢字変換を行うプログラムです。 -@xref{単漢字変換}. +@ref{単漢字変換}. -@item skk-tut.el -@cindex @file{skk-tut.el} + +@item +@code{skk-tut.el} SKK チュートリアルプログラム。 -@xref{チュートリアル}. +@ref{チュートリアル}. -@item skk-tutcode.el -@cindex @file{skk-tutcode.el} + +@item +@code{skk-tutcode.el} SKK で TUT-code 入力を実現します。 -@xref{TUT-code}. +@ref{TUT-code}. + + +@item +@code{skk-vars.el} + +DDSKK で使われる変数を集約したファイル。 -@item skk-vars.el -@item skk-version.el -@cindex @file{skk-version.el} +@item +@code{skk-version.el} DDSKK のバージョン情報を提供するプログラムファイル。 -@item skk-viper.el -@cindex @file{skk-viper.el} + +@item +@code{skk-viper.el} VIPER インターフェイスプログラムを集めたファイル。 -@xref{VIP/VIPERとの併用}. +@ref{VIP/VIPERとの併用}. + -@item skk-xemacs.el -@cindex @file{skk-xemacs.el} +@item +@code{skk-xemacs.el} -XEmacs の拡張機能を利用するプログラムを集めたファイル。 -インジケータのカラー化や画像表示、ツールティップ利用など。 +XEmacs の拡張機能を利用するプログラムを集めたファイル。インジケータのカ +ラー化や画像表示、ツールティップ利用など。 -@item tar-util.el -@end table +@item +@code{tar-util.el} + +utility for tar archive +@end itemize @node ユーザオプションの設定方法 @section ユーザオプションの設定方法 -@cindex @file{~/.emacs.d/init.el} -@cindex @file{~/.xemacs/init.el} -@cindex @file{~/.skk} -DDSKK のカスタマイズは、@file{~/.emacs.d/init.el} あるいは @file{~/.skk} に記述し +@cindex ~/.emacs.d/init.el +@cindex ~/.xemacs/init.el +@cindex ~/.skk +DDSKK のカスタマイズは、 @code{~/.emacs.d/init.el} あるいは @code{~/.skk} に記述し ます。また、各ファイルの提供するフックも利用します。上記のファイルやフッ クを利用した設定がいつ有効になるのか、という点についてここで説明します。 + @menu * 設定ファイル:: +* skk-init-file の自動コンパイル:: * フック:: -* Customize による設定変更:: このマニュアルで解説されていない変数も設定できます。 +* Customize による設定変更:: * skk-customize による設定変更:: @end menu @node 設定ファイル @subsection 設定ファイル -@table @file -@item ~/.emacs.d/init.el -@itemx ~/.xemacs/init.el +@itemize +@item +@code{~/.emacs.d/init.el} , @code{~/.xemacs/init.el} Emacs を起動したときに一度だけ読み込まれます。 -このマニュアルは @file{~/.emacs.d/init.el} という記述で統一しています。 -@xref{Init File, ,Emacs Initialization File, emacs, GNU Emacs Manual}. +@ref{Init File,The Emacs Initialization File in GNU Emacs Manual,,emacs,}. -@item ~/.skk +このマニュアルは @code{~/.emacs.d/init.el} という記述で統一しています。 +@end itemize -DDSKK を起動した最初の一度だけ読み込まれます。ファイル名のデフォルトは、OS -の種類により異なりますが、実際は Emacs の関数 -@code{convert-standard-filename} により加工されます。 @findex convert-standard-filename -@file{~/.skk} のファイル名は変数 @code{skk-init-file} で変更することがで -きます。また、DDSKK にはこのファイルを自動的にバイトコンパイルする機能が -あります。 +@itemize +@item +@code{~/.skk} -@xref{skk-init-fileの自動コンパイル}. -@end table +DDSKK を起動した最初の一度だけ読み込まれます。ファイル名の標準設定 +は OS の種類により異なりますが、実際は Emacs の関数 @code{convert-standard-filename} に +より加工されます。 + +@code{~/.skk} のファイル名は変数 @code{skk-init-file} で変更することができます。 +また、DDSKK にはこのファイルを自動的にバイトコンパイルする機能があり +ます。 +@end itemize +@defvar skk-user-directory -@defvr {ユーザ変数} skk-user-directory -DDSKK は、@file{~/.skk} や @file{~/.skk-jisyo} といった複数のファイルを -使用します。これらのファイルをひとつのディレクトリにまとめて置きたい場合 -は、変数 @code{skk-user-directory} にそのディレクトリ名を設定します。 - -この変数のデフォルトは @code{nil} です。この変数は @file{~/.emacs.d/init.el} で設定 -してください。DDSKK 起動時に @code{skk-user-directory} が指すディレクトリ -が存在しない場合は、自動的に作られます。 +DDSKK は @code{~/.skk} や @code{~/.skk-jisyo} といった複数のファイルを使用します。 +これらのファイルをひとつのディレクトリにまとめて置きたい場合は、変数 @code{skk-user-directory} に +そのディレクトリ名を設定します。標準設定は @code{nil} です。 + +この変数は @code{~/.emacs.d/init.el} で設定してください。DDSKK 起動時に @code{skk-user-directory} が +指すディレクトリが存在しない場合は、自動的に作られます。 @lisp (setq skk-user-directory "~/.ddskk") @end lisp -この変数を設定した場合(例えば上記 @code{~/.ddskk})、以下に挙げる各変 -数のデフォルト値が変更されます。 +この変数を設定した場合(例えば上記 @code{~/.ddskk} )、以下に挙げる各変数の +標準設定値が変更されます。 @example -@group -影響を受ける変数 デフォルト値 変更後のデフォルト値 -skk-init-file ~/.skk ~/.ddskk/init -skk-jisyo ~/.skk-jisyo ~/.ddskk/jisyo -skk-backup-jisyo ~/.skk-jisyo.BAK ~/.ddskk/jisyo.bak -skk-emacs-id-file ~/.skk-emacs-id ~/.ddskk/emacs-id -skk-record-file ~/.skk-record ~/.ddskk/record -skk-study-file ~/.skk-study ~/.ddskk/study -skk-study-backup-file ~/.skk-study.BAK ~/.ddskk/study.bak -skk-bayesian-history-file ~/.skk-bayesian ~/.ddskk/bayesian -skk-bayesian-corpus-file ~/.skk-corpus ~/.ddskk/corpus -@end group +影響を受ける変数 標準設定値 変更後の標準設定値 +skk-init-file ~/.skk ~/.ddskk/init +skk-jisyo ~/.skk-jisyo ~/.ddskk/jisyo +skk-backup-jisyo ~/.skk-jisyo.BAK ~/.ddskk/jisyo.bak +skk-emacs-id-file ~/.skk-emacs-id ~/.ddskk/emacs-id +skk-record-file ~/.skk-record ~/.ddskk/record +skk-study-file ~/.skk-study ~/.ddskk/study +skk-study-backup-file ~/.skk-study.BAK ~/.ddskk/study.bak +skk-bayesian-history-file ~/.skk-bayesian ~/.ddskk/bayesian +skk-bayesian-corpus-file ~/.skk-corpus ~/.ddskk/corpus @end example -なお、@code{skk-user-directory} を設定した場合でも、各変数を個別に設定し -ている場合はその個別の設定が優先されます。 +なお、 @code{skk-user-directory} を設定した場合でも、各変数を個別に設定してい +る場合はその個別の設定が優先されます。 +@end defvar -@end defvr +@node skk-init-file の自動コンパイル +@subsection skk-init-file の自動コンパイル -@menu -* skk-init-fileの自動コンパイル:: -@end menu +@defvar skk-byte-compile-init-file + +ここでは、「DDSKK の設定ファイル」を @code{el} と、「DDSKK の設定ファイルを +バイトコンパイルしたファイル」を @code{elc} とそれぞれ呼ぶこととします。 + +@itemize +@item +DDSKK の起動時に、この変数の値が @code{non-nil} であれば、 -@node skk-init-fileの自動コンパイル -@subsubsection skk-init-fileの自動コンパイル +「 @code{elc} が存在しない」又は「 @code{elc} よりも @code{el} が新しい」とき +は、 @code{el} をバイトコンパイルした @code{elc} を生成します。 -@defvr {ユーザ変数} skk-byte-compile-init-file -@cartouche -@smallformat -ここでは -@itemize @minus -@item 「DDSKK の設定ファイル」を @code{el} と、 -@item 「DDSKK の設定ファイルをバイトコンパイルしたファイル」を @code{elc} と +@item +DDSKK の起動時に、この変数の値が @code{nil} であれば、 + +@code{elc} よりも @code{el} が新しいときは、 @code{elc} を消去します。 @end itemize +以上の機能を有効にしたい場合は @code{~/.emacs.d/init.el} に -それぞれ呼ぶこととします。 -@end smallformat -@end cartouche +@example +(setq skk-byte-compile-init-file t) +@end example -DDSKK の起動時に、 +と記述します。この変数は @code{~/.skk} が読み込まれる前に調べられるた +め、 @code{~/.skk} に上記の設定を記述しても無効です。 +@end defvar -@itemize @bullet -@item この変数の値が @code{non-nil} であれば、 +@node フック +@subsection フック -@itemize @minus -@item @code{elc} が存在しないか、又は -@item @code{elc} よりも @code{el} が新しいとき -@end itemize +@defvar skk-mode-hook -は、@code{el} をバイトコンパイルした @code{elc} を生成します。 +@code{C-x C-j} と入力して SKK モードに入る度に呼ばれます。主にバッファローカ +ルの設定などを行います。 +@end defvar -@item この変数の値が @code{nil} であれば、 +@defvar skk-auto-fill-mode-hook -@code{elc} よりも @code{el} が新しいときは、@code{elc} を消去します。 -@end itemize +@code{C-x j} と入力してオートフィルモード付きで SKK モードに入る度に呼ばれま +す。主にバッファローカルの設定などを行います。 +@end defvar -以上の機能を有効にしたい場合は、@file{~/.emacs.d/init.el} に +@defvar skk-load-hook -@lisp -(setq skk-byte-compile-init-file t) -@end lisp +@code{skk.el} の読み込みを完了した時点で呼ばれます。 @code{~/.skk} は SKK モード +を起動しなければ読み込まれないのに対し、このフックは @code{skk.el} を読み込 +んだら SKK モードを起動しなくとも呼ばれます。 +@end defvar -@noindent -と記述します。この変数は @file{~/.skk} が読み込まれる前に調べられるた -め、@file{~/.skk} に上記の設定を記述してもこの機能は有効になりません。 -@end defvr +各ファイルの読み込みが完了した直後に呼ばれるフックは以下のとおり。 -@node フック -@subsection フック +@defvar skk-act-load-hook -@table @code -@item skk-mode-hook -@vindex skk-mode-hook - -@kbd{C-x C-j} と入力して SKK モードに入る度に呼ばれます。主にバッファロー -カルの設定などを行います。 - -@item skk-auto-fill-mode-hook -@vindex skk-auto-fill-mode-hook - -@kbd{C-x j} と入力してオートフィルモード付きで SKK モードに入る度に呼ば -れます。主にバッファローカルの設定などを行います。 - -@item skk-load-hook -@vindex skk-load-hook - -@file{skk.el} の読み込みを完了した時点で呼ばれます。@file{~/.skk} は SKK -モードを起動しなければ読み込まれないのに対し、このフックは、 -@file{skk.el} を読み込んだら SKK モードを起動しなくとも呼ばれます。 - -@item skk-act-load-hook -@itemx skk-auto-load-hook -@itemx skk-azik-load-hook -@itemx skk-comp-load-hook -@itemx skk-gadget-load-hook -@itemx skk-kakasi-load-hook -@itemx skk-kcode-load-hook -@itemx skk-num-load-hook -@itemx skk-server-load-hook -@c @itemx skk-viper-load-hook -@vindex skk-act-load-hook -@vindex skk-auto-load-hook -@vindex skk-azik-load-hook -@vindex skk-comp-load-hook -@vindex skk-gadget-load-hook -@vindex skk-kakasi-load-hook -@vindex skk-kcode-load-hook -@vindex skk-num-load-hook -@vindex skk-server-load-hook -@c @vindex skk-viper-load-hook - -@file{skk-act.el}, @file{skk-auto.el}, @file{skk-azik.el}, @file{skk-comp.el}, -@file{skk-gadget.el}, @file{skk-kakasi.el}, @file{skk-kcode.el}, -@file{skk-num.el}, @file{skk-server.el} -@c , @file{skk-viper.el} -の各ファイルの読み込みが完了した直後に呼ばれるフック。 -@end table +@code{skk-act.el} +@end defvar + +@defvar skk-auto-load-hook + +@code{skk-auto.el} +@end defvar + +@defvar skk-azik-load-hook + +@code{skk-azik.el} +@end defvar + +@defvar skk-comp-load-hook + +@code{skk-comp.el} +@end defvar + +@defvar skk-gadget-load-hook + +@code{skk-gadget.el} +@end defvar + +@defvar skk-kakasi-load-hook + +@code{skk-kakasi.el} +@end defvar + +@defvar skk-kcode-load-hook + +@code{skk-kcode.el} +@end defvar + +@defvar skk-num-load-hook + +@code{skk-num.el} +@end defvar + +@defvar skk-server-load-hook + +@code{skk-server.el} +@end defvar @findex eval-after-load @code{load-hook} が提供されていないプログラムであっても、ロード完了後に何らか -の設定を行いたい場合は、関数 @code{eval-after-load} を使用します。例え -ば、 +の設定を行いたい場合は、関数 @code{eval-after-load} を使用します。 @lisp -@group (eval-after-load "skk-look" '( - @dots{} + ... )) -@end group @end lisp -@noindent -のように記述します。 - @node Customize による設定変更 @subsection Customize による設定変更 -@cindex Customize -Emacs 標準の Customize 機能を使って SKK を設定することもできます。 -ただし、 Customize での設定は @file{~/.emacs.d/init.el} での設定と同様、 -@file{~/.skk} による設定で上書きされてしまいますので注意してください。 +Emacs 標準の Customize 機能を使って SKK を設定することもできます。ただし、 +Customize での設定は @code{~/.emacs.d/init.el} での設定と同様に、 @code{/.skk} によ +る設定で上書きされてしまいますので注意してください。 @kindex M-x customize-group @kindex M-x skk-emacs-customize - -@kbd{M-x customize-group} を実行すると skk の設定を対話的に変更することができます。ミニバッファに ``Customize group:'' とプロンプトが表示されます。 +@code{M-x customize-group} を実行すると skk の設定を対話的に変更することができ +ます。ミニバッファに @code{Customize group:} とプロンプトが表示されます。 @example -@group ------ Minibuffer ------- -Customize group: (default emacs) @point{} +Customize group: (default emacs) * ------ Minibuffer ------- -@end group @end example -ここで ``skk'' と答えると、SKK グループの画面へ展開します。 - -@kbd{M-x skk-emacs-customize} と実行するのも同様です。 +ここで @code{skk} と答えると、SKK グループの画面へ展開します。 @code{M-x skk-emacs-customize} と +実行するのも同様です。 あるいは、モードラインの SKK インジケータをマウスの右ボタン(第3ボタン) -でクリックすると表示されるメニューから ``SKKをカスタマイズ'' を選んでも同 +でクリックすると表示されるメニューから「SKK をカスタマイズ」を選んでも同 じ画面となります。 -カスタマイズの使い方は以下を参照してください。 - -@display -@xref{Easy Customization, , Easy Customization, emacs, GNU Emacs Manual}. -@end display +カスタマイズの使い方は Info (@ref{Easy Customization,Easy Customization in GNU Emacs Manual,,emacs,}.) を参照してください。 skk で設定できる変数の中には、まだこのマニュアルで解説されていないものも あります。 Customize を使うと、それらについても知ることができます。 @@ -2680,124 +2946,121 @@ @node skk-customize による設定変更 @subsection skk-customize による設定変更 +@table @asis @kindex M-x skk-customize +@cindex skk-customize +@item @kbd{M-x skk-customize} @tie{}@tie{}@tie{}@tie{}(@code{skk-customize}) -前述の「Emacs 標準の Customize 機能 (@kbd{M-x customize-group}) 」による -設定が複雑すぎると感じるユーザのために、簡易版として @kbd{M-x skk-customize} を -用意しています。これは SKK グループのユーザオプションのうち、よく使うもの -だけ抜粋して設定できるようにしたものです。 - -これは、モードラインの SKK インジケータをマウスの右ボタン(第3ボタン)で -クリックして表示されるメニューから ``SKK をカスタマイズ (簡易版)'' を選ん -で呼び出すこともできます。 +前述の「Emacs 標準の Customize 機能 @code{M-x customize-group} 」による設定 +が複雑すぎると感じるユーザのために、簡易版として @code{M-x skk-customize} を +用意しています。これは SKK グループのユーザオプションのうち、よく使うも +のだけ抜粋して設定できるようにしたものです。 + +これは、モードラインの SKK インジケータをマウスの右ボタン(第3ボタン) +でクリックして表示されるメニューから「SKK をカスタマイズ(簡易版)」を選 +んで呼び出すこともできます。 +@end table @node カタカナ、英字入力の便法 @section カタカナ、英字入力の便法 この節では、カタカナや全英文字を入力するための、便利な方法を説明します。 -単純に各モードを用いる方法については前述しました。 -(@w{@pxref{入力モード, , カナモード、全英モード}}) +単純に各モードを用いる方法については前述 (@ref{入力モード}.) しました。 + @menu * かなモードからカタカナを入力:: * 全英文字の入力:: -* 領域の操作:: 領域の中の文字種を変換 +* 領域の操作:: * カタカナの見出し語:: -* 文脈に応じた自動モード切り替え:: プログラムでは、コメントの中だけ skk +* 文脈に応じた自動モード切り替え:: @end menu @node かなモードからカタカナを入力 @subsection かなモードからカタカナを入力 + @kindex q @cindex トグル変換 - -まず、かなモードに入ります。@kbd{Q} キーでいったん▽モードにして何かひらがなを入力し、 -最後に @kbd{q} をタイプすると、カタカナに変換され確定されます。 +まず、かなモードに入ります。 @code{Q} キーでいったん▽モードにして何かひらがな +を入力し、最後に @code{q} を打鍵すると、カタカナに変換され確定されます。 実際には、ひらがな以外からも変換できます。以下のようになります。 -@itemize @bullet -@item カタカナはひらがなへ -@item ひらがなはカタカナへ -@item 全英文字はアスキー文字へ -@item アスキー文字は全英文字へ +@itemize +@item +カタカナ は ひらがな へ + +@item +ひらがな は カタカナ へ + +@item +全英文字 は アスキー文字 へ + +@item +アスキー文字 は 全英文字 へ @end itemize -細かく言えば、@samp{▽} とポイント間の文字列の -種類@footnote{正確には @samp{▽} の次の位置にある文字列によって文字種を -判別しているので、途中で文字種類の違う文字が混在していても無視されます。} を -キーとして変換が行われます。 -かなモード、カナモード、どちらでも同じです。 +細かく言えば、▽マークとポイント間の文字列の種類 @footnote{正確には、▽マークの次の位置にある文字列によって文字種を判別 +しているので、途中で文字種類の違う文字が混在していても無視されます。} をキーとし +て変換が行われます。かなモード、カナモード、どちらでも同じです。 -このような変換を、トグル変換と呼びます。以下はトグル変換の例です。 +このような変換を @strong{トグル変換} と呼びます。以下はトグル変換の例です。 @example -@kbd{K a t a k a n a} +K a t a k a n a -@group ------- Buffer: foo ------ -▽かたかな@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽かたかな* + ------ Buffer: foo ------ -@kbd{q} +q -@group ------- Buffer: foo ------ -カタカナ@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + カタカナ* + ------ Buffer: foo ------ @end example このトグル変換を上手く利用することにより、かなモードのまま一時的にカタカ ナを入力したり、またその逆を行うことができます。こうすると、例えばひらが -な/カタカナが混在した文章を書くときに、その都度 @kbd{q} キーを押して入力 -モードを切り換える必要がありません -@footnote{全英文字とアスキー文字のトグルでの変換を行うこともできます。 -ただし、全英モードやアスキーモードでは @kbd{Q} やその他の大文字により▽ -モードに入ることができないので、かな ⇔ カナ のときと同様にトグル変換で -きるわけではありません。かなモード/カナモードにおいて、既に入力さ -れた全英文字、アスキー文字に対してトグル変換をするような設計になっていま -す。}。 +な/カタカナが混在した文章を書くときに、その都度 @code{q} キーを押して入力モー +ドを切り換える必要がありません @footnote{全英文字とアスキー文字のトグルでの変換を行うこともできます。 +ただし、全英モードやアスキーモードでは @code{Q} やその他の大文字により▽モード +に入ることができないので、かな ⇔ カナ のときと同様にトグル変換できるわけ +ではありません。かなモード/カナモードにおいて、既に入力された全英文字、 +アスキー文字に対してトグル変換をするような設計になっています。} 。 -領域を対象としたコマンドでも「かな←→カナ」のトグル変換を行うことができ -ます。(@w{@pxref{領域の操作}}) +領域を対象としたコマンド (@ref{領域の操作}.) でも「かな←→カナ」のトグル +変換を行うことができます。 @node 全英文字の入力 @subsection 全英文字の入力 -@kindex / -@kindex C-q -まず、かなモードに入ります。次に @kbd{/} をタイプすると SKK abbrev モー -ド@footnote{SKK abbrev モードでは @samp{is} @result{} @samp{インクリメン -タル・サーチ} のような変換を行うことができます。他の変換と同様、 -@key{SPC} を押すと変換モードに入ってしまいますので、 SKK abbrev モードか -らアスキー文字を入力するのは、一語のみの場合以外は不便です。 -(@w{@pxref{アスキー文字を見出し語とした変換}})} -に入りますのでアルファベット (アスキー文字) を入力します。 -アルファベットの入力後に -@kbd{C-q} @footnote{@kbd{C-q} は @code{skk-abbrev-mode-map} にて -特別な動作をするように定義されています。 -@xref{アスキー文字を見出し語とした変換}.}をタイプすることで @samp{▽}マー -クから @kbd{C-q} をタイプした位置までの間にあるアルファベットが全角アルフ -ァベットに変換されて確定されます。 +まず、かなモードに入ります。次に @code{/} を打鍵すると SKK abbrev モード @footnote{SKK abbrev モードでは @code{is} ⇒ 「インクリメンタル・サーチ」の +ような変換を行うことができます。他の変換と同様に @code{SPC} を押すと変換モード +に入ってしまいますので、 SKK abbrev モードからアスキー文字を入力するのは、 +一語のみの場合以外は不便です。 + +@ref{アスキー文字を見出し語とした変換}.} に +入りますのでアルファベット(アスキー文字)を入力します。アルファベットの +入力後に @code{C-q} を打鍵する @footnote{@code{C-q} は @code{skk-abbrev-mode-map} にて特別な動作をするように定義さ +れています。 + +@ref{アスキー文字を見出し語とした変換}.} ことで▽マークから @code{C-q} を打鍵した位 +置までの間にあるアルファベットが全角アルファベットに変換されて確定されま +す。 @example -@kbd{/ f i l e} +/ f i l e -@group ------- Buffer: foo ------ -▽file@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽file* + ------ Buffer: foo ------ -@kbd{C-q} +C-q -@group ------- Buffer: foo ------ -file@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + file* + ------ Buffer: foo ------ @end example なお、この変換を行うために、 @@ -2808,710 +3071,700 @@ @noindent のような辞書エントリを持つ必要はありません。なぜなら、辞書を参照せずにア -スキー文字を 1 文字ずつ全英文字に変換しているからです。 +スキー文字を1文字ずつ全英文字に変換しているからです。 @node 領域の操作 @subsection 領域の操作 -以下のコマンドを @kbd{M-x} により呼ぶことで、領域内の文字列を一括変換する -ことができます -@cindex Menu Bars -@cindex メニューバー -@footnote{メニューバーが使用できる環境では、メニューバーを使ってこれらの一括変換 -コマンドを呼び出すことができます。ただし @command{kakasi} がインストールされていない -場合は @command{kakasi} を利用する機能が灰色になり使用できません。 -@w{@xref{Menu Bars, ,メニューバー, emacs, GNU Emacs Manual}.}}。 +以下のコマンドを @code{M-x} により呼ぶことで @footnote{メニューバーが使用できる環境では、メニューバーを使ってこれら +の一括変換コマンドを呼び出すことができます。ただし @code{kakasi} がインストー +ルされていない場合は @code{kakasi} を利用する機能が灰色になり使用できません。 -@table @kbd -@item M-x skk-hiragana-region +@ref{Menu Bars,Menu Bars in GNU Emacs Manual,,emacs,}.} 、領域内の文字列を一 +括変換することができます。 + +@table @asis @kindex M-x skk-hiragana-region -@findex skk-hiragana-region +@cindex skk-hiragana-region +@item @kbd{M-x skk-hiragana-region} @tie{}@tie{}@tie{}@tie{}(@code{skk-hiragana-region}) -カタカナをひらがなへ変換。 +カタカナ を ひらがな へ変換。 -@item M-x skk-katakana-region @kindex M-x skk-katakana-region -@findex skk-katakana-region +@cindex skk-katakana-region +@item @kbd{M-x skk-katakana-region} @tie{}@tie{}@tie{}@tie{}(@code{skk-katakana-region}) -ひらがなをカタカナへ変換。 +ひらがな を カタカナ へ変換。 -@item M-x skk-latin-region @kindex M-x skk-latin-region -@findex skk-latin-region +@cindex skk-latin-region +@item @kbd{M-x skk-latin-region} @tie{}@tie{}@tie{}@tie{}(@code{skk-latin-region}) -全英文字をアスキー文字へ変換。 +全英文字 を アスキー文字 へ変換。 -@item M-x skk-jisx0208-latin-region @kindex M-x skk-jisx0208-latin-region -@findex skk-jisx0208-latin-region +@cindex skk-jisx0208-latin-region +@item @kbd{M-x skk-jisx0208-latin-region} @tie{}@tie{}@tie{}@tie{}(@code{skk-jisx0208-latin-region}) -アスキー文字を全英文字へ変換。 +アスキー文字 を 全英文字 へ変換。 @end table @cindex 逆引き -以下に紹介する「漢字から読みを求めるコマンド」は、外部プログラム @command{KAKASI} -@footnote{@uref{http://kakasi.namazu.org/, KAKASI - 漢字→かな(ローマ字)変換プログラム}} が必要です。 -@command{KAKASI} がインストールされていなければ使用することができません。 +以下に紹介する「漢字から読みを求めるコマンド」は、外部プログラム @code{KAKASI} @footnote{@uref{http://kakasi.namazu.org/, KAKASI - 漢字→かな(ローマ字)変換プログラム}}が +必要です。 @code{KAKASI} がインストールされていなければ使用することができません。 -@table @kbd -@item M-x skk-gyakubiki-region + +@table @asis @kindex M-x skk-gyakubiki-region -@findex skk-gyakubiki-region +@cindex skk-gyakubiki-region +@item @kbd{M-x skk-gyakubiki-region} @tie{}@tie{}@tie{}@tie{}(@code{skk-gyakubiki-region}) 漢字をひらがなへ変換。具体的な変換例をあげると、 @example -``漢字をひらがなへ変換。''@expansion{}``かんじをひらがなへへんかん。'' + 漢字をひらがなへ変換。 → かんじをひらがなへへんかん。 @end example -@noindent -のようになります。引数を渡して、 - -@kbd{C-u M-x skk-gyakubiki-region} +のようになります。引数を渡して @code{C-u M-x skk-gyakubiki-region} のように +すると、複数の候補がある場合に @code{@{ @}} で囲って表示します。例えば -のようにすると、複数の候補がある場合に、`@{@}' で囲って表示します。例え -ば - -@example -``中島''@expansion{}``@{なかしま|なかじま@}'' -@end example +@quotation +@code{中島 → @{なかしま|なかじま@}} +@end quotation -@noindent のようになります。 -送り仮名がある語は、送り仮名まで含めて領域に指定します (さもないと誤変換 -の原因となります)。 例えば、@samp{五月蝿い} について、送り仮名 @samp{い} -を含めずにこのコマンドを実行すると、@samp{ごがつはえ} に変換されてしまい -ます。 +送り仮名がある語は、送り仮名まで含めて領域に指定します(さもないと誤変 +換の原因となります)。 例えば「五月蝿い」について、送り仮名「い」を含め +ずにこのコマンドを実行すると「ごがつはえ」に変換されてしまいます。 -@item M-x skk-gyakubiki-and-henkan @kindex M-x skk-gyakubiki-and-henkan -@findex skk-gyakubiki-and-henkan +@cindex skk-gyakubiki-and-henkan +@item @kbd{M-x skk-gyakubiki-and-henkan} @tie{}@tie{}@tie{}@tie{}(@code{skk-gyakubiki-and-henkan}) -領域の漢字をひらがなへ変換し、これで得たひらがなを見出し語として -漢字変換を実行します。 +領域の漢字をひらがなへ変換し、これで得たひらがなを見出し語として漢字変 +換を実行します。 -@item M-x skk-gyakubiki-katakana-region @kindex M-x skk-gyakubiki-katakana-region -@findex skk-gyakubiki-katakana-region +@cindex skk-gyakubiki-katakana-region +@item @kbd{M-x skk-gyakubiki-katakana-region} @tie{}@tie{}@tie{}@tie{}(@code{skk-gyakubiki-katakana-region}) 漢字をカタカナへ変換。 -引数を渡して、@kbd{C-u M-x skk-gyakubiki-katakana-region} のようにすると、 -複数の候補がある場合に、`@{@}' で囲って表示します。 +引数を渡して @code{C-u M-x skk-gyakubiki-katakana-region} のようにすると、 +複数の候補がある場合に @code{@{ @}} で囲って表示します。 -@item M-x skk-hurigana-region @kindex M-x skk-hurigana-region -@findex skk-hurigana-region +@cindex skk-hurigana-region +@item @kbd{M-x skk-hurigana-region} @tie{}@tie{}@tie{}@tie{}(@code{skk-hurigana-region}) 漢字にふりがなを付ける。例えば、 @example -``漢字の脇に''@expansion{}``漢字[かんじ]の脇[わき]に'' + 漢字の脇に → 漢字[かんじ]の脇[わき]に @end example -@noindent -のようになります。引数を渡して @kbd{C-u M-x skk-hurigana-region} のよう -にすると、複数の候補がある場合に、`@{@}' で囲って表示します。 +のようになります。引数を渡して @code{C-u M-x skk-hurigana-region} のようにす +ると、複数の候補がある場合に @code{@{ @}} で囲って表示します。 -@item M-x skk-hurigana-katakana-region @kindex M-x skk-hurigana-katakana-region -@findex skk-hurigana-katakana-region +@cindex skk-hurigana-katakana-region +@item @kbd{M-x skk-hurigana-katakana-region} @tie{}@tie{}@tie{}@tie{}(@code{skk-hurigana-katakana-region}) 漢字にカタカナのふりがなを付ける。 -引数を渡して、@kbd{C-u M-x skk-hurigana-katakana-region} のようにすると、 -複数の候補がある場合に、`@{@}' で囲って表示します。 +引数を渡して @code{C-u M-x skk-hurigana-katakana-region} のようにすると、複 +数の候補がある場合に @code{@{ @}} で囲って表示します。 -@item M-x skk-romaji-region -@kindex M-x skk-hurigana-region -@findex skk-romaji-region +@kindex M-x skk-romaji-region +@cindex skk-romaji-region +@item @kbd{M-x skk-romaji-region} @tie{}@tie{}@tie{}@tie{}(@code{skk-romaji-region}) -漢字、ひらがな、カタカナをローマ字へ、全英文字をアスキー文字へ変換。標準 -では、ローマ字への変換様式はヘボン式です。例えば、 +漢字、ひらがな、カタカナをローマ字へ、全英文字をアスキー文字へ変換。標 +準では、ローマ字への変換様式はヘボン式です。例えば、 @example -``し'' @expansion{} ``shi'' + し → shi @end example -@noindent となります。 - @end table 以下のコマンドは、領域内の文字列を置き換える代わりに、変換結果をエコーエ リアに表示します。 -@itemize @bullet -@item @kbd{M-x skk-gyakubiki-message} +@table @asis @kindex M-x skk-gyakubiki-message -@findex skk-gyakubiki-message -@item @kbd{M-x skk-gyakubiki-katakana-message} +@cindex skk-gyakubiki-message +@item @kbd{M-x skk-gyakubiki-message} @tie{}@tie{}@tie{}@tie{}(@code{skk-gyakubiki-message}) @kindex M-x skk-gyakubiki-katakana-message -@findex skk-gyakubiki-katakana-message -@item @kbd{M-x skk-hurigana-message} +@cindex skk-gyakubiki-katakana-message +@item @kbd{M-x skk-gyakubiki-katakana-message} @tie{}@tie{}@tie{}@tie{}(@code{skk-gyakubiki-katakana-message}) @kindex M-x skk-hurigana-message -@findex skk-hurigana-message -@item @kbd{M-x skk-hurigana-katakana-message} +@cindex skk-hurigana-message +@item @kbd{M-x skk-hurigana-message} @tie{}@tie{}@tie{}@tie{}(@code{skk-hurigana-message}) @kindex M-x skk-hurigana-katakana-message -@findex skk-hurigana-katakana-message -@item @kbd{M-x skk-romaji-message} +@cindex skk-hurigana-katakana-message +@item @kbd{M-x skk-hurigana-katakana-message} @tie{}@tie{}@tie{}@tie{}(@code{skk-hurigana-katakana-message}) @kindex M-x skk-romaji-message -@findex skk-romaji-message -@end itemize - -@c http://mail.ring.gr.jp/skk/200110/msg00005.html -@defvr {ユーザ変数} skk-gyakubiki-jisyo-list +@cindex skk-romaji-message +@item @kbd{M-x skk-romaji-message} @tie{}@tie{}@tie{}@tie{}(@code{skk-romaji-message}) +@end table -関数 @code{skk-gyakubiki-region} はコマンド @command{kakasi} を呼び出し -ています。 -@command{kakasi} には漢字をひらがなへ変換する機能があり、この変換には環 -境変数 @env{KANWADICTPATH} で指定されている辞書を利用しています。 +@cindex KANWADICTPATH +@defvar skk-gyakubiki-jisyo-list -変数 @code{skk-gyakubiki-jisyo-list} を設定することによっ -て @command{kakasi} へ与える辞書を任意に追加することができます。 -以下のように設定して @command{kakasi} へ個人辞書 @code{skk-jisyo} を与え -ることによって辞書登録モードで登録したばかりの単語も @command{kakasi} に -よる逆引き変換の対象とすることができます。 +関数 @code{skk-gyakubiki-region} はコマンド @code{kakasi} を呼び出しています。 +@code{kakasi} には漢字をひらがなへ変換する機能があり、この変換には環境変 +数 @code{KANWADICTPATH} で指定されている辞書を利用しています。 + +変数 @code{skk-gyakubiki-jisyo-list} を設定することによって @code{kakasi} へ与え +る辞書を任意に追加することができます。 +以下のように設定して @code{kakasi} へ個人辞書 @code{skk-jisyo} を与えることによっ +て辞書登録モードで登録したばかりの単語も @code{kakasi} による逆引き変換の対 +象とすることができます。 @lisp (setq skk-gyakubiki-jisyo-list (list skk-jisyo)) @end lisp -@end defvr +@end defvar -@defvr {ユーザ変数} skk-romaji-*-by-hepburn +@defvar skk-romaji-*-by-hepburn -この変数の値を @code{nil} に設定すると、 -コマンド @code{skk-romaji-@{region|message@}} によるローマ字への変換様式 -に訓令式を用います。デフォルトは @code{t} です。 - -例えば、 +この変数の値を @code{nil} に設定すると、コマンド @code{skk-romaji-@{region|message@}} に +よるローマ字への変換様式に訓令式 @footnote{昭和29年12月9日付内閣告示第一号によれば、原則的に訓令式(日本式) +を用いるかのように記載されていますが、今日一般的な記載方法は、むしろヘボ +ン式であるようです。} を用います。標準設定は @code{t} です。 @example -``し'' @expansion{} ``si'' + し → si @end example - -@noindent -のようになります -@footnote{昭和 29 年 12 月 9 日付内閣告示第一号によれば、原則的に訓令式 -(日本式) を用いるかのように記載されていますが、今日一般的な記載方法は、 -むしろヘボン式であるようです。}。 - -@end defvr +@end defvar @node カタカナの見出し語 @subsection カタカナの見出し語 -@kbd{q} のタイプでかなモード、カナモードを度々切り替えて入力を続けていると、 -カナモードで誤って▼モードに入ってしまうことがあります。そのため、カナ -モードで▼モードに入った場合は、まず見出し語をひらがなに変換してから辞 -書の検索に入るよう設計されています。なお、この場合の送りあり変換での送 -り仮名は、カタカナになります。 +@code{q} の打鍵でかなモード、カナモードを度々切り替えて入力を続けていると、カ +ナモードで誤って▼モードに入ってしまうことがあります。そのため、カナモー +ドで▼モードに入った場合は、まず見出し語をひらがなに変換してから辞書の検 +索に入るよう設計されています。なお、この場合の送りあり変換での送り仮名は、 +カタカナになります。 @node 文脈に応じた自動モード切り替え @subsection 文脈に応じた自動モード切り替え -@cindex 文脈に応じた自動モード切り替え -@cindex @file{context-skk.el} -@kindex M-x context-skk-mode -@file{context-skk.el} は、編集中の文脈に応じて SKK の入力モードを自動的に -アスキーモードに切り替える等の機能を提供します。 +@cindex context-skk.el +@findex M-x context-skk-mode +@code{context-skk.el} は、編集中の文脈に応じて SKK の入力モードを自動的にアス +キーモードに切り替える等の機能を提供します。 -@file{context-skk.el} をロードするには、@file{~/.emacs.d/init.el} に +@code{context-skk.el} をロードするには @code{~/.emacs.d/init.el} に @lisp -@group (add-hook 'skk-load-hook - (lambda () - (require 'context-skk))) -@end group + (lambda () + (require 'context-skk))) @end lisp +@noindent と書いてください。 あるプログラミング言語のプログラムを書いているとき、日本語入力の必要があ るのは一般に、そのプログラミング言語の文字列中かコメント中に限られます。 たとえば Emacs Lisp で日本語入力の必要があるのは + @lisp -@group "文字列" ;; コメント -@end group @end lisp -といった個所だけでしょう。 -文字列・コメントの「外」を編集するときは、多くの場合は日本語入力は必要あ -りません。 -現在の文字列・コメントの「外」で編集開始と同時に(skk がオンであれば) +@noindent +といった個所だけでしょう。文字列・コメントの @strong{外} を編集するときは、多く +の場合は日本語入力は必要ありません。 + +現在の文字列・コメントの @strong{外} で編集開始と同時に(skk がオンであれば) skk の入力モードをアスキーモードに切り替えます。 エコーエリアに @example -@group -------------------- Echo Area -------------------- [context-skk] 日本語入力 off -------------------- Echo Area -------------------- -@end group @end example -と表示され、アスキーモードに切り替わったことが分かります。 -これにより、文字列・コメントの「外」での編集を開始するにあたって、日本語 -入力が on になっていたために発生する入力誤りとその修正操作を回避すること -ができます。 +@noindent +と表示され、アスキーモードに切り替わったことが分かります。これにより、文 +字列・コメントの @strong{外} での編集を開始するにあたって、日本語入力が on にな +っていたために発生する入力誤りとその修正操作を回避することができます。 上記の機能は context-skk-mode というマイナーモードとして実装されており -@kbd{M-x context-skk-mode} でオン/オフを制御できます。 -オンの場合、モードラインのメジャーモード名の隣に「;▽」と表示されます。 +@code{M-x context-skk-mode} でオン/オフを制御できます。オンの場合、モードライ +ンのメジャーモード名の隣に「;▽」と表示されます。 + +@defvar context-skk-programming-mode -@defvr {ユーザ変数} context-skk-programming-mode context-skk が「プログラミングモード」と見做すメジャーモード。 -@end defvr +@end defvar + +@defvar context-skk-mode-off-message -@defvr {ユーザ変数} context-skk-mode-off-message アスキーモードに切り替わった瞬間にエコーエリアに表示するメッセージ。 -@end defvr +@end defvar @node 補完 @section 補完 -@cindex 見出し語の補完 -@cindex 読みの補完 -@cindex 補完 -読みの前半だけを入力して @key{TAB} を押せば残りを自動的に補ってくれる、 -これが補完です。 Emacs ユーザにはおなじみの機能が DDSKK でも使えます。 +読みの前半だけを入力して @code{TAB} を押せば残りを自動的に補ってくれる、これが +補完です。 Emacs ユーザにはおなじみの機能が DDSKK でも使えます。 + +よく使う長い語を効率良く入力するには、アルファベットの略語を登録する方法 +もあります。 + +@ref{アスキー文字を見出し語とした変換}. + @menu -* 読みの補完:: 「かか」 + Tab -> 「かかみがはらし」 ! -* 補完しながら変換:: 「かしたん」 + M-SPC -> 「瑕疵担保責任」 !! -* 動的補完:: 入力しながら候補を表示 +* 読みの補完:: +* 補完しながら変換:: +* 動的補完:: @end menu -よく使う長い語を効率良く入力するには、アルファベットの略語を登録する方法もあります。 -(@w{@pxref{アスキー文字を見出し語とした変換}}) - @node 読みの補完 @subsection 読みの補完 -@kindex @key{TAB} -▽モードで @key{TAB} を押すと、見出し語(▽マークから、ポイントまでの文字 -列)に対する補完が行われます@footnote{細かい説明です。 @key{TAB} を押す直 -前に▽モードで入力された文字列を X と呼ぶことにします。このとき、個人辞書 -の送りなしエントリの中から「先頭が X と一致し」かつ「長さが X よりも長い -見出し語」を検索して、そのような語が該当すれば X の代わりに表示します。}。 -見出し語補完は、個人辞書の内、送りなしエントリに対して行われます。 -個人辞書に限っているのは、共有辞書では先頭の文字を共通にする見出し語が多すぎて、 -望みの補完が行える確率が低いためです。 +@kindex TAB +▽モードで @code{TAB} を押すと、見出し語(▽マークからポイントまでの文字列)に +対する補完 @footnote{細かい説明です。 @code{TAB} を押す直前に▽モードで入力された文字列を X と +呼ぶことにします。このとき、個人辞書の送りなしエントリの中から「先頭が X と +一致し」かつ「長さが X よりも長い見出し語」を検索して、そのような語が該当 +すれば X の代わりに表示します。} が行われます。見出し語補完は、個人辞書のうち送りなし +エントリに対して行われます。個人辞書に限っているのは、共有辞書では先頭の +文字を共通にする見出し語が多すぎて、望みの補完が行える確率が低いためです。 @kindex , @kindex . -次の読みの候補を表示するには、@kbd{.} (ピリオド) を、戻る時には @kbd{,} -(コンマ)を押します。その読みで別の語を出すには、いつものように @key{SPC} を -押します。 +次の読みの候補を表示するには @code{.} (ピリオド)を、戻る時には @code{,} (コンマ) +を押します。その読みで別の語を出すには、いつものように @code{SPC} を押します。 例を見てみましょう。実際の動作は、個人辞書の内容によって異なります。 - @example -@kbd{S a} - -@group ------- Buffer: foo ------ -▽さ@point{} ------- Buffer: foo ------ -@end group +S a -@key{TAB} + ------ Buffer: foo ------ + ▽さ* + ------ Buffer: foo ------ -@group ------- Buffer: foo ------ -▽さとう@point{} ------- Buffer: foo ------ -@end group +TAB -@kbd{.} + ------ Buffer: foo ------ + ▽さとう* + ------ Buffer: foo ------ -@end example +. -@example -@group ------- Buffer: foo ------ -▽さいとう@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽さいとう* + ------ Buffer: foo ------ -@kbd{,} +, -@group ------- Buffer: foo ------ -▽さとう@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽さとう* + ------ Buffer: foo ------ -@key{SPC} +SPC -@group ------- Buffer: foo ------ -▼佐藤@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼佐藤* + ------ Buffer: foo ------ -@kbd{C-j} +C-j -@group ------- Buffer: foo ------ -佐藤@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 佐藤* + ------ Buffer: foo ------ @end example -補完される見出し語がどのような順で表示されるかと言うと「最近使われた語から」 -となります。例えば、@samp{斉藤}、@samp{佐藤} の順で変換した後、@samp{さ} をキー -にして見出し語の補完を行うと、最初に @samp{さとう} が、その次に -@samp{さいとう} が補完されます。これは、個人辞書では、最近使われたエントリほど -上位に来るようになっているためです。@footnote{@ref{辞書の書式}} +補完される見出し語がどのような順で表示されるかと言うと「最近使われた語か +ら」となります。例えば「斉藤」、「佐藤」の順で変換した後、「さ」をキーに +して見出し語の補完を行うと、最初に「さとう」が、その次に「さいとう」が補 +完されます。これは、個人辞書では、最近使われたエントリほど上位に来るよう +になっている (@ref{辞書の書式}.) ためです。 + +いったん @code{SPC} を入力して▼モードに入ると、以後は見出し語補完は行われませ +ん。 -いったん @key{SPC} を入力して▼モードに入ると、以後は見出し語補完は行われません。 +@kindex C-u TAB +また、 @code{.} の代わりに @code{C-u TAB} を入力すると、現在の候補に対して補完をし +ます。上の例では「さ」に対し「さとう」が補完された時に @code{C-u TAB} を押すと、 +以後の補完は「さとう」を含む語(例えば「さとうせんせい」など)について行 +われます。 -@kindex @kbd{C-u @key{TAB}} -また、@kbd{.} の代わりに @kbd{C-u @key{TAB}} を入力 -すると、現在の候補に対して補完をします。上の例では @samp{さ} に対し、 -@samp{さとう} が補完された時に @kbd{C-u @key{TAB}} を押すと、 -以後の補完は、@samp{さとう} を含む語 (例えば、@samp{さとうせんせい}など) -について行われます。 +@defvar skk-completion-prog-list -@defvr {ユーザ変数} skk-completion-prog-list -補完関数、補完対象の辞書を決定するためのリスト。 -デフォルトは以下のとおり。 +補完関数、補完対象の辞書を決定するためのリスト。標準設定は以下のとお +り。 @lisp -@group - '((skk-comp-by-history) - (skk-comp-from-jisyo skk-jisyo) - (skk-look-completion)) -@end group +'((skk-comp-by-history) + (skk-comp-from-jisyo skk-jisyo) + (skk-look-completion)) @end lisp +@end defvar -@end defvr +@defvar skk-comp-circulate -@defvr {ユーザ変数} skk-comp-circulate -@kbd{.} (ピリオド)で次の見出し語候補を、@kbd{,} (コンマ)で前の見出し -語候補を表示するところ、候補が尽きていればデフォルト @code{nil} では「○ -○で補完すべき見出し語は他にありません」とエコーエリアに表示して動作が止 -まります。この変数が @code{non-nil} であれば当初の見出し語を再び表示して -見出し語補完を再開します。 -@end defvr +@code{.} (ピリオド)で次の見出し語候補を、 @code{,} (コンマ)で前の見出し語候補 +を表示するところ、候補が尽きていれば標準設定 @code{nil} では「○○で補完す +べき見出し語は他にありません」とエコーエリアに表示して動作が止まります。 +この変数が @code{non-nil} であれば当初の見出し語を再び表示して見出し語補完を +再開します。 +@end defvar -@defvr {ユーザ変数} skk-try-completion-char -見出し語補完を開始するキーキャラクタです。デフォルトは @key{TAB} です。 -@end defvr +@defvar skk-try-completion-char -@defvr {ユーザ変数} skk-next-completion-char -次の見出し語候補へ移るキーキャラクタです。デフォルトはピリオド @kbd{.} です。 -@end defvr +見出し語補完を開始するキーキャラクタです。標準設定は @code{TAB} です。 +@end defvar -@defvr {ユーザ変数} skk-previous-completion-char -前の見出し語候補へ戻るキーキャラクタです。デフォルトはコンマ @kbd{,} です。 -@end defvr +@defvar skk-next-completion-char + +次の見出し語候補へ移るキーキャラクタです。標準設定はピリオド @code{.} です。 +@end defvar + +@defvar skk-previous-completion-char + +前の見出し語候補へ戻るキーキャラクタです。標準設定はコンマ @code{,} です。 +@end defvar @cindex backtab @kindex SHIFT TAB -@defvr {ユーザ変数} skk-previous-completion-use-backtab -@code{Non-nil} であれば、前の見出し語候補へ戻る動作を @kbd{@key{SHIFT}+@key{TAB}} で -も可能とします。デフォルトは @code{t} です。 -この機能の有効化/無効化の切り替えは、ファイル @file{~/.skk} を書き換えて Emacs を -再起動してください。 -@end defvr - -@defvr {ユーザ変数} skk-previous-completion-backtab-key -@kbd{@key{SHIFT}+@key{TAB}} が発行する key event です。Emacs の種類/実行環境 -によって異なります。 -@end defvr +@defopt skk-previous-completion-use-backtab + +@code{Non-nil} であれば、前の見出し語候補へ戻る動作を @code{SHIFT + TAB} でも可能 +とします。標準設定は @code{t} です。この機能の有効化/無効化の切り替えは、 +ファイル @code{~/.skk} を書き換えて Emacs を再起動してください。 +@end defopt + +@defvar skk-previous-completion-backtab-key + +@code{SHIFT + TAB} が発行する key event です。Emacs の種類/実行環境によって +異なります。 +@end defvar @defun skk-comp-lisp-symbol &optional PREDICATE + この関数をリスト @code{skk-completion-prog-list} へ追加すると、Lisp symbol 名 の補完を行います。 @lisp -@group (add-to-list 'skk-completion-prog-list '(skk-comp-lisp-symbol) t) -@end group @end lisp - @end defun @node 補完しながら変換 @subsection 補完しながら変換 -@kindex M-@key{SPC} +@kindex M-SPC 前節で見出し語の補完について述べました。本節では、見出し語の補完動作を行 -った後、@key{SPC} を入力し、▼モードに入るまでの動作を一回の操作で行 -う方法について説明します。 +った後、 @code{SPC} を打鍵し、▼モードに入るまでの動作を一回の操作で行う方法に +ついて説明します。 -やり方は簡単。@key{TAB}・@key{SPC} と打鍵していたところを @kbd{M-@key{SPC}} に -換えると、見出し語を補完した上で変換を開始します。 +やり方は簡単。 @code{TAB} ・ @code{SPC} と打鍵していたところを @code{M-SPC} に換えると、 +見出し語を補完した上で変換を開始します。 この方法によると、補完される見出し語があらかじめ分かっている状況では、キー -入力を一回分省略できるので、読みが長い見出し語の単語を連続して入力する場合 -などに威力を発揮します。 +入力を一回分省略できるので、読みが長い見出し語の単語を連続して入力する場 +合などに威力を発揮します。 @example -@group -@kbd{K a s i t a n n p o s e k i n i n n} +K a s i t a n n p o s e k i n i n n ------- Buffer: foo ------ -▽かしたんぽせきにん@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽かしたんぽせきにん* + ------ Buffer: foo ------ -@group -@key{SPC}, @key{RET} +SPC RET ------- Buffer: foo ------ -瑕疵担保責任@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 瑕疵担保責任* + ------ Buffer: foo ------ -@group -@kbd{K a} +K a ------- Buffer: foo ------ -▽か@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽か* + ------ Buffer: foo ------ -@group -@kbd{M-@key{SPC}} +M-SPC ------- Buffer: foo ------ -▼瑕疵担保責任@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼瑕疵担保責任* + ------ Buffer: foo ------ @end example -@defvr {ユーザ変数} skk-start-henkan-with-completion-char +@defvar skk-start-henkan-with-completion-char -デフォルトは @kbd{M-@key{SPC}} です。 - -@end defvr +標準設定は @code{M-SPC} です。 +@end defvar @node 動的補完 @subsection 動的補完 -@cindex @file{skk-dcomp.el} -▽モードでは、@key{TAB} を押さなくとも、文字を入力する都度、自動的に見 -出し語補完の読みを表示させる事ができます。この機能を以下「動的補完」と呼 -びます。類似の機能としては、ウェブブラウザの URL の入力や、Microsoft Excel の -セル入力の自動補完@footnote{同じ列に既に入力している文字列があったときに -それを参照して補完しようとする機能}をイメージすると分かりやすいかも知れ -ません。動的補完も、個人辞書の送りなしエントリに対してのみ行なわれます。 +▽モードでは @code{TAB} を押さなくとも、文字を入力する都度、自動的に見出し語補 +完の読みを表示させる事ができます。この機能を以下「動的補完」と呼びます。 +類似の機能としては、ウェブブラウザの URL の入力や、Microsoft Excel のセル +入力の自動補完 @footnote{同じ列に既に入力している文字列があったときにそれを参照して補完 +しようとする機能} をイメージすると分かりやすいかも知れません。動 +的補完も、個人辞書の送りなしエントリに対してのみ行なわれます。 -動的補完を利用するには @file{~/.skk} に次の式を書きましょう。 +動的補完を利用するには @code{~/.skk} に次の式を書きましょう。 @lisp (setq skk-dcomp-activate t) @end lisp -例を見てみましょう。実際の動作は、個人辞書の内容によって左右されます。 @point{} は -ポイント位置を表します。 +例を見てみましょう。実際の動作は、個人辞書の内容によって左右されます。 +@code{*} はポイント位置を表します。 @example -@group - -@kbd{H o} +H o ----------------- Buffer: foo ------------------ -▽ほ@point{}んとう ----------------- Buffer: foo ------------------ - -@end group + ---------------- Buffer: foo ------------------ + ▽ほ*んとう + ---------------- Buffer: foo ------------------ @end example -face が使える環境では、@samp{んとう}の部分が異なる face で表示され、動的 -補完機能によって補完された部分であることを示します。 +face が使える環境では「んとう」の部分が異なる face で表示され、動的補完機 +能によって補完された部分であることを示します。 -自動的に補完された見出し語が自分の意図したものであれば、 @key{TAB} を押 -すことでポイント位置を動かし、補完された見出し語を選択することができます。 +自動的に補完された見出し語が自分の意図したものであれば @code{TAB} を押すことで +ポイント位置を動かし、補完された見出し語を選択することができます。 @example -@group -@key{TAB} +TAB ----------------- Buffer: foo ------------------ -▽ほんとう@point{} ----------------- Buffer: foo ------------------ -@end group + ---------------- Buffer: foo ------------------ + ▽ほんとう* + ---------------- Buffer: foo ------------------ @end example -この状態から @key{SPC} を押して変換するなり、@kbd{q} を押してカタカナに -するなり、DDSKK 本来の動作を何でも行うことができます。 +この状態から @code{SPC} を押して変換するなり、 @code{q} を押してカタカナにするなり、 +DDSKK 本来の動作を何でも行うことができます。 補完された見出し語が自分の意図したものでない場合は、かまわず次の入力を続 けて下さい。補完された部分を無視したかのように動作します。 @example -@group - -@kbd{H o} - ----------------- Buffer: foo ------------------ -▽ほ@point{}んとう ----------------- Buffer: foo ------------------ +H o -@kbd{k a} + ---------------- Buffer: foo ------------------ + ▽ほ*んとう + ---------------- Buffer: foo ------------------ ----------------- Buffer: foo ------------------ -▽ほか@point{}ん ----------------- Buffer: foo ------------------ +k a -@end group + ---------------- Buffer: foo ------------------ + ▽ほか*ん + ---------------- Buffer: foo ------------------ @end example 補完されない状態が自分の意図したものである場合も、補完された部分を単に無 -視するだけで OK です。下記の例では、@samp{ほ} を見出し語とした変換を行っ -ています。 +視するだけで OK です。下記の例では「ほ」を見出し語とした変換を行っていま +す。 @example -@group - -@kbd{H o} +H o ----------------- Buffer: foo ------------------ -▽ほ@point{}んとう ----------------- Buffer: foo ------------------ + ---------------- Buffer: foo ------------------ + ▽ほ*んとう + ---------------- Buffer: foo ------------------ -@key{SPC} +SPC ----------------- Buffer: foo ------------------ -▼保 ----------------- Buffer: foo ------------------ -@end group + ---------------- Buffer: foo ------------------ + ▼保 + ---------------- Buffer: foo ------------------ @end example -補完された状態から @key{BS} を押すと、消された補完前の見出し語から再度補 -完動作を行います。 +補完された状態から @code{BS} を押すと、消された補完前の見出し語から再度補完動 +作を行います。 @example -@group +H o -@kbd{H o} - ----------------- Buffer: foo ------------------ -▽ほ@point{}んとう ----------------- Buffer: foo ------------------ + ---------------- Buffer: foo ------------------ + ▽ほ*んとう + ---------------- Buffer: foo ------------------ -@kbd{k a} +k a ----------------- Buffer: foo ------------------ -▽ほか@point{}ん ----------------- Buffer: foo ------------------ + ---------------- Buffer: foo ------------------ + ▽ほか*ん + ---------------- Buffer: foo ------------------ -@key{BS} +BS ----------------- Buffer: foo ------------------ -▽ほ@point{}んとう ----------------- Buffer: foo ------------------ -@end group + ---------------- Buffer: foo ------------------ + ▽ほ*んとう + ---------------- Buffer: foo ------------------ @end example +@defvar skk-dcomp-activate -@defvr {ユーザ変数} skk-dcomp-activate - -この変数の値が @code{Non-nil} であれば、カーソル位置に関わらず常に動的補完が有効となります。 -値がシンボル @code{eolp} であれば、カーソルが行末にあるときに限って動的補完が有効となります。 -値が @code{nil} であれば、動的補完機能は無効となります。 +この変数の値が @code{Non-nil} であれば、カーソル位置に関わらず常に動的補完が +有効となります。値がシンボル @code{eolp} であれば、カーソルが行末にあるとき +に限って動的補完が有効となります。値が @code{nil} であれば、動的補完機能は無 +効となります。 +@end defvar -@end defvr - -@defvr {ユーザ変数} skk-dcomp-face +@defvar skk-dcomp-face この変数の値はフェイスであり、このフェイスによって動的に補完された部分が -装飾されます。標準は ``DarkKhaki'' です。 - -@end defvr +装飾されます。標準は DarkKhaki です。 +@end defvar -@defvr {ユーザ変数} skk-dcomp-multiple-activate +@defopt skk-dcomp-multiple-activate -@b{XEmacs では動作しません。} +@strong{XEmacs では動作しません。} -@code{Non-nil} であれば、動的補完の候補をインラインに複数表示します -@footnote{現在は候補群の右側1カラムのフェイスがデフォルトに戻る、という制約があります。}。 +@code{Non-nil} であれば、動的補完の候補をインラインに複数表示 @footnote{現在は候補群の右側1カラムのフェイスが標準設定に戻る、という +制約があります。} します。 @example -@group ---------------- Buffer: foo ------------------ -▽ほ@point{}んとう +▽ほ*んとう  ほんとう  ほかん  ほっかいどう  ほうほう - @dots{} + : ---------------- Buffer: foo ------------------ -@end group @end example -@kindex @key{TAB} -@kindex , -@kindex . -@kindex SHIFT TAB +候補の選択には @code{TAB} 又は @code{SHIFT + TAB} を押します。 +また、普通の補完 (@ref{読みの補完}.) と同様に @code{.} (ピリオド)と @code{,} (コンマ)も +利用できます。 +@end defopt + +@defvar skk-dcomp-multiple-rows + +動的補完の候補を複数表示する場合の表示行数。標準は 7。 +@end defvar + +@defvar skk-dcomp-multiple-face + +動的補完の複数表示群のフェイス。上記例では「ほ」のフェイス。 +@end defvar + +@defvar skk-dcomp-multiple-trailing-face + +動的補完の複数表示群の補完部分のフェイス。上記例では「んとう」、「かん」 +「っかいどう」、「うほう」のフェイス。 +@end defvar + +@defvar skk-dcomp-multiple-selected-face + +動的補完の複数表示群の選択対象のフェイス。上記例では @code{TAB} を押すたびに +「ほんとう」、「ほかん」、「ほっかいどう」と選択位置が移ります。その現 +在選択位置に適用するフェイスです。 +@end defvar + +@node 便利な変換、その他の変換 +@section 便利な変換、その他の変換 + + +@menu +* 単漢字変換:: +* 候補の絞り込み:: +* 接頭辞・接尾辞:: +* 数値変換:: +* アスキー文字を見出し語とした変換:: +* 今日の日付の入力:: +* プログラム実行変換:: +* 空白・改行・タブを含んだ見出し語の変換:: +* カタカナ変換:: +* サ変動詞変換:: +* 異体字へ変換する:: +* ファンクションキーの使い方:: +@end menu + +@node 単漢字変換 +@subsection 単漢字変換 + +ファイル @code{skk-tankan.el} を読み込むことによって単漢字変換が可能となります。 +候補は総画数の昇順でソートして表示します。 -候補の選択には @key{TAB} 又は @kbd{@key{SHIFT}+@key{TAB}} を押します。また、 -普通の補完と同様に @kbd{.} (ピリオド) と @kbd{,} (コンマ) も利用できま -す。@w{@ref{読みの補完}} +単漢字変換を使うには設定が必要ですが、先に例を見てみましょう。▽モードの +最後の文字に @code{@@} を付して変換を開始してください。 -@end defvr +@lisp +T a n @@ -@defvr {ユーザ変数} skk-dcomp-multiple-rows + ----- Buffer: foo ----- + ▽たん@@* + ----- Buffer: foo ----- -動的補完の候補を複数表示する場合の表示行数。標準は 7。 +SPC -@end defvr + ----- Buffer: foo ----- + ▼丹* + ----- Buffer: foo ----- -@defvr {ユーザ変数} skk-dcomp-multiple-face + ----- Echo Area ----- + 4画(丶部3画) + ----- Echo Area ----- -動的補完の複数表示群のフェイス。上記例では「ほ」のフェイス。 +SPC -@end defvr + ----- Buffer: foo ----- + ▼反* + ----- Buffer: foo ----- -@defvr {ユーザ変数} skk-dcomp-multiple-trailing-face + ----- Echo Area ----- + 4画(又部2画) + ----- Echo Area ----- -動的補完の複数表示郡の補完部分のフェイス。上記例では「んとう」、「かん」 -「っかいどう」、「うほう」のフェイス。 +SPC -@end defvr + ----- Buffer: foo ----- + ▼旦* + ----- Buffer: foo ----- -@defvr {ユーザ変数} skk-dcomp-multiple-selected-face + ----- Echo Area ----- + 5画(日部1画) + ----- Echo Area ----- -動的補完の複数表示郡の選択対象のフェイス。上記例では @key{TAB} を押すたび -に「ほんとう」、「ほかん」、「ほっかいどう」と選択位置が移ります。その現在 -選択位置に適用するフェイスです。 +SPC -@end defvr + ----- Buffer: foo ----- + ▼但* + ----- Buffer: foo ----- -@node 便利な変換、その他の変換 -@section 便利な変換、その他の変換 + ----- Echo Area ----- + 7画(人部5画) + ----- Echo Area ----- -@menu -* 単漢字変換:: 一文字だけ漢字に変換 -* 候補の絞り込み:: 「わ」だけど「魏志倭人伝」の「倭」が欲しい -* 接頭辞・接尾辞:: 接頭辞・接尾辞だけを変換 -* 数値変換:: 数を含む文字列の変換。 -* アスキー文字を見出し語とした変換:: 「wg」 -> 「ワーキンググループ」 -* 今日の日付の入力:: 今日の日付を一発入力。 -* プログラム実行変換:: Emacs Lisp プログラムを使った変換。 -* 空白・改行・タブを含んだ見出し語の変換:: -* カタカナ変換:: 個人辞書でカタカナ語を育てられます。 -* サ変動詞変換:: サ行変格活用動詞の送りあり変換が可能です -* 異体字へ変換する:: -* ファンクションキーの使い方:: -@end menu +SPC -@node 単漢字変換 -@subsection 単漢字変換 -@cindex @file{skk-tankan.el} -@cindex 単漢字 + ----- Buffer: foo ----- + ▼* + ----- Buffer: foo ----- + + ----- Buffer: *候補* ----- + A:坦;8画(土部5画) + S:担;8画(手部5画) + D:単;9画(十部7画) + F:彖;9画(彑部6画) + J:炭;9画(火部5画) + K:眈;9画(目部4画) + L:胆;9画(肉部5画) + [残り 50+++++] +----- Buffer: *候補* ----- +@end lisp + +以上のとおり、総画数の昇順でソートされた候補が次々に表示されます。 -ファイル @file{skk-tankan.el} を読み込むことによって単漢字変換が可能とな -ります。候補は総画数の昇順でソートして表示します。 @menu * 検索キーの設定:: @@ -3521,461 +3774,321 @@ * 部首の読みによる単漢字変換:: @end menu -単漢字変換を使うには設定が必要ですが、先に例を見てみましょう。 - -▽モードの最後の文字に @kbd{@@} を付加してから変換を開始してください。 - -@example -T a n @@ - -@group ------ Buffer: foo ----- -▽たん@@@point{} ------ Buffer: foo ----- -@end group - -@key{SPC} - -@group ------ Buffer: foo ----- -▼丹@point{} ------ Buffer: foo ----- -@end group - -@group ------ Echo Area ----- -4画(丶部3画) ------ Echo Area ----- -@end group - -@key{SPC} - -@group ------ Buffer: foo ----- -▼反@point{} ------ Buffer: foo ----- -@end group - -@group ------ Echo Area ----- -4画(又部2画) ------ Echo Area ----- -@end group - -@key{SPC} - -@group ------ Buffer: foo ----- -▼旦@point{} ------ Buffer: foo ----- -@end group - -@group ------ Echo Area ----- -5画(日部1画) ------ Echo Area ----- -@end group - -@key{SPC} - -@group ------ Buffer: foo ----- -▼但@point{} ------ Buffer: foo ----- -@end group - -@group ------ Echo Area ----- -7画(人部5画) ------ Echo Area ----- -@end group - -@key{SPC} - -@group ------ Buffer: foo ----- -▼@point{} ------ Buffer: foo ----- -@end group - -@group ------ Buffer: *候補* ----- -A:坦;8画(土部5画) -S:担;8画(手部5画) -D:単;9画(十部7画) -F:彖;9画(彑部6画) -J:炭;9画(火部5画) -K:眈;9画(目部4画) -L:胆;9画(肉部5画) -[残り 50+++++] ------ Buffer: *候補* ----- -@end group -@end example - -以上のとおり、総画数の昇順でソートされた候補が次々に表示されます。 - @node 検索キーの設定 @subsubsection 検索キーの設定 -デフォルトの検索キーは @kbd{@@} です。 -DDSKK の標準設定ではキー @kbd{@@} は関数 @code{skk-today} の実行に割り -当てられていますが、DDSKK 14.2 からは特段の設定なしに▽モードで @kbd{@@} の -タイプが可能となりました。 - -@defvr {ユーザ変数} skk-tankan-search-key -単漢字変換の検索キーは、変数 @code{skk-tankan-search-key} で変更できます。 -以下は、検索キーを @kbd{!} へと変更する例です。 +標準設定の検索キーは @code{@@} です。DDSKK の標準設定ではキー @code{@@} は +関数 @code{skk-today} の実行に割り当てられていますが、DDSKK 14.2 からは特段の +設定なしに▽モードで @code{@@} の打鍵が可能となりました。 + +@defopt skk-tankan-search-key + +単漢字変換の検索キー。以下は、検索キーを @code{!} へと変更する例です。 @lisp (setq skk-tankan-search-key ?!) @end lisp - -@end defvr +@end defopt @node 辞書の設定 @subsubsection 辞書の設定 -@findex skk-tankan-search +DDSKK 14.2 からは標準で変数 @code{skk-search-prog-list} に @code{skk-tankan-search} が +含まれています。DDSKK 14.1 を利用の方、ご自身で @code{skk-search-prog-list} を +設定する方は以下の解説を参考にしてください。 -DDSKK 14.2 からは、標準で変数 @code{skk-search-prog-list} に -@code{skk-tankan-search} が含まれています。 -DDSKK 14.1 を利用の方、ご自身で @code{skk-search-prog-list} を設定する方は -以下の解説を参考にしてください。 +@code{skk-tankan.el} には、漢字の部首とその中での画数のデータのみが入っていま +す。読みのデータは、普通の辞書ファイルを使います。 -@file{skk-tankan.el} には、漢字の部首とその中での画数の -データのみが入っています。読みのデータは、普通の辞書ファイルを使います。 - -単漢字変換の辞書の設定は、変数 @code{skk-search-prog-list} に以下の形式で -要素を追加します。 +単漢字変換の辞書の設定は、変数 @code{skk-search-prog-list} に以下の形式で要素 +を追加します。 @lisp -(skk-tankan-search 'function . args) +(skk-tankan-search 'function . args) @end lisp -@b{「確定変換」}を併用する場合は、@code{skk-search-prog-list} の -先頭の要素は @code{skk-search-kakutei-jisyo-file} でなければいけませんので、 +@strong{確定変換} を併用する場合は、 @code{skk-search-prog-list} の先頭の要素は + @code{skk-search-kakutei-jisyo-file} でなければいけませんので、 @code{skk-search-prog-list} の2番目の要素に @code{skk-tankan-search} を追加します。 @lisp -@group ;; skk-search-prog-list の2番目の要素に skk-tankan-search を追加する (setq skk-search-prog-list (cons (car skk-search-prog-list) (cons '(skk-tankan-search 'skk-search-jisyo-file skk-large-jisyo 10000) (cdr skk-search-prog-list)))) -@end group @end lisp -なお、確定変換を使用しない場合は、 @code{skk-search-prog-list} の要素 -の先頭が @code{skk-tankan-search} でも大丈夫です。 +なお、確定変換を使用しない場合は、 @code{skk-search-prog-list} の要素の先頭 +が @code{skk-tankan-search} でも大丈夫です。 @lisp -@group (add-to-list 'skk-search-prog-list '(skk-tankan-search 'skk-search-jisyo-file skk-large-jisyo 10000)) -@end group @end lisp -@xref{辞書の検索方法の設定}. +@ref{辞書の検索方法の設定}. @node 総画数による単漢字変換 @subsubsection 総画数による単漢字変換 -@cindex 画数変換 -@kindex C-u 総画数 M-x skk-tankan -▽モードで総画数を入力して最後に @kbd{@@} を付加してから変換を開始します -@footnote{@kbd{C-u 総画数 M-x skk-tankan} でも可。}。 +@kindex C-u 総画数 M-x skk-tankan +▽モードで総画数を入力して最後に @code{@@} を付してから変換を開始します。 +@code{C-u 総画数 M-x skk-tankan} でも可能です。 -@example +@lisp Q 1 0 @@ -@group ------ Buffer: foo ----- -▽10@@@point{} ------ Buffer: foo ----- -@end group - -@key{SPC} - -@group ------ Buffer: *候補* ----- -A:倹;10画(人部8画) -S:倦;10画(人部8画) -D:個;10画(人部8画) -F:候;10画(人部8画) -J:倖;10画(人部8画) -K:借;10画(人部8画) -L:修;10画(人部8画) -[残り 532+++++++] ------ Buffer: *候補* ----- -@end group - -@end example + ----- Buffer: foo ----- + ▽10@@* + ----- Buffer: foo ----- + +SPC + + ----- Buffer: *候補* ----- + A:倹;10画(人部8画) + S:倦;10画(人部8画) + D:個;10画(人部8画) + F:候;10画(人部8画) + J:倖;10画(人部8画) + K:借;10画(人部8画) + L:修;10画(人部8画) + [残り 532+++++++] + ----- Buffer: *候補* ----- +@end lisp @node 部首による単漢字変換 @subsubsection 部首による単漢字変換 -@cindex 部首変換 -@kindex M-x skk-tankan -▽モードで @kbd{@@} を2つ重ねて変換を開始すると、部首による単漢字変換が -できます@footnote{@kbd{M-x skk-tankan} でも可。}。 +▽モードで @code{@@} を2つ重ねて変換を開始すると、部首による単漢字変換が +できます。 @code{M-x skk-tankan} でも可能です。 -@example +@lisp Q @@ @@ -@group ------ Buffer: foo ----- -▽@@@@@point{} ------ Buffer: foo ----- -@end group - -@key{SPC} - -@group ------- Minibuffer ------- -部首を番号で選択(TABで一覧表示): @point{} ------- Minibuffer ------- -@end group - -@key{TAB} - -@group ------- *Completions* ------- -Click on a completion to select it. -In this buffer, type RET to select the completion near point. - -Possible completions are: -001 一 (いち) 002 | (ぼう、たてぼう) -003 丶 (てん) 004 丿 (の) -005 乙 (おつ) 006 亅 (はねぼう) - : : ------- *Completions* ------- -@end group - -@kindex M-v -@kbd{0 1 8 @key{RET}} @footnote{@kbd{M-v} の打鍵で、カーソルを *Completions* バッファへ移すこともできます。} - -@group ------ Buffer: *候補* ----- -A:切;4画(刀部2画) -S:刈;4画(刀部2画) -D:刊;5画(刀部3画) -F:刋;5画(刀部3画) -J:刎;6画(刀部4画) -K:刑;6画(刀部4画) -L:刔;6画(刀部4画) -[残り 51+++++++] ------ Buffer: *候補* ----- -@end group - -@end example - -@defvr {ユーザ変数} skk-tankan-face - -@kbd{M-x skk-tankan} を実行したときに表示される「単漢字バッファ」で使用 -するフェイスです。 + ----- Buffer: foo ----- + ▽@@@@* + ----- Buffer: foo ----- + +SPC + + ------ Minibuffer ------- + 部首を番号で選択(TABで一覧表示): * + ------ Minibuffer ------- + +TAB + + ------ *Completions* ------- + Click on a completion to select it. + In this buffer, type RET to select the completion near point. + + Possible completions are: + 001 一 (いち) 002 | (ぼう、たてぼう) + 003 丶 (てん) 004 丿 (の) + 005 乙 (おつ) 006 亅 (はねぼう) + : : + ------ *Completions* ------- + +0 1 8 RET +注) M-v の打鍵で、カーソルを *Completions* バッファへ移すこともできます。 + + ----- Buffer: *候補* ----- + A:切;4画(刀部2画) + S:刈;4画(刀部2画) + D:刊;5画(刀部3画) + F:刋;5画(刀部3画) + J:刎;6画(刀部4画) + K:刑;6画(刀部4画) + L:刔;6画(刀部4画) + [残り 51+++++++] + ----- Buffer: *候補* ----- +@end lisp + +@defvar skk-tankan-face + +@code{M-x skk-tankan} を実行したときに表示される @strong{単漢字バッファ} で使用する +フェイスです。 +@end defvar -@end defvr - -@defvr {ユーザ変数} skk-tankan-radical-name-face +@defvar skk-tankan-radical-name-face 部首の読みに適用するフェイスです。 - -@end defvr +@end defvar @node 部首の読みによる単漢字変換 @subsubsection 部首の読みによる単漢字変換 直前の小々節「部首による単漢字変換」にて、部首番号を入力するプロンプトで -単に @key{RET} をタイプすると、部首の読みを入力するプロンプトに替わります。 +単に @code{RET} を打鍵すると、部首の読みを入力するプロンプトに替わります。 @example + ------ Minibuffer ------- + 部首を読みで選択(TABで一覧表示): * + ------ Minibuffer ------- -@group ------- Minibuffer ------- -部首を読みで選択(TABで一覧表示): @point{} ------- Minibuffer ------- -@end group +TAB -@key{TAB} - -@group ------- Completion List ------- -In this buffer, type RET to select the completion near point. - -Possible completions are: -あいくち (021) 匕 あお (174) 青 -あか (155) 赤 あくび (076) 欠 -あさ (200) 麻 あさかんむり (200) 麻 - : : ------- Completion List ------- -@end group + ------ Completion List ------- + In this buffer, type RET to select the completion near point. + Possible completions are: + あいくち (021) 匕 あお (174) 青 + あか (155) 赤 あくび (076) 欠 + あさ (200) 麻 あさかんむり (200) 麻 + : : + ------ Completion List ------- @end example @node 候補の絞り込み @subsection 候補の絞り込み -@cindex @file{skk-hint.el} -@file{skk-hint.el} は、2つの読みの積集合みたいなものを取ることによって -候補の絞り込みを行うプログラムです。 -インストールは @file{~/.skk} に以下を記入します。 +@code{skk-hint.el} は、2つの読みの積集合みたいなものを取ることによって候補の +絞り込みを行うプログラムです。インストールは @code{~/.skk} に以下を記入します。 @lisp (require 'skk-hint) @end lisp -例えば、読み ``かんどう'' に対する変換は L 辞書によると +例えば、読み「かんどう」に対する変換は L 辞書によると @example 感動、勘当、完動、間道、官道、貫道 @end example -と複数の候補があります。 +@noindent +と複数の候補があります。一方、これに「あいだ」という「他の読み」(ヒント) +を与えると候補は「間道」に一意に決まります。 -一方、これに ``あいだ'' という「他の読み」(ヒント)を与えると候補は -``間道'' に一意に決まります。 -ヒントは @kbd{;} に続けて入力します。 +ヒントは @code{;} に続けて入力します。 @example -@kbd{K a n d o u ; a i d a} +K a n d o u ; a i d a ※ ; 自体は表示されません。 -※ @samp{;} 自体は表示されません。 + ----- Buffer: foo ----- + ▽かんどうあいだ + ----- Buffer: foo ----- ------ Buffer: foo ----- -▽かんどうあいだ ------ Buffer: foo ----- +SPC -@key{SPC} - ------ Buffer: foo ----- -▼間道 ------ Buffer: foo ----- + ----- Buffer: foo ----- + ▼間道 + ----- Buffer: foo ----- @end example -@file{skk-hint.el} は、2つの読みの厳密な積集合を取っているわけではなく、 -通常の変換候補のなかでヒントとして与えられた読みを含んだ漢字を持つものに -候補を絞ります。この実例として ``感動'' と ``感圧'' を挙げます。 +@code{skk-hint.el} は、2つの読みの厳密な積集合を取っているわけではなく、通常 +の変換候補のなかでヒントとして与えられた読みを含んだ漢字を持つものに候補 +を絞ります。この実例として「感動」と「感圧」を挙げます。 @example -@kbd{K a n d o u ; k a n n a t u} +K a n d o u ; k a n n a t u ------ Buffer: foo ----- -▽かんどうかんあつ ------ Buffer: foo ----- + ----- Buffer: foo ----- + ▽かんどうかんあつ + ----- Buffer: foo ----- -@key{SPC} +SPC ------ Buffer: foo ----- -▼感動 ------ Buffer: foo ----- + ----- Buffer: foo ----- + ▼感動 + ----- Buffer: foo ----- @end example -@file{skk-hint.el} は単漢字の候補がたくさんある場合に、そこから候補を絞 -りこむ手段としても非常に有効です。例えば +@code{skk-hint.el} は単漢字の候補がたくさんある場合に、そこから候補を絞りこむ +手段としても非常に有効です。例えば @example -▽わ +▽わ* @end example -を変換すると、輪、環、話、和、羽、@dots{}と大量に候補が出てきます。 -この中から ``和'' を選びたいとします。普通に変換していても -そのうち ``和'' が表示されますが、これを @kbd{W a ; h e i w a} と入力し -変換すると、「▼へいわ」の候補である「平和」に含まれる +@noindent +を変換すると、輪、環、話、和、羽、@dots{} と大量に候補が出てきます。この中か +ら「和」を選びたいとします。普通に変換していてもそのうち「和」が表示され +ますが、これを @code{W a ; h e i w a} と入力し変換すると、「▼へいわ」の候補で +ある「平和」に含まれる @example -▼和 +▼和* @end example +@noindent が唯一の候補となります。 @example -@kbd{W a ; h e i w a} +W a ; h e i w a ------ Buffer: foo ----- -▽わへいわ ------ Buffer: foo ----- + ----- Buffer: foo ----- + ▽わへいわ* + ----- Buffer: foo ----- -@key{SPC} +SPC ------ Buffer: foo ----- -▼和 ------ Buffer: foo ----- + ----- Buffer: foo ----- + ▼和* + ----- Buffer: foo ----- @end example -@defvr {ユーザ変数} skk-hint-start-char +@defopt skk-hint-start-char + ヒント変換を開始するキーを character で指定します。 -@end defvr +@end defopt @node 接頭辞・接尾辞 @subsection 接頭辞・接尾辞 -@cindex 接頭辞 -@cindex 接尾辞 -接頭辞 (prefix)、接尾辞 (suffix)の入力のために特別な方法が用意されていま -す。たとえば、「し」の候補は沢山あり、「し」から「氏」を変換するのは、そのままでは -効率が悪いです。接尾辞の「し」ならば、「氏」や「市」が優先されるでしょう。 +接頭辞 (prefix)、接尾辞 (suffix) の入力のために特別な方法が用意されていま +す。たとえば、「し」の候補は沢山あり、「し」から「氏」を変換するのは、そ +のままでは効率が悪いです。接尾辞の「し」ならば、「氏」や「市」が優先され +るでしょう。 -接頭辞・接尾辞は辞書の中では、@samp{>} などで示されます。 +接頭辞・接尾辞は、辞書の中では @code{>} などで示されます。 @example >し /氏/ @end example @noindent -というエントリがあるとき、@samp{小林氏}を接尾辞入力を用いて、以下のよう -に入力することができます。 +というエントリがあるとき、「小林氏」を接尾辞入力を用いて、以下のように入 +力することができます。 @example -@kbd{K o b a y a s h i} +K o b a y a s h i -@group ------- Buffer: foo ------ -▽こばやし@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽こばやし* + ------ Buffer: foo ------ -@key{SPC} +SPC -@group ------- Buffer: foo ------ -▼小林@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼小林* + ------ Buffer: foo ------ -@kbd{>} +> -@group ------- Buffer: foo ------ -小林▽>@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 小林▽>* + ------ Buffer: foo ------ -@kbd{s i} +s i -@group ------- Buffer: foo ------ -小林▽>し@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 小林▽>し* + ------ Buffer: foo ------ -@key{SPC} +SPC -@group ------- Buffer: foo ------ -小林▼氏@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 小林▼氏* + ------ Buffer: foo ------ -@kbd{C-j} -@group ------- Buffer: foo ------ -小林氏@point{} ------- Buffer: foo ------ -@end group +C-j + + ------ Buffer: foo ------ + 小林氏* + ------ Buffer: foo ------ @end example 接頭辞も同様です。辞書に @@ -3985,157 +4098,141 @@ @end example @noindent -というエントリがあるとき、@samp{超大型} を接頭辞入力を用いて、以下のよう -に入力することができます。 +というエントリがあるとき、「超大型」を接頭辞入力を用いて、以下のように入 +力することができます。 @example -@kbd{T y o u} +T y o u -@group ------- Buffer: foo ------ -▽ちょう@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽ちょう* + ------ Buffer: foo ------ -@kbd{>} +> -@group ------- Buffer: foo ------ -▼超@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼超* + ------ Buffer: foo ------ -@kbd{O o g a t a} +O o g a t a -@group ------- Buffer: foo ------ -超▽おおがた@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 超▽おおがた* + ------ Buffer: foo ------ -@key{SPC} +SPC -@group ------- Buffer: foo ------ -超▼大型@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 超▼大型* + ------ Buffer: foo ------ -@kbd{C-j} +C-j -@group ------- Buffer: foo ------ -超大型@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 超大型* + ------ Buffer: foo ------ @end example -キー @kbd{>} を押しただけで、@key{SPC} が押されたかのように変換されます。 -他の接頭辞を選びたいときは、@key{SPC} を押して下さい。 +キー @code{>} を押しただけで @code{SPC} が押されたかのように変換されます。他の接頭 +辞を選びたいときは @code{SPC} を押して下さい。 -@defvr {ユーザ変数} skk-special-midashi-char-list +@defvar skk-special-midashi-char-list -▽モードまたは▼モードにおいて、この変数の値に含まれる文字の入力があった -場合、接頭辞・接尾辞の入力を開始します。この変数のデフォルトは、 +▽モードまたは▼モードにおいて、この変数の値に含まれる文字の入力があっ +た場合、接頭辞・接尾辞の入力を開始します。この変数の標準設定は、 @lisp (?> ?< ??) @end lisp -@noindent -です。つまり、@samp{>} と @samp{<} と @samp{?} を入力した時に接頭辞・接尾辞入 -力を行います。@samp{?} を入力したときに接頭辞・接尾辞入力を行わない場合は -@samp{?} を外して +です。つまり、 @code{>} と @code{<} と @code{?} を入力した時に接頭辞・接尾辞入力を行い +ます。 @code{?} を入力したときに接頭辞・接尾辞入力を行わない場合は @code{?} を外 +して @lisp (setq skk-special-midashi-char-list '(?> ?<)) @end lisp -@noindent -とします。 - -L 辞書の接頭・接尾辞は、昔は @samp{<}, @samp{?} も使われていましたが、 -現在は @samp{>} に統一されています。 -@end defvr +とします。L 辞書の接頭・接尾辞は、昔は @code{<} と @code{?} も使われていましたが、 +現在は @code{>} に統一されています。 +@end defvar @node 数値変換 @subsection 数値変換 -@cindex #0 -@cindex #1 -@cindex #2 -@cindex #3 -@cindex #4 -@cindex #5 -@cindex #8 -@cindex #9 -@cindex 数をパラメータとする語の変換 -@cindex 数値再変換 -@cindex 大字 -@cindex 漢数字 -@cindex 金額 - -DDSKK は、@b{数字を含む見出し語}を様々な候補に変換することができます。 -例えば、見出し語 @samp{だい12かい} を変換すると @samp{第12回}、 -@samp{第一二回}、@samp{第十二回} といった候補を挙げます。 - -この節では、このような候補を辞書に登録する方法を説明します。基本は、 -数字の部分を @samp{#} で置き替えることです。辞書 @file{SKK-JISYO.L} のエ -ントリーから具体例を見てみましょう。 + +DDSKK は @strong{数字を含む見出し語} を様々な候補に変換することができます。例え +ば、見出し語「だい12かい」を変換すると「第12回」、「第一二回」、「第十 +二回」といった候補を挙げます。 + +この節では、このような候補を辞書に登録する方法を説明します。基本は、数字 +の部分を @code{#} で置き替えることです。辞書 @code{SKK-JISYO.L} のエントリーから具 +体例を見てみましょう。 @example だい#かい /第#1回/第#0回/第#2回/第#3回/第 #0 回/ @end example -@noindent -@samp{だい12かい} のような@b{数字を含む見出し語}を変換した場合、見出し -語の中の数字の部分は自動的に @samp{#} に置き換えられますの -で、辞書エントリーの左辺(つまり見出し語) @samp{だい#かい} にマッチします。 +「だい12かい」のような @strong{数字を含む見出し語} を変換した場合、見出し語の中 +の数字の部分は自動的に @code{#} に置き換えられますので、辞書エントリーの左辺( +つまり見出し語)である "@code{だい#かい}" にマッチします。 -辞書エントリーの右辺の @samp{#1}、@samp{#2} などは「どのように数字を加工 -するか」のタイプを表します。以下、各タイプについて説明します。 +辞書エントリーの右辺の @code{#1} 、 @code{#2} などは「どのように数字を加工するか」 +のタイプを表します。以下、各タイプについて説明します。 -@table @samp -@item #0 +@itemize +@item +@code{#0} -タイプ 0。無変換。入力されたアスキー文字をそのまま出力します。例えば、 -@samp{第12回} のような変換を得るために使います。 +無変換。入力されたアスキー文字をそのまま出力します。例えば、「第12回」 +のような変換を得るために使います。 -@item #1 -タイプ 1。全角文字の数字。@samp{12} を @samp{12} に変換します。 +@item +@code{#1} -@item #2 +全角文字の数字。 @code{12} を「12」に変換します。 -タイプ 2。漢数字で位取りあり。@samp{1024} を @samp{一〇二四} に変換しま -す。 -@item #3 +@item +@code{#2} -タイプ 3。漢数字で位取りなし。@samp{1024} を @samp{千二十四} に変換しま -す。 +漢数字で位取りあり。 @code{1024} を「一〇二四」に変換します。 -@item #4 -タイプ 4。数値再変換。見出し語中の数字そのもの -@footnote{@samp{p125} という見出し語であれば、その数値部分である -@samp{125} が再変換の見出し語となります。}をキーとして辞書を再検索し、 -@samp{#4} の部分を再検索の結果の文字列で入れ替えます。これについては後で -例を挙げて説明します。 +@item +@code{#3} -@item #5 +漢数字で位取りなし。 @code{1024} を「千二十四」に変換します。 -タイプ 5。小切手や手形の金額記入の際用いられる表記で変換します。例えば、 -@samp{1995} を @samp{壱阡九百九拾伍} に変換します。(これを大字と言います。) -@item #8 +@item +@code{#4} -タイプ 8。桁区切り。@samp{1234567} を @samp{1,234,567} に変換します。 +数値再変換。見出し語中の数字そのもの @footnote{@code{p125} という見出し語であれば、その数値部分である @code{125} が再変換 +の見出し語となります。} をキーとして辞書を再検索し、 @code{#4} の +部分を再検索の結果の文字列で入れ替えます。これについては後で例を挙げて +説明します。 -@item #9 -タイプ 9。将棋の棋譜の入力用。@samp{全角数字 + 漢数字} に変換します。こ -れについては後で例を挙げて説明します。 -@end table +@item +@code{#5} + +小切手や手形の金額記入の際用いられる表記で変換します。例えば、 @code{1995} を +「壱阡九百九拾伍」に変換します。これを大字と言います。 + + +@item +@code{#8} + +桁区切り。 @code{1234567} を @code{1,234,567} に変換します。 + + +@item +@code{#9} + +将棋の棋譜の入力用。「全角数字+漢数字」に変換します。これについては後 +で例を挙げて説明します。 +@end itemize 以下にいくつか例を示します。辞書に @@ -4147,16 +4244,14 @@ というエントリがあるときに、 @example -@group -@kbd{Q 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 @key{SPC}} -@end group +Q 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 SPC + または +/ 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 SPC @end example @noindent -と入力@footnote{または @kbd{/ 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 @key{SPC}}} -すれば、@samp{百兆二千三億四十万五百} と変換されます -@footnote{SHIFT キーを伴って数字を入力し始めることはできないので、@kbd{Q} または -@kbd{/} で▽モードに入る必要があります。}。 +とキー入力 @footnote{SHIFT キーを伴って数字を入力し始めることはできないので @code{Q} ま +たは @code{/} で▽モードに入る必要があります。} すれば「百兆二千三億四十万五百」と変換されます。 辞書に @@ -4165,12 +4260,11 @@ @end example @noindent -というエントリがあるときに、@kbd{/ 2 m 2 5 d @key{SPC}} と入力すれば、 -@samp{2月25日}と変換されます -@footnote{@samp{m} や @samp{d} などアスキー文字を見出し語として入 -力する場合は @kbd{/} キーを最初に入力して SKK abbrev モードに入ってから -入力する必要があります。 -@w{@xref{アスキー文字を見出し語とした変換, , SKK abbrev mode}.}}。 +というエントリがあるときに @code{/ 2 m 2 5 d SPC} と入力 @footnote{@code{m} や @code{d} などアスキー文字を見出し語として入力する場合は @code{/} キー +を最初に入力して SKK abbrev モードに入ってから入力する必要があります。 + +@ref{アスキー文字を見出し語とした変換}.} すれ +ば「2月25日」と変換されます。 辞書に @@ -4179,90 +4273,83 @@ @end example @noindent -というエントリがあるときに、@kbd{/ 3 4 k i n @key{SPC}} と入力すれば、 -@samp{3四金}と変換されます。 +というエントリがあるときに @code{/ 3 4 k i n SPC} と入力すれば「3四金」と変換 +されます。 辞書に @example -@group p# /#4/ 125 /東京都葛飾区/ -@end group @end example @noindent -というエントリがあるときに、@kbd{/ p 1 2 5 @key{SPC}} と入力すれば、見出 -し語 @samp{p125} の候補が @samp{#4} なので、見出し語の数字部分の -@samp{125} に対し辞書が再検索され、@samp{東京都葛飾区} と変換されます。 +というエントリがあるときに @code{/ p 1 2 5 SPC} と入力すれば、見出し語 @code{p125} の +候補が @code{#4} なので、見出し語の数字部分の @code{125} に対し辞書が再検索さ +れ「東京都葛飾区」と変換されます。 -最後に、実際に登録する例を 1 つ挙げます。@samp{2月25日}を得るために、 +最後に、実際に登録する例をひとつ挙げます。「2月25日」を得るために、 @example -@kbd{Q 2 g a t u 2 5 n i t i @key{SPC}} +Q 2 g a t u 2 5 n i t i SPC @end example @noindent -と入力したときに、辞書に見出し語 +とキー入力したときに、辞書に見出し語 @example #がつ#にち /#1月#1日/ @end example @noindent -がないときは、辞書登録モードのプロンプトは、@w{@samp{#がつ#にち}}となります。 -全角数字のタイプは、@samp{#1} なので、 @w{@samp{#1月#1日}} をミニバッファで作り登 -録します。 +がないときは、辞書登録モードのプロンプトは @code{「#がつ#にち」} となります。 +全角数字のタイプは @code{#1} なので @code{「#1月#1日」} をミニバッファで作り登録し +ます。 タイプを覚えている必要はありません。ちゃんと、ウィンドウが開かれて説明が 表示されます。 -@defvr {ユーザ変数} skk-num-convert-float +@defopt skk-num-convert-float -この変数の値を @code{non-nil} に設定すると、浮動小数点数を使った見出し語 -に対応して数値変換を行います。ただし、辞書において +この変数の値を @code{non-nil} に設定すると、浮動小数点数を使った見出し語に対 +応して数値変換を行います。ただし、辞書において @example #.# /#1.#1/#0月#0日/ @end example などの見出し語が使用できなくなります。 +@end defopt -@end defvr - -@defvr {ユーザ変数} skk-show-num-type-info - -@code{Non-nil} であれば、辞書登録モードに入るのと同時に変換タイプの案内を -表示する。デフォルトは @code{t} です。 +@defopt skk-show-num-type-info -@end defvr +@code{Non-nil} であれば、辞書登録モードに入るのと同時に変換タイプの案内を表 +示します。標準設定は @code{t} です。 +@end defopt -@defvr {ユーザ変数} skk-num-grouping-separator +@defvar skk-num-grouping-separator -タイプ 8 (@samp{#8}) で使用する記号。デフォルトは @samp{,}。 +タイプ @code{#8} で使用する記号。標準設定は @code{,} 。 +@end defvar -@end defvr +@defvar skk-num-grouping-places -@defvr {ユーザ変数} skk-num-grouping-places +タイプ @code{#8} について、何桁毎に区切るのかを数値で指定する。標準設定は 3。 +@end defvar -タイプ 8 (@samp{#8}) について、何桁毎に区切るのかを数値で指定する。デフォルトは 3。 +@defopt skk-use-numeric-conversion -@end defvr - -@defvr {ユーザ変数} skk-use-numeric-conversion - -この変数を @code{nil} に設定すると、本節で説明した数値変換の機能を全て -無効にします。 - -@end defvr +この変数を @code{nil} に設定すると、本節で説明した数値変換の機能を全て無効に +します。 +@end defopt @node アスキー文字を見出し語とした変換 @subsection アスキー文字を見出し語とした変換 @cindex SKK abbrev mode -かなモードで @kbd{/} をタイプすると @dfn{SKK abbrev mode} に入り、以後の -入力はアスキー文字になります。普通に @key{SPC} を押すと、その見出し語に係 -る変換が得られます。 +かなモードで @code{/} を打鍵すると @strong{SKK abbrev モード} に入り、以後の入力はアス +キー文字になります。普通に @code{SPC} を押すと、その見出し語に係る変換が得られ +ます。 仮に、辞書に @@ -4274,142 +4361,123 @@ というエントリがあるとして、以下に例を示します。 @example -@kbd{/} +/ -@group ------- Buffer: foo ------ -▽@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽* + ------ Buffer: foo ------ -@kbd{i s} +i s -@group ------- Buffer: foo ------ -▽is@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽is* + ------ Buffer: foo ------ -@key{SPC} +SPC -@group ------- Buffer: foo ------ -▼インクリメンタル・サーチ@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼インクリメンタル・サーチ* + ------ Buffer: foo ------ -@kbd{C-j} +C-j -@group ------- Buffer: foo ------ -インクリメンタル・サーチ@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + インクリメンタル・サーチ* + ------ Buffer: foo ------ @end example -候補を確定すると SKK abbrev モードを抜けてかなモードに戻ります。 +候補を確定すると SKK abbrev モードを抜けて かなモード に戻ります。 SKK abbrve モードで使われる辞書は、普通のかな漢字変換と同じです。見出し語 がアスキー文字で書かれているだけで、特殊な点はありません。 -上記の例において @key{SPC} の代わりに @kbd{C-q} をタイプすることで、入力 -したアスキー文字をそのまま全角アルファベットに変換することもできます。 -(@w{@ref{全英文字の入力}}) +上記の例において @code{SPC} の代わりに @code{C-q} を打鍵することで、入力したアスキー +文字をそのまま全角アルファベットに変換することもできます。 + +@ref{全英文字の入力}. -なお、SKK abbrev モードにおいても @key{TAB} による「見出し語の補完」を行 -うことができます。(@w{@pxref{補完}}) +なお、SKK abbrev モードにおいても @code{TAB} による「見出し語の補完」 (@ref{補完}.) を +行うことができます。 @node 今日の日付の入力 @subsection 今日の日付の入力 -@kindex @@ -@cindex プログラム実行変換 -かな/カナモードで @kbd{@@} を入力すれば、今日の日付が入力されます。 +@cindex プログラム実行変換 +かなモード/カナモードで @code{@@} を入力すれば、今日の日付が入力されます。 日付の形式は以下の変数により決定されます。 -@defvr {ユーザ変数} skk-date-ad +@defopt skk-date-ad -この変数の値が @code{non-nil} であれば西暦で、@code{nil} であれば元号で -表示します。デフォルトは @code{nil} です。 +この変数の値が @code{non-nil} であれば西暦で、 @code{nil} であれば元号で表示しま +す。標準設定は @code{nil} です。 +@end defopt -@end defvr +@defvar skk-number-style -@defvr {ユーザ変数} skk-number-style +この変数の値は以下のように解釈されます。標準設定は @code{1} です。 -この変数の値は以下のように解釈されます。デフォルトは @samp{1} です。 +@itemize +@item +@code{0} or @code{nil} -@table @code -@item 0 -@itemx nil +ASCII 数字。「1996年7月21日(日)」のようになります。 -ASCII 数字。@samp{1996年7月21日(日)} のようになります。 -@item 1 -@itemx t +@item +@code{1} or @code{t} -全角数字。@samp{1996年7月21日(日)} のようになります。 +全角数字。「1996年7月21日(日)」のようになります。 -@item 2 -漢数字(位取)。@samp{一九九六年七月二一日(日)} のようになります。 +@item +@code{2} -@item 3 +漢数字(位取)。「一九九六年七月二一日(日)」のようになります。 -漢数字。@samp{千九百九十六年七月二十一日(日)} のようになります。 -@end table -上記の @samp{1996年}、@samp{1996年}、@samp{一九九六年} の部分は、変 -数 @code{skk-date-ad} の値が @code{nil} であれば @samp{平成8年} のよう -に元号で表示されます。 -@end defvr - -辞書 @file{SKK-JISYO.lisp} には、見出し語 @samp{today} の候補 -として、@code{skk-date-ad} と @code{skk-number-style} の全ての組み合わせが -プログラム実行変換機能@footnote{@ref{プログラム実行変換}.} を用いて登録さ -れています。従って、@kbd{/ t o d a y @key{SPC}} と入力すると、今日の日付 -が上記の形式で順次候補として表示されます。 - -関数 @code{skk-relative-date} を利用すると、昨日、一昨日、明後日など任意 -の日付を求めることができます。詳細は @file{skk-gadget.el} のコメントを参 -照してください。 +@item +@code{3} -なお、@kbd{@@} のタイプで日付を挿入するのではなく、文字どおり @samp{@@} を -挿入したい場合は次のとおり。 +漢数字。「千九百九十六年七月二十一日(日)」のようになります。 +@end itemize +@end defvar -@lisp -@group -(setq skk-rom-kana-rule-list - (append skk-rom-kana-rule-list - '(("@@" nil "@@")))) -@end group -@end lisp +上記の「1996年」、「1996年」、「一九九六年」の部分は、変数 @code{skk-date-ad} の +値が @code{nil} であれば「平成8年」のように元号で表示されます。 + +辞書 @code{SKK-JISYO.lisp} には、見出し語 @code{today} の候補として @code{skk-date-ad} と @code{skk-number-style} の +全ての組み合わせがプログラム実行変換機能を用いて登録されています。従って、 +@code{/ t o d a y SPC} と入力すると、今日の日付が上記の形式で順次候補として表 +示されます。 -全角文字の @samp{@} を挿入したい場合は次のとおり。 +関数 @code{skk-relative-date} を利用すると、昨日、一昨日、明後日など任意の日付 +を求めることができます。詳細は @code{skk-gadget.el} のコメントを参照してくださ +い。 + +なお、 @code{@@} の打鍵で日付を挿入するのではなく、文字どおり @code{@@} を挿入したい +場合は次のとおり。 @lisp -@group (setq skk-rom-kana-rule-list (append skk-rom-kana-rule-list - '(("@@" nil "@")))) -@end group + '(("@@" nil "@@")))) @end lisp @node プログラム実行変換 @subsection プログラム実行変換 -@cindex @file{skk-gadget.el} -辞書の候補に Emacs Lisp のプログラムが書いてあれば、そのプログラムを -Emacs に実行させ、返り値をカレントバッファに挿入します。これを @b{「プロ -グラム実行変換」}と呼んでいます。例えば、辞書に +辞書の候補に Emacs Lisp のプログラムが書いてあれば、そのプログラムを Emacs に +実行させ、返り値をカレントバッファに挿入します。これを @strong{プログラム実行変換} と +呼んでいます。例えば、辞書に @example now /(current-time-string)/ @end example @noindent -というエントリがあるとします。このとき @kbd{/ n o w @key{SPC}} と入力す -れば、現在のバッファに @code{current-time-string} の返り値である +というエントリがあるとします。このとき @code{/ n o w SPC} とキー入力すれば、現 +在のバッファに関数 @code{current-time-string} の返り値である @example Sun Jul 21 06:40:34 1996 @@ -4419,62 +4487,55 @@ のような文字列が挿入されます。 ここで、プログラムの返り値は文字列である必要があります。また、プログラム -実行変換の辞書登録は通常の単語と同様に行うことができますが、その中に改 -行を含まないように書く必要があります -@footnote{通常の単語では、改行を含むことが可能です。それは、評価するとその位置に -改行を挿入するような実行変換プログラムに変換して辞書に書き込んでいるからです。 -@w{@xref{辞書の種類}.} +実行変換の辞書登録は通常の単語と同様に行うことができますが、その中に改行 +を含まないように書く必要 @footnote{通常の単語では、改行を含むことが可能です。それは、評価すると +その位置に改行を挿入するような実行変換プログラムに変換して辞書に書き込ん +でいるからです。 + +@ref{辞書の種類}. -しかし、実行変換されるプログラムを辞書登録する際にはこの機能を利用できないため、 -改行を含むことができません。}。 +しかし、実行変換されるプログラムを辞書登録する際にはこの +機能を利用できないため、改行を含むことができません。} があります。 -今日の日付の入力 -@footnote{@xref{今日の日付の入力}.} で説明した @samp{today} の辞書エント -リは、実際は下記のようなプログラムを候補にもっています。 +今日の日付の入力 @footnote{@ref{今日の日付の入力}.} で説明した @code{today} の辞書エントリは、実際は下 +記のようなプログラムを候補にもっています。 @lisp -@group -today /(let ((skk-date-ad) (skk-number-style t)) (skk-today))/@dots{}/ -@end group +today /(let ((skk-date-ad) (skk-number-style t)) (skk-today))/.../ @end lisp -@file{skk-gadget.el} には、西暦/元号変換や簡単な計算などプログラム実行変 -換用の関数が集められています。 +@code{skk-gadget.el} には、西暦/元号変換や簡単な計算などプログラム実行変換用 +の関数が集められています。 @defun skk-calc operator -skk-calc は、引数を 1 つ取り、見出し語の数字に対しその演算を行う簡単な計算 -プログラムです。 +@code{skk-calc} は、引数をひとつ取り、見出し語の数字に対しその演算を行う簡単 +な計算プログラムです。 @lisp -@group (defun skk-calc (operator) - ;;@r{2つの引数を取って operator の計算をする。} - ;;@r{注意: '/ は引数として渡せないので (defalias 'div '/) などとし、別の形で} - ;;@r{skk-calc に渡す。} - ;;@r{辞書見出し例; #*# /(skk-calc '*)/} + ;; 2つの引数を取って operator の計算をする。 + ;; 注意: '/ は引数として渡せないので (defalias 'div '/) などとし、別の形で + ;; skk-calc に渡す。 + ;; 辞書エントリの例 -> #*# /(skk-calc '*)/ (number-to-string (apply operator - (mapcar 'string-to-number + (mapcar 'string-to-number skk-num-list)))) -@end group @end lisp -この関数を実際にプログラム実行変換で利用するには、辞書に以下のようなエン -トリを追加します -@footnote{@ref{数値変換}.}。 +この関数を実際にプログラム実行変換で利用するには、辞書に以下のようなエ +ントリを追加します @footnote{@ref{数値変換}.} 。 @example #*# /(skk-calc '*)/ @end example -@noindent -@kbd{Q 1 1 1 * 4 5 @key{SPC}} と入力します。ここで、@samp{111} と -@samp{45} の 2 つの数字は、変換時に @w{@code{("111" "45")}} のような文字 -列のリストにまとめられ、変数 @code{skk-num-list} の値として保存されます。 -次に関数 @code{skk-calc} が呼ばれます。この中で、@code{skk-num-list} の -各要素に対し演算を行うため、各要素は数に変換されます。その上で、 -@code{skk-calc} に与えられた引数 (この場合は @samp{*}) を演算子として演 -算を行います。 +@code{Q 1 1 1 * 4 5 SPC} とキー入力します。ここで @code{111} と @code{45} の2つの数字 +は、変換時に @code{("111" "45")} のような文字列のリストにまとめられ、 +変数 @code{skk-num-list} の値として保存されます。次に関数 @code{skk-calc} が呼ば +れます。この中で @code{skk-num-list} の各要素に対し演算を行うため、各要素は +数に変換されます。その上で @code{skk-calc} に与えられた引数(この場合は @code{*} ) +を演算子として演算を行います。 @end defun @defun skk-gadget-units-conversion 基準単位 数値 変換単位 @@ -4482,35 +4543,29 @@ 数値について、基準単位から変換単位への変換を行います。 @example -@kbd{/ 1 3 m i l e} +/ 1 3 m i l e -@group ------- Buffer: foo ------ -▽13mile@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽13mile* + ------ Buffer: foo ------ -@key{SPC} +SPC -@group ------- Buffer: foo ------ -▼20.9209km@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼20.9209km* + ------ Buffer: foo ------ -@key{RET} +RET -@group ------- Buffer: foo ------ -20.9209km@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 20.9209km* + ------ Buffer: foo ------ @end example 単位変換の情報は、変数 @code{skk-units-alist} で定義されています。 @end defun -@defvr {ユーザ変数} skk-units-alist +@defvar skk-units-alist この変数は以下の形式の連想リストです。 @@ -4519,11 +4574,10 @@ (… . …)) @end example -関数 @code{skk-gadget-units-conversion} で利用されています。デフォルトで -は、以下の単位変換の情報を定義しています。 +関数 @code{skk-gadget-units-conversion} で利用されています。標準設定では、 +以下の単位変換の情報を定義しています。 @lisp -@group ("mile" ("km" . 1.6093) ("yard" . 1760)) @@ -4535,19 +4589,17 @@ ("inch" ("feet" . 0.5) ("cm" . 2.54)) -@end group @end lisp -@end defvr +@end defvar -@defun skk-relative-date pp-function format and-time &key (yy 0) (mm 0) (dd 0) +@defun skk-relative-date pp-function format and-time &key (yy 0) (mm 0) (dd 0) -@code{skk-current-date} の拡張版。@code{PP-FUNCTION}, @code{FORMAT}, @code{AND-TIME} の +@code{skk-current-date} の拡張版。 @code{PP-FUNCTION} , @code{FORMAT} , @code{AND-TIME} の 意味は @code{skk-current-date} の docstring を参照のこと。 -キーワード変数 @code{:yy}, @code{:mm}, @code{:dd} に正または負の数値を指定することで -明日、明後日、一昨日などの日付を求めることができる。 -詳細は @file{skk-gadget.el} のコメントを参照のこと。 - -@end defun +キーワード変数 @code{:yy} , @code{:mm} , @code{:dd} に正または負の数値を指定することで +明日、明後日、一昨日などの日付を求めることができる。詳細は @code{skk-gadget.el} の +コメントを参照のこと。 +@end defun @node 空白・改行・タブを含んだ見出し語の変換 @subsection 空白・改行・タブを含んだ見出し語の変換 @@ -4555,248 +4607,252 @@ 変換の際、見出し語の中の空白、改行、タブは無視されます。 @example -@group ----------------- Buffer: foo ------------------ -▽じんじょうしょ -うがっこう@point{} ----------------- Buffer: foo ------------------ -@end group - -@key{SPC} - -@group ----------------- Buffer: foo ------------------ -▼尋常小学校@point{} ----------------- Buffer: foo ------------------ -@end group + ---------------- Buffer: foo ------------------ + ▽じんじょうしょ + うがっこう* + ---------------- Buffer: foo ------------------ + +SPC + + ---------------- Buffer: foo ------------------ + ▼尋常小学校* + ---------------- Buffer: foo ------------------ @end example オートフィルモードで折り返された文字列に対し、折り返された状 態のまま変換することもできます。 @example -@group ----------------- Buffer: foo ------------------ -仮名漢字変換プログラムをさ -くせいしました。@point{} + ---------------- Buffer: foo ------------------ + 仮名漢字変換プログラムをさ + くせいしました。* + ---------------- Buffer: foo ------------------ + +C-u 10 C-b Q + + ---------------- Buffer: foo ------------------ + 仮名漢字変換プログラムを*さ + くせいしました。 + ---------------- Buffer: foo ------------------ + +C-u 5 C-f + + ---------------- Buffer: foo ------------------ + 仮名漢字変換プログラムを▽さ + くせい*しました。 ---------------- Buffer: foo ------------------ -@end group -@kbd{C-u 10 C-b Q} +SPC -@group ----------------- Buffer: foo ------------------ -仮名漢字変換プログラムを▽@point{}さ -くせいしました。 ----------------- Buffer: foo ------------------ -@end group - -@kbd{C-u 5 C-f} - -@group ----------------- Buffer: foo ------------------ -仮名漢字変換プログラムを▽さ -くせい@point{}しました。 ----------------- Buffer: foo ------------------ -@end group - -@key{SPC} - -@group ----------------- Buffer: foo ------------------ -仮名漢字変換プログラムを▼作成@point{}しました。 ----------------- Buffer: foo ------------------ -@end group + ---------------- Buffer: foo ------------------ + 仮名漢字変換プログラムを▼作成*しました。 + ---------------- Buffer: foo ------------------ @end example ここでは改行を越えて見出し語を探し、変換する例を示しました。同様に、空白、 タブ文字を中間に含む文字列に対しても変換を行うことができます。 -@defvr {ユーザ変数} skk-allow-spaces-newlines-and-tabs +@defopt skk-allow-spaces-newlines-and-tabs -この変数を @code{nil} に設定すると、本節で説明したような2行以上にまたが -る文字列に対する変換を禁止します。 - -@end defvr +この変数を @code{nil} に設定すると、本節で説明したような2行以上にまたがる文 +字列に対する変換を禁止します。 +@end defopt @node カタカナ変換 @subsection カタカナ変換 -@defvr {ユーザ変数} skk-search-katakana +@defvar skk-search-katakana 通常、SKK でカタカナ語を入力するには、 -@itemize @bullet -@item @kbd{q} でカナモードに移ってからカタカナを入力する -@item ▽モードで @kbd{q} によりカタカナへ変換する@footnote{@ref{かなモードからカタカナを入力}} -@end itemize -のどちらかです。これらの方法は手軽ですが、個人辞書に登録されないため見出 -し語の補完候補にも現れず、何度でも入力しなければいけません。 - -そこで、ここに紹介する方法ではカタカナ語が普通の変換候補として現れ、個人 -辞書にも登録されます。設定するには以下を @file{~/.skk} に記述します -@footnote{@code{skk-search-prog-list} の設定をユーザが変更している場合は -期待どおりに動作しない場合があります。その場合は@code{skk-search-prog-list} の -設定に関数 @code{skk-search-katakana} の呼び出しがあることを確認してくだ -さい。またこの機能の設定は DDSKK 14.1 以前では異なります。詳しくはソース -に付属のドキュメント、設定例をご覧ください。}。 + +@itemize +@item +@code{q} でカナモードに移ってからカタカナを入力する + + +@item +▽モードで @code{q} によりカタカナへ変換する @footnote{@ref{かなモードからカタカナを入力}.} +@end itemize +のどちらかです。これらの方法は手軽ですが、個人辞書に登録されないため見 +出し語の補完候補にも現れず、何度でも入力しなければなりません。 + +そこで、ここに紹介する方法ではカタカナ語が普通の変換候補として現れ、個 +人辞書にも登録されます。設定するには以下を @code{~/.skk} に記述します @footnote{@code{skk-search-prog-list} の設定をユーザが変更している場合は期待 +どおりに動作しない場合があります。その場合は @code{skk-search-prog-list} の設 +定に関数 @code{skk-search-katakana} の呼び出しがあることを確認してください。 +またこの機能の設定は DDSKK 14.1 以前では異なります。詳しくはソースに付属 +のドキュメント、設定例をご覧ください。} 。 @lisp (setq skk-search-katakana t) @end lisp -また、値をシンボル@code{'jisx0201-kana} とすると、カタカナ候補に加え半角 -カタカナ候補も変換候補に現れます。 +また、値をシンボル @code{jisx0201-kana} とすると、カタカナ候補に加え半角カタ +カナ候補も変換候補に現れます。 @lisp (setq skk-search-katakana 'jisx0201-kana) @end lisp -@end defvr +@end defvar @node サ変動詞変換 @subsection サ変動詞変換 -@defvr {ユーザ変数} skk-search-sagyo-henkaku +@defvar skk-search-sagyo-henkaku -通常、SKK では諸般の事情によりサ行変格活用の動詞は送りなし変換をする前提 -になっています。このことは共有辞書のメンテナンスにおける便宜上やむをえな -いのですが、個人辞書が育たない (サ変動詞と名詞の区別ができない) という弱 -点もあります。(@w{@pxref{サ変動詞の辞書登録に関する注意}}) - -しかし、ここに紹介する方法では任意の送りなし候補を利用してサ行の送りプレ -フィックスに限定して送りあり変換が可能になり、個人辞書を育てることが可能 -になります。設定するには以下を @file{~/.skk} に記述します。 -@footnote{@code{skk-search-prog-list} の設定をユーザが変更している場合は -期待どおりに動作しない場合があります。その場合は @code{skk-search-prog-list} -の設定に関数 @code{skk-search-sagyo-henkaku} の呼び出しがあることを確認 -してください。またこの機能の設定は DDSKK 14.1 以前では異なります。詳しく -はソースに付属のドキュメント、設定例をご覧ください。} +通常、SKK では諸般の事情によりサ行変格活用の動詞は送りなし変換をする前 +提になっています。このことは共有辞書のメンテナンスにおける便宜上やむを +えないのですが、個人辞書が育たない(サ変動詞と名詞の区別ができない)と +いう弱点もあります。 + +@ref{サ変動詞の辞書登録に関する注意}. + +しかし、ここに紹介する方法では任意の送りなし候補を利用してサ行の送りプ +レフィックスに限定して送りあり変換が可能になり、個人辞書を育てることが +可能になります。設定するには以下を @code{~/.skk} に記述します @footnote{@code{skk-search-prog-list} の設定をユーザが変更している場合は期待ど +おりに動作しない場合があります。その場合は @code{skk-search-prog-list} の設定 +に関数 @code{skk-search-sagyo-henkaku} の呼び出しがあることを確認してください。 +またこの機能の設定は DDSKK 14.1 以前では異なります。詳しくはソースに付属 +のドキュメント、設定例をご覧ください。} 。 @lisp (setq skk-search-sagyo-henkaku t) @end lisp -例えば @samp{お茶する} の変換は以下のように変化します。 +例えば「お茶する」の変換は以下のように変化します。 -@itemize @bullet -@item 従来 … @kbd{O c h a @key{SPC} s u r u} -@item サ変 … @kbd{O c h a S u r u} -@end itemize +@itemize +@item +従来 … @code{O c h a SPC s u r u} -変数の値を @code{anything} に設定すると、サ行に限らず任意の送り仮名を許 -可し、送りあり変換をします。これにより、送りあり変換の利用範囲を形容詞・ -動詞の変換のみならず、あらゆるひらがな開始点の指定に拡張することができま -す。 -このサ変動詞送りあり変換機能は、カタカナ変換機能と組み合わせるとさらに有 -効です。(@w{@pxref{カタカナ変換}}) -@end defvr +@item +サ変 … @code{O c h a S u r u} +@end itemize +変数の値をシンボル @code{anything} に設定すると、サ行に限らず任意の送り仮名 +を許可し、送りあり変換をします。これにより、送りあり変換の利用範囲を形 +容詞・動詞の変換のみならず、あらゆるひらがな開始点の指定に拡張すること +ができます。 + +このサ変動詞送りあり変換機能は、カタカナ変換機能 (@ref{カタカナ変換}.) と +組み合わせるとさらに有効です。 +@end defvar @node 異体字へ変換する @subsection 異体字へ変換する -@samp{辺} (42区53点) の異体字である @samp{邊} (78区20点) や @samp{邉} (78 -区21点) を入力したいときがあります@footnote{辞書が充実していればかな漢字 -変換で見出し語 @samp{へん} から @samp{邊} や @samp{邉} を求めることができ -ます。もちろん、文字コードを指定して @samp{邊} や @samp{邉} を直接挿入す -ることもできます。}。 -@example -@point{}辺 +「辺」(42区53点)の異体字である「邊」(78区20点)や「邉」(78区21点)を +入力したいときがあります @footnote{辞書が充実していればかな漢字変換で見出し語「へん」から「邊」 +や「邉」を求めることができます。もちろん、文字コードを指定して「邊」や +「邉」を直接挿入することもできます。} 。 -@kbd{Q} +@example + ---- Buffer: foo ---- + *辺 + ---- Buffer: foo ---- -▽@point{}辺 +Q -@kbd{C-f} + ---- Buffer: foo ---- + ▽*辺 + ---- Buffer: foo ---- -▽辺@point{} +C-f -@key{SPC} + ---- Buffer: foo ---- + ▽辺* + ---- Buffer: foo ---- -▼邊@point{} +SPC -@key{SPC} + ---- Buffer: foo ---- + ▼邊* + ---- Buffer: foo ---- -▼邉@point{} +SPC + ---- Buffer: foo ---- + ▼邉* + ---- Buffer: foo ---- @end example -@defvr {ユーザ変数} skk-itaiji-jisyo - -辞書ファイル @file{SKK-JISYO.itaiji} 又は @file{SKK-JISYO.itaiji.JIS3_4} へ -のパスを指定する。 +@defvar skk-itaiji-jisyo -他の辞書ファイルと異なり、この 2 つの辞書ファイルは見出し語が漢字です。 +辞書ファイル @code{SKK-JISYO.itaiji} 又は @code{SKK-JISYO.itaiji.JIS3_4} へ +のパスを指定する。他の辞書ファイルと異なり、この2つの辞書ファイルは見 +出し語が漢字です。 +@end defvar -@end defvr @defun skk-search-itaiji -not documented - -@url{http://mail.ring.gr.jp/skk/200303/msg00071.html} +not documented. +@uref{http://mail.ring.gr.jp/skk/200303/msg00071.html} @end defun @node ファンクションキーの使い方 @subsection ファンクションキーの使い方 -@defvr {ユーザ変数} skk-j-mode-function-key-usage +@defvar skk-j-mode-function-key-usage -シンボル @code{conversion} ならば、@code{skk-search-prog-list-1} 〜 @code{skk-search-prog-list-9} および @code{skk-search-prog-list-0} を -実行するよう自動設定します。これらのプログラムは▽モード限定でファンクション -キー (@key{[F1]} 〜 @key{[F10]}) に割り当てられます。@key{[F5]} 〜 @key{[F10]} に -ついては本オプションの設定により自動的に割り当てられます。 -これらの割り当てはユーザオプション @code{skk-verbose} を設定するとエコー -エリアに表示されるようになります。(@w{@pxref{冗長な案内メッセージの表示}}) - -@itemize @bullet -@item @key{[F5]} … 単漢字 -@item @key{[F6]} … 無変換 -@item @key{[F7]} … カタカナ -@item @key{[F8]} … 半角カナ -@item @key{[F9]} … 全角ローマ -@item @key{[F10]} … ローマ -@end itemize +シンボル @code{conversion} ならば、 @code{skk-search-prog-list-1} 〜 @code{skk-search-prog-list-9} お +よび @code{skk-search-prog-list-0} を実行するよう自動設定します。これらのプ +ログラムは▽モード限定でファンクションキー ( @code{[F1]} 〜 @code{[F10]} ) に割り +当てられます。 @code{[F5]} 〜 @code{[F10]} については本オプションの設定により自動 +的に割り当てられます。これらの割り当てはユーザオプション @code{skk-verbose} を +設定するとエコーエリアに表示されるようになります。 -シンボル @code{kanagaki} ならば、かなキーボード入力用に自動設定します。 +@ref{冗長な案内メッセージの表示}. -@code{nil} ならば、自動設定しません。 +@itemize +@item +@code{[F5]} … 単漢字 + +@item +@code{[F6]} … 無変換 + +@item +@code{[F7]} … カタカナ + +@item +@code{[F8]} … 半角カナ -@end defvr +@item +@code{[F9]} … 全角ローマ + +@item +@code{[F10]} … ローマ +@end itemize +シンボル @code{kanagaki} ならば、かなキーボード入力用に自動設定します。 +@code{nil} ならば、自動設定しません。 +@end defvar @node キー設定 -@section キー設定 -@cindex キー設定 +@section キー設定 + @menu -文字の入力 -* かなモード/カナモードのキー設定:: +* かなモード/カナモードのキー設定:: * 全英モードのキー設定:: -* 閉じ括弧の自動入力:: +* 閉じ括弧の自動入力:: * リージョンを括弧で囲む:: - -@noindent -変換、確定など -* 確定するキー:: RET 以外で確定されるには -* 候補の選択に用いるキー:: asdfjkl 以外 -* ▼モードでのRET:: 改行も同時にする? しない? -* ▼モードでのBS:: 削除 vs 前候補 -* 送りあり変換中のC-g:: -* 変換位置の指定方法:: 大文字以外でも変換位置を指定可能に。 - -@noindent -他 -* 1回の取り消し操作(undo)の対象:: +* 確定するキー:: +* 候補の選択に用いるキー:: +* ▼モードでの RET:: +* ▼モードでの BS:: +* 送りあり変換中の C-g:: +* 変換位置の指定方法:: +* 1回の取り消し操作 (undo) の対象:: @end menu -関連項目: @w{@ref{ローマ字入力以外の入力方式}} +@node かなモード/カナモードのキー設定 +@subsection かなモード/カナモードのキー設定 -@node かなモード/カナモードのキー設定 -@subsection かなモード/カナモードのキー設定 @menu * ローマ字のルールの設定:: -* ローマ字ルールの変更例:: 略号なども設定できます。 +* ローマ字ルールの変更例:: * ■モードに関連するその他の変数:: * 数字や記号文字の入力:: @end menu @@ -4804,87 +4860,86 @@ @node ローマ字のルールの設定 @subsubsection ローマ字のルールの設定 -@table @code -@item skk-rom-kana-base-rule-list -@vindex skk-rom-kana-base-rule-list -@item skk-rom-kana-rule-list -@vindex skk-rom-kana-rule-list -@end table +@itemize +@item +@code{skk-rom-kana-base-rule-list} + +@item +@code{skk-rom-kana-rule-list} +@end itemize DDSKK の■モードにおける文字変換は、これら2つの変数を用いて行われます。 -@code{skk-rom-kana-base-rule-list} には基本的なローマ字かな変換のルールが -定められています。一方、@code{skk-rom-kana-rule-list} はユーザが独自のルールを -定めるために用意されており、@code{skk-rom-kana-base-rule-list} よりも優先されます。 +@code{skk-rom-kana-base-rule-list} には基本的なローマ字かな変換のルールが定め +られています。一方 @code{skk-rom-kana-rule-list} はユーザが独自のルールを定め +るために用意されており、 @code{skk-rom-kana-base-rule-list} よりも優先されます。 これらは「入出力の状態がいかに移り変わるべきか」を決定します。その内容は、 @lisp -@example (入力される文字列 出力後に自動的に入力に追加される文字列 出力) -@end example @end lisp @noindent という形のリストを列挙したものです。 -@itemize @bullet -@item 入力される文字列…変換される前のアスキー文字の文字列をいいます。 +@itemize +@item +入力される文字列…変換される前のアスキー文字の文字列をいいます。 -@item 出力…次の入力状態に移るときにバッファに挿入される文字列の組み合 -わせであり、 @w{@code{("ア" . "あ")}} のようなコンスセルです。 +@item +出力…次の入力状態に移るときにバッファに挿入される文字列の組み合わせ +であり、 @code{("ア" . "あ")} のようなコンスセルです。 @end itemize @code{skk-rom-kana-base-rule-list} の一部を見てみましょう。 @lisp -@example ("a" nil ("ア" . "あ")) ("ki" nil ("キ" . "き")) ("tt" "t" ("ッ" . "っ")) ("nn" nil ("ン" . "ん")) ("n'" nil ("ン" . "ん")) -@end example @end lisp @noindent のような規則があります。これによると @example -a @expansion{}あ -ki @expansion{}き -tt @expansion{}っt -nn @expansion{}ん -n' @expansion{}ん +a → あ +ki → き +tt → っt +nn → ん +n' → ん @end example @noindent のようになります。 -@code{skk-rom-kana-base-rule-list} には、次のような便利な変換ルールも定め -られています。 +@code{skk-rom-kana-base-rule-list} には、次のような便利な変換ルールも定められ +ています。 -@example -z @expansion{} □ (全角スペース) -z* @expansion{} ※ -z, @expansion{} ‥ -z- @expansion{} 〜 -z. @expansion{} … -z/ @expansion{} ・ -z0 @expansion{} ○ -z@@ @expansion{} ◎ -z[ @expansion{} 『 -z] @expansion{} 』 -z@{ @expansion{} 【 -z@} @expansion{} 】 -z( @expansion{} ( -z) @expansion{} ) -zh @expansion{} ← -zj @expansion{} ↓ -zk @expansion{} ↑ -zl @expansion{} → -zL @expansion{} ⇒ -@end example +@lisp +z SPC → 全角スペース +z* → ※ +z, → ‥ +z- → 〜 +z. → … +z/ → ・ +z0 → ○ +z@@ → ◎ +z[ → 『 +z] → 』 +z@{ → 【 +z@} → 】 +z( → ( +z) → ) +zh → ← +zj → ↓ +zk → ↑ +zl → → +zL → ⇒ +@end lisp @node ローマ字ルールの変更例 @subsubsection ローマ字ルールの変更例 @@ -4892,27 +4947,25 @@ @code{skk-rom-kana-base-rule-list} の規則に従うと @example -hannou @expansion{}はんおう -han'ou @expansion{}はんおう -hannnou @expansion{}はんのう +hannou → はんおう +han'ou → はんおう +hannnou → はんのう @end example @noindent のようになります。ここで @lisp -@group (setq skk-rom-kana-rule-list (append skk-rom-kana-rule-list '(("nn" "n" ("ン" . "ん"))))) -@end group @end lisp @noindent のような設定にすることで @example -hannou @expansion{}はんのう +hannou → はんのう @end example @noindent @@ -4921,21 +4974,19 @@ 他の例として、略号を設定することもできます。 @example -tp @expansion{}東北大学 -skk @expansion{}skk -skK @expansion{}SKK +tp → 東北大学 +skk → skk +skK → SKK @end example @noindent といった変換は、 @lisp -@group ("tp" nil ("東北大学" . "東北大学")) ("sk" nil ("" . "")) ("skk" nil ("skk" . "skk")) ("skK" nil ("SKK" . "SKK")) -@end group @end lisp @noindent @@ -4943,110 +4994,110 @@ あるので、適当な省略形を用いて、このリストに追加しておく、といった利用を お勧めします。 -更に @code{skk-rom-kana-rule-list} を用いれば TUT-code による日本語入力を -実現することもできます。TUT-code による入力についてはソースアーカイブ -の @samp{tut-code} ディレクトリに収録されている各ファイルを参照してくださ -い。@w{(@pxref{ローマ字入力以外の入力方式})} +更に @code{skk-rom-kana-rule-list} を用いれば TUT-code による日本語入力を実現 +することもできます。TUT-code による入力についてはソースアーカイブの @code{tut-code} デ +ィレクトリに収録されている各ファイルを参照してください。 + +@ref{ローマ字入力以外の入力方式}. @node ■モードに関連するその他の変数 @subsubsection ■モードに関連するその他の変数 -@defvr {ユーザ変数} skk-kana-input-search-function +@defvar skk-kana-input-search-function ルールリストの中に記せない変換ルールを処理する関数。 これは @code{skk-rom-kana-base-rule-list} と @code{skk-rom-kana-rule-list} の -要素を全て検索した後にコールされます。引数はありません。バッファの文字を、 -直接 @code{preceding-char} などで調べて下さい。 +要素を全て検索した後にコールされます。引数はありません。バッファの文字 +を、直接 @code{preceding-char} などで調べて下さい。 -初期設定では @kbd{h} で、長音を表すために使われています。次の例を見て下さい。 +初期設定では @code{h} で、長音を表すために使われています。次の例を見て下さい。 @example -ohsaka @expansion{} おおさか -ohta @expansion{} おおた +ohsaka → おおさか +ohta → おおた @end example -@noindent -一方で、@kbd{hh} は「っ」になります。 +一方で、 @code{hh} は「っ」になります。 @example -ohhonn @expansion{} おっほん -ohhira @expansion{} おっひら +ohhonn → おっほん +ohhira → おっひら @end example -@noindent -これは @code{skk-rom-kana-rule-list} のデフォルトに +これは @code{skk-rom-kana-rule-list} の標準設定に @lisp ("hh" "h" ("ッ" . "っ")) @end lisp -@noindent が入っているためです。これを削除すれば @example -ohhonn @expansion{} おおほん -ohhira @expansion{} おおひら +ohhonn → おおほん +ohhira → おおひら @end example -@noindent となります。 -@end defvr +@end defvar @kindex M-x skk-toggle-kutouten -@defvr {ユーザ変数} skk-kutouten-type -■モードの標準では、キーボードの @kbd{.} をタイプすると「。」が、 -@kbd{,} をタイプすると「、」がバッファに入力されます。 -変数 @code{skk-kutouten-type} に適切なシンボルを設定することにより、この -組み合せを変更することができます -@footnote{変数 @code{skk-use-kana-keyboard} が @code{non-nil} ならば無効 -である。}。そのシンボルとは、次の4つです。 - -@example -'jp@ @ @ @ @expansion{} 「。」「、」 (デフォルト) -'en@ @ @ @ @expansion{} 「.」「,」 -'jp-en @expansion{} 「。」「,」 -'en-jp @expansion{} 「.」「、」 -@end example -または、変数 @code{skk-kutouten-type} にはコンスセルを指定することも可 -能です。その場合は、 +@defvar skk-kutouten-type + +■モードの標準では、キーボードの @code{.} を打鍵すると「。」が、 @code{,} を打鍵 +すると「、」がバッファに挿入されます。変数 @code{skk-kutouten-type} に適切な +シンボルを設定することにより、この組み合せを変更 @footnote{変数 @code{skk-use-kana-keyboard} が @code{non-nil} ならば無効である。} すること +ができます。そのシンボルとは、次の4つです。 + +@itemize +@item +シンボル @code{jp} → 「。」「、」 (標準設定) + +@item +シンボル @code{en} → 「.」「,」 + +@item +シンボル @code{jp-en} → 「。」「,」 + +@item +シンボル @code{en-jp} → 「.」「、」 +@end itemize +または、変数 @code{skk-kutouten-type} にはコンスセルを指定することも可能です。 +その場合は、 @example (句点を示す文字列 . 読点を示す文字列) @end example のように指定します。例として、次のように設定するとキーボード -の @kbd{.} で @code{abc} が、@kbd{,} で @code{def} がバッファに入力され -ます。 -@c ↓実用的な例が思い付きませんでした +の @code{.} で @code{abc} が、 @code{,} で @code{def} がバッファに入力されます。 + @lisp (setq skk-kutouten-type '("abc" . "def")) @end lisp -なお、変数 @code{skk-kutouten-type} はバッファローカル変数です。すべての -バッファで統一した設定としたい場合は、 +なお、変数 @code{skk-kutouten-type} はバッファローカル変数です。すべてのバッ +ファで統一した設定としたい場合は、 @lisp (setq-default skk-kutouten-type 'en) @end lisp のように関数 @code{setq-default} を用いてください。 -@end defvr - -@defvr {ユーザ変数} skk-use-auto-kutouten +@end defvar -デフォルトは @code{nil}。@code{Non-nil} であれば、カーソル直前の文字種に -応じて句読点を動的に変更します。 +@defvar skk-use-auto-kutouten -@end defvr +標準設定は @code{nil} 。 @code{Non-nil} であれば、カーソル直前の文字種に応じて +句読点を動的に変更します。 +@end defvar @node 数字や記号文字の入力 @subsubsection 数字や記号文字の入力 -かなモード/カナモードにおける次のキーは、関数 @code{skk-insert} にバインドされています。 +かなモード/カナモードにおける次のキーは、関数 @code{skk-insert} にバインドされています。 @example -@group ! # % & ' * + - 0 1 2 3 4 5 @@ -5058,14 +5109,12 @@ ] @{ @} ^ _ ` | ~ -@end group @end example これらの数字や記号文字のキーに対応し挿入される文字をカスタマイズするため には、変数 @code{skk-rom-kana-rule-list} を利用します。 @lisp -@group (setq skk-rom-kana-rule-list (append skk-rom-kana-rule-list '(("!" nil "!") @@ -5074,34 +5123,28 @@ (":" nil ":") (";" nil ";") ("?" nil "?")))) -@end group @end lisp -@code{skk-insert} は、Emacs のオリジナル関数 @code{self-insert-command} -をエミュレートしています。具体的には、引数を渡すことによって同じ文字を複 -数、一度に挿入することが可能です。 +関数 @code{skk-insert} は、Emacs のオリジナル関数 @code{self-insert-command} をエミ +ュレートしています。具体的には、引数を渡すことによって同じ文字を複数、一 +度に挿入することが可能です。 @example -@group +C-u 2 ! -@kbd{C-u 2 !} - ------- Buffer: foo ------ -!! ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + !! + ------ Buffer: foo ------ @end example @node 全英モードのキー設定 @subsection 全英モードのキー設定 -全英モードにおける印字可能な全てのキーはコマンド -@code{skk-jisx0208-latin-insert} に割り付けられています。また、変数 -@code{skk-jisx0208-latin-vector} の値により挿入される文字が決定され、 -そのデフォルトは以下のようになっています。 +全英モードにおける印字可能な全てのキーはコマンド @code{skk-jisx0208-latin-insert} に +割り付けられています。また、変数 @code{skk-jisx0208-latin-vector} の値により挿 +入される文字が決定され、その標準設定は以下のようになっています。 @lisp -@group [nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil @@ -5118,156 +5161,130 @@ "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z" "{" "|" "}" "〜" nil] -@end group @end lisp -挿入される文字を変更したい場合は、@w{@ref{数字や記号文字の入力}} を参照し -てください。 +挿入される文字を変更したい場合: @ref{数字や記号文字の入力}. -@code{skk-jisx0208-latin-insert} も Emacs オリジナルの関数 -@code{self-insert-command} をエミュレートしています。つまり、引数を渡す -ことにより同じ文字を複数、一度に挿入することができます。 -@code{skk-insert} における動作と同じですから、 -@w{@ref{数字や記号文字の入力}} の例を参考にしてください。 +関数 @code{skk-jisx0208-latin-insert} も Emacs オリジナルの関数 @code{self-insert-command} を +エミュレートしています。つまり、関数 @code{skk-insert} における動作と同じく、 +引数を渡すことにより同じ文字を複数、一度に挿入することができます。 + +@ref{数字や記号文字の入力}. @node 閉じ括弧の自動入力 @subsection 閉じ括弧の自動入力 -@c 次の行、今は当てはまらない? ChangeLog を見たが記述なし。(2009-11-19) -@c @samp{「}や@samp{」}が上手く処理されない...。 -通常、`「' を入力したら、`」' を後で入力する必要があります。`「' の入 -力時点で、対になる文字を自動挿入してくれると打鍵数を減らすことができます -し、同時に入力忘れの防止にもなるでしょう。 +通常、 @strong{「} を入力したら @strong{」} を後で入力する必要があります。 @strong{「} の入力 +時点で、対になる文字を自動挿入してくれると打鍵数を減らすことができますし、 +同時に入力忘れの防止にもなるでしょう。 @vindex skk-auto-insert-paren -そのために変数 @code{skk-auto-insert-paren} が用意されています。この値を -@code{non-nil} にすると、上記の自動挿入を行います。 +そのために変数 @code{skk-auto-insert-paren} が用意されています。この値を @code{non-nil} に +すると、上記の自動挿入を行います。 @example -@group ------- Buffer: foo ------ -彼はこう言った@point{} ------- Buffer: foo ------ + ------ Buffer: foo ------ + 彼はこう言った* + ------ Buffer: foo ------ -@kbd{[} +[ ------- Buffer: foo ------ -彼はこう言った「@point{}」 ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 彼はこう言った「*」 + ------ Buffer: foo ------ @end example -@noindent -@c @samp{「}や@samp{」}が上手く処理されない...。 -上記のように `「' の入力時点で対となる`」'を自動挿入し、`「'と`」'の間に -ポイントを再配置するので、その位置からかぎかっこに囲まれた文字列を即始め -ることができます。 +上記のように @strong{「} の入力時点で対となる @strong{」} を自動挿入し、 @strong{「} と @strong{」} の +間にポイントを再配置するので、その位置からかぎかっこに囲まれた文字列を即 +始めることができます。 -@defvr {ユーザ変数} skk-auto-paren-string-alist -自動挿入すべきペアの文字列を指定します。デフォルトは下記のとおり。 + +@defvar skk-auto-paren-string-alist + +自動挿入すべきペアの文字列を指定します。標準設定は下記のとおり。 @lisp -@group -(("「" . "」") ("『" . "』") ("(" . ")") ("(" . ")") ("@{" . "@}") - ("{" . "}") ("〈" . "〉") ("《" . "》") ("[" . "]") ("[" . "]") - ("〔" . "〕") ("【" . "】") ("\"" . "\"") ("“" . "”") ("`" . "'")) -@end group +(("「" . "」") ("『" . "』") ("(" . ")") ("(" . ")") ("@{" . "@}") + ("{" . "}") ("〈" . "〉") ("《" . "》") ("[" . "]") ("[" . "]") + ("〔" . "〕") ("【" . "】") ("\"" . "\"") ("“" . "”") ("`" . "'")) @end lisp -これは、ひと言でまとめると、「開き括弧と閉じ括弧とのコンスセルを集めたリ -スト」です。各コンスセルの @code{car} にある文字列を挿入したときに、 -@code{cdr} にある文字列が自動挿入されます。 -@vindex skk-rom-kana-rule-list -@footnote{このリストの各要素の @code{car} の文字列は、必ず変数 -@code{skk-rom-kana-rule-list} の規則によって入力されなければなりません。 -例えば、@samp{(} に対する @samp{)} を自動挿入するには +これは、ひと言でまとめると、「開き括弧と閉じ括弧とのコンスセルを集めた +リスト」です。各コンスセルの @code{car} にある文字列を挿入したときに @code{cdr} に +ある文字列が自動挿入されます。 + +このリストの各要素の @code{car} の文字列は、必ず変数 @code{skk-rom-kana-rule-list} の +規則によって入力されなければなりません。例えば、 @code{(} に対する @code{)} を自 +動挿入するには @lisp -@group (setq skk-rom-kana-rule-list (append skk-rom-kana-rule-list - '(("(" nil "(")))) -@end group + '(("(" nil "(")))) @end lisp -@noindent -のように設定する必要があります。} -@footnote{既に SKK モードになっているバッファで変数 -@code{skk-auto-paren-string-alist} を変更した場合は、@kbd{C-x C-j} もし -くは @kbd{C-x j} を 2 度タイプして @code{skk-mode} もしくは -@code{skk-auto-fill-mode} を起動し直す必要があります。} +のように設定する必要があります。 -@end defvr +既に SKK モードになっているバッファで変数 @code{skk-auto-paren-string-alist} を +変更した場合は、 @code{C-x C-j} もしくは @code{C-x j} を2度キー入力して @code{skk-mode} も +しくは @code{skk-auto-fill-mode} を起動し直す必要があります。 +@end defvar キーとなる文字が挿入されても、その挿入後のポイントに自動挿入すべき文字が 既に存在している場合には、自動挿入されないように設計されています。 @example -@group ------- Buffer: foo ------ -@point{}」 ------- Buffer: foo ------ - -@kbd{[} - ------- Buffer: foo ------ -「@point{}」 ------- Buffer: foo ------ - -@end group + ------ Buffer: foo ------ + *」 + ------ Buffer: foo ------ + +[ + + ------ Buffer: foo ------ + 「*」 + ------ Buffer: foo ------ @end example 対になる文字を複数挿入したい場合は、引数を渡して文字を指定します。 @example -@group - -@kbd{C-u 2 [} +C-u 2 [ ------- Buffer: foo ------ -「「@point{}」」 ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 「「*」」 + ------ Buffer: foo ------ @end example -@vindex yatex-mode -@code{yatex-mode} など、既に同様の機能が付いているモードがあります。その -ようなモードにおいてもこの自動挿入の機能が邪魔になることはないでしょうが、 -特定のモードに限って自動入力機能をオフにしたい場合は、当該モードに入った -ときにコールされるフック変数を利用して設定することができます。 +@cindex yatex-mode +@code{yatex-mode} など、既に同様の機能が付いているモードがあります。そのような +モードにおいてもこの自動挿入の機能が邪魔になることはないでしょうが、特定 +のモードに限って自動入力機能をオフにしたい場合は、当該モードに入ったとき +にコールされるフック変数を利用して設定することができます。 @lisp -@group (add-hook 'yatex-mode-hook (lambda () (when skk-auto-insert-paren (make-local-variable 'skk-auto-insert-paren) (setq skk-auto-insert-paren nil)))) -@end group @end lisp 特定のモードにおいて、自動挿入すべき文字を変更したい場合にも同様にフック 変数を用いて操作できます。 -@vindex tex-mode-hook +@cindex tex-mode-hook @lisp -@group (add-hook 'tex-mode-hook (lambda () (when skk-auto-insert-paren (make-local-variable 'skk-auto-paren-string-alist) (setq skk-auto-paren-string-alist (cons '("$" . "$") skk-auto-paren-string-alist))))) -@end group @end lisp -@noindent 同様に、特定のペアを削除したい場合は、例えば下記のように設定します。 -@c @footnote{何故関数 @code{copy-sequence} を使用するのかについては、 -@c @w{@ref{数字や記号文字の入力}} を参照してください。}。 @lisp -@group (add-hook 'tex-mode-hook (lambda () (when skk-auto-insert-paren @@ -5276,7 +5293,6 @@ (delete '("$" . "$") (copy-sequence skk-auto-paren-string-alist)))))) -@end group @end lisp @node リージョンを括弧で囲む @@ -5285,388 +5301,299 @@ 「閉じ括弧の自動入力」の応用として、リージョンを括弧で囲むことができます。 @example -@group ------- Buffer: foo ------ -このマニュアルにおいて@point{}DDSKK@point{}と呼びます ------- Buffer: foo ------ + ------ Buffer: foo ------ + このマニュアルにおいて*DDSKK*と呼びます + ------ Buffer: foo ------ -@kbd{`} +` ------- Buffer: foo ------ -このマニュアルにおいて`DDSKK'と呼びます ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + このマニュアルにおいて`DDSKK'*と呼びます + ------ Buffer: foo ------ @end example -@defvr {ユーザ変数} skk-use-auto-enclose-pair-of-region + +@defopt skk-use-auto-enclose-pair-of-region + @code{non-nil} であれば、上記の機能が有効になります。 当然に @code{skk-auto-insert-paren} も @code{non-nil} である必要があります。 - -なお、@code{delete-selection-mode} の方が優先されます。 -@end defvr +なお、 @code{delete-selection-mode} の方が優先されます。 +@end defopt @node 確定するキー @subsection 確定するキー -@kindex C-j - -@defvr {ユーザ変数} skk-kakutei-key -この変数の値は、明示的な確定動作を行うキーを指定します。 -標準設定では @kbd{C-j} となっています。 +@kindex C-j +@defvar skk-kakutei-key -@end defvr +この変数の値は、明示的な確定動作を行うキーを指定します。標準設定では @code{C-j} と +なっています。 -関連事項: @w{@ref{暗黙の確定のタイミング}} +@ref{暗黙の確定のタイミング}. +@end defvar @node 候補の選択に用いるキー @subsection 候補の選択に用いるキー -変換において、候補が5つ以上あるときは、5番目以降の候補は7つずつ -まとめてエコーエリアに下記のように表示されます -@footnote{@ref{▼モード}.}。 +変換において、候補が5つ以上あるときは、5番目以降の候補は7つずつまとめ +てエコーエリアに下記のように表示されます @footnote{@ref{▼モード}.} 。 @example -@group -------------------- Echo Area -------------------- A:嘘 S:拒 D:拠 F:虚 J:挙 K:許 L:渠 [残り 2] -------------------- Echo Area -------------------- -@end group @end example この際、候補の選択に用いるキーは、次の変数によって決定されます。 -@defvr {ユーザ変数} skk-henkan-show-candidates-keys +@defvar skk-henkan-show-candidates-keys -7つの異なる文字のリスト。文字は必ず小文字とする -@footnote{@kbd{x}, @key{SPC} 及び @kbd{C-g} は、それぞれ候補選択中に -おける前候補群の表示、次候補群の表示、取り止めのために割り付けられている -ので、@code{skk-henkan-show-candidates-keys} の中に含めてはいけません。}。 -デフォルトは、以下のとおり。 +7つの異なる文字のリスト。文字は必ず小文字とする。 @code{x} , @code{SPC} 及び @code{C-g} は、 +それぞれ候補選択中における前候補群の表示、次候補群の表示、取り止めのた +めに割り付けられているので、含めてはならない。標準設定は、以下のとおり。 @lisp (?a ?s ?d ?f ?j ?k ?l) @end lisp -@end defvr +@end defvar + +@defvar skk-henkan-show-candidates-keys-face -@c メニューによる文字入力 -@c @footnote{@w{@ref{文字コードまたはメニューによる文字入力}}.}の際に候補の選択 -@c に用いられるキーは、次の2つの変数により変更されます。 -@c -@c @defvr {ユーザ変数} skk-input-by-code-menu-keys1 -@c -@c 第1段階のメニューにおける候補の選択キー。デフォルトは、 -@c -@c @lisp -@c (?a ?s ?d ?f ?g ?h ?q ?w ?e ?r ?t ?y) -@c @end lisp -@c -@c @noindent -@c です。このリストには 12 個の異なる文字を含む必要があります。 -@c -@c @end defvr -@c -@c @defvr {ユーザ変数} skk-input-by-code-menu-keys2 -@c -@c 第2段階のメニューにおける候補の選択キー。デフォルトは、 -@c -@c @lisp -@c (?a ?s ?d ?f ?g ?h ?j ?k ?l ?q ?w ?e ?r ?t ?y ?u) -@c @end lisp -@c -@c @noindent -@c です。このリストには 16 個の異なる文字を含む必要があります。 -@c @end defvr -@c -@c 上記の2つの変数の要素は@b{全て小文字で指定すること}を強くお勧めします -@c @footnote{小文字が指定された場合は、候補の選択の際に対応する大文字キーが -@c 入力されても候補の選択が可能となるように設計されています。その一方で、大 -@c 文字が指定された場合、候補の選択の際に対応する小文字キーが入力されても候 -@c 補の選択ができません。これは現在の仕様です。}。 -@c -@defvr {ユーザ変数} skk-henkan-show-candidates-keys-face 選択キーを表示する際のフェイスを指定します。 -@end defvr +@end defvar + +@defvar skk-henkan-rest-indicator + +標準設定は @code{nil} 。 @code{Non-nil} であれば @code{[残り 99++]} の表示を右寄せ配 +置する。 +@end defvar -@defvr {ユーザ変数} skk-henkan-rest-indicator -デフォルトは @code{nil}。@code{Non-nil} であれば @samp{[残り 99++]} の表示を右寄せ配置する。 -@end defvr - -@defvr {ユーザ変数} skk-henkan-rest-indicator-face -@samp{[残り 99++]} の face 属性。デフォルトは @code{default}。 -@end defvr +@defvar skk-henkan-rest-indicator-face -@node ▼モードでのRET -@subsection ▼モードでのRET +@code{[残り 99++]} の face 属性。標準設定は @code{default} 。 +@end defvar + +@node ▼モードでの RET +@subsection ▼モードでの RET 標準設定では、 @example -@kbd{K a k u t e i @key{SPC}} +K a k u t e i SPC -@group ------- Buffer: foo ------ -▼確定@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼確定* + ------ Buffer: foo ------ -@key{RET} +RET -@group ------- Buffer: foo ------ -確定 -@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 確定 + * + ------ Buffer: foo ------ @end example @noindent -のように、▼モードで @key{RET} を入力すると、確定し、かつ改行を行います。 -この挙動を変えるためのユーザオプションが用意されています。 - -@defvr {ユーザ変数} skk-egg-like-newline +のように、▼モードで @code{RET} を入力すると、確定し、かつ改行を行います。この +挙動を変えるためのユーザオプションが用意されています。 -この変数の値を @code{non-nil} にすると、▼モードで @key{RET} を入力した -ときに確定のみ行い、改行はしません@footnote{従って、辞書登録モードにおいて▼モードであるときの @key{RET} -入力時の挙動も変化します。標準の確定、登録の動作については、 -@w{@ref{辞書登録モード}} を参照してください。}。 +@defopt skk-egg-like-newline -@end defvr +この変数の値を @code{non-nil} にすると、▼モードで @code{RET} を入力したときに確 +定のみ行い、改行はしません。従って、辞書登録モードにおいて▼モードであ +るときの @code{RET} 打鍵時の挙動も変化 @footnote{辞書登録モードの標準の確定、登録の動作は @ref{辞書登録モード}.} します。 @example -@kbd{K a k u t e i @key{SPC}} +K a k u t e i SPC -@group ------ Buffer: foo ------ -▼確定@point{} +▼確定* ------ Buffer: foo ------ -@end group -@key{RET} +RET -@group ------ Buffer: foo ------ -確定@point{} +確定* ------ Buffer: foo ------ -@end group @end example +@end defopt -@node ▼モードでのBS -@subsection ▼モードでのBS -@kindex @key{BS} +@node ▼モードでの BS +@subsection ▼モードでの BS -標準設定では、▼モードで @key{BS} を押すと、前の一文字を削除した上で確定 -します。 +標準設定では、▼モードで @code{BS} を押すと、前の一文字を削除した上で確定しま +す。 @example -@kbd{D e n k i y a @key{SPC}} +D e n k i y a SPC -@group ------- Buffer: foo ------ -▼電気屋@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼電気屋* + ------ Buffer: foo ------ -@key{BS} +BS -@group ------- Buffer: foo ------ -電気@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 電気* + ------ Buffer: foo ------ @end example -@defvr {ユーザ変数} skk-delete-implies-kakutei +@defopt skk-delete-implies-kakutei -この変数の値を @code{nil} に設定すると、▼モードで @key{BS} を押した時 -に一つ前の候補を表示します。例えば、 +この変数の値を @code{nil} に設定すると、▼モードで @code{BS} を押した時にひとつ前 +の候補を表示します。例えば、 @example -でんき /電気/伝記/ + でんき /電気/伝記/ @end example -@noindent という辞書エントリがあるとき、以下のようになります。 +@end defopt @example -@kbd{D e n k i} +D e n k i -@group ------- Buffer: foo ------ -▽でんき@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽でんき* + ------ Buffer: foo ------ -@key{SPC} +SPC -@group ------- Buffer: foo ------ -▼電気@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼電気* + ------ Buffer: foo ------ -@key{SPC} +SPC -@group ------- Buffer: foo ------ -▼伝記@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼伝記* + ------ Buffer: foo ------ -@key{BS} +BS -@group ------- Buffer: foo ------ -▼電気@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼電気* + ------ Buffer: foo ------ -@key{BS} +BS -@group ------- Buffer: foo ------ -▽でんき@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽でんき* + ------ Buffer: foo ------ @end example -@end defvr -変数 @code{skk-delete-implies-kakutei} がシンボル @code{dont-update} で -あれば、@code{non-nil} 時と同じ動作のうえで個人辞書を更新しません。 +変数 @code{skk-delete-implies-kakutei} がシンボル @code{dont-update} であれば、 +@code{non-nil} 時と同じ動作のうえで個人辞書を更新しません。 なお、変数 @code{skk-delete-implies-kakutei} の値にかかわらず、*候補*バッファ -を表示している場合は一つ前の候補表示に戻る動作となります。 +を表示している場合はひとつ前の候補表示に戻る動作となります。 -@node 送りあり変換中のC-g -@subsection 送りあり変換中のC-g -@kindex C-g +@node 送りあり変換中の C-g +@subsection 送りあり変換中の C-g -送りありの変換中に @kbd{C-g} を入力すると、▼モードを抜け、その見出し語 -と送り仮名を現在のバッファに挿入し、▽モードに入ります。 +送りありの変換中に @code{C-g} を入力すると、▼モードを抜け、その見出し語と送り +仮名を現在のバッファに挿入し、▽モードに入ります。 @example -@kbd{N a K u} +N a K u -@group ------- Buffer: foo ------ -▼泣く@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼泣く* + ------ Buffer: foo ------ -@kbd{C-g} +C-g -@group ------- Buffer: foo ------ -▽なく@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽なく* + ------ Buffer: foo ------ @end example -@defvr {ユーザ変数} skk-delete-okuri-when-quit +@defopt skk-delete-okuri-when-quit -この変数の値を @code{non-nil} に設定すると、送りありの変換中に @kbd{C-g} を -入力したときの挙動が変化します。▽モードに入るのは同じですが、同時に -送り仮名を消します。送り仮名の入力間違いを修正するのには便利です。 -例えば、以下のようになります。 -@end defvr +この変数の値を @code{non-nil} に設定すると、送りありの変換中に @code{C-g} を入力 +したときの挙動が変化します。▽モードに入るのは同じですが、同時に送り仮 +名を消します。送り仮名の入力間違いを修正するのには便利です。例えば、以 +下のようになります。 @example -@kbd{N a K u} +N a K u -@group ------- Buffer: foo ------ -▼泣く@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼泣く* + ------ Buffer: foo ------ -@kbd{C-g} +C-g -@group ------- Buffer: foo ------ -▽な@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽な* + ------ Buffer: foo ------ @end example +@end defopt @node 変換位置の指定方法 @subsection 変換位置の指定方法 -@cindex @file{skk-sticky.el} -@kindex ; -SKK では通常、「漢字変換の開始位置」と「送り仮名の開始位置」を大文字で指定します -が、これらを任意のキーで指定することで sticky-shift ライクな操作 -@footnote{あくまでも「任意のキーで変換開始位置を指定する」ものであり、 -sticky-shift そのものではありません。したがって、アスキーモードや -abbrev モード、また SKK 以外でも sticky-shift を使いたい場合は前述のような -設定を併用する必要があります。}も可能です。 +SKK では通常、「漢字変換の開始位置」と「送り仮名の開始位置」を大文字で指 +定しますが、これらを任意のキーで指定することで sticky-shift ライクな +操作 @footnote{あくまでも「任意のキーで変換開始位置を指定する」ものであり、 +sticky-shift そのものではありません。したがって、アスキーモードや SKK abbrev モード、 +また SKK 以外でも sticky-shift を使いたい場合は、前述のような設定を併用す +る必要があります。} も可能です。 @lisp (setq skk-sticky-key ";") @end lisp @noindent -と設定すると @kbd{;} キーで -@footnote{@file{skk-hint.el} を併用する場合は @code{skk-hint-start-char} -のデフォルトも @kbd{;} であるため、どちらかを別のキーに割り当てる必要が -あります。@w{@pxref{候補の絞り込み}}} 漢字変換位置が指定できるようになり -ます。 +と設定すると @code{;} キーで @footnote{@code{skk-hint.el} を併用する場合は @code{skk-hint-start-char} の標準 +設定も @code{;} であるため、どちらかを別のキーに割り当てる必要があります。 + +@ref{候補の絞り込み}.} 漢字変換位置が指定できるようになりま +す。 -例えば @samp{有る} という単語を入力するには +例えば「有る」という単語を入力するには @example -@kbd{; a ; r u} +; a ; r u @end example +@noindent というキー入力で可能となり、シフトキーを押す必要がなくなります。 -操作上は -@w{@pxref{Q3-4 左手の小指を SHIFT で酷使したくありません。}} などにある通 -常の sticky-shift と変わりませんが、画面表示は - -@display -@group -@multitable {打鍵 } {通常の@tie{}sticky} {skk-sticky} -@item 打鍵 -@tab 通常の@tie{}sticky -@tab skk-sticky -@item @kbd{;} -@tab 変化なし -@tab ▽ -@item @kbd{a} -@tab ▽あ -@tab ▽あ -@item @kbd{;} -@tab ▽あ -@tab ▽あ* -@item @kbd{r} -@tab ▽あ*r -@tab ▽あ*r -@end multitable -@end group -@end display +操作上は通常の sticky-shift @footnote{@ref{Q3-4 左手の小指を SHIFT で酷使したくありません。}.} と変わりませんが、画面表示は + +@example +打鍵 通常の sticky skk-sticky +; 変化なし ▽ +a ▽あ ▽あ +; ▽あ ▽あ* +r ▽あ*r ▽あ*r +@end example @noindent -と遷移します。通常の sticky と比べて skk-sticky は @kbd{;} を押した時点で -画面表示が変化するので若干分かり易いと思います。 +と遷移します。通常の sticky と比べて skk-sticky は @code{;} を押した時点で画面 +表示が変化するので若干分かり易いと思います。 キーの設定方法は、割り当てるキーの種類によって異なります。 -@enumerate +@itemize @item 表示を伴うキー -@kbd{;} などの表示を伴うキーの場合は +@code{;} などの表示を伴うキーの場合は @lisp (setq skk-sticky-key ";") @end lisp -のように @code{string} を設定して下さい。@code{skk-sticky-key} に設定した -文字そのものを入力したい場合は2回続けて打つと入力できます。 +のように @code{string} を設定して下さい。 @code{skk-sticky-key} に設定した文字そ +のものを入力したい場合は2回続けて打鍵すると入力できます。 + @item 表示を伴わないキー -【@key{無変換}】のような表示を伴わないキーの場合は +【無変換】のような表示を伴わないキーの場合は @lisp (setq skk-sticky-key [muhenkan]) ;Microsoft Windows では [noconvert] @@ -5674,11 +5601,12 @@ のようにそのキーを表わす @code{vector} を設定して下さい。 + @item 同時打鍵 2つのキーを同時に打鍵することでも漢字変換位置を指定できます。例えば -@kbd{f} と @kbd{j} の同時打鍵で指定する場合は +@code{f} と @code{j} の同時打鍵で指定する場合は @lisp (setq skk-sticky-key '(?f ?j)) @@ -5686,166 +5614,148 @@ のように @code{character} のリストを設定して下さい。 -Dvorak 配列のような、押しやすい場所に適当なキーがない環境でもこの機能を使 -いたい場合に便利かもしれません。 -@end enumerate +Dvorak 配列のような、押しやすい場所に適当なキーがない環境でもこの機能を +使いたい場合に便利かもしれません。 + +@end itemize -@defvr {ユーザ変数} skk-sticky-double-interval +@defvar skk-sticky-double-interval この変数が指定する秒数以内に打鍵されたものを同時打鍵と判定する。 -デフォルトは 0.1 秒。 - -@end defvr +標準設定は 0.1 秒。 +@end defvar -@node 1回の取り消し操作(undo)の対象 -@subsection 1回の取り消し操作(undo)の対象 -@cindex @file{keyboard.c} -@findex self-insert-command -@findex skk-abbrev-comma -@findex skk-abbrev-period -@findex skk-kana-input -@findex skk-insert -@findex skk-set-henkan-point -@findex skk-jisx0208-latin-insert -@vindex skk-self-insert-non-undo-count +@node 1回の取り消し操作 (undo) の対象 +@subsection 1回の取り消し操作 (undo) の対象 -Emacs では本来、連続する 20 文字の挿入が一回の取り消し操作 (アンドゥ) の +Emacs では本来、連続する 20 文字の挿入が一回の取り消し操作(アンドゥ)の 対象となっています。そこで DDSKK のかな・カナ・全英モードにおける入力も、 -これと同様の動作をするように設計されています -@footnote{@code{buffer-undo-list} に Emacs が挿入したアンドゥの境目の目印を -取り除く方法でエミュレートしています。}。正確に言えば、 -@code{skk-insert}, @code{skk-set-henkan-point}, -@code{skk-jisx0208-latin-insert} -@footnote{SKK abbrev モードでは、アスキー文字入力が Emacs 本来の -@code{self-insert-command} により行われているので、エミュレーションの -ための内部変数である @code{skk-self-insert-non-undo-count} をインクリメ -ントすることができず、アンドゥをエミュレートできません。しかも、カンマや -ピリオドを挿入した時点で、コマンド @code{skk-abbrev-comma} や -@code{skk-abbrev-period} を使うことになるので、本来のアンドゥの機能も損 -なってしまいます。ただし、現実問題として、元来 SKK abbrev モードは省略形 -としての見出し語を挿入するためのモードですから、長い見出し語を挿入するこ -とはあまりないと考えられます。}の各関数にバインドされたキー入力について -は、連続して入力された 20 文字を 1 つのアンドゥの対象としています -@footnote{`20' は Emacs のソースファイルの一部である @file{keyboard.c} -に定められたマジックナンバーと一致します。}。 - -ただし、これらの DDSKK のコマンドと Emacs 本来の -@code{self-insert-command} を織り混ぜてキー入力した場合 -@footnote{かなモードでの入力中、アスキーモードに移行して入力した場合など -がこれにあたります。}は、このエミュレーションは正常に動作しませんが、こ -れは現在の仕様です。 - -@example -@group -@kbd{a i u e o k a k i k u k e k o s a s i s u s e s o t a t i t u t e t o} - -------------------------- Buffer: foo ------------------------- -あいうえおかきくけこさしすせそたちつてと@point{} ;@r{連続する20文字。} -------------------------- Buffer: foo ------------------------- -@end group -@group - -@kbd{C-_} - -------------------------- Buffer: foo ------------------------- -@point{} ;@r{20文字全てがアンドゥの対象となる。} -------------------------- Buffer: foo ------------------------- -@end group - -@group -@kbd{a i u e o k a k i k u k e k o s a s i s u s e s o t a t i t u t e t o n a} - --------------------------- Buffer: foo -------------------------- -あいうえおかきくけこさしすせそたちつてとな@point{} ;@r{連続する21文字。} --------------------------- Buffer: foo -------------------------- -@end group -@group - -@kbd{C-_} - --------------------------- Buffer: foo -------------------------- -あいうえおかきくけこさしすせそたちつてと@point{} ;@r{最後の1文字のみがアンドゥの対象となる。} --------------------------- Buffer: foo -------------------------- -@end group +これと同様の動作をするように設計されています @footnote{@code{buffer-undo-list} に Emacs が挿入したアンドゥの境目の目印を取り +除く方法でエミュレートしています。} 。正確に言えば、 +@code{skk-insert} , @code{skk-set-henkan-point} , @code{skk-jisx0208-latin-insert} @footnote{SKK abbrev モードでは、アスキー文字入力が Emacs 本来の @code{self-insert-command} に +より行われているので、エミュレーションのための内部変数である @code{skk-self-insert-non-undo-count} を +インクリメントすることができず、アンドゥをエミュレートできません。しかも、 +カンマやピリオドを挿入した時点で、コマンド @code{skk-abbrev-comma} や @code{skk-abbrev-period} を +使うことになるので、本来のアンドゥの機能も損なってしまいます。ただし、現 +実問題として、元来 SKK abbrev モードは省略形としての見出し語を挿入するた +めのモードですから、長い見出し語を挿入することはあまりないと考えられます。} の +各関数にバインドされたキー入力については、連続して入力された 20 文字をい +ちどのアンドゥの対象としています @footnote{20 は Emacs のソースファイルの一部である @code{keyboard.c} に定められ +たマジックナンバーと一致します。} 。 + +ただし、これらの DDSKK のコマンドと Emacs 本来の @code{self-insert-command} を +織り混ぜてキー入力した場合 @footnote{かなモードでの入力中、アスキーモードに移行して入力した場合など +がこれにあたります。} は、このエミュレーションは正常に動作 +しませんが、これは現在の仕様です。 + +@example +a i u e o k a k i k u k e k o s a s i s u s e s o t a t i t u t e t o + + ------------------------- Buffer: foo ------------------------- + あいうえおかきくけこさしすせそたちつてと* ※ 連続する20文字 + ------------------------- Buffer: foo ------------------------- + +C-_ + + ------------------------- Buffer: foo ------------------------- + * ※ 20文字全てがアンドゥの対象 + ------------------------- Buffer: foo ------------------------- + +a i u e o k a k i k u k e k o s a s i s u s e s o t a t i t u t e t o n a + + -------------------------- Buffer: foo -------------------------- + あいうえおかきくけこさしすせそたちつてとな* ※ 連続する21文字 + -------------------------- Buffer: foo -------------------------- + +C-_ + + -------------------------- Buffer: foo -------------------------- + あいうえおかきくけこさしすせそたちつてと* ※ 最後の1文字のみがアンドゥの対象 + -------------------------- Buffer: foo -------------------------- @end example @node 変換、確定の前後 @section 変換、確定の前後 -@menu -* ポイントを戻して▽モードへ:: ▽モードに入り忘れた! -* 直前の確定を再変換:: 間違って確定したら、再変換 -* 自動変換開始:: @key{SPC} を押さなくても「を」「。」で変換開始。 -* 暗黙の確定のタイミング:: 変換の後、いつ確定するか。 -* 積極的な確定:: 候補が一つ? じゃ確定でしょ。 -* 確定辞書:: 特定の語は一発確定 -@end menu - 関連事項: -@itemize @bullet -@item @w{@ref{送りあり変換の変換開始のタイミング}} -@item @w{@ref{変換位置の指定方法}} (大文字以外で変換位置を指定する方法を説明) + +@itemize +@item +@ref{送りあり変換の変換開始のタイミング}. + + +@item +@ref{変換位置の指定方法}. @end itemize + +@menu +* ポイントを戻して▽モードへ:: +* 直前の確定を再変換:: +* 自動変換開始:: +* 暗黙の確定のタイミング:: +* 積極的な確定:: +* 確定辞書:: +@end menu + @node ポイントを戻して▽モードへ @subsection ポイントを戻して▽モードへ -@cindex 後から▽モードに入る方法 -@findex skk-backward-and-set-henkan-point -@vindex skk-allow-spaces-newlines-and-tabs - -▽モードに入り忘れた場合に、手動で▽マークを付ける方法については、前述しました -@footnote{@w{@xref{後から▽モードに入る方法}.}}。 -ここで述べる方法では、遡って▽マークを付ける位置を自動的に選び、しかもカーソルは動きません。 +▽モードに入り忘れた場合に、手動で▽マークを付ける方法 (@ref{後から▽モードに入る方法}.) に +ついては、前述しました。 + +ここで述べる方法では、遡って▽マークを付ける位置を自動的に選び、しかもポ +イントは動きません。 + +@table @asis @kindex M-Q -@kbd{M-Q} -(大文字の @samp{Q} です。) とタイプすると現在位置の直前の文字列について走査し、 -同種の文字 @footnote{ひらがな、カタカナ、全角アルファベット、アルファベットの 4 種 -類のいずれか。}が続く限り後方に戻り、▽マークを付けます。ポイントは動きません。 +@cindex skk-backward-and-set-henkan-point +@item @kbd{M-Q} @tie{}@tie{}@tie{}@tie{}(@code{skk-backward-and-set-henkan-point}) + +@code{M-Q} (大文字の @code{Q} です。)と打鍵すると、現在位置の直前の文字列につい +て走査し、同種の文字(ひらがな、カタカナ、全角アルファベット、アルファ +ベットの4種類のいずれか)が続く限り後方に戻って▽マークを付けます。ポ +イントは動きません。 @example -@kbd{k a n j i} +k a n j i -@group ------- Buffer: foo ------ -かんじ@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + かんじ* + ------ Buffer: foo ------ -@kbd{M-Q} +M-Q -@group ------- Buffer: foo ------ -▽かんじ@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽かんじ* + ------ Buffer: foo ------ @end example -変換開始位置を決定するとき、スペース文字、タブ文字、長音を表わす @samp{ー} -は無条件に無視されます。ただし、ひらがなの場合は @samp{を} が、カタカナ -の場合は @samp{ヲ} が見つかった時点で変換開始位置の走査を止め、▽モードに -入ります。変換開始ポイントを @samp{を}、@samp{ヲ} の直前で止めるのは、たい -ていその直後から単語が始まるからです。 - -以上は @kbd{M-Q} を引数を与えないで実行した場合です。一方で、@kbd{C-u 5 -M-Q} のように引数を渡して実行すると、変換開始位置から現在位置までの文字 -数を指定することができます。この場合は文字種別を問わず、与えられた文字数 -だけ無条件にポイントを戻します。 - -@vindex skk-allow-spaces-newlines-and-tabs -後方にポイントを戻す途中で行頭に到達した場合は、更に上の行について、行末 -の文字列から同様の走査を行い、必要があれば更にポイントを戻します。こうし -た「行を超えての走査」をやめるためには、変数 -@code{skk-allow-spaces-newlines-and-tabs} の値を @code{nil} に設定します。 +変換開始位置を決定するとき、スペース文字、タブ文字、長音を表わす「ー」 +は無条件に無視されます。ただし、ひらがなの場合は「を」が、カタカナの場 +合は「ヲ」が見つかった時点で変換開始位置の走査を止めて▽モードに入りま +す。変換開始ポイントを「を」又は「ヲ」の直前で止めるのは、たいていその +直後から単語が始まるからです。 +@end table + +以上は、引数を与えないで @code{M-Q} を実行した場合です。一方で、 @code{C-u 5 M-Q} の +ように引数を渡して実行すると、変換開始位置から現在位置までの文字数を指定 +することができます。この場合は文字種別を問わず、与えられた文字数だけ無条 +件にポイントを戻します。 + +@defopt skk-allow-spaces-newlines-and-tabs + +後方にポイントを戻す途中で行頭に到達した場合は、更に上の行について、行 +末の文字列から同様の走査を行い、必要があれば更にポイントを戻します。こ +うした「行を超えての走査」をやめるためには、この変数の値を @code{nil} に設定 +します。 +@end defopt @node 直前の確定を再変換 @subsection 直前の確定を再変換 -@cindex 確定アンドゥ -@cindex 再変換 -@kindex M-x skk-undo-kakutei 一番最後(直近)の確定を取り消して、再変換することができます。 -これを@b{「確定アンドゥ」}と呼びます。 +これを @strong{確定アンドゥ} と呼びます。 例えば、辞書エントリが @@ -5857,275 +5767,242 @@ のようになっているとします。 @example -@kbd{K o u k o u @key{SPC}} +K o u k o u SPC -@group ------- Buffer: foo ------ -▼高校@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼高校* + ------ Buffer: foo ------ -@kbd{s u r u} +s u r u -@group ------- Buffer: foo ------ -高校する@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 高校する* + ------ Buffer: foo ------ -@kbd{M-x skk-undo-kakutei} +M-x skk-undo-kakutei -@group ------- Buffer: foo ------ -▼孝行@point{}する ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼孝行* + ------ Buffer: foo ------ @end example -@noindent -この例では、@samp{高校} の確定を取り消しています。すると、辞書の第 -一候補である @samp{高校} をとばして、次候補である @samp{孝行} が現れます。 -ここで更に @key{SPC} を押せば次候補である @samp{航行} が現れ、更にもう一 -度 @key{SPC} を押せば候補が尽きて辞書登録モードに入ります。 - -この例のとおり、確定アンドゥは、確定した直後でなくとも有効です。 -より正確には、次の新たな確定 -@footnote{@kbd{C-j} をタイプして明示的に確定した場合は勿論、「暗黙の確定 -」を行った場合も同様です。}を行うまでは確定に関する情報が保持されている -ので、確定アンドゥすることができます。 - -また、変換、確定に関連しない文字列は、確定アンドゥを行っても削除されな -いように設計されています。上記の例では、@samp{する} がそのままカレントバ -ッファに残っています。 +この例では、「高校」の確定を取り消しています。すると、辞書の第一候補であ +る「高校」をとばして、次候補である「孝行」が現れます。ここで更に @code{SPC} を +押せば次候補である「航行」が現れ、更にもう一度 @code{SPC} を押せば候補が尽きて +辞書登録モードに入ります。 -@defvr {ユーザ変数} skk-undo-kakutei-return-previous-point +この例のとおり、確定アンドゥは、確定した直後でなくとも有効です。より正確 +には、次の新たな確定を行うまで @footnote{@code{C-j} を打鍵して明示的に確定した場合は勿論、「暗黙の確定」を +行った場合も同様です。} は確定に関する情報が保持され +ているので、確定アンドゥすることができます。 -この変数の値が @code{non-nil} であれば、確定アンドゥ処理が完了した後に、 -確定アンドゥ処理の直前の位置にカーソルが戻ります。 +また、変換、確定に関連しない文字列は、確定アンドゥを行っても削除されない +ように設計されています。上記の例では「する」がそのままカレントバッファに +残っています。 -上の例の場合、確定アンドゥ処理が完了した後のカーソル位置は、デフォル -ト @code{nil} では @samp{孝行} の直後のままですが、@code{non-nil} であれ -ば @samp{する} の直後に復帰します。 +@defopt skk-undo-kakutei-return-previous-point -@end defvr +この変数の値が @code{non-nil} であれば、確定アンドゥ処理が完了した後に、確定 +アンドゥ処理の直前の位置にカーソルが戻ります。上の例の場合、確定アンド +ゥ処理が完了した後のカーソル位置は、標準設定 @code{nil} では「孝行」の直後 +のままですが、 @code{non-nil} であれば「する」の直後に復帰します。 +@end defopt @node 自動変換開始 @subsection 自動変換開始 ▽モードで見出し語を入力しているときに「を」や「。」などの文字を打鍵する -と、@key{SPC} を押したかのように変換を開始@footnote{▽マークからポイント -の直前の文字までを見出し語とします。最後に入力された文字(「を」や「。」 -)は見出し語には含まれません。}し、▼モードに入るようになっています。 +と、 @code{SPC} を押したかのように変換を開始 @footnote{▽マークからポイントの直前の文字までを見出し語とします。 +打鍵に入力された文字(「を」や「。」)は見出し語には含まれません。} し、▼モードに入 +るようになっています。 @example -@kbd{K a n j i} +K a n j i -@group ------- Buffer: foo ------ -▽かんじ@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽かんじ* + ------ Buffer: foo ------ -@group +w o -@kbd{w o} ------- Buffer: foo ------ -▼漢字を@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼漢字を* + ------ Buffer: foo ------ +@end example + +@defopt skk-auto-okuri-process + +この変数を @code{non-nil} に設定して送り仮名の自動処理 @footnote{@ref{送り仮名の自動処理}.} を行ってい +る場合は、以下のような変換も可能です。ただし、個人辞書に + +@example + できr /出来/[る/出来/]/ @end example -@vindex skk-auto-okuri-process -変数 @code{skk-auto-okuri-process} の値を @code{non-nil} に設定して 送り -仮名の自動処理 @w{(@pxref{送り仮名の自動処理})} を行っている場合は、以下 -のような変換も可能です。ただし、個人辞書に @samp{できr /出来/[る/出来/]/} というようなエントリがあると仮定します。 @example -@kbd{D e k i r u n n d e s u} +D e k i r u n n d e s u -@group ------- Buffer: foo ------ -▽できるんです ------- Buffer: foo ------ -@end group -@group + ------ Buffer: foo ------ + ▽できるんです + ------ Buffer: foo ------ -@kbd{.} ------- Buffer: foo ------ -▼出来るんです。 ------- Buffer: foo ------ -@end group +. + + ------ Buffer: foo ------ + ▼出来るんです。 + ------ Buffer: foo ------ @end example +@end defopt -@defvr {ユーザ変数} skk-auto-start-henkan-keyword-list +@defvar skk-auto-start-henkan-keyword-list -この変数の値は、単語や文節の区切りとなるような文字列のリストです。 -デフォルトは以下のようになっています。 -@end defvr +この変数の値は、単語や文節の区切りとなるような文字列のリストです。標準 +設定は以下のようになっています。 @lisp -@group ("を" "、" "。" "." "," "?" "」" "!" ";" ":" ")" ";" ":" ")" "”" "】" "』" "》" "〉" "}" "]" "〕" "@}" "]" "?" "." "," "!" ) -@end group @end lisp +@end defvar -@defvr {ユーザ変数} skk-auto-start-henkan +@defvar skk-auto-start-henkan -この変数の値を @code{nil} に設定すると、本節で説明した自動変換開始機能 -を無効にします。デフォルトは @code{t} です。 -@end defvr +この変数の値を @code{nil} に設定すると、本節で説明した自動変換開始機能を無効 +にします。標準設定は @code{t} です。 +@end defvar @node 暗黙の確定のタイミング @subsection 暗黙の確定のタイミング -@cindex 暗黙の確定 -@vindex skk-process-okuri-early -標準の設定では、確定が済む前に次の文字を入力すると、 -直ちに確定されます -@footnote{正確には、印字可能な文字または @key{RET} が入力されたときです。}。 -これを「暗黙の確定」と呼んでいます。具体的には以下のようになります。 +標準の設定では、確定が済む前に次の文字 @footnote{正確には、印字可能な文字または @code{RET} が入力されたときです。} を入力すると、直ちに確 +定されます。これを「暗黙の確定」と呼んでいます。具体的には以下のようにな +ります。 @example -@kbd{K a k u t e i} +K a k u t e i -@group ------- Buffer: foo ------ -▽かくてい@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽かくてい* + ------ Buffer: foo ------ -@key{SPC} +SPC -@group ------- Buffer: foo ------ -▼確定@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼確定* + ------ Buffer: foo ------ -@kbd{s} +s -@group ------- Buffer: foo ------ -確定s@point{} ; 暗黙の確定 ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 確定s* ; 暗黙の確定 + ------ Buffer: foo ------ -@kbd{u} +u -@group ------- Buffer: foo ------ -確定す@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 確定す* + ------ Buffer: foo ------ @end example -@defvr {ユーザ変数} skk-kakutei-early +@defopt skk-kakutei-early -この変数の値を @code{nil} にすると、「暗黙の確定」を遅らせます。 -具体的には、 +この変数の値を @code{nil} にすると、「暗黙の確定」を遅らせます。具体的には、 -@itemize @bullet -@item 括弧 @kbd{(} @kbd{)} @kbd{[} @kbd{]} の入力時 -@item 句読点 @kbd{,} @kbd{.} の入力時 -@item 次の変換開始時 (@kbd{A} から @kbd{Z} までの大文字の入力時) -@item @key{RET} 入力時 -@end itemize +@itemize +@item +括弧 @code{(} @code{)} @code{[} @code{]} の入力時 + +@item +句読点 @code{,} @code{.} の入力時 + +@item +次の変換開始時( @code{A} から @code{Z} までの大文字の入力時) -まで暗黙の確定が遅延されます -@footnote{@code{skk-kakutei-early} の機能と -@code{skk-process-okuri-early} の機能を同時に有効にすることはできません。 -@code{skk-kakutei-early} の 値を @code{non-nil} にする場合は -@code{skk-process-okuri-early} の値を @code{nil} にする必要がありま -す。}。 -@end defvr +@item +@code{RET} 入力時 +@end itemize +まで暗黙の確定が遅延されます @footnote{@code{skk-kakutei-early} の機能と @code{skk-process-okuri-early} の +機能を同時に有効にすることはできません。 @code{skk-kakutei-early} の値を @code{non-nil} に +する場合は @code{skk-process-okuri-early} の値を @code{nil} にする必要があります。} 。 @example -@kbd{K a k u t e i} +K a k u t e i -@group ------- Buffer: foo ------ -▽かくてい@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽かくてい* + ------ Buffer: foo ------ -@key{SPC} +SPC -@group ------- Buffer: foo ------ -▼確定@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼確定* + ------ Buffer: foo ------ -@kbd{s} +s -@group ------- Buffer: foo ------ -▼確定s@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼確定s* + ------ Buffer: foo ------ -@kbd{u r u} +u r u -@group ------- Buffer: foo ------ -▼確定する@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼確定する* + ------ Buffer: foo ------ -@kbd{.} +. -@group ------- Buffer: foo ------ -確定する。@point{} ; 暗黙の確定 ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + 確定する。* ; 暗黙の確定 + ------ Buffer: foo ------ @end example +@end defopt @node 積極的な確定 @subsection 積極的な確定 -変換候補が一つしか見つからない場合は自動的に確定する、という設定ができます。 +変換候補がひとつしか見つからない場合は自動的に確定する、という設定ができ +ます。 -@defvr {ユーザ変数} skk-kakutei-when-unique-candidate +@defopt skk-kakutei-when-unique-candidate -この値が @code{non-nil} の場合、この機能が有効になります。 +この値が @code{non-nil} であれば、この機能が有効になります。 -@code{t} であれば送りあり変換、送りなし変換、abbrev モードでの変換、全て +@code{t} であれば送りあり変換、送りなし変換、SKK abbrev モードでの変換、全て でこの機能が有効になります。 -また、@samp{okuri-ari}, @samp{okuri-nasi}, @samp{abbrev} を要素とするリス -トであることもできます。その場合は変換対象がその条件に合致した場合のみ確 -定変換が機能します。 +また、 @code{okuri-ari} , @code{okuri-nasi} , @code{abbrev} を要素とするリストであるこ +ともできます。この場合は変換対象がその条件に合致した場合のみ確定変換が +機能します。 -例: @samp{'(okuri-nasi abbrev)} +@example +'(okuri-nasi abbrev) +@end example -この機能は、全ての辞書を検索した上で変換候補が唯一か否かを調べます。その -ため、@code{skk-search-prog-list} の内容によってはレスポンスが悪くなる可 -能性があります。(@w{@pxref{辞書の検索方法の設定}} +この機能は、全ての辞書を検索した上で変換候補が唯一か否かを調べます。そ +のため、 @code{skk-search-prog-list} の内容によってはレスポンスが悪くなる可 +能性があります。 -@end defvr +@ref{辞書の検索方法の設定}. +@end defopt -@defvr {ユーザ変数} skk-kakutei-search-prog-limit +@defvar skk-kakutei-search-prog-limit -この値が数値であった場合、積極的な確定(@code{skk-kakutei-when-unique-candidate}) に +この変数の値が数値であれば、積極的な確定 @code{skk-kakutei-when-unique-candidate} に おける「変換候補が唯一か否か」の判定を @code{skk-search-prog-list} の先頭か -ら数えてこの個数までの辞書に制限します。 +ら数えて当該数値の個数までの辞書に制限します。 数値以外であれば、無制限に全ての辞書を検索対象とします。 -@end defvr +@end defvar @node 確定辞書 @subsection 確定辞書 -@cindex 確定変換 -@cindex 確定辞書 -@findex skk-search-kakutei-jisyo-file -@vindex skk-kakutei-jisyo -特定の語は、変換したら即座に確定させる事ができます。これを@b{確定変換}と -呼び、利用するには「確定辞書」を用意します。例えば、 +特定の語は、変換したら即座に確定させる事ができます。これを @strong{確定変換} と +呼び、利用するには @strong{確定辞書} を用意します。例えば、 @example じしょ /辞書/ @@ -6135,94 +6012,78 @@ というエントリが確定辞書にあったとします。このとき、 @example -@group -@kbd{Z i s h o} +Z i s h o -@group ------- Buffer: foo ------ -▽じしょ@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▽じしょ* + ------ Buffer: foo ------ -@key{SPC} +SPC -@group ------- Buffer: foo ------ -辞書@point{} ------- Buffer: foo ------ -@end group -@end group + ------ Buffer: foo ------ + 辞書* + ------ Buffer: foo ------ @end example -@cindex 暗黙の確定 @noindent -のように、@key{SPC} を押しただけでいきなり確定します。エントリの候補がひ -とつだけだからです。 +のように @code{SPC} を押しただけでいきなり確定します。エントリの候補がひとつだ +けだからです。 確定辞書以外の辞書に登録されているであろう同音異義語を得るには、確定変換 -の直後に @kbd{x} をタイプします。すると、▼モードに戻って次の候補を検索す -ることができます。 +の直後に @code{x} を打鍵します。すると、▼モードに戻って次の候補を検索すること +ができます。 -次の例では、確定辞書に @samp{辞書} が、個人辞書(や共有辞書)に @samp{自署} が -登録されているとします。 +次の例では、確定辞書に「辞書」が、個人辞書(や共有辞書)に「自署」が登録 +されているとします。 @example -@group -@kbd{Z i s y o @key{SPC}} - -@group ------- Buffer: foo ------ -辞書@point{} ------- Buffer: foo ------ -@end group +Z i s y o SPC -@kbd{x} + ------ Buffer: foo ------ + 辞書* + ------ Buffer: foo ------ -@group ------- Buffer: foo ------ -▼自署@point{} ------- Buffer: foo ------ -@end group +x -@end group + ------ Buffer: foo ------ + ▼自署* + ------ Buffer: foo ------ @end example 確定辞書の単語は、優先的に変換されます。 -@defvr {ユーザ変数} skk-kakutei-jisyo +@defvar skk-kakutei-jisyo -確定変換用の辞書ファイルを指定します -@footnote{確定変換用辞書の見出し語の配列については、サイズが大きい場合は -、共有辞書と同様、ソートして二分検索を行い、サイズが小さければ適当な配置 -で直線的検索を行うことをお勧めします。次も参照してください。@* -@w{@ref{辞書検索のための関数}}@* -@w{@ref{エントリの配列}} -}。 -この辞書は、標準の配布パッケージには含まれていないので、使用するのであれ -ばユーザ側で用意する必要があります。@* -(@w{@pxref{辞書の書式}}) +確定変換用の辞書ファイル @footnote{確定変換用辞書の見出し語の配列については、サイズが大き +い場合は、共有辞書と同様、ソートして二分検索(バイナリサーチ)を行い、サ +イズが小さければ適当な配置で直線的検索(リニアサーチ)を行うことをお勧め +します。次も参照してください。 -@code{nil} であれば、確定変換は行われません。 +@ref{辞書検索のための関数}. -@end defvr +@ref{エントリの配列}.} を指定します。 @code{nil} であれ +ば、確定変換は行われません。この辞書は、標準の配布パッケージには含まれ +ていないので、使用するのであればユーザ側で用意する必要があります。 + +@ref{辞書の書式}. +@end defvar @node 送り仮名関連 @section 送り仮名関連 -SKK の送り仮名の処理は、好みが分かれるところです。色々な -対策が用意されていますので、試してみて下さい。 +SKK の送り仮名の処理は、好みが分かれるところです。色々な対策が用意されて +いますので、試してみて下さい。 + @menu -* 送り仮名の厳密なマッチ:: 「多きい」対策、その 1 -* 送り仮名の優先的なマッチ:: 「多きい」対策、その 2 -* 送り仮名の自動処理:: 送り仮名があっても、後から SPC +* 送り仮名の厳密なマッチ:: +* 送り仮名の優先的なマッチ:: +* 送り仮名の自動処理:: * 送りあり変換の変換開始のタイミング:: @end menu @node 送り仮名の厳密なマッチ @subsection 送り仮名の厳密なマッチ -@vindex minibuffer-exit-hook -@vindex minibuffer-setup-hook 今、個人辞書に @@ -6233,42 +6094,37 @@ @noindent という送りありエントリがあると仮定します。 -ここで @kbd{O o K i i @key{SPC}} と入力した場合、普通は @samp{大きい} と -@samp{多きい} という 2 通りの候補が出力されますが、このうち @samp{多きい} -は現代の日本語として正しくありません。このような場合に、出力される候補を -正しい表現のみに絞りこむ方法について、説明します。 - - -@defvr {ユーザ変数} skk-henkan-okuri-strictly -@vindex skk-process-okuri-early - -この変数の値を @code{non-nil} に設定すると、見出し語がマッチするかどう -かのチェックの上に、送り仮名がマッチするかどうかのチェックが行われま -す。結果として送り仮名がマッチしない候補は出力されません。上記の例では、 -送り仮名 @samp{き} がマッチする @samp{大きい} は出力されますが、 -@samp{多きい} は出力されません -@footnote{この機能は、変数 @code{skk-process-okuri-early} の値を -@code{non-nil} に設定した状態と共存できません。この理由を知りたい場合は -@ref{送りあり変換の変換開始のタイミング}を参照してください。}。 - -個人辞書の送りありエントリが充実していれば、標準の設定よりも候補が絞り込 -まれるので変換効率がアップしますが、さもなければ、すぐに辞書登録モードに -入ってしまうため逆に不便になります。 -@end defvr - -変数 @code{skk-henkan-okuri-strictly} の値を @code{non-nil} にすると、 -辞書登録モードに入っても送り仮名のマッチが厳密に行われます。これは辞 -書登録の際希望する候補を得るためには障害となります。そのような障害を避 -けるためには、下記のようにフック変数を設定します。これにより、辞書登録 -時だけは、一時的に送り仮名の厳密なマッチをしないようになります -@footnote{実は変数 @code{skk-henkan-okuri-strictly} の値は辞書バッファで -参照されるので、ミニバッファのバッファローカル値を変更してもうまくいきま -せん。将来のバージョンでは、これを改良し、辞書バッファでの動作に影響する -ユーザ変数をバッファローカル化できるようにする予定です。 -@w{@xref{最新情報}.}}。 +ここで @code{O o K i i SPC} と入力した場合、普通は「大きい」と「多きい」という +2通りの候補が出力されますが、このうち「多きい」は現代の日本語として正し +くありません。このような場合に、出力される候補を正しい表現のみに絞りこむ +方法について、説明します。 + +@defopt skk-henkan-okuri-strictly + +この変数の値を @code{non-nil} に設定すると、見出し語がマッチするかどうかのチ +ェックの上に、送り仮名がマッチするかどうかのチェックが行われます。結果 +として送り仮名がマッチしない候補は出力されません。上記の例では、送り仮 +名「き」がマッチする「大きい」は出力されますが、「多きい」は出力されま +せん @footnote{この機能は、変数 @code{skk-process-okuri-early} の値を +@code{non-nil} に設定した状態と共存できません。 + +@ref{送りあり変換の変換開始のタイミング}.} 。 + +個人辞書の送りありエントリが充実していれば、標準の設定よりも候補が絞り +込まれるので変換効率がアップしますが、さもなければ、すぐに辞書登録モー +ドに入ってしまうため逆に不便になります。 +@end defopt + +変数 @code{skk-henkan-okuri-strictly} の値を @code{non-nil} にすると、辞書登録モー +ドに入っても送り仮名のマッチが厳密に行われます。これは辞書登録の際希望す +る候補を得るためには障害となります。そのような障害を避けるためには、下記 +のようにフック変数を設定します。これにより、辞書登録時だけは、一時的に送 +り仮名の厳密なマッチをしないようになります @footnote{実は変数 @code{skk-henkan-okuri-strictly} の値は辞書バッフ +ァで参照されるので、ミニバッファのバッファローカル値を変更してもうまくい +きません。将来のバージョンでは、これを改良し、辞書バッファでの動作に影響 +するユーザ変数をバッファローカル化できるようにする予定です。} 。 @lisp -@group (add-hook 'minibuffer-setup-hook (lambda () (when (and (boundp 'skk-henkan-okuri-strictly) @@ -6276,25 +6132,27 @@ (not (eq last-command 'skk-purge-jisyo))) (setq skk-henkan-okuri-strictly nil) (put 'skk-henkan-okuri-strictly 'temporary-nil t)))) +@end lisp -@end group -@group +@lisp (add-hook 'minibuffer-exit-hook (lambda () (when (and (get 'skk-henkan-okuri-strictly 'temporary-nil) (<= (minibuffer-depth) 1)) (put 'skk-henkan-okuri-strictly 'temporary-nil nil) (setq skk-henkan-okuri-strictly t)))) -@end group @end lisp @node 送り仮名の優先的なマッチ @subsection 送り仮名の優先的なマッチ -@ref{送り仮名の厳密なマッチ} では、見出し語と送り仮名が一致した場合のみ -候補を表示します。ここでは、その条件を緩めて優先的に表示する方法を紹介し -ます@footnote{@samp{大く}などの候補は鬱陶しいが、すぐに単語登録に入って -しまうのも嫌な人におすすめです。}。 +「送り仮名の厳密なマッチ」では、見出し語と送り仮名が一致した場合のみ候 +補を表示します。 + +@ref{送り仮名の厳密なマッチ}. + +ここでは、その条件を緩めて優先的に表示する方法を紹介します @footnote{「大く」などの候補は鬱陶しいが、すぐに単語登録に入っ +てしまうのも嫌な人におすすめです。} 。 今、個人辞書に @@ -6305,33 +6163,29 @@ @noindent という送りありエントリがあると仮定します。 -ここで @kbd{O o K i i @key{SPC}} と入力した場合、普通は @samp{大きい} と -@samp{多きい} という 2 通りの候補が出力されますが、このうち @samp{多きい} -は現代の日本語として正しくありません。このような場合に、出力される候補を -正しい表現が優先的にする設定を紹介します。 - -@defvr {ユーザ変数} skk-henkan-strict-okuri-precedence -@vindex skk-henkan-okuri-strictly -@vindex skk-process-okuri-early - -この変数の値を @code{non-nil} に設定すると、見出し語と送り仮名がマッチ -した候補を優先して表示します。 - -上記の例では @samp{▽おお*く} を変換したとき、まず @samp{多く} を出力し、 -次に @samp{大く} を出力します。 - -この変数の値が @code{non-nil} の時は、変数 -@code{skk-process-okuri-early} の値は @code{nil} でなければなりません -@footnote{理由を知りたい場合は、@ref{送りあり変換の変換開始のタイミング} -を参照してください。}。また変数 @code{skk-henkan-okuri-strictly} が -@code{non-nil} のときは、この変数は無視されます。 -@end defvr +ここで @code{O o K i i SPC} と入力した場合、普通は「大きい」と「多きい」という +2通りの候補が出力されますが、このうち「多きい」は現代の日本語として正し +くありません。このような場合に、出力される候補を正しい表現が優先的にする +設定を紹介します。 + +@defopt skk-henkan-strict-okuri-precedence + +この変数の値を @code{non-nil} に設定すると、見出し語と送り仮名がマッチした候 +補を優先して表示します。上記の例では「▽おお*く」を変換したとき、まず +「多く」を出力し、次に「大く」を出力します。 + +この変数の値が @code{non-nil} の時は、変数 @code{skk-process-okuri-early} の値は @code{nil} で +なければなりません @footnote{@ref{送りあり変換の変換開始のタイミング}.} 。 +また、変数 @code{skk-henkan-okuri-strictly} が @code{non-nil} のときは、この変数 +は無視されます。 +@end defopt @node 送り仮名の自動処理 @subsection 送り仮名の自動処理 -この節では、「あげる」と入力してから @key{SPC} を押しても「上げる」と変換 -する機能を紹介します。 +この節では、「あげる」と入力してから @code{SPC} を押しても「上げる」と変換する +機能を紹介します。 + @menu * どのように変換されるか:: @@ -6341,59 +6195,65 @@ @node どのように変換されるか @subsubsection どのように変換されるか -@defvr {ユーザ変数} skk-auto-okuri-process -この変数の値を @code{non-nil} に設定すると、送り仮名の自動処理が行わ -れます。 -@end defvr +@defopt skk-auto-okuri-process -例えば、@kbd{T a t i a g e r u @key{SPC}} と入力した場合を考えます。 -このとき、検索される見出し語の変化を追うと、 +この変数の値を @code{non-nil} に設定すると、送り仮名の自動処理が行われます。 +@end defopt -@example -@samp{たちあげる} @result{} @samp{たちあげr} @result{} @samp{たちあg} -@result{} @samp{たちa} @result{} @samp{たt} -@end example +例えば @code{T a t i a g e r u SPC} とキー入力した場合を考えます。このとき、検 +索される見出し語の変化を追うと、 + +@itemize +@item +たちあげる + +@item +たちあげr + +@item +たちあg + +@item +たちa + +@item +たt +@end itemize @noindent のようになります。仮に個人辞書エントリが、 @example -@group たちあg /立ち上/[げ/立ち上/]/[が/立ち上/]/ たt /建/断/経/立/[つ/建/断/経/立/]/[ち/建/断/経/立/]/[て/経/立/建/]/ -@end group @end example @noindent -の 2 つのエントリを含むとすると、見出し語を後方から順に切り詰める過程で -@samp{たちあg} と @samp{たt} の 2 つの見出し語の検索時にこれらの辞書エン -トリがマッチします。 - -@noindent -つまり、@samp{たちあげる} という見出し語に対し、見出し語を最後尾から1文 -字ずつ切り詰め、「切り詰めの結果残った文字列」と、「切り捨てられた先頭の -文字のローマ字プレフィックス」を連結した文字列を送りあり変換の見出し語と -して、 -検索します。@footnote{実際には、普通の送りなし変換として最初は検索されます。 -個人辞書まで調べて候補が見つからないときは、その後、送り仮名の自動処理の検索に -移ります。} +の2つのエントリを含むとすると、見出し語を後方から順に切り詰める過程で +「たちあg」と「たt」の2つの見出し語の検索時にこれらの辞書エントリがマッ +チします。 + +つまり、「たちあげる」という見出し語に対し、見出し語を最後尾から1文字ず +つ切り詰め、「切り詰めの結果残った文字列」と、「切り捨てられた先頭の文字 +のローマ字プレフィックスを連結した文字列」を送りあり変換の見出し語として +検索します @footnote{実際には、普通の送りなし変換として最初は検索されます。個 +人辞書まで調べて候補が見つからないときは、その後、送り仮名の自動処理の検 +索に移ります。} 。 -@noindent 次に、マッチしたエントリの各候補に対し、切り捨てられた先頭の文字を送り仮 -名として取るかどうかをチェックします。この判断には、個人辞書の送り仮名ブロッ -ク部分 -@footnote{@ref{送りありエントリのブロック形式}.}を利用します。 +名として取るかどうかをチェックします。この判断には、個人辞書の送り仮名ブ +ロック部分 @footnote{@ref{送りありエントリのブロック形式}.} を利用します。 -@samp{たちあg} の場合の送り仮名チェックの対象は、切り捨てられた最初の文 -字の @samp{げ} です。個人辞書に +「たちあg」の場合の送り仮名チェックの対象は、切り捨てられた最初の文字の +「げ」です。個人辞書に @example [げ/立ち上/] @end example @noindent -の部分があることから、送り仮名として取るべきと判断します。また、@samp{た -t} の場合の送り仮名チェックの対象は、@samp{ち} です。個人辞書に +の部分があることから、送り仮名として取るべきと判断します。また、「たt」の +場合の送り仮名チェックの対象は「ち」です。個人辞書に @example [ち/建/断/経/立/] @@ -6402,164 +6262,156 @@ @noindent の部分があることから、送り仮名として取るべきと判断します。 -@noindent -こうして、送り仮名がマッチする候補が @samp{立ち上}、@samp{建}、@samp{断}、 -@samp{経}、@samp{立} の5つに絞られます。これらは文字列の長さ順に昇順に -ソートされ -@footnote{長さ順にソートするのは、変換された部分がより長い候補を先順位 -として出力するためです。}、それぞれの候補と該当の見出し語から切り捨てら -れた文字列と連結したもの -@footnote{@samp{該当の見出し語から切り捨てられた文字列} を送り仮名とみな -して処理しています。}を、送り仮名の自動処理の最終候補として返します。上 -記の例は、@samp{立ち上げる}、@samp{建ちあげる}、@samp{断ちあげる}、 -@samp{経ちあげる}、@samp{立ちあげる} の5つが最終候補になります。 +こうして、送り仮名がマッチする候補が「立ち上」、「建」、「断」、「経」、 +「立」の5つに絞られます。これらは文字列の長さ順に昇順にソートされ @footnote{長さ順にソートするのは、変換された部分がより長い候補を先 +順位として出力するためです。} 、 +それぞれの候補と該当の見出し語から切り捨てられた文字列と連結したもの @footnote{「該当の見出し語から切り捨てられた文字列」を送り仮名とみ +なして処理しています。} を、 +送り仮名の自動処理の最終候補として返します。上記の例は、「立ち上げる」、 +「建ちあげる」、「断ちあげる」、「経ちあげる」、「立ちあげる」 の5つが +最終候補になります。 自動送り機能は、個人辞書のみを検索します。 -ここで、自動送り機能の長所を考えてみると、 +ここで、自動送り機能の特徴を考えてみると、 + +@itemize +@item +長所 +@itemize +@item +送り仮名の最初のローマ字表現を大文字で始める必要がない。 -@itemize @bullet -@item 送り仮名の最初のローマ字表現を大文字で始める必要がない。 -@item 送り仮名を正確に思い出せない場合に送り仮名を指定しなくとも変換でき -る。 +@item +送り仮名を正確に思い出せない場合に送り仮名を指定しなくとも変換できる。 @end itemize -などがあります。一方短所としては、 +@item +短所 +@itemize +@item +意図しない変換をされる割合が増える。 -@itemize @bullet -@item 意図しない変換をされる割合が増える。 -@item 個人辞書の送りありエントリが貧弱な場合は、自動処理ができない可能性 -が高い。 +@item +個人辞書の送りありエントリが貧弱な場合は、自動処理ができない可能性が高い。 @end itemize +@end itemize + +@noindent +となります。 -などが考えられます。変数 @code{skk-auto-okuri-process} の値を -@code{non-nil} に設定しても、従来通りの送りあり変換も同時にできますから、 -一度この機能を試してみることをお勧めします -@footnote{専ら補完的に自動送り処理を利用するのであれば、 -@code{(skk-okuri-search)} を @code{skk-search-prog-list} の最後にもってく -るという手もあります。(@w{@pxref{辞書の検索方法の設定}})}。 +変数 @code{skk-auto-okuri-process} の値を @code{non-nil} に設定したとしても、従来 +どおりの送りあり変換も同時にできますので、一度この機能を試してみることを +お勧めします @footnote{専ら補完的に自動送り処理を利用するのであれば + @code{(skk-okuri-search)} を @code{skk-search-prog-list} の最後に設定するという方 +法もあります。 + +@ref{辞書の検索方法の設定}.} 。 @node 辞書登録の際に注意すべきこと @subsubsection 辞書登録の際に注意すべきこと -送り仮名の自動処理を行っている場合@footnote{変数 -@code{skk-auto-okuri-process} の値を @code{non-nil} に設定している。}に -は、辞書登録の際に注意すべきことがあります。 +送り仮名の自動処理を行っている場合 @footnote{変数 @code{skk-auto-okuri-process} の値を @code{non-nil} に設定している。} には、辞書登録の際に注 +意すべきことがあります。 -個人辞書に見出し語 @samp{わたs} についてのエントリが全くない場合、あるい -は個人辞書のエントリが +個人辞書に見出し語「わたs」についてのエントリが全くない場合、あるいは個人 +辞書のエントリが @example わたs /渡/[し/渡/]/ @end example @noindent -のような送り仮名のブロックを持たない場合を考えてみます。ここで、@kbd{W a -t a s i t a @key{SPC}}と入力すると、送り仮名の自動処理においては送り仮名 -がマッチしないので、候補が見つからずに辞書登録モードに入ります。 +のような送り仮名のブロックを持たない場合を考えてみます。 +ここで @code{W a t a s i t a SPC} と入力すると、送り仮名の自動処理においては +送り仮名がマッチしないので、候補が見つからずに辞書登録モードに入ります。 @example -@group -@kbd{W a t a s i t a @key{SPC}} +W a t a s i t a SPC ------- Buffer: foo ------ -▼わたした ------- Buffer: foo ------ + ------ Buffer: foo ------ + ▼わたした + ------ Buffer: foo ------ ------- Minibuffer ------- -[辞書登録] わたした@point{} ------- Minibuffer ------- -@end group + ------ Minibuffer ------- + [辞書登録] わたした* + ------ Minibuffer ------- @end example @noindent -辞書登録モードで @kbd{W a t a S i t a @key{RET}} と送り仮名を明示的に入 -力し、@samp{渡した} と変換して登録したとします。この場合、登録する語の最 -後が平仮名で終わるので、その最後の平仮名の文字列 (上記の例では、@samp{し -た}) が見出し語の最後と一致するかを調べます。一致する場合には、辞書の登 -録を送りありエントリとして行うのかどうかの確認を求めます。 +辞書登録モードで @code{W a t a S i t a RET} と送り仮名を明示的に入力して「渡し +た」と変換して登録したとします。この場合、登録する語の最後が平仮名で終わ +るので、その最後の平仮名の文字列(上記の例では「した」)が見出し語の最後 +と一致するかを調べます。一致する場合には、辞書の登録を送りありエントリと +して行うのかどうかの確認を求めます。 @example -@group -@kbd{W a t a S i t a} ------- Minibuffer ------- -[辞書登録] わたした 渡した@point{} ------- Minibuffer ------- -@end group -@group +W a t a S i t a -@key{RET} + ------ Minibuffer ------- + [辞書登録] わたした 渡した* + ------ Minibuffer ------- --------------------------- Echo Area -------------------------- -Shall I register this as okuri-ari word: わたs /渡/ ? (y or n) --------------------------- Echo Area -------------------------- -@end group +RET + + -------------------------- Echo Area -------------------------- + Shall I register this as okuri-ari word: わたs /渡/ ? (y or n) + -------------------------- Echo Area -------------------------- @end example @noindent -この確認に対し、@samp{y} と回答した場合は、 +この確認に対して @code{y} と回答した場合は、 @example わたs /渡/[し/渡/]/ @end example @noindent -という辞書エントリが個人辞書の送りありエントリに書き込まれます。一方 -@samp{n} と回答した場合は、個人辞書の送りなしエントリに +という辞書エントリが個人辞書の送りありエントリに書き込まれます。一方 @code{n} と +回答した場合は、個人辞書の送りなしエントリに @example わたした /渡した/ @end example @noindent -というエントリが書き込まれます。本例の場合は、@samp{y} と回答するのが正 -解です。 +というエントリが書き込まれます。本例の場合は @code{y} と回答するのが正解です。 -@table @code -@item skk-kana-rom-vector -@vindex skk-kana-rom-vector -@c XXX この変数は定数になった。 +@defvar skk-kana-rom-vector -この変数は、送り仮名部分をローマ字プレフィックスに分解する際に、参照され -ます。 -@end table +この変数は、送り仮名部分をローマ字プレフィックスに分解する際に、参照さ +れます。 +@end defvar -変数 @code{skk-kana-rom-vector} のデフォルトは以下のようになっています。 +変数 @code{skk-kana-rom-vector} の標準設定は以下のようになっています。 @example -@group ["x" "a" "x" "i" "x" "u" "x" "e" "x" "o" "k" "g" "k" "g" "k" "g" "k" "g" "k" "g" "s" "z" "s" "j" "s" "z" "s" "z" "s" "z" "t" "d" "t" "d" "x" "t" "d" "t" "d" "t" "d" "n" "n" "n" "n" "n" "h" "b" "p" "h" "b" "p" "h" "b" "p" "h" "b" "p" "h" "b" "p" "m" "m" "m" "m" "m" "x" "y" "x" "y" "x" "y" "r" "r" "r" "r" "r" "x" "w" "x" "x" "w" "n"] -@end group @end example このベクトルは、それぞれ下記のかな文字をそのローマ字プレフィックスで現し たものです。 @example -@group ぁ あ ぃ い ぅ う ぇ え ぉ お か が き ぎ く ぐ け げ こ ご さ ざ し じ す ず せ ぜ そ ぞ た だ ち ぢ っ つ づ て で と ど な に ぬ ね の は ば ぱ ひ び ぴ ふ ぶ ぷ へ べ ぺ ほ ぼ ぽ ま み む め も ゃ や ゅ ゆ ょ よ ら り る れ ろ ゎ わ ゐ ゑ を ん -@end group @end example -@noindent これに従うと、見出し語中の送り仮名がローマ字プレフィックスに分解される際、 -例えば @samp{じ} は @samp{j} に、@samp{ち} は @samp{t} に、@samp{ふ} は -@samp{h} に、それぞれ分解されます。これらをそれぞれ @samp{z}、@samp{c}、 -@samp{f} に変更することもできます。それには変数 -@code{skk-kana-rom-vector} の該当部分を "z"、"c"、"f" に変更します。 +例えば「じ」は @code{j} に、「ち」は @code{t} に、「ふ」は @code{h} に、それぞれ分解され +ます。これらをそれぞれ @code{z} 、 @code{c} 、 @code{f} に変更することもできます。それに +は変数 @code{skk-kana-rom-vector} の該当部分を @code{z} 、 @code{c} 、 @code{f} に変更します。 @lisp -@group (setq skk-rom-kana-vector ["x" "a" "x" "i" "x" "u" "x" "e" "x" "o" "k" "g" "k" "g" "k" "g" "k" "g" "k" "g" "s" "z" "s" "z" "s" "z" "s" "z" "s" "z" "t" "d" @@ -6567,21 +6419,19 @@ "p" "h" "b" "p" "f" "b" "p" "h" "b" "p" "h" "b" "p" "m" "m" "m" "m" "m" "x" "y" "x" "y" "x" "y" "r" "r" "r" "r" "r" "x" "w" "x" "x" "w" "n"]) -@end group @end lisp -次にもうひとつ例を挙げます。 @samp{ありがさつき} に対し @samp{有賀さつき} -を登録したい場合は、上記と同様に辞書登録をし、 +次にもうひとつ例を挙げます。「ありがさつき」に対して「有賀さつき」を登録 +したい場合は、上記と同様に辞書登録をし、 @example -@group +-------------------------- Echo Area -------------------------- Shall I register this as okuri-ari entry: ありがs /有賀/ ? (y or n) -@end group +-------------------------- Echo Area -------------------------- @end example @noindent -の確認に対し @samp{n} と回答します。この結果、個人辞書の送りなしエントリ -には、 +の確認に対して @code{n} と回答します。この結果、個人辞書の送りなしエントリには、 @example ありがさつき /有賀さつき/ @@ -6592,63 +6442,62 @@ @node 送りあり変換の変換開始のタイミング @subsection 送りあり変換の変換開始のタイミング -@kindex C-x C-j -@kindex C-x j -@defvr {ユーザ変数} skk-process-okuri-early -@vindex skk-auto-okuri-process -@vindex skk-henkan-okuri-strictly -@vindex skk-kakutei-early +@defopt skk-process-okuri-early -この変数の値を @code{non-nil} に設定すると、送りあり変換の変換開始のタ -イミングが早められます。つまり、送り仮名のローマ字プレフィックスの入力 -時点で変換を開始します。 +この変数の値を @code{non-nil} に設定すると、送りあり変換の変換開始のタイミン +グが早められます。つまり、送り仮名のローマ字プレフィックスの入力時点で +変換を開始します。 @example -@group -@kbd{U g o K} +U g o K ------- Buffer: foo ------ -▼動k ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + ▼動k + ------ Buffer: foo ------ @end example -送り仮名が分からないまま変換しているため、個人辞書が送り仮名に対応した形に -成長しません。つまり @samp{うごk /動/} のような形態のままとなります。た +送り仮名が分からないまま変換しているため、個人辞書が送り仮名に対応した +形に成長しません。つまり @code{うごk /動/} のような形態のままとなります。た だし、 @example -@group -うごk /動/[く/動/]/[か/動/]/[け/動/]/[き/動/]/[こ/動/]/ -@end group + うごk /動/[く/動/]/[か/動/]/[け/動/]/[き/動/]/[こ/動/]/ @end example -@noindent -のようなエントリが既に個人辞書にある場合、それを破壊することはありません -@footnote{@ref{辞書の書式}を参照してください。}。 +のようなエントリが既に個人辞書にある場合、それを破壊することはありませ +ん @footnote{@ref{辞書の書式}.} 。 + +このユーザオプションを @code{non-nil} に設定して SKK モードを起動すると、両 +立できないオプションである下記オプションは自動的に @code{nil} に設定されます。 + +@itemize +@item +@code{skk-kakutei-early} + +@item +@code{skk-auto-okuri-process} + +@item +@code{skk-henkan-okuri-strictly} +@end itemize +既に SKK モードに入った後でこの変数の設定を変更した場合は、カレントバッ +ファで @code{C-x C-j} もしくは @code{C-x j} を2回打鍵して SKK モードを起動し直す +ことで、これらの変数間の衝突を調整します。 -このユーザオプションを @code{non-nil} に設定して SKK モードを起動する -と、両立できないオプションである下記オプションは自動的に @code{nil} に -設定されます。 +@itemize +@item +@ref{暗黙の確定のタイミング}. -@itemize @bullet -@item @code{skk-kakutei-early} -@item @code{skk-auto-okuri-process} -@item @code{skk-henkan-okuri-strictly} -@end itemize -既に SKK モードに入った後でこの変数の設定を変更した場合は、カレントバッ -ファで @kbd{C-x C-j} もしくは @kbd{C-x j} を 2 回タイプして SKK モードを -起動し直すことで、これらの変数間の衝突を調整します。 +@item +@ref{送り仮名の自動処理}. -@display -@xref{暗黙の確定のタイミング, , skk-kakutei-early}. -@xref{送り仮名の自動処理, , skk-auto-okuri-process}. -@xref{送り仮名の厳密なマッチ, , skk-henkan-okuri-strictly}. -@end display -@end defvr +@item +@ref{送り仮名の厳密なマッチ}. +@end itemize +@end defopt @node 候補の順序 @section 候補の順序 @@ -6656,169 +6505,181 @@ skk の初期設定では、変換で確定された単語は、次の変換時では最初に表示され ます。この動作を変更して、効率良く変換する方法があります。 +ここで解説するほか、確定辞書を用いた変換も、候補の順序に影響を与えます。 + +@ref{確定辞書}. + + @menu -* 変換の学習:: 関連のある語は上位に表示 -* 候補の順序の固定:: いつも同じ順序で候補を表示 +* 変換の学習:: +* 候補の順序の固定:: * ベイズ統計を用いた学習:: @end menu -ここで解説するほか、確定辞書 (@w{@pxref{確定辞書}}) を用いた変換も、候補の順序に影響を与えます。 - @node 変換の学習 @subsection 変換の学習 -@cindex @file{skk-study.el} -@vindex skk-study-associates-number -@vindex skk-study-search-times -@file{skk-study.el} は、ある語 A を確定した場合に、A 及びその見出し -語 A' に対して、直前に変換した語 B とその見出し語 B' を関連語として登 -録しておき、再度見出し語 A' の変換を行ったときに、B 及び B' のペアが直 -前の何回かに確定した語の中に見つかれば、A を優先して出力する単純な学習 -効果を提供するプログラムです。 +@code{skk-study.el} は、ある語 A を確定した場合に、A 及びその見出し語 A' に対 +して、直前に変換した語 B とその見出し語 B' を関連語として登録しておき、 +再度見出し語 A' の変換を行ったときに、B 及び B' のペアが直前の何回かに確 +定した語の中に見つかれば、A を優先して出力する単純な学習効果を提供するプ +ログラムです。 -@file{~/.skk} に @code{(require 'skk-study)} と書いて DDSKK を起動して下 -さい。以降、かな漢字変換の学習を始めます。 +@code{~/.skk} に @code{(require 'skk-study)} と書いて DDSKK を起動して下さい。以降、 +かな漢字変換の学習を始めます。 -例えば、@samp{梅雨には雨が降る} と変換した場合、 +例えば「梅雨には雨が降る」と変換した場合、 -@itemize @bullet +@itemize @item -@samp{雨} (@samp{あめ}) の関連語 @expansion{} @samp{梅雨} (@samp{つゆ})、 +雨(あめ)の関連語 → 梅雨(つゆ) + @item -@samp{降る} (@samp{ふr}) の関連語 @expansion{} @samp{雨} (@samp{あめ})、 +降る(ふr)の関連語 → 雨(あめ) @end itemize @noindent という風に「直前に確定した語」を関連語として、語と語の関連性を学習します。 -ここで続けて、@samp{傘を振る} と変換すると、個人辞書がアップデートされ -てしまい、見出し語 @samp{ふr} の第一候補は @samp{振る} になってしまい -ます。 +ここで続けて「傘を振る」と変換すると、個人辞書が更新されてしまい、見出し +語「ふr」の第一候補は「振る」になってしまいます。 + +しかし、更に続けて @code{A m e SPC g a H u R u} とキー入力すると、 +@code{H u R u} (ふr)に対して「雨」(あめ)が関連語になっているため、 +「ふr」と対で記憶されている「降る」に変換されるというわけです。 + +では、またここで「傘を振る」と変換し、個人辞書の第一候補が「振る」に更新 +された状態で、 + +@example +A m e SPC g a T a i r y o u SPC n i H u R u +@end example + +@noindent +と変換すれば、「ふr」はどう変換されるでしょうか? 今度は「雨」(あめ)と +「ふr」の間に「大量」(たいりょう)が入っています @footnote{「ふr」に対して「大量」(たいりょう)が関連語として保存されま +す。勿論、「ふr」に対する「雨」(あめ)の学習もまだ生きています。} 。 + +実はちゃんと「雨が大量に降る」と変換されます。何故なら「ふr」の関連語を探 +す際、 @code{skk-study-search-times} に指定された回数分だけ遡って、以前に確定 +した語の中に関連語がないか探すのです。従って、この場合だと、2つ前の確定 +情報を探した際に「雨」(あめ)を見つけ、これを関連語として「ふr」の値を決 +めようとするのです。 + +@code{skk-study.el} に関するその他のオプションを説明します。 + +@defvar skk-study-sesearch-times + +現在の変換キーに対する関連変換キーをいくつまで遡って検索するか。標準設 +定は 5 です。 +@end defvar -しかし、更に続けて @kbd{A m e @key{SPC} g a H u R u} と type すると、 -@kbd{H u R u} (@samp{ふr}) に対して @samp{雨} (@samp{あめ}) が関 -連語になっているため、@samp{ふr} と対で記憶されている @samp{降る} に変 -換されるというわけです。 - -では、またここで @samp{傘を振る} と変換し、個人辞書の第一候補が -@samp{振る} になった状態で、 - -@display -@kbd{A m e @key{SPC} g a T a i r y o u @key{SPC} n i H u R u} -@end display - -@noindent -と変換すれば @kbd{ふr} はどう変換されるでしょうか? - 今度は @samp{雨} @w{(@samp{あめ})} と @kbd{ふr} の間に @samp{大量} @w{(@samp{たいりょう})} -が入っています@footnote{@samp{ふr} に対して @samp{大量} @w{(@samp{たいりょう})} が -関連語として保存されます。勿論 @w{(@samp{ふr})} に対する @samp{雨} @w{(@samp{あめ})} の学習も -まだ生きています。}。 - -実はちゃんと - -@display -@samp{雨が大量に降る} -@end display - -@noindent -と変換されます。何故なら @w{@samp{ふr}} の関連語を探す際、 -@code{skk-study-search-times} @footnote{デフォルト値は 5 です。} に -指定された回数分だけ遡って、以前に確定した語の中に関連語がないか探すの -です。従って、この場合だと、2つ前の確定情報を探した際に @samp{雨} -@w{(@samp{あめ})} 見つけ、これを関連語として、@w{@samp{ふr}} の値を -決めようとするのです。 - -@file{skk-study.el} に関するその他のオプションを説明します。 - -@defvr {ユーザ変数} skk-study-max-distance -この変数には integer を指定します。直前に確定したポイントと今回の変換ポ -イントがこの距離以上離れていると学習データを蓄積しないようにします。 -この変数は、必ずしも文章がバッファの @code{point-min} か -ら @code{point-max} へ流れるように書かれるものではなく、ポイントを前に戻 -したり後へ移動したりして書かれることを想定しています。 -この変数に integer を設定すると、直前の変換よりも前のポイントで変換した -場合に学習データを蓄積しないようにします。この変数に @code{nil} を指定す -ると直前に確定したポイントとの距離を考慮せずに学習します。この変数のデフ -ォルト値は 30 です。 - -なお、この変数の値にかかわらず、直前の変換バッファと現在変換を行っている -バッファが異なる場合は学習データを蓄積しません。 -@end defvr - -@defvr {ユーザ変数} skk-study-first-candidate -この変数が @code{non-nil} であれば、第一候補 -で確定した際も学習します。@code{nil} であれば、第一候補で確定したとき -のみ学習データを蓄積しません。学習データをできるだけ小さくしたい場合、 -この変数を @code{nil} にすると効果があるかもしれません。 -この変数のデフォルト値は @code{t} です。 -@end defvr - -@defvr {ユーザ変数} skk-study-file -学習結果を保存するファイル名です。 -この変数のデフォルト値は @file{~/.skk-study} です。 +@defvar skk-study-max-distance + +この変数には integer を指定します。標準設定値は 30 です。直前に確定し +たポイントと今回の変換ポイントがこの距離以上離れていると学習データを蓄 +積しないようにします。この変数は、必ずしも文章がバッファの @code{point-min} か +ら @code{point-max} へ流れるように書かれるものではなく、ポイントを前に戻した +り後へ移動したりして書かれることを想定しています。この変数に integer を +設定すると、直前の変換よりも前のポイントで変換した場合に学習データを蓄 +積しないようにします。 + +この変数に @code{nil} を指定すると、直前に確定したポイントとの距離を考慮せず +に学習します。 + +なお、この変数の値にかかわらず、直前の変換バッファと現在変換を行ってい +るバッファが異なる場合は学習データを蓄積しません。 +@end defvar + +@defvar skk-study-first-candidate + +この変数が @code{non-nil} であれば、第一候補で確定した際も学習します。 @code{nil} で +あれば、第一候補で確定したときのみ学習データを蓄積しません。学習データ +をできるだけ小さくしたい場合、この変数を @code{nil} にすると効果があるかもし +れません。この変数の標準設定値は @code{t} です。 +@end defvar + +@defvar skk-study-file + +学習結果を保存するファイル名です。この変数の標準設定値は @code{~/.skk-study} です。 変数 @code{skk-user-directory} からも設定ができます。 -(@w{@pxref{設定ファイル}}) -@end defvr -@defvr {ユーザ変数} skk-study-backup-file -@file{~/.skk-study} のバックアップファイルです。 -この変数のデフォルト値は @file{~/.skk-study.BAK} です。 -@end defvr - -@defvr {ユーザ変数} skk-study-sort-saving -学習データのデータ構造に関するものです。この変数の値が @code{non-nil} で -あれば学習結果をソートしてセーブします。この変数が影響を及ぼすのは学習デ -ータの単なる見映えの問題だけです。 -この変数のデフォルト値は @code{nil} です。 -@end defvr - -@defvr {ユーザ変数} skk-study-check-alist-format -学習データのデータ構造に関するものです。この変数の値が @code{non-nil} で -あれば、学習結果の読み込み時に連想リストのフォーマットをチェックします。 -これは主に debug の目的で使います。 -この変数のデフォルト値は @code{nil} です。 -@end defvr +@ref{設定ファイル}. +@end defvar + +@defvar skk-study-backup-file -@table @kbd +@code{~/.skk-study} のバックアップファイルです。 +この変数の標準設定値は @code{~/.skk-study.BAK} です。 +@end defvar +@defvar skk-study-sort-saving + +学習データのデータ構造に関するものです。この変数の値が @code{non-nil} であれ +ば、学習結果をソートしてセーブします。この変数が影響を及ぼすのは学習デ +ータの単なる見映えの問題だけです。この変数の標準設定値は @code{nil} です。 +@end defvar + +@defvar skk-study-check-alist-format + +学習データのデータ構造に関するものです。この変数の値が @code{non-nil} であれ +ば、学習結果の読み込み時に連想リストのフォーマットをチェックします。 +これは主に debug の目的で使います。この変数の標準設定値は @code{nil} です。 +@end defvar + +@table @asis @kindex M-x skk-study-switch-current-theme -@item M-x skk-study-switch-current-theme -そのバッファで利用する学習テーマを切り替えます。 -プロンプト @samp{Theme of current buffer: } に対して学習テーマ名を入力し -てください。例えば、科学の話題を書くバッファでは science と、法律の話題 -を書くバッファでは law などと入力してください。 +@cindex skk-study-switch-current-theme +@item @kbd{M-x skk-study-switch-current-theme} @tie{}@tie{}@tie{}@tie{}(@code{skk-study-switch-current-theme}) + +そのバッファで利用する学習テーマを切り替えます。プロンプト + +@example +------ Minibuffer ------- +Theme of current buffer: * +------ Minibuffer ------- +@end example + +に対して学習テーマ名を入力してください。例えば、科学の話題を書くバッフ +ァでは "@code{science}" と、法律の話題を書くバッファでは "@code{law}" などと入力 +してください。 @kindex M-x skk-study-remove-theme -@item M-x skk-study-remove-theme +@cindex skk-study-remove-theme +@item @kbd{M-x skk-study-remove-theme} @tie{}@tie{}@tie{}@tie{}(@code{skk-study-remove-theme}) + 不要な学習テーマを消去します。 @kindex M-x skk-study-copy-theme -@item M-x skk-study-copy-theme -学習テーマを複製します。 +@cindex skk-study-copy-theme +@item @kbd{M-x skk-study-copy-theme} @tie{}@tie{}@tie{}@tie{}(@code{skk-study-copy-theme}) +学習テーマを複製します。 @end table @node 候補の順序の固定 @subsection 候補の順序の固定 -skk の初期設定では、変換、選択された候補は、次回の変換では最初に表示されます。 -これに対し、毎回同じ順序で候補を表示させることができます。 +skk の初期設定では、変換、選択された候補は、次回の変換では最初に表示され +ます。これに対し、毎回同じ順序で候補を表示させることができます。 -@defvr {ユーザ変数} skk-jisyo-fix-order +@defvar skk-jisyo-fix-order -@code{non-nil} であれば、確定の際に個人辞書の同音語の順序を変更せず、 -個人辞書に新規追加する際は既出語の後に追加する。標準は @code{nil}。 -@end defvr +@code{non-nil} であれば、確定の際に個人辞書の同音語の順序を変更せず、個人辞 +書に新規追加する際は既出語の後に追加する。標準は @code{nil} 。 +@end defvar これは、個人辞書のエントリの中の各候補の順序を変更しないことで実現されて -いますから、@file{skk-study.el} を用いた学習 @w{(@pxref{変換の学習})} と -併用できます。 +いますので、 @code{skk-study.el} による変換の学習と併用できます。 -@code{skk-jisyo-fix-order} が @code{non-nil} の時、個人辞書の候補を手軽に並べ替 -える方法は、現時点ではありません。個人辞書ファイルを直接編集するか、 -コマンド @kbd{M-x skk-edit-private-jisyo} を実行して下さい。 -(@w{@pxref{個人辞書ファイルの編集}}) +@ref{変換の学習}. + +@code{skk-jisyo-fix-order} が @code{non-nil} の時、個人辞書の候補を手軽に並べ替える +方法は、現時点ではありません。個人辞書ファイルを直接編集する +コマンド @code{M-x skk-edit-private-jisyo} を実行して下さい。 + +@ref{個人辞書ファイルの編集}. 直前に変換したばかりの単語は、個人辞書の送りあり/なしエントリの一番上に ありますので、すぐに見つけることができます。 @@ -6826,78 +6687,76 @@ @node ベイズ統計を用いた学習 @subsection ベイズ統計を用いた学習 -@file{skk-bayesian.el} は、直前の履歴のみ使用する @file{skk-study.el} に比べて、 -更に拡張された学習機能です。ベイズ統計を用いて文脈から変換候補が選択される確率を -計算して候補順をソートします。なお、機能が重なることから @file{skk-study.el} と +@code{skk-bayesian.el} は、直前の履歴のみ使用する @code{skk-study.el} に比べて、 +更に拡張された学習機能です。ベイズ統計を用いて文脈から変換候補が選択され +る確率を計算して候補順をソートします。なお、機能が重なることから @code{skk-study.el} と の併用はお勧めできません。 -動作の枠組みは emacs lisp の @file{skk-bayesian.el} と ruby@footnote{@url{http://www.ruby-lang.org}} スクリプト -の @file{bskk} が連携することで実現しています。 - -@file{skk-bayesian.el} のインストールについては @file{bayesian/README.ja.md} を -参照してください。 - -@cartouche +動作の枠組みは emacs lisp の @code{skk-bayesian.el} と ruby スクリプト @footnote{@uref{http://www.ruby-lang.org}} の @code{bskk} @footnote{Ruby 2.4 以降を使用する場合は、DDSKK 16.2 以降に付属する @code{bayesian/bskk} を +使用してください。} が +連携することで実現しています。 -Ruby 2.4 以降を使用する場合は、DDSKK 16.2 以降に付属する @file{bayesian/bskk} を -使用してください。 - -@end cartouche +@code{skk-bayesian.el} のインストールについては @code{bayesian/README.ja.md} を参照 +してください。 -@defvr {ユーザ変数} skk-bayesian-debug +@defopt skk-bayesian-debug @code{non-nil} ならば、以下のとおりデバッグ用のメッセージを表示します。 -@itemize @bullet +@itemize +@item +@code{skk-bayesian.el} が吐き出すメッセージを @code{*Messages*} バッファに表示します。 -@item @file{skk-bayesian.el} が吐き出すメッセージを *Messages* バッファに表示します。 -@item @file{bskk} サブプロセスを @code{-d} オプションで起動させます。@file{bskk} は @file{$HOME/tmp/bskk.log} にメッセージを吐き出します。 +@item +@code{bskk} サブプロセスを @code{-d} オプションで起動させます。 @code{bskk} は @code{$HOME/tmp/bskk.log} に +メッセージを吐き出します。 -@item 普段は非表示である *skk-bayesian* バッファを表示するようにします。このバッファには @file{bskk} の出力が表示されます。 +@item +普段は非表示である @code{*skk-bayesian*} バッファを表示するようにします。 +このバッファには @code{bskk} の出力が表示されます。 @end itemize +@end defopt -@end defvr - -@defvr {ユーザ変数} skk-bayesian-prefer-server +@defopt skk-bayesian-prefer-server -@code{non-nil} ならば @code{skk-bayesian-host} の @code{skk-bayesian-port} に接 -続します。 -@code{nil} であれば @file{bskk} を emacs のサブプロセスとして起動します。 +@code{non-nil} ならば @code{skk-bayesian-host} の @code{skk-bayesian-port} に接続しま +す。 @code{nil} であれば @code{bskk} を emacs のサブプロセスとして起動します。 +@end defopt -@end defvr +@defvar skk-bayesian-host -@defvr {ユーザ変数} skk-bayesian-host +@code{bskk} サーバが稼動しているホスト名 +@end defvar -@file{bskk} サーバが稼動しているホスト名 +@defvar skk-bayesian-port -@end defvr +@code{bskk} サーバのポート番号 +@end defvar -@defvr {ユーザ変数} skk-bayesian-port +@defvar skk-bayesian-history-file -@file{bskk} サーバのポート番号 +not documented +@end defvar -@end defvr +@defvar skk-bayesian-corpus-make -@defvr {ユーザ変数} skk-bayesian-history-file -@c ~/.skk-bayesian or ~/.ddskk/bayesian not documented -@end defvr +@end defvar -@defvr {ユーザ変数} skk-bayesian-corpus-make -not documented -@end defvr +@defvar skk-bayesian-corpus-file -@defvr {ユーザ変数} skk-bayesian-corpus-file -@c ~/.skk-corpus or ~/.ddskk/corpus not documented -@end defvr +@end defvar +@table @asis @kindex M-x skk-bayesian-kill-process -@defun {コマンド} skk-bayesian-kill-process +@cindex skk-bayesian-kill-process +@item @kbd{M-x skk-bayesian-kill-process} @tie{}@tie{}@tie{}@tie{}(@code{skk-bayesian-kill-process}) + not documented -@end defun +@end table @node 辞書関連 @section 辞書関連 @@ -6905,182 +6764,175 @@ 本節では、辞書の種別と形式、設定方法、その他辞書にまつわる動作や設定を説明しま す。 + @menu -辞書の設定 * 辞書の種類:: * 辞書ファイルの指定:: -* 辞書の検索方法の設定:: 検索対象と検索順序の設定。 +* 辞書の検索方法の設定:: * Emacs 付属の辞書:: * サーバ関連:: * サーバコンプリージョン:: - -@noindent -辞書の管理 * 辞書の書式:: * 強制的に辞書登録モードへ入る:: -* 誤った登録の削除:: 削除も登録みたいにできます。 -* 個人辞書ファイルの編集:: 個人辞書を編集するコマンドがあります。 -* 個人辞書の保存動作:: いつ個人辞書が更新、保存されるか。 +* 誤った登録の削除:: +* 個人辞書ファイルの編集:: +* 個人辞書の保存動作:: * 変換及び個人辞書に関する統計:: - -@noindent -他 * 辞書バッファ:: * 辞書バッファの文字コードの設定:: -* 辞書バッファのbuffer-file-name:: +* 辞書バッファの buffer-file-name:: @end menu @node 辞書の種類 @subsection 辞書の種類 -@table @b -@item 共有辞書 -@cindex 共有辞書 -@cindex L 辞書 -@cindex M 辞書 -@cindex S 辞書 -@cindex @file{SKK-JISYO.L} -@cindex @file{SKK-JISYO.ML} -@cindex @file{SKK-JISYO.M} -@cindex @file{SKK-JISYO.S} - -@file{SKK-JISYO.S} (S 辞書)、 @file{SKK-JISYO.M} (M 辞書)、 -@file{SKK-JISYO.ML} (ML 辞書)、 @file{SKK-JISYO.L} (L 辞書) などがありま -す。通常、個人辞書よりもサイズが大きく、省資源の面からユーザ間で共有して -参照されます。 +@itemize +@item +共有辞書 ユーザの変換操作によって内容が書き替えられることはありません。 -これら以外にも、共有辞書として使えるファイルが配布されています。 -それぞれの辞書の詳細については @url{http://openlab.jp/skk/dic.html} を -ご参照下さい。 +@code{SKK-JISYO.S} (S 辞書)、 @code{SKK-JISYO.M} (M 辞書)、 @code{SKK-JISYO.ML} (ML 辞書)、 + @code{SKK-JISYO.L} (L 辞書) などがあります。通常、個人辞書よりもサイズが大き +く、省資源の面からユーザ間で共有して参照されます。 -@item 個人辞書 -@cindex 個人辞書 -@vindex skk-jisyo +これら以外にも、共有辞書として使えるファイルが配布されています。それぞ +れの辞書の詳細については @uref{http://openlab.jp/skk/dic.html} をご参照下さい。 -変数 @code{skk-jisyo} で指定されるファイル。DDSKK を一番最初に使い始めた -ときにホームディレクトリに自動的に作られます。その後の使用により日々刻々 -とエントリが追加され、更新されていきます。 -なお、最初の個人辞書として S 辞書をリネームして使用するのも良いかもしれ -ません。 +@item +個人辞書 -@item @code{skk-initial-search-jisyo} -@itemx @code{skk-kakutei-jisyo} -@vindex skk-initial-search-jisyo -@vindex skk-kakutei-jisyo - -これらは共有辞書、個人辞書という区分のいずれにも属しません。これらは個人 -毎に持つものを使用するか、ユーザ間で共有しているものを使用します。その性 -格から、辞書内容の更新は行われず、参照のみ行われます。また使用目的から、 -通常は小さい辞書を使用します。 -@end table +変数 @code{skk-jisyo} で指定されるファイル。DDSKK を一番最初に使い始めたとき +にホームディレクトリに自動的に作られます。その後の使用により日々刻々と +エントリが追加され、更新されていきます。なお、最初の個人辞書として S 辞 +書をリネームして使用するのも良いかもしれません。 + + +@item +@code{skk-initial-search-jisyo} + +@item +@code{skk-kakutei-jisyo} + +これらは共有辞書、個人辞書という区分のいずれにも属しません。これらは個 +人毎に持つものを使用するか、ユーザ間で共有しているものを使用します。そ +の性格から、辞書内容の更新は行われず、参照のみ行われます。また使用目的 +から、通常は小さい辞書を使用します。 +@end itemize -個人辞書、@code{skk-initial-search-jisyo}, @code{skk-kakutei-jisyo} は -Emacs のバッファに読み込んで検索を行います。 +個人辞書、 @code{skk-initial-search-jisyo}, @code{skk-kakutei-jisyo} は Emacs のバ +ッファに読み込んで検索を行います。 -共有辞書は設定により Emacs のバッファに読み込んで使用するか、または辞書 -サーバ経由で使用します。 +共有辞書は設定により Emacs のバッファに読み込んで使用するか、または辞書サ +ーバ経由で使用します。 @node 辞書ファイルの指定 @subsection 辞書ファイルの指定 -この節では、辞書ファイルを指定する変数を説明します。 -個人辞書とバックアップのディレクトリは、変数 @code{skk-user-directory} で -も変更できます。(@w{@pxref{設定ファイル}}) - -@defvr {ユーザ変数} skk-kakutei-jisyo -確定変換(@w{@pxref{確定辞書}})のための辞書です。一番最初に参照されます。 -確定変換をしない時は、初期設定の @code{nil} のままで良いです。 -@end defvr - -@defvr {ユーザ変数} skk-initial-search-jisyo -確定辞書の後、かつ、個人辞書の前に検索を行う辞書です。 - -この辞書を適当に指定することにより、最初に出てくる候補を操作することがで -きます。例えば、複数の専門用語毎の辞書を用意しておい -て @code{skk-initial-search-jisyo} の値を切り替えることにより、専門分野 -毎の専門用語を切り替えて入力することができます。 - -この辞書は、標準の配布パッケージには含まれていないので、使用するのであれ -ばユーザ側で用意する必要があります。 - -不要ならば、初期設定の @code{nil} のままで良いです。 -@end defvr - -@defvr {ユーザ変数} skk-jisyo -個人辞書。DDSKK を一番最初に起動したとき、変数 @code{skk-jisyo} が指すフ -ァイルが存在しなければ自動的に作られます。 -@end defvr - -@defvr {ユーザ変数} skk-backup-jisyo -個人辞書の予備 (バックアップ) です。検索の対象ではなく、あくまで個人辞書 -のバックアップとして指定してください。 -@end defvr +この節では、辞書ファイルを指定する変数を説明します。個人辞書とバックアッ +プのディレクトリは、変数 @code{skk-user-directory} でも変更できます。 + +@ref{設定ファイル}. + +@defvar skk-kakutei-jisyo + +確定変換のための辞書です。 + +@ref{確定辞書}. + +一番最初に参照されます。確定変換をしない時は、初期設定の @code{nil} のままで +良いです。 +@end defvar + +@defvar skk-initial-search-jisyo + +確定辞書の後、かつ、個人辞書の前に検索を行う辞書です。この辞書を適当に +指定することにより、最初に出てくる候補を操作することができます。例えば、 +複数の専門用語毎の辞書を用意しておいて @code{skk-initial-search-jisyo} の値 +を切り替えることにより、専門分野毎の専門用語を切り替えて入力することが +できます。 + +この辞書は、標準の配布パッケージには含まれていないので、使用するのであ +ればユーザ側で用意する必要があります。不要ならば、初期設定の @code{nil} のま +まで良いです。 +@end defvar + +@defvar skk-jisyo + +個人辞書。DDSKK を一番最初に起動したとき、変数 @code{skk-jisyo} が指すファイ +ルが存在しなければ自動的に作られます。 +@end defvar + +@defvar skk-backup-jisyo + +個人辞書の予備(バックアップ)です。検索の対象ではなく、あくまで個人辞 +書のバックアップとして指定してください。 +@end defvar + +@defvar skk-cdb-large-jisyo -@defvr {ユーザ変数} skk-cdb-large-jisyo 共有辞書のうち CDB 形式に変換した辞書です。指定した場合は @code{skk-large-jisyo} よ -りも先に検索されます。DDSKK 14.1 からは辞書サーバを経由せずとも CDB 形式 -辞書ファイルを直接検索できるようになりました。 -@end defvr - -@defvr {ユーザ変数} skk-large-jisyo -共有辞書のひとつ。バッファに読み込んで検索を行います。 - -例えば @code{skk-large-jisyo} に S 辞書か M 辞書を指定し、 -@code{skk-aux-large-jisyo} に L 辞書を指定する、という選択肢もあります。 - -また、辞書サーバ経由のアクセスも決して遅くはないので「共有辞書はバッファには -読み込まない」という設定も自然であり、これには @code{skk-large-jisyo} を -@code{nil} に設定します。 -@end defvr - -@defvr {ユーザ変数} skk-aux-large-jisyo -共有辞書のひとつ。辞書サーバに接続できない時にバッファに読み込んで検索を行う -辞書です。 -@end defvr - -@defvr {ユーザ変数} skk-extra-jisyo-file-list -SKK では個人辞書の他に、共有辞書 (@code{skk-large-jisyo}、 -@code{skk-cdb-large-jisyo}) または辞書サーバを設定して利用するのが一般的 -ですが、郵便番号辞書 @file{SKK-JISYO.zipcode} をはじめとした多彩な辞書も -メンテナンスされています。 +りも先に検索されます。DDSKK 14.1 からは辞書サーバを経由せずとも CDB 形 +式辞書ファイルを直接検索できるようになりました。 +@end defvar + +@defvar skk-large-jisyo + +共有辞書のひとつ。バッファに読み込んで検索を行います。例えば @code{skk-large-jisyo} に S 辞書 +か M 辞書を指定し、 @code{skk-aux-large-jisyo} に L 辞書を指定する、という +選択肢もあります。 + +また、辞書サーバ経由のアクセスも決して遅くはないので「共有辞書はバッフ +ァには読み込まない」という設定も自然であり、これには @code{skk-large-jisyo} を @code{nil} に +設定します。 +@end defvar + +@defvar skk-aux-large-jisyo + +共有辞書のひとつ。辞書サーバに接続できない時にバッファに読み込んで検索 +を行う辞書です。 +@end defvar + +@defvar skk-extra-jisyo-file-list -これらの辞書を利用するために変数 @code{skk-search-prog-list} を手動で編集 -することもできますが、この変数は厳密にはユーザ変数に分類されていないため、 +SKK では個人辞書の他に、共有辞書または辞書サーバを設定して利用するのが +一般的ですが、郵便番号辞書 @code{SKK-JISYO.zipcode} をはじめとした多彩な辞書 +もメンテナンスされています。 + +これらの辞書を利用するために変数 @code{skk-search-prog-list} を手動で編集す +ることもできますが、この変数は厳密にはユーザ変数に分類されていないため、 予期しない問題が起こることもあります。 DDSKK 14.2 以降では追加の辞書を簡単に設定する方法を提供します。以下の例 -を参考に変数 @code{skk-extra-jisyo-file-list} の設定を @file{~/.skk} に -記述します。 +を参考に変数 @code{skk-extra-jisyo-file-list} の設定を @code{~/.skk} に記述します。 @lisp -@group (setq skk-extra-jisyo-file-list (list '("/usr/share/skk/SKK-JISYO.JIS3_4" . euc-jisx0213) "/usr/share/skk/SKK-JISYO.zipcode")) -@end group @end lisp -このように、辞書のファイル名のリストを指定します -@footnote{@code{skk-search-prog-list} に登録されている関 -数 @code{skk-search-extra-jisyo-files} が、@code{skk-extra-jisyo-file-list} の -各要素を逐次処理します。}。 -ただし、変数 @code{skk-jisyo-code} (@w{@pxref{辞書バッファの文字コードの設定}}) と -は異なる文字コードのファイルについては、上記の例中の @file{SKK-JISYO.JIS3_4} の -ように「ファイル名と文字コードのペア」を記述します。 -@end defvr - -これらの変数の意味するところは初期設定でのものですが、 -@code{skk-search-prog-list} の設定で変更することもできます。 -(@w{@pxref{辞書検索のための関数}}) +このように、辞書のファイル名のリストを指定します @footnote{@code{skk-search-prog-list} に登録されている関 +数 @code{skk-search-extra-jisyo-files} が、 @code{skk-extra-jisyo-file-list} の +各要素を逐次処理します。} 。 + +ただし、変数 @code{skk-jisyo-code} @footnote{@ref{辞書バッファの文字コードの設定}.} とは異なる文字コードのファイルに +ついては、上記の例中の @code{SKK-JISYO.JIS3_4} のように「ファイル名と文字コー +ドのペア」を記述します。 +@end defvar + +これらの変数の意味するところは初期設定でのものですが、 @code{skk-search-prog-list} の +設定で変更することもできます。 + +@ref{辞書検索のための関数}. @node 辞書の検索方法の設定 @subsection 辞書の検索方法の設定 -辞書の検索方法の指定は、変数 @code{skk-search-prog-list} で行われます。 -特に必要が無ければ、読み飛ばして下さい。 +辞書の検索方法の指定は、変数 @code{skk-search-prog-list} で行われます。特に必 +要が無ければ、読み飛ばして下さい。 + @menu * 辞書検索の設定の具体例:: @@ -7089,18 +6941,16 @@ @node 辞書検索の設定の具体例 @subsubsection 辞書検索の設定の具体例 -@vindex skk-search-prog-list -この節では、@code{skk-search-prog-list} の初期設定を示し、大体 -の流れを説明します。 +この節では @code{skk-search-prog-list} の初期設定を示し、大体の流れを説明しま +す。 -DDSKK では、複数の辞書を扱うことが可能です。複数の辞書が同時に -検索されるのではなく、指定した順番に検索します。 -@code{skk-search-prog-list} はリストであり、大雑把に言えば、 -確定されるまで、先頭の要素から順に lisp として評価されます。 +DDSKK では、複数の辞書を扱うことが可能です。複数の辞書が同時並列に検索さ +れるのではなく、指定した順番に検索します。 @code{skk-search-prog-list} はリス +トであり、大雑把に言えば、確定されるまで先頭の要素から順に lisp として評 +価されます。 @lisp -@group ((skk-search-kakutei-jisyo-file skk-kakutei-jisyo 10000 t) (skk-search-jisyo-file skk-initial-search-jisyo 10000 t) (skk-search-jisyo-file skk-jisyo 0 t) @@ -7111,292 +6961,264 @@ (skk-search-ja-dic-maybe) (skk-search-extra-jisyo-files) (skk-search-katakana-maybe) - (skk-search-sagyo-henkaku-maybe))) -@end group + (skk-search-sagyo-henkaku-maybe)) @end lisp この例では、 -@enumerate +@itemize @item -@code{skk-kakutei-jisyo} (@w{@pxref{確定辞書}}), -@code{skk-initial-search-jisyo}, @code{skk-jisyo} (個人辞書) の順に検索を -行い、 +@code{skk-kakutei-jisyo} (@ref{確定辞書}.) @item -次に送り仮名の自動処理を行い、(@w{@pxref{送り仮名の自動処理}}) +@code{skk-initial-search-jisyo} @item -その後、@code{skk-cdb-large-jisyo} と @code{skk-large-jisyo} の検索を順 -に行い、 +@code{skk-jisyo} (個人辞書) +@end itemize + +@noindent +の順に検索を行い、次に +@itemize @item -最後に @code{skk-aux-large-jisyo} に辞書サーバ経由でアクセスしています。 -@end enumerate +送り仮名の自動処理 (@ref{送り仮名の自動処理}.) +@end itemize + +@noindent +を行い、その後 -これらの辞書の意味については、@w{@pxref{辞書ファイルの指定}} 参照。 +@itemize +@item +@code{skk-cdb-large-jisyo} と -もし確定辞書で候補が見つかったらそのまま自動的に確定されます。1 回 -@key{SPC} を押す動作に対し、プログラム側では新たな候補を見つけるまで上記 -の動作を進めます。例えば、 -@enumerate @item -確定辞書では候補は見つけられなかったが @code{skk-initial-search-jisyo} -に候補がある場合、そこでいったん止まりユーザにその候補を表示します。 +@code{skk-large-jisyo} の +@end itemize + +@noindent +検索を順に行い、最後に @code{skk-aux-large-jisyo} に辞書サーバ経由でアクセスし +ています。 + +これらの辞書の意味について: @ref{辞書ファイルの指定}. +もし確定辞書で候補が見つかったらそのまま自動的に確定されます。1回 @code{SPC} を +押す動作に対し、プログラム側では新たな候補を見つけるまで上記の動作を進め +ます。例えば、 + +@itemize @item -更に @key{SPC} が押されると、次は個人辞書を検索します。そこで候補が見つ -かり、しかもその候補が @code{skk-initial-search-jisyo} で見つけた候補とは -異なるものであったときは、そこでまた止まりその候補をユーザに表示し -ます。 -@end enumerate +確定辞書では候補は見つけられなかったが @code{skk-initial-search-jisyo} に候 +補がある場合、そこでいったん止まりユーザにその候補を表示します。 -以降、共有辞書についても同様の繰り返しを行います。最後まで候補が -見つからなかった時は、辞書登録モードに入ります。 -@c DDSKK 14.1 では、以下はあてはまらない。 -@c -@c @footnote{@file{skk-auto.el} を読みこむと、 -@c -@c @lisp -@c (skk-okuri-search) -@c @end lisp -@c -@c @noindent -@c というリストが @code{skk-search-prog-list} に自動的に追加されます。実際 -@c には、@file{skk-auto.el} は必要に応じてオートロードされるので明示的に読みこむ必 -@c 要はありません。オートロードされるのは、具体的には -@c @code{skk-auto-okuri-process} を @code{non-nil} に設定したとき、 あるいは -@c -@c @lisp -@c (skk-okuri-search) -@c @end lisp -@c -@c @noindent -@c というリストを @code{skk-search-prog-list} に明示的に指定したときなどで -@c す。} -@c -@c @footnote{@file{skk-server.el} を読みこむと、 -@c -@c @lisp -@c (skk-search-server skk-aux-large-jisyo 10000) -@c @end lisp -@c -@c @noindent -@c というリストが @code{skk-search-prog-list} に自動的に追加されます。実際 -@c には、@file{skk-server.el} は必要に応じてオートロードされるので明示的に読みこむ -@c 必要はありません。オートロードされるのは、具体的には -@c @code{skk-server-host} または @code{skk-servers-list} を @code{non-nil} -@c に設定したとき、あるいは -@c -@c @lisp -@c (skk-search-server skk-aux-large-jisyo 10000) -@c @end lisp -@c -@c @noindent -@c というリストを @code{skk-search-prog-list} に明示的に指定したときなどで -@c す。} +@item +更に @code{SPC} が押されると、次は個人辞書を検索します。そこで候補が見つかり、 +しかもその候補が @code{skk-initial-search-jisyo} で見つけた候補とは異なるも +のであったときは、そこでまた止まりその候補をユーザに表示します。 +@end itemize + +以降、共有辞書についても同様の繰り返しを行います。最後まで候補が見つから +なかった時は、辞書登録モードに入ります。 @node 辞書検索のための関数 @subsubsection 辞書検索のための関数 -前節で見たとおり、変数 @code{skk-search-prog-list} を適切に定義することによ -って辞書の検索方法を指定します。 -そこで使われる辞書検索のための関数を使いこなすことで、 -より細かい辞書検索の方法を指定することができます。 - -@defun skk-search-jisyo-file FILE LIMIT &optional NOMSG -通常の検索を行うプログラム。変数 @code{skk-henkan-key} を見出し語(検索文 -字列)として、 FILE を被検索対象として変換検索を実施します。個人辞書、共 -有辞書又は辞書サーバを使わずに検索を行いたい場合はこの関数を使用します。 - -第1引数 @code{FILE} は、被検索対象となる辞書ファイルを指定します。 -@code{nil} を指定したときは、検索を行いません。 -@code{FILE} で指定した辞書ファイルは Emacs のバッファに読み込まれます。 +前節で見たとおり、変数 @code{skk-search-prog-list} を適切に定義することによっ +て辞書の検索方法を指定します。そこで使われる辞書検索のための関数を使いこ +なすことで、より細かい辞書検索の方法を指定することができます。 @cindex 二分検索 @cindex 直線的検索 -第2引数 @code{LIMIT} は二分検索(バイナリ・サーチ)が行なわれる領域の大 -きさを指定します。一つの見出し語に対する変換動作に対し、検索対象の領域の -大きさ@footnote{「検索領域の先頭ポイント」と「同末尾ポイント」の差}が第2 -引数に指定された数値より小さくなるまでは二分検索が行われ、最後に直線的検 -索(リニア・サーチ, search-forward)が1回行われます。 - -第2引数に 0 を指定すると、常に直線的検索のみが行われます。 -個人辞書 @code{skk-jisyo} はソートされておらず二分検索が不可能であるため @code{LIMIT} を 0 にして下さい。 - -第3引数 @code{NOMSG} が @code{nil} ならば、辞書ファイルをバッファに -読み込む関数 @code{skk-get-jisyo-buffer} のメッセージをミニバッファに出力し -ます。@code{non-nil} を与えると出力しません。 +@defun skk-search-jisyo-file FILE LIMIT &optional NOMSG + +通常の検索を行うプログラム。変数 @code{skk-henkan-key} を見出し語(検索文字 +列)として、 @code{FILE} を被検索対象として変換検索を実施します。個人辞書、 +共有辞書又は辞書サーバを使わずに検索を行いたい場合はこの関数を使用しま +す。 + +第1引数 @code{FILE} は、被検索対象となる辞書ファイルを指定します。 @code{nil} を +指定したときは、検索を行いません。 @code{FILE} で指定した辞書ファイルは Emacs の +バッファに読み込まれます。 + +第2引数 @code{LIMIT} は二分検索(バイナリ・サーチ)が行なわれる領域の大きさ +を指定します。ひとつの見出し語に対する変換動作に対し、検索対象の領域の +大きさ @footnote{検索領域の先頭ポイントと末尾ポイントの差} が第2引数に指定された数値より小さくなるまでは二分 +検索が行われ、最後に直線的検索(リニア・サーチ、 @code{search-forward} )が +1回行われます。 + +第2引数に 0 を指定すると、常に直線的検索のみが行われます。個人辞書 @code{skk-jisyo} は +ソートされておらず二分検索が不可能であるため @code{LIMIT} を 0 にして下さい。 + +第3引数 @code{NOMSG} が @code{nil} ならば、辞書ファイルをバッファに読み込む関 +数 @code{skk-get-jisyo-buffer} のメッセージをエコーエリアに出力します。 @code{non-nil} を +与えると出力しません。 @end defun + @defun skk-search-cdb-jisyo CDB-PATH not documented - @end defun -@defun skk-search-kakutei-jisyo-file FILE LIMIT &optional NOMSG @cindex 確定変換 @vindex skk-kakutei-henkan-flag -@b{「確定変換」}を行う検索プログラム。検索対象の辞書ファイルは Emacs の -バッファに読み込まれます。検索対象のファイルから候補を見つけると、内部 -変数 @code{skk-kakutei-henkan-flag} を立てて、いきなり確定します。このため -ユーザが確定操作を行う必要はありません。 +@defun skk-search-kakutei-jisyo-file FILE LIMIT &optional NOMSG -引数の意味はいずれも @code{skk-search-jisyo-file} の場合と同様です。 +確定変換を行う検索プログラム。検索対象の辞書ファイルは Emacs のバッファ +に読み込まれます。検索対象のファイルから候補を見つけると、内部変数 @code{skk-kakutei-henkan-flag} を +立てて、いきなり確定します。このためユーザが確定操作を行う必要はありま +せん。引数の意味はいずれも @code{skk-search-jisyo-file} の場合と同様です。 @end defun -@w{@xref{確定辞書}.} - @defun skk-okuri-search -形式: (skk-okuri-search) -自動送り処理を行うプログラム。変数 @code{skk-auto-okuri-process} の値 -が @code{non-nil} のときだけ機能します。 +自動送り処理を行うプログラム。変数 @code{skk-auto-okuri-process} の値が @code{non-nil} の +ときだけ機能します。個人辞書の送りありエントリを検索対象としているので、 +個人辞書のバッファを流用します。そのため、専用の辞書バッファは作りません。 -個人辞書の送りありエントリを検索対象としているので、個人辞書のバッファを -流用します。そのため、専用の辞書バッファは作りません。 - -@w{@xref{送り仮名の自動処理}.} +@ref{送り仮名の自動処理}. @end defun @defun skk-search-server FILE LIMIT &optional NOMSG -辞書サーバ経由で検索するプログラム。 -辞書サーバが使用不能になると辞書ファイルを Emacs のバッファに読み込んで -検索を行います。引数の意味はいずれも @code{skk-search-jisyo-file} と -同じですが、これらは辞書を Emacs のバッファに読み込んだときのみ利用されます。 +辞書サーバ経由で検索するプログラム。辞書サーバが使用不能になると辞書フ +ァイルを Emacs のバッファに読み込んで検索を行います。引数の意味はいずれ +も @code{skk-search-jisyo-file} と同じですが、これらは辞書を Emacs のバッフ +ァに読み込んだときのみ利用されます。 辞書サーバが使う辞書ファイルの設定については、 -@itemize @bullet -@item @w{@pxref{辞書サーバを使いたいときの設定}} -@item @w{@pxref{サーバ関連}} -@end itemize +@itemize +@item +@ref{辞書サーバを使いたいときの設定}. + +@item +@ref{サーバ関連}. +@end itemize をご覧下さい。 @end defun @node Emacs 付属の辞書 @subsection Emacs 付属の辞書 -GNU Emacs には、 @file{SKK-JISYO.L} を元に変換された @file{leim/ja-dic/ja-dic.el} とい -う辞書が付属しています。 +GNU Emacs には、 @code{SKK-JISYO.L} を元に変換された @code{leim/ja-dic/ja-dic.el} と +いう辞書が付属しています。 -DDSKK 14.2 からは、この @file{ja-dic.el} を利用したかな漢字変換 (送りあり、 -送りなし、接頭辞、接尾辞) が可能となりました。 -つまり、@file{SKK-JISYO.L} などの辞書ファイルを別途準備しなくても一応 -は DDSKK の使用が可能、ということです。 +DDSKK 14.2 からは、この @code{ja-dic.el} を利用したかな漢字変換(送りあり、送 +りなし、接頭辞、接尾辞)が可能となりました。つまり、 @code{SKK-JISYO.L} などの +辞書ファイルを別途準備しなくても一応は DDSKK の使用が可能、ということです。 DDSKK 14.2 から追加された「ja-dic.el 検索機能」(@code{skk-search-ja-dic}) は、 -@itemize @bullet -@item @code{skk-large-jisyo} -@item @code{skk-aux-large-jisyo} -@item @code{skk-cdb-large-jisyo} -@item @code{skk-server-host} +@itemize +@item +@code{skk-large-jisyo} + +@item +@code{skk-aux-large-jisyo} + +@item +@code{skk-cdb-large-jisyo} + +@item +@code{skk-server-host} @end itemize の全てが無効な場合に有効となります。 -ただし、@file{SKK-JISYO.L} を利用する場合と比べて英数変換や数値変換などが -できません。可能な限り @file{SKK-JISYO.L} などの辞書を利用することを推奨 -します。 - -関連項目: @w{@ref{辞書の入手}} +ただし、 @code{SKK-JISYO.L} を利用する場合と比べて英数変換や数値変換などができ +ません。可能な限り @code{SKK-JISYO.L} などの辞書を利用することを推奨します。 -@defvr {ユーザ変数} skk-inhibit-ja-dic-search +@ref{辞書の入手}. -この変数を @code{Non-nil} に設定すると、@code{skk-large-jisyo} 等の値にか -かわらず、あらゆる場面で @code{skk-search-ja-dic} を無効とします。 +@defopt skk-inhibit-ja-dic-search -@end defvr +この変数を @code{Non-nil} に設定すると、 @code{skk-large-jisyo} 等の値にかかわら +ず、あらゆる場面で @code{skk-search-ja-dic} を無効とします。 +@end defopt @defun skk-search-ja-dic -GNU Emacs に付属するかな漢字変換辞書 @file{ja-dic.el} を用いて検索する。 -現在の Emacs には @file{SKK-JISYO.L} を基に変換された @file{ja-dic.el} が付属している。 -この辞書データを用いて送りあり、送りなし、接頭辞、接尾辞の変換を行う。 -ただし、@file{SKK-JISYO.L} のような英数変換、数値変換などはできず、また「大丈夫」 -のように複合語とみなしうる語彙が大幅に削除されている。 - +GNU Emacs に付属するかな漢字変換辞書 @code{ja-dic.el} を用いて検索する。現在 +の GNU Emacs には @code{SKK-JISYO.L} を基に変換された @code{ja-dic.el} が付属して +いる。この辞書データを用いて送りあり、送りなし、接頭辞、接尾辞の変換を +行う。ただし、 @code{SKK-JISYO.L} のような英数変換、数値変換などはできず、ま +た「大丈夫」のように複合語とみなしうる語彙が大幅に削除されている。 @end defun @node サーバ関連 @subsection サーバ関連 - -辞書サーバの基本的な設定は、@w{@pxref{辞書サーバを使いたいときの設定}} を -ご覧下さい。 -@defvr {ユーザ変数} skk-servers-list +辞書サーバの基本的な設定: @ref{辞書サーバを使いたいときの設定}. + +@defvar skk-servers-list この変数を使うと、複数のホスト上の辞書サーバを使い分けることができます。 +この変数の値は、辞書サーバ毎の情報リストです。各リストは次の4つの要素 +から成ります。 + +@itemize +@item +ホスト名 -この変数の値は、辞書サーバ毎の情報リストです。各リストは次の 4 つの要素か -ら成ります。 +@item +辞書サーバ名(フルパス) -@itemize @bullet -@item ホスト名 -@item 辞書サーバ名 (フルパス) -@item 辞書サーバが読み込む辞書ファイル名 -@item 辞書サーバが使用するポート番号 -@end itemize +@item +辞書サーバが読み込む辞書ファイル名 -ただし、辞書ファイル名及びポート番号は、辞書サーバ自身が決定することもあるため、そのような場合は @code{nil} として構いません。 +@item +辞書サーバが使用するポート番号 +@end itemize +ただし、辞書ファイル名及びポート番号は、辞書サーバ自身が決定することも +あるため、そのような場合は @code{nil} として構いません。 例えば、以下のように設定します。 @lisp -@group (setq skk-servers-list '(("host1" "/your/path/to/skkserv" nil nil) ("host2" "/your/path/to/skkserv" nil nil))) -@end group @end lisp -上記の設定の場合、まず host1 上の辞書サーバと接続します。接続できなくなると、 -次に host2 上の辞書サーバと接続します。 -@end defvr +上記の設定の場合、まず host1 上の辞書サーバと接続します。接続できなくな +ると、次に host2 上の辞書サーバと接続します。 +@end defvar -@defvr {ユーザ変数} skk-server-report-response +@defvar skk-server-report-response この変数の値が @code{non-nil} であれば、変換時に、辞書サーバの送出する文字を 受け取るまでに関数 @code{accept-process-output} が実行された回数をエコーエリ アに報告します。 @example -@group -------------------- Echo Area -------------------- 辞書サーバの応答を 99 回待ちました -------------------- Echo Area -------------------- -@end group @end example +@end defvar -@end defvr - -@defvr {ユーザ変数} skk-server-inhibit-startup-server - -デフォルト値は @code{t} です。この変数を @code{nil} に設定すると、辞書サ -ーバと接続できない場合に @code{call-process} で辞書サーバプログラムの起動 -を試みます。 +@defvar skk-server-inhibit-startup-server -inetd 経由で起動する多くの辞書サーバは @code{call-process} で起動するこ -とができませんが、@file{skkserv} のように @code{call-process} で起動する -ことができる辞書サーバを利用している場合には、この変数を @code{nil} に設 -定するのが良いかもしれません。 +標準設定値は @code{t} です。この変数を @code{nil} に設定すると、辞書サーバと接 +続できない場合に @code{call-process} で辞書サーバプログラムの起動を試みます。 -@end defvr +@code{inetd} 経由で起動する多くの辞書サーバは @code{call-process} で起動すること +ができませんが、 @code{skkserv} のように @code{call-process} で起動することができ +る辞書サーバを利用している場合には、この変数を @code{nil} に設定するのが良い +かもしれません。 +@end defvar -@defvr {ユーザ変数} skk-server-remote-shell-program +@defvar skk-server-remote-shell-program -この変数には、リモートシェルのプログラム名を指定します。デフォルトは、システ -ム依存性を考慮する必要があるため、以下の Emacs Lisp コードを評価すること -により決定されています。 +この変数には、リモートシェルのプログラム名を指定します。標準設定は、 +システム依存性を考慮する必要があるため、以下の Emacs Lisp コードを評価 +することにより決定されています。 @lisp -@group (or (getenv "REMOTESHELL") (and (boundp 'remote-shell-program) remote-shell-program) (cond @@ -7408,86 +7230,76 @@ ((eq system-type 'EWS-UX/V) "/usr/ucb/remsh") ((eq system-type 'pcux) "/usr/bin/rcmd") (t "rsh"))) -@end group @end lisp -@end defvr +@end defvar + +@defun skk-server-version -@defun {コマンド} skk-server-version 辞書サーバから得たバージョン文字列とホスト名文字列を表示する。 @example (skk-server-version) -@print{} SKK SERVER version (wceSKKSERV) 0.2.0.0 (ホスト名 foo:192.168.0.999: ) +-| SKK SERVER version (wceSKKSERV) 0.2.0.0 (ホスト名 foo:192.168.0.999: ) @end example - @end defun @node サーバコンプリージョン @subsection サーバコンプリージョン -Server completion に対応した辞書サーバであれば、見出し語から始まる全ての語句 -の検索が可能です。 +Server completion に対応した辞書サーバであれば、見出し語から始まる全ての +語句の検索が可能です。 @defun skk-comp-by-server-completion + この関数を @code{skk-completion-prog-list} の要素に追加すると、▽モードにお いて見出し語補完を実行します。 @lisp -@group (add-to-list 'skk-completion-prog-list '(skk-comp-by-server-completion) t) -@end group @end lisp - @end defun @defun skk-server-completion-search -この関数を @code{skk-search-prog-list} の要素に追加すると、 -変換を実行する際に @code{skk-server-completion-search-char} を付すことに -よって見出し語で始まるすべての候補を掲げます。 + +この関数を @code{skk-search-prog-list} の要素に追加すると、変換を実行する際 +に @code{skk-server-completion-search-char} を付すことによって見出し語で始ま +るすべての候補を掲げます。 +@end defun + @lisp -@group (add-to-list 'skk-search-prog-list '(skk-server-completion-search) t) -@end group @end lisp @example - -@group ------- Buffer: foo ------ -▽おおさか~@point{} ------- Buffer: foo ------ -@end group - -@key{SPC} - -@group ------- Buffer: *候補* ------ -A:おおさかいかだいがく -S:大阪医科大学 -D:おおさかいがい -F:大阪以外 -J:おおさかいだい -K:大阪医大 -L:おおさかいちりつだいがく ------- Buffer: *候補* ------ -@end group - + ------ Buffer: foo ------ + ▽おおさか~* + ------ Buffer: foo ------ + +SPC + + ------ Buffer: *候補* ------ + A:おおさかいかだいがく + S:大阪医科大学 + D:おおさかいがい + F:大阪以外 + J:おおさかいだい + K:大阪医大 + L:おおさかいちりつだいがく + ------ Buffer: *候補* ------ @end example -@end defun - -@defvr {ユーザ変数} skk-server-completion-search-char - -デフォルトは @samp{~}(チルダ、#x7e)です。 +@defvar skk-server-completion-search-char -@end defvr +標準設定は @code{~} (チルダ、 @code{#x7e} )です。 +@end defvar @node 辞書の書式 @subsection 辞書の書式 + @menu * 送りありエントリと送りなしエントリ:: * 送りありエントリのブロック形式:: @@ -7502,14 +7314,13 @@ @cindex ;; okuri-ari entries. @cindex ;; okuri-nasi entries. @example -@group ;; okuri-ari entries. たとe /例/[え/例/]/ もt /持/[つ/持/]/[って/持/]/[た/持/]/[て/持/]/[ち/持/]/[と/持/]/ たすk /助/[け/助/]/ うごk /動/[く/動/]/[か/動/]/[け/動/]/[き/動/]/[こ/動/]/ ふくm /含/[め/含/]/[む/含/]/[ま/含/]/[み/含/]/[も/含/]/ -@dots{} +: ;; okuri-nasi entries. てん /点/・/天/ ひつよう /必要/ @@ -7519,163 +7330,143 @@ ぐん /群/郡/ こうほ /候補/ いち /位置/一/壱/ -@dots{} -@end group @end example -@noindent -@samp{てん /点/・/天/} を例にして説明します。これは @samp{てん} が見出し -語であり、その候補が、@samp{点}、@samp{・}、@samp{天} です。候補はそれぞ -れ、@samp{/} によって区切られています。SKK では、見出し語と候補群を合わ -せた @w{@samp{てん /点/・/天/}} の一行を@b{「エントリ」}と呼びます。 @cindex エントリ +@code{てん /点/・/天/} を例にして説明します。これは「てん」が見出し語であり、 +その候補が「点」、「・」、「天」です。候補はそれぞれ @code{/} によって区切られ +ています。SKK では、見出し語と候補群を合わせた @code{てん /点/・/天/} の一行 +を @strong{エントリ} と呼びます。 -辞書は単純なテキストファイルで、必ず下記の 2 つの行を持っています。 +辞書は単純なテキストファイルで、必ず下記の2つの行を持っています。 -@example -@group -;; okuri-ari entries. -;; okuri-nasi entries. -@end group -@end example +@itemize +@item +@code{;; okuri-ari entries.} -@noindent -この 2 つの行は、それぞれ送り仮名あり、送り仮名なしのエントリの開始地点 -を示すマークです。 @samp{;; okuri-ari entries.} までの行で @samp{;} を行 -頭に持つ行はコメント行として無視されます。@samp{;; okuri-ari entries.} -以降にコメント行を含むことはできません。 - -@w{@samp{;; okuri-ari entries.}} と @w{@samp{;; okuri-nasi entries.}} の -間に囲まれた上半分の部分が送り仮名ありのエントリです。これを@b{「送りあ -りエントリ」}と呼びます。 -@cindex 送りありエントリ -@w{@samp{;; okuri-nasi entries.}}以下の下半分部分が送り仮名なしのエント -リです。これを@b{「送りなしエントリ」}と呼びます。 -@cindex 送りなしエントリ +@item +@code{;; okuri-nasi entries.} +@end itemize + +この2つの行は、それぞれ送り仮名あり、送り仮名なしのエントリの開始地点を +示すマークです。 @code{;; okuri-ari entries.} までの行で @code{;} を行頭に持つ行は +コメント行として無視されます。 @code{;; okuri-ari entries.} 以降にコメント行を +含むことはできません。 + +@code{;; okuri-ari entries.} と @code{;; okuri-nasi entries.} の間に囲まれた上半分 +の部分が送り仮名ありのエントリです。これを @strong{送りありエントリ} と呼びます。 + +@code{;; okuri-nasi entries.} 以下の下半分部分が送り仮名なしのエントリです。 +これを @strong{送りなしエントリ} と呼びます。 @cindex 送りあり変換 @cindex 送りなし変換 -送りありエントリを検索する変換を@b{「送りあり変換」}、送りなしエントリを -検索する変換を@b{「送りなし変換」}と呼びます。SKK では送り仮名の有無が変 -換方法の 1 つの種別となっています。送り仮名がある変換では送りありエント -リのみが検索され、送り仮名がない変換では送りなしエントリのみが検索されま -す。 +送りありエントリを検索する変換を @strong{送りあり変換} 、送りなしエントリを検索 +する変換を @strong{送りなし変換} と呼びます。SKK では送り仮名の有無が変換方法の +ひとつの種別となっています。送り仮名がある変換では送りありエントリのみが +検索され、送り仮名がない変換では送りなしエントリのみが検索されます。 + +ひとつの見出し語についてのエントリは1行内に書かれます。2行以上にまたが +ることはできません。改行を含む候補については @code{(concat "改\n行")} のように、 +評価すると改行を該当個所に挿入するような Lisp プログラムに変換して辞書に +収めています。 -1 つの見出し語についてのエントリは 1 行内に書かれます。2 行以上にまたが -ることはできません。改行を含む候補については、@code{(concat "改\n行")} -のように、評価すると改行を該当個所に挿入するような Lisp プログラム -(@w{@pxref{プログラム実行変換}}) に候補を変換して辞書に収めています。 +@ref{プログラム実行変換}. @cindex ローマ字プレフィックス -送りありエントリは、基本的には @samp{もt /持/} のようになっています。送 -り仮名部分は、送り仮名をローマ字表現したときの 1 文字目 -@footnote{あるかな文字をローマ字表現したときの 1 文字目を@b{「ローマ字プ -レフィックス」}と呼びます。}で表現されています。 -この 1 エントリで @samp{持た}、@samp{持ち}、@samp{持つ}、@samp{持て}、 -@samp{持と} の5つの候補に対応します。その5つの候補の送り仮名をローマ -字プレフィックスで表現すれば、いずれも @samp{t} になります。 +送りありエントリは、基本的には @code{もt /持/} のようになっています。送り仮名 +部分は、送り仮名をローマ字表現したときの1文字目 @footnote{あるかな文字をローマ字表現したときの1文字目を @strong{ローマ字プレフィックス} と +呼びます。} で表現されていま +す。この1エントリで「持た」「持ち」「持つ」「持て」「持と」の5つの候補 +に対応します。その5つの候補の送り仮名をローマ字プレフィックスで表現すれば、 +いずれも @code{t} になります。 @node 送りありエントリのブロック形式 @subsubsection 送りありエントリのブロック形式 -個人辞書の送りありエントリには @samp{[} と @samp{]} に囲まれたブロックが -あります。これは、そのブロックの先頭にある平仮名を送り仮名に取る候補群で -す。 +個人辞書の送りありエントリには @code{[} と @code{]} に囲まれたブロックがあります。 +これは、そのブロックの先頭にある平仮名を送り仮名に取る候補群です。 @example -@group たとe /例/[え/例/]/ -@dots{} +: ふくm /含/[め/含/]/[む/含/]/[ま/含/]/[み/含/]/[も/含/]/ -@end group @end example -この例で見ると、見出し語 @samp{たとe} の場合は @samp{え} を送り仮名とす -る 1 つのブロックから構成されています。見出し語 @samp{ふくm} の場合は、 -@samp{ま}、@samp{み}、@samp{む}、@samp{め}、@samp{も} を送り仮名とする5 -ブロックに分けられています。 +この例で見ると、見出し語「たとe」の場合は「え」を送り仮名とするひとつブロ +ックから構成されています。見出し語「ふくm」の場合は「ま」「み」「む」「め」「も」 +を送り仮名とする5ブロックに分けられています。 @vindex skk-auto-okuri-process @vindex skk-henkan-okuri-strictly -この送り仮名毎のブロック部分は、@code{skk-henkan-okuri-strictly} あるい -は @code{skk-auto-okuri-process} のいずれかの変数が @code{non-nil} で -ある場合に使用されます。その場合、検索において、見出し語の一致に加えて、 -更に送り仮名もマッチするかどうかをテストします。例えば、 +この送り仮名毎のブロック部分は、 @code{skk-henkan-okuri-strictly} あるい +は @code{skk-auto-okuri-process} のいずれかの変数が @code{non-nil} である場合に使用 +されます。その場合、検索において、見出し語の一致に加えて、更に送り仮名も +マッチするかどうかをテストします。例えば、 @example おおk /大/多/[く/多/]/[き/大/]/ @end example @noindent -というエントリがあるとします。同じ見出し語 @samp{おおk} であっても、送り -仮名が @samp{き} であれば、候補は @samp{大} のみで @samp{多} は無視されま -す。 -@footnote{@xref{送り仮名の自動処理, , skk-henkan-okuri-strictly}. -@xref{送り仮名の厳密なマッチ, , skk-auto-okuri-process}. -@xref{送り仮名の優先的なマッチ, , skk-henkan-strict-okuri-precedence}. -} +というエントリがあるとします。同じ見出し語「おおk」であっても、送り仮名が +「き」であれば、候補は「大」のみで「多」は無視されます @footnote{@ref{送り仮名の自動処理}. + +@ref{送り仮名の厳密なマッチ}. + +@ref{送り仮名の優先的なマッチ}.} 。 @vindex skk-process-okuri-early -現在 @url{http://openlab.jp/skk/dic.html} で配布されている共有辞書では、 -@samp{[} と @samp{]} を使用した送り仮名毎のブロックの形式に対応していません。 -個人辞書のみがこの形式で書き込まれていきます。 -@code{skk-henkan-okuri-strictly} が @code{nil} であっても送り仮名のブロッ -ク形式で書き込まれます。@footnote{ただし @code{skk-process-okuri-early} -の値が @code{non-nil} であれば、送り仮名を決定する前に変換を開始すること -になるので、送り仮名を明示的に入力していても個人辞書にはブロック形式は作 -られません。} +@uref{http://openlab.jp/skk/dic.html} で配布されている共有辞書では、 @code{[} と @code{]} を +使用した送り仮名毎のブロックの形式に対応していません。個人辞書のみがこの +形式で書き込まれていきます。 @code{skk-henkan-okuri-strictly} が @code{nil} であっ +ても送り仮名のブロック形式で書き込まれます @footnote{ただし @code{skk-process-okuri-early} の値が @code{non-nil} であれば、 +送り仮名を決定する前に変換を開始することになるので、送り仮名を明示的に入 +力していても個人辞書にはブロック形式は作られません。} 。 @node エントリの配列 @subsubsection エントリの配列 @cindex 辞書のソート方法 -共有辞書は、送りありエントリは @w{@samp{;; okuri-ari entries.}} から順 -に下方向に見出し語をキーとして@b{降順}に配置され、送りなしエントリ -は @w{@samp{;; okuri-nasi entries.}} から順に下方向に見出し語をキーと -して@b{昇順}に配置されます。 -降順/昇順に配置されるのは、辞書サイズが大きいことに配慮して二分検索 -を行うためです -@footnote{ソートする際には、見出し語を unsigned-char と見なします。 -この順序は Emacs が 関数 @code{string<} で文字列を比較するときの順序であ -り、UNIX の @command{sort} コマンドでの標準の順序とは異なります。 -Emacs のコマンド @code{sort-lines}を用いればファイルをこの順序でソートす -ることができます。Emacs のコマンド @code{sort-columns} は内部的に UNIX コ -マンドの @command{sort} を使っているので、辞書のソートには使えません。}。 - -一方、個人辞書は、一番最後に変換された語が最も手前に置かれます。 -つまり、送りなし/送りあり、それぞれのエントリが -@w{@samp{;; okuri-ari entries.}}, @w{@samp{;; okuri-nasi entries.}} を -基点として最小ポイントに挿入されて辞書が -更新されます @footnote{正確に言えば、送りあり変換では @w{@code{skk-okuri-ari-min}+ 1} -の位置、送りなし変換では @w{@code{skk-okuri-nasi-min}+ 1} の位置。}。 +共有辞書は、送りありエントリは @code{;; okuri-ari entries.} から順に下方向に見 +出し語をキーとして @strong{降順} に配置され、送りなしエントリ +は @code{;; okuri-nasi entries.} から順に下方向に見出し語をキーとして @strong{昇順} に +配置されます。降順/昇順に配置されるのは、辞書サイズが大きいことに配慮して +二分検索(バイナリサーチ)を行うためです @footnote{ソートする際には、見出し語を unsigned-char と見なします。この順 +序は Emacs が 関数 @code{string<} で文字列を比較するときの順序であり、UNIX の @code{sort} コマンド +での標準の順序とは異なります。Emacs のコマンド @code{sort-lines} を用いればフ +ァイルをこの順序でソートすることができます。Emacs のコマンド @code{sort-columns} は +内部的に UNIX コマンドの @code{sort} を使っているので、辞書のソートには使えません。} 。 + +一方、個人辞書は、一番最後に変換された語が最も手前に置かれます。つまり、 +送りなしエントリは @code{;; okuri-ari entries.} を、送りありエントリは @code{;; okuri-nasi entries.} を +基点として最小ポイントに挿入されて辞書が更新されます @footnote{正確に言えば、送りあり変換では @code{skk-okuri-ari-min + 1} の位置、 +送りなし変換では @code{skk-okuri-nasi-min + 1} の位置} 。 個人辞書は、通常は共有辞書ほどはサイズが大きくないので、検索時にはそれぞ -れの基点から直線的に検索が行われます。 - -最後に確定された語は、一つのエントリの中の最初の位置に置かれます。 - +れの基点から直線的検索(リニアサーチ)が行われます。最後に確定された語は、 +ひとつのエントリの中の最初の位置に置かれます。 + @node 強制的に辞書登録モードへ入る @subsection 強制的に辞書登録モードへ入る -@kindex . -▼モードにて、エコーエリアに変換候補が表示されているときに @kbd{.} をタイ -プすると、強制的に辞書登録モードへ入ります。 -@defvr {ユーザ変数} skk-force-registration-mode-char +▼モードにて、エコーエリアに変換候補が表示されているときに @code{.} を打鍵する +と、強制的に辞書登録モードへ入ります。 + +@defvar skk-force-registration-mode-char + 強制的に辞書登録モードへ入るためのキーキャラクタをこの変数で定義します。 -標準設定は @kbd{.} です。 -@end defvr +標準設定は @code{.} です。 +@end defvar @node 誤った登録の削除 @subsection 誤った登録の削除 -@cindex 個人辞書エントリの削除 -@cindex 誤登録 -@kindex X 誤って個人辞書に登録した単語は削除できます。 -削除したい単語を変換により求め、その単語が表示された時点で @kbd{X} を入力 -します。ミニバッファに確認プロンプトが出るので @kbd{y e s} と答えると、個 -人辞書の対応するエントリが削除されます。現在のバッファに先程入力した「誤 -りの変換結果」も削除されます。 +削除したい単語を変換により求め、その単語が表示された時点 @footnote{確定する前の▼モードの状態} で @code{X} (大文字のエックス) +を打鍵します。ミニバッファに確認プロンプトが出るので @code{y e s} と答えると、 +個人辞書の対応するエントリが削除されます。現在のバッファに先程入力した +「誤りの変換結果」も削除されます。 例えば、 @@ -7688,334 +7479,298 @@ 場合を説明します。 @example -@kbd{S a i k i t e k i @key{SPC}} - -@group ------- Buffer: foo ------ -▼再起的@point{} ------- Buffer: foo ------ -@end group +S a i k i t e k i SPC -@kbd{X} + ------ Buffer: foo ------ + ▼再起的* + ------ Buffer: foo ------ -@group ------------------- MiniBuffer ------------------ -Really purge ``さいきてき /再起的/''?(yes or no) @point{} ------------------- MiniBuffer ------------------ -@end group +X -@kbd{y e s @key{RET}} + ------------------ MiniBuffer ------------------ + Really purge "さいきてき /再起的/" ? (yes or no) * + ------------------ MiniBuffer ------------------ -@group ------- Buffer: foo ------ -@point{} ------- Buffer: foo ------ -@end group +y e s RET + ------ Buffer: foo ------ + * + ------ Buffer: foo ------ @end example @node 個人辞書ファイルの編集 @subsection 個人辞書ファイルの編集 -@kindex M-x skk-edit-private-jisyo -@b{構文チェックが十分ではありません。個人辞書ファイルの編集は、自己責任 -のもと行ってください。} +@strong{構文チェックが十分ではありません。個人辞書ファイルの編集は、自己責任のもと行ってください。} -コマンド @kbd{M-x skk-edit-private-jisyo} を使うと、個人辞書ファイルが -開かれます@footnote{前置引数を伴って実行 (@kbd{C-u M-x skk-edit-private-jisyo}) す -ることで、コーディングシステムを指定して個人辞書を開くことができます。}。 - -個人辞書ファイルを開いて編集している最中も skk を使えますが、 -skk からの単語の登録、削除はできません。(他にも少し制限がありますが、 -気にならないでしょう。) +@kindex C-c C-c +@table @asis +@kindex M-x skk-edit-private-jisyo +@cindex skk-edit-private-jisyo +@item @kbd{M-x skk-edit-private-jisyo} @tie{}@tie{}@tie{}@tie{}(@code{skk-edit-private-jisyo}) -編集が終わったら、@kbd{C-c C-c} と押すと個人辞書ファイルをセーブしてバッ +このコマンドを使うと、個人辞書ファイルが開かれます @footnote{前置引数を伴って実行する( @code{C-u M-x skk-edit-private-jisyo} ) +ことで、コーディングシステムを指定して個人辞書を開くことができます。} 。個人辞書 +ファイルを開いて編集している最中も skk を使えますが、skk からの単語の登 +録、削除はできません。他にも少し制限がありますが、気にならないでしょう。 + +編集が終わったら @code{C-c C-c} とキー入力と、個人辞書ファイルを保存してバッ ファを閉じます。 +@end table @node 個人辞書の保存動作 @subsection 個人辞書の保存動作 -@cindex 個人辞書 -@cindex 個人辞書のオートセーブ -@kindex C-x C-c -@vindex skk-save-jisyo-instantly -個人辞書の保存動作について説明します。 +個人辞書の保存動作について説明します。個人辞書の保存が行われる場合として、 +次の4通りがあります。 -個人辞書の保存が行われる場合として、次の4通りがあります。 - -@enumerate +@itemize @item -@kbd{C-x C-c} (または @kbd{M-x save-buffers-kill-emacs}) によって Emacs を -終了する場合。 +@code{C-x C-c} または @code{M-x save-buffers-kill-emacs} によって Emacs を終了す +る場合 + @item -@kbd{M-x skk-save-jisyo} と入力したか、メニューバーの @samp{Save Jisyo} を -選択した場合。 +@code{M-x skk-save-jisyo} と入力したか、メニューバーの @code{Save Jisyo} を選択し +た場合 + @item -個人辞書の更新回数が、変数 @code{skk-jisyo-save-count} で指定された値に -達した結果として、自動保存 (オートセーブ) 機能が働くとき。 +個人辞書の更新回数が、変数 @code{skk-jisyo-save-count} で指定された値に達し +た結果として、自動保存(オートセーブ)機能が働くとき。 + -@item -変数 @code{skk-save-jisyo-instantly} が @code{non-nil} であれば、 -単語登録(単語削除)のたびに個人辞書を保存する。 -@end enumerate +@item +変数 @code{skk-save-jisyo-instantly} が @code{non-nil} であれば、単語登録(単語削 +除)のたびに個人辞書を保存する。 +@end itemize -保存動作を分析して考えます。まず、 Emacs に読み込んだ個人辞書が更新され -ているかどうかを調べます。更新されていたら保存動作に入ります。Emacs の個 -人辞書バッファを一時ファイルに保存して、そのファイルサイズが現存の (セー -ブ前の) 個人辞書より小さくないかどうかをチェックします。個人辞書より小さ -いときは、保存動作を継続するかどうか、確認のための質問がされます -@footnote{通常の使用の範囲では @kbd{M-x skk-purge-from-jisyo} した場合、あ +保存動作を分析して考えます。まず、 Emacs に読み込んだ個人辞書が更新されて +いるかどうかを調べます。更新されていたら保存動作に入ります。Emacs の個人 +辞書バッファを一時ファイルに保存して、そのファイルサイズが現存の(セーブ +前の)個人辞書より小さくないかどうかをチェックします。個人辞書より小さい +ときは、保存動作を継続するかどうか、確認のための質問がされます @footnote{通常の使用の範囲では @code{M-x skk-purge-from-jisyo} した場合、あ るいは個人辞書をユーザが意図的に編集した場合、複数の Emacs で DDSKK を 使用した場合などに、個人辞書が小さくなることがあります。他の場合はバグの -可能性があります。}。 +可能性があります。} 。 @example -@group - --------------------------- Minibuffer ----------------------------- New ~/.skk-jisyo will be 11bytes smaller. Save anyway?(yes or no) --------------------------- Minibuffer ----------------------------- - -@end group @end example @noindent -ここで @kbd{n o @key{RET}} と答えた場合は、そこで保存動作が中止され、個 -人辞書は以前の状態のままになります。@kbd{y e s @key{RET}} と答えた場合は -元の個人辞書を退避用の辞書 @file{~/.skk-jisyo.BAK} に退避し、一時ファイ -ルに保存した新しい個人辞書を @code{skk-jisyo} に保存します。 +ここで @code{n o RET} と答えた場合は、そこで保存動作が中止され、個人辞書は以前 +の状態のままになります。 @code{y e s RET} と答えた場合は、元の個人辞書を退避用 +の辞書 @code{~/.skk-jisyo.BAK} に退避し、一時ファイルに保存した新しい個人辞書 +を @code{skk-jisyo} に保存します。 + +もし、一時ファイルのサイズが 0 である場合は、なんらかの異常と考えられるた +め保存動作は直ちに中止されます。 +その場合は @code{M-x skk-kill-emacs-without-saving-jisyo} で Emacs を終了させ、 +個人辞書 (@code{skk-jisyo}) 及び個人辞書の退避用辞書 (@code{skk-backup-jisyo}) をチ +ェックするよう強くお勧めします @footnote{@code{skk-jisyo} が既に壊れていても、変数 @code{skk-backup-jisyo} が指し +示すファイルにそれ以前の個人辞書が残っている可能性があります。} 。 -もし、一時ファイルのサイズが 0 である場合は、なんらかの異常と考えられる -ため保存動作は直ちに中止されます。その場合は +@defopt skk-compare-jisyo-size-when-saving -@kindex M-x skk-kill-emacs-without-saving-jisyo +この変数の値を @code{nil} に設定すると、保存前の個人辞書とのサイズを比較しま +せん。 +@end defopt -@kbd{M-x skk-kill-emacs-without-saving-jisyo} +@defvar skk-jisyo-save-count -@noindent -で Emacs を終了させ、個人辞書 (@code{skk-jisyo}) 及び個人辞書の退避用辞 -書 (@code{skk-backup-jisyo}) をチェックするよう強くお勧めします -@footnote{@code{skk-jisyo} が既に壊れていても、変数 @code{skk-backup-jisyo} が -指し示すファイルにそれ以前の個人辞書が残っている可能性があります。}。 +この変数で指定された回数、個人辞書が更新された場合に個人辞書が自動保存 +されます。標準設定は 50 です。この値を @code{nil} にすると、個人辞書の自動 +保存機能が無効になります。 -@defvr {ユーザ変数} skk-compare-jisyo-size-when-saving -この変数の値を @code{nil} に設定すると、保存前の個人辞書とのサイズを比較 -しません。 -@end defvr +ここで、個人辞書の更新回数は確定回数と一致します。また、同じ候補につい +て確定した場合でもそれぞれ1回と数えられます @footnote{これは、個人辞書の最小ポイントに、常に最後に変換を行ったエン +トリを移動させるために、エントリ数、候補数が全く増えていなくとも、確定に +より個人辞書が更新されているからです。} 。 +@end defvar -@defvr {ユーザ変数} skk-jisyo-save-count +@defopt skk-save-jisyo-instantly -この変数で指定された回数、個人辞書が更新された場合に個人辞書が自動保存さ -れます。デフォルトは 50 です。また、この値を @code{nil} にすると、個人辞 -書の自動保存機能が無効になります。 +この変数が @code{non-nil} であれば、単語を登録するたび(削除するたび)に個人 +辞書を保存します。 +@end defopt -ここで、個人辞書の更新回数は確定回数と一致します。また、同じ候補について -確定した場合でもそれぞれ 1 回と数えられます -@footnote{これは、個人辞書の最小ポイントに、常に最後に変換を行ったエン -トリを移動させるために、エントリ数、候補数が全く増えていなくとも、確定に -より個人辞書が更新されているからです。}。 -@end defvr +@defopt skk-share-private-jisyo -@defvr {ユーザ変数} skk-save-jisyo-instantly -この変数が @code{non-nil} であれば、単語を登録するたび(削除するたび)に -個人辞書を保存します。 -@end defvr - -@defvr {ユーザ変数} skk-share-private-jisyo -@code{Non-nil} であれば、複数の SKK による個人辞書の共有を考慮して辞書を -更新する。 SKK 起動後にこの変数を変更した場合は @kbd{M-x skk-restart} で -反映させること。 -@end defvr +@code{Non-nil} であれば、複数の SKK による個人辞書の共有を考慮して辞書を更新 +する。 SKK 起動後にこの変数を変更した場合は @code{M-x skk-restart} で反映さ +せること。 +@end defopt @node 変換及び個人辞書に関する統計 @subsection 変換及び個人辞書に関する統計 DDSKK は、かな漢字変換及び個人辞書に関する統計を取っており、Emacs の終了 -時にファイル @file{~/.skk-record} に保存します。保存する内容は、以下の形 -式です。 +時にファイル @code{~/.skk-record} に保存します。保存する内容は、以下の形式です。 -@cartouche +@example Sun Jul 28 09:38:59 1996 登録: 4 確定: 285 確定率: 98% 語数: 3042 -@end cartouche +@end example -上記の「語数:」の数は個人辞書 @file{skk-jisyo} に登録されている候補数です -が、ここでは 1 行を 1 語として数えています。そのため、1 つの見出し語に対 -して複数の候補を持っている場合は、2 つ目以降の候補を無視しています。 +上記の「語数:」の数は個人辞書 @code{skk-jisyo} に登録されている候補数ですが、 +ここでは1行を1語として数えています。そのため、ひとつの見出し語に対して +複数の候補を持っている場合は、2つ目以降の候補を無視しています。 -@defvr {ユーザ変数} skk-record-file +@defvar skk-record-file 統計情報を保存するファイル名を指定します。 -(@w{@pxref{設定ファイル}}) - -@end defvr -@defvr {ユーザ変数} skk-keep-record +@ref{設定ファイル}. +@end defvar -この変数の値を @code{nil} に設定すると、本節で説明した統計機能を無効に -します。数値を設定すると、@code{skk-record-file} を指定数値の行数よ -り大きくしません。 +@defvar skk-keep-record -@end defvr +この変数の値を @code{nil} に設定すると、本節で説明した統計機能を無効にします。 +数値を設定すると、 @code{skk-record-file} を指定数値の行数より大きくしません。 +@end defvar -@defvr {ユーザ変数} skk-count-private-jisyo-candidates-exactly +@defvar skk-count-private-jisyo-candidates-exactly この変数の値を @code{non-nil} に設定すると、「語数」の数え方を変更します。 -具体的には、 1 行を 1 語として数えるのではなく、正確に語数を数えます。 -なお、その分時間がかかります。また、この場合でも @samp{[} と @samp{]} -に囲まれた送り仮名毎のブロック形式内は数えません。 - -@end defvr - -@cindex Menu Bars -@cindex メニューバー -@findex skk-count-jisyo-candidates -@kindex M-x skk-count-jisyo-candidates +具体的には、1行を1語として数えるのではなく、正確に語数を数えます。 +なお、その分時間がかかります。また、この場合でも @code{[} と @code{]} に囲まれた +送り仮名毎のブロック形式内は数えません。 +@end defvar -@noindent -@kbd{M-x skk-count-jisyo-candidates} +@table @asis +@kindex M-x skk-count-jisyo-candidates +@cindex skk-count-jisyo-candidates +@item @kbd{M-x skk-count-jisyo-candidates} @tie{}@tie{}@tie{}@tie{}(@code{skk-count-jisyo-candidates}) +@end table このコマンドを使うと、辞書の候補数を数えることができます。 @example -@group -@kbd{M-x skk-count-jisyo-candidates} +M-x skk-count-jisyo-candidates + + --------------- MiniBuffer -------------- + Jisyo file: (default: /your/home/.skk-jisyo) ~/* + --------------- MiniBuffer -------------- + +. s k k - j i s y o RET + + -------------- Echo Area -------------- + Counting jisyo candidates... 100% done + -------------- Echo Area -------------- ---------------- MiniBuffer -------------- -Jisyo file: (default: /your/home/.skk-jisyo) ~/@point{} ---------------- MiniBuffer -------------- -@end group - -@group -@kbd{. s k k - j i s y o @key{RET}} - --------------- Echo Area -------------- -Counting jisyo candidates@dots{} 100% done --------------- Echo Area -------------- -@end group - -@group ------- Echo Area ------ -3530 candidates ------- Echo Area ------ -@end group + ------ Echo Area ------ + 3530 candidates + ------ Echo Area ------ @end example -ただし、@samp{[} と @samp{]} に囲まれた送り仮名毎のブロック形式内は数えませ -ん。 +ただし、 @code{[} と @code{]} に囲まれた送り仮名毎のブロック形式内は数えません。 + +また、メニューバーが使用できる環境では、メニューバーを使ってこのコマン +ドを呼び出すことができます。 -また、メニューバーが使用できる環境では、メニューバーを使ってこのコマンド -を呼び出すことができます。@w{@xref{Menu Bars, ,メニューバー, emacs, GNU Emacs Manual}.} +@ref{Menu Bars,Menu Bars in GNU Emacs Manual,,emacs,}. @node 辞書バッファ @subsection 辞書バッファ -@cindex @file{dabbrev.el} -@cindex @samp{ *SKK-JISYO.L*} + +@cindex dabbrev.el +@cindex *SKK-JISYO.L* @findex fundamental-mode @vindex major-mode @vindex mode-name @vindex skk-large-jisyo @cindex 辞書バッファの名付け規則 -辞書検索プログラムを実行すると、必要ならば辞書が Emacs のバッファに読み -込まれます。このバッファを@b{辞書バッファ}と呼びます。 - -辞書バッファの名前は、 - -「空白+@samp{*}+辞書ファイル名(ディレクトリ抜き)+@samp{*}」 - -@noindent -という規則に基づいて付けられます。例えば、変数 @code{skk-large-jisyo} の -値が - -@file{/usr/local/share/skk/SKK-JISYO.L} +辞書検索プログラムを実行すると、必要ならば辞書が Emacs のバッファに読み込 +まれます。このバッファを @strong{辞書バッファ} と呼びます。辞書バッファの命名規 +則は、 -@noindent -であるとき、これに対する辞書バッファ名は、 - -@samp{ *SKK-JISYO.L*} +@example +空白 + * + 辞書ファイル名(ディレクトリ抜き) + * +@end example @noindent -となります。 +です。例えば、変数 @code{skk-large-jisyo} の値が @code{/usr/local/share/skk/SKK-JISYO.L} で +あるとき、これに対する辞書バッファ名は "@code{_*SKK-JISYO.L*}" (アンダーバーは SPACE の +意)となります。 -このバッファのメジャーモードは @code{fundamental-mode} です。しかし、諸 -般の事情により、変数 @code{major-mode} の値をシンボル @code{skk-jisyo-mode} と、 -変数 @code{mode-name} の値を文字列 @samp{SKK dic} としています -@footnote{これは、Emacs の @file{dabbrev.el} の機能との調和を考えての措 -置です。 -Dabbrev においては、現在のバッファと同じモードの他のバッファを検索して -abbreviation の展開を行うように設定することができるのですが、仮に辞書 -バッファにおける変数 @code{major-mode} の値が @code{fundamental-mode} のま -まだとすると、 Dabbrev が辞書バッファを検索してしまう可能性があります。 -この措置によって、そのような事態を回避しています。}。 +このバッファのメジャーモードは @code{fundamental-mode} です。しかし、諸般の事 +情により、変数 @code{major-mode} の値をシンボル @code{skk-jisyo-mode} と、 +変数 @code{mode-name} の値を文字列 @code{SKK dic} としています @footnote{これは、Emacs の @code{dabbrev.el} の機能との調和を考えての +措置です。Dabbrev においては、現在のバッファと同じモードの他のバッファを +検索して abbreviation の展開を行うように設定することができるのですが、仮 +に辞書バッファにおける変数 @code{major-mode} の値が @code{fundamental-mode} のまま +だとすると、 Dabbrev が辞書バッファを検索してしまう可能性があります。この +措置によって、そのような事態を回避しています。} 。 @node 辞書バッファの文字コードの設定 @subsection 辞書バッファの文字コードの設定 + @vindex skk-coding-system-alist @findex skk-find-coding-system @findex describe-coding-system @findex list-coding-systems @findex coding-system-p @findex find-coding-system - -@defvr {ユーザ変数} skk-jisyo-code +@defvar skk-jisyo-code この変数は、辞書ファイルの文字コードを決定し、以下のような値を取ります。 -@itemize @bullet +@itemize +@item +@code{nil} (標準設定)この場合、シンボル @code{euc-jis-2004} が使われます @footnote{関数 @code{skk-find-coding-system} を参照のこと。} 。 -@item @code{nil} -@item Emacs の coding system (コード系) -@footnote{coding system は GNU Emacs の場合 @code{euc-jp}, @code{shift_jis}, -@code{junet} などのシンボルで表され、@kbd{M-x describe-coding-system} や -@kbd{M-x list-coding-systems} で調べることができます。 -XEmacs の場合、シンボルは coding system そのものでは -なく coding system object を指示するためのシンボルとして扱われます。 -具体的には GNU Emacs では @code{(coding-system-p 'euc-jp)} が @code{t} を -返すのに対し、 XEmacs では @code{nil} を返しますが、代わりにシンボルが示 -す coding system object を返す @code{find-coding-system} 関数が存在します。} +@item +Emacs の coding system (コード系) @footnote{coding system は GNU Emacs の場合 @code{euc-jp}, @code{shift_jis}, @code{junet} な +どのシンボルで表され、 @code{M-x describe-coding-system} や @code{M-x list-coding-systems} で +調べることができます。XEmacs の場合、シンボルは coding system そのもので +はなく coding system object を指示するためのシンボルとして扱われます。 +具体的には GNU Emacs では @code{(coding-system-p 'euc-jp)} が @code{t} を返すのに対 +し、 XEmacs では @code{nil} を返しますが、代わりにシンボルが示す coding system object を +返す関数 @code{find-coding-system} が存在します。} -@item @samp{euc}, @samp{ujis}, @samp{sjis}, @samp{jis} の文字列。@code{skk-coding-system-alist} に従って、順に @code{euc-jisx0213}, @code{euc-jisx0213}, @code{shift_jisx0213}, @code{iso-2022-jp-3-strict} の各シンボルへ変換されます。 +@item +@code{euc}, @code{ujis}, @code{sjis}, @code{jis} の文字列。 @code{skk-coding-system-alist} に +従って、順に @code{euc-jisx0213}, @code{euc-jisx0213}, @code{shift_jisx0213}, @code{iso-2022-jp-3-strict} の +各シンボルへ変換されます。 @end itemize +@end defvar -デフォルトは @code{nil} です。この場合、シンボル @code{euc-jis-2004} が使われます -@footnote{関数 @code{skk-find-coding-system} を参照のこと。} -。 +@node 辞書バッファの buffer-file-name +@subsection 辞書バッファの buffer-file-name -@end defvr - -@node 辞書バッファのbuffer-file-name -@subsection 辞書バッファのbuffer-file-name @vindex buffer-file-name @findex save-some-buffers +@kindex M-x compile +Emacs には @code{save-some-buffers} という関数があります。この関数は、ファイル +に関連付けられている各バッファについて、変更があればファイルに保存します +が、実際に保存するかどうかをユーザに質問します。 + +Emacs のコマンドには @code{M-x compile} のように @code{save-some-buffers} を呼び出 +すものがあります。もし、個人辞書の辞書バッファがファイル名と関連付けられ +ていたとしたら、こうしたコマンドを実行するたびに個人辞書を保存するかどう +か質問されるので、面倒です。 -Emacs には @code{save-some-buffers} という関数があります。この関数は、ファ -イルに関連付けられている各バッファについて、変更があればファイルに保存し -ますが、実際に保存するかどうかをユーザに質問します。 - -Emacs のコマンドには @kbd{M-x compile} のように、 -@code{save-some-buffers} を呼び出すものがあります。もし、個人辞書の辞書 -バッファがファイル名と関連付けられていたとしたら、こうしたコマンドを -実行するたびに個人辞書を保存するかどうか質問されるので、面倒です。 - -DDSKK では、このような事態を避けるため、辞書バッファにおける変数 -@code{buffer-file-name} の値を @code{nil} に設定しています。 +DDSKK では、このような事態を避けるため、辞書バッファにおける変数 @code{buffer-file-name} の +値を @code{nil} に設定しています。 -@node 注釈 (アノテーション) -@section 注釈 (アノテーション) +@node 注釈(アノテーション) +@section 注釈(アノテーション) -かな漢字変換の際に、候補に注釈 (アノテーション) が登録されていれば、それ +かな漢字変換の際に、候補に注釈(アノテーション)が登録されていれば、それ を表示することができます。 + @menu -* アノテーションの基礎:: 予備知識 -* アノテーションの使用:: +* アノテーションの基礎:: +* アノテーションの使用:: * アノテーションの登録:: * アノテーションとして EPWING 辞書を表示する:: -* Apple OS X 「辞書」サービスからアノテーションを取得する:: +* Apple macOS 「辞書」サービスからアノテーションを取得する:: * Wikipedia/Wiktionary からアノテーションを取得する:: * 外部コマンドからアノテーションを取得する:: * 各種アノテーション機能を SKK の枠をこえて活用する:: @@ -8026,227 +7781,221 @@ この節では、辞書の中でのアノテーションの取り扱いを説明します。 -アノテーションは、ユーザが登録したものと、共有辞書に元々登録されている -もの、それ以外の情報源から取得されるものの 3 つに大別されます。 +アノテーションは、ユーザが登録したものと、共有辞書に元々登録されているも +の、それ以外の情報源から取得されるものの3つに大別されます。 -ユーザが付けたアノテーションを「ユーザアノテーション」 -と呼びます。ユーザアノテーションは、次の形式で個人辞書に登録されます。 +ユーザが付けたアノテーションを「ユーザアノテーション」と呼びます。ユーザ +アノテーションは、次の形式で個人辞書に登録されます。 @example -「きかん /期間/機関;*機関投資家/基幹;*基幹業務/」 +きかん /期間/機関;*機関投資家/基幹;*基幹業務/ @end example -上記のとおり、@code{;} の直後に @code{*} が自動的に振られる -@footnote{@code{*} の文字は変換時には表示されません}ことによってユーザが -独自に登録したアノテーションであることが分かります。 +上記のとおり、 @code{;} の直後に @code{*} が自動的に振られる @footnote{@code{*} の文字は変換時には表示されません。} ことによって +ユーザが独自に登録したアノテーションであることが分かります。 -一方、共有辞書に元々登録されているアノテーションを「システムアノテー -ション」と呼び、これは @code{;} の直後に @code{*} の文字を伴いません。 -システムアノテーションは、次の形式で辞書に登録されています。 +一方、共有辞書に元々登録されているアノテーションを「システムアノテーショ +ン」と呼び、これは @code{;} の直後に @code{*} の文字を伴いません。システムアノテー +ションは、次の形式で辞書に登録されています。 @example -「いぜん /以前;previous/依然;still/」 +いぜん /以前;previous/依然;still/ @end example -システムアノテーションは、L 辞書等に採用されています。 +システムアノテーションは L 辞書等に採用されています。 上記のいずれでもなく、外部の辞典その他の情報源から得られるものを「外部ア ノテーション」といいます。外部アノテーションは Emacs Lisp パッケージであ -る lookup.el、 Apple OS X 付属の辞書、Wiktionary/Wikipedia などから取得可能 -です。 +る lookup.el、 Apple macOS 付属の辞書、Wiktionary/Wikipedia などから取得可 +能です。 @node アノテーションの使用 @subsection アノテーションの使用 -@defvr {ユーザ変数} skk-show-annotation - -この変数の値を @code{non-nil} に設定するとアノテーションを表示します -@footnote{Viper 対策はまだ行われていません。@file{~/.viper} に次のように -書いて下さい。 - -@lisp -(viper-harness-minor-mode "skk-annotation") -@end lisp -}。 +@defvar skk-show-annotation -@table @code +この変数の値を @code{non-nil} に設定するとアノテーションを表示します @footnote{Viper 対策はまだ行われていません。 @code{~/.viper} に次のように書い +て下さい。 @code{(viper-harness-minor-mode "skk-annotation")}} 。 -@item (setq skk-show-annotation t) +@itemize +@item +@code{(setq skk-show-annotation t)} アノテーションを常に表示します。 -@item (setq skk-show-annotation '(not list)) - *候補*バッファ@footnote{@code{skk-show-candidates-always-pop-to-buffer}}では、アノテーションを表示しません。 +@item +@code{(setq skk-show-annotatio@code{n '}(not list))} -@item (setq skk-show-annotation '(not minibuf)) +候補バッファ @footnote{@code{skk-show-candidates-always-pop-to-buffer}} ではアノテーションを表示しません。 -ミニバッファにおけるかな漢字変換(単語登録時)では、アノテーションを表示しません。 -@item (setq skk-show-annotation '(not list minibuf)) +@item +@code{(setq skk-show-annotatio@code{n '}(not minibuf))} - *候補*バッファ及びミニバッファでは、アノテーションを表示しません。 +ミニバッファにおけるかな漢字変換(単語登録時)では、アノテーションを +表示しません。 -@item (setq skk-show-annotation nil) -いかなる場合もアノテーションを表示しません。 +@item +@code{(setq skk-show-annotatio@code{n '}(not list minibuf))} -@end table +*候補バッファ及びミニバッファでは、アノテーションを表示しません。 -@end defvr -@defvr {ユーザ変数} skk-annotation-delay +@item +@code{(setq skk-show-annotation nil)} -アノテーションを表示するまでの遅延を秒で指定する。デフォルトは 1.0 秒。 +いかなる場合もアノテーションを表示しません。 +@end itemize +@end defvar -@end defvr +@defvar skk-annotation-delay -@kindex C-w -@defvr {ユーザ変数} skk-annotation-copy-key +アノテーションを表示するまでの遅延を秒で指定する。標準設定は 1.0 秒。 +@end defvar -@kbd{C-w} をタイプすると、現在表示されているアノテーションを kill ring に -保存します。保存した内容を Emacs 以外のアプリケーションで利用したい場合は -変数 @code{interprogram-cut-function} を設定してください。 +@cindex kill ring +@vindex interprogram-cut-function +@table @asis +@kindex C-w +@cindex skk-annotation-copy-key +@item @kbd{C-w} @tie{}@tie{}@tie{}@tie{}(@code{skk-annotation-copy-key}) -@end defvr +@code{C-w} をタイプすると、現在表示されているアノテーションを kill ring に保 +存します @footnote{kill ring については info を参照。 -@defvr {ユーザ変数} skk-annotation-show-as-message +@ref{Kill Ring,The Kill Ring in GNU Emacs Manual,,emacs,}. -@code{Non-nil} (デフォルト) であれば、アノテーションをエコーエリアに表示します。 +保存した内容を Emacs 以外のアプリケーションで利用したい場合は変数 @code{interprogram-cut-function} を +設定してください。} 。 -@code{nil} であれば、other-window を一時的に開いてアノテーションを表示します。 -other-window は、その候補を確定するか、その候補の選択を止める (次の -候補の表示又は quit) と自動的に閉じます。 +@end table -この変数の値にかかわらず、変数@code{skk-show-tooltip} が @code{non-nil} の -場合はアノテーションをツールティップで表示します。 +@defvar skk-annotation-show-as-message -@end defvr +@code{Non-nil} (標準設定)であれば、アノテーションをエコーエリアに表示し +ます。 @code{nil} であれば、other-window を一時的に開いてアノテーションを表 +示します。 @code{other-window} は、その候補を確定するか、その候補の選択を止 +める(次の候補の表示又は quit)と自動的に閉じます。 + +この変数の値にかかわらず、変数 @code{skk-show-tooltip} が @code{non-nil} の場合は +アノテーションをツールティップで表示します。 +@end defvar +@table @asis @kindex ^ -@defvr {ユーザ変数} skk-annotation-toggle-display-char +@cindex skk-annotation-toggle-display-char +@item @kbd{^} @tie{}@tie{}@tie{}@tie{}(@code{skk-annotation-toggle-display-char}) -「*候補*バッファ」で変換候補を一覧表示しているときにアノテーションの -表示/非表示を動的に切り替えるキーを設定します。 -デフォルトは @kbd{^} です。 +候補バッファで変換候補を一覧表示しているときにアノテーションの表示/非 +表示を動的に切り替えるキーを設定します。標準設定は @code{^} です。 @example -@group ------ Buffer: *候補* ----- -A:射 -S:亥;[十二支](12)いのしし -D:夷;夷狄 -F:姨;おば -J:洟;はな -K:痍;満身創痍 -L:維;維持 ------ Buffer: *候補* ----- -@end group - -@kbd{^} - -@group ------ Buffer: *候補* ----- -A:射 -S:亥; -D:夷; -F:姨; -J:洟; -K:痍; -L:維; ------ Buffer: *候補* ----- -@end group + ----- Buffer: *候補* ----- + A:射 + S:亥;[十二支](12)いのしし + D:夷;夷狄 + F:姨;おば + J:洟;はな + K:痍;満身創痍 + L:維;維持 + ----- Buffer: *候補* ----- + +^ + + ----- Buffer: *候補* ----- + A:射 + S:亥; + D:夷; + F:姨; + J:洟; + K:痍; + L:維; + ----- Buffer: *候補* ----- @end example -@end defvr +@end table -@defvr {ユーザ変数} skk-annotation-function +@defvar skk-annotation-function -ユーザアノテーションとシステムアノテーションを区別することで、ユーザアノ -テーションだけを表示したり、あるいはその逆を行うことが可能です。 +ユーザアノテーションとシステムアノテーションを区別することで、ユーザア +ノテーションだけを表示したり、あるいはその逆を行うことが可能です。 -変数 @code{skk-annotation-function} に「表示したいアノテーション -を @code{non-nil} と判定する関数」を定義します。 -アノテーション文字列を引数にして変数 @code{skk-annotation-function} が -指し示す関数が @code{funcall} されて、戻り値が @code{non-nil} である場合に -限ってアノテーションが表示されます。 +変数 @code{skk-annotation-function} に「表示したいアノテーションを @code{non-nil} と +判定する関数」を定義します。アノテーション文字列を引数にして変数 @code{skk-annotation-function} が +指し示す関数が @code{funcall} されて、戻り値が @code{non-nil} である場合に限って +アノテーションが表示されます。 @lisp -@group (setq skk-annotation-function (lambda (annotation) (eq (aref annotation 0) ?*))) -@end group @end lisp -@noindent -上記の例では、アノテーションの先頭が @code{*} で始まる「ユーザアノテー -ション」の場合に @code{t} を返すλ式を @code{skk-annotation-function} に -定義しました。これによってユーザアノテーションだけが表示されます。 - -@end defvr +上記の例では、アノテーションの先頭が @code{*} で始まる「ユーザアノテーション」 +の場合に @code{t} を返すλ式を @code{skk-annotation-function} に定義しました。こ +れによってユーザアノテーションだけが表示されます。 +@end defvar @node アノテーションの登録 @subsection アノテーションの登録 -@findex skk-annotation-add -@findex skk-annotation-kill -@findex skk-annotation-remove -@kindex M-x skk-annotation-add -@kindex M-x skk-annotation-kill -@kindex M-x skk-annotation-remove - -@defun {コマンド} skk-annotation-add &optional NO-PREVIOUS-ANNOTATION - -アノテーションを登録/修正するには、アノテーションを付けたい単語を確定し -た直後に同じバッファで @kbd{M-x skk-annotation-add} と実行します。 - -アノテーションを編集するバッファ(*SKK annotation*)が開いてカレントバッファ -になりますので、アノテーションとして表示する文章を編集してください。 -編集が終わったら @kbd{C-c C-c} とタイプします。 - -その単語に既にアノテーションが付いている場合は、あらかじめ当該アノテーショ -ンを挿入して *SKK annotation* を開きます。 -@end defun +@table @asis +@kindex M-x skk-annotation-add +@cindex skk-annotation-add +@item @kbd{M-x skk-annotation-add} @tie{}@tie{}@tie{}@tie{}(@code{skk-annotation-add}) -@defun {コマンド} skk-annotation-kill +アノテーションを登録/修正するには、アノテーションを付けたい単語を確定 +した直後に同じバッファで @code{M-x skk-annotation-add} と実行します。アノテー +ションを編集するバッファ @code{*SKK annotation*} が開いてカレントバッファに +なりますので、アノテーションとして表示する文章を編集してください。編集 +が終わったら @code{C-c C-c} とタイプします。 -上記 @kbd{M-x skk-annotation-add} を実行したもののアノテーションを付けず -に *SKK annotation* を閉じたいときは、@kbd{C-c C-k} とタイプするか -@kbd{M-x skk-annotation-kill} を実行してください。 +その単語に既にアノテーションが付いている場合は、あらかじめ当該アノテー +ションを挿入して @code{*SKK annotation*} バッファを開きます。 -@end defun +@kindex M-x skk-annotation-kill +@cindex skk-annotation-kill +@item @kbd{M-x skk-annotation-kill} @tie{}@tie{}@tie{}@tie{}(@code{skk-annotation-kill}) -@defun {コマンド} skk-annotation-remove +上記 @code{M-x skk-annotation-add} を実行したもののアノテーションを付けず +に @code{*SKK annotation*} バッファを閉じたいときは @code{C-c C-k} とタイプする +か @code{M-x skk-annotation-kill} を実行してください。 -最後に確定した候補からアノテーションを取り去りたいとき -は @kbd{M-x skk-annotation-remove} と実行します。 +@kindex M-x skk-annotation-remove +@cindex skk-annotation-remove +@item @kbd{M-x skk-annotation-remove} @tie{}@tie{}@tie{}@tie{}(@code{skk-annotation-remove}) -@end defun +特定の語からアノテーションを取り去りたいときは、まず、かな漢字変換で当該 +語を確定し、続けて @code{M-x skk-annotation-remove} と実行します。 +@end table @node アノテーションとして EPWING 辞書を表示する @subsection アノテーションとして EPWING 辞書を表示する -@file{skk-lookup.el} に含まれる関数 @code{skk-lookup-get-content} を活用 -することにより、EPWING 辞書から得た内容をアノテーション表示することが可能 -です。 - -辞書検索ツールの Lookup (@url{http://openlab.jp/edict/lookup/}) が正常に -インストールされていることが前提です。Lookup を新規にインストールした場 -合は、SKK をインストールし直す必要があります。 +@code{skk-lookup.el} に含まれる関数 @code{skk-lookup-get-content} を活用することに +より、EPWING 辞書から得た内容をアノテーション表示することが可能です。辞書 +検索ツールの Lookup @footnote{@uref{http://openlab.jp/edict/lookup/}} が正常にインストールされていることが前提 +です。Lookup を新規にインストールした場合は、SKK をインストールし直す必要 +があります。 EPWING 辞書の内容をアノテーション表示するには、2つの方法があります。 -@enumerate -@item -@code{skk-treat-candidate-appearance-function} を設定する方法 -候補の表示を装飾する関数を指定する変数 -@code{skk-treat-candidate-appearance-function} を設定する場合は、 -@file{etc/dot.skk} に示されている設定例を以下のように変更してください。 +@menu +* skk-treat-candidate-appearance-function を設定する方法:: +* skk-annotation-lookup-lookup を設定する方法:: +@end menu + +@node skk-treat-candidate-appearance-function を設定する方法 +@subsubsection skk-treat-candidate-appearance-function を設定する方法 + +候補の表示を装飾する関数を指定する変数 @code{skk-treat-candidate-appearance-function} を +設定する場合は、 @code{etc/dot.skk} に示されている設定例を以下のように変更して +ください。 @lisp -@group + (require 'skk-lookup) (setq skk-treat-candidate-appearance-function #'(lambda (candidate listing-p) @@ -8256,223 +8005,209 @@ + (note (skk-lookup-get-content cand listing-p)) (sep (if note ;セパレータ : -@end group @end lisp @defun skk-lookup-get-content 単語 listing-p -単語の意味を EPWING 辞書から取得します。オプション引数 listing-p が -@code{non-nil} なら候補一覧用に一行の短い文字列を返しますが、@code{nil} な +@strong{単語} の意味を EPWING 辞書から取得します。オプション引数 @code{listing-p} が +@code{non-nil} ならば候補一覧用に一行の短い文字列を返しますが、 @code{nil} な らば全体を返します。 - @end defun -@defvr {ユーザ変数} skk-lookup-get-content-nth-dic - -関数 @code{skk-lookup-get-content} が「どの EPWING 辞書から単語の意味を -取得するのか」を、ゼロを起点とした数値で指定します。 +@defvar skk-lookup-get-content-nth-dic -docstring に例示した S 式を評価してみてください。 +関数 @code{skk-lookup-get-content} が「どの EPWING 辞書から単語の意味を取得 +するのか」を、ゼロを起点とした数値で指定します。docstring に例示した S 式 +を評価してみてください。 +@end defvar -@end defvr - -@noindent -@kbd{M-x skk-lookup-get-content-setup-dic} +@table @asis @kindex M-x skk-lookup-get-content-setup-dic +@cindex skk-lookup-get-content-setup-dic +@item @kbd{M-x skk-lookup-get-content-setup-dic} @tie{}@tie{}@tie{}@tie{}(@code{skk-lookup-get-content-setup-dic}) +DDSKK の起動後に変数 @code{skk-lookup-get-content-nth-dic} の数値を変更した +場合は、このコマンドを必ず実行してください。 +@end table -@b{DDSKK の起動後に変数 @code{skk-lookup-get-content-nth-dic} の数値を変 -更した場合は、このコマンドを必ず実行してください。} - -@item -@code{skk-annotation-lookup-lookup} を設定する方法 +@node skk-annotation-lookup-lookup を設定する方法 +@subsubsection skk-annotation-lookup-lookup を設定する方法 -次に変数 @code{skk-annotation-lookup-lookup} について説明します。この変 -数は EPWING 経由アノテーションの設定を簡単にします。 +次に変数 @code{skk-annotation-lookup-lookup} について説明します。この変数は EPWING 経 +由アノテーションの設定を簡単にします。 -@defvr {ユーザ変数} skk-annotation-lookup-lookup +@defvar skk-annotation-lookup-lookup -@code{Non-nil} ならば @file{lookup.el} を利用してアノテーションを取得する。 +@code{Non-nil} ならば @code{lookup.el} を利用してアノテーションを取得する。 @lisp (setq skk-annotation-lookup-lookup t) @end lisp -この値を @code{always} に設定すると、候補一覧でも辞書サービスを引く。 -@footnote{この設定は変数 @code{skk-treat-candidate-appearance-function} -の値を上書きします。@code{skk-treat-candidate-appearance-function} を -自分で設定する場合は @code{skk-annotation-lookup-lookup} には @code{t} -または @code{nil} を必要に応じて設定します。} +この値をシンボル @code{always} に設定 @footnote{この設定は変数 @code{skk-treat-candidate-appearance-function} の値を +上書きします。 @code{skk-treat-candidate-appearance-function} を自分で設定する +場合は @code{skk-annotation-lookup-lookup} には @code{t} または @code{nil} を必要に応じ +て設定します。} すると、候補一覧でも辞書サー +ビスを引く。 @lisp (setq skk-annotation-lookup-lookup 'always) @end lisp +@end defvar -@end defvr +@node Apple macOS 「辞書」サービスからアノテーションを取得する +@subsection Apple macOS 「辞書」サービスからアノテーションを取得する -@end enumerate +Apple Mac OS X 10.5 (Leopard) 以降に標準で入っている国語辞典などからアノ +テーションが取得できます。 -@node Apple OS X 「辞書」サービスからアノテーションを取得する -@subsection Apple OS X 「辞書」サービスからアノテーションを取得する - -Mac OS X 10.5 以降に標準で入っている国語辞典などからアノテーションが取得 -できます。@footnote{この機能を利用するには、python の拡張機能として -readline と pyobject-framework-DictionaryServices が必要です。後者につい -ては OS X 10.5 (Leopard) 以降の OS 標準の python に初めからインストール -されています。readline については OS X 10.7 (Lion) 標準の python ではイ -ンストールする必要がありません。OS X 10.6 以前の場合は +この機能を利用するには、python の拡張機能として @code{readline} と @code{pyobject-framework-DictionaryServices} が必要です。 +後者については Apple Mac OS X 10.5 (Leopard) 以降の OS 標準の python に初 +めからインストールされています。 @code{readline} については Apple Mac OS X 10.7 (Lion) 標 +準の python ではインストールする必要がありません。Apple Mac OS X 10.6 (Snow Leopard) 以 +前の場合は @example -% easy_install readline +% easy_install readline @end example @noindent -などの方法でインストールします。} +などの方法でインストールします。 + +今のところ、アノテーションを取得する辞典を選択することはできません。 +Apple macOS (OS X) の「辞書」アプリ (@code{Dictionary.app}) を起動し、環境設定 +から辞書の検索順を指定してください。国語辞典を上位に指定すれば使いやすく +なります。 -@defvr {ユーザ変数} skk-annotation-lookup-DictionaryServices +@defopt skk-annotation-lookup-DictionaryServices -@code{Non-nil} ならば OS X の辞書サービスを利用してアノテーションを取得 -する。 +@code{Non-nil} ならば Apple macOS (OS X) の辞書サービスを利用してアノテーシ +ョンを取得する。 @lisp (setq skk-annotation-lookup-DictionaryServices t) @end lisp -この値を @code{always} に設定すると候補一覧でも辞書サービスを引く。 -@footnote{この設定は変数 @code{skk-treat-candidate-appearance-function} -の値を上書きします。@code{skk-treat-candidate-appearance-function} を -自分で設定したい場合は @code{skk-annotation-lookup-DictionaryServices} -には @code{t} または @code{nil} を必要に応じて設定します。} +この値をシンボル @code{always} に設定すると、候補一覧でも辞書サービスを引く @footnote{この設定は変数 @code{skk-treat-candidate-appearance-function} の値を +上書きします。 @code{skk-treat-candidate-appearance-function} を自分で設定した +い場合は @code{skk-annotation-lookup-DictionaryServices} には @code{t} または @code{nil} を +必要に応じて設定します。} 。 @lisp (setq skk-annotation-lookup-DictionaryServices 'always) @end lisp +@end defopt -@end defvr - -@defvr {ユーザ変数} skk-annotation-python-program +@defvar skk-annotation-python-program アノテーション取得のために呼びだす python のプログラム名。 @lisp (setq skk-annotation-python-program "/usr/bin/python") @end lisp - -@end defvr - -今のところ、アノテーションを取得する辞典を選択することはできません。 -OS X の「辞書」アプリ (Dictionary.app) を起動し、環境設定から辞書の検索 -順を指定してください。国語辞典を上位に指定すれば使いやすくなります。 +@end defvar @node Wikipedia/Wiktionary からアノテーションを取得する @subsection Wikipedia/Wiktionary からアノテーションを取得する 候補にアノテーションの登録がない場合、アノテーションに代えて -@uref{http://ja.wiktionay.org/, Wiktionary}, -@uref{http://ja.wikipedia.org/, Wikipedia} + +@itemize +@item +@uref{http://ja.wiktionay.org/, Wiktionary} + + +@item +@uref{http://ja.wikipedia.org/, Wikipedia} +@end itemize + による解説を表示することができます。他のアノテーションが変換時に自動的に 表示されるのに対し、 Wikipedia/Wiktionary アノテーションは基本的にユーザ -の指示によって取得される点で異なります。 +の指示によって取得される点が異なります。 -▼モードで候補を表示しているときに @kbd{C-i} を押すと、 -@code{skk-annotation-other-sources} で指定された順で解説を取得して -エコーエリアに表示@footnote{変数@code{skk-show-tooltip} が @code{non-nil} の -場合、ツールティップで表示します。} します。 +▼モードで候補を表示しているときに @code{C-i} を押すと、 @code{skk-annotation-other-sources} で +指定された順で解説を取得してエコーエリアに表示 @footnote{変数 @code{skk-show-tooltip} が @code{non-nil} の場合、ツールティップ +で表示します。} します。 @example B o k u j o u -@group ------ Buffer: foo ----- -▽ぼくじょう@point{} ------ Buffer: foo ----- -@end group - -@key{SPC} - -@group ------ Buffer: foo ----- -▼牧場@point{} ------ Buffer: foo ----- -@end group - -@kbd{C-i} - -@group ------------------------------ Echo Area ------------------------------ -牧場(ぼくじょう)とは、ウシ、ウマなどの家畜を飼養する施設。訓読みされ -てまきばと呼ばれることもある。 ------------------------------ Echo Area ------------------------------ -@end group -@end example + ----- Buffer: foo ----- + ▽ぼくじょう* + ----- Buffer: foo ----- -エコーエリアに解説が表示されている最中に @kbd{C-o} を押すと、 -関数 @code{browse-url} を用いて、その解説の元となった URL をブラウズしま -す。 +SPC + + ----- Buffer: foo ----- + ▼牧場* + ----- Buffer: foo ----- -@kindex C-i -@defvr {ユーザ変数} skk-annotation-wikipedia-key +C-i -デフォルトは @kbd{C-i} です。 + ----------------------------- Echo Area ------------------------------ + 牧場(ぼくじょう)とは、ウシ、ウマなどの家畜を飼養する施設。訓読みされ + てまきばと呼ばれることもある。 + ----------------------------- Echo Area ------------------------------ +@end example -@end defvr +エコーエリアに解説が表示されている最中に @code{C-o} を押すと、関数 @code{browse-url} を +用いて、その解説の元となった URL をブラウズします。 -@kindex C-o -@defvr {ユーザ変数} skk-annotation-browse-key +@defvar skk-annotation-wikipedia-key -デフォルトは @kbd{C-o} です。eww で閲覧したい場合は、次のとおり設定して -ください。 +標準設定は @code{C-i} です。 +@end defvar + +@defvar skk-annotation-browse-key + +標準設定は @code{C-o} です。EWW (Emacs Web Wowser) で閲覧したい場合は、次 +のとおり設定してください。 @ref{Top,,,eww,}. @lisp -(setq browse-url-browser-function 'eww-browse-url) +(setq browse-url-browser-functio@code{n '}eww-browse-url) @end lisp +@end defvar -@end defvr - -@defvr {ユーザ変数} skk-annotation-other-sources +@defvar skk-annotation-other-sources アノテーションを取得する SKK 辞書以外のソースを指定します。 - -@end defvr +@end defvar @node 外部コマンドからアノテーションを取得する @subsection 外部コマンドからアノテーションを取得する 外部コマンドからアノテーションを取得できます。 -@defvr {ユーザ変数} skk-annotation-lookup-dict +@defvar skk-annotation-lookup-dict -@code{Non-nil} ならば、@code{skk-annotation-dict-program} に指定された外 -部コマンドからアノテーションを指定します。 +@code{Non-nil} ならば、 @code{skk-annotation-dict-program} に指定された外部コマン +ドからアノテーションを指定します。 +@end defvar -@end defvr - -@defvr {ユーザ変数} skk-annotation-dict-program +@defvar skk-annotation-dict-program アノテーションを取得するための外部コマンド名を指定します。 +@end defvar -@end defvr - -@defvr {ユーザ変数} skk-annotation-dict-program-arguments +@defvar skk-annotation-dict-program-arguments アノテーションを取得に使う外部コマンドに渡す引数を指定します。 - -@end defvr +@end defvar @node 各種アノテーション機能を SKK の枠をこえて活用する @subsection 各種アノテーション機能を SKK の枠をこえて活用する -前述した各種外部アノテーション (lookup.el + EPWING 辞書、 Apple OS X 辞書、 +前述した各種外部アノテーション (lookup.el + EPWING 辞書、 Apple macOS 辞書、 Wikipedia/Wiktionary) は、SKK の変換モードだけでなく Emacs のあらゆる状 況で辞書引き機能として使うことができます。そのためには、コマンド @code{skk-annotation-lookup-region-or-at-point} を任意にキー定義します。 -@defun {コマンド} skk-annotation-lookup-region-or-at-point &optional PREFIX-ARG START END +@defun skk-annotation-lookup-region-or-at-point &optional PREFIX-ARG START END -このコマンドは、領域が指定されていればその領域の文字列をキーワードとして -Lookup.el, OS X 辞書サービス、または Wikipedia/Wiktionary アノテーション -を探し、表示します。領域が指定されていなければ、可能な範囲でその位置にあ -る単語 (始点と終点) を推測します。 +このコマンドは、領域が指定されていればその領域の文字列をキーワードとし +て Lookup.el, Apple macOS 辞書サービス、または Wikipedia/Wiktionary ア +ノテーションを探し、表示します。領域が指定されていなければ、可能な範囲 +でその位置にある単語(始点と終点)を推測します。 @end defun 一例として、以下のキー割当を紹介します。 @@ -8481,37 +8216,29 @@ (global-set-key "\M-i" 'skk-annotation-lookup-region-or-at-point) @end lisp -@noindent -このようにしておくと、何かの意味が調べたくなったとき、領域選択して -@kbd{M-i} とタイプすればその場で辞書を引くことができます。 +このようにしておくと、何かの意味が調べたくなったとき、領域選択して @code{M-i} と +打鍵すればその場で辞書を引くことができます。 -@noindent -さらに、ユーザオプション @code{skk-annotation-other-sources} の 3 番 -目 (Apple OS X では 4 番目) は標準で @code{en.wiktionary} になっています。 -例えば、英文を読んでいて buffer という語の正確な意味を参照したくなったと -します。そのときは 単語 buffer にポイントを合わせ、@kbd{M-3 M-i} -(Max OS X では @kbd{M-4 M-i}) とプレフィックス付でコマンドを実行してみて -ください。@footnote{@code{skk-annotation-other-sources} の標準の値は環境 -によって異なります。@file{lookup.el} と @file{skk-lookup.el} の設定が有 -効になっている場合は @code{en.wiktionary} は 4 番目 (Apple OS X では5番 -目) になります。} +さらに、ユーザオプション @code{skk-annotation-other-sources} の3番目 (Apple macOS で +は4番目) は標準で @code{en.wiktionary} になっています。例えば、英文を読んでい +て buffer という語の正確な意味を参照したくなったとします。そのときは単語 buffer に +ポイントを合わせて @code{M-3 M-i} (Apple macOS では @code{M-4 M-i}) とプレフィック +ス付でコマンドを実行してみてください @footnote{@code{skk-annotation-other-sources} の標準の値は環境によって異なりま +す。 @code{lookup.el} と @code{skk-lookup.el} の設定が有効になっている場合は @code{en.wiktionary} は +4番目 (Apple macOS では5番目) になります。} 。 @example -@group ----- Buffer: *scratch* ----- -;; This buffer@point{} is for notes you don't want to save, and for @dots{} +;; This buffer* is for notes you don't want to save, and for ... ----- Buffer: *scratch* ----- -@end group -@kbd{M-3 M-i} (Max OS X では @kbd{M-4 M-i}) +M-3 M-i (Apple macOS では M-4 M-i) @end example @noindent -すると SKK モードでのアノテーションと同様、以下のような説明が表示されま -す。 +すると SKK モードでのアノテーションと同様、以下のような説明が表示されます。 @example -@group -------------------- Echo Area -------------------- English, Noun buffer (plural buffers) @@ -8521,14 +8248,13 @@ 3: (computing) A portion of memory set aside to store data, often before it is sent to an external device or as it is received from an external device. -[@dots{}] -------------------- Echo Area -------------------- -@end group @end example @node 文字コード関連 @section 文字コード関連 + @menu * 文字コードまたはメニューによる文字入力:: * メニューによる文字入力:: @@ -8536,8 +8262,6 @@ * 文字コードを知る方法:: @end menu -関連項目 @w{@xref{辞書バッファの文字コードの設定}.} - @node 文字コードまたはメニューによる文字入力 @subsection 文字コードまたはメニューによる文字入力 @@ -8545,153 +8269,140 @@ @cindex EUCコード @kindex \ @kindex C-u \ -@vindex skk-kcode-charset +@kindex skk-kcode-charset +かなモードで @code{\} キーを打鍵すると、ミニバッファに -かなモードで @kbd{\} キーを入力すると、ミニバッファに @example -@group ---------------------------- Minibuffer ----------------------------- ○○の文字を指定します。7/8 ビット JIS コード (00nn), 区点コード (00-00), -UNICODE (U+00nn), または [RET] (文字一覧): @point{} +UNICODE (U+00nn), または [RET] (文字一覧): * ---------------------------- Minibuffer ----------------------------- -@end group @end example @noindent -というプロンプトが表示され、文字コード(JIS コード、EUC コードまたは区点番号) -またはメニューによる文字入力が促されます。 +というプロンプトが表示され、文字コード(JIS コード、EUC コードまたは区点 +番号)またはメニューによる文字入力が促されます。 -上記例示の○○部分は 変数 @code{skk-kcode-charset} の値であり、 -その初期値は @code{japanese-jisx0208} 又は @code{japanese-jisx0213-1} です。 -初期値は環境によって自動的に設定されます。 -キー @kbd{\} の代わりに @kbd{C-u \} と入力すると、異なる文字集合 (charset) を指定す -る事ができます。 +プロンプト中の○○部分は、変数 @code{skk-kcode-charset} の値であり、その初期値 +は @code{japanese-jisx0208} 又は @code{japanese-jisx0213-1} です。初期値は環境によ +って自動的に設定されます。キー @code{\} の代わりに @code{C-u \} と入力すると、異な +る文字集合 (charset) を指定する事ができます。 ここで、文字コードがあらかじめ分かっている場合には、その文字コードを入力 -します。例えば @samp{℃} の文字コードは、JIS コードでは @samp{216e}、EUC -コードでは @samp{a1ee} なので、いずれかの文字コードを入力すれば @samp{℃} -が現在のバッファに挿入されます。 - -区点番号で入力するには @samp{01-78} のように区と点の間にハイフン @samp{-} を -入れる必要があります。ハイフン @samp{-} で区切った3組の数字は JIS X 0213 の -2面を指定したとみなします。例えば @samp{2-93-44} で「魚花」(ほっけ)が入力 -できます。 +します。例えば @strong{℃} の文字コードは、JIS コードでは @code{216e} 、EUCコードで +は @code{a1ee} なので、いずれかの文字コードを入力すれば ℃ が現在のバッファに +挿入されます。 + +区点番号で入力するには @code{01-78} のように区と点の間にハイフン @code{-} を入れる +必要があります。ハイフン @code{-} で区切った3組の数字は JIS X 0213 の2面を指 +定したとみなします。例えば @code{2-93-44} で「魚花」(ほっけ U+29e3d)が入力で +きます。 @node メニューによる文字入力 @subsection メニューによる文字入力 文字コードが不明の文字を入力するには、文字コードを入力せずにそのまま -@key{RET} キーを入力します。するとミニバッファに以下のような表示が現れま +@code{RET} キーを入力します。するとミニバッファに以下のような表示が現れま す。 -@c 次の例示中では空欄となっているが、実行時は W: は U+ff0d (-), -@c R: は U+2295 (⊕), Y: は U+2194 (↔) である。 @example -@group ---------------------------- Minibuffer ----------------------------- A:  S: ̄ D:〜 F:} G:= H:¢ Q:◆ W:  E:∩ R:  T:≡ Y:  ---------------------------- Minibuffer ----------------------------- -@end group @end example -@kindex x -これを@b{「第1段階のメニュー」}と呼びます。第1段階のメニューでは、JIS 漢字を -コードの順に 16 文字毎に1文字抽出し、ミニバッファに一度に 12 文字ずつ -表示しています -@footnote{上記の例では、JIS コード 2121 (全角スペース)、2131、2141、2151、 -@dots{} の文字がそれぞれ表示されています。}。ここで @key{SPC} を入力する -と次の候補群を表示します -@footnote{文字コードの値を @w{16x12 @equiv{}192} ずつ増やします。}。 -@kbd{x} を入力すると1つ前の候補群に戻ります。 - -キー @kbd{a}, @kbd{s}, @kbd{d}, @kbd{f}, @kbd{g}, @kbd{h}, -@kbd{q}, @kbd{w}, @kbd{e}, @kbd{r}, @kbd{t}, @kbd{y} のいずれかを -入力すると -@footnote{大文字でも小文字でも構いません。なお、第1段階・第2段階とも +これを @strong{第1段階のメニュー} と呼びます。第1段階のメニューでは、JIS 漢字 +をコードの順に 16 文字毎に1文字抽出し、ミニバッファに一度に 12 文字ずつ +表示しています(上記の例では、JIS コード 2121(全角スペース)、2131、2141、 +2151@dots{} の文字がそれぞれ表示されています)。ここで @code{SPC} を打鍵すると次の +候補群を表示します(文字コードの値を 16 * 12 = 192 ずつ増やします)。 +キー @code{x} を打鍵するとひとつ前の候補群に戻ります。 + +キー @code{a}, @code{s}, @code{d}, @code{f}, @code{g}, @code{h}, @code{q}, @code{w}, @code{e}, @code{r}, @code{t}, @code{y} のいずれ +かを打鍵する @footnote{大文字でも小文字でも構いません。なお、第1段階・第2段階とも に、メニューのキーを変更することができます。 -@w{@ref{候補の選択に用いるキー}} を参照してください。} -、そのキーに対応する文字から始まる 16 個の文字が文字コード順に表示されま -す。これを@b{「第2段階のメニュー」}と呼びます。例えば、第1段階のメニュ -ーが上記の状態のときに @kbd{d} を入力すると 第2段階のメニューは以下のよ -うになります。 -@smallexample -@group ---------------------------------- Minibuffer ---------------------------------- +@ref{候補の選択に用いるキー}.} と、そのキーに対応する文字から始まる 16 個の文字 +が文字コード順に表示されます。これを @strong{第2段階のメニュー} と呼びます。例 +えば、第1段階のメニューが上記の状態のときに @code{d} を打鍵すると 第2段階の +メニューは以下のようになります。 + +@example +--------------------------------- Minibuffer ----------------------------- A:〜 S:‖ D:| F:… G:‥ H:‘ J:’ K:“ L:” Q:( W:) E:〔 R:〕 T:[ Y:] U:{ ---------------------------------- Minibuffer ---------------------------------- -@end group -@end smallexample - -ここで、キー @kbd{a}, @kbd{s}, @kbd{d}, @kbd{f}, @kbd{g}, @kbd{h}, @kbd{j}, -@kbd{k}, @kbd{l}, @kbd{q}, @kbd{w}, @kbd{e}, @kbd{r}, @kbd{t}, @kbd{y}, -@kbd{u}, のいずれかを -入力すると、対応する文字がカレントバッファに挿入されてメニューによる入力 -が終了します。 - -第2段階のメニューが表示されているときも @key{SPC} と @kbd{x} キーによ -り第2段階のメニューが前進、後退します。 - -@kindex < -@kindex > -@kindex ? -また @kbd{<}、@kbd{>} によりメニューを1文字分だけ移動します。例えば、 -第2段階のメニューが上記の状態のときに @kbd{<} を入力すると、メニューは -以下のようになります。 - -@smallexample -@group ---------------------------------- Minibuffer ---------------------------------- +--------------------------------- Minibuffer ----------------------------- +@end example + +ここで、キー @code{a}, @code{s}, @code{d}, @code{f}, @code{g}, @code{h}, @code{j}, @code{k}, @code{l}, @code{q}, @code{w}, @code{e}, @code{r}, @code{t}, @code{y}, @code{u} の +いずれかを打鍵すると、対応する文字がカレントバッファに挿入されてメニュー +による入力が終了します。 + +第2段階のメニューが表示されているときも @code{SPC} と @code{x} キーにより第2段階 +のメニューが前進、後退します。 + +また、キー @code{<} 及び @code{>} により、メニューを1文字分だけ移動します。例えば、 +第2段階のメニューが上記の状態のときにキー @code{<} を打鍵すると、メニューは以 +下のようになります。 + +@example +--------------------------------- Minibuffer ----------------------------- A:\ S:〜 D:‖ F:| G:… H:‥ J:‘ K:’ L:“ Q:” W:( E:) R:〔 T:〕 Y:[ U:] ---------------------------------- Minibuffer ---------------------------------- -@end group -@end smallexample - -第1段階あるいは第2段階のメニューが表示されているときに @kbd{?} を入 -力すると、そのときのキー @kbd{A} に対応する文字 (上記の例では、@samp{\}) -の文字コードが表示されます。 - -@defvr {ユーザ変数} skk-kcode-method - -@kbd{\} の打鍵で起動する @code{skk-input-by-code-or-menu} の挙動を調節します。 - -@table @code -@item 'char-list -@kbd{\} の打鍵で「文字コード一覧」(skk-list-chars)を起動します。 - -@item 'code-or-char-list -@kbd{\} の打鍵で「文字コード」(skk-input-by-code)を起動します。 -JIS コード/区点コード入力プロンプトの表示に対して単に @key{RET} をタイプした場合、 -「文字コード一覧」(skk-list-chars)を起動します。 - -@item 'this-key -@kbd{\} の打鍵で @samp{\} を挿入します。 - -@item 上記シンボル以外 -@kbd{\} の打鍵で「文字コード」(skk-input-by-code)を起動します。 -JIS コード/区点コード入力プロンプトの表示に対して単に @key{RET} をタイプした場合、 -「メニュー入力」を起動します。 +--------------------------------- Minibuffer ----------------------------- +@end example -@end table +第1段階あるいは第2段階のメニューが表示されているときにキー @code{?} を打鍵す +ると、そのときのキー @code{A} に対応する文字(上記の例では @strong{\} )の文字コード +が表示されます。 + +@defvar skk-kcode-method + +キー @code{\} の打鍵で起動する @code{skk-input-by-code-or-menu} の挙動を調節しま +す。 + +@itemize +@item +シンボル @code{char-list} + +キー @code{\} の打鍵で「文字コード一覧」 (@code{skk-list-chars}) を起動します。 + + +@item +シンボル @code{code-or-char-list} + +キー @code{\} の打鍵で「文字コード」 (@code{skk-input-by-code}) を起動します。 +JIS コード/区点コード入力プロンプトの表示に対して単に @code{RET} をタイプ +した場合、「文字コード一覧」 (@code{skk-list-chars}) を起動します。 -@end defvr + +@item +シンボル @code{this-key} + +キー @code{\} の打鍵で @code{\} を挿入します。 + + +@item +上記シンボル以外 + +キー @code{\} の打鍵で「文字コード」 (@code{skk-input-by-code}) を起動します。 +JIS コード/区点コード入力プロンプトの表示に対して単に @code{RET} をタイプ +した場合、「メニュー入力」を起動します。 +@end itemize +@end defvar @node 文字コード一覧 @subsection 文字コード一覧 + @kindex M-x skk-list-chars @kindex M-x list-charset-chars @kindex C-x 8 RET @vindex skk-kcode-charset -@kbd{M-x skk-list-chars} と実行すると、変数 @code{skk-kcode-charset} が指 -す文字集合に従ってバッファ @code{*skk-list-chars*} に文字の JIS コード一 -覧が表示されます。 - -プレフィックス付きで、つまり @kbd{C-u M-x skk-list-chars} と実行すると、 +@code{M-x skk-list-chars} と実行すると、変数 @code{skk-kcode-charset} が指す文字集 +合に従ってバッファ @code{*skk-list-chars*} に文字の JIS コード一覧が表示されま +す。プレフィックス付きで、つまり @code{C-u M-x skk-list-chars} と実行すると、 カーソル位置の文字に照準をあわすようコード一覧を表示します。 @example -@group -------------------- *skk-list-chars* -------------------- variable skk-kcode-charset's value is `japanese-jisx0208'. @@ -8701,187 +8412,224 @@   2140 \ 〜 ‖ | … ‥ ‘ ’ “ ” ( ) 〔 〕 [ ]   2150 { } 〈 〉 《 》 「 」 『 』 【 】 + − ± ×   2160 ÷ = ≠ < > ≦ ≧ ∞ ∴ ♂ ♀ ° ′ ″ ℃ ¥ -  2170 $ ¢ £ % # & * @ § ☆ ★ ○ ● ◎ ◇ -------------------- *skk-list-chars* -------------------- -@end group @end example -@table @kbd -@item f -@itemx C-f -@itemx l +@table @asis +@kindex C-f +@cindex next-completion +@item @kbd{C-f} @tie{}@tie{}@tie{}@tie{}(@code{next-completion}) +@kindex f +@cindex next-completion +@item @kbd{f} @tie{}@tie{}@tie{}@tie{}(@code{next-completion}) +@kindex l +@cindex next-completion +@item @kbd{l} @tie{}@tie{}@tie{}@tie{}(@code{next-completion}) + カーソル移動 -@item b -@itemx C-b -@itemx h +@kindex C-b +@cindex previous-completion +@item @kbd{C-b} @tie{}@tie{}@tie{}@tie{}(@code{previous-completion}) +@kindex b +@cindex previous-completion +@item @kbd{b} @tie{}@tie{}@tie{}@tie{}(@code{previous-completion}) +@kindex h +@cindex previous-completion +@item @kbd{h} @tie{}@tie{}@tie{}@tie{}(@code{previous-completion}) + カーソル移動 -@item n -@itemx C-n -@itemx j +@kindex C-n +@cindex skk-list-chars-next-line +@item @kbd{C-n} @tie{}@tie{}@tie{}@tie{}(@code{skk-list-chars-next-line}) +@kindex n +@cindex skk-list-chars-next-line +@item @kbd{n} @tie{}@tie{}@tie{}@tie{}(@code{skk-list-chars-next-line}) +@kindex j +@cindex skk-list-chars-next-line +@item @kbd{j} @tie{}@tie{}@tie{}@tie{}(@code{skk-list-chars-next-line}) + カーソル移動 -@item p -@itemx C-p -@itemx k +@kindex C-p +@cindex skk-list-chars-previous-line +@item @kbd{C-p} @tie{}@tie{}@tie{}@tie{}(@code{skk-list-chars-previous-line}) +@kindex p +@cindex skk-list-chars-previous-line +@item @kbd{p} @tie{}@tie{}@tie{}@tie{}(@code{skk-list-chars-previous-line}) +@kindex k +@cindex skk-list-chars-previous-line +@item @kbd{k} @tie{}@tie{}@tie{}@tie{}(@code{skk-list-chars-previous-line}) + カーソル移動 -@item C-x C-x +@kindex C-x C-x +@cindex skk-list-chars-goto-point +@item @kbd{C-x C-x} @tie{}@tie{}@tie{}@tie{}(@code{skk-list-chars-goto-point}) + カーソル移動 -@item \ -@itemx o +@kindex RET +@cindex skk-list-chars-insert +@item @kbd{RET} @tie{}@tie{}@tie{}@tie{}(@code{skk-list-chars-insert}) +@kindex i +@cindex skk-list-chars-insert +@item @kbd{i} @tie{}@tie{}@tie{}@tie{}(@code{skk-list-chars-insert}) + +文書バッファへ文字を挿入 + +@kindex g +@cindex skk-list-chars-jump +@item @kbd{g} @tie{}@tie{}@tie{}@tie{}(@code{skk-list-chars-jump}) + +@kindex \ +@cindex skk-list-chars-other-charset +@item @kbd{\} @tie{}@tie{}@tie{}@tie{}(@code{skk-list-chars-other-charset}) +@kindex o +@cindex skk-list-chars-other-charset +@item @kbd{o} @tie{}@tie{}@tie{}@tie{}(@code{skk-list-chars-other-charset}) + 文字集合の切り替え -@item c -文字コード入力 +@kindex c +@cindex skk-list-chars-code-input +@item @kbd{c} @tie{}@tie{}@tie{}@tie{}(@code{skk-list-chars-code-input}) -@item i -@itemx RET -文書バッファへ文字を挿入 +文字コード入力 -@item q -skk-list-chars を抜ける。 +@kindex $ +@cindex skk-list-chars-display-code +@item @kbd{$} @tie{}@tie{}@tie{}@tie{}(@code{skk-list-chars-display-code}) -@item $ カーソル位置の文字の文字コードを表示 +@kindex w +@cindex skk-list-chars-copy +@item @kbd{w} @tie{}@tie{}@tie{}@tie{}(@code{skk-list-chars-copy}) + +@kindex q +@cindex skk-list-chars-quit +@item @kbd{q} @tie{}@tie{}@tie{}@tie{}(@code{skk-list-chars-quit}) + +skk-list-chars を抜ける @end table -ほか、Emacs のコマンド @kbd{M-x list-charset-chars} や @kbd{C-x 8 RET} も有用でしょう。 +ほか、Emacs のコマンド @code{M-x list-charset-chars} や @code{C-x 8 RET} も有用でしょう。 + +@defvar skk-list-chars-table-header-face -@defvr {ユーザ変数} skk-list-chars-table-header-face コード一覧の枠線などに適用するフェイスです。 -@end defvr +@end defvar + +@defvar skk-list-chars-face -@defvr {ユーザ変数} skk-list-chars-face プレフィックス付きで実行したときの照準のフェイスです。 -@end defvr +@end defvar @node 文字コードを知る方法 @subsection 文字コードを知る方法 + @kindex $ +@kindex M-x skk-display-code-for-char-at-point @cindex JISコード @cindex EUCコード -@kindex M-x skk-display-code-for-char-at-point -かな/カナモードで @kbd{$} を入力する -@footnote{リードオンリーなバッファでは @kbd{M-x skk-display-code-for-char-at-point} を実行してください。} -と、現在のポイント位置の直後にある -文字の文字コードをエコーエリア@footnote{変数 @code{skk-show-tooltip} が -@code{non-nil} であればツールティップで表示します。 -変数 @code{skk-show-candidates-always-pop-to-buffer} が @code{non-nil} で -あれば other-window に表示します。@code{skk-show-tooltip} が優先します。} -に表示します。 +かなモード/カナモードでキー @code{$} を打鍵する @footnote{リードオンリーなバッファでは @code{M-x skk-display-code-for-char-at-point} を +実行してください。} と、現在のポイン +ト位置の直後にある文字の文字コードをエコーエリア @footnote{変数 @code{skk-show-tooltip} が @code{non-nil} であればツールティップ +で表示します。変数 @code{skk-show-candidates-always-pop-to-buffer} が @code{non-nil} で +あれば other-window に表示します。 @code{skk-show-tooltip} が優先します。} に表示します。 -例えば、カーソルを文字 @samp{А} の上に置いて @kbd{$} を入力すると、 +例えば、カーソルを文字 @code{А} の上に置いて @code{$} を入力すると、 @example -@group -------------------- Echo Area -------------------- -`А',KUTEN:07-01, JIS:#x2721, EUC:#xa7a1, SJIS:#x8440, UNICODE:U+0410, キリール大文字A,CYRILLIC CAPITAL LETTER A +`А',KUTEN:07-01, JIS:#x2721, EUC:#xa7a1, SJIS:#x8440, UNICODE:U+0410, +キリール大文字A,CYRILLIC CAPITAL LETTER A -------------------- Echo Area -------------------- -@end group @end example @noindent とエコーエリアに表示され、この文字がキリル文字であることがわかります。 -@c プレフィックス付きで @kbd{\}(つまり @kbd{C-u \})とタイプすると、 -@c ポイント直後の文字について文字コード一覧が表示されます。 -@c -@c @example -@c @group -@c -------------------- *skk-list-chars* -------------------- -@c 07-#x--- 0-- 1-- 2-- 3-- 4-- 5-- 6-- 7-- 8-- 9-- A-- B-- C-- D-- E-- F -@c   2720   А Б В Г Д Е Ё Ж З И Й К Л М Н -@c   2730 О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э -@c -------------------- *skk-list-chars* -------------------- -@c @end group -@c @end example -@c -ほか、 Emacs のコマンド @kbd{M-x describe-char} も@footnote{Emacs 21 では @kbd{M-x describe-char-after} です。}有用でしょう。 - -@defvr {ユーザ変数} skk-display-code-prompt-face -エコーエリアに表示されるメッセージ中 @samp{KUTEN:}、@samp{JIS:}@samp{EUC:}、@samp{SJIS:} 及び @samp{UNICODE:} に適用するフェイスです。 -@end defvr +ほか、 Emacs のコマンド @code{M-x describe-char} も有用でしょう。 + +@defvar skk-display-code-prompt-face + +エコーエリアに表示されるメッセージ中 @code{KUTEN:} 、 @code{JIS:} 、 @code{EUC:} 、 @code{SJIS:} 及 +び @code{UNICODE:} に適用するフェイスです。 +@end defvar + +@defvar skk-display-code-char-face -@defvr {ユーザ変数} skk-display-code-char-face エコーエリアに表示されるメッセージ中の当該文字に適用するフェイスです。 -@end defvr +@end defvar + +@defvar skk-display-code-tankan-radical-face -@defvr {ユーザ変数} skk-display-code-tankan-radical-face エコーエリアに表示されるメッセージ中の総画数表示に適用するフェイスです。 -@end defvr +@end defvar + +@defvar skk-display-code-tankan-annotation-face -@defvr {ユーザ変数} skk-display-code-tankan-annotation-face エコーエリアに表示されるメッセージ中の文字名表示に適用するフェイスです。 -@end defvr +@end defvar @node DDSKK 以外のツールを用いた辞書変換 @section DDSKK 以外のツールを用いた辞書変換 + @menu -* skk-lookup:: Lookup を用いた辞書変換 -* skk-look:: look コマンドを用いた辞書変換 +* skk-lookup:: +* skk-look:: * Lisp シンボル名の補完検索変換:: * Google CGI API for Japanese Input を利用したかな漢字変換:: @end menu @node skk-lookup @subsection skk-lookup -@cindex @file{skk-lookup.el} + +@cindex skk-lookup.el @cindex Lookup @vindex skk-lookup-search-agents @findex skk-lookup-search -@file{skk-lookup.el} を使用すると、辞書検索ツールの Lookup -(@url{http://openlab.jp/edict/lookup/}) で検索できる辞書を用いて単語 -の候補を出すことができるようになります @footnote{@file{skk-lookup.el} -は @file{skk-look.el} とは別ものです。}。 - -DDSKK のインストール過程で @code{(require 'lookup)} が成功する場合は -@file{skk-lookup.el} も自動的にインストールされます。 -まずは @samp{make what-where} を実行して、@samp{SKK modules:} 欄 -に @samp{skk-lookup} が含まれていることを確認してください。 - -Lookup がインストールされているにも関わらず、うまく @file{skk-lookup.el} が -インストールされない場合は、@file{SKK-CFG} を編集して @file{lookup.el} -が置かれているパスを @code{ADDITIONAL_LISPDIR} に設定し、再度 DDSKK をイ -ンストールして下さい -@footnote{関数 @code{skk-lookup-search} が @file{skk-autoloads.el} に -追加されます (@pxref{辞書検索のための関数}).}。 +@code{skk-lookup.el} を使用すると、辞書検索ツールの @uref{http://openlab.jp/edict/lookup/, Lookup} で +検索できる辞書を用いて単語の候補を出すことができるようになります。 + +DDSKK のインストール過程で @code{(require 'lookup)} が成功する場合は @code{skk-lookup.el} も +自動的にインストールされます。まずは @code{make what-where} を実行して @code{SKK modules:} 欄 +に @code{skk-lookup} が含まれていることを確認してください。 + +Lookup がインストールされているにも関わらず、うまく @code{skk-lookup.el} が +インストールされない場合は、 @code{SKK-CFG} を編集して @code{lookup.el} が置かれて +いるパスを @code{ADDITIONAL_LISPDIR} に設定し、再度 DDSKK をインストールして下 +さい @footnote{関数 @code{skk-lookup-search} が @code{skk-autoloads.el} に追加されます。 -@file{~/.skk} に以下のように設定します。 +@ref{辞書検索のための関数}.} 。 + +@code{~/.skk} に以下のように設定します。 @lisp -@group (setq skk-search-prog-list (append skk-search-prog-list (list '(skk-lookup-search)))) -@end group @end lisp -@noindent -@code{skk-lookup-search} は、 DDSKK が用意している検索プログラムの中で最 -も遅いものです。したがって、@code{skk-search-prog-list} の設定にあっては -辞書サーバの検索 (@code{skk-search-server}) よりも後方に置くよう設定します。 +@code{skk-lookup-search} は、 DDSKK が用意している検索プログラムの中で最も遅い +ものです。したがって、 @code{skk-search-prog-list} の設定にあっては辞書サーバ +の検索 (@code{skk-search-server}) よりも後方に置くよう設定します。 Lookup の agent で利用するのは、 @code{lookup-search-agents} から @code{ndkks}, -@code{ndcookie} 及び @code{ndnmz} を取り去ったものです -@footnote{@code{skk-lookup-search-agents} にセットして検索するように -しています。Lookup とは異なる設定をする場合、この変数の設定を変更すれば -可能です}。 +@code{ndcookie} 及び @code{ndnmz} を取り去ったものです @footnote{@uref{http://openlab.jp/edict/lookup/}} 。 @node skk-look @subsection skk-look -@cindex @file{skk-look.el} -@file{skk-look.el} は、 @command{look} コマンドを使って次の 3 つの機能を提供します -@footnote{@file{skk-look.el} は @file{skk-lookup.el} とは名前が似てい -ますが全くの別ものです}。 +@code{skk-look.el} は、 @code{look} コマンドを使って3つの機能を提供します。 + @menu * 英単語の補完:: @@ -8891,80 +8639,67 @@ @node 英単語の補完 @subsubsection 英単語の補完 -@vindex skk-use-look -@code{skk-use-look} を @code{non-nil} に設定すると @file{skk-look.el} -が使用できるようになります。 +@defvar skk-use-look -例えば、 @file{~/.skk} で以下のように設定します。 +@code{non-nil} に設定すると @code{skk-look.el} が使用できるようになります。例え +ば @code{~/.skk} で以下のように設定します。 @lisp (setq skk-use-look t) @end lisp +@end defvar -@noindent -SKK abbrev モードが拡張されて、@command{look} コマンドを使用した補完が有効 -になります。 +SKK abbrev モードが拡張されて @code{look} コマンドを使用した補完が有効になりま +す。 @example -@kbd{/ a b s t r} - -@group ------- Buffer: foo ------ -▽abstr@point{} ------- Buffer: foo ------ -@end group +/ a b s t r -@kbd{@key{TAB}} + ------ Buffer: foo ------ + ▽abstr* + ------ Buffer: foo ------ -@group ------- Buffer: foo ------ -▽abstract@point{} ------- Buffer: foo ------ -@end group +TAB + ------ Buffer: foo ------ + ▽abstract* + ------ Buffer: foo ------ @end example -と補完してくれます。通常の補完と同様に @kbd{.} で次の補完候補に、@kbd{,} で -ひとつ前の補完候補に移動できます。 +@noindent +と補完してくれます。通常の補完と同様に @code{.} (ピリオド)で次の補完候補 +に、 @code{,} (コンマ)でひとつ前の補完候補に移動できます。 -SKK 形式の英和辞書@footnote{SKK 形式の英和辞書 edict が提供されています。 -@xref{辞書の入手}.}があれば、ここから @key{SPC} を押して英和変換ができます。 +SKK 形式の英和辞書 edict @footnote{@ref{辞書の入手}.} があれば、ここから @code{SPC} を押して英和 +変換ができます。 @node 英単語をあいまいに変換して取り出す @subsubsection 英単語をあいまいに変換して取り出す -@vindex skk-search-excluding-word-pattern-function -見出し語にアスタリスク @samp{*} を入れて @key{SPC} を押すと英単語をあいまい -にして変換できます。 +見出し語にアスタリスク @code{*} を入れて @code{SPC} を押すと、英単語をあいまいにし +て変換できます。 @example + ------ Buffer: foo ------ + ▽abstr* + ------ Buffer: foo ------ -@group ------- Buffer: foo ------ -▽abstr@point{} ------- Buffer: foo ------ -@end group - -@key{SPC} - -@group ------- Buffer: foo ------ -▼abstract@point{} ------- Buffer: foo ------ -@end group +SPC + ------ Buffer: foo ------ + ▼abstract* + ------ Buffer: foo ------ @end example -確定すると、@samp{abstr*} を見出し語と、@samp{abstract} を候補とする -エントリが個人辞書に追加されます。このようなエントリを追加したくない場合、 -ユーザ変数 @code{skk-search-excluding-word-pattern-function} を適切に -設定します。 +確定すると、 @code{abstr*} を見出し語と、 @code{abstract} を候補とするエントリが個 +人辞書に追加されます。このようなエントリを追加したくない場合、 +ユーザ変数 @code{skk-search-excluding-word-pattern-function} を適切に設定しま +す。例えば次のような設定です。 -例えば次のような設定です。 +@defvar skk-search-excluding-word-pattern-function @lisp -@group (add-hook 'skk-search-excluding-word-pattern-function ;; 返り値が non-nil の時、個人辞書に取り込まない。 ;; KAKUTEI-WORD を引数にしてコールされるので、不要でも引数を取る @@ -8974,219 +8709,194 @@ (save-match-data ;; SKK-HENKAN-KEY が "*" で終わるとき (string-match "\\*$" skk-henkan-key))))) -@end group @end lisp - +@end defvar @node 英単語をあいまいに変換して取り出した後、更に再帰的な英和変換を行う @subsubsection 英単語をあいまいに変換して取り出した後、更に再帰的な英和変換を行う -@vindex skk-look-recursive-search -@vindex skk-look-expanded-word-only SKK 辞書に @example - abstract /アブストラクト/抽象/ - abstraction /アブストラクション/ +abstract /アブストラクト/抽象/ +abstraction /アブストラクション/ @end example @noindent -というエントリがあるとして解説します -@footnote{edict 辞書 @file{SKK-JISYO.edict} があれば、例えば、 - +というエントリがあるとして解説します @footnote{edict 辞書 @code{SKK-JISYO.edict} があれば、例えば、 @lisp -@group (setq skk-search-prog-list (append skk-search-prog-list (list '(skk-search-jisyo-file "/your-path/SKK-JISYO.edict" 0 t)))) -@end group @end lisp +のように設定することにより、 edict 辞書を使用できます。} 。 -@noindent -のように設定することにより、 edict 辞書を使用できます。}。 +@defvar skk-look-recursive-search -変数 @code{skk-look-recursive-search} の値を @code{non-nil} にセットして -下さい。 +@code{non-nil} であれば、英単語 + その英単語を見出し語にした候補の「セット」 +を変換結果として出力することができます。 @example -▽abstr* + ▽abstr* -@key{SPC} +SPC -▼abstract + ▼abstract -@key{SPC} +SPC -▼アブストラクト + ▼アブストラクト -@key{SPC} +SPC -▼抽象 + ▼抽象 -@key{SPC} +SPC -▼abstraction + ▼abstraction -@key{SPC} +SPC -▼アブストラクション + ▼アブストラクション @end example +@end defvar -@noindent -このように英単語 + その英単語を見出し語にした候補の「セット」を変換 -結果として出力することができます。 - -@defvr {ユーザ変数} skk-look-expanded-word-only +@defvar skk-look-expanded-word-only -この変数の値が @code{non-nil} であれば、再帰検索に成功した英単語の「セッ -ト」だけを出力することができます。再帰検索で検出されなかった英単語は無視 -して出力しません。 - -@end defvr +この変数の値が @code{non-nil} であれば、再帰検索に成功した英単語の「セット」 +だけを出力することができます。再帰検索で検出されなかった英単語は無視し +て出力しません。 +@end defvar @node Lisp シンボル名の補完検索変換 @subsection Lisp シンボル名の補完検索変換 SKK abbrev モードにて、Lisp シンボル名を補完して検索し、検索結果を候補と -して返すことができます。英文字の後ろに @samp{~} を付加してから変換を開始 -してください。 +して返すことができます。英文字の後ろに @strong{~} を付加してから変換を開始してく +ださい。 まずは動作例を示します。 @example / d e f i ~ -@group ------ Buffer: foo ----- -▽defi~@point{} ------ Buffer: foo ----- -@end group - -@key{SPC} - -@group ------ Buffer: foo ----- -▽defimage@point{} ------ Buffer: foo ----- -@end group - -@key{SPC} - -@group ------ Buffer: foo ----- -▽define-abbrev@point{} ------ Buffer: foo ----- -@end group - -@key{SPC} - -@group ------ Buffer: foo ----- -▽define-abbrev-table@point{} ------ Buffer: foo ----- -@end group - -@key{SPC} - -@group ------ Buffer: foo ----- -▽define-abbrevs@point{} ------ Buffer: foo ----- -@end group + ----- Buffer: foo ----- + ▽defi~* + ----- Buffer: foo ----- -@key{SPC} +SPC -@group ------ Buffer: *候補* ----- -A:define-auto-insert -S:define-category -D:define-ccl-codepoint-translation-table -F:define-ccl-constant-translation-table -J:define-ccl-identity-translation-table -K:define-ccl-program -L:define-ccl-slide-translation-table ------ Buffer: *候補* ----- -@end group + ----- Buffer: foo ----- + ▽defimage* + ----- Buffer: foo ----- + +SPC + + ----- Buffer: foo ----- + ▽define-abbrev* + ----- Buffer: foo ----- + +SPC + + ----- Buffer: foo ----- + ▽define-abbrev-table* + ----- Buffer: foo ----- + +SPC + + ----- Buffer: foo ----- + ▽define-abbrevs* + ----- Buffer: foo ----- + +SPC + + ----- Buffer: *候補* ----- + A:define-auto-insert + S:define-category + D:define-ccl-codepoint-translation-table + F:define-ccl-constant-translation-table + J:define-ccl-identity-translation-table + K:define-ccl-program + L:define-ccl-slide-translation-table + ----- Buffer: *候補* ----- @end example この機能を有効とするには、リスト @code{skk-search-prog-list} の要素に 関数 @code{skk-search-lisp-symbol} を加えてください。 @lisp -@group (add-to-list 'skk-search-prog-list - '(skk-search-lisp-symbol) t) -@end group + '(skk-search-lisp-symbol) t) @end lisp -なお、見出し語に @samp{~} を含む辞書もあります。例えば @file{SKK-JISYO.JIS3_4} には -@lisp +なお、見出し語に @strong{~} を含む辞書もあります。例えば @code{SKK-JISYO.JIS3_4} には + +@example A~ /チルド付きA(LATIN CAPITAL LETTER A WITH TILDE)/ -@end lisp -と登録@footnote{実際には JIS X 0213 の1面9区26点の1文字が登録されています。 -この文字を @file{skk.texi} に直接記載するのは避けました。}されています。 -したがって、▽A~ @key{SPC} と変換したときに「チルド付きA」が表示されるか、Lisp シンボル名が補完されるかは、リスト @code{skk-search-prog-list} 内の要素の順によります。 +@end example + +@noindent +と登録されています。したがって、 + +@example +▽A~ SPC +@end example + +@noindent +と変換したときに「チルド付きA」が表示されるか、Lisp シンボル名が補完され +るかは、リスト @code{skk-search-prog-list} 内の要素の順によります。 @defun skk-search-lisp-symbol &optional PREDICATE NOT-ABBREV-ONLY WITHOUT-CHAR-MAYBE -オプション @code{PREDICATE} で補完検索する範囲(関数名、変数名、コマンド名)を限定することができます。 -詳細は docstring を参照してください。 + +オプション @code{PREDICATE} で補完検索する範囲(関数名、変数名、コマンド名) +を限定することができます。詳細は docstring を参照してください。 @end defun -@defvr {ユーザ変数} skk-completion-search-char -@code{skk-completion-search} による変換機能を指示するキーキャラクタ。 -デフォルトは @kbd{~} です。 +@defvar skk-completion-search-char -@end defvr +@code{skk-completion-search} による変換機能を指示するキーキャラクタ。 +標準設定は @strong{~} です。 +@end defvar @node Google CGI API for Japanese Input を利用したかな漢字変換 @subsection Google CGI API for Japanese Input を利用したかな漢字変換 + @cindex Google CGI API for Japanese Input -@vindex skk-use-search-web -@findex skk-search-web -@vindex skk-search-prog-list -@vindex skk-read-from-minibuffer-function -かな漢字変換に Google CGI API for Japanese Input を利用することができます。 +かな漢字変換に @uref{http://www.google.co.jp/ime/cgiapi.html, Google CGI API for Japanese Input} を利用することができます。 連文節変換も可能となります。 -Google CGI API for Japanese Input については、次の URL を参照してください。 - -@url{http://www.google.co.jp/ime/cgiapi.html} - -まず、@file{~/.skk} にて、変数 @code{skk-use-search-web} を @code{non-nil} に -設定します。これにより、skk-mode を起動した際に @file{skk-search-web.el} を require す -るようになります。 +まず、 @code{~/.skk} にて、変数 @code{skk-use-search-web} を @code{non-nil} に設定します。 +これにより、skk-mode を起動した際に @code{skk-search-web.el} を require するよ +うになります。 -同じく @file{~/.skk} にて、リスト @code{skk-search-prog-list} の一番最後 -の要素として、関数 @code{skk-search-web} を追加します。 +同じく @code{~/.skk} にて、リスト @code{skk-search-prog-list} の一番最後の要素とし +て、関数 @code{skk-search-web} を追加します。 @lisp -@group (add-to-list 'skk-search-prog-list '(skk-search-web 'skk-google-cgi-api-for-japanese-input) t) -@end group @end lisp -以上の設定によって、通常のかな漢字変更の候補が尽きたときに関数 @code{skk-search-web} が +以上の設定によって、通常のかな漢字変換の @strong{候補が尽きたとき} に関数 @code{skk-search-web} が 実行され、Google CGI API for Japanese Input による変換結果が表示されます。 -そのほか、変数 @code{skk-read-from-minibuffer-function} を以下のように設 -定することで、辞書登録モードへの突入時の初期値に Google サジェストを表示す -ることもできます。 +そのほか、変数 @code{skk-read-from-minibuffer-function} を以下のように設定する +ことで、辞書登録モードへの突入時の初期値に Google サジェストを表示するこ +ともできます。 @lisp -@group (setq skk-read-from-minibuffer-function (lambda () (car (skk-google-suggest skk-henkan-key)))) -@end group @end lisp @node 飾りつけ @section 飾りつけ + @menu * 仮名文字のローマ字プレフィックスのエコー:: * 入力モードを示すモードラインの文字列の変更:: @@ -9200,369 +8910,421 @@ @node 仮名文字のローマ字プレフィックスのエコー @subsection 仮名文字のローマ字プレフィックスのエコー -@defvr {ユーザ変数} skk-echo +@defvar skk-echo + +この変数の値は、仮名文字のローマ字プレフィックスのエコーの有無を制御し +ます。 -この変数の値は、仮名文字のローマ字プレフィックス -@footnote{@xref{送りありエントリと送りなしエントリ, ローマ字プレフィックス}.} -のエコーの有無を制御します。 -@end defvr +@ref{送りありエントリと送りなしエントリ}. +@end defvar -変数 @code{skk-echo} の値が @code{non-nil} であれば、仮名文字のローマ字 -プレフィックスが、入力時点でいったん現在のバッファに挿入され、続く母音の入 -力の際に、かな文字に変換された時点で現在のバッファから消去されます。 +変数 @code{skk-echo} の値が @code{non-nil} であれば、仮名文字のローマ字プレフィック +スが、入力時点でいったん現在のバッファに挿入され、続く母音の入力の際に、 +かな文字に変換された時点で現在のバッファから消去されます。 @example -@group -@kbd{t} +t ------- Buffer: foo ------ -t@point{} ------- Buffer: foo ------ + ------ Buffer: foo ------ + t* + ------ Buffer: foo ------ -@end group -@group -@kbd{a} +a ------- Buffer: foo ------ -た@point{} ------- Buffer: foo ------ -@end group + ------ Buffer: foo ------ + た* + ------ Buffer: foo ------ @end example -変数 @code{skk-echo} の値が @code{nil} であれば、仮名文字のローマ字プレ -フィックスのエコーは行われません。これを上記の例で考えると、@samp{t} が現 -在のバッファに挿入されず、続く母音 (@kbd{a}) が入力されたとき @samp{た} -の文字が挿入されます。 +変数 @code{skk-echo} の値が @code{nil} であれば、仮名文字のローマ字プレフィックスの +エコーは行われません。これを上記の例で考えると、 @code{t} が現在のバッファに挿 +入されず、続く母音 @code{a} が入力された瞬間に「た」の文字が挿入されます。 + +@defvar skk-prefix-hiragana-face + +かなモードにおけるローマ字プレフィックスのフェイスを指定します。 +@end defvar + + +@defvar skk-prefix-katakana-face + +カナモードにおけるローマ字プレフィックスのフェイスを指定します。 +@end defvar + +@defvar skk-prefix-jisx0201-face + +JIS X 0201 モードにおけるローマ字プレフィックスのフェイスを指定します。 +@end defvar + +@node 入力モードを示すモードラインの文字列の変更 +@subsection 入力モードを示すモードラインの文字列の変更 + +下記の変数の値を変更することによって、モードライン上の「入力モードを示す文字 +列」を変更することができます。skk-show-mode の表示も連動します。 + +@defvar skk-latin-mode-string + +アスキーモードを示す文字列。標準は @strong{SKK} 。 +@end defvar + +@defvar skk-hiragana-mode-string + +かなモードを示す文字列。標準は @strong{かな} 。 +@end defvar + +@defvar skk-katakana-mode-string + +カナモードを示す文字列。標準は @strong{カナ} 。 +@end defvar + +@defvar skk-jisx0208-latin-mode-string + +全英モードを示す文字列。標準は @strong{全英} 。 +@end defvar + +@defvar skk-abbrev-mode-string + +SKK abbrev モードを示す文字列。標準は @strong{aあ} 。 +@end defvar + +@node 入力モードを示すカーソル色に関する設定 +@subsection 入力モードを示すカーソル色に関する設定 + +@defopt skk-use-color-cursor + +この変数が @code{non-nil} ならば、カーソルを色付けします。標準では、ウィンド +ウシステムを使用して、かつ、色表示が可能な場合に限って、この機能が有効 +になります。 +@end defopt + +この機能が有効になっているとき、以下の変数の値を変更することで、各モード +におけるカーソルの色を変更できます。 + +@defvar skk-cursor-default-color + +SKK モードがオフであることを示すカーソル色。標準では、カーソルのある該 +当フレームにおける標準のカーソル色を使います。 +@end defvar -@defvr {ユーザ変数} skk-prefix-hiragana-face +@defvar skk-cursor-hiragana-color -かなモードにおけるローマ字プレフィックスのフェイスを指定します。 +かなモードであることを示すカーソル色。標準は、背景の明暗により coral4 ま +たは pink です。 +@end defvar -@end defvr +@defvar skk-cursor-katakana-color -@defvr {ユーザ変数} skk-prefix-katakana-face +カナモードであることを示すカーソル色。標準は、背景の明暗により forestgreen ま +たは green です。 +@end defvar -カナモードにおけるローマ字プレフィックスのフェイスを指定します。 +@defvar skk-cursor-jisx0201-color -@end defvr +JIS X 0201 モードであることを示すカーソル色。標準は、背景の明暗により blueviolet ま +たは thistle です。 +@end defvar -@defvr {ユーザ変数} skk-prefix-jisx0201-face +@defvar skk-cursor-jisx0208-latin-color -JIS X 0201 モードにおけるローマ字プレフィックスのフェイスを指定します。 +全英モードであることを示すカーソル色。標準は、gold です。 +@end defvar -@end defvr +@defvar skk-cursor-latin-color -@node 入力モードを示すモードラインの文字列の変更 -@subsection 入力モードを示すモードラインの文字列の変更 +アスキーモードであることを示すカーソル色。標準は、背景の明暗により ivory4 ま +たは gray です。 +@end defvar -下記の変数の値を変更することによって、モードライン上の「入力モードを示す文字 -列」を変更することができます@footnote{skk-show-mode の表示も連動します。}。 +@defvar skk-cursor-abbrev-color -@defvr {ユーザ変数} skk-latin-mode-string -アスキーモードを示す文字列。標準は、``SKK''。 -@end defvr - -@defvr {ユーザ変数} skk-hiragana-mode-string -かなモードを示す文字列。標準は、``かな''。 -@end defvr - -@defvr {ユーザ変数} skk-katakana-mode-string -カナモードを示す文字列。標準は、``カナ''。 -@end defvr - -@defvr {ユーザ変数} skk-jisx0208-latin-mode-string -全英モードを示す文字列。標準は、``全英''。 -@end defvr - -@defvr {ユーザ変数} skk-abbrev-mode-string -SKK abbrev モードを示す文字列。標準は、``aあ''。 -@end defvr +SKK abbrev モードであることを示すカーソル色。標準は、royalblue です。 +@end defvar -@node 入力モードを示すカーソル色に関する設定 -@subsection 入力モードを示すカーソル色に関する設定 +@node 変換候補一覧の表示方法 +@subsection 変換候補一覧の表示方法 -@defvr {ユーザ変数} skk-use-color-cursor -この変数が @code{non-nil} ならば、カーソルを色付けします。@code{nil} -ならば、この機能を無効にします。 - -標準では、ウィンドウシステムを使用して、かつ、色表示が可能な場合に限 -って、この機能が有効になります。 -@end defvr +変換候補一覧の表示方法は、次の4つに大別されます。 -この機能が有効になっているとき、以下の変数の値を変更することで、各モード -におけるカーソルの色を変更できます。 +@itemize +@item +現在のウィンドウにインライン表示する -@defvr {ユーザ変数} skk-cursor-default-color -SKK モードがオフであることを示すカーソル色。標準では、カーソルのある該当 -フレームにおける標準のカーソル色を使います。 -@end defvr - -@defvr {ユーザ変数} skk-cursor-hiragana-color -かなモードであることを示すカーソル色。標準は、背景の明暗により coral4 また -は pink です。 -@end defvr - -@defvr {ユーザ変数} skk-cursor-katakana-color -カナモードであることを示すカーソル色。標準は、背景の明暗により forestgreen また -は green です。 -@end defvr - -@defvr {ユーザ変数} skk-cursor-jisx0201-color -JIS X 0201 モードであることを示すカーソル色。標準は、背景の明暗により blueviolet また -は thistle です。 -@end defvr -@defvr {ユーザ変数} skk-cursor-jisx0208-latin-color -全英モードであることを示すカーソル色。標準は、gold です。 -@end defvr +@item +ツールティップで表示する -@defvr {ユーザ変数} skk-cursor-latin-color -アスキーモードであることを示すカーソル色。標準は、背景の明暗により ivory4 また -は gray です。 -@end defvr -@defvr {ユーザ変数} skk-cursor-abbrev-color -skk abbrev モードであることを示すカーソル色。標準は、royalblue です。 +@item +現在のウィンドウの隣に別なウィンドウを開いて表示する(ポップアップ) -@end defvr -@page +@item +エコーエリアに表示する +@end itemize -@node 変換候補一覧の表示方法 -@subsection 変換候補一覧の表示方法 -変換候補一覧の表示方法は、次の4つに大別されます。 +@menu +* 現在のウィンドウにインライン表示する:: +* ツールティップで表示する:: +* 現在のウィンドウの隣に別なウィンドウを開いて表示する(ポップアップ):: +* エコーエリアに表示する:: +@end menu -@itemize @bullet -@item 現在のウィンドウにインライン表示する -@item ツールティップで表示する -@item 現在のウィンドウの隣に別なウィンドウを開いて表示する (ポップアップ) -@item エコーエリアに表示する -@end itemize +@node 現在のウィンドウにインライン表示する +@subsubsection 現在のウィンドウにインライン表示する -ここではその表示方法の制御について解説します。 +@strong{XEmacs ではインライン表示はサポートされません。} -@defvr {ユーザ変数} skk-show-inline +@defvar skk-show-inline -@b{XEmacs ではこの機能はサポートされません。} +この変数の値が @code{non-nil} であれば、候補一覧を現在のポイント位置でインラ +イン表示します。値がシンボル @code{vertical} であれば、各候補を縦方向にイン +ライン表示します。 +@end defvar -この変数の値が @code{non-nil} であれば、候補一覧を現在のポイント位置でインライン表 -示します。 -値が シンボル @code{'vertical} であれば、各候補を縦方向にインライン表示します。 +@defvar skk-inline-show-face -@cartouche -@defvr {ユーザ変数} skk-inline-show-face -インライン表示する変換候補を装飾するフェイスを指定します。デフォルト -は @code{'underline} です。 +インライン表示する変換候補を装飾するフェイスを指定します。標準設定 +は @code{underline} です。 @lisp (setq skk-inline-show-face 'font-lock-doc-face) @end lisp -@code{skk-treat-candidate-appearance-function} による装飾を優先するには -@code{nil} に設定して下さい。 -@end defvr +@code{skk-treat-candidate-appearance-function} による装飾を優先するには @code{nil} に +設定して下さい。 +@end defvar + +@defvar skk-inline-show-background-color -@defvr {ユーザ変数} skk-inline-show-background-color インライン表示する変換候補の背景色を指定します。 -@code{skk-inline-show-face} または -@code{skk-treat-candidate-appearance-function} にて、背景色が指定されてい -ない文字に対してのみ作用します。 -@end defvr +@code{skk-inline-show-face} または @code{skk-treat-candidate-appearance-function} に +て、背景色が指定されていない文字に対してのみ作用します。 +@end defvar + +@defvar skk-inline-show-background-color-odd -@defvr {ユーザ変数} skk-inline-show-background-color-odd インライン表示する変換候補の背景色(奇数ライン)を指定します。 -@end defvr +@end defvar -@end cartouche -@end defvr +@node ツールティップで表示する +@subsubsection ツールティップで表示する -@page +@defvar skk-show-tooltip + +この変数の値が @code{non-nil} であれば、候補一覧をツールティップで表示します。 +同時に、「注釈(アノテーション)の表示方法」と「文字コードの表示方法」 +も制御します。 + +@itemize +@item +@ref{注釈(アノテーション)}. + + +@item +@ref{文字コードまたはメニューによる文字入力}. +@end itemize +@end defvar + +@defvar skk-tooltip-face -@defvr {ユーザ変数} skk-show-tooltip -この変数の値が @code{non-nil} であれば、候補一覧をツールティップで表示し -ます。同時に、「注釈 (アノテーション) の表示方法」と「文字コードの表示方 -法」も制御します。 - -@xref{注釈 (アノテーション)}. - -@xref{文字コードまたはメニューによる文字入力}. - -@cartouche -@defvr {ユーザ変数} skk-tooltip-face -ツールティップ表示する文字列に適用するフェイスを指定する変数です。 +ツールティップ表示する文字列に適用するフェイスのシンボルを指定する変数 +です。 @lisp (setq skk-tooltip-face 'font-lock-doc-face) ;; (make-face 'skk-tooltip-face) ではないことに注意 @end lisp -候補文字列のフェイス属性(@code{skk-treat-candidate-appearance-function} による加工など)をそのまま使いたい場合は @code{nil} に設定して下さい。 -@end defvr +候補文字列のフェイス属性( @code{skk-treat-candidate-appearance-function} に +よる加工など)をそのまま使いたい場合は @code{nil} に設定して下さい。 +@end defvar + +@defvar skk-tooltip-mouse-behavior -@defvr {ユーザ変数} skk-tooltip-mouse-behavior +ツールティップを表示する位置及びマウスポインタの挙動を指定します。下記 +に掲げるシンボル以外のシンボルを指定した場合は @code{nil} となります。 -ツールティップを表示する位置及びマウスポインタの挙動を指定します。 -下記に掲げるシンボル以外のシンボルを指定した場合は @code{nil} となります。 +@itemize +@item +シンボル @code{follow} -@table @code -@item 'follow マウスポインタをカーソル位置へ移動させてツールティップを表示します。 -ツールティップの表示を終えるとマウスポインタは元の位置へ戻ります。ただし、元のマウスポインタが Emacs フレーム外であったならばツールティップの表示を終えてもマウスポインタはカーソル位置のままです。 +ツールティップの表示を終えるとマウスポインタは元の位置へ戻ります。た +だし、元のマウスポインタが Emacs フレーム外であったならばツールティッ +プの表示を終えてもマウスポインタはカーソル位置のままです。 -@item 'banish -マウスポインタを Emacs フレーム右上隅へ移動させてツールティップを表示します。 -ツールティップの表示を終えもてマウスポインタは Emacs フレーム右上隅のままです。 -@item 'avoid -マウスポインタを Emacs フレーム右上隅へ移動させてツールティップを表示します。 -ツールティップの表示を終えるとマウスポインタは元の位置へ戻ります。ただし、元のマウスポインタが Emacs フレーム外であったならばツールティップの表示を終えてもマウスポインタは Emacs フレーム右上隅のままです。 +@item +シンボル @code{banish} -@item 'avoid-maybe -マウスポインタが Emacs フレーム内であれば @code{'avoid} と同じ動作です。 -マウスポインタが Emacs フレーム外であればマウスポインタ位置を変更せず、その位置にツールティップを表示します。 +マウスポインタを Emacs フレーム右上隅へ移動させてツールティップを表示 +します。ツールティップの表示を終えもてマウスポインタは Emacs フレーム +右上隅のままです。 -@item nil -マウスポインタを一切移動せず、その位置にツールティップを表示します。 -ツールティップのテキストとマウスポインタが重なったり、うまくツールティップが表示できなかったりする場合があります。 -@end table +@item +シンボル @code{avoid} + +マウスポインタを Emacs フレーム右上隅へ移動させてツールティップを表示 +します。ツールティップの表示を終えるとマウスポインタは元の位置へ戻り +ます。ただし、元のマウスポインタが Emacs フレーム外であったならばツー +ルティップの表示を終えてもマウスポインタは Emacs フレーム右上隅のまま +です。 + -@end defvr +@item +シンボル @code{avoid-maybe} + +マウスポインタが Emacs フレーム内であれば @code{avoid} と同じ動作です。マ +ウスポインタが Emacs フレーム外であればマウスポインタ位置を変更せず、 +その位置にツールティップを表示します。 -@defvr {ユーザ変数} skk-tooltip-hide-delay -ツールティップを表示する秒数。デフォルトは 1,000秒。この時間が経過すると、 -ツールティップは自動的に消える。 +@item +@code{nil} + +マウスポインタを一切移動せず、その位置にツールティップを表示します。 +ツールティップのテキストとマウスポインタが重なったり、うまくツールテ +ィップが表示できなかったりする場合があります。 +@end itemize +@end defvar -@end defvr +@defvar skk-tooltip-hide-delay -@defvr {ユーザ変数} skk-tooltip-parameters +ツールティップを表示する秒数。標準設定は 1,000秒。この時間が経過する +と、ツールティップは自動的に消える。 +@end defvar -デフォルトは @code{nil}。SKK 独自のフレームパラメータを設定する。 -@code{nil} の場合、@code{tooltip-frame-parameters} が適用される。 +@defvar skk-tooltip-parameters -@end defvr +標準設定は @code{nil} 。SKK 独自のフレームパラメータを設定する。 @code{nil} の +場合、 @code{tooltip-frame-parameters} が適用される。 +@end defvar -@end cartouche -@end defvr +@node 現在のウィンドウの隣に別なウィンドウを開いて表示する(ポップアップ) +@subsubsection 現在のウィンドウの隣に別なウィンドウを開いて表示する(ポップアップ) -@page +@defvar skk-show-candidates-always-pop-to-buffer -@defvr {ユーザ変数} skk-show-candidates-always-pop-to-buffer -この値が @code{non-nil} であれば、画面を上下に分割したうえで、変換一覧を専用 -の「*候補*バッファ」で表示します。 +この値が @code{non-nil} であれば、画面を上下に分割したうえで、候補一覧を専用 +の *候補*バッファで表示します。 +@end defvar 候補一覧表示中に、この値を動的に切り換える手段が用意されています。 -@cartouche -@defvr {ユーザ変数} skk-show-candidates-toggle-display-place-char @kindex C-f -デフォルトは @kbd{C-f} です。このキーを候補一覧表示時にタイプすると、候補 -一覧の表示位置をエコーエリアとバッファとで切り替えます。 -@end defvr +@defvar skk-show-candidates-toggle-display-place-char -@defvr {ユーザ変数} skk-candidate-buffer-background-color - *候補*バッファの背景色を指定します。 -背景色を付けたくない場合は @code{nil} を指定すること(デフォルト)。 -@end defvr +候補一覧表示中に、候補一覧の表示位置をエコーエリアとバッファとで動的に +切り換えることができます。標準設定は @code{C-f} です。 +@end defvar -@defvr {ユーザ変数} skk-candidate-buffer-background-color-odd - *候補*バッファの背景色(奇数ライン)を指定します。 -@end defvr +@defvar skk-candidate-buffer-background-color -@defvr {ユーザ変数} skk-candidate-buffer-delete-other-windows - nil であれば、*候補*バッファ表示に際して window 配置を変更しない。 -@end defvr +*候補*バッファの背景色を指定します。背景色を付けたくない場合は @code{nil} を +指定すること(標準設定)。 +@end defvar -@end cartouche -@end defvr +@defvar skk-candidate-buffer-background-color-odd -@noindent -デフォルトでは3つの変数 +*候補*バッファの背景色(奇数ライン)を指定します。 +@end defvar -@itemize @bullet -@item @code{skk-show-inline} -@item @code{skk-show-tooltip} -@item @code{skk-show-candidates-always-pop-to-buffer} +@defvar skk-candidate-buffer-delete-other-windows + +@code{nil} であれば、*候補*バッファ表示に際して window 配置を変更しない。 +window 配置を popwin や shackle にまかせている場合は @code{nil} とすべき。 + +@itemize +@item +@uref{https://github.com/m2ym/popwin-el, Popup Window Manager for Emacs} + + +@item +@uref{https://github.com/wasamasa/shackle, Enforce rules for popup windows} @end itemize +@end defvar -とも @code{nil} であり、この状態では候補一覧はエコーエリアに表示 -@footnote{@code{frame-width} が不足する場合は *候補*バッファに表示します。} -します。 +@node エコーエリアに表示する +@subsubsection エコーエリアに表示する -もしも、これら変数のうち2つ以上が @code{non-nil} の場合、優先順位は上記 -の解説の順です。 +標準設定では3つの変数 -@page +@itemize +@item +@code{skk-show-inline} -@node ▼モードにおける変換候補のハイライト表示 -@subsection ▼モードにおける変換候補のハイライト表示 -@cindex @file{canna.el} -@cindex @file{rgb.txt} +@item +@code{skk-show-tooltip} -@defvr {ユーザ変数} skk-use-face +@item +@code{skk-show-candidates-always-pop-to-buffer} +@end itemize + +@noindent +とも @code{nil} であり、この状態では候補一覧はエコーエリアに表示 @footnote{ただし、 @code{frame-width} が不足する場合は、*候補*バッファに表示しま +す。} しま +す。もしも、これら変数のうち2つ以上が @code{non-nil} の場合、優先順位は上記の +解説の順です。 -この変数の値が @code{non-nil} であれば、Emacs のフェイス機能を使って変換 -候補をハイライト表示します。 +@node ▼モードにおける変換候補のハイライト表示 +@subsection ▼モードにおける変換候補のハイライト表示 +@cindex canna.el +@cindex rgb.txt @cindex Overlays @cindex Extents @cindex Text Properties -このハイライト表示には Emacs のオーバーレイ (overlay) の機能を使います -@footnote{以前のバージョンではテキスト属性 (text property) を使用してい -ました。 - -オーバーレイ属性はテキスト属性と異なり、テキストの一部とは見なされません。 -そのため、テキストのコピーの際にオーバーレイ属性は保存されません。その他 -にも、オーバーレイの移動やその属性の変更はバッファの変更とは見なされない -こと、オーバーレイの変更はバッファのアンドゥリストに記録されないこと、な -どが特徴として挙げられます。 - -なお、XEmacs にはオーバーレイ機能はありません。代わりに extent というも -のが用意されているのでそれを利用します。}。 -@end defvr - -@defvr {ユーザ変数} skk-henkan-face - -この変数の値はフェイスであり、このフェイスによって変換候補がハイライト表 -示されます。標準では、背景の明暗により ``black/darkseagreen2'' 又は -``white/darkolivegreen'' を用います。 - -なお、この変数よりも @code{skk-treat-candidate-appearance-function} の設 -定が優先されます。 -@end defvr - -変数 @code{skk-henkan-face} には、既存のフェイス -@footnote{Emacs 標準 では @code{default}, @code{modeline}, @code{region}, -@code{secondary-selection}, @code{highlight}, @code{underline}, -@code{bold}, @code{italic}, @code{bold-italic} があります。}を指定できま -すが、新たにフェイスを作ることもできます。そのために、以下の関数が用意さ -れています。 -@defun skk-make-face FACE +@defvar skk-use-face -形式: (skk-make-face FACE) +この変数の値が @code{non-nil} であれば、Emacs のフェイス機能を使って変換候補 +をハイライト表示します。このハイライト表示には GNU Emacs のオーバーレイ (overlay) の +機能を使います @footnote{以前のバージョンではテキスト属性 (text property) を使用して +いました。オーバーレイ属性はテキスト属性と異なり、テキストの一部とは見な +されません。そのため、テキストのコピーの際にオーバーレイ属性は保持されま +せん。その他にも、オーバーレイの移動やその属性の変更はバッファの変更とは +見なされないこと、オーバーレイの変更はバッファのアンドゥリストに記録され +ないこと、などが特徴として挙げられます。なお、XEmacs にはオーバーレイ機能 +はありません。代わりに extent というものが用意されているのでそれを利用し +ます。} 。 +@end defvar + +@defvar skk-henkan-face + +この変数の値はフェイスであり、このフェイスによって変換候補がハイライト +表示されます。標準では、背景の明暗により black/darkseagreen2 又は +white/darkolivegreen を用います。 + +なお、この変数よりも @code{skk-treat-candidate-appearance-function} の設定が +優先されます。 +@end defvar + +変数 @code{skk-henkan-face} には、既存のフェイス @footnote{Emacs 標準 では @code{default}, @code{modeline}, @code{region}, @code{secondary-selection}, +@code{highlight}, @code{underline}, @code{bold}, @code{italic}, @code{bold-italic} があります。} を指定できますが、 +新たにフェイスを作ることもできます。そのために次の関数が用意されています。 -この関数は、引数 FACE と同じ名前のフェイスを作成して、そのフェイスを返し -ます。フェイスの前景色・背景色は、引数 FACE にスラッシュを含めることよっ -て、例えば以下の例のように決定されます。 +@defun skk-make-face FACE + +この関数は、引数 @code{FACE} と同じ名前のフェイスを作成して、そのフェイスを +返します。フェイスの前景色・背景色は、引数 @code{FACE} にスラッシュ @code{/} を含 +めることよって、例えば以下の例のように決定されます。 @lisp (setq skk-henkan-face (skk-make-face 'DimGray/PeachPuff1)) @end lisp -この場合、前景色は DimGray に、背景色は PeachPuff1 になります。 - -もうひとつ例を挙げます。 +この場合、前景色は DimGray に、背景色は PeachPuff1 になります。もうひと +つ例を挙げます。 @lisp (setq skk-henkan-face (skk-make-face 'RosyBrown1)) @end lisp -この場合、前景色は RosyBrown1 になります。背景色が無指定の場合はバッファ -の背景色がそのまま見えます。 +この場合、前景色は RosyBrown1 になります。背景色が無指定の場合はバッフ +ァの背景色がそのまま見えます。 @end defun @node 変換候補の更なる装飾 @@ -9570,51 +9332,56 @@ 変換候補についてユーザの任意の加工を施すための変数を用意してあります。 -@defvr {ユーザ変数} skk-treat-candidate-appearance-function +@defvar skk-treat-candidate-appearance-function -この変数に適切な形式で関数を収めることによって、変換候補をユーザの任意に -加工することができます。「適切な形式」とは、次のとおりです。 +この変数に適切な形式で関数を収めることによって、変換候補をユーザの任意 +に加工することができます。「適切な形式」とは、次のとおりです。 -@cartouche -@enumerate +@itemize @item 引数を2つ取ること。 + @item 第1引数は文字列として扱うこと。これは加工前の文字列に相当する。 + @item -第2引数が @code{nil} の時は通常の変換時、@code{non-nil} の時は候補一覧表 -示時を表すものとして扱うこと。 +第2引数が @code{nil} の時は通常の変換時、 @code{non-nil} の時は候補一覧表示時 +を表すものとして扱うこと。 + @item 返り値は次のいずれかとすること。 -@table @samp -@item 文字列 +@itemize +@item +文字列 この場合、この文字列は候補と注釈を両方含みうるものとして処理される。 -@item (候補 . 注釈) -この場合、候補はもう注釈を含まないものとして処理される。注釈については先 -頭が @samp{;} かどうかを調べた上で処理される。 +@item +@code{(候補 . 注釈)} -@item (候補 . (セパレータ . 注釈)) +この場合、候補はもう注釈を含まないものとして処理される。注釈について +は先頭が @code{;} かどうかを調べた上で処理される。 -この場合、候補はもう注釈を含まないものとして処理される。セパレータは通常 -の @samp{;} の代わりに利用される。注釈はもうセパレータを含まないものとして処 -理される。 -@end table -@end enumerate -@end cartouche +@item +@code{(候補 . (セパレータ . 注釈))} -ファイル @file{etc/dot.skk} に設定例があるほか、サンプルとして関数 -@code{skk-treat-candidate-sample1} と @code{skk-treat-candidate-sample2} -を用意してあります。 -ファイル @file{~/.skk} に次のいずれかを書いてみて変換候補の装飾を試して -ください。 +この場合、候補はもう注釈を含まないものとして処理される。セパレータ +は通常の @code{;} の代わりに利用される。注釈はもうセパレータを含まないも +のとして処理される。 +@end itemize +@end itemize +@end defvar + +ファイル @code{etc/dot.skk} に設定例があるほか、サンプルとして関数 +@code{skk-treat-candidate-sample1} と @code{skk-treat-candidate-sample2} を用意して +あります。ファイル @code{~/.skk} に次のいずれかを書いてみて変換候補の装飾を試 +してください。 @lisp (setq skk-treat-candidate-appearance-function @@ -9626,12 +9393,11 @@ 'skk-treat-candidate-sample2) @end lisp -@end defvr - @node モードラインの装飾 @subsection モードラインの装飾 -XEmacs 及び Emacs 21 以降では、以下の機能が使用できます。 +XEmacs 及び GNU Emacs 21 以降では、以下の機能が使用できます。 + @menu * インジケータ:: @@ -9641,38 +9407,46 @@ @node インジケータ @subsubsection インジケータ -@defvr {ユーザ変数} skk-indicator-use-cursor-color - -DDSKK のインジケータをモードラインの左に表示 -@footnote{デフォルトでは、左です。@w{@xref{起動と終了}.}} -している場合、インジケータの色がカーソルの色と同期します。 -インジケータに色を付けたくない場合は、この変数を @code{nil} にします。 +@defvar skk-indicator-use-cursor-color -@end defvr +DDSKK のインジケータをモードラインの左 @footnote{標準設定では左です。 -@xref{入力モードを示すカーソル色に関する設定}. +@ref{起動と終了}.} に表示している場合、 +インジケータの色がカーソルの色と同期します。インジケータに色を付けたく +ない場合は、この変数を @code{nil} にします。 +@end defvar -インジケータに独自色を使いたい場合は、以下のフェイス@footnote{ -変数 @code{window-system} が @code{nil} の場合は、これらフェイスは未定義と -なります。} を設定します。この場合カーソルの色は参照されません。 +@ref{入力モードを示すカーソル色に関する設定}. -Emacs 21 以上 @footnote{変数 @code{mule-version} の値が 5.0 以上の Emacs} の場合 +インジケータに独自色を使いたい場合は、以下のフェイス @footnote{変数 @code{window-system} が @code{nil} の場合は、これらフェイスは未定義となります。} を設定し +ます。この場合カーソルの色は参照されません。 @vindex skk-emacs-hiragana-face @vindex skk-emacs-katakana-face @vindex skk-emacs-jisx0208-latin-face @vindex skk-emacs-jisx0201-face @vindex skk-emacs-abbrev-face +@itemize +@item +GNU Emacs 21 以上(変数 @code{mule-version} の値が 5.0 以上の GNU Emacs)の場合 -@itemize @bullet -@item @code{skk-emacs-hiragana-face} -@item @code{skk-emacs-katakana-face} -@item @code{skk-emacs-jisx0208-latin-face} -@item @code{skk-emacs-jisx0201-face} -@item @code{skk-emacs-abbrev-face} -@end itemize +@itemize +@item +@code{skk-emacs-hiragana-face} -XEmacs の場合 +@item +@code{skk-emacs-katakana-face} + +@item +@code{skk-emacs-jisx0208-latin-face} + +@item +@code{skk-emacs-jisx0201-face} + +@item +@code{skk-emacs-abbrev-face} +@end itemize +@end itemize @vindex skk-xemacs-hiragana-face @vindex skk-xemacs-katakana-face @@ -9680,39 +9454,53 @@ @vindex skk-xemacs-latin-face @vindex skk-xemacs-jisx0201-face @vindex skk-xemacs-abbrev-face +@itemize +@item +XEmacs の場合 -@itemize @bullet -@item @code{skk-xemacs-hiragana-face} -@item @code{skk-xemacs-katakana-face} -@item @code{skk-xemacs-jisx0208-latin-face} -@item @code{skk-xemacs-latin-face} -@item @code{skk-xemacs-jisx0201-face} -@item @code{skk-xemacs-abbrev-face} -@end itemize +@itemize +@item +@code{skk-xemacs-hiragana-face} -なお、インジケータを右クリックするとポップアップメニューが表示されます。 +@item +@code{skk-xemacs-katakana-face} -@node アイコン -@subsubsection アイコン -@cindex @file{skk-icon} +@item +@code{skk-xemacs-jisx0208-latin-face} -@defvr {ユーザ変数} skk-show-icon +@item +@code{skk-xemacs-latin-face} + +@item +@code{skk-xemacs-jisx0201-face} -変数 @code{skk-show-icon} の値を @code{non-nil} と設定することにより、モー -ドラインに SKK のアイコンが表示されます@footnote{@code{(image-type-available-p 'xpm)} が @code{t} を返す必要があるため、Emacsen の実行環境に依存します。}。 +@item +@code{skk-xemacs-abbrev-face} +@end itemize +@end itemize -@end defvr +なお、インジケータを右クリックするとポップアップメニューが表示されます。 -@defvr {ユーザ変数} skk-icon +@node アイコン +@subsubsection アイコン -アイコンの画像ファイル @file{skk.xpm} へのパス。 -関数 @code{skk-emacs-prepare-modeline-properties} で定義しています。 +@defvar skk-show-icon -@end defvr +変数 @code{skk-show-icon} の値を @code{non-nil} と設定することにより、モードライ +ンに SKK のアイコンが表示されます。なお、アイコン表示は @code{(image-type-available-p 'xpm)} が @code{t} を +返す必要があるため、Emacs の種類/実行環境に依存します。 +@end defvar + +@defvar skk-icon + +アイコンの画像ファイル @code{skk.xpm} へのパス。関数 @code{skk-emacs-prepare-modeline-properties} で +定義しています。 +@end defvar @node ユーザガイダンス関連 @section ユーザガイダンス関連 + @menu * エラーなどの日本語表示:: * 冗長な案内メッセージの表示:: @@ -9724,133 +9512,135 @@ 標準では、エラー、メッセージ及びミニバッファでのプロンプトは、英語で表示 されます。 -@defvr {ユーザ変数} skk-japanese-message-and-error +@defvar skk-japanese-message-and-error -この変数の値を @code{non-nil} に設定すると、エラー、メッセージ及びミニバ -ッファでのプロンプトを日本語で表示します。標準では @code{nil} です。 -@end defvr +この変数の値を @code{non-nil} に設定すると、エラー、メッセージ及びミニバッフ +ァでのプロンプトを日本語で表示します。標準では @code{nil} です。 +@end defvar -@defvr {ユーザ変数} skk-show-japanese-menu +@defvar skk-show-japanese-menu この変数の値を @code{non-nil} に設定すると、メニューバーを日本語で表示します。 -@end defvr +@end defvar -@defvr {ユーザ変数} skk-version-codename-ja +@defvar skk-version-codename-ja この変数の値を @code{non-nil} に設定すると、関数 @code{skk-version} を評価したと きのコードネームを日本語で表示します。 - -@end defvr +@end defvar @node 冗長な案内メッセージの表示 @subsection 冗長な案内メッセージの表示 -@c http://mail.ring.gr.jp/skk/200704/msg00036.html -@defvr {ユーザ変数} skk-verbose +@defvar skk-verbose -この変数の値を @code{non-nil} に設定すると、入力中/変換中に冗長なメッセ -ージを表示します。 +この変数の値を @code{non-nil} に設定すると、入力中/変換中に冗長なメッセージ +を表示します。 @lisp (setq skk-verbose t) @end lisp -@end defvr - -@table @asis -@item ▽モード +@end defvar -ファンクションキー (@key{F1} 〜 @key{F10}) に割り当てられている機能を表示 -します。変数 @code{skk-verbose} の設定と同時に変数 @code{skk-j-mode-function-key-usage} を以下のように設定してみてください。 @vindex skk-j-mode-function-key-usage +@itemize +@item +▽モード + +ファンクションキー (@code{F1} 〜 @code{F10}) に割り当てられている機能を表示します。 +変数 @code{skk-verbose} の設定と同時に変数 @code{skk-j-mode-function-key-usage} を +以下のように設定してみてください。 @lisp (setq skk-j-mode-function-key-usage 'conversion) @end lisp -@noindent -▽モードにおいてキー入力が一定時間 (標準では 1.5 秒) なされなかったとき、 +▽モードにおいてキー入力が一定時間(標準では 1.5 秒)なされなかったとき、 エコーエリアに以下のようなメッセージが表示されます。 -@smallexample -@group +@example -------------------- Echo Area -------------------- [F5]単漢字 [F6]無変換 [F7]カタカナ [F8]半角カナ [F9]全角ローマ [F10]ローマ -------------------- Echo Area -------------------- -@end group -@end smallexample - -@noindent -この案内に従ってファンクションキーを押すことで、一時的に単漢字変換やカタ -カナ変換を行うことができます。 +@end example -@item ▼モード +この案内に従ってファンクションキーを押すことで、一時的に単漢字変換やカ +タカナ変換を行うことができます。 +@end itemize -Wikipedia アノテーション機能の使い方をメッセージで案内します。 -変数 @code{skk-verbose} の設定と同時に変数 @code{skk-show-annotation} を @code{non-nil} に設定してみてください。 @vindex skk-show-annotation +@cindex kill ring +@vindex interprogram-cut-function +@itemize +@item +▼モード + +Wikipedia アノテーション機能の使い方をメッセージで案内します。変数 @code{skk-verbose} の +設定と同時に変数 @code{skk-show-annotation} を @code{non-nil} に設定してみてください。 @lisp (setq skk-show-annotation t) @end lisp -@noindent ▼モードにおいてキー入力が一定時間 (標準では 1.5 秒) なされなかったとき、 エコーエリアに以下のようなメッセージが表示されます。 -@smallexample -@group +@example -------------------- Echo Area -------------------- -@b{@{どれを参照?@}}[C-1 C-i]ja.wikipedia [C-2 C-i]en.wiktionary +どれを参照?[C-1 C-i]ja.wikipedia [C-2 C-i]en.wiktionary [C-3 C-i]simple.wikipedia [C-4 C-i]en.wikipedia [C-5 C-i]ja.wiktionary -------------------- Echo Area -------------------- -@end group -@end smallexample +@end example -@noindent -この案内に従って、例えば @kbd{C-1 C-i} をタイプすると日本語 Wikipedia の該当記 -事を調べて、あればその一部をアノテーションとして表示します。 +この案内に従って、例えば @code{C-1 C-i} を打鍵すると、日本語 Wikipedia の該 +当記事を調べて、あればその一部をアノテーションとして表示します。 一方、現在の変換候補に対するアノテーションが既に表示されているときは、 以下のメッセージが上記のものと交互に表示されます。 -@smallexample -@group +@example -------------------- Echo Area -------------------- -@b{@{アノテーション@}}[C-w]コピー [C-o]URLブラウズ [C-i]デフォルトのソースを参照 +@{アノテーション@}[C-w]コピー [C-o]URLブラウズ [C-i]標準設定のソースを参照 -------------------- Echo Area -------------------- -@end group -@end smallexample +@end example -@noindent -この案内に従って @kbd{C-w} をタイプすればアノテーションの全文を kill ring に -保存して利用することができます。また @kbd{C-o} を押した場合には、もし現 -在のアノテーションが Wikipedia アノテーションであればその出典となる +この案内に従って @code{C-w} を打鍵すれば、アノテーションの全文を kill ring に +保存して利用することができます @footnote{kill ring については info を参照。 + +@ref{Kill Ring,The Kill Ring in GNU Emacs Manual,,emacs,}. + +保存した内容を Emacs 以外のアプリケーションで利用したい場合は変数 @code{interprogram-cut-function} を +設定してください。} 。また、キー @code{C-o} を押した場合には、もし +現在のアノテーションが Wikipedia アノテーションであればその出典となる Wikipedia/Wiktionary のページをウェブブラウザで表示します。 -@end table -@defvr {ユーザ変数} skk-verbose-wait -冗長なメッセージを表示するまでの待ち時間 (秒)。標準は 1.5 秒です。 -@end defvr - -@defvr {ユーザ変数} skk-verbose-message-interval -冗長なメッセージが複数ある場合の1メッセージあたり表示時間を秒で指定する。 -標準は 5.0 秒です。 -この時間が経過したら表示を次の冗長なメッセージに切り替えます。 -@end defvr +@end itemize + +@defvar skk-verbose-wait + +冗長なメッセージを表示するまでの待ち時間(秒)。標準は 1.5 秒です。 +@end defvar + +@defvar skk-verbose-message-interval + +冗長なメッセージが複数ある場合の1メッセージあたり表示時間を秒で指定す +る。標準は 5.0 秒です。この時間が経過したら表示を次の冗長なメッセージ +に切り替えます。 +@end defvar + +@defvar skk-verbose-intention-face -@defvr {ユーザ変数} skk-verbose-intention-face 「どれを参照?」と「アノテーション」に適用するフェイスです。 -@end defvr +@end defvar -@defvr {ユーザ変数} skk-verbose-kbd-face -@samp{[F5]} や @samp{[C-1 C-i]} に適用するフェイスです。 -@end defvr +@defvar skk-verbose-kbd-face + +@code{[F5]} や @code{[C-1 C-i]} に適用するフェイスです。 +@end defvar + +@node I-search 関連 +@section I-search 関連 -@node I-search関連 -@section I-search関連 -@cindex I-search -@cindex Incremental search -@cindex @file{~/.skk} @menu * 起動時の入力モードの指定:: @@ -9860,316 +9650,346 @@ @node 起動時の入力モードの指定 @subsection 起動時の入力モードの指定 -@defvr {ユーザ変数} skk-isearch-start-mode +@defvar skk-isearch-start-mode -インクリメンタル・サーチを起動したときの入力モードをこの変数で指定できます。 -以下のいずれかのシンボルを指定できますが、変数 @code{skk-isearch-use-previous-mode} の +インクリメンタル・サーチを起動したときの入力モードをこの変数で指定でき +ます。以下のいずれかのシンボルを指定できますが、変数 @code{skk-isearch-use-previous-mode} の 設定が優先されます。 -@table @code +@itemize +@item +@code{nil} + +カレントバッファで SKK モードが起動されていれば、そのモードを。起動さ +れていなければアスキーモード。 -@item nil -カレントバッファで SKK モードが起動されていれば、そのモードを。 -起動されていなければアスキーモード。 -@item hiragana +@item +シンボル @code{hiragana} かなモード -@item jisx0208-latin - -全英モード -@item latin +@item +シンボル @code{jisx0208-latin} -アスキーモード +全英モード -@end table -@end defvr +@item +シンボル @code{latin} -@defvr {ユーザ変数} skk-isearch-use-previous-mode +アスキーモード +@end itemize +@end defvar -この変数の値が @code{non-nil} であれば、次のインクリメンタル・サーチ起動 -時の入力モードは、前回のインクリメンタル・サーチでの入力モードになります。 -@code{nil} であれば、変数 @code{skk-isearch-start-mode} の設定が優先され -ます。 +@defvar skk-isearch-use-previous-mode -@end defvr +この変数の値が @code{non-nil} であれば、次のインクリメンタル・サーチ起動時の +入力モードは、前回のインクリメンタル・サーチでの入力モードになります。 +@code{nil} であれば、変数 @code{skk-isearch-start-mode} の設定が優先されます。 +@end defvar @node 間に空白等を含む文字列の検索 @subsection 間に空白等を含む文字列の検索 -@cindex Incremental regexp search -@samp{検索} という文字列をインクリメンタル・サーチにより検索する場合に、 -バッファが以下のような状態になっていることがあります。 +「検索」という文字列をインクリメンタル・サーチにより検索する場合に、バッ +ファが以下のような状態になっていることがあります。 @example -@group -------- Buffer: foo -------- この行末から始まる文字列を検 索して下さい。 -------- Buffer: foo -------- -@end group @end example このような場合のために、Emacs は正規表現によるインクリメンタル・サーチを 提供しています。DDSKK はこの正規表現によるインクリメンタル・サーチにも対 応しているため、空白や改行を含んだ検索も可能です。 -@table @kbd - -@item M-x isearch-forward-regexp - -@findex isearch-forward-regexp -@kindex M-x isearch-forward-regexp @kindex C-u C-s @kindex M-C-s +@table @asis +@kindex M-x isearch-forward-regexp +@cindex isearch-forward-regexp +@item @kbd{M-x isearch-forward-regexp} @tie{}@tie{}@tie{}@tie{}(@code{isearch-forward-regexp}) -前方への正規表現によるインクリメンタル・サーチ。 -@kbd{C-u C-s} または @kbd{M-C-s} で起動します。 - -@item M-x isearch-backward-regexp +前方への正規表現によるインクリメンタル・サーチ。 @code{C-u C-s} または @code{M-C-s} で +起動します。 +@end table -@findex isearch-backward-regexp -@kindex M-x isearch-backward-regexp @kindex C-u C-r @kindex M-C-r +@table @asis +@kindex M-x isearch-backward-regexp +@cindex isearch-backward-regexp +@item @kbd{M-x isearch-backward-regexp} @tie{}@tie{}@tie{}@tie{}(@code{isearch-backward-regexp}) -後方への正規表現によるインクリメンタル・サーチ。 -@kbd{C-u C-r} または @kbd{M-C-r} で起動します。 +後方への正規表現によるインクリメンタル・サーチ。 @code{C-u C-r} または @code{M-C-r} で +起動します。 @end table -@c 以下は空白や改行の処理を制御する変数です。 +@defvar skk-isearch-whitespace-regexp -@defvr {ユーザ変数} skk-isearch-whitespace-regexp - -この変数の値は正規表現です。この正規表現にマッチする要素は「正規表現によ -るインクリメンタル・サーチにおいては、単語を区切る要素ではない」と判断さ -れます。この変数のデフォルトは以下のようになっています。 +この変数の値は正規表現です。この正規表現にマッチする要素は「正規表現に +よるインクリメンタル・サーチにおいては、単語を区切る要素ではない」と判 +断されます。この変数の標準設定は以下のようになっています。 @example "\\(\\s \\|[ \t\n\r\f]\\)*" @end example -この変数の値を変更することで、正規表現 -によるインクリメンタル・サーチを拡張することができます。例えば、電子メー -ルの引用部分を検索する場合を考えます。 +この変数の値を変更することで、正規表現によるインクリメンタル・サーチを +拡張することができます。例えば、電子メールの引用部分を検索する場合を考 +えます。 @example > 引用部分も検 > 索できる。 @end example -上記のうち、「検索」という語は 2 行に渡っている上、引用マークが挿入さ -れています。ここで +上記のうち、「検索」という語は 2 行に渡っている上、引用マークが挿入され +ています。ここで @lisp (setq skk-isearch-whitespace-regexp "\\(\\s \\|[ \t\n\r\f<>|]\\)*") @end lisp +@end defvar +@noindent と設定することにより、「検索」を検索できるようになります。 -@end defvr - @node VIP/VIPERとの併用 @section VIP/VIPERとの併用 -@cindex VIP -@cindex VIPER -@cindex @file{vip.el} -@cindex @file{viper.el} -@defvr {ユーザ変数} skk-use-viper -@c XXX VIP 3.7 について言及する。 +VIPER については Info を参照してください。 + +@ref{Top,VIPER Manual,,viper,}. + +また、VIPER の前身である VIP にも対応します。ただし、正式に対応しているバ +ージョンは 3.5 のみです。これは Mule 2.3 に標準添付します @footnote{Viper 対策はまだ行われていません。 @code{~/.viper} に次のように書い +て下さい。 @code{(viper-harness-minor-mode "skk-annotation")}} 。 + +@defvar skk-use-viper + +この変数の値を @code{non-nil} に設定すると、VIPER に対応します。 +@end defvar + +@node picture-modeとの併用 +@section picture-modeとの併用 + +@cindex BS +@cindex move-to-column +@cindex move-to-column-force +@cindex picture.el +@cindex picture-mode + +SKK モードを @code{picture-mode} において使用した場合は、以下のような問題点が +あります。ただし、これらは @code{picture-mode} の問題なので、現在のところ DDSKK 側 +では対処していません。 + +@itemize +@item +SKK モードで全角文字を入力した場合に、 @code{BS} で全角文字を消すことができ +ません。現状では、後方にある文字を消したい場合は、その文字にポイントを +合わせ、 @code{C-c C-d} で一文字ずつ消す必要があります。 + + +@item +コマンド @code{picture-movement-up} や @code{picture-movement-down} により上下に +全角文字を挿入した場合に、桁がずれる場合があります。 +@end itemize + +関数 @code{move-to-column-force} の中で使用されている関数 @code{move-to-column} の +引数として、全角文字を無視した桁数が与えられることがあり、そのときカーソ +ル移動ができないため、これらの問題が生じます。 + +@node ローマ字入力以外の入力方式 +@chapter ローマ字入力以外の入力方式 + +DDSKK は、SKK 旧来のローマ字式かな入力(訓令式、ヘボン式)方式のほか、各 +種キー配列と入力方式に対応しています。 + + +@menu +* AZIK:: +* ACT:: +* TUT-code:: +* かな入力と親指シフト:: +@end menu + +@node AZIK +@section AZIK + +@cindex AZIK + +AZIK (エイズィック)は QWERTY 配列をベースとした拡張ローマ字入力です。 +一般のローマ字入力がそのまま使える上での拡張であることが特徴です。 + +@uref{http://hp.vector.co.jp/authors/VA002116/azik/azikindx.htm, 拡張ローマ字入力『AZIK』・『ACT』で快適な日本語入力を!} + +@defvar skk-use-azik + +この値が @code{non-nil} であれば AZIK 拡張が有効となります。 @code{~/.skk} に + +@lisp +(setq skk-use-azik t) +@end lisp + +と書きます。 +@end defvar + +@defvar skk-azik-keyboard-type + +AZIK で使うときのキーボードのタイプを、シンボルで指定する。 + +@itemize +@item +シンボル @code{jp106} → 日本語 106 キーボード(標準設定) + + +@item +シンボル @code{jp-pc98} → NEC PC-98 キーボード + + +@item +シンボル @code{us101} → 英語キーボード + + +@item +@code{nil} → キーボード依存処理を無効にする +@end itemize +@end defvar + +azik と skk で仕様が重なる部分があるため、 @code{skk-azik.el} では以下のとおり +対応しています。 + +@itemize +@item +キー @code{q} + +AZIK では撥音「ん」を入力するには @code{q} を使うこととされていますが、skk で +は既に @code{q} に @code{skk-toggle-kana} を割り当てています。そのため @code{skk-azik.el} で +は @code{skk-toggle-kana} の実行を + +@itemize +@item +日本語キーボードであれば @code{@@} を、 + -この変数の値を @code{non-nil} に設定すると、VIPER に対応します。 -@end defvr +@item +英語キーボードであれば @code{[} を +@end itemize +それぞれ使用します。 -VIPER については @ref{Top, , VIPER, viper, VIPER Manual}. を参照してください。 -また、VIPER の前身である VIP にも対応します。ただし、正式に対応している -バージョンは 3.5 のみです。これは Mule 2.3 に標準添付します -@footnote{ちなみに、VIP 3.5 の作者は、SKK の原作者でもある佐藤雅彦氏(京 -都大学名誉教授)です。VIP 3.5 の発展版である VIPER は現在もメンテナンスさ -れています。Emacs19, 20 には、VIP 、VIPER とも標準添付します。}。 +@item +キー @code{@@} -@node picture-modeとの併用 -@section picture-modeとの併用 -@cindex @key{BS} -@cindex move-to-column -@cindex move-to-column-force -@cindex @file{picture.el} -@cindex picture-mode +上記のとおり、 @code{skk-toggle-kana} の実行には @code{@@} (日本語キーボード) +や @code{[} (英語キーボード)を使用しますが、skk では既に @code{@@} には「今日の +日付の入力」(プログラム実行変換)を割り当てています。そのため、skk 本 +来の動作には @code{x} を付けて、それぞれ @code{x@@} と @code{x[} で代用できるようにして +あります。 -SKK モードを @code{picture-mode} において使用した場合は、以下のような問 -題点があります。ただし、これらは @code{picture-mode} の問題なので、現在 -のところ DDSKK 側では対処していません。 -@enumerate @item -SKK モードで全角文字を入力した場合に、@key{BS} で全角文字を消すことができ -ません。現状では、後方にある文字を消したい場合は、その文字にポイントを合 -わせ、@kbd{C-c C-d} で一文字ずつ消す必要があります。 +キー @code{l} @item -コマンド @code{picture-movement-up} や @code{picture-movement-down} によ -り上下に全角文字を挿入した場合に、桁がずれる場合があります。 -@end enumerate +キー @code{xx} -関数 @code{move-to-column-force} の中で使用されている関数 -@code{move-to-column} の引数として、全角文字を無視した桁数が与えられるこ -とがあり、そのときカーソル移動ができないため、これらの問題が生じます。 +AZIK では単独の拗音「ゃゅょぁぃぅぇぉゎ」を入力するには @code{l} を前置する +こととされていますが、skk では既に @code{l} に「アスキーモードへの切り替え」 +を割り当てています。そのため @code{skk-azik.el} では、拗音のうち「ぁぃぅぇぉ」 +の入力については @code{xx} を前置することとしています。 -@node ローマ字入力以外の入力方式 -@chapter ローマ字入力以外の入力方式 +@itemize +@item +@code{xxa} → ぁ -DDSKK は、SKK 旧来のローマ字式かな入力 (訓令式、ヘボン式) 方式のほか、各 -種キー配列と入力方式に対応しています。 -@menu -* AZIK:: -* ACT:: -* TUT-code:: -* かな入力と親指シフト:: -@end menu +@item +@code{xxi} → ぃ -@node AZIK -@section AZIK -@cindex AZIK -AZIK (エイズィック) は QWERTY 配列をベースとした拡張ローマ字入力です。 -一般のローマ字入力がそのまま使える上での拡張であることが特徴です。 +@item +@code{xxu} → ぅ -@uref{http://hp.vector.co.jp/authors/VA002116/azik/azikindx.htm, 拡張ローマ字入力『AZIK』・『ACT』で快適な日本語入力を!} -azik と skk で仕様が重なる部分があるため、@file{skk-azik.el} では以下のと -おり対応しています。 -@table @b -@item @kbd{q} - -AZIK では撥音「ん」を入力するには @kbd{q} を使うこととされていますが、skk で -は既に @kbd{q} に @code{skk-toggle-kana} を割り当てています。 - -そのため @file{skk-azik.el} では @code{skk-toggle-kana} の実行を -@itemize @bullet -@item 日本語キーボードであれば @kbd{@@} を、 -@item 英語キーボードであれば @kbd{[} を -@end itemize -それぞれ使用します。 +@item +@code{xxe} → ぇ -@item @kbd{@@} -上記のとおり、@code{skk-toggle-kana} の実行に -は @kbd{@@} (日本語キーボード) や @kbd{[} (英語キーボード) を使用しますが、 -skk では既に @kbd{@@} には「今日の日付の入力」(プログラム実行変換)を割 -り当てています。 - -そのため、skk 本来の動作には @kbd{x} を付けて、それぞれ @kbd{x@@} と、 -@kbd{x[} で代用できるようにしてあります。 - -@item @kbd{l} -@itemx @kbd{xx} - -AZIK では単独の拗音「ゃゅょぁぃぅぇぉゎ」を入力するには @kbd{l} を前置す -ることとされていますが、skk では既に @kbd{l} に「アスキーモードへの切り -替え」を割り当てています。 - -そのため @file{skk-azik.el} では、拗音のうち「ぁぃぅぇぉ」の入力について -は @kbd{xx} を前置することとしています。 - -@itemize @bullet -@item @kbd{xxa} @expansion{} ぁ -@item @kbd{xxi} @expansion{} ぃ -@item @kbd{xxu} @expansion{} ぅ -@item @kbd{xxe} @expansion{} ぇ -@item @kbd{xxo} @expansion{} ぉ -@end itemize - -なお、拗音のうち「ゃゅょゎ」の単独入力は、AZIK 拡張 @file{skk-azik.el} で -はなく、標準 @file{skk-vars.el} です。 -@itemize @bullet -@item @kbd{xya} @expansion{} ゃ -@item @kbd{xyu} @expansion{} ゅ -@item @kbd{xyo} @expansion{} ょ -@item @kbd{xwa} @expansion{} ゎ -@end itemize - -@item @kbd{X} -@itemx 誤った登録の削除 -skk では、▼モードでの @kbd{X} は 関数 @code{skk-purge-from-jisyo} を実行 -しますが、AZIK では X は「シャ行」の入力に使われます。 -そのため、@file{skk-azik.el} での「誤った登録の削除」は、 -▼モードで @kbd{M-x skk-purge-from-jisyo} を実行してください。 +@item +@code{xxo} → ぉ +@end itemize +なお、拗音のうち「ゃゅょゎ」の単独入力は、AZIK 拡張 @code{skk-azik.el} では +なく、標準 @code{skk-vars.el} です。 -関連項目: @w{@ref{誤った登録の削除}} +@itemize +@item +@code{xya} → ゃ -@end table -@defvr {ユーザ変数} skk-use-azik +@item +@code{xyu} → ゅ -この値が @code{non-nil} であれば AZIK 拡張が有効となります。 -@file{~/.skk} に -@lisp -(setq skk-use-azik t) -@end lisp +@item +@code{xyo} → ょ -@noindent -と書きます。 -@end defvr +@item +@code{xwa} → ゎ +@end itemize -@defvr {ユーザ変数} skk-azik-keyboard-type -AZIK で使うときのキーボードのタイプを、シンボルで指定する。 +@item +キー @code{X} -@itemize @bullet -@item @code{'jp106} @expansion{} 日本語 106 キーボード (デフォルト) -@item @code{'jp-pc98} @expansion{} NEC PC-98 キーボード -@item @code{'us101} @expansion{} 英語キーボード -@item @code{nil} @expansion{} キーボード依存処理を無効にする +skk では、▼モードでの @code{X} は 関数 @code{skk-purge-from-jisyo} を実行します +が、AZIK では @code{X} は「シャ行」の入力に使われます。そのため、 @code{skk-azik.el} で +の「誤った登録の削除」は、▼モードで @code{M-x skk-purge-from-jisyo} を実行してください。 +@ref{誤った登録の削除}. @end itemize -@end defvr @node ACT @section ACT -@cindex ACT -ACT は AZIK の考え方を Dvorak 配列に適用し、Dvorak 配列でかなを快適にタ -イプできるように考案された方式です。 +ACT は AZIK の考え方を Dvorak 配列に適用し、Dvorak 配列でかなを快適にタイ +プできるように考案された方式です。 @uref{http://www1.vecceed.ne.jp/~bemu/act/act_index.html, ACT (AZIK on Dvorak)} -@defvr {ユーザ変数} skk-use-act +@defvar skk-use-act -この値が @code{non-nil} であれば ACT 拡張が有効となります。@file{~/.skk} -に +この値が @code{non-nil} であれば ACT 拡張が有効となります。 @code{~/.skk} に @lisp (setq skk-use-act t) @end lisp -@noindent と書きます。 -@end defvr +@end defvar @node TUT-code @section TUT-code -@cindex TUT-code -TUT-code は 2 ストローク系の日本語直接入力方式の一つです。 +TUT-code は、2ストローク系の日本語直接入力方式の一つです。 -@url{http://plone.crew.sfc.keio.ac.jp/groups/tut-code} +@uref{http://plone.crew.sfc.keio.ac.jp/groups/tut-code, TUT-code} 使用するには、SKK のインストール時にいくつかのファイルをインストールする -必要があります。SKK ソースの @file{tut-code} ディレクトリにある -@file{skk-tutcdef.el} と @file{skk-tutcode.el} を、SKK ソースのトップディレクトリにコピーして、SKK のインストールを再度行います。 +必要があります。SKK ソースの @code{tut-code} ディレクトリにある @code{skk-tutcdef.el} と @code{skk-tutcode.el} を +SKK ソースのトップディレクトリにコピーしてから、あらためて SKK をインスト +ールします。 -@xref{DDSKK のインストール}. +@ref{DDSKK のインストール}. -その後、@file{~/.skk} に +その後、 @code{~/.skk} に @lisp (require 'skk-tutcdef) @@ -10180,6 +10000,7 @@ @node かな入力と親指シフト @section かな入力と親指シフト + @cindex かな入力 @cindex 親指シフト @cindex NICOLA @@ -10187,37 +10008,39 @@ DDSKK はローマ字式ではない、いわゆるかな入力方式をサポートします。具体的 には -@itemize @bullet -@item 旧 JIS 配列でのかな入力 -@item 親指シフト方式でのかな入力 +@itemize +@item +旧 JIS 配列でのかな入力 + +@item +親指シフト方式でのかな入力 @end itemize @noindent -に対応しています。これを使うにはまず、nicola-ddskk 拡張パッケージをイン -ストールする必要があります。SKK ソースディレクトリの @file{nicola} ディ -レクトリに移動し、ドキュメントに従ってインストールしてください。 +に対応しています。これを使うにはまず、nicola-ddskk 拡張パッケージをインス +トールする必要があります。SKK ソースの @code{nicola} ディレクトリに移動し、ド +キュメントに従ってインストールしてください。 -@url{https://github.com/skk-dev/ddskk/blob/master/nicola/README.ja} +@uref{https://github.com/skk-dev/ddskk/blob/master/nicola/README.ja} -続いて設定をします。 +@defvar skk-use-kana-keyboard -@defvr {ユーザ変数} skk-use-kana-keyboard - -この変数を @code{non-nil} に設定すると、かな入力サポートが SKK 起動時に有効に -なります。 +この変数を @code{non-nil} に設定すると、かな入力サポートが SKK 起動時に有効 +になります。 @lisp (setq skk-use-kana-keyboard t) @end lisp +@end defvar -@end defvr - -@defvr {ユーザ変数} skk-kanagaki-keyboard-type +@defvar skk-kanagaki-keyboard-type -この変数で、かな入力サポートの種類を切換えます。適切なシンボルを設定してください。 +この変数で、かな入力サポートの種類を切換えます。適切なシンボルを設定し +てください。 -@table @samp -@item 106-jis +@itemize +@item +シンボル @code{106-jis} 日本語 106 キーボード (旧 JIS 配列) でのかな入力に対応します。 @@ -10225,22 +10048,32 @@ (setq skk-kanagaki-keyboard-type '106-jis) @end lisp -@item nicola-jis -日本語 106 キーボード (旧 JIS 配列) での親指シフトエミュレーションに対応 -します。 +@item +シンボル @code{nicola-jis} + +日本語 106 キーボード (旧 JIS 配列) での親指シフトエミュレーションに +対応します。 @lisp (setq skk-kanagaki-keyboard-type 'nicola-jis) @end lisp -@item nicola-us -@item nicola-dvorak +@item +シンボル @code{nicola-us} + + +@item +シンボル @code{nicola-dvorak} + + +@item +シンボル @code{nicola-colemak} -@item nicola-colemak -@item omelet-jis +@item +シンボル @code{omelet-jis} @code{nicola-jis} と同様ですが、より入力しやすい配列が考慮されています。 @@ -10248,40 +10081,49 @@ (setq skk-kanagaki-keyboard-type 'omelet-jis) @end lisp -@item omelet-us -@item omelet-dvorak +@item +シンボル @code{omelet-us} -@item omelet-colemak -@item oasys +@item +シンボル @code{omelet-dvorak} -@end table -@end defvr +@item +シンボル @code{omelet-colemak} + + +@item +シンボル @code{oasys} +@end itemize +@end defvar -かな入力方式使用時の■モードでは以下のコマンドなどが役に立ちます。 +かな入力方式使用時の■モードでは、以下のコマンドなどが役に立ちます。 -@table @kbd -@item F1 1 +@table @asis @kindex F1 1 +@cindex skk-nicola-help? +@item @kbd{F1 1} @tie{}@tie{}@tie{}@tie{}(@code{skk-nicola-help?}) かな入力方式での特殊キー定義の一覧を表示します。 -@item F1 2 @kindex F1 2 +@cindex skk-nicola-2nd-help? +@item @kbd{F1 2} @tie{}@tie{}@tie{}@tie{}(@code{skk-nicola-2nd-help?}) かな入力方式でのかなキー配列を表示します。 -@item F12 -@itemx M-x skk-kanagaki-toggle-rom-kana @kindex F12 -@kindex M-x skk-kanagaki-toggle-rom-kana +@cindex skk-kanagaki-toggle-rom-kana +@item @kbd{F12} @tie{}@tie{}@tie{}@tie{}(@code{skk-kanagaki-toggle-rom-kana}) かな入力方式とローマ字入力方式とを切り換えます。 @end table -なお、親指シフト方式については @uref{http://nicola.sunicom.co.jp/, NICOLA 日本語入力コンソーシアム} が参考になります。 +なお、親指シフト方式については次の url が参考になります。 + +@uref{http://nicola.sunicom.co.jp/, NICOLA 日本語入力コンソーシアム} @node そのほかの拡張機能 @chapter そのほかの拡張機能 @@ -10289,6 +10131,7 @@ 十分にテストされていない等の理由がありますが、便利・有益と思われる拡張機 能を紹介します。 + @menu * 交ぜ書き変換:: @end menu @@ -10296,28 +10139,34 @@ @node 交ぜ書き変換 @section 交ぜ書き変換 -@file{skk-mazegaki.el} をインストールすると、交ぜ書き変換が可能となります。 +@code{skk-mazegaki.el} をインストールすると、交ぜ書き変換が可能となります。 -@itemize @bullet -@item き車 @expansion{} 汽車 -@item き者 @expansion{} 記者 -@item き社 @expansion{} 貴社 +@itemize +@item +き車 → 汽車 + +@item +き者 → 記者 + +@item +き社 → 貴社 @end itemize インストール方法などは、次の投稿を参考にしてください。 -@url{http://mail.ring.gr.jp/skk/201111/msg00037.html} +@uref{http://mail.ring.gr.jp/skk/201111/msg00037.html} + +@node SKK に関する情報 +@chapter SKK に関する情報 -@node SKKに関する情報 -@chapter SKKに関する情報 @menu * 最新情報:: * SKKメーリングリスト:: -* SKK関連ソフトウェア:: -* SKK辞書について:: +* SKK 関連ソフトウェア:: +* SKK 辞書について:: * 辞書ツール:: -* SKKの作者:: +* SKK の作者:: * SKKの歴史:: * このマニュアルについて:: * 謝辞:: @@ -10326,42 +10175,34 @@ @node 最新情報 @section 最新情報 -DDSKK についての最新情報は、 - -@display -@url{http://openlab.jp/skk/} -@end display - -@noindent -から得ることができます。 +DDSKK についての最新情報は @uref{http://openlab.jp/skk/} から得ることができます。 SKK の開発は、 GitHub を利用して行われています。 -@display -@url{https://github.com/skk-dev/ddskk} -@end display +@itemize +@item +@uref{https://github.com/skk-dev/ddskk} +@end itemize 最新版 DDSKK の変更内容と更に過去の変更点については以下のリソースを参照 してください。 -@display -@url{https://github.com/skk-dev/ddskk/blob/master/READMEs/NEWS.ja} -@end display +@itemize +@item +@uref{https://github.com/skk-dev/ddskk/blob/master/READMEs/NEWS.ja} +@end itemize また、将来のバージョンにおける拡張アイディアについては、TODO としてまと められています。 -@display -@url{https://github.com/skk-dev/ddskk/blob/master/READMEs/TODO.ja} -@end display +@itemize +@item +@uref{https://github.com/skk-dev/ddskk/blob/master/READMEs/TODO.ja} +@end itemize SKK Openlab では、開発者、文章の整備にご協力いただける方、テスター、よろ -ずものを言う人などなど、常に募集しています。また要望、拡張の具体的アイディ -アがあれば、メーリングリストに連絡いただけることを期待します。 - -@display -@xref{SKKメーリングリスト}. -@end display +ずものを言う人などなど、常に募集しています。また要望、拡張の具体的アイデ +ィアがあれば、メーリングリストに連絡いただけることを期待します。 @node SKKメーリングリスト @section SKKメーリングリスト @@ -10370,86 +10211,114 @@ 者用などと分かれていない他、SKK 辞書、DDSKK の開発議論が中心ですが、辞書 サーバやフロントエンド、 SKK 辞書ツールの話題なども議論の範囲に入ります。 -@table @asis -@item メーリングリストに参加する +@itemize +@item +メーリングリストに参加する -アドレス @email{skk-subscribe@@ring.gr.jp} 宛てに空のメールを送って下さい。 -確認の為のメッセージが指定されたアドレス宛に送信されます。その確認の為の +アドレス @code{skk-subscribe@@ring.gr.jp} 宛てに空のメールを送って下さい。確 +認の為のメッセージが指定されたアドレス宛に送信されます。その確認の為の メッセージに対して返信することで加入手続きは終了します。 -@item メーリングリストから脱会する -アドレス @email{skk-unsubscribe@@ring.gr.jp} 宛てに空のメールを送って下さ -い。確認の為のメッセージが指定されたアドレス宛に送信されます。その確認の -為のメッセージに対して返信することで脱退手続きは終了します。 +@item +メーリングリストから脱会する + +アドレス @code{skk-unsubscribe@@ring.gr.jp} 宛てに空のメールを送って下さい。 +確認の為のメッセージが指定されたアドレス宛に送信されます。その確認の為 +のメッセージに対して返信することで脱退手続きは終了します。 + -@item 登録したアドレスを変更する +@item +登録したアドレスを変更する 古いアドレスについていったん unsubscribe して、新しいアドレスから再度 subscribe して下さい。 -@item 記事の投稿 -アドレス @email{skk@@ring.gr.jp} へ送ります。メーリングリストに登録されて -いる人全員にメールが配信されます。 +@item +記事の投稿 -@item 過去ログの閲覧 +アドレス @code{skk@@ring.gr.jp} へ送ります。メーリングリストに登録されている +人全員にメールが配信されます。 -@url{http://mail.ring.gr.jp/skk} -@url{news://news.ring.gr.jp/ring.openlab.skk} -@end table +@item +過去ログの閲覧 + +@itemize +@item +@uref{http://mail.ring.gr.jp/skk} +@end itemize +@end itemize -@node SKK関連ソフトウェア -@section SKK関連ソフトウェア +@node SKK 関連ソフトウェア +@section SKK 関連ソフトウェア SKK 関連ソフトウェアに関しては、次の URL にリンクをまとめてありますの で参照してください。 +@itemize +@item @uref{http://openlab.jp/skk/wiki/wiki.cgi?page=%A5%EA%A5%F3%A5%AF%BD%B8, SKK 辞書 Wiki におけるリンク集} +@end itemize -@node SKK辞書について -@section SKK辞書について +@node SKK 辞書について +@section SKK 辞書について SKK 辞書は多くのユーザの方々から提供された辞書によりコピーフリーの辞書と しては最大規模の辞書になっています。今後もこの方式により SKK 辞書をより 充実したものにしていきたいと思います。 -@url{http://openlab.jp/skk/registdic.cgi} にて Web/cgi を利用 -した登録・削除希望フォームを運用しています。 -SKK 辞書に追加したい単語、誤登録として削除したい単語がありましたら、 -是非ご利用下さい。 +@uref{http://openlab.jp/skk/registdic.cgi} にて Web/cgi を利用した登録・削除希望 +フォームを運用しています。SKK 辞書に追加したい単語、誤登録として削除した +い単語がありましたら、是非ご利用下さい。 -@node 辞書ツール +@node 辞書ツール @section 辞書ツール -SKK 辞書に関するツールには、Perl, C, Ruby の各言語により書かれたツールがありますが、Perl によるツールは現在十分メンテナンスされていません。 +SKK 辞書に関するツールには、Perl, C, Ruby の各言語により書かれたツールが +ありますが、Perl によるツールは現在十分メンテナンスされていません。 現在は C, Ruby のツールが開発・メンテナンスされています。 +@itemize +@item @uref{http://openlab.jp/skk/wiki/wiki.cgi?page=%BC%AD%BD%F1%A5%E1%A5%F3%A5%C6%A5%CA%A5%F3%A5%B9%A5%C4%A1%BC%A5%EB, 辞書メンテナンスツール} +@end itemize + +@node SKK の作者 +@section SKK の作者 -@node SKKの作者 -@section SKKの作者 +SKK の原作者は、現京都大学名誉教授の佐藤雅彦氏です。 -SKK の原作者は、現京都大学名誉教授の -@uref{http://www.ist.i.kyoto-u.ac.jp/organization/ex-professor.html#Sato, -佐藤雅彦氏}です。 +@itemize +@item +@uref{http://www.ist.i.kyoto-u.ac.jp/organization/ex-professor.html#Sato} +@end itemize 現在の DDSKK は、大勢のボランティアの貢献により成立しています。 -ファイル @file{READMEs/Contributors} に貢献者名の一覧がありますので、ご覧ください。 +ファイル @code{READMEs/Contributors} に貢献者名の一覧がありますので、ご覧ください。 @node SKKの歴史 @section SKKの歴史 SKK の成り立ちと歴史に関しては以下の URL を参照してください。 +@itemize +@item @uref{http://openlab.jp/skk/born-ja.html, SKK の誕生秘話} -@uref{http://openlab.jp/skk/SKK.html, ``SKK = I''} -@uref{http://openlab.jp/skk/history-ja.html, SKK の歴史 (付 Emacs の歴史の一部)} +@item +@uref{http://openlab.jp/skk/SKK.html, @math{SKK = I}} + + +@item +@uref{http://openlab.jp/skk/history-ja.html, SKK の歴史(付 Emacs の歴史の一部)} + +@item @uref{http://mail.ring.gr.jp/skk/201212/msg00007.html, SKK の 25年} +@end itemize @node このマニュアルについて @section このマニュアルについて @@ -10460,16 +10329,16 @@ @node 謝辞 @section 謝辞 -DDSKK の開発は、@uref{http://openlab.jp, Ring Server Open -Laboratory} (オープンラボラトリ) に @samp{SKK Openlab} として参加する形 -で行われています。@samp{SKK Openlab} は Ring から共有ディスク、CVS 及び -ML の提供を受けています。オープンラボラトリの運営は、完全にボランティア -により行われております。Ring 並びにオープンラボラトリにかかわる皆さんに +DDSKK の開発は、@uref{http://openlab.jp, Ring Server Open Laboratory} (オープンラボラトリ)に SKK Openlab と +して参加する形で行われています。SKK Openlab は Ring から共有ディスク、CVS 及 +び ML の提供を受けています。オープンラボラトリの運営は、完全にボランティ +アにより行われております。Ring 並びにオープンラボラトリにかかわる皆さんに 深く感謝いたします。 -(以降の記載は、SKK の原作者、佐藤雅彦教授により記載された旧来のマニュア -ルのものですが、歴史的意義を踏まえて、そのまま掲載します。) +以降の記載は、SKK の原作者、佐藤雅彦教授により記載された旧来のマニュア +ルのものですが、歴史的意義を踏まえて、そのまま掲載します。 +@quotation SKK の設計方針は TAO/ELIS 上の日本語入力システム Kanzen の影響を受けてい ます。Kanzen のデモを行ってくださり、また Kanzen を使う機会を与えてくだ さった NTT の竹内郁雄さんに感謝します。 @@ -10482,22 +10351,25 @@ た方々に感謝します。 SKK 辞書第 6, 7 版作成にあたり協力してくださった高橋裕信氏に感謝します。 +@end quotation -@node よくある質問とその回答(FAQ) -@chapter よくある質問とその回答(FAQ) +@node よくある質問とその回答 (FAQ) +@chapter よくある質問とその回答 (FAQ) これは SKK に対するよくある質問と、それに対する回答集です。 + @menu -* Introduction:: SKK のなぜなに。 -* Installation:: SKK の入手から導入まで。 -* Customization:: SKK の基本設定からお好みのカスタマイズまで。 -* Dictionaries:: SKK 辞書関連。 -* Miscellaneous:: SKK の活用法その他。 +* Introduction:: +* Installation:: +* Customization:: +* Dictionaries:: +* Miscellaneous:: @end menu @node Introduction -@section SKK のなぜなに +@section Introduction + @menu * Q1-1 Daredevil SKK って SKK とは違うのですか?:: @@ -10508,77 +10380,76 @@ @end menu @node Q1-1 Daredevil SKK って SKK とは違うのですか? -@unnumberedsubsec Q1-1 Daredevil SKK って SKK とは違うのですか? +@subsection Q1-1 Daredevil SKK って SKK とは違うのですか? -SKK Openlab で開発、リリースされる SKK は、京大の佐藤先生が中心になっ -て開発していた SKK と区別するために、@samp{Daredevil SKK} と呼ぶことに -しました。その略称は @samp{DDSKK} で、SKK Openlab で最初に -@samp{Daredevil SKK} としてリリースされた version は 11.1 です (オリジ -ナルの version を継承しました)。 - -なお、@samp{Daredevil} の名前の採択は、開発陣の一人が講読している某ラ -ジオ英会話講座の、ある日のスキット名が「Daredevil なんとか」で、その内 -容は「とにかくやってみよう。うぎゃぁぁぁ、やられたぁ」というものでした。 -これがあまりに自分の開発ポリシーに合致していた、ということに由来します。 +SKK Openlab で開発、リリースされる SKK は、京大の佐藤先生が中心になって開 +発していた SKK と区別するために、 @code{Daredevil SKK} と呼ぶことにしました。 +その略称は @code{DDSKK} で、SKK Openlab で最初に @code{Daredevil SKK} としてリリー +スされた version は 11.1 です(オリジナルの version を継承しました)。 + +なお、 @code{Daredevil} の名前の採択は、開発陣の一人が講読している某ラジオ英会 +話講座の、ある日のスキット名が「Daredevil なんとか」で、その内容は「とに +かくやってみよう。うぎゃぁぁぁ、やられたぁ」というものでした。これがあま +りに自分の開発ポリシーに合致していた、ということに由来します。 @node Q1-2 SKK はシンプルなのが長所だったのでは? -@unnumberedsubsec Q1-2 SKK はシンプルなのが長所だったのでは? +@subsection Q1-2 SKK はシンプルなのが長所だったのでは? かような議論は 10 年来行われてきており、結論は出ていませんが、事実として -現在まで開発が続けられています。 - -@display -「シンプルな操作性の維持と多機能化・高機能化は両立できる」 -@end display - -@noindent -というのが現在の開発陣の考えであるようです。 +現在まで開発が続けられています。「シンプルな操作性の維持と多機能化・高機 +能化は両立できる」というのが現在の開発陣の考えであるようです。 SKK が Simple Kana to Kanji conversion program の略であるとおり、かなを漢 -字に変換するルーチンの簡単さが SKK を定義付けています。その周辺の拡張に -関する制約は基本的にはありません。 +字に変換するルーチンの簡単さが SKK を定義付けています。その周辺の拡張に関 +する制約は基本的にはありません。 -多機能化と言っても多くはユーザオプションによって無効にすることができま -すし、@file{skk.el} 本体が複雑化しないようにモジュール化されています。 +多機能化と言っても多くはユーザオプションによって無効にすることができます +し、 @code{skk.el} 本体が複雑化しないようにモジュール化されています。 @node Q1-3 DDSKK はどの Emacs で使えますか? -@unnumberedsubsec Q1-3 DDSKK はどの Emacs で使えますか? - -基本的には、GNU Emacs と Mule 機能付きの XEmacs で使えます。 +@subsection Q1-3 DDSKK はどの Emacs で使えますか? -対応する Emacs のバージョンについては以下をご覧ください。 +基本的には、GNU Emacs と Mule 機能付きの XEmacs で使えます。対応する Emacs の +バージョンについては以下をご覧ください。 -@display -@xref{このバージョンのSKKについて}. -@end display +@ref{このバージョンの SKK について}. @node Q1-4 DDSKK はどんなオペレーティングシステムで使えますか? -@unnumberedsubsec Q1-4 DDSKK はどんなオペレーティングシステムで使えますか? +@subsection Q1-4 DDSKK はどんなオペレーティングシステムで使えますか? + +SKK がサポートしている Emacs がその OS で動いているなら、SKK の基本的な機 +能は動くはずです。 Microsoft Windows でも Apple macOS でも使えます。 + +拡張機能については、UNIX の各種コマンドを前提としているものがいくつかあり +ます( @code{look} や @code{ispell} など)。これらのコマンドがお使いの OS にも存在 +すれば該当の拡張機能も基本的には使えるでしょう。 -SKK がサポートしている Emacs がその OS で動いているなら、SKK の基本的 -な機能は動くはずです。 Microsoft Windows でも Apple OS X でも使えます。 +Apple macOS 版 Emacs に特化した情報については、以下のファイルを参照してください。 -拡張機能については、UNIX の各種コマンドを前提としているものがいくつか -あります (@command{look} や @command{ispell} など)。これらのコマンドがお使いの OS にも -存在すれば該当の拡張機能も基本的には使えるでしょう。 - -Apple OS X 版 Emacs に特化した情報については、以下のファイルを参照してください。 -@display -@url{https://github.com/skk-dev/ddskk/blob/master/READMEs/README.MacOSX.ja} -@end display +@itemize +@item +@uref{https://github.com/skk-dev/ddskk/blob/master/READMEs/README.MacOSX.ja} +@end itemize @node Q1-5 APEL って何? 必要ですか? -@unnumberedsubsec Q1-5 APEL って何? 必要ですか? +@subsection Q1-5 APEL って何? 必要ですか? -APEL は A Portable Emacs Library の略です。APEL の主な機能は異なる Emacs -間の非互換性を吸収することです。 +APEL は A Portable Emacs Library の略です。APEL の主な機能は、異なる Emacs 間 +の非互換性を吸収することです。 +@itemize +@item XEmacs では APEL が必要です。 -GNU Emacs 22 以上では APEL は不要となりました。この変更は 2010 年 9 月に CVS に commit され、2011 年 1 月に DDSKK 14.2 としてリリースされました。 + +@item +GNU Emacs 22 以上では APEL は不要となりました。この変更は 2010 年 9 月 +に CVS に commit され、2011 年 1 月に DDSKK 14.2 としてリリースされました。 +@end itemize @node Installation -@section SKK の入手から導入まで +@section Installation + @menu * Q2-1 SKK を使うのに何が必要ですか?:: @@ -10587,45 +10458,27 @@ @end menu @node Q2-1 SKK を使うのに何が必要ですか? -@unnumberedsubsec Q2-1 SKK を使うのに何が必要ですか? - -SKK 本体と SKK 辞書が必要です。オプションで辞書サーバを用意す -ることができます。 -XEmacs では事前に APEL をインストールしてください。 +@subsection Q2-1 SKK を使うのに何が必要ですか? -@display -@xref{XEmacs へのインストール}. -@end display +SKK 本体と SKK 辞書が必要です。オプションで辞書サーバを用意することができ +ます。XEmacs では事前に APEL をインストールしてください。 -SKK 本体は以下から入手できます。 - -@display -@url{http://openlab.jp/skk/maintrunk} -@end display +@ref{XEmacs へのインストール}. @node Q2-2 SKK 辞書はどこにありますか? -@unnumberedsubsec Q2-2 SKK 辞書はどこにありますか? - -以下を参照してください。 +@subsection Q2-2 SKK 辞書はどこにありますか? -@display -@xref{SKK辞書について}. -@end display +@ref{SKK 辞書について}. @node Q2-3 SKK サーバはどこにありますか? -@unnumberedsubsec Q2-3 SKK サーバはどこにありますか? +@subsection Q2-3 SKK サーバはどこにありますか? DDSKK は辞書サーバの種類、バージョンには依存していません。 - -@display -@url{http://openlab.jp/skk/skkserv-ja.html} -@end display - -@noindent -からお好きな辞書サーバを入手して下さい。 +@uref{http://openlab.jp/skk/skkserv-ja.html} からお好きな辞書サーバを入手して下さい。 @node Customization -@section SKK の基本設定からお好みのカスタマイズまで +@section Customization + @menu * Q3-1 「.」、「,」 が入力できるようにカスタマイズしたいのですが。:: @@ -10638,264 +10491,239 @@ @end menu @node Q3-1 「.」、「,」 が入力できるようにカスタマイズしたいのですが。 -@unnumberedsubsec Q3-1 「.」、「,」 が入力できるようにカスタマイズしたいのですが。 +@subsection Q3-1 「.」、「,」 が入力できるようにカスタマイズしたいのですが。 -3通りの方法を紹介します。 +3通りの方法を紹介します。 -@enumerate +@itemize @item -通常 @samp{.} で「.」、@samp{,} で「,」を入力したい場合 +通常 @code{.} で「.」を、 @code{,} で「,」を入力したい場合 -@file{~/.skk} に以下を設定します。 +@code{~/.skk} に以下を設定します。 @lisp (setq skk-kutouten-type 'en) @end lisp + @item -一時的に @samp{.} で「.」、@samp{,} で「,」を入力したい場合 +一時的に @code{.} で「.」を、 @code{,} で「,」を入力したい場合 + +@code{M-x skk-toggle-kutouten} を実行すると、その場で「,」「.」に切り替え +ることができます。「、」「。」に戻すには、もう一度 @code{M-x skk-toggle-kutouten} を +実行します。 -@kbd{M-x skk-toggle-kutouten} を実行すると、その場で「,」「.」に切り替える -ことができます。「、」「。」に戻すには、もう一度 -@kbd{M-x skk-toggle-kutouten} を実行を実行します。 -特定のバッファでのみ「,」「.」に切り替えたい場合は、 File Variables -(@pxref{File Variables, , File Variables, emacs, GNU Emacs Manual}) -を参照下さい。 -例えば、 tex モードでのみ「,」「.」に切り替えたい場合は、つぎの設定を -tex ファイルの最後に追加します。 +特定のバッファでのみ「,」「.」に切り替えたい場合は Info を参照下さい。 + +@ref{File Variables,Local Variables in Files in GNU Emacs Manual,,emacs,}. + +例えば、 tex モードでのみ「,」「.」に切り替えたい場合は、次の設定 +を tex 文書ファイルの最後に追加します。 @example % Local Variables: -% skk-kutouten-type: en +% skk-kutouten-type: en % end: @end example -@item -常に @samp{.} で「.」、@samp{,} で「,」を入力したい場合 -@code{skk-rom-kana-rule-list} を直接変更します。 -なお、この設定をすると、@kbd{M-x skk-toggle-kutouten} での切り替えが -効かなくなるので、注意して下さい。 +@item +常に @code{.} で「.」を、 @code{,} で「,」を入力したい場合 -@file{~/.skk} に以下を追加します。 +@code{skk-rom-kana-rule-list} を直接変更します。なお、この設定をすると、 @code{M-x skk-toggle-kutouten} で +の切り替えが効かなくなるので、注意して下さい。 @code{~/.skk} に以下を追加します。 @lisp -@group (setq skk-rom-kana-rule-list (append '(("." nil ".") ("," nil ",")) skk-rom-kana-rule-list)) -@end group @end lisp -この設定方法は応用が効き、細かく制御することが可能です。 -@samp{.} と @samp{,} のところをそれぞれ、@samp{.} と @samp{,} とすることで、 -「かなモード」「カナモード」でも、@samp{.} と@samp{,} を直接入力することが -できます。 -@end enumerate +この設定方法は応用が効き、細かく制御することが可能です。「.」と「,」 +のところをそれぞれ @code{.} と @code{,} とすることで、「かなモード」「カナモード」 +でも @code{.} と @code{,} を直接入力することができます。 +@end itemize @node Q3-2 「ゐ」や「ヰ」 が入力できるようにカスタマイズしたいのですが。 -@unnumberedsubsec Q3-2 「ゐ」や「ヰ」 が入力できるようにカスタマイズしたいのですが。 +@subsection Q3-2 「ゐ」や「ヰ」 が入力できるようにカスタマイズしたいのですが。 -一つ前の Q の変形問題ですね。かな/カナモードでそれぞれ出力する文字 -を変えるやり方です。 - -@file{~/.skk} に +一つ前の Q の変形問題ですね。かなモード/カナモードでそれぞれ出力する文字 +を変えるやり方です。 @code{~/.skk} に @lisp -@group (setq skk-rom-kana-rule-list (append '(("wi" nil ("ヰ" . "ゐ"))) skk-rom-kana-rule-list)) -@end group @end lisp @noindent -と書いてみましょう。 - -一番内側の cons cell は car がカナモード、cdr がかなモー -ドでの入力文字を表しています。 +と書いてみましょう。一番内側の cons cell は car がカナモード、cdr がかな +モードでの入力文字を表しています。 -一つ前の Q に対する答えのように、カナモード、かなモードともに入力す -る文字が変わらなければ、cons cell の代りに文字列を書くことができます。 +一つ前の Q に対する答えのように、カナモード、かなモードともに入力する文字 +が変わらなければ、cons cell の代りに文字列を書くことができます。 @node Q3-3 検索する辞書を増やしたいのですが。 -@unnumberedsubsec Q3-3 検索する辞書を増やしたいのですが。 +@subsection Q3-3 検索する辞書を増やしたいのですが。 -@code{skk-search-prog-list} で設定をしましょう。 @vindex skk-search-prog-list +@code{skk-search-prog-list} で設定をしましょう。 -まず、現在の設定を確認しましょうね。*scratch* バッファに -@code{skk-search-prog-list} と書いてそのシンボルの末尾にポイントを置いて -@kbd{C-j} してみましょう。例えば次のように出力されます。 +まず、現在の設定を確認しましょうね。*scratch*バッファに @code{skk-search-prog-list} と +書いてそのシンボルの末尾にポイントを置いて @code{C-j} してみましょう。例えば次 +のように出力されます。 @lisp -@group ((skk-search-jisyo-file skk-jisyo 0 t) (skk-search-server skk-aux-large-jisyo 10000)) -@end group @end lisp -上記の例は 2 つの要素を持ったリストになっています。設定によりもっと多 -くの要素があるかもしれません。 - -各要素は検索する関数と辞書を指定したリストです。要素の順番に検索がなさ -れます。上記の例だとまず最初に @code{skk-jisyo} (個人辞書) を -@code{skk-search-jisyo} という関数を使ってリニアサーチ、次に -@code{skk-search-server} という関数を使って @code{skk-aux-large-jisyo} -をサーチします。 - -変換の際、@key{SPC} を押しますよね? 1 回 @key{SPC} を押すと、SKK は候 -補が見つかるまでの間、@code{skk-search-prog-list} の要素を前から読んでいっ -て検索を行い、見つかればそこでいったん検索を止めてユーザに候補を提示します。 +上記の例は2つの要素を持ったリストになっています。設定によりもっと多くの +要素があるかもしれません。 -ユーザが @key{SPC} を更に押してゆき最初の要素のプログラムが見つけた候補が尽 -きると、SKK は中断していた個所から再び @code{skk-search-prog-list} の次 -の要素を見つけ、ここで指定されている関数を使って検索する、で新しい候補が -見つかればまた提示する、というシステムになっています。 - -では、辞書サーバを使って検索した後に、JIS 第 2 水準の単漢字辞書、 -@file{SKK-JISYO.JIS2} を検索したい場合はどうすれば良いでしょう? もう分 -かりますよね? 辞書サーバを使った検索式の次に第 2 水準辞書の検索式を書いた -リストを @code{skk-search-prog-list} に指定すれば良いのです。 -@file{~/.skk} に次のように書きましょう。 +各要素は検索する関数と辞書を指定したリストです。要素の順番に検索がなされ +ます。上記の例だとまず最初に @code{skk-jisyo} (個人辞書)を @code{skk-search-jisyo} と +いう関数を使ってリニアサーチし、次に @code{skk-search-server} という関数を +使って @code{skk-aux-large-jisyo} をサーチします。 + +変換の際、 @code{SPC} を押しますよね? 1回 @code{SPC} を押すと、SKK は候補が見つ +かるまでの間、 @code{skk-search-prog-list} の要素を前から読んでいって検索を行 +い、見つかればそこでいったん検索を止めてユーザに候補を提示します。 + +ユーザが @code{SPC} を更に押してゆき最初の要素のプログラムが見つけた候補が尽き +ると、SKK は中断していた個所から再び @code{skk-search-prog-list} の次の要素を +見つけ、ここで指定されている関数を使って検索する、で新しい候補が見つかれ +ばまた提示する、というシステムになっています。 + +では、辞書サーバを使って検索した後に、JIS 第2水準の単漢字辞書 @code{SKK-JISYO.JIS2} を +検索したい場合はどうすれば良いでしょう? もう分かりますよね? 辞書サーバ +を使った検索式の次に第2水準辞書の検索式を書いたリストを @code{skk-search-prog-list} に +指定すれば良いのです。 @code{~/.skk} に次のように書きましょう。 @lisp -@group (setq skk-search-prog-list '((skk-search-jisyo-file skk-jisyo 0 t) (skk-search-server skk-aux-large-jisyo 10000) (skk-search-jisyo-file "~/dic/SKK-JISYO.JIS2" 0))) -@end group @end lisp -@code{skk-search-jisyo-file} の第 2 引数、0 の数字はリニアサーチにて検索 -するよう指定しています。第 2 水準辞書はあまり大きくないので、リニアサー -チで十分でしょう。大きな辞書を検索する場合などは、 +@code{skk-search-jisyo-file} の第2引数である 0 の数字でリニアサーチにて検索 +するよう指定しています。第2水準辞書はあまり大きくないので、リニアサーチ +で十分でしょう。大きな辞書を検索する場合などは、 @lisp (skk-search-jisyo-file "~/dic/SKK-JISYO.L" 10000) @end lisp @noindent -のようにすると良いでしょう。SKK は Emacs のバッファに読み込まれた -@file{~/dic/SKK-JISYO.L} の検索リージョンのポイント差が 10,000 未満にな -るまではバイナリサーチを行い、その後リニアサーチを行います。大きな辞 -書ではバイナリサーチを行う方がはるかに効率が良いです。嘘だと思うなら、 -@file{SKK-JISYO.L} を読み込んでリニアサーチするような設定にして試してみ -て下さい。 +のようにすると良いでしょう。SKK は Emacs のバッファに読み込まれた辞書の検 +索リージョンのポイント差が 10,000 未満になるまではバイナリサーチを行い、 +その後リニアサーチを行います。大きな辞書ではバイナリサーチを行う方がはる +かに効率が良いです。 -ちなみに、@file{SKK-JISYO.JIS2} は、最大でもリージョン間のポイント差が -8,500 程度です。 +ちなみに、 @code{SKK-JISYO.JIS2} は、最大でもリージョン間のポイント差が 8,500 程 +度です。 @node Q3-4 左手の小指を SHIFT で酷使したくありません。 -@unnumberedsubsec Q3-4 左手の小指を SHIFT で酷使したくありません。 - -SKK を標準の状態で使っている場合、変換のためにシフトキーを多用しますの -で小指への負担が大きくなります。 -@footnote{このため、ある人々は SKK を小指キラーと呼びます。} +@subsection Q3-4 左手の小指を SHIFT で酷使したくありません。 -この苦しみを回避するためにここでは 4 つの方法を紹介します。 +SKK を標準の状態で使っている場合、変換のためにシフトキーを多用しますので +小指への負担が大きくなります。この苦しみを回避するためにここでは4つの方 +法を紹介します。 -@enumerate +@vindex key-translation-map +@itemize @item 親指の近くにあるキーを利用してシフトキーの代用とする。 -日本語 106 キーボードのように無変換、変換などのキーがある場合は、これ -らをシフトキーの代用とすることが可能です。こうすると、例えば +日本語 106 キーボードのように「無変換」、「変換」などのキーがある場合は、 +これらをシフトキーの代用とすることが可能です。こうすると、例えば -@display -@key{SHIFT} を押しながら @kbd{a} を押す -@end display +@example +SHIFT を押しながら a を押す +@end example -@noindent というキー操作は -@display -@key{無変換} を押して、その後で @kbd{a} を押す -@end display +@example + 「無変換」を押して、その後で a を押す +@end example -@noindent という操作で置き換えることができるようになります。 -それでは具体的なやり方を説明しましょう。まず、使用中の Emacs が無変換 -キーを何という名前で認識しているか調べます。それには +それでは具体的なやり方を説明しましょう。まず、使用中の Emacs が「無変換 +キー」を何という名前で認識しているか調べます。それには @example -@kbd{M-x describe-key} +M-x describe-key @end example -@noindent -というコマンドを実行し、続いて 無変換キーを押してみます。XFree86 上で -なら、おそらく +というコマンドを実行し、続いて「無変換キー」を押してみます。X Window System 上 +であれば、おそらく @example muhenkan is undefined @end example -@noindent -という答えが返ってくるでしょう。次に、この名前を使って @file{~/.emacs.d/init.el} -に設定を書きこみます。以下は @key{無変換} = @key{muhenkan} の場合の例で -す。 +という答えが返ってくるでしょう。次に、この名前を使って @code{~/.emacs.d/init.el} +に設定を書きこみます。以下は「無変換キー」 = @code{muhenkan} の場合の例です。 @lisp -@group (unless (keymapp key-translation-map) (setq key-translation-map (make-sparse-keymap))) - (let ((i ?a)) (while (<= i ?z) (define-key key-translation-map (vector 'muhenkan i) (vector (- i 32))) (setq i (1+ i)))) -@end group @end lisp -@vindex key-translation-map -この設定を終えると、@kbd{@key{muhenkan}-a} で @kbd{A} が入力できるように -なります。続いて SKK を起動してみましょう。@kbd{@key{muhenkan}-a} で -@samp{▽あ} となります。送りの開始点も、もちろん同様の操作で指定できます。 -@footnote{変数 @code{key-translation-map} の意味を調べてみてください。 +この設定を終えると、 @code{muhenkan-a} で @code{A} が入力できるようになります。 +続いて SKK を起動してみましょう。 @code{muhenkan-a} で + +@example + ▽あ* +@end example -@kbd{M-x describe-variable} @key{RET} key-translation-map} +となります。送りの開始点も、もちろん同様の操作で指定できます。 +@end itemize +@cindex xmodmap +@itemize @item xmodmap を使う。 -X Window System 上では、@command{xmodmap} というプログラムを使ってキー配列を変更で -きます。例えば、無変換キーをシフトキーとして使いたければ -@cindex xmodmap +X Window System 上では、 @code{xmodmap} というプログラムを使ってキー配列を変 +更できます。例えば、「無変換キー」をシフトキーとして使いたければ @example % xmodmap -e 'add Shift = Muhenkan' @end example -@noindent -とします。これで無変換キーは通常のシフトキーと同じような感じで使えるよ +とします。これで「無変換キー」は通常のシフトキーと同じような感じで使えるよ うになります。 -@item -@file{skk-sticky.el} を使う。 - -@w{@xref{変換位置の指定方法}.} @item -親指シフト入力のエミュレーション機能を利用する。 -@cindex 親指シフト入力 - -これは 1, 2 とはかなり違ったアプローチです。SKK 本来のローマ字的入力を捨 -てて、富士通のワープロ OASYS のような親指シフト入力を修得します。 -@footnote{親指シフト入力の詳細については、ここでは述べません。興味がある -場合は、日本語入力コンソーシアムの Web サイト +@code{skk-sticky.el} を使う。 -@display -@url{http://nicola.sunicom.co.jp/} -@end display +@ref{変換位置の指定方法}. +@end itemize -@noindent -を訪れてください。} +@cindex 親指シフト入力 @cindex OASYS @cindex NICOLA @cindex 日本語入力コンソーシアム +@itemize +@item +親指シフト入力のエミュレーション機能を利用する。 + +これは前述した方法とはかなり違ったアプローチです。SKK 本来のローマ字的 +入力を捨てて、富士通のワープロ OASYS のような親指シフト入力 @footnote{親指シフト入力の詳細については、ここでは述べません。興味がある +場合は、Web サイトを訪れてください。 + +@uref{http://nicola.sunicom.co.jp/, 日本語入力コンソーシアム}} を +修得します 。 DDSKK には NICOLA-DDSKK というプログラムが付属しており、これをインストー ルすると親指シフト入力が可能になります。インストール自体は簡単で、 @@ -10905,48 +10733,44 @@ % make install @end example -@noindent -とした後に、@file{~/.skk} に +とした後に、 @code{~/.skk} に @lisp -@group (setq skk-use-kana-keyboard t) (setq skk-kanagaki-keyboard-type 'omelet-jis) -@end group @end lisp -@noindent -と書くだけです。詳しいことは、NICOLA-DDSKK 付属のドキュメントを参照し -てください。 +と書くだけです。詳しいことは、NICOLA-DDSKK 付属のドキュメントを参照して +ください。 -NICOLA 配列は、特別に日本語入力のために考えられた配列なので、慣れれば -非常に効率的な日本語入力ができるようになると期待されます。一方で、ロー -マ字的入力方式に慣れてしまっている人にとっては、NICOLA 配列に慣れるま -でかなり練習を要することは確かです。 -@end enumerate +NICOLA 配列は、特別に日本語入力のために考えられた配列なので、慣れれば非 +常に効率的な日本語入力ができるようになると期待されます。一方で、ローマ +字的入力方式に慣れてしまっている人にとっては、NICOLA 配列に慣れるまでか +なり練習を要することは確かです。 +@end itemize @node Q3-5 全く漢字が出てきません。 -@unnumberedsubsec Q3-5 全く漢字が出てきません。 +@subsection Q3-5 全く漢字が出てきません。 恐らく辞書の設定ができていないのでしょう。 -@file{SKK-JISYO.L} というファイルがインストールされている場所を確認して -ください。普通は +@code{SKK-JISYO.L} というファイルがインストールされている場所を確認してくださ +い。普通は -@display -@file{/usr/local/share/skk} -@file{/usr/share/skk} -@end display +@example +/usr/local/share/skk +/usr/share/skk +@end example @noindent といった場所にインストールされています。XEmacs のパッケージならば -@display -@file{/usr/local/lib/xemacs/mule-packages/etc/skk} -@end display +@example +/usr/local/lib/xemacs/mule-packages/etc/skk +@end example @noindent -などを確認します。その後で @file{~/.skk} に +などを確認します。その後で @code{~/.skk} に @lisp (setq skk-large-jisyo "/usr/local/share/skk/SKK-JISYO.L") @@ -10959,52 +10783,43 @@ 辞書サーバの設定や、それがちゃんと起動しているかどうかを確認してくださ い。 -また、どこにも辞書がインストールされていない場合は - -@display -@url{http://openlab.jp/skk/dic/} -@end display - -@noindent -から取得します。 +また、どこにも辞書がインストールされていない場合は @uref{http://openlab.jp/skk/dic/} か +ら取得します。 @node Q3-6 チュートリアルが起動できません。 -@unnumberedsubsec Q3-6 チュートリアルが起動できません。 -@cindex チュートリアル +@subsection Q3-6 チュートリアルが起動できません。 -@file{SKK.tut} というファイルがインストールされている場所を確認してくだ -さい。普通は +@code{SKK.tut} というファイルがインストールされている場所を確認してください。 +普通は -@display -@file{/usr/local/share/skk} -@file{/usr/share/skk} -@end display +@example +/usr/local/share/skk +/usr/share/skk +@end example @noindent といった場所にインストールされています。XEmacs のパッケージならば -@cindex パッケージ -@display -@file{/usr/local/lib/xemacs/mule-packages/etc/skk} -@end display +@example +/usr/local/lib/xemacs/mule-packages/etc/skk +@end example @noindent -などを確認します。その後で @file{~/.emacs.d/init.el} に +などを確認します。その後で @code{~/.emacs.d/init.el} に @lisp (setq skk-tut-file "/usr/local/share/skk/SKK.tut") @end lisp -@vindex skk-tut-file @noindent のように設定します。 @node Q3-7 C-x C-j で dired が起動してしまいます。 -@unnumberedsubsec Q3-7 C-x C-j で dired が起動してしまいます。 +@subsection Q3-7 C-x C-j で dired が起動してしまいます。 -@code{dired-x} を読み込むと @kbd{C-x C-j} が @code{dired-jump} にバインドされます。 -この状態でも SKK を @kbd{C-x C-j} で起動したいときは、変数 @code{dired-bind-jump} に -@code{nil} を設定します。 +@code{dired-x} を読み込むと @code{C-x C-j} が @code{dired-jump} にバインドされます。この +状態でも SKK を @code{C-x C-j} で起動したいときは、変数 @code{dired-bind-jump} に @code{nil} を +設定します。 @lisp (setq dired-bind-jump nil) @@ -11013,7 +10828,8 @@ なお、この設定は @code{dired-x} を読み込む前である必要があります。 @node Dictionaries -@section SKK 辞書関連 +@section Dictionaries + @menu * Q4-1 SKK には郵便番号辞書がありますか?:: @@ -11023,66 +10839,41 @@ @end menu @node Q4-1 SKK には郵便番号辞書がありますか? -@unnumberedsubsec Q4-1 SKK には郵便番号辞書がありますか? - -CVS から辞書を取得した場合は、@file{zipcode} というディレクトリに入って -います。WWW では、 - -@display -@url{http://openlab.jp/skk/dic/} -@end display - -@noindent -より入手できます。使用方法は +@subsection Q4-1 SKK には郵便番号辞書がありますか? -@display -@url{http://openlab.jp/skk/skk/dic/zipcode/README.ja} -@end display - -@noindent -を御覧下さい。 +CVS から辞書を取得した場合は、 @code{zipcode} というディレクトリに入って +います。WWW では、 @uref{http://openlab.jp/skk/dic/} より入手できます。使用方法 +は @uref{http://openlab.jp/skk/skk/dic/zipcode/README.ja} を御覧下さい。 @node Q4-2 SKK の辞書には、品詞情報がないんですね。 -@unnumberedsubsec Q4-2 SKK の辞書には、品詞情報がないんですね。 -@cindex 品詞情報 +@subsection Q4-2 SKK の辞書には、品詞情報がないんですね。 -SKK は漢字とかなとの区切りをユーザが指定する方式により、品詞情報を使っ -た解析を用いることなく効率的入力ができます。 +SKK は漢字とかなとの区切りをユーザが指定する方式により、品詞情報を使った +解析を用いることなく効率的入力ができます。 -TODO としては、辞書に品詞情報を持たせることで更なる入力の効率化ができ -るという提案がなされており、そのような辞書の作成が既に試みられています。 -興味のある方は +TODO としては、辞書に品詞情報を持たせることで更なる入力の効率化ができると +いう提案がなされており、そのような辞書の作成が既に試みられています。興味 +のある方は次の url をご覧ください。 -@display -@url{http://openlab.jp/skk/wiki/wiki.cgi?page=SKK%BC%AD%BD%F1} -@end display - -における @file{SKK-JISYO.notes} の項目をご覧ください。 +@itemize +@item +@uref{http://openlab.jp/skk/wiki/wiki.cgi?page=SKK%BC%AD%BD%F1, SKK-JISYO.notes} +@end itemize @node Q4-3 複数の SKK 辞書を結合できますか? -@unnumberedsubsec Q4-3 複数の SKK 辞書を結合できますか? -@cindex 辞書のマージ +@subsection Q4-3 複数の SKK 辞書を結合できますか? -SKK 本体のパッケージには同封されていませんが、skk-tools という別パッケー -ジがあります。以下をご覧ください。 +SKK 本体のパッケージには同封されていませんが、 @code{skk-tools} という別パッケー +ジがあります。 -@display -@xref{辞書ツール}. -@end display +@ref{辞書ツール}. @node Q4-4 SKK 形式の英和辞書があると聞いたのですが。 -@unnumberedsubsec Q4-4 SKK 形式の英和辞書があると聞いたのですが。 -@cindex @file{edict2skk.awk} -@cindex @code{skkdic-expr} -@cindex @code{skkdic-sort} -@cindex edict -@cindex 英和辞書 +@subsection Q4-4 SKK 形式の英和辞書があると聞いたのですが。 edict は和英辞書ですが、これを SKK 辞書形式の英和辞書に変換したものを -@display -@url{http://openlab.jp/skk/dic/SKK-JISYO.edict} -@end display +@uref{http://openlab.jp/skk/dic/SKK-JISYO.edict} @noindent として置いています。これは edict を単純に機械的に変換した後、バグの修正 @@ -11090,15 +10881,11 @@ edict を自分で加工して上記と同等のものを作成することもできます。edict は -@display -@url{ftp://ftp.u-aizu.ac.jp:/pub/SciEng/nihongo/ftp.cc.monash.edu.au/} -@end display +@uref{ftp://ftp.u-aizu.ac.jp:/pub/SciEng/nihongo/ftp.cc.monash.edu.au/} @noindent -などから入手できます。 - -加工には日本語の通る @command{gawk} と skk-tools の中のプログラムを使い、下 -記のように行います。 +などから入手できます。加工には日本語の通る @code{gawk} と @code{skk-tools} の中のプ +ログラムを使い、下記のように行います。 @example % jgawk -f edict2skk.awk edict > temp @@ -11106,7 +10893,7 @@ % rm temp @end example -できた @file{SKK-JISYO.E2J} の利用方法は色々ありますが、 +できた @code{SKK-JISYO.E2J} の利用方法は色々ありますが、 @example % skkdic-expr SKK-JISYO.E2J + /usr/local/share/skk/SKK-JISYO.L | \ @@ -11114,20 +10901,19 @@ @end example @noindent -などとして、@file{SKK-JISYO.L} とマージして使うのが手軽です。 +などとして、 @code{SKK-JISYO.L} とマージして使うのが手軽です。 なお、edict の配布条件は GNU GPL (General Public License) ではありません。 -@display -@url{http://www.csse.monash.edu.au/groups/edrdg/newlic.html} -@end display +@uref{http://www.csse.monash.edu.au/groups/edrdg/newlic.html} @noindent -をご覧下さい。@file{SKK-JISYO.edict} のヘッダー部分にもそのダイジェスト +をご覧下さい。 @code{SKK-JISYO.edict} のヘッダー部分にもそのダイジェスト が記載されています。 @node Miscellaneous -@section SKK の活用法その他 +@section Miscellaneous + @menu * Q5-1 SKK abbrev モードでもっと英単語を利用した変換ができませんか?:: @@ -11136,163 +10922,155 @@ @end menu @node Q5-1 SKK abbrev モードでもっと英単語を利用した変換ができませんか? -@unnumberedsubsec Q5-1 SKK abbrev モードでもっと英単語を利用した変換ができませんか? -@cindex @code{look} -@cindex @file{skk-look.el} -@cindex edict -@cindex 英単語の検索 -@cindex 和英変換 -@kindex , -@kindex . -@vindex skk-look-expanded-word-only -@vindex skk-look-recursive-search -@vindex skk-look-use-ispell -@vindex skk-use-look +@subsection Q5-1 SKK abbrev モードでもっと英単語を利用した変換ができませんか? -UNIX @command{look} コマンドと @file{skk-look.el} を利用すると、色々できま -すよ。まず、 @file{~/.skk} で @code{skk-use-look} を @code{t} にセットして Emacs/SKK を立ち上げ直して下さい。 +UNIX @code{look} コマンドと @code{skk-look.el} を利用すると、色々できますよ。 +まず、 @code{~/.skk} で @code{skk-use-look} を @code{t} にセットして Emacs/SKK を立ち上 +げ直して下さい。 さぁ、下記のような芸当が可能になりました。 -@enumerate +@itemize @item 英単語の補完ができます。 @example - ▽abstr(@key{TAB}) @expansion{} ▽abstract + ▽abstr* + +TAB + + ▽abstract* @end example -通常の補完機能と同様に @kbd{.} で次の補完候補に、@kbd{,} でひとつ前の補完候補 -に移動できます。SKK 形式の英和辞書があれば、ここから @key{SPC} を押して -英和変換ができますね。また、@code{skk-look-use-ispell} の値が -@code{non-nil} であれば、@command{look} で検索する前に @command{ispell} でス -ペルチェック・修正をします。 +通常の補完機能と同様に @code{.} で次の補完候補に、 @code{,} でひとつ前の補完候補 +に移動できます。SKK 形式の英和辞書があれば、ここから @code{SPC} を押して英和 +変換ができますね。また、 @code{skk-look-use-ispell} の値が @code{non-nil} であれ +ば、 @code{look} で検索する前に @code{ispell} でスペルチェック・修正をします。 + @item -英単語をあいまいに変換して取り出すことができます。上記同様、 -@code{skk-look-use-ispell} の値が @code{non-nil} であれば、@command{look} -で検索する前に @command{ispell} でスペルチェック・修正をします。 +英単語をあいまいに変換して取り出す + +上記同様、 @code{skk-look-use-ispell} の値が @code{non-nil} であれば、 @code{look} で +検索する前に @code{ispell} でスペルチェック・修正をします。 @example - ▽abstr* (@key{SPC}) @expansion{} ▼abstract + ▽abstr* + +SPC + + ▼abstract* @end example -見出し語に @samp{*} を入れるのをお忘れなく。 +見出し語に @code{*} を入れるのをお忘れなく。 + @item -あいまいに変換した後、更に再帰的な英和変換を行うことができます。 +あいまいに変換した後、更に再帰的な英和変換を行う -まず、@code{skk-look-recursive-search} の値を @code{non-nil} にセット -して下さい。Emacs/SKK を再起動する必要はありません。すると、例えば、 +まず、 @code{skk-look-recursive-search} の値を @code{non-nil} にセットして下さい。 +Emacs / SKK を再起動する必要はありません。すると、例えば、 @example - ▽abstr* (@key{SPC}) - @expansion{} ▼abstract (@key{SPC}) - @expansion{} ▼アブストラクト (@key{SPC}) - @expansion{} ▼抽象 (@key{SPC}) - @expansion{} ▼abstraction (@key{SPC}) - @expansion{} ▼アブストラクション + ▽abstr* + +SPC + + ▼abstract + +SPC + + ▼アブストラクト + +SPC + + ▼抽象 + +SPC + + ▼abstraction + +SPC + + ▼アブストラクション @end example -このように英単語 + その英単語を見出し語にした候補の「セット」を変換結果 +このように英単語+その英単語を見出し語にした候補の「セット」を変換結果 として出力することができます。 -この際、@code{skk-look-expanded-word-only} の値が @code{non-nil} であ -れば、再帰検索に成功した英単語の「セット」だけを出力することができます -(再帰検索で検出されなかった英単語は無視して出力しません) 。 +この際、 @code{skk-look-expanded-word-only} の値が @code{non-nil} であれば、再帰 +検索に成功した英単語の「セット」だけを出力することができます(再帰検索 +で検出されなかった英単語は無視して出力しません)。 もちろん、SKK 辞書に @example - abstract /アブストラクト/抽象/ - abstraction /アブストラクション/ +abstract /アブストラクト/抽象/ +abstraction /アブストラクション/ @end example -@noindent というエントリがあることを前提としています。edict を SKK 辞書形式に変換 すると良いですね。 -@end enumerate +@end itemize -なお、@file{skk-look.el} を使った補完・変換が期待するスピードよりも遅 -い、補完・変換で余分な候補が出る、とお感じの貴方は、 -@code{skk-look-use-ispell} の値を @code{nil} にして @command{ispell} によ -るスペルチェック・修正をオフにしてお試し下さい。 +なお、 @code{skk-look.el} を使った補完・変換が期待するスピードよりも遅い、補完・変換 +で余分な候補が出る、とお感じの貴方は、 @code{skk-look-use-ispell} の値を @code{nil} に +して @code{ispell} によるスペルチェック・修正をオフにしてお試し下さい。 @node Q5-2 市販の CD-ROM 辞書やネットワークの辞書サーバが利用できますか? -@unnumberedsubsec Q5-2 市販の CD-ROM 辞書やネットワークの辞書サーバが利用できますか? -@cindex @file{skk-lookup.el} -@cindex Lookup -@vindex skk-search-prog-list -@findex skk-lookup-search +@subsection Q5-2 市販の CD-ROM 辞書やネットワークの辞書サーバが利用できますか? + +Lookup が扱える辞書はほとんど使えます。Lookup がインストールされている状 +態で SKK をインストールすると、SKK と Lookup のゲートウェイプログラム @code{skk-lookup.el} が +インストールされます。 -Lookup が扱える辞書はほとんど使えます。Lookup がインストールされている -状態で SKK をインストールすると、SKK と Lookup のゲートウェイプログラ -ム @file{skk-lookup.el} がインストールされます。 - -インストールで注意すべきは、@command{make} で呼び出される Emacs は -@option{-q -no-site-file} フラグ付きで呼ばれるので、@file{~/.emacs.d/init.el} や -@file{site-start.el} などは読み込まれないことです。デフォルトで -@code{load-path} の通っているディレクトリに lookup をインストールするか、 -@file{SKK-CFG} の中で @var{VERSION_SPECIFIC_LISPDIR} などにディレクトリ -を明示することで解決できます。 - -さぁ、@file{~/.skk} で @code{skk-search-prog-list} の -要素に @code{(skk-lookup-search)} を追加しましょう。他の検索エンジンより -も検索は比較的遅いので、最後の方が良いと思います。 +インストールで注意すべきは、 @code{make} で呼び出される Emacs は @code{-q -no-site-file} フ +ラグ付きで呼ばれるので、 @code{~/.emacs.d/init.el} や @code{site-start.el} などは読 +み込まれないことです。標準設定で @code{load-path} の通っているディレクトリに Lookup を +インストールするか、 @code{SKK-CFG} の中で @code{VERSION_SPECIFIC_LISPDIR} などにデ +ィレクトリを明示することで解決できます。 + +さぁ、 @code{~/.skk} で @code{skk-search-prog-list} の要素に @code{(skk-lookup-search)} を +追加しましょう。他の検索エンジンよりも検索は比較的遅いので、最後の方が良 +いと思います。 こんな感じです。 - @lisp -@group (setq skk-search-prog-list '((skk-search-jisyo-file skk-jisyo 0 t) (skk-search-server skk-aux-large-jisyo 10000) (skk-lookup-search))) -@end group @end lisp -Lookup については、 - -@display -@url{http://openlab.jp/edict/lookup/} -@end display - -@noindent -をご参照下さい。 +Lookup については、@uref{http://openlab.jp/edict/lookup/} をご参照下さい。 @node Q5-3 他の FEP を使用中にも SHIFT を押してしまいます。 -@unnumberedsubsec Q5-3 他の FEP を使用中にも SHIFT を押してしまいます。 +@subsection Q5-3 他の FEP を使用中にも SHIFT を押してしまいます。 治すには SKK をやめるしかありません :-) Emacs 上以外でも SKK みたいな操作性を実現するソフトウェアがあります。 -@ref{SKK関連ソフトウェア} をご覧になってください。 + +@ref{SKK 関連ソフトウェア}. @node 事項索引 -@unnumbered 事項索引 +@chapter 事項索引 @printindex cp @node 変数索引 -@unnumbered 変数索引 +@chapter 変数索引 @printindex vr @node 関数索引 -@unnumbered 関数索引 +@chapter 関数索引 @printindex fn @node キー索引 -@unnumbered キー索引 +@chapter キー索引 @printindex ky -@summarycontents -@contents @bye - -@c Local Variables: -@c fill-column: 72 -@c skk-kutouten-type: jp -@c End: diff -Nru ddskk-16.2/doc/texinfo-ja.tex ddskk-16.2+0.20190423/doc/texinfo-ja.tex --- ddskk-16.2/doc/texinfo-ja.tex 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/texinfo-ja.tex 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,84 @@ +% texinfo-ja.tex -- Japanese texinfo.tex loader +% Some CJK packages are necessary to load before texinfo.tex. +% +% Copyright 2016, 2017 Free Software Foundation, Inc. +% +% 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 3 of the license, 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 this program. If not, see . +% +% Written by Masamichi Hosoda, 6 May 2016, + +% +% For LuaTeX +% +\ifx\luatexversion\thisisundefined +\else + % LuaTeX 0.95+ is required. + \ifnum\luatexversion<95 + \errmessage{LuaTeX 0.95+ is required} + \fi + % LuaTeX-ja: Typeset Japanese with Lua(La)TeX + % http://www.ctan.org/tex-archive/macros/luatex/generic/luatexja + \openin 1 luatexja.sty \ifeof 1 + \errmessage{LuaTeX-ja is not found. + It is required for Japanese Texinfo files with LuaTeX. + http://www.ctan.org/tex-archive/macros/luatex/generic/luatexja + It might be contained in texlive-lang-japanese package} + \else + \input luatexja.sty + \def\txijapackage{LaTeX-ja} + \fi +\fi + +% +% For XeTeX +% +\ifx\XeTeXrevision\thisisundefined +\else + % XeTeX 0.9998+ is required. + \ifnum\strcmp{\the\XeTeXversion\XeTeXrevision}{0.9998}<0 + \errmessage{XeTeX 0.9998+ is required} + \fi + % zhspacing: Spacing for mixed CJK-English documents in XeTeX + % http://www.ctan.org/tex-archive/macros/xetex/generic/zhspacing + % + % This package is originally for Chinese, + % but can also used in Japanese. + % + \openin 1 zhspacing.sty \ifeof 1 + \errmessage{zhspacing is not found. + It is required for Japanese Texinfo files with XeTeX. + http://www.ctan.org/tex-archive/macros/xetex/generic/zhspacing + It might be contained in texlive-lang-chinese. + (This package is for Chinese, but can also used in Japanese)} + \else + \def\zhfont{dummy} % Cancel the request of SimSun font + \def\zhpunctfont{dummy} % Cancel the request of SimSun font + \input zhspacing.sty + \zhspacing + \def\txijapackage{zhspacing} + \fi +\fi + +% +% For others +% +\ifx\luatexversion\thisisundefined + \ifx\XeTeXrevision\thisisundefined + \errmessage{The TeX engine is not LuaTeX / XeTeX. + LuaTeX / XeTeX is required for Japanese Texinfo files} + \fi +\fi + +% Original texinfo.tex +\input texinfo.tex diff -Nru ddskk-16.2/doc/texinfo.tex ddskk-16.2+0.20190423/doc/texinfo.tex --- ddskk-16.2/doc/texinfo.tex 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/texinfo.tex 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,11685 @@ +% texinfo.tex -- TeX macros to handle Texinfo files. +% +% Load plain if necessary, i.e., if running under initex. +\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi +% +\def\texinfoversion{2017-07-06.22} +% +% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, +% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, +% 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 +% Free Software Foundation, Inc. +% +% This texinfo.tex file 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 3 of the +% License, or (at your option) any later version. +% +% This texinfo.tex file 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 this program. If not, see . +% +% As a special exception, when this file is read by TeX when processing +% a Texinfo source document, you may use the result without +% restriction. This Exception is an additional permission under section 7 +% of the GNU General Public License, version 3 ("GPLv3"). +% +% Please try the latest version of texinfo.tex before submitting bug +% reports; you can get the latest version from: +% http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or +% http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or +% http://www.gnu.org/software/texinfo/ (the Texinfo home page) +% The texinfo.tex in any given distribution could well be out +% of date, so if that's what you're using, please check. +% +% Send bug reports to bug-texinfo@gnu.org. Please include including a +% complete document in each bug report with which we can reproduce the +% problem. Patches are, of course, greatly appreciated. +% +% To process a Texinfo manual with TeX, it's most reliable to use the +% texi2dvi shell script that comes with the distribution. For a simple +% manual foo.texi, however, you can get away with this: +% tex foo.texi +% texindex foo.?? +% tex foo.texi +% tex foo.texi +% dvips foo.dvi -o # or whatever; this makes foo.ps. +% The extra TeX runs get the cross-reference information correct. +% Sometimes one run after texindex suffices, and sometimes you need more +% than two; texi2dvi does it as many times as necessary. +% +% It is possible to adapt texinfo.tex for other languages, to some +% extent. You can get the existing language-specific files from the +% full Texinfo distribution. +% +% The GNU Texinfo home page is http://www.gnu.org/software/texinfo. + + +\message{Loading texinfo [version \texinfoversion]:} + +% If in a .fmt file, print the version number +% and turn on active characters that we couldn't do earlier because +% they might have appeared in the input file name. +\everyjob{\message{[Texinfo version \texinfoversion]}% + \catcode`+=\active \catcode`\_=\active} + +% LaTeX's \typeout. This ensures that the messages it is used for +% are identical in format to the corresponding ones from latex/pdflatex. +\def\typeout{\immediate\write17}% + +\chardef\other=12 + +% We never want plain's \outer definition of \+ in Texinfo. +% For @tex, we can use \tabalign. +\let\+ = \relax + +% Save some plain tex macros whose names we will redefine. +\let\ptexb=\b +\let\ptexbullet=\bullet +\let\ptexc=\c +\let\ptexcomma=\, +\let\ptexdot=\. +\let\ptexdots=\dots +\let\ptexend=\end +\let\ptexequiv=\equiv +\let\ptexexclam=\! +\let\ptexfootnote=\footnote +\let\ptexgtr=> +\let\ptexhat=^ +\let\ptexi=\i +\let\ptexindent=\indent +\let\ptexinsert=\insert +\let\ptexlbrace=\{ +\let\ptexless=< +\let\ptexnewwrite\newwrite +\let\ptexnoindent=\noindent +\let\ptexplus=+ +\let\ptexraggedright=\raggedright +\let\ptexrbrace=\} +\let\ptexslash=\/ +\let\ptexsp=\sp +\let\ptexstar=\* +\let\ptexsup=\sup +\let\ptext=\t +\let\ptextop=\top +{\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode + +% If this character appears in an error message or help string, it +% starts a new line in the output. +\newlinechar = `^^J + +% Use TeX 3.0's \inputlineno to get the line number, for better error +% messages, but if we're using an old version of TeX, don't do anything. +% +\ifx\inputlineno\thisisundefined + \let\linenumber = \empty % Pre-3.0. +\else + \def\linenumber{l.\the\inputlineno:\space} +\fi + +% Set up fixed words for English if not already set. +\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi +\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi +\ifx\putworderror\undefined \gdef\putworderror{error}\fi +\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi +\ifx\putwordin\undefined \gdef\putwordin{in}\fi +\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi +\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi +\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi +\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi +\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi +\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi +\ifx\putwordof\undefined \gdef\putwordof{of}\fi +\ifx\putwordon\undefined \gdef\putwordon{on}\fi +\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi +\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi +\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi +\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi +\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi +\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi +\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi +% +\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi +\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi +\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi +\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi +\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi +\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi +\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi +\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi +\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi +\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi +\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi +\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi +% +\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi +\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi +\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi +\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi +\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi + +% Give the space character the catcode for a space. +\def\spaceisspace{\catcode`\ =10\relax} + +% Likewise for ^^M, the end of line character. +\def\endlineisspace{\catcode13=10\relax} + +\chardef\dashChar = `\- +\chardef\slashChar = `\/ +\chardef\underChar = `\_ + +% Ignore a token. +% +\def\gobble#1{} + +% The following is used inside several \edef's. +\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname} + +% Hyphenation fixes. +\hyphenation{ + Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script + ap-pen-dix bit-map bit-maps + data-base data-bases eshell fall-ing half-way long-est man-u-script + man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm + par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces + spell-ing spell-ings + stand-alone strong-est time-stamp time-stamps which-ever white-space + wide-spread wrap-around +} + +% Sometimes it is convenient to have everything in the transcript file +% and nothing on the terminal. We don't just call \tracingall here, +% since that produces some useless output on the terminal. We also make +% some effort to order the tracing commands to reduce output in the log +% file; cf. trace.sty in LaTeX. +% +\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% +\def\loggingall{% + \tracingstats2 + \tracingpages1 + \tracinglostchars2 % 2 gives us more in etex + \tracingparagraphs1 + \tracingoutput1 + \tracingmacros2 + \tracingrestores1 + \showboxbreadth\maxdimen \showboxdepth\maxdimen + \ifx\eTeXversion\thisisundefined\else % etex gives us more logging + \tracingscantokens1 + \tracingifs1 + \tracinggroups1 + \tracingnesting2 + \tracingassigns1 + \fi + \tracingcommands3 % 3 gives us more in etex + \errorcontextlines16 +}% + +% @errormsg{MSG}. Do the index-like expansions on MSG, but if things +% aren't perfect, it's not the end of the world, being an error message, +% after all. +% +\def\errormsg{\begingroup \indexnofonts \doerrormsg} +\def\doerrormsg#1{\errmessage{#1}} + +% add check for \lastpenalty to plain's definitions. If the last thing +% we did was a \nobreak, we don't want to insert more space. +% +\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount + \removelastskip\penalty-50\smallskip\fi\fi} +\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount + \removelastskip\penalty-100\medskip\fi\fi} +\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount + \removelastskip\penalty-200\bigskip\fi\fi} + +% Output routine +% + +% For a final copy, take out the rectangles +% that mark overfull boxes (in case you have decided +% that the text looks ok even though it passes the margin). +% +\def\finalout{\overfullrule=0pt } + +% Do @cropmarks to get crop marks. +% +\newif\ifcropmarks +\let\cropmarks = \cropmarkstrue +% +% Dimensions to add cropmarks at corners. +% Added by P. A. MacKay, 12 Nov. 1986 +% +\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines +\newdimen\cornerlong \cornerlong=1pc +\newdimen\cornerthick \cornerthick=.3pt +\newdimen\topandbottommargin \topandbottommargin=.75in + +% Output a mark which sets \thischapter, \thissection and \thiscolor. +% We dump everything together because we only have one kind of mark. +% This works because we only use \botmark / \topmark, not \firstmark. +% +% A mark contains a subexpression of the \ifcase ... \fi construct. +% \get*marks macros below extract the needed part using \ifcase. +% +% Another complication is to let the user choose whether \thischapter +% (\thissection) refers to the chapter (section) in effect at the top +% of a page, or that at the bottom of a page. + +% \domark is called twice inside \chapmacro, to add one +% mark before the section break, and one after. +% In the second call \prevchapterdefs is the same as \lastchapterdefs, +% and \prevsectiondefs is the same as \lastsectiondefs. +% Then if the page is not broken at the mark, some of the previous +% section appears on the page, and we can get the name of this section +% from \firstmark for @everyheadingmarks top. +% @everyheadingmarks bottom uses \botmark. +% +% See page 260 of The TeXbook. +\def\domark{% + \toks0=\expandafter{\lastchapterdefs}% + \toks2=\expandafter{\lastsectiondefs}% + \toks4=\expandafter{\prevchapterdefs}% + \toks6=\expandafter{\prevsectiondefs}% + \toks8=\expandafter{\lastcolordefs}% + \mark{% + \the\toks0 \the\toks2 % 0: marks for @everyheadingmarks top + \noexpand\or \the\toks4 \the\toks6 % 1: for @everyheadingmarks bottom + \noexpand\else \the\toks8 % 2: color marks + }% +} + +% \gettopheadingmarks, \getbottomheadingmarks, +% \getcolormarks - extract needed part of mark. +% +% \topmark doesn't work for the very first chapter (after the title +% page or the contents), so we use \firstmark there -- this gets us +% the mark with the chapter defs, unless the user sneaks in, e.g., +% @setcolor (or @url, or @link, etc.) between @contents and the very +% first @chapter. +\def\gettopheadingmarks{% + \ifcase0\topmark\fi + \ifx\thischapter\empty \ifcase0\firstmark\fi \fi +} +\def\getbottomheadingmarks{\ifcase1\botmark\fi} +\def\getcolormarks{\ifcase2\topmark\fi} + +% Avoid "undefined control sequence" errors. +\def\lastchapterdefs{} +\def\lastsectiondefs{} +\def\lastsection{} +\def\prevchapterdefs{} +\def\prevsectiondefs{} +\def\lastcolordefs{} + +% Margin to add to right of even pages, to left of odd pages. +\newdimen\bindingoffset +\newdimen\normaloffset +\newdimen\txipagewidth \newdimen\txipageheight + +% Main output routine. +% +\chardef\PAGE = 255 +\output = {\onepageout{\pagecontents\PAGE}} + +\newbox\headlinebox +\newbox\footlinebox + +% \onepageout takes a vbox as an argument. +% \shipout a vbox for a single page, adding an optional header, footer, +% cropmarks, and footnote. This also causes index entries for this page +% to be written to the auxiliary files. +% +\def\onepageout#1{% + \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi + % + \ifodd\pageno \advance\hoffset by \bindingoffset + \else \advance\hoffset by -\bindingoffset\fi + % + % Common context changes for both heading and footing. + % Do this outside of the \shipout so @code etc. will be expanded in + % the headline as they should be, not taken literally (outputting ''code). + \def\commmonheadfootline{\let\hsize=\txipagewidth \texinfochars} + % + % Retrieve the information for the headings from the marks in the page, + % and call Plain TeX's \makeheadline and \makefootline, which use the + % values in \headline and \footline. + % + % This is used to check if we are on the first page of a chapter. + \ifcase1\topmark\fi + \let\prevchaptername\thischaptername + \ifcase0\firstmark\fi + \let\curchaptername\thischaptername + % + \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi + \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi + % + \ifx\curchaptername\prevchaptername + \let\thischapterheading\thischapter + \else + % \thischapterheading is the same as \thischapter except it is blank + % for the first page of a chapter. This is to prevent the chapter name + % being shown twice. + \def\thischapterheading{}% + \fi + % + \global\setbox\headlinebox = \vbox{\commmonheadfootline \makeheadline}% + \global\setbox\footlinebox = \vbox{\commmonheadfootline \makefootline}% + % + {% + % Set context for writing to auxiliary files like index files. + % Have to do this stuff outside the \shipout because we want it to + % take effect in \write's, yet the group defined by the \vbox ends + % before the \shipout runs. + % + \indexdummies % don't expand commands in the output. + \normalturnoffactive % \ in index entries must not stay \, e.g., if + % the page break happens to be in the middle of an example. + % We don't want .vr (or whatever) entries like this: + % \entry{{\indexbackslash }acronym}{32}{\code {\acronym}} + % "\acronym" won't work when it's read back in; + % it needs to be + % {\code {{\backslashcurfont }acronym} + \shipout\vbox{% + % Do this early so pdf references go to the beginning of the page. + \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi + % + \ifcropmarks \vbox to \outervsize\bgroup + \hsize = \outerhsize + \vskip-\topandbottommargin + \vtop to0pt{% + \line{\ewtop\hfil\ewtop}% + \nointerlineskip + \line{% + \vbox{\moveleft\cornerthick\nstop}% + \hfill + \vbox{\moveright\cornerthick\nstop}% + }% + \vss}% + \vskip\topandbottommargin + \line\bgroup + \hfil % center the page within the outer (page) hsize. + \ifodd\pageno\hskip\bindingoffset\fi + \vbox\bgroup + \fi + % + \unvbox\headlinebox + \pagebody{#1}% + \ifdim\ht\footlinebox > 0pt + % Only leave this space if the footline is nonempty. + % (We lessened \vsize for it in \oddfootingyyy.) + % The \baselineskip=24pt in plain's \makefootline has no effect. + \vskip 24pt + \unvbox\footlinebox + \fi + % + \ifcropmarks + \egroup % end of \vbox\bgroup + \hfil\egroup % end of (centering) \line\bgroup + \vskip\topandbottommargin plus1fill minus1fill + \boxmaxdepth = \cornerthick + \vbox to0pt{\vss + \line{% + \vbox{\moveleft\cornerthick\nsbot}% + \hfill + \vbox{\moveright\cornerthick\nsbot}% + }% + \nointerlineskip + \line{\ewbot\hfil\ewbot}% + }% + \egroup % \vbox from first cropmarks clause + \fi + }% end of \shipout\vbox + }% end of group with \indexdummies + \advancepageno + \ifnum\outputpenalty>-20000 \else\dosupereject\fi +} + +\newinsert\margin \dimen\margin=\maxdimen + +% Main part of page, including any footnotes +\def\pagebody#1{\vbox to\txipageheight{\boxmaxdepth=\maxdepth #1}} +{\catcode`\@ =11 +\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi +% marginal hacks, juha@viisa.uucp (Juha Takala) +\ifvoid\margin\else % marginal info is present + \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi +\dimen@=\dp#1\relax \unvbox#1\relax +\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi +\ifr@ggedbottom \kern-\dimen@ \vfil \fi} +} + +% Here are the rules for the cropmarks. Note that they are +% offset so that the space between them is truly \outerhsize or \outervsize +% (P. A. MacKay, 12 November, 1986) +% +\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} +\def\nstop{\vbox + {\hrule height\cornerthick depth\cornerlong width\cornerthick}} +\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} +\def\nsbot{\vbox + {\hrule height\cornerlong depth\cornerthick width\cornerthick}} + + +% Argument parsing + +% Parse an argument, then pass it to #1. The argument is the rest of +% the input line (except we remove a trailing comment). #1 should be a +% macro which expects an ordinary undelimited TeX argument. +% For example, \def\foo{\parsearg\fooxxx}. +% +\def\parsearg{\parseargusing{}} +\def\parseargusing#1#2{% + \def\argtorun{#2}% + \begingroup + \obeylines + \spaceisspace + #1% + \parseargline\empty% Insert the \empty token, see \finishparsearg below. +} + +{\obeylines % + \gdef\parseargline#1^^M{% + \endgroup % End of the group started in \parsearg. + \argremovecomment #1\comment\ArgTerm% + }% +} + +% First remove any @comment, then any @c comment. Also remove a @texinfoc +% comment (see \scanmacro for details). Pass the result on to \argcheckspaces. +\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm} +\def\argremovec#1\c#2\ArgTerm{\argremovetexinfoc #1\texinfoc\ArgTerm} +\def\argremovetexinfoc#1\texinfoc#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm} + +% Each occurrence of `\^^M' or `\^^M' is replaced by a single space. +% +% \argremovec might leave us with trailing space, e.g., +% @end itemize @c foo +% This space token undergoes the same procedure and is eventually removed +% by \finishparsearg. +% +\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M} +\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M} +\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{% + \def\temp{#3}% + \ifx\temp\empty + % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp: + \let\temp\finishparsearg + \else + \let\temp\argcheckspaces + \fi + % Put the space token in: + \temp#1 #3\ArgTerm +} + +% If a _delimited_ argument is enclosed in braces, they get stripped; so +% to get _exactly_ the rest of the line, we had to prevent such situation. +% We prepended an \empty token at the very beginning and we expand it now, +% just before passing the control to \argtorun. +% (Similarly, we have to think about #3 of \argcheckspacesY above: it is +% either the null string, or it ends with \^^M---thus there is no danger +% that a pair of braces would be stripped. +% +% But first, we have to remove the trailing space token. +% +\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}} + + +% \parseargdef - define a command taking an argument on the line +% +% \parseargdef\foo{...} +% is roughly equivalent to +% \def\foo{\parsearg\Xfoo} +% \def\Xfoo#1{...} +\def\parseargdef#1{% + \expandafter \doparseargdef \csname\string#1\endcsname #1% +} +\def\doparseargdef#1#2{% + \def#2{\parsearg#1}% + \def#1##1% +} + +% Several utility definitions with active space: +{ + \obeyspaces + \gdef\obeyedspace{ } + + % Make each space character in the input produce a normal interword + % space in the output. Don't allow a line break at this space, as this + % is used only in environments like @example, where each line of input + % should produce a line of output anyway. + % + \gdef\sepspaces{\obeyspaces\let =\tie} + + % If an index command is used in an @example environment, any spaces + % therein should become regular spaces in the raw index file, not the + % expansion of \tie (\leavevmode \penalty \@M \ ). + \gdef\unsepspaces{\let =\space} +} + + +\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} + +% Define the framework for environments in texinfo.tex. It's used like this: +% +% \envdef\foo{...} +% \def\Efoo{...} +% +% It's the responsibility of \envdef to insert \begingroup before the +% actual body; @end closes the group after calling \Efoo. \envdef also +% defines \thisenv, so the current environment is known; @end checks +% whether the environment name matches. The \checkenv macro can also be +% used to check whether the current environment is the one expected. +% +% Non-false conditionals (@iftex, @ifset) don't fit into this, so they +% are not treated as environments; they don't open a group. (The +% implementation of @end takes care not to call \endgroup in this +% special case.) + + +% At run-time, environments start with this: +\def\startenvironment#1{\begingroup\def\thisenv{#1}} +% initialize +\let\thisenv\empty + +% ... but they get defined via ``\envdef\foo{...}'': +\long\def\envdef#1#2{\def#1{\startenvironment#1#2}} +\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}} + +% Check whether we're in the right environment: +\def\checkenv#1{% + \def\temp{#1}% + \ifx\thisenv\temp + \else + \badenverr + \fi +} + +% Environment mismatch, #1 expected: +\def\badenverr{% + \errhelp = \EMsimple + \errmessage{This command can appear only \inenvironment\temp, + not \inenvironment\thisenv}% +} +\def\inenvironment#1{% + \ifx#1\empty + outside of any environment% + \else + in environment \expandafter\string#1% + \fi +} + +% @end foo executes the definition of \Efoo. +% But first, it executes a specialized version of \checkenv +% +\parseargdef\end{% + \if 1\csname iscond.#1\endcsname + \else + % The general wording of \badenverr may not be ideal. + \expandafter\checkenv\csname#1\endcsname + \csname E#1\endcsname + \endgroup + \fi +} + +\newhelp\EMsimple{Press RETURN to continue.} + + +% Be sure we're in horizontal mode when doing a tie, since we make space +% equivalent to this in @example-like environments. Otherwise, a space +% at the beginning of a line will start with \penalty -- and +% since \penalty is valid in vertical mode, we'd end up putting the +% penalty on the vertical list instead of in the new paragraph. +{\catcode`@ = 11 + % Avoid using \@M directly, because that causes trouble + % if the definition is written into an index file. + \global\let\tiepenalty = \@M + \gdef\tie{\leavevmode\penalty\tiepenalty\ } +} + +% @: forces normal size whitespace following. +\def\:{\spacefactor=1000 } + +% @* forces a line break. +\def\*{\unskip\hfil\break\hbox{}\ignorespaces} + +% @/ allows a line break. +\let\/=\allowbreak + +% @. is an end-of-sentence period. +\def\.{.\spacefactor=\endofsentencespacefactor\space} + +% @! is an end-of-sentence bang. +\def\!{!\spacefactor=\endofsentencespacefactor\space} + +% @? is an end-of-sentence query. +\def\?{?\spacefactor=\endofsentencespacefactor\space} + +% @frenchspacing on|off says whether to put extra space after punctuation. +% +\def\onword{on} +\def\offword{off} +% +\parseargdef\frenchspacing{% + \def\temp{#1}% + \ifx\temp\onword \plainfrenchspacing + \else\ifx\temp\offword \plainnonfrenchspacing + \else + \errhelp = \EMsimple + \errmessage{Unknown @frenchspacing option `\temp', must be on|off}% + \fi\fi +} + +% @w prevents a word break. Without the \leavevmode, @w at the +% beginning of a paragraph, when TeX is still in vertical mode, would +% produce a whole line of output instead of starting the paragraph. +\def\w#1{\leavevmode\hbox{#1}} + +% @group ... @end group forces ... to be all on one page, by enclosing +% it in a TeX vbox. We use \vtop instead of \vbox to construct the box +% to keep its height that of a normal line. According to the rules for +% \topskip (p.114 of the TeXbook), the glue inserted is +% max (\topskip - \ht (first item), 0). If that height is large, +% therefore, no glue is inserted, and the space between the headline and +% the text is small, which looks bad. +% +% Another complication is that the group might be very large. This can +% cause the glue on the previous page to be unduly stretched, because it +% does not have much material. In this case, it's better to add an +% explicit \vfill so that the extra space is at the bottom. The +% threshold for doing this is if the group is more than \vfilllimit +% percent of a page (\vfilllimit can be changed inside of @tex). +% +\newbox\groupbox +\def\vfilllimit{0.7} +% +\envdef\group{% + \ifnum\catcode`\^^M=\active \else + \errhelp = \groupinvalidhelp + \errmessage{@group invalid in context where filling is enabled}% + \fi + \startsavinginserts + % + \setbox\groupbox = \vtop\bgroup + % Do @comment since we are called inside an environment such as + % @example, where each end-of-line in the input causes an + % end-of-line in the output. We don't want the end-of-line after + % the `@group' to put extra space in the output. Since @group + % should appear on a line by itself (according to the Texinfo + % manual), we don't worry about eating any user text. + \comment +} +% +% The \vtop produces a box with normal height and large depth; thus, TeX puts +% \baselineskip glue before it, and (when the next line of text is done) +% \lineskip glue after it. Thus, space below is not quite equal to space +% above. But it's pretty close. +\def\Egroup{% + % To get correct interline space between the last line of the group + % and the first line afterwards, we have to propagate \prevdepth. + \endgraf % Not \par, as it may have been set to \lisppar. + \global\dimen1 = \prevdepth + \egroup % End the \vtop. + \addgroupbox + \prevdepth = \dimen1 + \checkinserts +} + +\def\addgroupbox{ + % \dimen0 is the vertical size of the group's box. + \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox + % \dimen2 is how much space is left on the page (more or less). + \dimen2 = \txipageheight \advance\dimen2 by -\pagetotal + % if the group doesn't fit on the current page, and it's a big big + % group, force a page break. + \ifdim \dimen0 > \dimen2 + \ifdim \pagetotal < \vfilllimit\txipageheight + \page + \fi + \fi + \box\groupbox +} + +% +% TeX puts in an \escapechar (i.e., `@') at the beginning of the help +% message, so this ends up printing `@group can only ...'. +% +\newhelp\groupinvalidhelp{% +group can only be used in environments such as @example,^^J% +where each line of input produces a line of output.} + +% @need space-in-mils +% forces a page break if there is not space-in-mils remaining. + +\newdimen\mil \mil=0.001in + +\parseargdef\need{% + % Ensure vertical mode, so we don't make a big box in the middle of a + % paragraph. + \par + % + % If the @need value is less than one line space, it's useless. + \dimen0 = #1\mil + \dimen2 = \ht\strutbox + \advance\dimen2 by \dp\strutbox + \ifdim\dimen0 > \dimen2 + % + % Do a \strut just to make the height of this box be normal, so the + % normal leading is inserted relative to the preceding line. + % And a page break here is fine. + \vtop to #1\mil{\strut\vfil}% + % + % TeX does not even consider page breaks if a penalty added to the + % main vertical list is 10000 or more. But in order to see if the + % empty box we just added fits on the page, we must make it consider + % page breaks. On the other hand, we don't want to actually break the + % page after the empty box. So we use a penalty of 9999. + % + % There is an extremely small chance that TeX will actually break the + % page at this \penalty, if there are no other feasible breakpoints in + % sight. (If the user is using lots of big @group commands, which + % almost-but-not-quite fill up a page, TeX will have a hard time doing + % good page breaking, for example.) However, I could not construct an + % example where a page broke at this \penalty; if it happens in a real + % document, then we can reconsider our strategy. + \penalty9999 + % + % Back up by the size of the box, whether we did a page break or not. + \kern -#1\mil + % + % Do not allow a page break right after this kern. + \nobreak + \fi +} + +% @br forces paragraph break (and is undocumented). + +\let\br = \par + +% @page forces the start of a new page. +% +\def\page{\par\vfill\supereject} + +% @exdent text.... +% outputs text on separate line in roman font, starting at standard page margin + +% This records the amount of indent in the innermost environment. +% That's how much \exdent should take out. +\newskip\exdentamount + +% This defn is used inside fill environments such as @defun. +\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break} + +% This defn is used inside nofill environments such as @example. +\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount + \leftline{\hskip\leftskip{\rm#1}}}} + +% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current +% paragraph. For more general purposes, use the \margin insertion +% class. WHICH is `l' or `r'. Not documented, written for gawk manual. +% +\newskip\inmarginspacing \inmarginspacing=1cm +\def\strutdepth{\dp\strutbox} +% +\def\doinmargin#1#2{\strut\vadjust{% + \nobreak + \kern-\strutdepth + \vtop to \strutdepth{% + \baselineskip=\strutdepth + \vss + % if you have multiple lines of stuff to put here, you'll need to + % make the vbox yourself of the appropriate size. + \ifx#1l% + \llap{\ignorespaces #2\hskip\inmarginspacing}% + \else + \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}% + \fi + \null + }% +}} +\def\inleftmargin{\doinmargin l} +\def\inrightmargin{\doinmargin r} +% +% @inmargin{TEXT [, RIGHT-TEXT]} +% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right; +% else use TEXT for both). +% +\def\inmargin#1{\parseinmargin #1,,\finish} +\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing. + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \def\lefttext{#1}% have both texts + \def\righttext{#2}% + \else + \def\lefttext{#1}% have only one text + \def\righttext{#1}% + \fi + % + \ifodd\pageno + \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin + \else + \def\temp{\inleftmargin\lefttext}% + \fi + \temp +} + +% @include FILE -- \input text of FILE. +% +\def\include{\parseargusing\filenamecatcodes\includezzz} +\def\includezzz#1{% + \pushthisfilestack + \def\thisfile{#1}% + {% + \makevalueexpandable % we want to expand any @value in FILE. + \turnoffactive % and allow special characters in the expansion + \indexnofonts % Allow `@@' and other weird things in file names. + \wlog{texinfo.tex: doing @include of #1^^J}% + \edef\temp{\noexpand\input #1 }% + % + % This trickery is to read FILE outside of a group, in case it makes + % definitions, etc. + \expandafter + }\temp + \popthisfilestack +} +\def\filenamecatcodes{% + \catcode`\\=\other + \catcode`~=\other + \catcode`^=\other + \catcode`_=\other + \catcode`|=\other + \catcode`<=\other + \catcode`>=\other + \catcode`+=\other + \catcode`-=\other + \catcode`\`=\other + \catcode`\'=\other +} + +\def\pushthisfilestack{% + \expandafter\pushthisfilestackX\popthisfilestack\StackTerm +} +\def\pushthisfilestackX{% + \expandafter\pushthisfilestackY\thisfile\StackTerm +} +\def\pushthisfilestackY #1\StackTerm #2\StackTerm {% + \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}% +} + +\def\popthisfilestack{\errthisfilestackempty} +\def\errthisfilestackempty{\errmessage{Internal error: + the stack of filenames is empty.}} +% +\def\thisfile{} + +% @center line +% outputs that line, centered. +% +\parseargdef\center{% + \ifhmode + \let\centersub\centerH + \else + \let\centersub\centerV + \fi + \centersub{\hfil \ignorespaces#1\unskip \hfil}% + \let\centersub\relax % don't let the definition persist, just in case +} +\def\centerH#1{{% + \hfil\break + \advance\hsize by -\leftskip + \advance\hsize by -\rightskip + \line{#1}% + \break +}} +% +\newcount\centerpenalty +\def\centerV#1{% + % The idea here is the same as in \startdefun, \cartouche, etc.: if + % @center is the first thing after a section heading, we need to wipe + % out the negative parskip inserted by \sectionheading, but still + % prevent a page break here. + \centerpenalty = \lastpenalty + \ifnum\centerpenalty>10000 \vskip\parskip \fi + \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi + \line{\kern\leftskip #1\kern\rightskip}% +} + +% @sp n outputs n lines of vertical space +% +\parseargdef\sp{\vskip #1\baselineskip} + +% @comment ...line which is ignored... +% @c is the same as @comment +% @ignore ... @end ignore is another way to write a comment + + +\def\c{\begingroup \catcode`\^^M=\active% +\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% +\cxxx} +{\catcode`\^^M=\active \gdef\cxxx#1^^M{\endgroup}} +% +\let\comment\c + +% @paragraphindent NCHARS +% We'll use ems for NCHARS, close enough. +% NCHARS can also be the word `asis' or `none'. +% We cannot feasibly implement @paragraphindent asis, though. +% +\def\asisword{asis} % no translation, these are keywords +\def\noneword{none} +% +\parseargdef\paragraphindent{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \defaultparindent = 0pt + \else + \defaultparindent = #1em + \fi + \fi + \parindent = \defaultparindent +} + +% @exampleindent NCHARS +% We'll use ems for NCHARS like @paragraphindent. +% It seems @exampleindent asis isn't necessary, but +% I preserve it to make it similar to @paragraphindent. +\parseargdef\exampleindent{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \lispnarrowing = 0pt + \else + \lispnarrowing = #1em + \fi + \fi +} + +% @firstparagraphindent WORD +% If WORD is `none', then suppress indentation of the first paragraph +% after a section heading. If WORD is `insert', then do indent at such +% paragraphs. +% +% The paragraph indentation is suppressed or not by calling +% \suppressfirstparagraphindent, which the sectioning commands do. +% We switch the definition of this back and forth according to WORD. +% By default, we suppress indentation. +% +\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent} +\def\insertword{insert} +% +\parseargdef\firstparagraphindent{% + \def\temp{#1}% + \ifx\temp\noneword + \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent + \else\ifx\temp\insertword + \let\suppressfirstparagraphindent = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @firstparagraphindent option `\temp'}% + \fi\fi +} + +% Here is how we actually suppress indentation. Redefine \everypar to +% \kern backwards by \parindent, and then reset itself to empty. +% +% We also make \indent itself not actually do anything until the next +% paragraph. +% +\gdef\dosuppressfirstparagraphindent{% + \gdef\indent {\restorefirstparagraphindent \indent}% + \gdef\noindent{\restorefirstparagraphindent \noindent}% + \global\everypar = {\kern -\parindent \restorefirstparagraphindent}% +} +% +\gdef\restorefirstparagraphindent{% + \global\let\indent = \ptexindent + \global\let\noindent = \ptexnoindent + \global\everypar = {}% +} + + +% @refill is a no-op. +\let\refill=\relax + +% @setfilename INFO-FILENAME - ignored +\let\setfilename=\comment + +% @bye. +\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} + + +\message{pdf,} +% adobe `portable' document format +\newcount\tempnum +\newcount\lnkcount +\newtoks\filename +\newcount\filenamelength +\newcount\pgn +\newtoks\toksA +\newtoks\toksB +\newtoks\toksC +\newtoks\toksD +\newbox\boxA +\newbox\boxB +\newcount\countA +\newif\ifpdf +\newif\ifpdfmakepagedest + +% +% For LuaTeX +% + +\newif\iftxiuseunicodedestname +\txiuseunicodedestnamefalse % For pdfTeX etc. + +\ifx\luatexversion\thisisundefined +\else + % Use Unicode destination names + \txiuseunicodedestnametrue + % Escape PDF strings with converting UTF-16 from UTF-8 + \begingroup + \catcode`\%=12 + \directlua{ + function UTF16oct(str) + tex.sprint(string.char(0x5c) .. '376' .. string.char(0x5c) .. '377') + for c in string.utfvalues(str) do + if c < 0x10000 then + tex.sprint( + string.format(string.char(0x5c) .. string.char(0x25) .. '03o' .. + string.char(0x5c) .. string.char(0x25) .. '03o', + (c / 256), (c % 256))) + else + c = c - 0x10000 + local c_hi = c / 1024 + 0xd800 + local c_lo = c % 1024 + 0xdc00 + tex.sprint( + string.format(string.char(0x5c) .. string.char(0x25) .. '03o' .. + string.char(0x5c) .. string.char(0x25) .. '03o' .. + string.char(0x5c) .. string.char(0x25) .. '03o' .. + string.char(0x5c) .. string.char(0x25) .. '03o', + (c_hi / 256), (c_hi % 256), + (c_lo / 256), (c_lo % 256))) + end + end + end + } + \endgroup + \def\pdfescapestrutfsixteen#1{\directlua{UTF16oct('\luaescapestring{#1}')}} + % Escape PDF strings without converting + \begingroup + \directlua{ + function PDFescstr(str) + for c in string.bytes(str) do + if c <= 0x20 or c >= 0x80 or c == 0x28 or c == 0x29 or c == 0x5c then + tex.sprint( + string.format(string.char(0x5c) .. string.char(0x25) .. '03o', + c)) + else + tex.sprint(string.char(c)) + end + end + end + } + \endgroup + \def\pdfescapestring#1{\directlua{PDFescstr('\luaescapestring{#1}')}} + \ifnum\luatexversion>84 + % For LuaTeX >= 0.85 + \def\pdfdest{\pdfextension dest} + \let\pdfoutput\outputmode + \def\pdfliteral{\pdfextension literal} + \def\pdfcatalog{\pdfextension catalog} + \def\pdftexversion{\numexpr\pdffeedback version\relax} + \let\pdfximage\saveimageresource + \let\pdfrefximage\useimageresource + \let\pdflastximage\lastsavedimageresourceindex + \def\pdfendlink{\pdfextension endlink\relax} + \def\pdfoutline{\pdfextension outline} + \def\pdfstartlink{\pdfextension startlink} + \def\pdffontattr{\pdfextension fontattr} + \def\pdfobj{\pdfextension obj} + \def\pdflastobj{\numexpr\pdffeedback lastobj\relax} + \let\pdfpagewidth\pagewidth + \let\pdfpageheight\pageheight + \edef\pdfhorigin{\pdfvariable horigin} + \edef\pdfvorigin{\pdfvariable vorigin} + \fi +\fi + +% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 +% can be set). So we test for \relax and 0 as well as being undefined. +\ifx\pdfoutput\thisisundefined +\else + \ifx\pdfoutput\relax + \else + \ifcase\pdfoutput + \else + \pdftrue + \fi + \fi +\fi + +% PDF uses PostScript string constants for the names of xref targets, +% for display in the outlines, and in other places. Thus, we have to +% double any backslashes. Otherwise, a name like "\node" will be +% interpreted as a newline (\n), followed by o, d, e. Not good. +% +% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and +% related messages. The final outcome is that it is up to the TeX user +% to double the backslashes and otherwise make the string valid, so +% that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to +% do this reliably, so we use it. + +% #1 is a control sequence in which to do the replacements, +% which we \xdef. +\def\txiescapepdf#1{% + \ifx\pdfescapestring\thisisundefined + % No primitive available; should we give a warning or log? + % Many times it won't matter. + \xdef#1{#1}% + \else + % The expandable \pdfescapestring primitive escapes parentheses, + % backslashes, and other special chars. + \xdef#1{\pdfescapestring{#1}}% + \fi +} +\def\txiescapepdfutfsixteen#1{% + \ifx\pdfescapestrutfsixteen\thisisundefined + % No UTF-16 converting macro available. + \txiescapepdf{#1}% + \else + \xdef#1{\pdfescapestrutfsixteen{#1}}% + \fi +} + +\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images +with PDF output, and none of those formats could be found. (.eps cannot +be supported due to the design of the PDF format; use regular TeX (DVI +output) for that.)} + +\ifpdf + % + % Color manipulation macros using ideas from pdfcolor.tex, + % except using rgb instead of cmyk; the latter is said to render as a + % very dark gray on-screen and a very dark halftone in print, instead + % of actual black. The dark red here is dark enough to print on paper as + % nearly black, but still distinguishable for online viewing. We use + % black by default, though. + \def\rgbDarkRed{0.50 0.09 0.12} + \def\rgbBlack{0 0 0} + % + % rg sets the color for filling (usual text, etc.); + % RG sets the color for stroking (thin rules, e.g., normal _'s). + \def\pdfsetcolor#1{\pdfliteral{#1 rg #1 RG}} + % + % Set color, and create a mark which defines \thiscolor accordingly, + % so that \makeheadline knows which color to restore. + \def\setcolor#1{% + \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}% + \domark + \pdfsetcolor{#1}% + } + % + \def\maincolor{\rgbBlack} + \pdfsetcolor{\maincolor} + \edef\thiscolor{\maincolor} + \def\lastcolordefs{} + % + \def\makefootline{% + \baselineskip24pt + \line{\pdfsetcolor{\maincolor}\the\footline}% + } + % + \def\makeheadline{% + \vbox to 0pt{% + \vskip-22.5pt + \line{% + \vbox to8.5pt{}% + % Extract \thiscolor definition from the marks. + \getcolormarks + % Typeset the headline with \maincolor, then restore the color. + \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}% + }% + \vss + }% + \nointerlineskip + } + % + % + \pdfcatalog{/PageMode /UseOutlines} + % + % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). + \def\dopdfimage#1#2#3{% + \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% + \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% + % + % pdftex (and the PDF format) support .pdf, .png, .jpg (among + % others). Let's try in that order, PDF first since if + % someone has a scalable image, presumably better to use that than a + % bitmap. + \let\pdfimgext=\empty + \begingroup + \openin 1 #1.pdf \ifeof 1 + \openin 1 #1.PDF \ifeof 1 + \openin 1 #1.png \ifeof 1 + \openin 1 #1.jpg \ifeof 1 + \openin 1 #1.jpeg \ifeof 1 + \openin 1 #1.JPG \ifeof 1 + \errhelp = \nopdfimagehelp + \errmessage{Could not find image file #1 for pdf}% + \else \gdef\pdfimgext{JPG}% + \fi + \else \gdef\pdfimgext{jpeg}% + \fi + \else \gdef\pdfimgext{jpg}% + \fi + \else \gdef\pdfimgext{png}% + \fi + \else \gdef\pdfimgext{PDF}% + \fi + \else \gdef\pdfimgext{pdf}% + \fi + \closein 1 + \endgroup + % + % without \immediate, ancient pdftex seg faults when the same image is + % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.) + \ifnum\pdftexversion < 14 + \immediate\pdfimage + \else + \immediate\pdfximage + \fi + \ifdim \wd0 >0pt width \pdfimagewidth \fi + \ifdim \wd2 >0pt height \pdfimageheight \fi + \ifnum\pdftexversion<13 + #1.\pdfimgext + \else + {#1.\pdfimgext}% + \fi + \ifnum\pdftexversion < 14 \else + \pdfrefximage \pdflastximage + \fi} + % + \def\setpdfdestname#1{{% + % We have to set dummies so commands such as @code, and characters + % such as \, aren't expanded when present in a section title. + \indexnofonts + \makevalueexpandable + \turnoffactive + \iftxiuseunicodedestname + \ifx \declaredencoding \latone + % Pass through Latin-1 characters. + % LuaTeX with byte wise I/O converts Latin-1 characters to Unicode. + \else + \ifx \declaredencoding \utfeight + % Pass through Unicode characters. + \else + % Use ASCII approximations in destination names. + \passthroughcharsfalse + \fi + \fi + \else + % Use ASCII approximations in destination names. + \passthroughcharsfalse + \fi + \def\pdfdestname{#1}% + \txiescapepdf\pdfdestname + }} + % + \def\setpdfoutlinetext#1{{% + \indexnofonts + \makevalueexpandable + \turnoffactive + \ifx \declaredencoding \latone + % The PDF format can use an extended form of Latin-1 in bookmark + % strings. See Appendix D of the PDF Reference, Sixth Edition, for + % the "PDFDocEncoding". + \passthroughcharstrue + % Pass through Latin-1 characters. + % LuaTeX: Convert to Unicode + % pdfTeX: Use Latin-1 as PDFDocEncoding + \def\pdfoutlinetext{#1}% + \else + \ifx \declaredencoding \utfeight + \ifx\luatexversion\thisisundefined + % For pdfTeX with UTF-8. + % TODO: the PDF format can use UTF-16 in bookmark strings, + % but the code for this isn't done yet. + % Use ASCII approximations. + \passthroughcharsfalse + \def\pdfoutlinetext{#1}% + \else + % For LuaTeX with UTF-8. + % Pass through Unicode characters for title texts. + \passthroughcharstrue + \def\pdfoutlinetext{#1}% + \fi + \else + % For non-Latin-1 or non-UTF-8 encodings. + % Use ASCII approximations. + \passthroughcharsfalse + \def\pdfoutlinetext{#1}% + \fi + \fi + % LuaTeX: Convert to UTF-16 + % pdfTeX: Use Latin-1 as PDFDocEncoding + \txiescapepdfutfsixteen\pdfoutlinetext + }} + % + \def\pdfmkdest#1{% + \setpdfdestname{#1}% + \safewhatsit{\pdfdest name{\pdfdestname} xyz}% + } + % + % used to mark target names; must be expandable. + \def\pdfmkpgn#1{#1} + % + % by default, use black for everything. + \def\urlcolor{\rgbBlack} + \def\linkcolor{\rgbBlack} + \def\endlink{\setcolor{\maincolor}\pdfendlink} + % + % Adding outlines to PDF; macros for calculating structure of outlines + % come from Petr Olsak + \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% + \else \csname#1\endcsname \fi} + \def\advancenumber#1{\tempnum=\expnumber{#1}\relax + \advance\tempnum by 1 + \expandafter\xdef\csname#1\endcsname{\the\tempnum}} + % + % #1 is the section text, which is what will be displayed in the + % outline by the pdf viewer. #2 is the pdf expression for the number + % of subentries (or empty, for subsubsections). #3 is the node text, + % which might be empty if this toc entry had no corresponding node. + % #4 is the page number + % + \def\dopdfoutline#1#2#3#4{% + % Generate a link to the node text if that exists; else, use the + % page number. We could generate a destination for the section + % text in the case where a section has no node, but it doesn't + % seem worth the trouble, since most documents are normally structured. + \setpdfoutlinetext{#1} + \setpdfdestname{#3} + \ifx\pdfdestname\empty + \def\pdfdestname{#4}% + \fi + % + \pdfoutline goto name{\pdfmkpgn{\pdfdestname}}#2{\pdfoutlinetext}% + } + % + \def\pdfmakeoutlines{% + \begingroup + % Read toc silently, to get counts of subentries for \pdfoutline. + \def\partentry##1##2##3##4{}% ignore parts in the outlines + \def\numchapentry##1##2##3##4{% + \def\thischapnum{##2}% + \def\thissecnum{0}% + \def\thissubsecnum{0}% + }% + \def\numsecentry##1##2##3##4{% + \advancenumber{chap\thischapnum}% + \def\thissecnum{##2}% + \def\thissubsecnum{0}% + }% + \def\numsubsecentry##1##2##3##4{% + \advancenumber{sec\thissecnum}% + \def\thissubsecnum{##2}% + }% + \def\numsubsubsecentry##1##2##3##4{% + \advancenumber{subsec\thissubsecnum}% + }% + \def\thischapnum{0}% + \def\thissecnum{0}% + \def\thissubsecnum{0}% + % + % use \def rather than \let here because we redefine \chapentry et + % al. a second time, below. + \def\appentry{\numchapentry}% + \def\appsecentry{\numsecentry}% + \def\appsubsecentry{\numsubsecentry}% + \def\appsubsubsecentry{\numsubsubsecentry}% + \def\unnchapentry{\numchapentry}% + \def\unnsecentry{\numsecentry}% + \def\unnsubsecentry{\numsubsecentry}% + \def\unnsubsubsecentry{\numsubsubsecentry}% + \readdatafile{toc}% + % + % Read toc second time, this time actually producing the outlines. + % The `-' means take the \expnumber as the absolute number of + % subentries, which we calculated on our first read of the .toc above. + % + % We use the node names as the destinations. + \def\numchapentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}% + \def\numsecentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}% + \def\numsubsecentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}% + \def\numsubsubsecentry##1##2##3##4{% count is always zero + \dopdfoutline{##1}{}{##3}{##4}}% + % + % PDF outlines are displayed using system fonts, instead of + % document fonts. Therefore we cannot use special characters, + % since the encoding is unknown. For example, the eogonek from + % Latin 2 (0xea) gets translated to a | character. Info from + % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100. + % + % TODO this right, we have to translate 8-bit characters to + % their "best" equivalent, based on the @documentencoding. Too + % much work for too little return. Just use the ASCII equivalents + % we use for the index sort strings. + % + \indexnofonts + \setupdatafile + % We can have normal brace characters in the PDF outlines, unlike + % Texinfo index files. So set that up. + \def\{{\lbracecharliteral}% + \def\}{\rbracecharliteral}% + \catcode`\\=\active \otherbackslash + \input \tocreadfilename + \endgroup + } + {\catcode`[=1 \catcode`]=2 + \catcode`{=\other \catcode`}=\other + \gdef\lbracecharliteral[{]% + \gdef\rbracecharliteral[}]% + ] + % + \def\skipspaces#1{\def\PP{#1}\def\D{|}% + \ifx\PP\D\let\nextsp\relax + \else\let\nextsp\skipspaces + \addtokens{\filename}{\PP}% + \advance\filenamelength by 1 + \fi + \nextsp} + \def\getfilename#1{% + \filenamelength=0 + % If we don't expand the argument now, \skipspaces will get + % snagged on things like "@value{foo}". + \edef\temp{#1}% + \expandafter\skipspaces\temp|\relax + } + \ifnum\pdftexversion < 14 + \let \startlink \pdfannotlink + \else + \let \startlink \pdfstartlink + \fi + % make a live url in pdf output. + \def\pdfurl#1{% + \begingroup + % it seems we really need yet another set of dummies; have not + % tried to figure out what each command should do in the context + % of @url. for now, just make @/ a no-op, that's the only one + % people have actually reported a problem with. + % + \normalturnoffactive + \def\@{@}% + \let\/=\empty + \makevalueexpandable + % do we want to go so far as to use \indexnofonts instead of just + % special-casing \var here? + \def\var##1{##1}% + % + \leavevmode\setcolor{\urlcolor}% + \startlink attr{/Border [0 0 0]}% + user{/Subtype /Link /A << /S /URI /URI (#1) >>}% + \endgroup} + \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} + \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} + \def\maketoks{% + \expandafter\poptoks\the\toksA|ENDTOKS|\relax + \ifx\first0\adn0 + \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 + \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 + \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 + \else + \ifnum0=\countA\else\makelink\fi + \ifx\first.\let\next=\done\else + \let\next=\maketoks + \addtokens{\toksB}{\the\toksD} + \ifx\first,\addtokens{\toksB}{\space}\fi + \fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \next} + \def\makelink{\addtokens{\toksB}% + {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} + \def\pdflink#1{% + \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} + \setcolor{\linkcolor}#1\endlink} + \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} +\else + % non-pdf mode + \let\pdfmkdest = \gobble + \let\pdfurl = \gobble + \let\endlink = \relax + \let\setcolor = \gobble + \let\pdfsetcolor = \gobble + \let\pdfmakeoutlines = \relax +\fi % \ifx\pdfoutput + +% +% For XeTeX +% +\ifx\XeTeXrevision\thisisundefined +\else + % + % XeTeX version check + % + \ifnum\strcmp{\the\XeTeXversion\XeTeXrevision}{0.99996}>-1 + % TeX Live 2016 contains XeTeX 0.99996 and xdvipdfmx 20160307. + % It can use the `dvipdfmx:config' special (from TeX Live SVN r40941). + % For avoiding PDF destination name replacement, we use this special + % instead of xdvipdfmx's command line option `-C 0x0010'. + \special{dvipdfmx:config C 0x0010} + % XeTeX 0.99995+ comes with xdvipdfmx 20160307+. + % It can handle Unicode destination names for PDF. + \txiuseunicodedestnametrue + \else + % XeTeX < 0.99996 (TeX Live < 2016) cannot use the + % `dvipdfmx:config' special. + % So for avoiding PDF destination name replacement, + % xdvipdfmx's command line option `-C 0x0010' is necessary. + % + % XeTeX < 0.99995 can not handle Unicode destination names for PDF + % because xdvipdfmx 20150315 has a UTF-16 conversion issue. + % It is fixed by xdvipdfmx 20160106 (TeX Live SVN r39753). + \txiuseunicodedestnamefalse + \fi + % + % Color support + % + \def\rgbDarkRed{0.50 0.09 0.12} + \def\rgbBlack{0 0 0} + % + \def\pdfsetcolor#1{\special{pdf:scolor [#1]}} + % + % Set color, and create a mark which defines \thiscolor accordingly, + % so that \makeheadline knows which color to restore. + \def\setcolor#1{% + \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}% + \domark + \pdfsetcolor{#1}% + } + % + \def\maincolor{\rgbBlack} + \pdfsetcolor{\maincolor} + \edef\thiscolor{\maincolor} + \def\lastcolordefs{} + % + \def\makefootline{% + \baselineskip24pt + \line{\pdfsetcolor{\maincolor}\the\footline}% + } + % + \def\makeheadline{% + \vbox to 0pt{% + \vskip-22.5pt + \line{% + \vbox to8.5pt{}% + % Extract \thiscolor definition from the marks. + \getcolormarks + % Typeset the headline with \maincolor, then restore the color. + \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}% + }% + \vss + }% + \nointerlineskip + } + % + % PDF outline support + % + % Emulate pdfTeX primitive + \def\pdfdest name#1 xyz{% + \special{pdf:dest (#1) [@thispage /XYZ @xpos @ypos null]}% + } + % + \def\setpdfdestname#1{{% + % We have to set dummies so commands such as @code, and characters + % such as \, aren't expanded when present in a section title. + \indexnofonts + \makevalueexpandable + \turnoffactive + \iftxiuseunicodedestname + % Pass through Unicode characters. + \else + % Use ASCII approximations in destination names. + \passthroughcharsfalse + \fi + \def\pdfdestname{#1}% + \txiescapepdf\pdfdestname + }} + % + \def\setpdfoutlinetext#1{{% + \turnoffactive + % Always use Unicode characters in title texts. + \def\pdfoutlinetext{#1}% + % For XeTeX, xdvipdfmx converts to UTF-16. + % So we do not convert. + \txiescapepdf\pdfoutlinetext + }} + % + \def\pdfmkdest#1{% + \setpdfdestname{#1}% + \safewhatsit{\pdfdest name{\pdfdestname} xyz}% + } + % + % by default, use black for everything. + \def\urlcolor{\rgbBlack} + \def\linkcolor{\rgbBlack} + \def\endlink{\setcolor{\maincolor}\pdfendlink} + % + \def\dopdfoutline#1#2#3#4{% + \setpdfoutlinetext{#1} + \setpdfdestname{#3} + \ifx\pdfdestname\empty + \def\pdfdestname{#4}% + \fi + % + \special{pdf:out [-] #2 << /Title (\pdfoutlinetext) /A + << /S /GoTo /D (\pdfdestname) >> >> }% + } + % + \def\pdfmakeoutlines{% + \begingroup + % + % For XeTeX, counts of subentries are not necessary. + % Therefore, we read toc only once. + % + % We use node names as destinations. + \def\partentry##1##2##3##4{}% ignore parts in the outlines + \def\numchapentry##1##2##3##4{% + \dopdfoutline{##1}{1}{##3}{##4}}% + \def\numsecentry##1##2##3##4{% + \dopdfoutline{##1}{2}{##3}{##4}}% + \def\numsubsecentry##1##2##3##4{% + \dopdfoutline{##1}{3}{##3}{##4}}% + \def\numsubsubsecentry##1##2##3##4{% + \dopdfoutline{##1}{4}{##3}{##4}}% + % + \let\appentry\numchapentry% + \let\appsecentry\numsecentry% + \let\appsubsecentry\numsubsecentry% + \let\appsubsubsecentry\numsubsubsecentry% + \let\unnchapentry\numchapentry% + \let\unnsecentry\numsecentry% + \let\unnsubsecentry\numsubsecentry% + \let\unnsubsubsecentry\numsubsubsecentry% + % + % For XeTeX, xdvipdfmx converts strings to UTF-16. + % Therefore, the encoding and the language may not be considered. + % + \indexnofonts + \setupdatafile + % We can have normal brace characters in the PDF outlines, unlike + % Texinfo index files. So set that up. + \def\{{\lbracecharliteral}% + \def\}{\rbracecharliteral}% + \catcode`\\=\active \otherbackslash + \input \tocreadfilename + \endgroup + } + {\catcode`[=1 \catcode`]=2 + \catcode`{=\other \catcode`}=\other + \gdef\lbracecharliteral[{]% + \gdef\rbracecharliteral[}]% + ] + + \special{pdf:docview << /PageMode /UseOutlines >> } + % ``\special{pdf:tounicode ...}'' is not necessary + % because xdvipdfmx converts strings from UTF-8 to UTF-16 without it. + % However, due to a UTF-16 conversion issue of xdvipdfmx 20150315, + % ``\special{pdf:dest ...}'' cannot handle non-ASCII strings. + % It is fixed by xdvipdfmx 20160106 (TeX Live SVN r39753). +% + \def\skipspaces#1{\def\PP{#1}\def\D{|}% + \ifx\PP\D\let\nextsp\relax + \else\let\nextsp\skipspaces + \addtokens{\filename}{\PP}% + \advance\filenamelength by 1 + \fi + \nextsp} + \def\getfilename#1{% + \filenamelength=0 + % If we don't expand the argument now, \skipspaces will get + % snagged on things like "@value{foo}". + \edef\temp{#1}% + \expandafter\skipspaces\temp|\relax + } + % make a live url in pdf output. + \def\pdfurl#1{% + \begingroup + % it seems we really need yet another set of dummies; have not + % tried to figure out what each command should do in the context + % of @url. for now, just make @/ a no-op, that's the only one + % people have actually reported a problem with. + % + \normalturnoffactive + \def\@{@}% + \let\/=\empty + \makevalueexpandable + % do we want to go so far as to use \indexnofonts instead of just + % special-casing \var here? + \def\var##1{##1}% + % + \leavevmode\setcolor{\urlcolor}% + \special{pdf:bann << /Border [0 0 0] + /Subtype /Link /A << /S /URI /URI (#1) >> >>}% + \endgroup} + \def\endlink{\setcolor{\maincolor}\special{pdf:eann}} + \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} + \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} + \def\maketoks{% + \expandafter\poptoks\the\toksA|ENDTOKS|\relax + \ifx\first0\adn0 + \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 + \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 + \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 + \else + \ifnum0=\countA\else\makelink\fi + \ifx\first.\let\next=\done\else + \let\next=\maketoks + \addtokens{\toksB}{\the\toksD} + \ifx\first,\addtokens{\toksB}{\space}\fi + \fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \next} + \def\makelink{\addtokens{\toksB}% + {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} + \def\pdflink#1{% + \special{pdf:bann << /Border [0 0 0] + /Type /Annot /Subtype /Link /A << /S /GoTo /D (#1) >> >>}% + \setcolor{\linkcolor}#1\endlink} + \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} +% + % + % @image support + % + % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). + \def\doxeteximage#1#2#3{% + \def\xeteximagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% + \def\xeteximageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% + % + % XeTeX (and the PDF format) supports .pdf, .png, .jpg (among + % others). Let's try in that order, PDF first since if + % someone has a scalable image, presumably better to use that than a + % bitmap. + \let\xeteximgext=\empty + \begingroup + \openin 1 #1.pdf \ifeof 1 + \openin 1 #1.PDF \ifeof 1 + \openin 1 #1.png \ifeof 1 + \openin 1 #1.jpg \ifeof 1 + \openin 1 #1.jpeg \ifeof 1 + \openin 1 #1.JPG \ifeof 1 + \errmessage{Could not find image file #1 for XeTeX}% + \else \gdef\xeteximgext{JPG}% + \fi + \else \gdef\xeteximgext{jpeg}% + \fi + \else \gdef\xeteximgext{jpg}% + \fi + \else \gdef\xeteximgext{png}% + \fi + \else \gdef\xeteximgext{PDF}% + \fi + \else \gdef\xeteximgext{pdf}% + \fi + \closein 1 + \endgroup + % + \def\xetexpdfext{pdf}% + \ifx\xeteximgext\xetexpdfext + \XeTeXpdffile "#1".\xeteximgext "" + \else + \def\xetexpdfext{PDF}% + \ifx\xeteximgext\xetexpdfext + \XeTeXpdffile "#1".\xeteximgext "" + \else + \XeTeXpicfile "#1".\xeteximgext "" + \fi + \fi + \ifdim \wd0 >0pt width \xeteximagewidth \fi + \ifdim \wd2 >0pt height \xeteximageheight \fi \relax + } +\fi + + +% +\message{fonts,} + +% Set the baselineskip to #1, and the lineskip and strut size +% correspondingly. There is no deep meaning behind these magic numbers +% used as factors; they just match (closely enough) what Knuth defined. +% +\def\lineskipfactor{.08333} +\def\strutheightpercent{.70833} +\def\strutdepthpercent {.29167} +% +% can get a sort of poor man's double spacing by redefining this. +\def\baselinefactor{1} +% +\newdimen\textleading +\def\setleading#1{% + \dimen0 = #1\relax + \normalbaselineskip = \baselinefactor\dimen0 + \normallineskip = \lineskipfactor\normalbaselineskip + \normalbaselines + \setbox\strutbox =\hbox{% + \vrule width0pt height\strutheightpercent\baselineskip + depth \strutdepthpercent \baselineskip + }% +} + +% PDF CMaps. See also LaTeX's t1.cmap. +% +% do nothing with this by default. +\expandafter\let\csname cmapOT1\endcsname\gobble +\expandafter\let\csname cmapOT1IT\endcsname\gobble +\expandafter\let\csname cmapOT1TT\endcsname\gobble + +% if we are producing pdf, and we have \pdffontattr, then define cmaps. +% (\pdffontattr was introduced many years ago, but people still run +% older pdftex's; it's easy to conditionalize, so we do.) +\ifpdf \ifx\pdffontattr\thisisundefined \else + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1-0) +%%Title: (TeX-OT1-0 TeX OT1 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1) +/Supplement 0 +>> def +/CMapName /TeX-OT1-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +8 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<23> <26> <0023> +<28> <3B> <0028> +<3F> <5B> <003F> +<5D> <5E> <005D> +<61> <7A> <0061> +<7B> <7C> <2013> +endbfrange +40 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <00660066> +<0C> <00660069> +<0D> <0066006C> +<0E> <006600660069> +<0F> <00660066006C> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<21> <0021> +<22> <201D> +<27> <2019> +<3C> <00A1> +<3D> <003D> +<3E> <00BF> +<5C> <201C> +<5F> <02D9> +<60> <2018> +<7D> <02DD> +<7E> <007E> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +% +% \cmapOT1IT + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1IT-0) +%%Title: (TeX-OT1IT-0 TeX OT1IT 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1IT) +/Supplement 0 +>> def +/CMapName /TeX-OT1IT-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +8 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<25> <26> <0025> +<28> <3B> <0028> +<3F> <5B> <003F> +<5D> <5E> <005D> +<61> <7A> <0061> +<7B> <7C> <2013> +endbfrange +42 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <00660066> +<0C> <00660069> +<0D> <0066006C> +<0E> <006600660069> +<0F> <00660066006C> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<21> <0021> +<22> <201D> +<23> <0023> +<24> <00A3> +<27> <2019> +<3C> <00A1> +<3D> <003D> +<3E> <00BF> +<5C> <201C> +<5F> <02D9> +<60> <2018> +<7D> <02DD> +<7E> <007E> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1IT\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +% +% \cmapOT1TT + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1TT-0) +%%Title: (TeX-OT1TT-0 TeX OT1TT 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1TT) +/Supplement 0 +>> def +/CMapName /TeX-OT1TT-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +5 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<21> <26> <0021> +<28> <5F> <0028> +<61> <7E> <0061> +endbfrange +32 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <2191> +<0C> <2193> +<0D> <0027> +<0E> <00A1> +<0F> <00BF> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<20> <2423> +<27> <2019> +<60> <2018> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1TT\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +\fi\fi + + +% Set the font macro #1 to the font named \fontprefix#2. +% #3 is the font's design size, #4 is a scale factor, #5 is the CMap +% encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit). +% Example: +% #1 = \textrm +% #2 = \rmshape +% #3 = 10 +% #4 = \mainmagstep +% #5 = OT1 +% +\def\setfont#1#2#3#4#5{% + \font#1=\fontprefix#2#3 scaled #4 + \csname cmap#5\endcsname#1% +} +% This is what gets called when #5 of \setfont is empty. +\let\cmap\gobble +% +% (end of cmaps) + +% Use cm as the default font prefix. +% To specify the font prefix, you must define \fontprefix +% before you read in texinfo.tex. +\ifx\fontprefix\thisisundefined +\def\fontprefix{cm} +\fi +% Support font families that don't use the same naming scheme as CM. +\def\rmshape{r} +\def\rmbshape{bx} % where the normal face is bold +\def\bfshape{b} +\def\bxshape{bx} +\def\ttshape{tt} +\def\ttbshape{tt} +\def\ttslshape{sltt} +\def\itshape{ti} +\def\itbshape{bxti} +\def\slshape{sl} +\def\slbshape{bxsl} +\def\sfshape{ss} +\def\sfbshape{ss} +\def\scshape{csc} +\def\scbshape{csc} + +% Definitions for a main text size of 11pt. (The default in Texinfo.) +% +\def\definetextfontsizexi{% +% Text fonts (11.2pt, magstep1). +\def\textnominalsize{11pt} +\edef\mainmagstep{\magstephalf} +\setfont\textrm\rmshape{10}{\mainmagstep}{OT1} +\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} +\setfont\textbf\bfshape{10}{\mainmagstep}{OT1} +\setfont\textit\itshape{10}{\mainmagstep}{OT1IT} +\setfont\textsl\slshape{10}{\mainmagstep}{OT1} +\setfont\textsf\sfshape{10}{\mainmagstep}{OT1} +\setfont\textsc\scshape{10}{\mainmagstep}{OT1} +\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep +\def\textecsize{1095} + +% A few fonts for @defun names and args. +\setfont\defbf\bfshape{10}{\magstep1}{OT1} +\setfont\deftt\ttshape{10}{\magstep1}{OT1TT} +\setfont\defsl\slshape{10}{\magstep1}{OT1TT} +\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT} +\def\df{\let\ttfont=\deftt \let\bffont = \defbf +\let\ttslfont=\defttsl \let\slfont=\defsl \bf} + +% Fonts for indices, footnotes, small examples (9pt). +\def\smallnominalsize{9pt} +\setfont\smallrm\rmshape{9}{1000}{OT1} +\setfont\smalltt\ttshape{9}{1000}{OT1TT} +\setfont\smallbf\bfshape{10}{900}{OT1} +\setfont\smallit\itshape{9}{1000}{OT1IT} +\setfont\smallsl\slshape{9}{1000}{OT1} +\setfont\smallsf\sfshape{9}{1000}{OT1} +\setfont\smallsc\scshape{10}{900}{OT1} +\setfont\smallttsl\ttslshape{10}{900}{OT1TT} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 +\def\smallecsize{0900} + +% Fonts for small examples (8pt). +\def\smallernominalsize{8pt} +\setfont\smallerrm\rmshape{8}{1000}{OT1} +\setfont\smallertt\ttshape{8}{1000}{OT1TT} +\setfont\smallerbf\bfshape{10}{800}{OT1} +\setfont\smallerit\itshape{8}{1000}{OT1IT} +\setfont\smallersl\slshape{8}{1000}{OT1} +\setfont\smallersf\sfshape{8}{1000}{OT1} +\setfont\smallersc\scshape{10}{800}{OT1} +\setfont\smallerttsl\ttslshape{10}{800}{OT1TT} +\font\smalleri=cmmi8 +\font\smallersy=cmsy8 +\def\smallerecsize{0800} + +% Fonts for title page (20.4pt): +\def\titlenominalsize{20pt} +\setfont\titlerm\rmbshape{12}{\magstep3}{OT1} +\setfont\titleit\itbshape{10}{\magstep4}{OT1IT} +\setfont\titlesl\slbshape{10}{\magstep4}{OT1} +\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} +\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} +\setfont\titlesf\sfbshape{17}{\magstep1}{OT1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4}{OT1} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\titleecsize{2074} + +% Chapter (and unnumbered) fonts (17.28pt). +\def\chapnominalsize{17pt} +\setfont\chaprm\rmbshape{12}{\magstep2}{OT1} +\setfont\chapit\itbshape{10}{\magstep3}{OT1IT} +\setfont\chapsl\slbshape{10}{\magstep3}{OT1} +\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT} +\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT} +\setfont\chapsf\sfbshape{17}{1000}{OT1} +\let\chapbf=\chaprm +\setfont\chapsc\scbshape{10}{\magstep3}{OT1} +\font\chapi=cmmi12 scaled \magstep2 +\font\chapsy=cmsy10 scaled \magstep3 +\def\chapecsize{1728} + +% Section fonts (14.4pt). +\def\secnominalsize{14pt} +\setfont\secrm\rmbshape{12}{\magstep1}{OT1} +\setfont\secrmnotbold\rmshape{12}{\magstep1}{OT1} +\setfont\secit\itbshape{10}{\magstep2}{OT1IT} +\setfont\secsl\slbshape{10}{\magstep2}{OT1} +\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT} +\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT} +\setfont\secsf\sfbshape{12}{\magstep1}{OT1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep2}{OT1} +\font\seci=cmmi12 scaled \magstep1 +\font\secsy=cmsy10 scaled \magstep2 +\def\sececsize{1440} + +% Subsection fonts (13.15pt). +\def\ssecnominalsize{13pt} +\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1} +\setfont\ssecit\itbshape{10}{1315}{OT1IT} +\setfont\ssecsl\slbshape{10}{1315}{OT1} +\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT} +\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT} +\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{1315}{OT1} +\font\sseci=cmmi12 scaled \magstephalf +\font\ssecsy=cmsy10 scaled 1315 +\def\ssececsize{1200} + +% Reduced fonts for @acronym in text (10pt). +\def\reducednominalsize{10pt} +\setfont\reducedrm\rmshape{10}{1000}{OT1} +\setfont\reducedtt\ttshape{10}{1000}{OT1TT} +\setfont\reducedbf\bfshape{10}{1000}{OT1} +\setfont\reducedit\itshape{10}{1000}{OT1IT} +\setfont\reducedsl\slshape{10}{1000}{OT1} +\setfont\reducedsf\sfshape{10}{1000}{OT1} +\setfont\reducedsc\scshape{10}{1000}{OT1} +\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT} +\font\reducedi=cmmi10 +\font\reducedsy=cmsy10 +\def\reducedecsize{1000} + +\textleading = 13.2pt % line spacing for 11pt CM +\textfonts % reset the current fonts +\rm +} % end of 11pt text font size definitions, \definetextfontsizexi + + +% Definitions to make the main text be 10pt Computer Modern, with +% section, chapter, etc., sizes following suit. This is for the GNU +% Press printing of the Emacs 22 manual. Maybe other manuals in the +% future. Used with @smallbook, which sets the leading to 12pt. +% +\def\definetextfontsizex{% +% Text fonts (10pt). +\def\textnominalsize{10pt} +\edef\mainmagstep{1000} +\setfont\textrm\rmshape{10}{\mainmagstep}{OT1} +\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} +\setfont\textbf\bfshape{10}{\mainmagstep}{OT1} +\setfont\textit\itshape{10}{\mainmagstep}{OT1IT} +\setfont\textsl\slshape{10}{\mainmagstep}{OT1} +\setfont\textsf\sfshape{10}{\mainmagstep}{OT1} +\setfont\textsc\scshape{10}{\mainmagstep}{OT1} +\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep +\def\textecsize{1000} + +% A few fonts for @defun names and args. +\setfont\defbf\bfshape{10}{\magstephalf}{OT1} +\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT} +\setfont\defsl\slshape{10}{\magstephalf}{OT1TT} +\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT} +\def\df{\let\ttfont=\deftt \let\bffont = \defbf +\let\slfont=\defsl \let\ttslfont=\defttsl \bf} + +% Fonts for indices, footnotes, small examples (9pt). +\def\smallnominalsize{9pt} +\setfont\smallrm\rmshape{9}{1000}{OT1} +\setfont\smalltt\ttshape{9}{1000}{OT1TT} +\setfont\smallbf\bfshape{10}{900}{OT1} +\setfont\smallit\itshape{9}{1000}{OT1IT} +\setfont\smallsl\slshape{9}{1000}{OT1} +\setfont\smallsf\sfshape{9}{1000}{OT1} +\setfont\smallsc\scshape{10}{900}{OT1} +\setfont\smallttsl\ttslshape{10}{900}{OT1TT} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 +\def\smallecsize{0900} + +% Fonts for small examples (8pt). +\def\smallernominalsize{8pt} +\setfont\smallerrm\rmshape{8}{1000}{OT1} +\setfont\smallertt\ttshape{8}{1000}{OT1TT} +\setfont\smallerbf\bfshape{10}{800}{OT1} +\setfont\smallerit\itshape{8}{1000}{OT1IT} +\setfont\smallersl\slshape{8}{1000}{OT1} +\setfont\smallersf\sfshape{8}{1000}{OT1} +\setfont\smallersc\scshape{10}{800}{OT1} +\setfont\smallerttsl\ttslshape{10}{800}{OT1TT} +\font\smalleri=cmmi8 +\font\smallersy=cmsy8 +\def\smallerecsize{0800} + +% Fonts for title page (20.4pt): +\def\titlenominalsize{20pt} +\setfont\titlerm\rmbshape{12}{\magstep3}{OT1} +\setfont\titleit\itbshape{10}{\magstep4}{OT1IT} +\setfont\titlesl\slbshape{10}{\magstep4}{OT1} +\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} +\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} +\setfont\titlesf\sfbshape{17}{\magstep1}{OT1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4}{OT1} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\titleecsize{2074} + +% Chapter fonts (14.4pt). +\def\chapnominalsize{14pt} +\setfont\chaprm\rmbshape{12}{\magstep1}{OT1} +\setfont\chapit\itbshape{10}{\magstep2}{OT1IT} +\setfont\chapsl\slbshape{10}{\magstep2}{OT1} +\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT} +\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT} +\setfont\chapsf\sfbshape{12}{\magstep1}{OT1} +\let\chapbf\chaprm +\setfont\chapsc\scbshape{10}{\magstep2}{OT1} +\font\chapi=cmmi12 scaled \magstep1 +\font\chapsy=cmsy10 scaled \magstep2 +\def\chapecsize{1440} + +% Section fonts (12pt). +\def\secnominalsize{12pt} +\setfont\secrm\rmbshape{12}{1000}{OT1} +\setfont\secit\itbshape{10}{\magstep1}{OT1IT} +\setfont\secsl\slbshape{10}{\magstep1}{OT1} +\setfont\sectt\ttbshape{12}{1000}{OT1TT} +\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT} +\setfont\secsf\sfbshape{12}{1000}{OT1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep1}{OT1} +\font\seci=cmmi12 +\font\secsy=cmsy10 scaled \magstep1 +\def\sececsize{1200} + +% Subsection fonts (10pt). +\def\ssecnominalsize{10pt} +\setfont\ssecrm\rmbshape{10}{1000}{OT1} +\setfont\ssecit\itbshape{10}{1000}{OT1IT} +\setfont\ssecsl\slbshape{10}{1000}{OT1} +\setfont\ssectt\ttbshape{10}{1000}{OT1TT} +\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT} +\setfont\ssecsf\sfbshape{10}{1000}{OT1} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{1000}{OT1} +\font\sseci=cmmi10 +\font\ssecsy=cmsy10 +\def\ssececsize{1000} + +% Reduced fonts for @acronym in text (9pt). +\def\reducednominalsize{9pt} +\setfont\reducedrm\rmshape{9}{1000}{OT1} +\setfont\reducedtt\ttshape{9}{1000}{OT1TT} +\setfont\reducedbf\bfshape{10}{900}{OT1} +\setfont\reducedit\itshape{9}{1000}{OT1IT} +\setfont\reducedsl\slshape{9}{1000}{OT1} +\setfont\reducedsf\sfshape{9}{1000}{OT1} +\setfont\reducedsc\scshape{10}{900}{OT1} +\setfont\reducedttsl\ttslshape{10}{900}{OT1TT} +\font\reducedi=cmmi9 +\font\reducedsy=cmsy9 +\def\reducedecsize{0900} + +\divide\parskip by 2 % reduce space between paragraphs +\textleading = 12pt % line spacing for 10pt CM +\textfonts % reset the current fonts +\rm +} % end of 10pt text font size definitions, \definetextfontsizex + +% Fonts for short table of contents. +\setfont\shortcontrm\rmshape{12}{1000}{OT1} +\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12 +\setfont\shortcontsl\slshape{12}{1000}{OT1} +\setfont\shortconttt\ttshape{12}{1000}{OT1TT} + + +% We provide the user-level command +% @fonttextsize 10 +% (or 11) to redefine the text font size. pt is assumed. +% +\def\xiword{11} +\def\xword{10} +\def\xwordpt{10pt} +% +\parseargdef\fonttextsize{% + \def\textsizearg{#1}% + %\wlog{doing @fonttextsize \textsizearg}% + % + % Set \globaldefs so that documents can use this inside @tex, since + % makeinfo 4.8 does not support it, but we need it nonetheless. + % + \begingroup \globaldefs=1 + \ifx\textsizearg\xword \definetextfontsizex + \else \ifx\textsizearg\xiword \definetextfontsizexi + \else + \errhelp=\EMsimple + \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'} + \fi\fi + \endgroup +} + +% +% Change the current font style to #1, remembering it in \curfontstyle. +% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in +% italics, not bold italics. +% +\def\setfontstyle#1{% + \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd. + \csname #1font\endcsname % change the current font +} + +\def\rm{\fam=0 \setfontstyle{rm}} +\def\it{\fam=\itfam \setfontstyle{it}} +\def\sl{\fam=\slfam \setfontstyle{sl}} +\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf} +\def\tt{\fam=\ttfam \setfontstyle{tt}} + +% Texinfo sort of supports the sans serif font style, which plain TeX does not. +% So we set up a \sf. +\newfam\sffam +\def\sf{\fam=\sffam \setfontstyle{sf}} + +% We don't need math for this font style. +\def\ttsl{\setfontstyle{ttsl}} + + +% In order for the font changes to affect most math symbols and letters, +% we have to define the \textfont of the standard families. We don't +% bother to reset \scriptfont and \scriptscriptfont; awaiting user need. +% +\def\resetmathfonts{% + \textfont0=\rmfont \textfont1=\ifont \textfont2=\syfont + \textfont\itfam=\itfont \textfont\slfam=\slfont \textfont\bffam=\bffont + \textfont\ttfam=\ttfont \textfont\sffam=\sffont +} + +% + +% The font-changing commands (all called \...fonts) redefine the meanings +% of \STYLEfont, instead of just \STYLE. We do this because \STYLE needs +% to also set the current \fam for math mode. Our \STYLE (e.g., \rm) +% commands hardwire \STYLEfont to set the current font. +% +% Each font-changing command also sets the names \lsize (one size lower) +% and \lllsize (three sizes lower). These relative commands are used +% in, e.g., the LaTeX logo and acronyms. +% +% This all needs generalizing, badly. +% + +\def\assignfonts#1{% + \expandafter\let\expandafter\rmfont\csname #1rm\endcsname + \expandafter\let\expandafter\itfont\csname #1it\endcsname + \expandafter\let\expandafter\slfont\csname #1sl\endcsname + \expandafter\let\expandafter\bffont\csname #1bf\endcsname + \expandafter\let\expandafter\ttfont\csname #1tt\endcsname + \expandafter\let\expandafter\smallcaps\csname #1sc\endcsname + \expandafter\let\expandafter\sffont \csname #1sf\endcsname + \expandafter\let\expandafter\ifont \csname #1i\endcsname + \expandafter\let\expandafter\syfont \csname #1sy\endcsname + \expandafter\let\expandafter\ttslfont\csname #1ttsl\endcsname +} + +\newif\ifrmisbold + +% Select smaller font size with the current style. Used to change font size +% in, e.g., the LaTeX logo and acronyms. If we are using bold fonts for +% normal roman text, also use bold fonts for roman text in the smaller size. +\def\switchtolllsize{% + \expandafter\assignfonts\expandafter{\lllsize}% + \ifrmisbold + \let\rmfont\bffont + \fi + \csname\curfontstyle\endcsname +}% + +\def\switchtolsize{% + \expandafter\assignfonts\expandafter{\lsize}% + \ifrmisbold + \let\rmfont\bffont + \fi + \csname\curfontstyle\endcsname +}% + +\def\definefontsetatsize#1#2#3#4#5{% +\expandafter\def\csname #1fonts\endcsname{% + \def\curfontsize{#1}% + \def\lsize{#2}\def\lllsize{#3}% + \csname rmisbold#5\endcsname + \assignfonts{#1}% + \resetmathfonts + \setleading{#4}% +}} + +\definefontsetatsize{text} {reduced}{smaller}{\textleading}{false} +\definefontsetatsize{title} {chap} {subsec} {27pt} {true} +\definefontsetatsize{chap} {sec} {text} {19pt} {true} +\definefontsetatsize{sec} {subsec} {reduced}{17pt} {true} +\definefontsetatsize{ssec} {text} {small} {15pt} {true} +\definefontsetatsize{reduced}{small} {smaller}{10.5pt}{false} +\definefontsetatsize{small} {smaller}{smaller}{10.5pt}{false} +\definefontsetatsize{smaller}{smaller}{smaller}{9.5pt} {false} + +\def\titlefont#1{{\titlefonts\rm #1}} +\let\subsecfonts = \ssecfonts +\let\subsubsecfonts = \ssecfonts + +% Define these just so they can be easily changed for other fonts. +\def\angleleft{$\langle$} +\def\angleright{$\rangle$} + +% Set the fonts to use with the @small... environments. +\let\smallexamplefonts = \smallfonts + +% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample +% can fit this many characters: +% 8.5x11=86 smallbook=72 a4=90 a5=69 +% If we use \scriptfonts (8pt), then we can fit this many characters: +% 8.5x11=90+ smallbook=80 a4=90+ a5=77 +% For me, subjectively, the few extra characters that fit aren't worth +% the additional smallness of 8pt. So I'm making the default 9pt. +% +% By the way, for comparison, here's what fits with @example (10pt): +% 8.5x11=71 smallbook=60 a4=75 a5=58 +% --karl, 24jan03. + +% Set up the default fonts, so we can use them for creating boxes. +% +\definetextfontsizexi + + +\message{markup,} + +% Check if we are currently using a typewriter font. Since all the +% Computer Modern typewriter fonts have zero interword stretch (and +% shrink), and it is reasonable to expect all typewriter fonts to have +% this property, we can check that font parameter. +% +\def\ifmonospace{\ifdim\fontdimen3\font=0pt } + +% Markup style infrastructure. \defmarkupstylesetup\INITMACRO will +% define and register \INITMACRO to be called on markup style changes. +% \INITMACRO can check \currentmarkupstyle for the innermost +% style and the set of \ifmarkupSTYLE switches for all styles +% currently in effect. +\newif\ifmarkupvar +\newif\ifmarkupsamp +\newif\ifmarkupkey +%\newif\ifmarkupfile % @file == @samp. +%\newif\ifmarkupoption % @option == @samp. +\newif\ifmarkupcode +\newif\ifmarkupkbd +%\newif\ifmarkupenv % @env == @code. +%\newif\ifmarkupcommand % @command == @code. +\newif\ifmarkuptex % @tex (and part of @math, for now). +\newif\ifmarkupexample +\newif\ifmarkupverb +\newif\ifmarkupverbatim + +\let\currentmarkupstyle\empty + +\def\setupmarkupstyle#1{% + \csname markup#1true\endcsname + \def\currentmarkupstyle{#1}% + \markupstylesetup +} + +\let\markupstylesetup\empty + +\def\defmarkupstylesetup#1{% + \expandafter\def\expandafter\markupstylesetup + \expandafter{\markupstylesetup #1}% + \def#1% +} + +% Markup style setup for left and right quotes. +\defmarkupstylesetup\markupsetuplq{% + \expandafter\let\expandafter \temp + \csname markupsetuplq\currentmarkupstyle\endcsname + \ifx\temp\relax \markupsetuplqdefault \else \temp \fi +} + +\defmarkupstylesetup\markupsetuprq{% + \expandafter\let\expandafter \temp + \csname markupsetuprq\currentmarkupstyle\endcsname + \ifx\temp\relax \markupsetuprqdefault \else \temp \fi +} + +{ +\catcode`\'=\active +\catcode`\`=\active + +\gdef\markupsetuplqdefault{\let`\lq} +\gdef\markupsetuprqdefault{\let'\rq} + +\gdef\markupsetcodequoteleft{\let`\codequoteleft} +\gdef\markupsetcodequoteright{\let'\codequoteright} +} + +\let\markupsetuplqcode \markupsetcodequoteleft +\let\markupsetuprqcode \markupsetcodequoteright +% +\let\markupsetuplqexample \markupsetcodequoteleft +\let\markupsetuprqexample \markupsetcodequoteright +% +\let\markupsetuplqkbd \markupsetcodequoteleft +\let\markupsetuprqkbd \markupsetcodequoteright +% +\let\markupsetuplqsamp \markupsetcodequoteleft +\let\markupsetuprqsamp \markupsetcodequoteright +% +\let\markupsetuplqverb \markupsetcodequoteleft +\let\markupsetuprqverb \markupsetcodequoteright +% +\let\markupsetuplqverbatim \markupsetcodequoteleft +\let\markupsetuprqverbatim \markupsetcodequoteright + +% Allow an option to not use regular directed right quote/apostrophe +% (char 0x27), but instead the undirected quote from cmtt (char 0x0d). +% The undirected quote is ugly, so don't make it the default, but it +% works for pasting with more pdf viewers (at least evince), the +% lilypond developers report. xpdf does work with the regular 0x27. +% +\def\codequoteright{% + \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax + \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax + '% + \else \char'15 \fi + \else \char'15 \fi +} +% +% and a similar option for the left quote char vs. a grave accent. +% Modern fonts display ASCII 0x60 as a grave accent, so some people like +% the code environments to do likewise. +% +\def\codequoteleft{% + \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax + \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax + % [Knuth] pp. 380,381,391 + % \relax disables Spanish ligatures ?` and !` of \tt font. + \relax`% + \else \char'22 \fi + \else \char'22 \fi +} + +% Commands to set the quote options. +% +\parseargdef\codequoteundirected{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxicodequoteundirected\endcsname + = t% + \else\ifx\temp\offword + \expandafter\let\csname SETtxicodequoteundirected\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}% + \fi\fi +} +% +\parseargdef\codequotebacktick{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxicodequotebacktick\endcsname + = t% + \else\ifx\temp\offword + \expandafter\let\csname SETtxicodequotebacktick\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}% + \fi\fi +} + +% [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font. +\def\noligaturesquoteleft{\relax\lq} + +% Count depth in font-changes, for error checks +\newcount\fontdepth \fontdepth=0 + +% Font commands. + +% #1 is the font command (\sl or \it), #2 is the text to slant. +% If we are in a monospaced environment, however, 1) always use \ttsl, +% and 2) do not add an italic correction. +\def\dosmartslant#1#2{% + \ifusingtt + {{\ttsl #2}\let\next=\relax}% + {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}% + \next +} +\def\smartslanted{\dosmartslant\sl} +\def\smartitalic{\dosmartslant\it} + +% Output an italic correction unless \next (presumed to be the following +% character) is such as not to need one. +\def\smartitaliccorrection{% + \ifx\next,% + \else\ifx\next-% + \else\ifx\next.% + \else\ifx\next\.% + \else\ifx\next\comma% + \else\ptexslash + \fi\fi\fi\fi\fi + \aftersmartic +} + +% Unconditional use \ttsl, and no ic. @var is set to this for defuns. +\def\ttslanted#1{{\ttsl #1}} + +% @cite is like \smartslanted except unconditionally use \sl. We never want +% ttsl for book titles, do we? +\def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection} + +\def\aftersmartic{} +\def\var#1{% + \let\saveaftersmartic = \aftersmartic + \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}% + \smartslanted{#1}% +} + +\let\i=\smartitalic +\let\slanted=\smartslanted +\let\dfn=\smartslanted +\let\emph=\smartitalic + +% Explicit font changes: @r, @sc, undocumented @ii. +\def\r#1{{\rm #1}} % roman font +\def\sc#1{{\smallcaps#1}} % smallcaps font +\def\ii#1{{\it #1}} % italic font + +% @b, explicit bold. Also @strong. +\def\b#1{{\bf #1}} +\let\strong=\b + +% @sansserif, explicit sans. +\def\sansserif#1{{\sf #1}} + +% We can't just use \exhyphenpenalty, because that only has effect at +% the end of a paragraph. Restore normal hyphenation at the end of the +% group within which \nohyphenation is presumably called. +% +\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} +\def\restorehyphenation{\hyphenchar\font = `- } + +% Set sfcode to normal for the chars that usually have another value. +% Can't use plain's \frenchspacing because it uses the `\x notation, and +% sometimes \x has an active definition that messes things up. +% +\catcode`@=11 + \def\plainfrenchspacing{% + \sfcode`\.=\@m \sfcode`\?=\@m \sfcode`\!=\@m + \sfcode`\:=\@m \sfcode`\;=\@m \sfcode`\,=\@m + \def\endofsentencespacefactor{1000}% for @. and friends + } + \def\plainnonfrenchspacing{% + \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000 + \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250 + \def\endofsentencespacefactor{3000}% for @. and friends + } +\catcode`@=\other +\def\endofsentencespacefactor{3000}% default + +% @t, explicit typewriter. +\def\t#1{% + {\tt \rawbackslash \plainfrenchspacing #1}% + \null +} + +% @samp. +\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}} + +% @indicateurl is \samp, that is, with quotes. +\let\indicateurl=\samp + +% @code (and similar) prints in typewriter, but with spaces the same +% size as normal in the surrounding text, without hyphenation, etc. +% This is a subroutine for that. +\def\tclose#1{% + {% + % Change normal interword space to be same as for the current font. + \spaceskip = \fontdimen2\font + % + % Switch to typewriter. + \tt + % + % But `\ ' produces the large typewriter interword space. + \def\ {{\spaceskip = 0pt{} }}% + % + % Turn off hyphenation. + \nohyphenation + % + \rawbackslash + \plainfrenchspacing + #1% + }% + \null % reset spacefactor to 1000 +} + +% We *must* turn on hyphenation at `-' and `_' in @code. +% (But see \codedashfinish below.) +% Otherwise, it is too hard to avoid overfull hboxes +% in the Emacs manual, the Library manual, etc. +% +% Unfortunately, TeX uses one parameter (\hyphenchar) to control +% both hyphenation at - and hyphenation within words. +% We must therefore turn them both off (\tclose does that) +% and arrange explicitly to hyphenate at a dash. -- rms. +{ + \catcode`\-=\active \catcode`\_=\active + \catcode`\'=\active \catcode`\`=\active + \global\let'=\rq \global\let`=\lq % default definitions + % + \global\def\code{\begingroup + \setupmarkupstyle{code}% + % The following should really be moved into \setupmarkupstyle handlers. + \catcode\dashChar=\active \catcode\underChar=\active + \ifallowcodebreaks + \let-\codedash + \let_\codeunder + \else + \let-\normaldash + \let_\realunder + \fi + % Given -foo (with a single dash), we do not want to allow a break + % after the hyphen. + \global\let\codedashprev=\codedash + % + \codex + } + % + \gdef\codedash{\futurelet\next\codedashfinish} + \gdef\codedashfinish{% + \normaldash % always output the dash character itself. + % + % Now, output a discretionary to allow a line break, unless + % (a) the next character is a -, or + % (b) the preceding character is a -. + % E.g., given --posix, we do not want to allow a break after either -. + % Given --foo-bar, we do want to allow a break between the - and the b. + \ifx\next\codedash \else + \ifx\codedashprev\codedash + \else \discretionary{}{}{}\fi + \fi + % we need the space after the = for the case when \next itself is a + % space token; it would get swallowed otherwise. As in @code{- a}. + \global\let\codedashprev= \next + } +} +\def\normaldash{-} +% +\def\codex #1{\tclose{#1}\endgroup} + +\def\codeunder{% + % this is all so @math{@code{var_name}+1} can work. In math mode, _ + % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) + % will therefore expand the active definition of _, which is us + % (inside @code that is), therefore an endless loop. + \ifusingtt{\ifmmode + \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_. + \else\normalunderscore \fi + \discretionary{}{}{}}% + {\_}% +} + +% An additional complication: the above will allow breaks after, e.g., +% each of the four underscores in __typeof__. This is bad. +% @allowcodebreaks provides a document-level way to turn breaking at - +% and _ on and off. +% +\newif\ifallowcodebreaks \allowcodebreakstrue + +\def\keywordtrue{true} +\def\keywordfalse{false} + +\parseargdef\allowcodebreaks{% + \def\txiarg{#1}% + \ifx\txiarg\keywordtrue + \allowcodebreakstrue + \else\ifx\txiarg\keywordfalse + \allowcodebreaksfalse + \else + \errhelp = \EMsimple + \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}% + \fi\fi +} + +% For @command, @env, @file, @option quotes seem unnecessary, +% so use \code rather than \samp. +\let\command=\code +\let\env=\code +\let\file=\code +\let\option=\code + +% @uref (abbreviation for `urlref') aka @url takes an optional +% (comma-separated) second argument specifying the text to display and +% an optional third arg as text to display instead of (rather than in +% addition to) the url itself. First (mandatory) arg is the url. + +% TeX-only option to allow changing PDF output to show only the second +% arg (if given), and not the url (which is then just the link target). +\newif\ifurefurlonlylink + +% The main macro is \urefbreak, which allows breaking at expected +% places within the url. (There used to be another version, which +% didn't support automatic breaking.) +\def\urefbreak{\begingroup \urefcatcodes \dourefbreak} +\let\uref=\urefbreak +% +\def\dourefbreak#1{\urefbreakfinish #1,,,\finish} +\def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% look for second arg + \ifdim\wd0 > 0pt + \ifpdf + % For pdfTeX and LuaTeX + \ifurefurlonlylink + % PDF plus option to not display url, show just arg + \unhbox0 + \else + % PDF, normally display both arg and url for consistency, + % visibility, if the pdf is eventually used to print, etc. + \unhbox0\ (\urefcode{#1})% + \fi + \else + \ifx\XeTeXrevision\thisisundefined + \unhbox0\ (\urefcode{#1})% DVI, always show arg and url + \else + % For XeTeX + \ifurefurlonlylink + % PDF plus option to not display url, show just arg + \unhbox0 + \else + % PDF, normally display both arg and url for consistency, + % visibility, if the pdf is eventually used to print, etc. + \unhbox0\ (\urefcode{#1})% + \fi + \fi + \fi + \else + \urefcode{#1}% only url given, so show it + \fi + \fi + \endlink +\endgroup} + +% Allow line breaks around only a few characters (only). +\def\urefcatcodes{% + \catcode`\&=\active \catcode`\.=\active + \catcode`\#=\active \catcode`\?=\active + \catcode`\/=\active +} +{ + \urefcatcodes + % + \global\def\urefcode{\begingroup + \setupmarkupstyle{code}% + \urefcatcodes + \let&\urefcodeamp + \let.\urefcodedot + \let#\urefcodehash + \let?\urefcodequest + \let/\urefcodeslash + \codex + } + % + % By default, they are just regular characters. + \global\def&{\normalamp} + \global\def.{\normaldot} + \global\def#{\normalhash} + \global\def?{\normalquest} + \global\def/{\normalslash} +} + +% we put a little stretch before and after the breakable chars, to help +% line breaking of long url's. The unequal skips make look better in +% cmtt at least, especially for dots. +\def\urefprestretchamount{.13em} +\def\urefpoststretchamount{.1em} +\def\urefprestretch{\urefprebreak \hskip0pt plus\urefprestretchamount\relax} +\def\urefpoststretch{\urefpostbreak \hskip0pt plus\urefprestretchamount\relax} +% +\def\urefcodeamp{\urefprestretch \&\urefpoststretch} +\def\urefcodedot{\urefprestretch .\urefpoststretch} +\def\urefcodehash{\urefprestretch \#\urefpoststretch} +\def\urefcodequest{\urefprestretch ?\urefpoststretch} +\def\urefcodeslash{\futurelet\next\urefcodeslashfinish} +{ + \catcode`\/=\active + \global\def\urefcodeslashfinish{% + \urefprestretch \slashChar + % Allow line break only after the final / in a sequence of + % slashes, to avoid line break between the slashes in http://. + \ifx\next/\else \urefpoststretch \fi + } +} + +% One more complication: by default we'll break after the special +% characters, but some people like to break before the special chars, so +% allow that. Also allow no breaking at all, for manual control. +% +\parseargdef\urefbreakstyle{% + \def\txiarg{#1}% + \ifx\txiarg\wordnone + \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak} + \else\ifx\txiarg\wordbefore + \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak} + \else\ifx\txiarg\wordafter + \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak} + \else + \errhelp = \EMsimple + \errmessage{Unknown @urefbreakstyle setting `\txiarg'}% + \fi\fi\fi +} +\def\wordafter{after} +\def\wordbefore{before} +\def\wordnone{none} + +\urefbreakstyle after + +% @url synonym for @uref, since that's how everyone uses it. +% +\let\url=\uref + +% rms does not like angle brackets --karl, 17may97. +% So now @email is just like @uref, unless we are pdf. +% +%\def\email#1{\angleleft{\tt #1}\angleright} +\ifpdf + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} +\else + \ifx\XeTeXrevision\thisisundefined + \let\email=\uref + \else + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} + \fi +\fi + +% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), +% `example' (@kbd uses ttsl only inside of @example and friends), +% or `code' (@kbd uses normal tty font always). +\parseargdef\kbdinputstyle{% + \def\txiarg{#1}% + \ifx\txiarg\worddistinct + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% + \else\ifx\txiarg\wordexample + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% + \else\ifx\txiarg\wordcode + \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% + \else + \errhelp = \EMsimple + \errmessage{Unknown @kbdinputstyle setting `\txiarg'}% + \fi\fi\fi +} +\def\worddistinct{distinct} +\def\wordexample{example} +\def\wordcode{code} + +% Default is `distinct'. +\kbdinputstyle distinct + +% @kbd is like @code, except that if the argument is just one @key command, +% then @kbd has no effect. +\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}} + +\def\xkey{\key} +\def\kbdsub#1#2#3\par{% + \def\one{#1}\def\three{#3}\def\threex{??}% + \ifx\one\xkey\ifx\threex\three \key{#2}% + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi +} + +% definition of @key that produces a lozenge. Doesn't adjust to text size. +%\setfont\keyrm\rmshape{8}{1000}{OT1} +%\font\keysy=cmsy9 +%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% +% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% +% \vbox{\hrule\kern-0.4pt +% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% +% \kern-0.4pt\hrule}% +% \kern-.06em\raise0.4pt\hbox{\angleright}}}} + +% definition of @key with no lozenge. If the current font is already +% monospace, don't change it; that way, we respect @kbdinputstyle. But +% if it isn't monospace, then use \tt. +% +\def\key#1{{\setupmarkupstyle{key}% + \nohyphenation + \ifmonospace\else\tt\fi + #1}\null} + +% @clicksequence{File @click{} Open ...} +\def\clicksequence#1{\begingroup #1\endgroup} + +% @clickstyle @arrow (by default) +\parseargdef\clickstyle{\def\click{#1}} +\def\click{\arrow} + +% Typeset a dimension, e.g., `in' or `pt'. The only reason for the +% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. +% +\def\dmn#1{\thinspace #1} + +% @acronym for "FBI", "NATO", and the like. +% We print this one point size smaller, since it's intended for +% all-uppercase. +% +\def\acronym#1{\doacronym #1,,\finish} +\def\doacronym#1,#2,#3\finish{% + {\switchtolsize #1}% + \def\temp{#2}% + \ifx\temp\empty \else + \space ({\unsepspaces \ignorespaces \temp \unskip})% + \fi + \null % reset \spacefactor=1000 +} + +% @abbr for "Comput. J." and the like. +% No font change, but don't do end-of-sentence spacing. +% +\def\abbr#1{\doabbr #1,,\finish} +\def\doabbr#1,#2,#3\finish{% + {\plainfrenchspacing #1}% + \def\temp{#2}% + \ifx\temp\empty \else + \space ({\unsepspaces \ignorespaces \temp \unskip})% + \fi + \null % reset \spacefactor=1000 +} + +% @asis just yields its argument. Used with @table, for example. +% +\def\asis#1{#1} + +% @math outputs its argument in math mode. +% +% One complication: _ usually means subscripts, but it could also mean +% an actual _ character, as in @math{@var{some_variable} + 1}. So make +% _ active, and distinguish by seeing if the current family is \slfam, +% which is what @var uses. +{ + \catcode`\_ = \active + \gdef\mathunderscore{% + \catcode`\_=\active + \def_{\ifnum\fam=\slfam \_\else\sb\fi}% + } +} +% Another complication: we want \\ (and @\) to output a math (or tt) \. +% FYI, plain.tex uses \\ as a temporary control sequence (for no +% particular reason), but this is not advertised and we don't care. +% +% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. +\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} +% +\def\math{% + \ifmmode\else % only go into math if not in math mode already + \tex + \mathunderscore + \let\\ = \mathbackslash + \mathactive + % make the texinfo accent commands work in math mode + \let\"=\ddot + \let\'=\acute + \let\==\bar + \let\^=\hat + \let\`=\grave + \let\u=\breve + \let\v=\check + \let\~=\tilde + \let\dotaccent=\dot + % have to provide another name for sup operator + \let\mathopsup=\sup + $\expandafter\finishmath\fi +} +\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. + +% Some active characters (such as <) are spaced differently in math. +% We have to reset their definitions in case the @math was an argument +% to a command which sets the catcodes (such as @item or @section). +% +{ + \catcode`^ = \active + \catcode`< = \active + \catcode`> = \active + \catcode`+ = \active + \catcode`' = \active + \gdef\mathactive{% + \let^ = \ptexhat + \let< = \ptexless + \let> = \ptexgtr + \let+ = \ptexplus + \let' = \ptexquoteright + } +} + +% for @sub and @sup, if in math mode, just do a normal sub/superscript. +% If in text, use math to place as sub/superscript, but switch +% into text mode, with smaller fonts. This is a different font than the +% one used for real math sub/superscripts (8pt vs. 7pt), but let's not +% fix it (significant additions to font machinery) until someone notices. +% +\def\sub{\ifmmode \expandafter\sb \else \expandafter\finishsub\fi} +\def\finishsub#1{$\sb{\hbox{\switchtolllsize #1}}$}% +% +\def\sup{\ifmmode \expandafter\ptexsp \else \expandafter\finishsup\fi} +\def\finishsup#1{$\ptexsp{\hbox{\switchtolllsize #1}}$}% + +% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. +% Ignore unless FMTNAME == tex; then it is like @iftex and @tex, +% except specified as a normal braced arg, so no newlines to worry about. +% +\def\outfmtnametex{tex} +% +\long\def\inlinefmt#1{\doinlinefmt #1,\finish} +\long\def\doinlinefmt#1,#2,\finish{% + \def\inlinefmtname{#1}% + \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi +} +% +% @inlinefmtifelse{FMTNAME,THEN-TEXT,ELSE-TEXT} expands THEN-TEXT if +% FMTNAME is tex, else ELSE-TEXT. +\long\def\inlinefmtifelse#1{\doinlinefmtifelse #1,,,\finish} +\long\def\doinlinefmtifelse#1,#2,#3,#4,\finish{% + \def\inlinefmtname{#1}% + \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\else \ignorespaces #3\fi +} +% +% For raw, must switch into @tex before parsing the argument, to avoid +% setting catcodes prematurely. Doing it this way means that, for +% example, @inlineraw{html, foo{bar} gets a parse error instead of being +% ignored. But this isn't important because if people want a literal +% *right* brace they would have to use a command anyway, so they may as +% well use a command to get a left brace too. We could re-use the +% delimiter character idea from \verb, but it seems like overkill. +% +\long\def\inlineraw{\tex \doinlineraw} +\long\def\doinlineraw#1{\doinlinerawtwo #1,\finish} +\def\doinlinerawtwo#1,#2,\finish{% + \def\inlinerawname{#1}% + \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi + \endgroup % close group opened by \tex. +} + +% @inlineifset{VAR, TEXT} expands TEXT if VAR is @set. +% +\long\def\inlineifset#1{\doinlineifset #1,\finish} +\long\def\doinlineifset#1,#2,\finish{% + \def\inlinevarname{#1}% + \expandafter\ifx\csname SET\inlinevarname\endcsname\relax + \else\ignorespaces#2\fi +} + +% @inlineifclear{VAR, TEXT} expands TEXT if VAR is not @set. +% +\long\def\inlineifclear#1{\doinlineifclear #1,\finish} +\long\def\doinlineifclear#1,#2,\finish{% + \def\inlinevarname{#1}% + \expandafter\ifx\csname SET\inlinevarname\endcsname\relax \ignorespaces#2\fi +} + + +\message{glyphs,} +% and logos. + +% @@ prints an @, as does @atchar{}. +\def\@{\char64 } +\let\atchar=\@ + +% @{ @} @lbracechar{} @rbracechar{} all generate brace characters. +\def\lbracechar{{\ifmonospace\char123\else\ensuremath\lbrace\fi}} +\def\rbracechar{{\ifmonospace\char125\else\ensuremath\rbrace\fi}} +\let\{=\lbracechar +\let\}=\rbracechar + +% @comma{} to avoid , parsing problems. +\let\comma = , + +% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent +% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. +\let\, = \ptexc +\let\dotaccent = \ptexdot +\def\ringaccent#1{{\accent23 #1}} +\let\tieaccent = \ptext +\let\ubaraccent = \ptexb +\let\udotaccent = \d + +% Other special characters: @questiondown @exclamdown @ordf @ordm +% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. +\def\questiondown{?`} +\def\exclamdown{!`} +\def\ordf{\leavevmode\raise1ex\hbox{\switchtolllsize \underbar{a}}} +\def\ordm{\leavevmode\raise1ex\hbox{\switchtolllsize \underbar{o}}} + +% Dotless i and dotless j, used for accents. +\def\imacro{i} +\def\jmacro{j} +\def\dotless#1{% + \def\temp{#1}% + \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi + \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi + \else \errmessage{@dotless can be used only with i or j}% + \fi\fi +} + +% The \TeX{} logo, as in plain, but resetting the spacing so that a +% period following counts as ending a sentence. (Idea found in latex.) +% +\edef\TeX{\TeX \spacefactor=1000 } + +% @LaTeX{} logo. Not quite the same results as the definition in +% latex.ltx, since we use a different font for the raised A; it's most +% convenient for us to use an explicitly smaller font, rather than using +% the \scriptstyle font (since we don't reset \scriptstyle and +% \scriptscriptstyle). +% +\def\LaTeX{% + L\kern-.36em + {\setbox0=\hbox{T}% + \vbox to \ht0{\hbox{% + \ifx\textnominalsize\xwordpt + % for 10pt running text, lllsize (8pt) is too small for the A in LaTeX. + % Revert to plain's \scriptsize, which is 7pt. + \count255=\the\fam $\fam\count255 \scriptstyle A$% + \else + % For 11pt, we can use our lllsize. + \switchtolllsize A% + \fi + }% + \vss + }}% + \kern-.15em + \TeX +} + +% Some math mode symbols. Define \ensuremath to switch into math mode +% unless we are already there. Expansion tricks may not be needed here, +% but safer, and can't hurt. +\def\ensuremath{\ifmmode \expandafter\asis \else\expandafter\ensuredmath \fi} +\def\ensuredmath#1{$\relax#1$} +% +\def\bullet{\ensuremath\ptexbullet} +\def\geq{\ensuremath\ge} +\def\leq{\ensuremath\le} +\def\minus{\ensuremath-} + +% @dots{} outputs an ellipsis using the current font. +% We do .5em per period so that it has the same spacing in the cm +% typewriter fonts as three actual period characters; on the other hand, +% in other typewriter fonts three periods are wider than 1.5em. So do +% whichever is larger. +% +\def\dots{% + \leavevmode + \setbox0=\hbox{...}% get width of three periods + \ifdim\wd0 > 1.5em + \dimen0 = \wd0 + \else + \dimen0 = 1.5em + \fi + \hbox to \dimen0{% + \hskip 0pt plus.25fil + .\hskip 0pt plus1fil + .\hskip 0pt plus1fil + .\hskip 0pt plus.5fil + }% +} + +% @enddots{} is an end-of-sentence ellipsis. +% +\def\enddots{% + \dots + \spacefactor=\endofsentencespacefactor +} + +% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. +% +% Since these characters are used in examples, they should be an even number of +% \tt widths. Each \tt character is 1en, so two makes it 1em. +% +\def\point{$\star$} +\def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}} +\def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} +\def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}} +\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} +\def\equiv{\leavevmode\hbox to 1em{\hfil$\ptexequiv$\hfil}} + +% The @error{} command. +% Adapted from the TeXbook's \boxit. +% +\newbox\errorbox +% +{\ttfont \global\dimen0 = 3em}% Width of the box. +\dimen2 = .55pt % Thickness of rules +% The text. (`r' is open on the right, `e' somewhat less so on the left.) +\setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt} +% +\setbox\errorbox=\hbox to \dimen0{\hfil + \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. + \advance\hsize by -2\dimen2 % Rules. + \vbox{% + \hrule height\dimen2 + \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. + \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. + \kern3pt\vrule width\dimen2}% Space to right. + \hrule height\dimen2} + \hfil} +% +\def\error{\leavevmode\lower.7ex\copy\errorbox} + +% @pounds{} is a sterling sign, which Knuth put in the CM italic font. +% +\def\pounds{{\it\$}} + +% @euro{} comes from a separate font, depending on the current style. +% We use the free feym* fonts from the eurosym package by Henrik +% Theiling, which support regular, slanted, bold and bold slanted (and +% "outlined" (blackboard board, sort of) versions, which we don't need). +% It is available from http://www.ctan.org/tex-archive/fonts/eurosym. +% +% Although only regular is the truly official Euro symbol, we ignore +% that. The Euro is designed to be slightly taller than the regular +% font height. +% +% feymr - regular +% feymo - slanted +% feybr - bold +% feybo - bold slanted +% +% There is no good (free) typewriter version, to my knowledge. +% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide. +% Hmm. +% +% Also doesn't work in math. Do we need to do math with euro symbols? +% Hope not. +% +% +\def\euro{{\eurofont e}} +\def\eurofont{% + % We set the font at each command, rather than predefining it in + % \textfonts and the other font-switching commands, so that + % installations which never need the symbol don't have to have the + % font installed. + % + % There is only one designed size (nominal 10pt), so we always scale + % that to the current nominal size. + % + % By the way, simply using "at 1em" works for cmr10 and the like, but + % does not work for cmbx10 and other extended/shrunken fonts. + % + \def\eurosize{\csname\curfontsize nominalsize\endcsname}% + % + \ifx\curfontstyle\bfstylename + % bold: + \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize + \else + % regular: + \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize + \fi + \thiseurofont +} + +% Glyphs from the EC fonts. We don't use \let for the aliases, because +% sometimes we redefine the original macro, and the alias should reflect +% the redefinition. +% +% Use LaTeX names for the Icelandic letters. +\def\DH{{\ecfont \char"D0}} % Eth +\def\dh{{\ecfont \char"F0}} % eth +\def\TH{{\ecfont \char"DE}} % Thorn +\def\th{{\ecfont \char"FE}} % thorn +% +\def\guillemetleft{{\ecfont \char"13}} +\def\guillemotleft{\guillemetleft} +\def\guillemetright{{\ecfont \char"14}} +\def\guillemotright{\guillemetright} +\def\guilsinglleft{{\ecfont \char"0E}} +\def\guilsinglright{{\ecfont \char"0F}} +\def\quotedblbase{{\ecfont \char"12}} +\def\quotesinglbase{{\ecfont \char"0D}} +% +% This positioning is not perfect (see the ogonek LaTeX package), but +% we have the precomposed glyphs for the most common cases. We put the +% tests to use those glyphs in the single \ogonek macro so we have fewer +% dummy definitions to worry about for index entries, etc. +% +% ogonek is also used with other letters in Lithuanian (IOU), but using +% the precomposed glyphs for those is not so easy since they aren't in +% the same EC font. +\def\ogonek#1{{% + \def\temp{#1}% + \ifx\temp\macrocharA\Aogonek + \else\ifx\temp\macrochara\aogonek + \else\ifx\temp\macrocharE\Eogonek + \else\ifx\temp\macrochare\eogonek + \else + \ecfont \setbox0=\hbox{#1}% + \ifdim\ht0=1ex\accent"0C #1% + \else\ooalign{\unhbox0\crcr\hidewidth\char"0C \hidewidth}% + \fi + \fi\fi\fi\fi + }% +} +\def\Aogonek{{\ecfont \char"81}}\def\macrocharA{A} +\def\aogonek{{\ecfont \char"A1}}\def\macrochara{a} +\def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E} +\def\eogonek{{\ecfont \char"A6}}\def\macrochare{e} +% +% Use the European Computer Modern fonts (cm-super in outline format) +% for non-CM glyphs. That is ec* for regular text and tc* for the text +% companion symbols (LaTeX TS1 encoding). Both are part of the ec +% package and follow the same conventions. +% +\def\ecfont{\etcfont{e}} +\def\tcfont{\etcfont{t}} +% +\def\etcfont#1{% + % We can't distinguish serif/sans and italic/slanted, but this + % is used for crude hacks anyway (like adding French and German + % quotes to documents typeset with CM, where we lose kerning), so + % hopefully nobody will notice/care. + \edef\ecsize{\csname\curfontsize ecsize\endcsname}% + \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}% + \ifmonospace + % typewriter: + \font\thisecfont = #1ctt\ecsize \space at \nominalsize + \else + \ifx\curfontstyle\bfstylename + % bold: + \font\thisecfont = #1cb\ifusingit{i}{x}\ecsize \space at \nominalsize + \else + % regular: + \font\thisecfont = #1c\ifusingit{ti}{rm}\ecsize \space at \nominalsize + \fi + \fi + \thisecfont +} + +% @registeredsymbol - R in a circle. The font for the R should really +% be smaller yet, but lllsize is the best we can do for now. +% Adapted from the plain.tex definition of \copyright. +% +\def\registeredsymbol{% + $^{{\ooalign{\hfil\raise.07ex\hbox{\switchtolllsize R}% + \hfil\crcr\Orb}}% + }$% +} + +% @textdegree - the normal degrees sign. +% +\def\textdegree{$^\circ$} + +% Laurent Siebenmann reports \Orb undefined with: +% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38 +% so we'll define it if necessary. +% +\ifx\Orb\thisisundefined +\def\Orb{\mathhexbox20D} +\fi + +% Quotes. +\chardef\quotedblleft="5C +\chardef\quotedblright=`\" +\chardef\quoteleft=`\` +\chardef\quoteright=`\' + + +\message{page headings,} + +\newskip\titlepagetopglue \titlepagetopglue = 1.5in +\newskip\titlepagebottomglue \titlepagebottomglue = 2pc + +% First the title page. Must do @settitle before @titlepage. +\newif\ifseenauthor +\newif\iffinishedtitlepage + +% @setcontentsaftertitlepage used to do an implicit @contents or +% @shortcontents after @end titlepage, but it is now obsolete. +\def\setcontentsaftertitlepage{% + \errmessage{@setcontentsaftertitlepage has been removed as a Texinfo + command; move your @contents command if you want the contents + after the title page.}}% +\def\setshortcontentsaftertitlepage{% + \errmessage{@setshortcontentsaftertitlepage has been removed as a Texinfo + command; move your @shortcontents and @contents commands if you + want the contents after the title page.}}% + +\parseargdef\shorttitlepage{% + \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} + +\envdef\titlepage{% + % Open one extra group, as we want to close it in the middle of \Etitlepage. + \begingroup + \parindent=0pt \textfonts + % Leave some space at the very top of the page. + \vglue\titlepagetopglue + % No rule at page bottom unless we print one at the top with @title. + \finishedtitlepagetrue + % + % Most title ``pages'' are actually two pages long, with space + % at the top of the second. We don't want the ragged left on the second. + \let\oldpage = \page + \def\page{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + \let\page = \oldpage + \page + \null + }% +} + +\def\Etitlepage{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + % It is important to do the page break before ending the group, + % because the headline and footline are only empty inside the group. + % If we use the new definition of \page, we always get a blank page + % after the title page, which we certainly don't want. + \oldpage + \endgroup + % + % Need this before the \...aftertitlepage checks so that if they are + % in effect the toc pages will come out with page numbers. + \HEADINGSon +} + +\def\finishtitlepage{% + \vskip4pt \hrule height 2pt width \hsize + \vskip\titlepagebottomglue + \finishedtitlepagetrue +} + +% Settings used for typesetting titles: no hyphenation, no indentation, +% don't worry much about spacing, ragged right. This should be used +% inside a \vbox, and fonts need to be set appropriately first. \par should +% be specified before the end of the \vbox, since a vbox is a group. +% +\def\raggedtitlesettings{% + \rm + \hyphenpenalty=10000 + \parindent=0pt + \tolerance=5000 + \ptexraggedright +} + +% Macros to be used within @titlepage: + +\let\subtitlerm=\rmfont +\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines} + +\parseargdef\title{% + \checkenv\titlepage + \vbox{\titlefonts \raggedtitlesettings #1\par}% + % print a rule at the page bottom also. + \finishedtitlepagefalse + \vskip4pt \hrule height 4pt width \hsize \vskip4pt +} + +\parseargdef\subtitle{% + \checkenv\titlepage + {\subtitlefont \rightline{#1}}% +} + +% @author should come last, but may come many times. +% It can also be used inside @quotation. +% +\parseargdef\author{% + \def\temp{\quotation}% + \ifx\thisenv\temp + \def\quotationauthor{#1}% printed in \Equotation. + \else + \checkenv\titlepage + \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi + {\secfonts\rm \leftline{#1}}% + \fi +} + + +% Set up page headings and footings. + +\let\thispage=\folio + +\newtoks\evenheadline % headline on even pages +\newtoks\oddheadline % headline on odd pages +\newtoks\evenfootline % footline on even pages +\newtoks\oddfootline % footline on odd pages + +% Now make \makeheadline and \makefootline in Plain TeX use those variables +\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline + \else \the\evenheadline \fi}} +\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline + \else \the\evenfootline \fi}\HEADINGShook} +\let\HEADINGShook=\relax + +% Commands to set those variables. +% For example, this is what @headings on does +% @evenheading @thistitle|@thispage|@thischapter +% @oddheading @thischapter|@thispage|@thistitle +% @evenfooting @thisfile|| +% @oddfooting ||@thisfile + + +\def\evenheading{\parsearg\evenheadingxxx} +\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish} +\def\evenheadingyyy #1\|#2\|#3\|#4\finish{% +\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\def\oddheading{\parsearg\oddheadingxxx} +\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish} +\def\oddheadingyyy #1\|#2\|#3\|#4\finish{% +\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}% + +\def\evenfooting{\parsearg\evenfootingxxx} +\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish} +\def\evenfootingyyy #1\|#2\|#3\|#4\finish{% +\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\def\oddfooting{\parsearg\oddfootingxxx} +\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish} +\def\oddfootingyyy #1\|#2\|#3\|#4\finish{% + \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% + % + % Leave some space for the footline. Hopefully ok to assume + % @evenfooting will not be used by itself. + \global\advance\txipageheight by -12pt + \global\advance\vsize by -12pt +} + +\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}} + +% @evenheadingmarks top \thischapter <- chapter at the top of a page +% @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page +% +% The same set of arguments for: +% +% @oddheadingmarks +% @evenfootingmarks +% @oddfootingmarks +% @everyheadingmarks +% @everyfootingmarks + +% These define \getoddheadingmarks, \getevenheadingmarks, +% \getoddfootingmarks, and \getevenfootingmarks, each to one of +% \gettopheadingmarks, \getbottomheadingmarks. +% +\def\evenheadingmarks{\headingmarks{even}{heading}} +\def\oddheadingmarks{\headingmarks{odd}{heading}} +\def\evenfootingmarks{\headingmarks{even}{footing}} +\def\oddfootingmarks{\headingmarks{odd}{footing}} +\parseargdef\everyheadingmarks{\headingmarks{even}{heading}{#1} + \headingmarks{odd}{heading}{#1} } +\parseargdef\everyfootingmarks{\headingmarks{even}{footing}{#1} + \headingmarks{odd}{footing}{#1} } +% #1 = even/odd, #2 = heading/footing, #3 = top/bottom. +\def\headingmarks#1#2#3 {% + \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname + \global\expandafter\let\csname get#1#2marks\endcsname \temp +} + +\everyheadingmarks bottom +\everyfootingmarks bottom + +% @headings double turns headings on for double-sided printing. +% @headings single turns headings on for single-sided printing. +% @headings off turns them off. +% @headings on same as @headings double, retained for compatibility. +% @headings after turns on double-sided headings after this page. +% @headings doubleafter turns on double-sided headings after this page. +% @headings singleafter turns on single-sided headings after this page. +% By default, they are off at the start of a document, +% and turned `on' after @end titlepage. + +\parseargdef\headings{\csname HEADINGS#1\endcsname} + +\def\headingsoff{% non-global headings elimination + \evenheadline={\hfil}\evenfootline={\hfil}% + \oddheadline={\hfil}\oddfootline={\hfil}% +} + +\def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting +\HEADINGSoff % it's the default + +% When we turn headings on, set the page number to 1. +% For double-sided printing, put current file name in lower left corner, +% chapter name on inside top of right hand pages, document +% title on inside top of left hand pages, and page numbers on outside top +% edge of all pages. +\def\HEADINGSdouble{% +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} +\let\contentsalignmacro = \chappager + +% For single-sided printing, chapter title goes across top left of page, +% page number on top right. +\def\HEADINGSsingle{% +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapterheading\hfil\folio}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} +\def\HEADINGSon{\HEADINGSdouble} + +\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} +\let\HEADINGSdoubleafter=\HEADINGSafter +\def\HEADINGSdoublex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} + +\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} +\def\HEADINGSsinglex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapterheading\hfil\folio}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} + +% Subroutines used in generating headings +% This produces Day Month Year style of output. +% Only define if not already defined, in case a txi-??.tex file has set +% up a different format (e.g., txi-cs.tex does this). +\ifx\today\thisisundefined +\def\today{% + \number\day\space + \ifcase\month + \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr + \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug + \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec + \fi + \space\number\year} +\fi + +% @settitle line... specifies the title of the document, for headings. +% It generates no output of its own. +\def\thistitle{\putwordNoTitle} +\def\settitle{\parsearg{\gdef\thistitle}} + + +\message{tables,} +% Tables -- @table, @ftable, @vtable, @item(x). + +% default indentation of table text +\newdimen\tableindent \tableindent=.8in +% default indentation of @itemize and @enumerate text +\newdimen\itemindent \itemindent=.3in +% margin between end of table item and start of table text. +\newdimen\itemmargin \itemmargin=.1in + +% used internally for \itemindent minus \itemmargin +\newdimen\itemmax + +% Note @table, @ftable, and @vtable define @item, @itemx, etc., with +% these defs. +% They also define \itemindex +% to index the item name in whatever manner is desired (perhaps none). + +\newif\ifitemxneedsnegativevskip + +\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} + +\def\internalBitem{\smallbreak \parsearg\itemzzz} +\def\internalBitemx{\itemxpar \parsearg\itemzzz} + +\def\itemzzz #1{\begingroup % + \advance\hsize by -\rightskip + \advance\hsize by -\tableindent + \setbox0=\hbox{\itemindicate{#1}}% + \itemindex{#1}% + \nobreak % This prevents a break before @itemx. + % + % If the item text does not fit in the space we have, put it on a line + % by itself, and do not allow a page break either before or after that + % line. We do not start a paragraph here because then if the next + % command is, e.g., @kindex, the whatsit would get put into the + % horizontal list on a line by itself, resulting in extra blank space. + \ifdim \wd0>\itemmax + % + % Make this a paragraph so we get the \parskip glue and wrapping, + % but leave it ragged-right. + \begingroup + \advance\leftskip by-\tableindent + \advance\hsize by\tableindent + \advance\rightskip by0pt plus1fil\relax + \leavevmode\unhbox0\par + \endgroup + % + % We're going to be starting a paragraph, but we don't want the + % \parskip glue -- logically it's part of the @item we just started. + \nobreak \vskip-\parskip + % + % Stop a page break at the \parskip glue coming up. However, if + % what follows is an environment such as @example, there will be no + % \parskip glue; then the negative vskip we just inserted would + % cause the example and the item to crash together. So we use this + % bizarre value of 10001 as a signal to \aboveenvbreak to insert + % \parskip glue after all. Section titles are handled this way also. + % + \penalty 10001 + \endgroup + \itemxneedsnegativevskipfalse + \else + % The item text fits into the space. Start a paragraph, so that the + % following text (if any) will end up on the same line. + \noindent + % Do this with kerns and \unhbox so that if there is a footnote in + % the item text, it can migrate to the main vertical list and + % eventually be printed. + \nobreak\kern-\tableindent + \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 + \unhbox0 + \nobreak\kern\dimen0 + \endgroup + \itemxneedsnegativevskiptrue + \fi +} + +\def\item{\errmessage{@item while not in a list environment}} +\def\itemx{\errmessage{@itemx while not in a list environment}} + +% @table, @ftable, @vtable. +\envdef\table{% + \let\itemindex\gobble + \tablecheck{table}% +} +\envdef\ftable{% + \def\itemindex ##1{\doind {fn}{\code{##1}}}% + \tablecheck{ftable}% +} +\envdef\vtable{% + \def\itemindex ##1{\doind {vr}{\code{##1}}}% + \tablecheck{vtable}% +} +\def\tablecheck#1{% + \ifnum \the\catcode`\^^M=\active + \endgroup + \errmessage{This command won't work in this context; perhaps the problem is + that we are \inenvironment\thisenv}% + \def\next{\doignore{#1}}% + \else + \let\next\tablex + \fi + \next +} +\def\tablex#1{% + \def\itemindicate{#1}% + \parsearg\tabley +} +\def\tabley#1{% + {% + \makevalueexpandable + \edef\temp{\noexpand\tablez #1\space\space\space}% + \expandafter + }\temp \endtablez +} +\def\tablez #1 #2 #3 #4\endtablez{% + \aboveenvbreak + \ifnum 0#1>0 \advance \leftskip by #1\mil \fi + \ifnum 0#2>0 \tableindent=#2\mil \fi + \ifnum 0#3>0 \advance \rightskip by #3\mil \fi + \itemmax=\tableindent + \advance \itemmax by -\itemmargin + \advance \leftskip by \tableindent + \exdentamount=\tableindent + \parindent = 0pt + \parskip = \smallskipamount + \ifdim \parskip=0pt \parskip=2pt \fi + \let\item = \internalBitem + \let\itemx = \internalBitemx +} +\def\Etable{\endgraf\afterenvbreak} +\let\Eftable\Etable +\let\Evtable\Etable +\let\Eitemize\Etable +\let\Eenumerate\Etable + +% This is the counter used by @enumerate, which is really @itemize + +\newcount \itemno + +\envdef\itemize{\parsearg\doitemize} + +\def\doitemize#1{% + \aboveenvbreak + \itemmax=\itemindent + \advance\itemmax by -\itemmargin + \advance\leftskip by \itemindent + \exdentamount=\itemindent + \parindent=0pt + \parskip=\smallskipamount + \ifdim\parskip=0pt \parskip=2pt \fi + % + % Try typesetting the item mark so that if the document erroneously says + % something like @itemize @samp (intending @table), there's an error + % right away at the @itemize. It's not the best error message in the + % world, but it's better than leaving it to the @item. This means if + % the user wants an empty mark, they have to say @w{} not just @w. + \def\itemcontents{#1}% + \setbox0 = \hbox{\itemcontents}% + % + % @itemize with no arg is equivalent to @itemize @bullet. + \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi + % + \let\item=\itemizeitem +} + +% Definition of @item while inside @itemize and @enumerate. +% +\def\itemizeitem{% + \advance\itemno by 1 % for enumerations + {\let\par=\endgraf \smallbreak}% reasonable place to break + {% + % If the document has an @itemize directly after a section title, a + % \nobreak will be last on the list, and \sectionheading will have + % done a \vskip-\parskip. In that case, we don't want to zero + % parskip, or the item text will crash with the heading. On the + % other hand, when there is normal text preceding the item (as there + % usually is), we do want to zero parskip, or there would be too much + % space. In that case, we won't have a \nobreak before. At least + % that's the theory. + \ifnum\lastpenalty<10000 \parskip=0in \fi + \noindent + \hbox to 0pt{\hss \itemcontents \kern\itemmargin}% + % + \ifinner\else + \vadjust{\penalty 1200}% not good to break after first line of item. + \fi + % We can be in inner vertical mode in a footnote, although an + % @itemize looks awful there. + }% + \flushcr +} + +% \splitoff TOKENS\endmark defines \first to be the first token in +% TOKENS, and \rest to be the remainder. +% +\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% + +% Allow an optional argument of an uppercase letter, lowercase letter, +% or number, to specify the first label in the enumerated list. No +% argument is the same as `1'. +% +\envparseargdef\enumerate{\enumeratey #1 \endenumeratey} +\def\enumeratey #1 #2\endenumeratey{% + % If we were given no argument, pretend we were given `1'. + \def\thearg{#1}% + \ifx\thearg\empty \def\thearg{1}\fi + % + % Detect if the argument is a single token. If so, it might be a + % letter. Otherwise, the only valid thing it can be is a number. + % (We will always have one token, because of the test we just made. + % This is a good thing, since \splitoff doesn't work given nothing at + % all -- the first parameter is undelimited.) + \expandafter\splitoff\thearg\endmark + \ifx\rest\empty + % Only one token in the argument. It could still be anything. + % A ``lowercase letter'' is one whose \lccode is nonzero. + % An ``uppercase letter'' is one whose \lccode is both nonzero, and + % not equal to itself. + % Otherwise, we assume it's a number. + % + % We need the \relax at the end of the \ifnum lines to stop TeX from + % continuing to look for a . + % + \ifnum\lccode\expandafter`\thearg=0\relax + \numericenumerate % a number (we hope) + \else + % It's a letter. + \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax + \lowercaseenumerate % lowercase letter + \else + \uppercaseenumerate % uppercase letter + \fi + \fi + \else + % Multiple tokens in the argument. We hope it's a number. + \numericenumerate + \fi +} + +% An @enumerate whose labels are integers. The starting integer is +% given in \thearg. +% +\def\numericenumerate{% + \itemno = \thearg + \startenumeration{\the\itemno}% +} + +% The starting (lowercase) letter is in \thearg. +\def\lowercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more lowercase letters in @enumerate; get a bigger + alphabet}% + \fi + \char\lccode\itemno + }% +} + +% The starting (uppercase) letter is in \thearg. +\def\uppercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more uppercase letters in @enumerate; get a bigger + alphabet} + \fi + \char\uccode\itemno + }% +} + +% Call \doitemize, adding a period to the first argument and supplying the +% common last two arguments. Also subtract one from the initial value in +% \itemno, since @item increments \itemno. +% +\def\startenumeration#1{% + \advance\itemno by -1 + \doitemize{#1.}\flushcr +} + +% @alphaenumerate and @capsenumerate are abbreviations for giving an arg +% to @enumerate. +% +\def\alphaenumerate{\enumerate{a}} +\def\capsenumerate{\enumerate{A}} +\def\Ealphaenumerate{\Eenumerate} +\def\Ecapsenumerate{\Eenumerate} + + +% @multitable macros +% Amy Hendrickson, 8/18/94, 3/6/96 +% +% @multitable ... @end multitable will make as many columns as desired. +% Contents of each column will wrap at width given in preamble. Width +% can be specified either with sample text given in a template line, +% or in percent of \hsize, the current width of text on page. + +% Table can continue over pages but will only break between lines. + +% To make preamble: +% +% Either define widths of columns in terms of percent of \hsize: +% @multitable @columnfractions .25 .3 .45 +% @item ... +% +% Numbers following @columnfractions are the percent of the total +% current hsize to be used for each column. You may use as many +% columns as desired. + + +% Or use a template: +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item ... +% using the widest term desired in each column. + +% Each new table line starts with @item, each subsequent new column +% starts with @tab. Empty columns may be produced by supplying @tab's +% with nothing between them for as many times as empty columns are needed, +% ie, @tab@tab@tab will produce two empty columns. + +% @item, @tab do not need to be on their own lines, but it will not hurt +% if they are. + +% Sample multitable: + +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item first col stuff @tab second col stuff @tab third col +% @item +% first col stuff +% @tab +% second col stuff +% @tab +% third col +% @item first col stuff @tab second col stuff +% @tab Many paragraphs of text may be used in any column. +% +% They will wrap at the width determined by the template. +% @item@tab@tab This will be in third column. +% @end multitable + +% Default dimensions may be reset by user. +% @multitableparskip is vertical space between paragraphs in table. +% @multitableparindent is paragraph indent in table. +% @multitablecolmargin is horizontal space to be left between columns. +% @multitablelinespace is space to leave between table items, baseline +% to baseline. +% 0pt means it depends on current normal line spacing. +% +\newskip\multitableparskip +\newskip\multitableparindent +\newdimen\multitablecolspace +\newskip\multitablelinespace +\multitableparskip=0pt +\multitableparindent=6pt +\multitablecolspace=12pt +\multitablelinespace=0pt + +% Macros used to set up halign preamble: +% +\let\endsetuptable\relax +\def\xendsetuptable{\endsetuptable} +\let\columnfractions\relax +\def\xcolumnfractions{\columnfractions} +\newif\ifsetpercent + +% #1 is the @columnfraction, usually a decimal number like .5, but might +% be just 1. We just use it, whatever it is. +% +\def\pickupwholefraction#1 {% + \global\advance\colcount by 1 + \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}% + \setuptable +} + +\newcount\colcount +\def\setuptable#1{% + \def\firstarg{#1}% + \ifx\firstarg\xendsetuptable + \let\go = \relax + \else + \ifx\firstarg\xcolumnfractions + \global\setpercenttrue + \else + \ifsetpercent + \let\go\pickupwholefraction + \else + \global\advance\colcount by 1 + \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a + % separator; typically that is always in the input, anyway. + \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% + \fi + \fi + \ifx\go\pickupwholefraction + % Put the argument back for the \pickupwholefraction call, so + % we'll always have a period there to be parsed. + \def\go{\pickupwholefraction#1}% + \else + \let\go = \setuptable + \fi% + \fi + \go +} + +% multitable-only commands. +% +% @headitem starts a heading row, which we typeset in bold. Assignments +% have to be global since we are inside the implicit group of an +% alignment entry. \everycr below resets \everytab so we don't have to +% undo it ourselves. +\def\headitemfont{\b}% for people to use in the template row; not changeable +\def\headitem{% + \checkenv\multitable + \crcr + \gdef\headitemcrhook{\nobreak}% attempt to avoid page break after headings + \global\everytab={\bf}% can't use \headitemfont since the parsing differs + \the\everytab % for the first item +}% +% +% default for tables with no headings. +\let\headitemcrhook=\relax +% +% A \tab used to include \hskip1sp. But then the space in a template +% line is not enough. That is bad. So let's go back to just `&' until +% we again encounter the problem the 1sp was intended to solve. +% --karl, nathan@acm.org, 20apr99. +\def\tab{\checkenv\multitable &\the\everytab}% + +% @multitable ... @end multitable definitions: +% +\newtoks\everytab % insert after every tab. +% +\envdef\multitable{% + \vskip\parskip + \startsavinginserts + % + % @item within a multitable starts a normal row. + % We use \def instead of \let so that if one of the multitable entries + % contains an @itemize, we don't choke on the \item (seen as \crcr aka + % \endtemplate) expanding \doitemize. + \def\item{\crcr}% + % + \tolerance=9500 + \hbadness=9500 + \setmultitablespacing + \parskip=\multitableparskip + \parindent=\multitableparindent + \overfullrule=0pt + \global\colcount=0 + % + \everycr = {% + \noalign{% + \global\everytab={}% Reset from possible headitem. + \global\colcount=0 % Reset the column counter. + % + % Check for saved footnotes, etc.: + \checkinserts + % + % Perhaps a \nobreak, then reset: + \headitemcrhook + \global\let\headitemcrhook=\relax + }% + }% + % + \parsearg\domultitable +} +\def\domultitable#1{% + % To parse everything between @multitable and @item: + \setuptable#1 \endsetuptable + % + % This preamble sets up a generic column definition, which will + % be used as many times as user calls for columns. + % \vtop will set a single line and will also let text wrap and + % continue for many paragraphs if desired. + \halign\bgroup &% + \global\advance\colcount by 1 + \multistrut + \vtop{% + % Use the current \colcount to find the correct column width: + \hsize=\expandafter\csname col\the\colcount\endcsname + % + % In order to keep entries from bumping into each other + % we will add a \leftskip of \multitablecolspace to all columns after + % the first one. + % + % If a template has been used, we will add \multitablecolspace + % to the width of each template entry. + % + % If the user has set preamble in terms of percent of \hsize we will + % use that dimension as the width of the column, and the \leftskip + % will keep entries from bumping into each other. Table will start at + % left margin and final column will justify at right margin. + % + % Make sure we don't inherit \rightskip from the outer environment. + \rightskip=0pt + \ifnum\colcount=1 + % The first column will be indented with the surrounding text. + \advance\hsize by\leftskip + \else + \ifsetpercent \else + % If user has not set preamble in terms of percent of \hsize + % we will advance \hsize by \multitablecolspace. + \advance\hsize by \multitablecolspace + \fi + % In either case we will make \leftskip=\multitablecolspace: + \leftskip=\multitablecolspace + \fi + % Ignoring space at the beginning and end avoids an occasional spurious + % blank line, when TeX decides to break the line at the space before the + % box from the multistrut, so the strut ends up on a line by itself. + % For example: + % @multitable @columnfractions .11 .89 + % @item @code{#} + % @tab Legal holiday which is valid in major parts of the whole country. + % Is automatically provided with highlighting sequences respectively + % marking characters. + \noindent\ignorespaces##\unskip\multistrut + }\cr +} +\def\Emultitable{% + \crcr + \egroup % end the \halign + \global\setpercentfalse +} + +\def\setmultitablespacing{% + \def\multistrut{\strut}% just use the standard line spacing + % + % Compute \multitablelinespace (if not defined by user) for use in + % \multitableparskip calculation. We used define \multistrut based on + % this, but (ironically) that caused the spacing to be off. + % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100. +\ifdim\multitablelinespace=0pt +\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip +\global\advance\multitablelinespace by-\ht0 +\fi +% Test to see if parskip is larger than space between lines of +% table. If not, do nothing. +% If so, set to same dimension as multitablelinespace. +\ifdim\multitableparskip>\multitablelinespace +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller + % than skip between lines in the table. +\fi% +\ifdim\multitableparskip=0pt +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller + % than skip between lines in the table. +\fi} + + +\message{conditionals,} + +% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext, +% @ifnotxml always succeed. They currently do nothing; we don't +% attempt to check whether the conditionals are properly nested. But we +% have to remember that they are conditionals, so that @end doesn't +% attempt to close an environment group. +% +\def\makecond#1{% + \expandafter\let\csname #1\endcsname = \relax + \expandafter\let\csname iscond.#1\endcsname = 1 +} +\makecond{iftex} +\makecond{ifnotdocbook} +\makecond{ifnothtml} +\makecond{ifnotinfo} +\makecond{ifnotplaintext} +\makecond{ifnotxml} + +% Ignore @ignore, @ifhtml, @ifinfo, and the like. +% +\def\direntry{\doignore{direntry}} +\def\documentdescription{\doignore{documentdescription}} +\def\docbook{\doignore{docbook}} +\def\html{\doignore{html}} +\def\ifdocbook{\doignore{ifdocbook}} +\def\ifhtml{\doignore{ifhtml}} +\def\ifinfo{\doignore{ifinfo}} +\def\ifnottex{\doignore{ifnottex}} +\def\ifplaintext{\doignore{ifplaintext}} +\def\ifxml{\doignore{ifxml}} +\def\ignore{\doignore{ignore}} +\def\menu{\doignore{menu}} +\def\xml{\doignore{xml}} + +% Ignore text until a line `@end #1', keeping track of nested conditionals. +% +% A count to remember the depth of nesting. +\newcount\doignorecount + +\def\doignore#1{\begingroup + % Scan in ``verbatim'' mode: + \obeylines + \catcode`\@ = \other + \catcode`\{ = \other + \catcode`\} = \other + % + % Make sure that spaces turn into tokens that match what \doignoretext wants. + \spaceisspace + % + % Count number of #1's that we've seen. + \doignorecount = 0 + % + % Swallow text until we reach the matching `@end #1'. + \dodoignore{#1}% +} + +{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source. + \obeylines % + % + \gdef\dodoignore#1{% + % #1 contains the command name as a string, e.g., `ifinfo'. + % + % Define a command to find the next `@end #1'. + \long\def\doignoretext##1^^M@end #1{% + \doignoretextyyy##1^^M@#1\_STOP_}% + % + % And this command to find another #1 command, at the beginning of a + % line. (Otherwise, we would consider a line `@c @ifset', for + % example, to count as an @ifset for nesting.) + \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}% + % + % And now expand that command. + \doignoretext ^^M% + }% +} + +\def\doignoreyyy#1{% + \def\temp{#1}% + \ifx\temp\empty % Nothing found. + \let\next\doignoretextzzz + \else % Found a nested condition, ... + \advance\doignorecount by 1 + \let\next\doignoretextyyy % ..., look for another. + % If we're here, #1 ends with ^^M\ifinfo (for example). + \fi + \next #1% the token \_STOP_ is present just after this macro. +} + +% We have to swallow the remaining "\_STOP_". +% +\def\doignoretextzzz#1{% + \ifnum\doignorecount = 0 % We have just found the outermost @end. + \let\next\enddoignore + \else % Still inside a nested condition. + \advance\doignorecount by -1 + \let\next\doignoretext % Look for the next @end. + \fi + \next +} + +% Finish off ignored text. +{ \obeylines% + % Ignore anything after the last `@end #1'; this matters in verbatim + % environments, where otherwise the newline after an ignored conditional + % would result in a blank line in the output. + \gdef\enddoignore#1^^M{\endgroup\ignorespaces}% +} + + +% @set VAR sets the variable VAR to an empty value. +% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. +% +% Since we want to separate VAR from REST-OF-LINE (which might be +% empty), we can't just use \parsearg; we have to insert a space of our +% own to delimit the rest of the line, and then take it out again if we +% didn't need it. +% We rely on the fact that \parsearg sets \catcode`\ =10. +% +\parseargdef\set{\setyyy#1 \endsetyyy} +\def\setyyy#1 #2\endsetyyy{% + {% + \makevalueexpandable + \def\temp{#2}% + \edef\next{\gdef\makecsname{SET#1}}% + \ifx\temp\empty + \next{}% + \else + \setzzz#2\endsetzzz + \fi + }% +} +% Remove the trailing space \setxxx inserted. +\def\setzzz#1 \endsetzzz{\next{#1}} + +% @clear VAR clears (i.e., unsets) the variable VAR. +% +\parseargdef\clear{% + {% + \makevalueexpandable + \global\expandafter\let\csname SET#1\endcsname=\relax + }% +} + +% @value{foo} gets the text saved in variable foo. +\def\value{\begingroup\makevalueexpandable\valuexxx} +\def\valuexxx#1{\expandablevalue{#1}\endgroup} +{ + \catcode`\-=\active \catcode`\_=\active + % + \gdef\makevalueexpandable{% + \let\value = \expandablevalue + % We don't want these characters active, ... + \catcode`\-=\other \catcode`\_=\other + % ..., but we might end up with active ones in the argument if + % we're called from @code, as @code{@value{foo-bar_}}, though. + % So \let them to their normal equivalents. + \let-\normaldash \let_\normalunderscore + } +} + +% We have this subroutine so that we can handle at least some @value's +% properly in indexes (we call \makevalueexpandable in \indexdummies). +% The command has to be fully expandable (if the variable is set), since +% the result winds up in the index file. This means that if the +% variable's value contains other Texinfo commands, it's almost certain +% it will fail (although perhaps we could fix that with sufficient work +% to do a one-level expansion on the result, instead of complete). +% +% Unfortunately, this has the consequence that when _ is in the *value* +% of an @set, it does not print properly in the roman fonts (get the cmr +% dot accent at position 126 instead). No fix comes to mind, and it's +% been this way since 2003 or earlier, so just ignore it. +% +\def\expandablevalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + {[No value for ``#1'']}% + \message{Variable `#1', used in @value, is not set.}% + \else + \csname SET#1\endcsname + \fi +} + +% Like \expandablevalue, but completely expandable (the \message in the +% definition above operates at the execution level of TeX). Used when +% writing to auxiliary files, due to the expansion that \write does. +% If flag is undefined, pass through an unexpanded @value command: maybe it +% will be set by the time it is read back in. +% +% NB flag names containing - or _ may not work here. +\def\dummyvalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \noexpand\value{#1}% + \else + \csname SET#1\endcsname + \fi +} + +% Used for @value's in index entries to form the sort key: expand the @value +% if possible, otherwise sort late. +\def\indexnofontsvalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + ZZZZZZZ + \else + \csname SET#1\endcsname + \fi +} + +% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined +% with @set. +% +% To get the special treatment we need for `@end ifset,' we call +% \makecond and then redefine. +% +\makecond{ifset} +\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}} +\def\doifset#1#2{% + {% + \makevalueexpandable + \let\next=\empty + \expandafter\ifx\csname SET#2\endcsname\relax + #1% If not set, redefine \next. + \fi + \expandafter + }\next +} +\def\ifsetfail{\doignore{ifset}} + +% @ifclear VAR ... @end executes the `...' iff VAR has never been +% defined with @set, or has been undefined with @clear. +% +% The `\else' inside the `\doifset' parameter is a trick to reuse the +% above code: if the variable is not set, do nothing, if it is set, +% then redefine \next to \ifclearfail. +% +\makecond{ifclear} +\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}} +\def\ifclearfail{\doignore{ifclear}} + +% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written +% without the @) is in fact defined. We can only feasibly check at the +% TeX level, so something like `mathcode' is going to considered +% defined even though it is not a Texinfo command. +% +\makecond{ifcommanddefined} +\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}} +% +\def\doifcmddefined#1#2{{% + \makevalueexpandable + \let\next=\empty + \expandafter\ifx\csname #2\endcsname\relax + #1% If not defined, \let\next as above. + \fi + \expandafter + }\next +} +\def\ifcmddefinedfail{\doignore{ifcommanddefined}} + +% @ifcommandnotdefined CMD ... handled similar to @ifclear above. +\makecond{ifcommandnotdefined} +\def\ifcommandnotdefined{% + \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}} +\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}} + +% Set the `txicommandconditionals' variable, so documents have a way to +% test if the @ifcommand...defined conditionals are available. +\set txicommandconditionals + +% @dircategory CATEGORY -- specify a category of the dir file +% which this file should belong to. Ignore this in TeX. +\let\dircategory=\comment + +% @defininfoenclose. +\let\definfoenclose=\comment + + +\message{indexing,} +% Index generation facilities + +% Define \newwrite to be identical to plain tex's \newwrite +% except not \outer, so it can be used within macros and \if's. +\edef\newwrite{\makecsname{ptexnewwrite}} + +% \newindex {foo} defines an index named IX. +% It automatically defines \IXindex such that +% \IXindex ...rest of line... puts an entry in the index IX. +% It also defines \IXindfile to be the number of the output channel for +% the file that accumulates this index. The file's extension is IX. +% The name of an index should be no more than 2 characters long +% for the sake of vms. +% +\def\newindex#1{% + \expandafter\chardef\csname#1indfile\endcsname=0 + \expandafter\xdef\csname#1index\endcsname{% % Define @#1index + \noexpand\doindex{#1}} +} + +% @defindex foo == \newindex{foo} +% +\def\defindex{\parsearg\newindex} + +% Define @defcodeindex, like @defindex except put all entries in @code. +% +\def\defcodeindex{\parsearg\newcodeindex} +% +\def\newcodeindex#1{% + \expandafter\chardef\csname#1indfile\endcsname=0 + \expandafter\xdef\csname#1index\endcsname{% + \noexpand\docodeindex{#1}}% +} + +% The default indices: +\newindex{cp}% concepts, +\newcodeindex{fn}% functions, +\newcodeindex{vr}% variables, +\newcodeindex{tp}% types, +\newcodeindex{ky}% keys +\newcodeindex{pg}% and programs. + + +% @synindex foo bar makes index foo feed into index bar. +% Do this instead of @defindex foo if you don't want it as a separate index. +% +% @syncodeindex foo bar similar, but put all entries made for index foo +% inside @code. +% +\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}} +\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}} + +% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo), +% #3 the target index (bar). +\def\dosynindex#1#2#3{% + \requireopenindexfile{#3}% + % redefine \fooindfile: + \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname + \expandafter\let\csname#2indfile\endcsname=\temp + % redefine \fooindex: + \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}% +} + +% Define \doindex, the driver for all index macros. +% Argument #1 is generated by the calling \fooindex macro, +% and it is the two-letter name of the index. + +\def\doindex#1{\edef\indexname{#1}\parsearg\doindexxxx} +\def\doindexxxx #1{\doind{\indexname}{#1}} + +% like the previous two, but they put @code around the argument. +\def\docodeindex#1{\edef\indexname{#1}\parsearg\docodeindexxxx} +\def\docodeindexxxx #1{\doind{\indexname}{\code{#1}}} + + +% Used when writing an index entry out to an index file to prevent +% expansion of Texinfo commands that can appear in an index entry. +% +\def\indexdummies{% + \escapechar = `\\ % use backslash in output files. + \definedummyletter\@% + \definedummyletter\ % + % + % For texindex which always views { and } as separators. + \def\{{\lbracechar{}}% + \def\}{\rbracechar{}}% + % + % Do the redefinitions. + \definedummies +} + +% Used for the aux and toc files, where @ is the escape character. +% +\def\atdummies{% + \definedummyletter\@% + \definedummyletter\ % + \definedummyletter\{% + \definedummyletter\}% + % + % Do the redefinitions. + \definedummies + \otherbackslash +} + +% \definedummyword defines \#1 as \string\#1\space, thus effectively +% preventing its expansion. This is used only for control words, +% not control letters, because the \space would be incorrect for +% control characters, but is needed to separate the control word +% from whatever follows. +% +% These can be used both for control words that take an argument and +% those that do not. If it is followed by {arg} in the input, then +% that will dutifully get written to the index (or wherever). +% +% For control letters, we have \definedummyletter, which omits the +% space. +% +\def\definedummyword #1{\def#1{\string#1\space}}% +\def\definedummyletter#1{\def#1{\string#1}}% +\let\definedummyaccent\definedummyletter + +% Called from \indexdummies and \atdummies, to effectively prevent +% the expansion of commands. +% +\def\definedummies{% + % + \let\commondummyword\definedummyword + \let\commondummyletter\definedummyletter + \let\commondummyaccent\definedummyaccent + \commondummiesnofonts + % + \definedummyletter\_% + \definedummyletter\-% + % + % Non-English letters. + \definedummyword\AA + \definedummyword\AE + \definedummyword\DH + \definedummyword\L + \definedummyword\O + \definedummyword\OE + \definedummyword\TH + \definedummyword\aa + \definedummyword\ae + \definedummyword\dh + \definedummyword\exclamdown + \definedummyword\l + \definedummyword\o + \definedummyword\oe + \definedummyword\ordf + \definedummyword\ordm + \definedummyword\questiondown + \definedummyword\ss + \definedummyword\th + % + % Although these internal commands shouldn't show up, sometimes they do. + \definedummyword\bf + \definedummyword\gtr + \definedummyword\hat + \definedummyword\less + \definedummyword\sf + \definedummyword\sl + \definedummyword\tclose + \definedummyword\tt + % + \definedummyword\LaTeX + \definedummyword\TeX + % + % Assorted special characters. + \definedummyword\atchar + \definedummyword\arrow + \definedummyword\bullet + \definedummyword\comma + \definedummyword\copyright + \definedummyword\registeredsymbol + \definedummyword\dots + \definedummyword\enddots + \definedummyword\entrybreak + \definedummyword\equiv + \definedummyword\error + \definedummyword\euro + \definedummyword\expansion + \definedummyword\geq + \definedummyword\guillemetleft + \definedummyword\guillemetright + \definedummyword\guilsinglleft + \definedummyword\guilsinglright + \definedummyword\lbracechar + \definedummyword\leq + \definedummyword\mathopsup + \definedummyword\minus + \definedummyword\ogonek + \definedummyword\pounds + \definedummyword\point + \definedummyword\print + \definedummyword\quotedblbase + \definedummyword\quotedblleft + \definedummyword\quotedblright + \definedummyword\quoteleft + \definedummyword\quoteright + \definedummyword\quotesinglbase + \definedummyword\rbracechar + \definedummyword\result + \definedummyword\sub + \definedummyword\sup + \definedummyword\textdegree + % + % We want to disable all macros so that they are not expanded by \write. + \macrolist + \let\value\dummyvalue + % + \normalturnoffactive +} + +% \commondummiesnofonts: common to \definedummies and \indexnofonts. +% Define \commondummyletter, \commondummyaccent and \commondummyword before +% using. Used for accents, font commands, and various control letters. +% +\def\commondummiesnofonts{% + % Control letters and accents. + \commondummyletter\!% + \commondummyaccent\"% + \commondummyaccent\'% + \commondummyletter\*% + \commondummyaccent\,% + \commondummyletter\.% + \commondummyletter\/% + \commondummyletter\:% + \commondummyaccent\=% + \commondummyletter\?% + \commondummyaccent\^% + \commondummyaccent\`% + \commondummyaccent\~% + \commondummyword\u + \commondummyword\v + \commondummyword\H + \commondummyword\dotaccent + \commondummyword\ogonek + \commondummyword\ringaccent + \commondummyword\tieaccent + \commondummyword\ubaraccent + \commondummyword\udotaccent + \commondummyword\dotless + % + % Texinfo font commands. + \commondummyword\b + \commondummyword\i + \commondummyword\r + \commondummyword\sansserif + \commondummyword\sc + \commondummyword\slanted + \commondummyword\t + % + % Commands that take arguments. + \commondummyword\abbr + \commondummyword\acronym + \commondummyword\anchor + \commondummyword\cite + \commondummyword\code + \commondummyword\command + \commondummyword\dfn + \commondummyword\dmn + \commondummyword\email + \commondummyword\emph + \commondummyword\env + \commondummyword\file + \commondummyword\image + \commondummyword\indicateurl + \commondummyword\inforef + \commondummyword\kbd + \commondummyword\key + \commondummyword\math + \commondummyword\option + \commondummyword\pxref + \commondummyword\ref + \commondummyword\samp + \commondummyword\strong + \commondummyword\tie + \commondummyword\U + \commondummyword\uref + \commondummyword\url + \commondummyword\var + \commondummyword\verb + \commondummyword\w + \commondummyword\xref +} + +% For testing: output @{ and @} in index sort strings as \{ and \}. +\newif\ifusebracesinindexes + +\let\indexlbrace\relax +\let\indexrbrace\relax + +{\catcode`\@=0 +\catcode`\\=13 + @gdef@backslashdisappear{@def\{}} +} + +{ +\catcode`\<=13 +\catcode`\-=13 +\catcode`\`=13 + \gdef\indexnonalnumdisappear{% + \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax\else + % @set txiindexlquoteignore makes us ignore left quotes in the sort term. + % (Introduced for FSFS 2nd ed.) + \let`=\empty + \fi + % + \expandafter\ifx\csname SETtxiindexbackslashignore\endcsname\relax\else + \backslashdisappear + \fi + % + \expandafter\ifx\csname SETtxiindexhyphenignore\endcsname\relax\else + \def-{}% + \fi + \expandafter\ifx\csname SETtxiindexlessthanignore\endcsname\relax\else + \def<{}% + \fi + \expandafter\ifx\csname SETtxiindexatsignignore\endcsname\relax\else + \def\@{}% + \fi + } + + \gdef\indexnonalnumreappear{% + \useindexbackslash + \let-\normaldash + \let<\normalless + \def\@{@}% + } +} + + +% \indexnofonts is used when outputting the strings to sort the index +% by, and when constructing control sequence names. It eliminates all +% control sequences and just writes whatever the best ASCII sort string +% would be for a given command (usually its argument). +% +\def\indexnofonts{% + % Accent commands should become @asis. + \def\commondummyaccent##1{\let##1\asis}% + % We can just ignore other control letters. + \def\commondummyletter##1{\let##1\empty}% + % All control words become @asis by default; overrides below. + \let\commondummyword\commondummyaccent + \commondummiesnofonts + % + % Don't no-op \tt, since it isn't a user-level command + % and is used in the definitions of the active chars like <, >, |, etc. + % Likewise with the other plain tex font commands. + %\let\tt=\asis + % + \def\ { }% + \def\@{@}% + \def\_{\normalunderscore}% + \def\-{}% @- shouldn't affect sorting + % + \uccode`\1=`\{ \uppercase{\def\{{1}}% + \uccode`\1=`\} \uppercase{\def\}{1}}% + \let\lbracechar\{% + \let\rbracechar\}% + % + % Non-English letters. + \def\AA{AA}% + \def\AE{AE}% + \def\DH{DZZ}% + \def\L{L}% + \def\OE{OE}% + \def\O{O}% + \def\TH{TH}% + \def\aa{aa}% + \def\ae{ae}% + \def\dh{dzz}% + \def\exclamdown{!}% + \def\l{l}% + \def\oe{oe}% + \def\ordf{a}% + \def\ordm{o}% + \def\o{o}% + \def\questiondown{?}% + \def\ss{ss}% + \def\th{th}% + % + \def\LaTeX{LaTeX}% + \def\TeX{TeX}% + % + % Assorted special characters. \defglyph gives the control sequence a + % definition that removes the {} that follows its use. + \defglyph\atchar{@}% + \defglyph\arrow{->}% + \defglyph\bullet{bullet}% + \defglyph\comma{,}% + \defglyph\copyright{copyright}% + \defglyph\dots{...}% + \defglyph\enddots{...}% + \defglyph\equiv{==}% + \defglyph\error{error}% + \defglyph\euro{euro}% + \defglyph\expansion{==>}% + \defglyph\geq{>=}% + \defglyph\guillemetleft{<<}% + \defglyph\guillemetright{>>}% + \defglyph\guilsinglleft{<}% + \defglyph\guilsinglright{>}% + \defglyph\leq{<=}% + \defglyph\lbracechar{\{}% + \defglyph\minus{-}% + \defglyph\point{.}% + \defglyph\pounds{pounds}% + \defglyph\print{-|}% + \defglyph\quotedblbase{"}% + \defglyph\quotedblleft{"}% + \defglyph\quotedblright{"}% + \defglyph\quoteleft{`}% + \defglyph\quoteright{'}% + \defglyph\quotesinglbase{,}% + \defglyph\rbracechar{\}}% + \defglyph\registeredsymbol{R}% + \defglyph\result{=>}% + \defglyph\textdegree{o}% + % + % We need to get rid of all macros, leaving only the arguments (if present). + % Of course this is not nearly correct, but it is the best we can do for now. + % makeinfo does not expand macros in the argument to @deffn, which ends up + % writing an index entry, and texindex isn't prepared for an index sort entry + % that starts with \. + % + % Since macro invocations are followed by braces, we can just redefine them + % to take a single TeX argument. The case of a macro invocation that + % goes to end-of-line is not handled. + % + \macrolist + \let\value\indexnofontsvalue +} +\def\defglyph#1#2{\def#1##1{#2}} % see above + + + + +\let\SETmarginindex=\relax % put index entries in margin (undocumented)? + +% Most index entries go through here, but \dosubind is the general case. +% #1 is the index name, #2 is the entry text. +\def\doind#1#2{\dosubind{#1}{#2}{}} + +% There is also \dosubind {index}{topic}{subtopic} +% which makes an entry in a two-level index such as the operation index. +% TODO: Two-level index? Operation index? + +% Workhorse for all indexes. +% #1 is name of index, #2 is stuff to put there, #3 is subentry -- +% empty if called from \doind, as we usually are (the main exception +% is with most defuns, which call us directly). +% +\def\dosubind#1#2#3{% + \iflinks + {% + \requireopenindexfile{#1}% + % Store the main index entry text (including the third arg). + \toks0 = {#2}% + % If third arg is present, precede it with a space. + \def\thirdarg{#3}% + \ifx\thirdarg\empty \else + \toks0 = \expandafter{\the\toks0 \space #3}% + \fi + % + \edef\writeto{\csname#1indfile\endcsname}% + % + \safewhatsit\dosubindwrite + }% + \fi +} + +% Check if an index file has been opened, and if not, open it. +\def\requireopenindexfile#1{% +\ifnum\csname #1indfile\endcsname=0 + \expandafter\newwrite \csname#1indfile\endcsname + \edef\suffix{#1}% + % A .fls suffix would conflict with the file extension for the output + % of -recorder, so use .f1s instead. + \ifx\suffix\indexisfl\def\suffix{f1}\fi + % Open the file + \immediate\openout\csname#1indfile\endcsname \jobname.\suffix + % Using \immediate above here prevents an object entering into the current + % box, which could confound checks such as those in \safewhatsit for + % preceding skips. + \typeout{Writing index file \jobname.\suffix}% +\fi} +\def\indexisfl{fl} + +% Output \ as {\indexbackslash}, because \ is an escape character in +% the index files. +\let\indexbackslash=\relax +{\catcode`\@=0 \catcode`\\=\active + @gdef@useindexbackslash{@def\{{@indexbackslash}}} +} + +% Definition for writing index entry text. +\def\sortas#1{\ignorespaces}% + +% Definition for writing index entry sort key. Should occur at the at +% the beginning of the index entry, like +% @cindex @sortas{september} \september +% The \ignorespaces takes care of following space, but there's no way +% to remove space before it. +{ +\catcode`\-=13 +\gdef\indexwritesortas{% + \begingroup + \indexnonalnumreappear + \indexwritesortasxxx} +\gdef\indexwritesortasxxx#1{% + \xdef\indexsortkey{#1}\endgroup} +} + + +% Write the entry in \toks0 to the index file. +% +\def\dosubindwrite{% + % Put the index entry in the margin if desired. + \ifx\SETmarginindex\relax\else + \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}% + \fi + % + % Remember, we are within a group. + \indexdummies % Must do this here, since \bf, etc expand at this stage + \useindexbackslash % \indexbackslash isn't defined now so it will be output + % as is; and it will print as backslash. + % The braces around \indexbrace are recognized by texindex. + % + % Get the string to sort by, by processing the index entry with all + % font commands turned off. + {\indexnofonts + \def\lbracechar{{\indexlbrace}}% + \def\rbracechar{{\indexrbrace}}% + \let\{=\lbracechar + \let\}=\rbracechar + \indexnonalnumdisappear + \xdef\indexsortkey{}% + \let\sortas=\indexwritesortas + \edef\temp{\the\toks0}% + \setbox\dummybox = \hbox{\temp}% Make sure to execute any \sortas + \ifx\indexsortkey\empty + \xdef\indexsortkey{\temp}% + \ifx\indexsortkey\empty\xdef\indexsortkey{ }\fi + \fi + }% + % + % Set up the complete index entry, with both the sort key and + % the original text, including any font commands. We write + % three arguments to \entry to the .?? file (four in the + % subentry case), texindex reduces to two when writing the .??s + % sorted result. + \edef\temp{% + \write\writeto{% + \string\entry{\indexsortkey}{\noexpand\folio}{\the\toks0}}% + }% + \temp +} +\newbox\dummybox % used above + +% Take care of unwanted page breaks/skips around a whatsit: +% +% If a skip is the last thing on the list now, preserve it +% by backing up by \lastskip, doing the \write, then inserting +% the skip again. Otherwise, the whatsit generated by the +% \write or \pdfdest will make \lastskip zero. The result is that +% sequences like this: +% @end defun +% @tindex whatever +% @defun ... +% will have extra space inserted, because the \medbreak in the +% start of the @defun won't see the skip inserted by the @end of +% the previous defun. +% +% But don't do any of this if we're not in vertical mode. We +% don't want to do a \vskip and prematurely end a paragraph. +% +% Avoid page breaks due to these extra skips, too. +% +% But wait, there is a catch there: +% We'll have to check whether \lastskip is zero skip. \ifdim is not +% sufficient for this purpose, as it ignores stretch and shrink parts +% of the skip. The only way seems to be to check the textual +% representation of the skip. +% +% The following is almost like \def\zeroskipmacro{0.0pt} except that +% the ``p'' and ``t'' characters have catcode \other, not 11 (letter). +% +\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname} +% +\newskip\whatsitskip +\newcount\whatsitpenalty +% +% ..., ready, GO: +% +\def\safewhatsit#1{\ifhmode + #1% + \else + % \lastskip and \lastpenalty cannot both be nonzero simultaneously. + \whatsitskip = \lastskip + \edef\lastskipmacro{\the\lastskip}% + \whatsitpenalty = \lastpenalty + % + % If \lastskip is nonzero, that means the last item was a + % skip. And since a skip is discardable, that means this + % -\whatsitskip glue we're inserting is preceded by a + % non-discardable item, therefore it is not a potential + % breakpoint, therefore no \nobreak needed. + \ifx\lastskipmacro\zeroskipmacro + \else + \vskip-\whatsitskip + \fi + % + #1% + % + \ifx\lastskipmacro\zeroskipmacro + % If \lastskip was zero, perhaps the last item was a penalty, and + % perhaps it was >=10000, e.g., a \nobreak. In that case, we want + % to re-insert the same penalty (values >10000 are used for various + % signals); since we just inserted a non-discardable item, any + % following glue (such as a \parskip) would be a breakpoint. For example: + % @deffn deffn-whatever + % @vindex index-whatever + % Description. + % would allow a break between the index-whatever whatsit + % and the "Description." paragraph. + \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi + \else + % On the other hand, if we had a nonzero \lastskip, + % this make-up glue would be preceded by a non-discardable item + % (the whatsit from the \write), so we must insert a \nobreak. + \nobreak\vskip\whatsitskip + \fi +\fi} + +% The index entry written in the file actually looks like +% \entry {sortstring}{page}{topic} +% or +% \entry {sortstring}{page}{topic}{subtopic} +% The texindex program reads in these files and writes files +% containing these kinds of lines: +% \initial {c} +% before the first topic whose initial is c +% \entry {topic}{pagelist} +% for a topic that is used without subtopics +% \primary {topic} +% for the beginning of a topic that is used with subtopics +% \secondary {subtopic}{pagelist} +% for each subtopic. + +% Define the user-accessible indexing commands +% @findex, @vindex, @kindex, @cindex. + +\def\findex {\fnindex} +\def\kindex {\kyindex} +\def\cindex {\cpindex} +\def\vindex {\vrindex} +\def\tindex {\tpindex} +\def\pindex {\pgindex} + +\def\cindexsub {\begingroup\obeylines\cindexsub} +{\obeylines % +\gdef\cindexsub "#1" #2^^M{\endgroup % +\dosubind{cp}{#2}{#1}}} + +% Define the macros used in formatting output of the sorted index material. + +% @printindex causes a particular index (the ??s file) to get printed. +% It does not print any chapter heading (usually an @unnumbered). +% +\parseargdef\printindex{\begingroup + \dobreak \chapheadingskip{10000}% + % + \smallfonts \rm + \tolerance = 9500 + \plainfrenchspacing + \everypar = {}% don't want the \kern\-parindent from indentation suppression. + % + % See if the index file exists and is nonempty. + % Change catcode of @ here so that if the index file contains + % \initial {@} + % as its first line, TeX doesn't complain about mismatched braces + % (because it thinks @} is a control sequence). + \catcode`\@ = 12 + % See comment in \requireopenindexfile. + \def\indexname{#1}\ifx\indexname\indexisfl\def\indexname{f1}\fi + \openin 1 \jobname.\indexname s + \ifeof 1 + % \enddoublecolumns gets confused if there is no text in the index, + % and it loses the chapter title and the aux file entries for the + % index. The easiest way to prevent this problem is to make sure + % there is some text. + \putwordIndexNonexistent + \typeout{No file \jobname.\indexname s.}% + \else + \catcode`\\ = 0 + % + % If the index file exists but is empty, then \openin leaves \ifeof + % false. We have to make TeX try to read something from the file, so + % it can discover if there is anything in it. + \read 1 to \thisline + \ifeof 1 + \putwordIndexIsEmpty + \else + % Index files are almost Texinfo source, but we use \ as the escape + % character. It would be better to use @, but that's too big a change + % to make right now. + \def\indexbackslash{\ttbackslash}% + \let\indexlbrace\{ % Likewise, set these sequences for braces + \let\indexrbrace\} % used in the sort key. + \begindoublecolumns + \let\dotheinsertentrybox\dotheinsertentryboxwithpenalty + % + % Read input from the index file line by line. + \loopdo + \ifeof1 \else + \read 1 to \nextline + \fi + % + \indexinputprocessing + \thisline + % + \ifeof1\else + \let\thisline\nextline + \repeat + %% + \enddoublecolumns + \fi + \fi + \closein 1 +\endgroup} +\def\loopdo#1\repeat{\def\body{#1}\loopdoxxx} +\def\loopdoxxx{\let\next=\relax\body\let\next=\loopdoxxx\fi\next} + +\def\indexinputprocessing{% + \ifeof1 + \let\firsttoken\relax + \else + \edef\act{\gdef\noexpand\firsttoken{\getfirsttoken\nextline}}% + \act + \fi +} +\def\getfirsttoken#1{\expandafter\getfirsttokenx#1\endfirsttoken} +\long\def\getfirsttokenx#1#2\endfirsttoken{\noexpand#1} + + +% These macros are used by the sorted index file itself. +% Change them to control the appearance of the index. + +{\catcode`\/=13 \catcode`\-=13 \catcode`\^=13 \catcode`\~=13 \catcode`\_=13 +\catcode`\|=13 \catcode`\<=13 \catcode`\>=13 \catcode`\+=13 \catcode`\"=13 +\catcode`\$=3 +\gdef\initialglyphs{% + % Some changes for non-alphabetic characters. Using the glyphs from the + % math fonts looks more consistent than the typewriter font used elsewhere + % for these characters. + \def\indexbackslash{\math{\backslash}}% + \let\\=\indexbackslash + % + % Can't get bold backslash so don't use bold forward slash + \catcode`\/=13 + \def/{{\secrmnotbold \normalslash}}% + \def-{{\normaldash\normaldash}}% en dash `--' + \def^{{\chapbf \normalcaret}}% + \def~{{\chapbf \normaltilde}}% + \def\_{% + \leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }% + \def|{$\vert$}% + \def<{$\less$}% + \def>{$\gtr$}% + \def+{$\normalplus$}% +}} + +\def\initial{% + \bgroup + \initialglyphs + \initialx +} + +\def\initialx#1{% + % Remove any glue we may have, we'll be inserting our own. + \removelastskip + % + % We like breaks before the index initials, so insert a bonus. + % The glue before the bonus allows a little bit of space at the + % bottom of a column to reduce an increase in inter-line spacing. + \nobreak + \vskip 0pt plus 5\baselineskip + \penalty -300 + \vskip 0pt plus -5\baselineskip + % + % Typeset the initial. Making this add up to a whole number of + % baselineskips increases the chance of the dots lining up from column + % to column. It still won't often be perfect, because of the stretch + % we need before each entry, but it's better. + % + % No shrink because it confuses \balancecolumns. + \vskip 1.67\baselineskip plus 1\baselineskip + \leftline{\secfonts \kern-0.05em \secbf #1}% + % \secfonts is inside the argument of \leftline so that the change of + % \baselineskip will not affect any glue inserted before the vbox that + % \leftline creates. + % Do our best not to break after the initial. + \nobreak + \vskip .33\baselineskip plus .1\baselineskip + \egroup % \initialglyphs +} + +\newdimen\entryrightmargin +\entryrightmargin=0pt + +% \entry typesets a paragraph consisting of the text (#1), dot leaders, and +% then page number (#2) flushed to the right margin. It is used for index +% and table of contents entries. The paragraph is indented by \leftskip. +% +\def\entry{% + \begingroup + % + % For pdfTeX and XeTeX. + % The redefinition of \domark stops marks being added in \pdflink to + % preserve coloured links across page boundaries. Otherwise the marks + % would get in the way of \lastbox in \insertentrybox. + \let\domark\relax + % + % Start a new paragraph if necessary, so our assignments below can't + % affect previous text. + \par + % + % No extra space above this paragraph. + \parskip = 0in + % + % When reading the text of entry, convert explicit line breaks + % from @* into spaces. The user might give these in long section + % titles, for instance. + \def\*{\unskip\space\ignorespaces}% + \def\entrybreak{\hfil\break}% An undocumented command + % + % Swallow the left brace of the text (first parameter): + \afterassignment\doentry + \let\temp = +} +\def\entrybreak{\unskip\space\ignorespaces}% +\def\doentry{% + % Save the text of the entry + \global\setbox\boxA=\hbox\bgroup + \bgroup % Instead of the swallowed brace. + \noindent + \aftergroup\finishentry + % And now comes the text of the entry. + % Not absorbing as a macro argument reduces the chance of problems + % with catcodes occurring. +} +{\catcode`\@=11 +\gdef\finishentry#1{% + \egroup % end box A + \dimen@ = \wd\boxA % Length of text of entry + \global\setbox\boxA=\hbox\bgroup\unhbox\boxA + % #1 is the page number. + % + % Get the width of the page numbers, and only use + % leaders if they are present. + \global\setbox\boxB = \hbox{#1}% + \ifdim\wd\boxB = 0pt + \null\nobreak\hfill\ % + \else + % + \null\nobreak\indexdotfill % Have leaders before the page number. + % + \ifpdf + \pdfgettoks#1.% + \hskip\skip\thinshrinkable\the\toksA + \else + \ifx\XeTeXrevision\thisisundefined + \hskip\skip\thinshrinkable #1% + \else + \pdfgettoks#1.% + \hskip\skip\thinshrinkable\the\toksA + \fi + \fi + \fi + \egroup % end \boxA + \ifdim\wd\boxB = 0pt + \global\setbox\entrybox=\vbox{\unhbox\boxA}% + \else + \global\setbox\entrybox=\vbox\bgroup + % We want the text of the entries to be aligned to the left, and the + % page numbers to be aligned to the right. + % + \parindent = 0pt + \advance\leftskip by 0pt plus 1fil + \advance\leftskip by 0pt plus -1fill + \rightskip = 0pt plus -1fil + \advance\rightskip by 0pt plus 1fill + % Cause last line, which could consist of page numbers on their own + % if the list of page numbers is long, to be aligned to the right. + \parfillskip=0pt plus -1fill + % + \advance\rightskip by \entryrightmargin + % Determine how far we can stretch into the margin. + % This allows, e.g., "Appendix H GNU Free Documentation License" to + % fit on one line in @letterpaper format. + \ifdim\entryrightmargin>2.1em + \dimen@i=2.1em + \else + \dimen@i=0em + \fi + \advance \parfillskip by 0pt minus 1\dimen@i + % + \dimen@ii = \hsize + \advance\dimen@ii by -1\leftskip + \advance\dimen@ii by -1\entryrightmargin + \advance\dimen@ii by 1\dimen@i + \ifdim\wd\boxA > \dimen@ii % If the entry doesn't fit in one line + \ifdim\dimen@ > 0.8\dimen@ii % due to long index text + \dimen@ = 0.7\dimen@ % Try to split the text roughly evenly + \dimen@ii = \hsize + \ifnum\dimen@>\dimen@ii + % If the entry is too long, use the whole line + \dimen@ = \dimen@ii + \fi + \advance\leftskip by 0pt plus 1fill % ragged right + \advance \dimen@ by 1\rightskip + \parshape = 2 0pt \dimen@ 0em \dimen@ii + % Ideally we'd add a finite glue at the end of the first line only, + % instead of using \parshape with explicit line lengths, but TeX + % doesn't seem to provide a way to do such a thing. + % + \leftskip = 1em + \parindent = -1em + \fi\fi + \indent % start paragraph + \unhbox\boxA + % + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % Word spacing - no stretch + \spaceskip=\fontdimen2\font minus \fontdimen4\font + % + \linepenalty=1000 % Discourage line breaks. + \hyphenpenalty=5000 % Discourage hyphenation. + % + \par % format the paragraph + \egroup % The \vbox + \fi + \endgroup + \dotheinsertentrybox +}} + +\newskip\thinshrinkable +\skip\thinshrinkable=.15em minus .15em + +\newbox\entrybox +\def\insertentrybox{% + \ourunvbox\entrybox +} + +% default definition +\let\dotheinsertentrybox\insertentrybox + +% Use \lastbox to take apart vbox box by box, and add each sub-box +% to the current vertical list. +\def\ourunvbox#1{% +\bgroup % for local binding of \delayedbox + % Remove the last box from box #1 + \global\setbox#1=\vbox{% + \unvbox#1% + \unskip % remove any glue + \unpenalty + \global\setbox\interbox=\lastbox + }% + \setbox\delayedbox=\box\interbox + \ifdim\ht#1=0pt\else + \ourunvbox#1 % Repeat on what's left of the box + \nobreak + \fi + \box\delayedbox +\egroup +} +\newbox\delayedbox +\newbox\interbox + +% Used from \printindex. \firsttoken should be the first token +% after the \entry. If it's not another \entry, we are at the last +% line of a group of index entries, so insert a penalty to discourage +% widowed index entries. +\def\dotheinsertentryboxwithpenalty{% + \ifx\firsttoken\isentry + \else + \penalty 9000 + \fi + \insertentrybox +} +\def\isentry{\entry}% + +% Like plain.tex's \dotfill, except uses up at least 1 em. +% The filll stretch here overpowers both the fil and fill stretch to push +% the page number to the right. +\def\indexdotfill{\cleaders + \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1filll} + + +\def\primary #1{\line{#1\hfil}} + +\newskip\secondaryindent \secondaryindent=0.5cm +\def\secondary#1#2{{% + \parfillskip=0in + \parskip=0in + \hangindent=1in + \hangafter=1 + \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill + \ifpdf + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \else + \ifx\XeTeXrevision\thisisundefined + #2 + \else + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \fi + \fi + \par +}} + +% Define two-column mode, which we use to typeset indexes. +% Adapted from the TeXbook, page 416, which is to say, +% the manmac.tex format used to print the TeXbook itself. +\catcode`\@=11 % private names + +\newbox\partialpage +\newdimen\doublecolumnhsize + +% Use inside an output routine to save \topmark and \firstmark +\def\savemarks{% + \global\savedtopmark=\expandafter{\topmark }% + \global\savedfirstmark=\expandafter{\firstmark }% +} +\newtoks\savedtopmark +\newtoks\savedfirstmark + +% Set \topmark and \firstmark for next time \output runs. +% Can't be run from withinside \output (because any material +% added while an output routine is active, including +% penalties, is saved for after it finishes). The page so far +% should be empty, otherwise what's on it will be thrown away. +\def\restoremarks{% + \mark{\the\savedtopmark}% + \bgroup\output = {% + \setbox\dummybox=\box\PAGE + }abc\eject\egroup + % "abc" because output routine doesn't fire for a completely empty page. + \mark{\the\savedfirstmark}% +} + +\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns + % If not much space left on page, start a new page. + \ifdim\pagetotal>0.8\vsize\vfill\eject\fi + % + % Grab any single-column material above us. + \output = {% + % + % Here is a possibility not foreseen in manmac: if we accumulate a + % whole lot of material, we might end up calling this \output + % routine twice in a row (see the doublecol-lose test, which is + % essentially a couple of indexes with @setchapternewpage off). In + % that case we just ship out what is in \partialpage with the normal + % output routine. Generally, \partialpage will be empty when this + % runs and this will be a no-op. See the indexspread.tex test case. + \ifvoid\partialpage \else + \onepageout{\pagecontents\partialpage}% + \fi + % + \global\setbox\partialpage = \vbox{% + % Unvbox the main output page. + \unvbox\PAGE + \kern-\topskip \kern\baselineskip + }% + \savemarks + }% + \eject % run that output routine to set \partialpage + \restoremarks + % + % We recover the two marks that the last output routine saved in order + % to propagate the information in marks added around a chapter heading, + % which could be otherwise be lost by the time the final page is output. + % + % + % Use the double-column output routine for subsequent pages. + \output = {\doublecolumnout}% + % + % Change the page size parameters. We could do this once outside this + % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 + % format, but then we repeat the same computation. Repeating a couple + % of assignments once per index is clearly meaningless for the + % execution time, so we may as well do it in one place. + % + % First we halve the line length, less a little for the gutter between + % the columns. We compute the gutter based on the line length, so it + % changes automatically with the paper format. The magic constant + % below is chosen so that the gutter has the same value (well, +-<1pt) + % as it did when we hard-coded it. + % + % We put the result in a separate register, \doublecolumhsize, so we + % can restore it in \pagesofar, after \hsize itself has (potentially) + % been clobbered. + % + \doublecolumnhsize = \hsize + \advance\doublecolumnhsize by -.04154\hsize + \divide\doublecolumnhsize by 2 + \hsize = \doublecolumnhsize + % + % Double the \vsize as well. + \advance\vsize by -\ht\partialpage + \vsize = 2\vsize + % + % For the benefit of balancing columns + \advance\baselineskip by 0pt plus 0.5pt +} + +% The double-column output routine for all double-column pages except +% the last, which is done by \balancecolumns. +% +\def\doublecolumnout{% + % + \splittopskip=\topskip \splitmaxdepth=\maxdepth + % Get the available space for the double columns -- the normal + % (undoubled) page height minus any material left over from the + % previous page. + \dimen@ = \vsize + \divide\dimen@ by 2 + % + % box0 will be the left-hand column, box2 the right. + \setbox0=\vsplit\PAGE to\dimen@ \setbox2=\vsplit\PAGE to\dimen@ + \global\advance\vsize by 2\ht\partialpage + \onepageout\pagesofar + \unvbox\PAGE + \penalty\outputpenalty +} +% +% Re-output the contents of the output page -- any previous material, +% followed by the two boxes we just split, in box0 and box2. +\def\pagesofar{% + \unvbox\partialpage + % + \hsize = \doublecolumnhsize + \wd0=\hsize \wd2=\hsize + \hbox to\txipagewidth{\box0\hfil\box2}% +} + + +% Finished with with double columns. +\def\enddoublecolumns{% + % The following penalty ensures that the page builder is exercised + % _before_ we change the output routine. This is necessary in the + % following situation: + % + % The last section of the index consists only of a single entry. + % Before this section, \pagetotal is less than \pagegoal, so no + % break occurs before the last section starts. However, the last + % section, consisting of \initial and the single \entry, does not + % fit on the page and has to be broken off. Without the following + % penalty the page builder will not be exercised until \eject + % below, and by that time we'll already have changed the output + % routine to the \balancecolumns version, so the next-to-last + % double-column page will be processed with \balancecolumns, which + % is wrong: The two columns will go to the main vertical list, with + % the broken-off section in the recent contributions. As soon as + % the output routine finishes, TeX starts reconsidering the page + % break. The two columns and the broken-off section both fit on the + % page, because the two columns now take up only half of the page + % goal. When TeX sees \eject from below which follows the final + % section, it invokes the new output routine that we've set after + % \balancecolumns below; \onepageout will try to fit the two columns + % and the final section into the vbox of \txipageheight (see + % \pagebody), causing an overfull box. + % + % Note that glue won't work here, because glue does not exercise the + % page builder, unlike penalties (see The TeXbook, pp. 280-281). + \penalty0 + % + \output = {% + % Split the last of the double-column material. + \savemarks + \balancecolumns + % + % Having called \balancecolumns once, we do not + % want to call it again. Therefore, reset \output to its normal + % definition right away. + \global\output = {\onepageout{\pagecontents\PAGE}}% + }% + \eject + \endgroup % started in \begindoublecolumns + \restoremarks + % Leave the double-column material on the current page, no automatic + % page break. + \box\balancedcolumns + % + % \pagegoal was set to the doubled \vsize above, since we restarted + % the current page. We're now back to normal single-column + % typesetting, so reset \pagegoal to the normal \vsize. + \global\vsize = \txipageheight % + \pagegoal = \txipageheight % +} +\newbox\balancedcolumns +\setbox\balancedcolumns=\vbox{shouldnt see this}% +% +% Only called for the last of the double column material. \doublecolumnout +% does the others. +\def\balancecolumns{% + \setbox0 = \vbox{\unvbox\PAGE}% like \box255 but more efficient, see p.120. + \dimen@ = \ht0 + \advance\dimen@ by \topskip + \advance\dimen@ by-\baselineskip + \ifdim\dimen@<5\baselineskip + % Don't split a short final column in two. + \setbox2=\vbox{}% + \else + \divide\dimen@ by 2 % target to split to + \dimen@ii = \dimen@ + \splittopskip = \topskip + % Loop until left column is at least as high as the right column. + {% + \vbadness = 10000 + \loop + \global\setbox3 = \copy0 + \global\setbox1 = \vsplit3 to \dimen@ + \ifdim\ht1<\ht3 + \global\advance\dimen@ by 1pt + \repeat + }% + % Now the left column is in box 1, and the right column in box 3. + % Check whether the left column has come out higher than the page itself. + % (Note that we have doubled \vsize for the double columns, so + % the actual height of the page is 0.5\vsize). + \ifdim2\ht1>\vsize + % Just split the last of the double column material roughly in half. + \setbox2=\box0 + \setbox0 = \vsplit2 to \dimen@ii + \setbox0=\vbox to \dimen@ii {\unvbox0\vfill}% + \setbox2=\vbox to \dimen@ii {\unvbox2\vfill}% + \else + % Compare the heights of the two columns. + \ifdim4\ht1>5\ht3 + % Column heights are too different, so don't make their bottoms + % flush with each other. + \setbox2=\vbox to \ht1 {\unvbox3\vfill}% + \setbox0=\vbox to \ht1 {\unvbox1\vfill}% + \else + % Make column bottoms flush with each other. + \setbox2=\vbox to\ht1{\unvbox3\unskip}% + \setbox0=\vbox to\ht1{\unvbox1\unskip}% + \fi + \fi + \fi + % + \global\setbox\balancedcolumns=\vbox{\pagesofar}% +} +\catcode`\@ = \other + + +\message{sectioning,} +% Chapters, sections, etc. + +% Let's start with @part. +\outer\parseargdef\part{\partzzz{#1}} +\def\partzzz#1{% + \chapoddpage + \null + \vskip.3\vsize % move it down on the page a bit + \begingroup + \noindent \titlefonts\rm #1\par % the text + \let\lastnode=\empty % no node to associate with + \writetocentry{part}{#1}{}% but put it in the toc + \headingsoff % no headline or footline on the part page + % This outputs a mark at the end of the page that clears \thischapter + % and \thissection, as is done in \startcontents. + \let\pchapsepmacro\relax + \chapmacro{}{Yomitfromtoc}{}% + \chapoddpage + \endgroup +} + +% \unnumberedno is an oxymoron. But we count the unnumbered +% sections so that we can refer to them unambiguously in the pdf +% outlines by their "section number". We avoid collisions with chapter +% numbers by starting them at 10000. (If a document ever has 10000 +% chapters, we're in trouble anyway, I'm sure.) +\newcount\unnumberedno \unnumberedno = 10000 +\newcount\chapno +\newcount\secno \secno=0 +\newcount\subsecno \subsecno=0 +\newcount\subsubsecno \subsubsecno=0 + +% This counter is funny since it counts through charcodes of letters A, B, ... +\newcount\appendixno \appendixno = `\@ +% +% \def\appendixletter{\char\the\appendixno} +% We do the following ugly conditional instead of the above simple +% construct for the sake of pdftex, which needs the actual +% letter in the expansion, not just typeset. +% +\def\appendixletter{% + \ifnum\appendixno=`A A% + \else\ifnum\appendixno=`B B% + \else\ifnum\appendixno=`C C% + \else\ifnum\appendixno=`D D% + \else\ifnum\appendixno=`E E% + \else\ifnum\appendixno=`F F% + \else\ifnum\appendixno=`G G% + \else\ifnum\appendixno=`H H% + \else\ifnum\appendixno=`I I% + \else\ifnum\appendixno=`J J% + \else\ifnum\appendixno=`K K% + \else\ifnum\appendixno=`L L% + \else\ifnum\appendixno=`M M% + \else\ifnum\appendixno=`N N% + \else\ifnum\appendixno=`O O% + \else\ifnum\appendixno=`P P% + \else\ifnum\appendixno=`Q Q% + \else\ifnum\appendixno=`R R% + \else\ifnum\appendixno=`S S% + \else\ifnum\appendixno=`T T% + \else\ifnum\appendixno=`U U% + \else\ifnum\appendixno=`V V% + \else\ifnum\appendixno=`W W% + \else\ifnum\appendixno=`X X% + \else\ifnum\appendixno=`Y Y% + \else\ifnum\appendixno=`Z Z% + % The \the is necessary, despite appearances, because \appendixletter is + % expanded while writing the .toc file. \char\appendixno is not + % expandable, thus it is written literally, thus all appendixes come out + % with the same letter (or @) in the toc without it. + \else\char\the\appendixno + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + +% Each @chapter defines these (using marks) as the number+name, number +% and name of the chapter. Page headings and footings can use +% these. @section does likewise. +\def\thischapter{} +\def\thischapternum{} +\def\thischaptername{} +\def\thissection{} +\def\thissectionnum{} +\def\thissectionname{} + +\newcount\absseclevel % used to calculate proper heading level +\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count + +% @raisesections: treat @section as chapter, @subsection as section, etc. +\def\raisesections{\global\advance\secbase by -1} +\let\up=\raisesections % original BFox name + +% @lowersections: treat @chapter as section, @section as subsection, etc. +\def\lowersections{\global\advance\secbase by 1} +\let\down=\lowersections % original BFox name + +% we only have subsub. +\chardef\maxseclevel = 3 +% +% A numbered section within an unnumbered changes to unnumbered too. +% To achieve this, remember the "biggest" unnum. sec. we are currently in: +\chardef\unnlevel = \maxseclevel +% +% Trace whether the current chapter is an appendix or not: +% \chapheadtype is "N" or "A", unnumbered chapters are ignored. +\def\chapheadtype{N} + +% Choose a heading macro +% #1 is heading type +% #2 is heading level +% #3 is text for heading +\def\genhead#1#2#3{% + % Compute the abs. sec. level: + \absseclevel=#2 + \advance\absseclevel by \secbase + % Make sure \absseclevel doesn't fall outside the range: + \ifnum \absseclevel < 0 + \absseclevel = 0 + \else + \ifnum \absseclevel > 3 + \absseclevel = 3 + \fi + \fi + % The heading type: + \def\headtype{#1}% + \if \headtype U% + \ifnum \absseclevel < \unnlevel + \chardef\unnlevel = \absseclevel + \fi + \else + % Check for appendix sections: + \ifnum \absseclevel = 0 + \edef\chapheadtype{\headtype}% + \else + \if \headtype A\if \chapheadtype N% + \errmessage{@appendix... within a non-appendix chapter}% + \fi\fi + \fi + % Check for numbered within unnumbered: + \ifnum \absseclevel > \unnlevel + \def\headtype{U}% + \else + \chardef\unnlevel = 3 + \fi + \fi + % Now print the heading: + \if \headtype U% + \ifcase\absseclevel + \unnumberedzzz{#3}% + \or \unnumberedseczzz{#3}% + \or \unnumberedsubseczzz{#3}% + \or \unnumberedsubsubseczzz{#3}% + \fi + \else + \if \headtype A% + \ifcase\absseclevel + \appendixzzz{#3}% + \or \appendixsectionzzz{#3}% + \or \appendixsubseczzz{#3}% + \or \appendixsubsubseczzz{#3}% + \fi + \else + \ifcase\absseclevel + \chapterzzz{#3}% + \or \seczzz{#3}% + \or \numberedsubseczzz{#3}% + \or \numberedsubsubseczzz{#3}% + \fi + \fi + \fi + \suppressfirstparagraphindent +} + +% an interface: +\def\numhead{\genhead N} +\def\apphead{\genhead A} +\def\unnmhead{\genhead U} + +% @chapter, @appendix, @unnumbered. Increment top-level counter, reset +% all lower-level sectioning counters to zero. +% +% Also set \chaplevelprefix, which we prepend to @float sequence numbers +% (e.g., figures), q.v. By default (before any chapter), that is empty. +\let\chaplevelprefix = \empty +% +\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz +\def\chapterzzz#1{% + % section resetting is \global in case the chapter is in a group, such + % as an @include file. + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\chapno by 1 + % + % Used for \float. + \gdef\chaplevelprefix{\the\chapno.}% + \resetallfloatnos + % + % \putwordChapter can contain complex things in translations. + \toks0=\expandafter{\putwordChapter}% + \message{\the\toks0 \space \the\chapno}% + % + % Write the actual heading. + \chapmacro{#1}{Ynumbered}{\the\chapno}% + % + % So @section and the like are numbered underneath this chapter. + \global\let\section = \numberedsec + \global\let\subsection = \numberedsubsec + \global\let\subsubsection = \numberedsubsubsec +} + +\outer\parseargdef\appendix{\apphead0{#1}} % normally calls appendixzzz +% +\def\appendixzzz#1{% + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\appendixno by 1 + \gdef\chaplevelprefix{\appendixletter.}% + \resetallfloatnos + % + % \putwordAppendix can contain complex things in translations. + \toks0=\expandafter{\putwordAppendix}% + \message{\the\toks0 \space \appendixletter}% + % + \chapmacro{#1}{Yappendix}{\appendixletter}% + % + \global\let\section = \appendixsec + \global\let\subsection = \appendixsubsec + \global\let\subsubsection = \appendixsubsubsec +} + +% normally unnmhead0 calls unnumberedzzz: +\outer\parseargdef\unnumbered{\unnmhead0{#1}} +\def\unnumberedzzz#1{% + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\unnumberedno by 1 + % + % Since an unnumbered has no number, no prefix for figures. + \global\let\chaplevelprefix = \empty + \resetallfloatnos + % + % This used to be simply \message{#1}, but TeX fully expands the + % argument to \message. Therefore, if #1 contained @-commands, TeX + % expanded them. For example, in `@unnumbered The @cite{Book}', TeX + % expanded @cite (which turns out to cause errors because \cite is meant + % to be executed, not expanded). + % + % Anyway, we don't want the fully-expanded definition of @cite to appear + % as a result of the \message, we just want `@cite' itself. We use + % \the to achieve this: TeX expands \the only once, + % simply yielding the contents of . (We also do this for + % the toc entries.) + \toks0 = {#1}% + \message{(\the\toks0)}% + % + \chapmacro{#1}{Ynothing}{\the\unnumberedno}% + % + \global\let\section = \unnumberedsec + \global\let\subsection = \unnumberedsubsec + \global\let\subsubsection = \unnumberedsubsubsec +} + +% @centerchap is like @unnumbered, but the heading is centered. +\outer\parseargdef\centerchap{% + \let\centerparametersmaybe = \centerparameters + \unnmhead0{#1}% + \let\centerparametersmaybe = \relax +} + +% @top is like @unnumbered. +\let\top\unnumbered + +% Sections. +% +\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz +\def\seczzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}% +} + +% normally calls appendixsectionzzz: +\outer\parseargdef\appendixsection{\apphead1{#1}} +\def\appendixsectionzzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}% +} +\let\appendixsec\appendixsection + +% normally calls unnumberedseczzz: +\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} +\def\unnumberedseczzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}% +} + +% Subsections. +% +% normally calls numberedsubseczzz: +\outer\parseargdef\numberedsubsec{\numhead2{#1}} +\def\numberedsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}% +} + +% normally calls appendixsubseczzz: +\outer\parseargdef\appendixsubsec{\apphead2{#1}} +\def\appendixsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Yappendix}% + {\appendixletter.\the\secno.\the\subsecno}% +} + +% normally calls unnumberedsubseczzz: +\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} +\def\unnumberedsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Ynothing}% + {\the\unnumberedno.\the\secno.\the\subsecno}% +} + +% Subsubsections. +% +% normally numberedsubsubseczzz: +\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} +\def\numberedsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Ynumbered}% + {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +% normally appendixsubsubseczzz: +\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} +\def\appendixsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Yappendix}% + {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +% normally unnumberedsubsubseczzz: +\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} +\def\unnumberedsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Ynothing}% + {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +% These macros control what the section commands do, according +% to what kind of chapter we are in (ordinary, appendix, or unnumbered). +% Define them by default for a numbered chapter. +\let\section = \numberedsec +\let\subsection = \numberedsubsec +\let\subsubsection = \numberedsubsubsec + +% Define @majorheading, @heading and @subheading + +\def\majorheading{% + {\advance\chapheadingskip by 10pt \chapbreak }% + \parsearg\chapheadingzzz +} + +\def\chapheading{\chapbreak \parsearg\chapheadingzzz} +\def\chapheadingzzz#1{% + \vbox{\chapfonts \raggedtitlesettings #1\par}% + \nobreak\bigskip \nobreak + \suppressfirstparagraphindent +} + +% @heading, @subheading, @subsubheading. +\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} +\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} +\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} + +% These macros generate a chapter, section, etc. heading only +% (including whitespace, linebreaking, etc. around it), +% given all the information in convenient, parsed form. + +% Args are the skip and penalty (usually negative) +\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} + +% Parameter controlling skip before chapter headings (if needed) +\newskip\chapheadingskip + +% Define plain chapter starts, and page on/off switching for it. +\def\chapbreak{\dobreak \chapheadingskip {-4000}} + +% Start a new page +\def\chappager{\par\vfill\supereject} + +% \chapoddpage - start on an odd page for a new chapter +% Because \domark is called before \chapoddpage, the filler page will +% get the headings for the next chapter, which is wrong. But we don't +% care -- we just disable all headings on the filler page. +\def\chapoddpage{% + \chappager + \ifodd\pageno \else + \begingroup + \headingsoff + \null + \chappager + \endgroup + \fi +} + +\parseargdef\setchapternewpage{\csname CHAPPAG#1\endcsname} + +\def\CHAPPAGoff{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chapbreak +\global\let\pagealignmacro=\chappager} + +\def\CHAPPAGon{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chappager +\global\let\pagealignmacro=\chappager +\global\def\HEADINGSon{\HEADINGSsingle}} + +\def\CHAPPAGodd{% +\global\let\contentsalignmacro = \chapoddpage +\global\let\pchapsepmacro=\chapoddpage +\global\let\pagealignmacro=\chapoddpage +\global\def\HEADINGSon{\HEADINGSdouble}} + +\CHAPPAGon + +% \chapmacro - Chapter opening. +% +% #1 is the text, #2 is the section type (Ynumbered, Ynothing, +% Yappendix, Yomitfromtoc), #3 the chapter number. +% Not used for @heading series. +% +% To test against our argument. +\def\Ynothingkeyword{Ynothing} +\def\Yappendixkeyword{Yappendix} +\def\Yomitfromtockeyword{Yomitfromtoc} +% +\def\chapmacro#1#2#3{% + \expandafter\ifx\thisenv\titlepage\else + \checkenv{}% chapters, etc., should not start inside an environment. + \fi + % FIXME: \chapmacro is currently called from inside \titlepage when + % \setcontentsaftertitlepage to print the "Table of Contents" heading, but + % this should probably be done by \sectionheading with an option to print + % in chapter size. + % + % Insert the first mark before the heading break (see notes for \domark). + \let\prevchapterdefs=\lastchapterdefs + \let\prevsectiondefs=\lastsectiondefs + \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}% + \gdef\thissection{}}% + % + \def\temptype{#2}% + \ifx\temptype\Ynothingkeyword + \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% + \gdef\thischapter{\thischaptername}}% + \else\ifx\temptype\Yomitfromtockeyword + \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% + \gdef\thischapter{}}% + \else\ifx\temptype\Yappendixkeyword + \toks0={#1}% + \xdef\lastchapterdefs{% + \gdef\noexpand\thischaptername{\the\toks0}% + \gdef\noexpand\thischapternum{\appendixletter}% + % \noexpand\putwordAppendix avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thischapter{\noexpand\putwordAppendix{} + \noexpand\thischapternum: + \noexpand\thischaptername}% + }% + \else + \toks0={#1}% + \xdef\lastchapterdefs{% + \gdef\noexpand\thischaptername{\the\toks0}% + \gdef\noexpand\thischapternum{\the\chapno}% + % \noexpand\putwordChapter avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thischapter{\noexpand\putwordChapter{} + \noexpand\thischapternum: + \noexpand\thischaptername}% + }% + \fi\fi\fi + % + % Output the mark. Pass it through \safewhatsit, to take care of + % the preceding space. + \safewhatsit\domark + % + % Insert the chapter heading break. + \pchapsepmacro + % + % Now the second mark, after the heading break. No break points + % between here and the heading. + \let\prevchapterdefs=\lastchapterdefs + \let\prevsectiondefs=\lastsectiondefs + \domark + % + {% + \chapfonts \rm + \let\footnote=\errfootnoteheading % give better error message + % + % Have to define \lastsection before calling \donoderef, because the + % xref code eventually uses it. On the other hand, it has to be called + % after \pchapsepmacro, or the headline will change too soon. + \gdef\lastsection{#1}% + % + % Only insert the separating space if we have a chapter/appendix + % number, and don't print the unnumbered ``number''. + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unnchap}% + \else\ifx\temptype\Yomitfromtockeyword + \setbox0 = \hbox{}% contents like unnumbered, but no toc entry + \def\toctype{omit}% + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{\putwordAppendix{} #3\enspace}% + \def\toctype{app}% + \else + \setbox0 = \hbox{#3\enspace}% + \def\toctype{numchap}% + \fi\fi\fi + % + % Write the toc entry for this chapter. Must come before the + % \donoderef, because we include the current node name in the toc + % entry, and \donoderef resets it to empty. + \writetocentry{\toctype}{#1}{#3}% + % + % For pdftex, we have to write out the node definition (aka, make + % the pdfdest) after any page break, but before the actual text has + % been typeset. If the destination for the pdf outline is after the + % text, then jumping from the outline may wind up with the text not + % being visible, for instance under high magnification. + \donoderef{#2}% + % + % Typeset the actual heading. + \nobreak % Avoid page breaks at the interline glue. + \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe + \unhbox0 #1\par}% + }% + \nobreak\bigskip % no page break after a chapter title + \nobreak +} + +% @centerchap -- centered and unnumbered. +\let\centerparametersmaybe = \relax +\def\centerparameters{% + \advance\rightskip by 3\rightskip + \leftskip = \rightskip + \parfillskip = 0pt +} + + +% Section titles. These macros combine the section number parts and +% call the generic \sectionheading to do the printing. +% +\newskip\secheadingskip +\def\secheadingbreak{\dobreak \secheadingskip{-1000}} + +% Subsection titles. +\newskip\subsecheadingskip +\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}} + +% Subsubsection titles. +\def\subsubsecheadingskip{\subsecheadingskip} +\def\subsubsecheadingbreak{\subsecheadingbreak} + + +% Print any size, any type, section title. +% +% #1 is the text of the title, +% #2 is the section level (sec/subsec/subsubsec), +% #3 is the section type (Ynumbered, Ynothing, Yappendix, Yomitfromtoc), +% #4 is the section number. +% +\def\seckeyword{sec} +% +\def\sectionheading#1#2#3#4{% + {% + \def\sectionlevel{#2}% + \def\temptype{#3}% + % + % It is ok for the @heading series commands to appear inside an + % environment (it's been historically allowed, though the logic is + % dubious), but not the others. + \ifx\temptype\Yomitfromtockeyword\else + \checkenv{}% non-@*heading should not be in an environment. + \fi + \let\footnote=\errfootnoteheading + % + % Switch to the right set of fonts. + \csname #2fonts\endcsname \rm + % + % Insert first mark before the heading break (see notes for \domark). + \let\prevsectiondefs=\lastsectiondefs + \ifx\temptype\Ynothingkeyword + \ifx\sectionlevel\seckeyword + \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}% + \gdef\thissection{\thissectionname}}% + \fi + \else\ifx\temptype\Yomitfromtockeyword + % Don't redefine \thissection. + \else\ifx\temptype\Yappendixkeyword + \ifx\sectionlevel\seckeyword + \toks0={#1}% + \xdef\lastsectiondefs{% + \gdef\noexpand\thissectionname{\the\toks0}% + \gdef\noexpand\thissectionnum{#4}% + % \noexpand\putwordSection avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thissection{\noexpand\putwordSection{} + \noexpand\thissectionnum: + \noexpand\thissectionname}% + }% + \fi + \else + \ifx\sectionlevel\seckeyword + \toks0={#1}% + \xdef\lastsectiondefs{% + \gdef\noexpand\thissectionname{\the\toks0}% + \gdef\noexpand\thissectionnum{#4}% + % \noexpand\putwordSection avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thissection{\noexpand\putwordSection{} + \noexpand\thissectionnum: + \noexpand\thissectionname}% + }% + \fi + \fi\fi\fi + % + % Go into vertical mode. Usually we'll already be there, but we + % don't want the following whatsit to end up in a preceding paragraph + % if the document didn't happen to have a blank line. + \par + % + % Output the mark. Pass it through \safewhatsit, to take care of + % the preceding space. + \safewhatsit\domark + % + % Insert space above the heading. + \csname #2headingbreak\endcsname + % + % Now the second mark, after the heading break. No break points + % between here and the heading. + \global\let\prevsectiondefs=\lastsectiondefs + \domark + % + % Only insert the space after the number if we have a section number. + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unn}% + \gdef\lastsection{#1}% + \else\ifx\temptype\Yomitfromtockeyword + % for @headings -- no section number, don't include in toc, + % and don't redefine \lastsection. + \setbox0 = \hbox{}% + \def\toctype{omit}% + \let\sectionlevel=\empty + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{#4\enspace}% + \def\toctype{app}% + \gdef\lastsection{#1}% + \else + \setbox0 = \hbox{#4\enspace}% + \def\toctype{num}% + \gdef\lastsection{#1}% + \fi\fi\fi + % + % Write the toc entry (before \donoderef). See comments in \chapmacro. + \writetocentry{\toctype\sectionlevel}{#1}{#4}% + % + % Write the node reference (= pdf destination for pdftex). + % Again, see comments in \chapmacro. + \donoderef{#3}% + % + % Interline glue will be inserted when the vbox is completed. + % That glue will be a valid breakpoint for the page, since it'll be + % preceded by a whatsit (usually from the \donoderef, or from the + % \writetocentry if there was no node). We don't want to allow that + % break, since then the whatsits could end up on page n while the + % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000. + \nobreak + % + % Output the actual section heading. + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright + \hangindent=\wd0 % zero if no section number + \unhbox0 #1}% + }% + % Add extra space after the heading -- half of whatever came above it. + % Don't allow stretch, though. + \kern .5 \csname #2headingskip\endcsname + % + % Do not let the kern be a potential breakpoint, as it would be if it + % was followed by glue. + \nobreak + % + % We'll almost certainly start a paragraph next, so don't let that + % glue accumulate. (Not a breakpoint because it's preceded by a + % discardable item.) However, when a paragraph is not started next + % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out + % or the negative glue will cause weirdly wrong output, typically + % obscuring the section heading with something else. + \vskip-\parskip + % + % This is so the last item on the main vertical list is a known + % \penalty > 10000, so \startdefun, etc., can recognize the situation + % and do the needful. + \penalty 10001 +} + + +\message{toc,} +% Table of contents. +\newwrite\tocfile + +% Write an entry to the toc file, opening it if necessary. +% Called from @chapter, etc. +% +% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno} +% We append the current node name (if any) and page number as additional +% arguments for the \{chap,sec,...}entry macros which will eventually +% read this. The node name is used in the pdf outlines as the +% destination to jump to. +% +% We open the .toc file for writing here instead of at @setfilename (or +% any other fixed time) so that @contents can be anywhere in the document. +% But if #1 is `omit', then we don't do anything. This is used for the +% table of contents chapter openings themselves. +% +\newif\iftocfileopened +\def\omitkeyword{omit}% +% +\def\writetocentry#1#2#3{% + \edef\writetoctype{#1}% + \ifx\writetoctype\omitkeyword \else + \iftocfileopened\else + \immediate\openout\tocfile = \jobname.toc + \global\tocfileopenedtrue + \fi + % + \iflinks + {\atdummies + \edef\temp{% + \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}% + \temp + }% + \fi + \fi + % + % Tell \shipout to create a pdf destination on each page, if we're + % writing pdf. These are used in the table of contents. We can't + % just write one on every page because the title pages are numbered + % 1 and 2 (the page numbers aren't printed), and so are the first + % two pages of the document. Thus, we'd have two destinations named + % `1', and two named `2'. + \ifpdf + \global\pdfmakepagedesttrue + \else + \ifx\XeTeXrevision\thisisundefined + \else + \global\pdfmakepagedesttrue + \fi + \fi +} + + +% These characters do not print properly in the Computer Modern roman +% fonts, so we must take special care. This is more or less redundant +% with the Texinfo input format setup at the end of this file. +% +\def\activecatcodes{% + \catcode`\"=\active + \catcode`\$=\active + \catcode`\<=\active + \catcode`\>=\active + \catcode`\\=\active + \catcode`\^=\active + \catcode`\_=\active + \catcode`\|=\active + \catcode`\~=\active +} + + +% Read the toc file, which is essentially Texinfo input. +\def\readtocfile{% + \setupdatafile + \activecatcodes + \input \tocreadfilename +} + +\newskip\contentsrightmargin \contentsrightmargin=1in +\newcount\savepageno +\newcount\lastnegativepageno \lastnegativepageno = -1 + +% Prepare to read what we've written to \tocfile. +% +\def\startcontents#1{% + % If @setchapternewpage on, and @headings double, the contents should + % start on an odd page, unlike chapters. Thus, we maintain + % \contentsalignmacro in parallel with \pagealignmacro. + % From: Torbjorn Granlund + \contentsalignmacro + \immediate\closeout\tocfile + % + % Don't need to put `Contents' or `Short Contents' in the headline. + % It is abundantly clear what they are. + \chapmacro{#1}{Yomitfromtoc}{}% + % + \savepageno = \pageno + \begingroup % Set up to handle contents files properly. + \raggedbottom % Worry more about breakpoints than the bottom. + \entryrightmargin=\contentsrightmargin % Don't use the full line length. + % + % Roman numerals for page numbers. + \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi +} + +% redefined for the two-volume lispref. We always output on +% \jobname.toc even if this is redefined. +% +\def\tocreadfilename{\jobname.toc} + +% Normal (long) toc. +% +\def\contents{% + \startcontents{\putwordTOC}% + \openin 1 \tocreadfilename\space + \ifeof 1 \else + \readtocfile + \fi + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \ifeof 1 \else + \pdfmakeoutlines + \fi + \closein 1 + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno +} + +% And just the chapters. +\def\summarycontents{% + \startcontents{\putwordShortTOC}% + % + \let\partentry = \shortpartentry + \let\numchapentry = \shortchapentry + \let\appentry = \shortchapentry + \let\unnchapentry = \shortunnchapentry + % We want a true roman here for the page numbers. + \secfonts + \let\rm=\shortcontrm \let\bf=\shortcontbf + \let\sl=\shortcontsl \let\tt=\shortconttt + \rm + \hyphenpenalty = 10000 + \advance\baselineskip by 1pt % Open it up a little. + \def\numsecentry##1##2##3##4{} + \let\appsecentry = \numsecentry + \let\unnsecentry = \numsecentry + \let\numsubsecentry = \numsecentry + \let\appsubsecentry = \numsecentry + \let\unnsubsecentry = \numsecentry + \let\numsubsubsecentry = \numsecentry + \let\appsubsubsecentry = \numsecentry + \let\unnsubsubsecentry = \numsecentry + \openin 1 \tocreadfilename\space + \ifeof 1 \else + \readtocfile + \fi + \closein 1 + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno +} +\let\shortcontents = \summarycontents + +% Typeset the label for a chapter or appendix for the short contents. +% The arg is, e.g., `A' for an appendix, or `3' for a chapter. +% +\def\shortchaplabel#1{% + % This space should be enough, since a single number is .5em, and the + % widest letter (M) is 1em, at least in the Computer Modern fonts. + % But use \hss just in case. + % (This space doesn't include the extra space that gets added after + % the label; that gets put in by \shortchapentry above.) + % + % We'd like to right-justify chapter numbers, but that looks strange + % with appendix letters. And right-justifying numbers and + % left-justifying letters looks strange when there is less than 10 + % chapters. Have to read the whole toc once to know how many chapters + % there are before deciding ... + \hbox to 1em{#1\hss}% +} + +% These macros generate individual entries in the table of contents. +% The first argument is the chapter or section name. +% The last argument is the page number. +% The arguments in between are the chapter number, section number, ... + +% Parts, in the main contents. Replace the part number, which doesn't +% exist, with an empty box. Let's hope all the numbers have the same width. +% Also ignore the page number, which is conventionally not printed. +\def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}} +\def\partentry#1#2#3#4{\dochapentry{\numeralbox\labelspace#1}{}} +% +% Parts, in the short toc. +\def\shortpartentry#1#2#3#4{% + \penalty-300 + \vskip.5\baselineskip plus.15\baselineskip minus.1\baselineskip + \shortchapentry{{\bf #1}}{\numeralbox}{}{}% +} + +% Chapters, in the main contents. +\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} + +% Chapters, in the short toc. +% See comments in \dochapentry re vbox and related settings. +\def\shortchapentry#1#2#3#4{% + \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}% +} + +% Appendices, in the main contents. +% Need the word Appendix, and a fixed-size box. +% +\def\appendixbox#1{% + % We use M since it's probably the widest letter. + \setbox0 = \hbox{\putwordAppendix{} M}% + \hbox to \wd0{\putwordAppendix{} #1\hss}} +% +\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\hskip.7em#1}{#4}} + +% Unnumbered chapters. +\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}} +\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}} + +% Sections. +\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}} +\let\appsecentry=\numsecentry +\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}} + +% Subsections. +\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}} +\let\appsubsecentry=\numsubsecentry +\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}} + +% And subsubsections. +\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}} +\let\appsubsubsecentry=\numsubsubsecentry +\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}} + +% This parameter controls the indentation of the various levels. +% Same as \defaultparindent. +\newdimen\tocindent \tocindent = 15pt + +% Now for the actual typesetting. In all these, #1 is the text and #2 is the +% page number. +% +% If the toc has to be broken over pages, we want it to be at chapters +% if at all possible; hence the \penalty. +\def\dochapentry#1#2{% + \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip + \begingroup + % Move the page numbers slightly to the right + \advance\entryrightmargin by -0.05em + \chapentryfonts + \tocentry{#1}{\dopageno\bgroup#2\egroup}% + \endgroup + \nobreak\vskip .25\baselineskip plus.1\baselineskip +} + +\def\dosecentry#1#2{\begingroup + \secentryfonts \leftskip=\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsecentry#1#2{\begingroup + \subsecentryfonts \leftskip=2\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsubsecentry#1#2{\begingroup + \subsubsecentryfonts \leftskip=3\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +% We use the same \entry macro as for the index entries. +\let\tocentry = \entry + +% Space between chapter (or whatever) number and the title. +\def\labelspace{\hskip1em \relax} + +\def\dopageno#1{{\rm #1}} +\def\doshortpageno#1{{\rm #1}} + +\def\chapentryfonts{\secfonts \rm} +\def\secentryfonts{\textfonts} +\def\subsecentryfonts{\textfonts} +\def\subsubsecentryfonts{\textfonts} + + +\message{environments,} +% @foo ... @end foo. + +% @tex ... @end tex escapes into raw TeX temporarily. +% One exception: @ is still an escape character, so that @end tex works. +% But \@ or @@ will get a plain @ character. + +\envdef\tex{% + \setupmarkupstyle{tex}% + \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 + \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 + \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie + \catcode `\%=14 + \catcode `\+=\other + \catcode `\"=\other + \catcode `\|=\other + \catcode `\<=\other + \catcode `\>=\other + \catcode `\`=\other + \catcode `\'=\other + % + % ' is active in math mode (mathcode"8000). So reset it, and all our + % other math active characters (just in case), to plain's definitions. + \mathactive + % + % Inverse of the list at the beginning of the file. + \let\b=\ptexb + \let\bullet=\ptexbullet + \let\c=\ptexc + \let\,=\ptexcomma + \let\.=\ptexdot + \let\dots=\ptexdots + \let\equiv=\ptexequiv + \let\!=\ptexexclam + \let\i=\ptexi + \let\indent=\ptexindent + \let\noindent=\ptexnoindent + \let\{=\ptexlbrace + \let\+=\tabalign + \let\}=\ptexrbrace + \let\/=\ptexslash + \let\sp=\ptexsp + \let\*=\ptexstar + %\let\sup=\ptexsup % do not redefine, we want @sup to work in math mode + \let\t=\ptext + \expandafter \let\csname top\endcsname=\ptextop % we've made it outer + \let\frenchspacing=\plainfrenchspacing + % + \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% + \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% + \def\@{@}% +} +% There is no need to define \Etex. + +% Define @lisp ... @end lisp. +% @lisp environment forms a group so it can rebind things, +% including the definition of @end lisp (which normally is erroneous). + +% Amount to narrow the margins by for @lisp. +\newskip\lispnarrowing \lispnarrowing=0.4in + +% This is the definition that ^^M gets inside @lisp, @example, and other +% such environments. \null is better than a space, since it doesn't +% have any width. +\def\lisppar{\null\endgraf} + +% This space is always present above and below environments. +\newskip\envskipamount \envskipamount = 0pt + +% Make spacing and below environment symmetrical. We use \parskip here +% to help in doing that, since in @example-like environments \parskip +% is reset to zero; thus the \afterenvbreak inserts no space -- but the +% start of the next paragraph will insert \parskip. +% +\def\aboveenvbreak{{% + % =10000 instead of <10000 because of a special case in \itemzzz and + % \sectionheading, q.v. + \ifnum \lastpenalty=10000 \else + \advance\envskipamount by \parskip + \endgraf + \ifdim\lastskip<\envskipamount + \removelastskip + \ifnum\lastpenalty<10000 + % Penalize breaking before the environment, because preceding text + % often leads into it. + \penalty100 + \fi + \vskip\envskipamount + \fi + \fi +}} + +\def\afterenvbreak{{% + % =10000 instead of <10000 because of a special case in \itemzzz and + % \sectionheading, q.v. + \ifnum \lastpenalty=10000 \else + \advance\envskipamount by \parskip + \endgraf + \ifdim\lastskip<\envskipamount + \removelastskip + % it's not a good place to break if the last penalty was \nobreak + % or better ... + \ifnum\lastpenalty<10000 \penalty-50 \fi + \vskip\envskipamount + \fi + \fi +}} + +% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will +% also clear it, so that its embedded environments do the narrowing again. +\let\nonarrowing=\relax + +% @cartouche ... @end cartouche: draw rectangle w/rounded corners around +% environment contents. +\font\circle=lcircle10 +\newdimen\circthick +\newdimen\cartouter\newdimen\cartinner +\newskip\normbskip\newskip\normpskip\newskip\normlskip +\circthick=\fontdimen8\circle +% +\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth +\def\ctr{{\hskip 6pt\circle\char'010}} +\def\cbl{{\circle\char'012\hskip -6pt}} +\def\cbr{{\hskip 6pt\circle\char'011}} +\def\carttop{\hbox to \cartouter{\hskip\lskip + \ctl\leaders\hrule height\circthick\hfil\ctr + \hskip\rskip}} +\def\cartbot{\hbox to \cartouter{\hskip\lskip + \cbl\leaders\hrule height\circthick\hfil\cbr + \hskip\rskip}} +% +\newskip\lskip\newskip\rskip + +\envdef\cartouche{% + \ifhmode\par\fi % can't be in the midst of a paragraph. + \startsavinginserts + \lskip=\leftskip \rskip=\rightskip + \leftskip=0pt\rightskip=0pt % we want these *outside*. + \cartinner=\hsize \advance\cartinner by-\lskip + \advance\cartinner by-\rskip + \cartouter=\hsize + \advance\cartouter by 18.4pt % allow for 3pt kerns on either + % side, and for 6pt waste from + % each corner char, and rule thickness + \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip + % + % If this cartouche directly follows a sectioning command, we need the + % \parskip glue (backspaced over by default) or the cartouche can + % collide with the section heading. + \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi + % + \setbox\groupbox=\vbox\bgroup + \baselineskip=0pt\parskip=0pt\lineskip=0pt + \carttop + \hbox\bgroup + \hskip\lskip + \vrule\kern3pt + \vbox\bgroup + \kern3pt + \hsize=\cartinner + \baselineskip=\normbskip + \lineskip=\normlskip + \parskip=\normpskip + \vskip -\parskip + \comment % For explanation, see the end of def\group. +} +\def\Ecartouche{% + \ifhmode\par\fi + \kern3pt + \egroup + \kern3pt\vrule + \hskip\rskip + \egroup + \cartbot + \egroup + \addgroupbox + \checkinserts +} + + +% This macro is called at the beginning of all the @example variants, +% inside a group. +\newdimen\nonfillparindent +\def\nonfillstart{% + \aboveenvbreak + \ifdim\hfuzz < 12pt \hfuzz = 12pt \fi % Don't be fussy + \sepspaces % Make spaces be word-separators rather than space tokens. + \let\par = \lisppar % don't ignore blank lines + \obeylines % each line of input is a line of output + \parskip = 0pt + % Turn off paragraph indentation but redefine \indent to emulate + % the normal \indent. + \nonfillparindent=\parindent + \parindent = 0pt + \let\indent\nonfillindent + % + \emergencystretch = 0pt % don't try to avoid overfull boxes + \ifx\nonarrowing\relax + \advance \leftskip by \lispnarrowing + \exdentamount=\lispnarrowing + \else + \let\nonarrowing = \relax + \fi + \let\exdent=\nofillexdent +} + +\begingroup +\obeyspaces +% We want to swallow spaces (but not other tokens) after the fake +% @indent in our nonfill-environments, where spaces are normally +% active and set to @tie, resulting in them not being ignored after +% @indent. +\gdef\nonfillindent{\futurelet\temp\nonfillindentcheck}% +\gdef\nonfillindentcheck{% +\ifx\temp % +\expandafter\nonfillindentgobble% +\else% +\leavevmode\nonfillindentbox% +\fi% +}% +\endgroup +\def\nonfillindentgobble#1{\nonfillindent} +\def\nonfillindentbox{\hbox to \nonfillparindent{\hss}} + +% If you want all examples etc. small: @set dispenvsize small. +% If you want even small examples the full size: @set dispenvsize nosmall. +% This affects the following displayed environments: +% @example, @display, @format, @lisp +% +\def\smallword{small} +\def\nosmallword{nosmall} +\let\SETdispenvsize\relax +\def\setnormaldispenv{% + \ifx\SETdispenvsize\smallword + % end paragraph for sake of leading, in case document has no blank + % line. This is redundant with what happens in \aboveenvbreak, but + % we need to do it before changing the fonts, and it's inconvenient + % to change the fonts afterward. + \ifnum \lastpenalty=10000 \else \endgraf \fi + \smallexamplefonts \rm + \fi +} +\def\setsmalldispenv{% + \ifx\SETdispenvsize\nosmallword + \else + \ifnum \lastpenalty=10000 \else \endgraf \fi + \smallexamplefonts \rm + \fi +} + +% We often define two environments, @foo and @smallfoo. +% Let's do it in one command. #1 is the env name, #2 the definition. +\def\makedispenvdef#1#2{% + \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}% + \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}% + \expandafter\let\csname E#1\endcsname \afterenvbreak + \expandafter\let\csname Esmall#1\endcsname \afterenvbreak +} + +% Define two environment synonyms (#1 and #2) for an environment. +\def\maketwodispenvdef#1#2#3{% + \makedispenvdef{#1}{#3}% + \makedispenvdef{#2}{#3}% +} +% +% @lisp: indented, narrowed, typewriter font; +% @example: same as @lisp. +% +% @smallexample and @smalllisp: use smaller fonts. +% Originally contributed by Pavel@xerox. +% +\maketwodispenvdef{lisp}{example}{% + \nonfillstart + \tt\setupmarkupstyle{example}% + \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. + \gobble % eat return +} +% @display/@smalldisplay: same as @lisp except keep current font. +% +\makedispenvdef{display}{% + \nonfillstart + \gobble +} + +% @format/@smallformat: same as @display except don't narrow margins. +% +\makedispenvdef{format}{% + \let\nonarrowing = t% + \nonfillstart + \gobble +} + +% @flushleft: same as @format, but doesn't obey \SETdispenvsize. +\envdef\flushleft{% + \let\nonarrowing = t% + \nonfillstart + \gobble +} +\let\Eflushleft = \afterenvbreak + +% @flushright. +% +\envdef\flushright{% + \let\nonarrowing = t% + \nonfillstart + \advance\leftskip by 0pt plus 1fill\relax + \gobble +} +\let\Eflushright = \afterenvbreak + + +% @raggedright does more-or-less normal line breaking but no right +% justification. From plain.tex. Don't stretch around special +% characters in urls in this environment, since the stretch at the right +% should be enough. +\envdef\raggedright{% + \rightskip0pt plus2.4em \spaceskip.3333em \xspaceskip.5em\relax + \def\urefprestretchamount{0pt}% + \def\urefpoststretchamount{0pt}% +} +\let\Eraggedright\par + +\envdef\raggedleft{% + \parindent=0pt \leftskip0pt plus2em + \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt + \hbadness=10000 % Last line will usually be underfull, so turn off + % badness reporting. +} +\let\Eraggedleft\par + +\envdef\raggedcenter{% + \parindent=0pt \rightskip0pt plus1em \leftskip0pt plus1em + \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt + \hbadness=10000 % Last line will usually be underfull, so turn off + % badness reporting. +} +\let\Eraggedcenter\par + + +% @quotation does normal linebreaking (hence we can't use \nonfillstart) +% and narrows the margins. We keep \parskip nonzero in general, since +% we're doing normal filling. So, when using \aboveenvbreak and +% \afterenvbreak, temporarily make \parskip 0. +% +\makedispenvdef{quotation}{\quotationstart} +% +\def\quotationstart{% + \indentedblockstart % same as \indentedblock, but increase right margin too. + \ifx\nonarrowing\relax + \advance\rightskip by \lispnarrowing + \fi + \parsearg\quotationlabel +} + +% We have retained a nonzero parskip for the environment, since we're +% doing normal filling. +% +\def\Equotation{% + \par + \ifx\quotationauthor\thisisundefined\else + % indent a bit. + \leftline{\kern 2\leftskip \sl ---\quotationauthor}% + \fi + {\parskip=0pt \afterenvbreak}% +} +\def\Esmallquotation{\Equotation} + +% If we're given an argument, typeset it in bold with a colon after. +\def\quotationlabel#1{% + \def\temp{#1}% + \ifx\temp\empty \else + {\bf #1: }% + \fi +} + +% @indentedblock is like @quotation, but indents only on the left and +% has no optional argument. +% +\makedispenvdef{indentedblock}{\indentedblockstart} +% +\def\indentedblockstart{% + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \parindent=0pt + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \exdentamount = \lispnarrowing + \else + \let\nonarrowing = \relax + \fi +} + +% Keep a nonzero parskip for the environment, since we're doing normal filling. +% +\def\Eindentedblock{% + \par + {\parskip=0pt \afterenvbreak}% +} +\def\Esmallindentedblock{\Eindentedblock} + + +% LaTeX-like @verbatim...@end verbatim and @verb{...} +% If we want to allow any as delimiter, +% we need the curly braces so that makeinfo sees the @verb command, eg: +% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org +% +% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook. +% +% [Knuth] p.344; only we need to do the other characters Texinfo sets +% active too. Otherwise, they get lost as the first character on a +% verbatim line. +\def\dospecials{% + \do\ \do\\\do\{\do\}\do\$\do\&% + \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~% + \do\<\do\>\do\|\do\@\do+\do\"% + % Don't do the quotes -- if we do, @set txicodequoteundirected and + % @set txicodequotebacktick will not have effect on @verb and + % @verbatim, and ?` and !` ligatures won't get disabled. + %\do\`\do\'% +} +% +% [Knuth] p. 380 +\def\uncatcodespecials{% + \def\do##1{\catcode`##1=\other}\dospecials} +% +% Setup for the @verb command. +% +% Eight spaces for a tab +\begingroup + \catcode`\^^I=\active + \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }} +\endgroup +% +\def\setupverb{% + \tt % easiest (and conventionally used) font for verbatim + \def\par{\leavevmode\endgraf}% + \setupmarkupstyle{verb}% + \tabeightspaces + % Respect line breaks, + % print special symbols as themselves, and + % make each space count + % must do in this order: + \obeylines \uncatcodespecials \sepspaces +} + +% Setup for the @verbatim environment +% +% Real tab expansion. +\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount +% +% We typeset each line of the verbatim in an \hbox, so we can handle +% tabs. The \global is in case the verbatim line starts with an accent, +% or some other command that starts with a begin-group. Otherwise, the +% entire \verbbox would disappear at the corresponding end-group, before +% it is typeset. Meanwhile, we can't have nested verbatim commands +% (can we?), so the \global won't be overwriting itself. +\newbox\verbbox +\def\starttabbox{\global\setbox\verbbox=\hbox\bgroup} +% +\begingroup + \catcode`\^^I=\active + \gdef\tabexpand{% + \catcode`\^^I=\active + \def^^I{\leavevmode\egroup + \dimen\verbbox=\wd\verbbox % the width so far, or since the previous tab + \divide\dimen\verbbox by\tabw + \multiply\dimen\verbbox by\tabw % compute previous multiple of \tabw + \advance\dimen\verbbox by\tabw % advance to next multiple of \tabw + \wd\verbbox=\dimen\verbbox \box\verbbox \starttabbox + }% + } +\endgroup + +% start the verbatim environment. +\def\setupverbatim{% + \let\nonarrowing = t% + \nonfillstart + \tt % easiest (and conventionally used) font for verbatim + % The \leavevmode here is for blank lines. Otherwise, we would + % never \starttabox and the \egroup would end verbatim mode. + \def\par{\leavevmode\egroup\box\verbbox\endgraf}% + \tabexpand + \setupmarkupstyle{verbatim}% + % Respect line breaks, + % print special symbols as themselves, and + % make each space count. + % Must do in this order: + \obeylines \uncatcodespecials \sepspaces + \everypar{\starttabbox}% +} + +% Do the @verb magic: verbatim text is quoted by unique +% delimiter characters. Before first delimiter expect a +% right brace, after last delimiter expect closing brace: +% +% \def\doverb'{'#1'}'{#1} +% +% [Knuth] p. 382; only eat outer {} +\begingroup + \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other + \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next] +\endgroup +% +\def\verb{\begingroup\setupverb\doverb} +% +% +% Do the @verbatim magic: define the macro \doverbatim so that +% the (first) argument ends when '@end verbatim' is reached, ie: +% +% \def\doverbatim#1@end verbatim{#1} +% +% For Texinfo it's a lot easier than for LaTeX, +% because texinfo's \verbatim doesn't stop at '\end{verbatim}': +% we need not redefine '\', '{' and '}'. +% +% Inspired by LaTeX's verbatim command set [latex.ltx] +% +\begingroup + \catcode`\ =\active + \obeylines % + % ignore everything up to the first ^^M, that's the newline at the end + % of the @verbatim input line itself. Otherwise we get an extra blank + % line in the output. + \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}% + % We really want {...\end verbatim} in the body of the macro, but + % without the active space; thus we have to use \xdef and \gobble. +\endgroup +% +\envdef\verbatim{% + \setupverbatim\doverbatim +} +\let\Everbatim = \afterenvbreak + + +% @verbatiminclude FILE - insert text of file in verbatim environment. +% +\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude} +% +\def\doverbatiminclude#1{% + {% + \makevalueexpandable + \setupverbatim + \indexnofonts % Allow `@@' and other weird things in file names. + \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}% + \input #1 + \afterenvbreak + }% +} + +% @copying ... @end copying. +% Save the text away for @insertcopying later. +% +% We save the uninterpreted tokens, rather than creating a box. +% Saving the text in a box would be much easier, but then all the +% typesetting commands (@smallbook, font changes, etc.) have to be done +% beforehand -- and a) we want @copying to be done first in the source +% file; b) letting users define the frontmatter in as flexible order as +% possible is desirable. +% +\def\copying{\checkenv{}\begingroup\scanargctxt\docopying} +\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}} +% +\def\insertcopying{% + \begingroup + \parindent = 0pt % paragraph indentation looks wrong on title page + \scanexp\copyingtext + \endgroup +} + + +\message{defuns,} +% @defun etc. + +\newskip\defbodyindent \defbodyindent=.4in +\newskip\defargsindent \defargsindent=50pt +\newskip\deflastargmargin \deflastargmargin=18pt +\newcount\defunpenalty + +% Start the processing of @deffn: +\def\startdefun{% + \ifnum\lastpenalty<10000 + \medbreak + \defunpenalty=10003 % Will keep this @deffn together with the + % following @def command, see below. + \else + % If there are two @def commands in a row, we'll have a \nobreak, + % which is there to keep the function description together with its + % header. But if there's nothing but headers, we need to allow a + % break somewhere. Check specifically for penalty 10002, inserted + % by \printdefunline, instead of 10000, since the sectioning + % commands also insert a nobreak penalty, and we don't want to allow + % a break between a section heading and a defun. + % + % As a further refinement, we avoid "club" headers by signalling + % with penalty of 10003 after the very first @deffn in the + % sequence (see above), and penalty of 10002 after any following + % @def command. + \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi + % + % Similarly, after a section heading, do not allow a break. + % But do insert the glue. + \medskip % preceded by discardable penalty, so not a breakpoint + \fi + % + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent +} + +\def\dodefunx#1{% + % First, check whether we are in the right environment: + \checkenv#1% + % + % As above, allow line break if we have multiple x headers in a row. + % It's not a great place, though. + \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi + % + % And now, it's time to reuse the body of the original defun: + \expandafter\gobbledefun#1% +} +\def\gobbledefun#1\startdefun{} + +% \printdefunline \deffnheader{text} +% +\def\printdefunline#1#2{% + \begingroup + % call \deffnheader: + #1#2 \endheader + % common ending: + \interlinepenalty = 10000 + \advance\rightskip by 0pt plus 1fil\relax + \endgraf + \nobreak\vskip -\parskip + \penalty\defunpenalty % signal to \startdefun and \dodefunx + % Some of the @defun-type tags do not enable magic parentheses, + % rendering the following check redundant. But we don't optimize. + \checkparencounts + \endgroup +} + +\def\Edefun{\endgraf\medbreak} + +% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn; +% the only thing remaining is to define \deffnheader. +% +\def\makedefun#1{% + \expandafter\let\csname E#1\endcsname = \Edefun + \edef\temp{\noexpand\domakedefun + \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}% + \temp +} + +% \domakedefun \deffn \deffnx \deffnheader { (defn. of \deffnheader) } +% +% Define \deffn and \deffnx, without parameters. +% \deffnheader has to be defined explicitly. +% +\def\domakedefun#1#2#3{% + \envdef#1{% + \startdefun + \doingtypefnfalse % distinguish typed functions from all else + \parseargusing\activeparens{\printdefunline#3}% + }% + \def#2{\dodefunx#1}% + \def#3% +} + +\newif\ifdoingtypefn % doing typed function? +\newif\ifrettypeownline % typeset return type on its own line? + +% @deftypefnnewline on|off says whether the return type of typed functions +% are printed on their own line. This affects @deftypefn, @deftypefun, +% @deftypeop, and @deftypemethod. +% +\parseargdef\deftypefnnewline{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxideftypefnnl\endcsname + = \empty + \else\ifx\temp\offword + \expandafter\let\csname SETtxideftypefnnl\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @txideftypefnnl value `\temp', + must be on|off}% + \fi\fi +} + +% Untyped functions: + +% @deffn category name args +\makedefun{deffn}{\deffngeneral{}} + +% @deffn category class name args +\makedefun{defop}#1 {\defopon{#1\ \putwordon}} + +% \defopon {category on}class name args +\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } + +% \deffngeneral {subind}category name args +% +\def\deffngeneral#1#2 #3 #4\endheader{% + % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}. + \dosubind{fn}{\code{#3}}{#1}% + \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}% +} + +% Typed functions: + +% @deftypefn category type name args +\makedefun{deftypefn}{\deftypefngeneral{}} + +% @deftypeop category class type name args +\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}} + +% \deftypeopon {category on}class type name args +\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } + +% \deftypefngeneral {subind}category type name args +% +\def\deftypefngeneral#1#2 #3 #4 #5\endheader{% + \dosubind{fn}{\code{#4}}{#1}% + \doingtypefntrue + \defname{#2}{#3}{#4}\defunargs{#5\unskip}% +} + +% Typed variables: + +% @deftypevr category type var args +\makedefun{deftypevr}{\deftypecvgeneral{}} + +% @deftypecv category class type var args +\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}} + +% \deftypecvof {category of}class type var args +\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} } + +% \deftypecvgeneral {subind}category type var args +% +\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{% + \dosubind{vr}{\code{#4}}{#1}% + \defname{#2}{#3}{#4}\defunargs{#5\unskip}% +} + +% Untyped variables: + +% @defvr category var args +\makedefun{defvr}#1 {\deftypevrheader{#1} {} } + +% @defcv category class var args +\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}} + +% \defcvof {category of}class var args +\def\defcvof#1#2 {\deftypecvof{#1}#2 {} } + +% Types: + +% @deftp category name args +\makedefun{deftp}#1 #2 #3\endheader{% + \doind{tp}{\code{#2}}% + \defname{#1}{}{#2}\defunargs{#3\unskip}% +} + +% Remaining @defun-like shortcuts: +\makedefun{defun}{\deffnheader{\putwordDeffunc} } +\makedefun{defmac}{\deffnheader{\putwordDefmac} } +\makedefun{defspec}{\deffnheader{\putwordDefspec} } +\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} } +\makedefun{defvar}{\defvrheader{\putwordDefvar} } +\makedefun{defopt}{\defvrheader{\putwordDefopt} } +\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} } +\makedefun{defmethod}{\defopon\putwordMethodon} +\makedefun{deftypemethod}{\deftypeopon\putwordMethodon} +\makedefun{defivar}{\defcvof\putwordInstanceVariableof} +\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof} + +% \defname, which formats the name of the @def (not the args). +% #1 is the category, such as "Function". +% #2 is the return type, if any. +% #3 is the function name. +% +% We are followed by (but not passed) the arguments, if any. +% +\def\defname#1#2#3{% + \par + % Get the values of \leftskip and \rightskip as they were outside the @def... + \advance\leftskip by -\defbodyindent + % + % Determine if we are typesetting the return type of a typed function + % on a line by itself. + \rettypeownlinefalse + \ifdoingtypefn % doing a typed function specifically? + % then check user option for putting return type on its own line: + \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else + \rettypeownlinetrue + \fi + \fi + % + % How we'll format the category name. Putting it in brackets helps + % distinguish it from the body text that may end up on the next line + % just below it. + \def\temp{#1}% + \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi} + % + % Figure out line sizes for the paragraph shape. We'll always have at + % least two. + \tempnum = 2 + % + % The first line needs space for \box0; but if \rightskip is nonzero, + % we need only space for the part of \box0 which exceeds it: + \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip + % + % If doing a return type on its own line, we'll have another line. + \ifrettypeownline + \advance\tempnum by 1 + \def\maybeshapeline{0in \hsize}% + \else + \def\maybeshapeline{}% + \fi + % + % The continuations: + \dimen2=\hsize \advance\dimen2 by -\defargsindent + % + % The final paragraph shape: + \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2 + % + % Put the category name at the right margin. + \noindent + \hbox to 0pt{% + \hfil\box0 \kern-\hsize + % \hsize has to be shortened this way: + \kern\leftskip + % Intentionally do not respect \rightskip, since we need the space. + }% + % + % Allow all lines to be underfull without complaint: + \tolerance=10000 \hbadness=10000 + \exdentamount=\defbodyindent + {% + % defun fonts. We use typewriter by default (used to be bold) because: + % . we're printing identifiers, they should be in tt in principle. + % . in languages with many accents, such as Czech or French, it's + % common to leave accents off identifiers. The result looks ok in + % tt, but exceedingly strange in rm. + % . we don't want -- and --- to be treated as ligatures. + % . this still does not fix the ?` and !` ligatures, but so far no + % one has made identifiers using them :). + \df \tt + \def\temp{#2}% text of the return type + \ifx\temp\empty\else + \tclose{\temp}% typeset the return type + \ifrettypeownline + % put return type on its own line; prohibit line break following: + \hfil\vadjust{\nobreak}\break + \else + \space % type on same line, so just followed by a space + \fi + \fi % no return type + #3% output function name + }% + {\rm\enskip}% hskip 0.5 em of \rmfont + % + \boldbrax + % arguments will be output next, if any. +} + +% Print arguments in slanted roman (not ttsl), inconsistently with using +% tt for the name. This is because literal text is sometimes needed in +% the argument list (groff manual), and ttsl and tt are not very +% distinguishable. Prevent hyphenation at `-' chars. +% +\def\defunargs#1{% + % use sl by default (not ttsl), + % tt for the names. + \df \sl \hyphenchar\font=0 + % + % On the other hand, if an argument has two dashes (for instance), we + % want a way to get ttsl. We used to recommend @var for that, so + % leave the code in, but it's strange for @var to lead to typewriter. + % Nowadays we recommend @code, since the difference between a ttsl hyphen + % and a tt hyphen is pretty tiny. @code also disables ?` !`. + \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}% + #1% + \sl\hyphenchar\font=45 +} + +% We want ()&[] to print specially on the defun line. +% +\def\activeparens{% + \catcode`\(=\active \catcode`\)=\active + \catcode`\[=\active \catcode`\]=\active + \catcode`\&=\active +} + +% Make control sequences which act like normal parenthesis chars. +\let\lparen = ( \let\rparen = ) + +% Be sure that we always have a definition for `(', etc. For example, +% if the fn name has parens in it, \boldbrax will not be in effect yet, +% so TeX would otherwise complain about undefined control sequence. +{ + \activeparens + \global\let(=\lparen \global\let)=\rparen + \global\let[=\lbrack \global\let]=\rbrack + \global\let& = \& + + \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} + \gdef\magicamp{\let&=\amprm} +} + +\newcount\parencount + +% If we encounter &foo, then turn on ()-hacking afterwards +\newif\ifampseen +\def\amprm#1 {\ampseentrue{\bf\ }} + +\def\parenfont{% + \ifampseen + % At the first level, print parens in roman, + % otherwise use the default font. + \ifnum \parencount=1 \rm \fi + \else + % The \sf parens (in \boldbrax) actually are a little bolder than + % the contained text. This is especially needed for [ and ] . + \sf + \fi +} +\def\infirstlevel#1{% + \ifampseen + \ifnum\parencount=1 + #1% + \fi + \fi +} +\def\bfafterword#1 {#1 \bf} + +\def\opnr{% + \global\advance\parencount by 1 + {\parenfont(}% + \infirstlevel \bfafterword +} +\def\clnr{% + {\parenfont)}% + \infirstlevel \sl + \global\advance\parencount by -1 +} + +\newcount\brackcount +\def\lbrb{% + \global\advance\brackcount by 1 + {\bf[}% +} +\def\rbrb{% + {\bf]}% + \global\advance\brackcount by -1 +} + +\def\checkparencounts{% + \ifnum\parencount=0 \else \badparencount \fi + \ifnum\brackcount=0 \else \badbrackcount \fi +} +% these should not use \errmessage; the glibc manual, at least, actually +% has such constructs (when documenting function pointers). +\def\badparencount{% + \message{Warning: unbalanced parentheses in @def...}% + \global\parencount=0 +} +\def\badbrackcount{% + \message{Warning: unbalanced square brackets in @def...}% + \global\brackcount=0 +} + + +\message{macros,} +% @macro. + +% To do this right we need a feature of e-TeX, \scantokens, +% which we arrange to emulate with a temporary file in ordinary TeX. +\ifx\eTeXversion\thisisundefined + \newwrite\macscribble + \def\scantokens#1{% + \toks0={#1}% + \immediate\openout\macscribble=\jobname.tmp + \immediate\write\macscribble{\the\toks0}% + \immediate\closeout\macscribble + \input \jobname.tmp + } +\fi + +% alias because \c means cedilla in @tex or @math +\let\texinfoc=\c + +\newcount\savedcatcodeone +\newcount\savedcatcodetwo + +% Used at the time of macro expansion. +% Argument is macro body with arguments substituted +\def\scanmacro#1{% + \newlinechar`\^^M + \def\xeatspaces{\eatspaces}% + % + % Temporarily undo catcode changes of \printindex. Set catcode of @ to + % 0 so that @-commands in macro expansions aren't printed literally when + % formatting an index file, where \ is used as the escape character. + \savedcatcodeone=\catcode`\@ + \savedcatcodetwo=\catcode`\\ + \catcode`\@=0 + \catcode`\\=\active + % + % Process the macro body under the current catcode regime. + \scantokens{#1@texinfoc}% + % + \catcode`\@=\savedcatcodeone + \catcode`\\=\savedcatcodetwo + % + % The \texinfoc is to remove the \newlinechar added by \scantokens, and + % can be noticed by \parsearg. + % We avoid surrounding the call to \scantokens with \bgroup and \egroup + % to allow macros to open or close groups themselves. +} + +% Used for copying and captions +\def\scanexp#1{% + \expandafter\scanmacro\expandafter{#1}% +} + +\newcount\paramno % Count of parameters +\newtoks\macname % Macro name +\newif\ifrecursive % Is it recursive? + +% List of all defined macros in the form +% \commondummyword\macro1\commondummyword\macro2... +% Currently is also contains all @aliases; the list can be split +% if there is a need. +\def\macrolist{} + +% Add the macro to \macrolist +\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname} +\def\addtomacrolistxxx#1{% + \toks0 = \expandafter{\macrolist\commondummyword#1}% + \xdef\macrolist{\the\toks0}% +} + +% Utility routines. +% This does \let #1 = #2, with \csnames; that is, +% \let \csname#1\endcsname = \csname#2\endcsname +% (except of course we have to play expansion games). +% +\def\cslet#1#2{% + \expandafter\let + \csname#1\expandafter\endcsname + \csname#2\endcsname +} + +% Trim leading and trailing spaces off a string. +% Concepts from aro-bend problem 15 (see CTAN). +{\catcode`\@=11 +\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} +\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} +\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} +\def\unbrace#1{#1} +\unbrace{\gdef\trim@@@ #1 } #2@{#1} +} + +% Trim a single trailing ^^M off a string. +{\catcode`\^^M=\other \catcode`\Q=3% +\gdef\eatcr #1{\eatcra #1Q^^MQ}% +\gdef\eatcra#1^^MQ{\eatcrb#1Q}% +\gdef\eatcrb#1Q#2Q{#1}% +} + +% Macro bodies are absorbed as an argument in a context where +% all characters are catcode 10, 11 or 12, except \ which is active +% (as in normal texinfo). It is necessary to change the definition of \ +% to recognize macro arguments; this is the job of \mbodybackslash. +% +% Non-ASCII encodings make 8-bit characters active, so un-activate +% them to avoid their expansion. Must do this non-globally, to +% confine the change to the current group. +% +% It's necessary to have hard CRs when the macro is executed. This is +% done by making ^^M (\endlinechar) catcode 12 when reading the macro +% body, and then making it the \newlinechar in \scanmacro. +% +\def\scanctxt{% used as subroutine + \catcode`\"=\other + \catcode`\+=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\^=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\~=\other + \passthroughcharstrue +} + +\def\scanargctxt{% used for copying and captions, not macros. + \scanctxt + \catcode`\@=\other + \catcode`\\=\other + \catcode`\^^M=\other +} + +\def\macrobodyctxt{% used for @macro definitions + \scanctxt + \catcode`\ =\other + \catcode`\@=\other + \catcode`\{=\other + \catcode`\}=\other + \catcode`\^^M=\other + \usembodybackslash +} + +% Used when scanning braced macro arguments. Note, however, that catcode +% changes here are ineffectual if the macro invocation was nested inside +% an argument to another Texinfo command. +\def\macroargctxt{% + \scanctxt + \catcode`\ =\active + \catcode`\^^M=\other + \catcode`\\=\active +} + +\def\macrolineargctxt{% used for whole-line arguments without braces + \scanctxt + \catcode`\{=\other + \catcode`\}=\other +} + +% \mbodybackslash is the definition of \ in @macro bodies. +% It maps \foo\ => \csname macarg.foo\endcsname => #N +% where N is the macro parameter number. +% We define \csname macarg.\endcsname to be \realbackslash, so +% \\ in macro replacement text gets you a backslash. +% +{\catcode`@=0 @catcode`@\=@active + @gdef@usembodybackslash{@let\=@mbodybackslash} + @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} +} +\expandafter\def\csname macarg.\endcsname{\realbackslash} + +\def\margbackslash#1{\char`\#1 } + +\def\macro{\recursivefalse\parsearg\macroxxx} +\def\rmacro{\recursivetrue\parsearg\macroxxx} + +\def\macroxxx#1{% + \getargs{#1}% now \macname is the macname and \argl the arglist + \ifx\argl\empty % no arguments + \paramno=0\relax + \else + \expandafter\parsemargdef \argl;% + \if\paramno>256\relax + \ifx\eTeXversion\thisisundefined + \errhelp = \EMsimple + \errmessage{You need eTeX to compile a file with macros with more than 256 arguments} + \fi + \fi + \fi + \if1\csname ismacro.\the\macname\endcsname + \message{Warning: redefining \the\macname}% + \else + \expandafter\ifx\csname \the\macname\endcsname \relax + \else \errmessage{Macro name \the\macname\space already defined}\fi + \global\cslet{macsave.\the\macname}{\the\macname}% + \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% + \addtomacrolist{\the\macname}% + \fi + \begingroup \macrobodyctxt + \ifrecursive \expandafter\parsermacbody + \else \expandafter\parsemacbody + \fi} + +\parseargdef\unmacro{% + \if1\csname ismacro.#1\endcsname + \global\cslet{#1}{macsave.#1}% + \global\expandafter\let \csname ismacro.#1\endcsname=0% + % Remove the macro name from \macrolist: + \begingroup + \expandafter\let\csname#1\endcsname \relax + \let\commondummyword\unmacrodo + \xdef\macrolist{\macrolist}% + \endgroup + \else + \errmessage{Macro #1 not defined}% + \fi +} + +% Called by \do from \dounmacro on each macro. The idea is to omit any +% macro definitions that have been changed to \relax. +% +\def\unmacrodo#1{% + \ifx #1\relax + % remove this + \else + \noexpand\commondummyword \noexpand#1% + \fi +} + +% \getargs -- Parse the arguments to a @macro line. Set \macname to +% the name of the macro, and \argl to the braced argument list. +\def\getargs#1{\getargsxxx#1{}} +\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} +\def\getmacname#1 #2\relax{\macname={#1}} +\def\getmacargs#1{\def\argl{#1}} +% This made use of the feature that if the last token of a +% is #, then the preceding argument is delimited by +% an opening brace, and that opening brace is not consumed. + +% Parse the optional {params} list to @macro or @rmacro. +% Set \paramno to the number of arguments, +% and \paramlist to a parameter text for the macro (e.g. #1,#2,#3 for a +% three-param macro.) Define \macarg.BLAH for each BLAH in the params +% list to some hook where the argument is to be expanded. If there are +% less than 10 arguments that hook is to be replaced by ##N where N +% is the position in that list, that is to say the macro arguments are to be +% defined `a la TeX in the macro body. +% +% That gets used by \mbodybackslash (above). +% +% If there are 10 or more arguments, a different technique is used: see +% \parsemmanyargdef. +% +\def\parsemargdef#1;{% + \paramno=0\def\paramlist{}% + \let\hash\relax + % \hash is redefined to `#' later to get it into definitions + \let\xeatspaces\relax + \parsemargdefxxx#1,;,% + \ifnum\paramno<10\relax\else + \paramno0\relax + \parsemmanyargdef@@#1,;,% 10 or more arguments + \fi +} +\def\parsemargdefxxx#1,{% + \if#1;\let\next=\relax + \else \let\next=\parsemargdefxxx + \advance\paramno by 1 + \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname + {\xeatspaces{\hash\the\paramno}}% + \edef\paramlist{\paramlist\hash\the\paramno,}% + \fi\next} + +% \parsemacbody, \parsermacbody +% +% Read recursive and nonrecursive macro bodies. (They're different since +% rec and nonrec macros end differently.) +% +% We are in \macrobodyctxt, and the \xdef causes backslashshes in the macro +% body to be transformed. +% Set \macrobody to the body of the macro, and call \defmacro. +% +{\catcode`\ =\other\long\gdef\parsemacbody#1@end macro{% +\xdef\macrobody{\eatcr{#1}}\endgroup\defmacro}}% +{\catcode`\ =\other\long\gdef\parsermacbody#1@end rmacro{% +\xdef\macrobody{\eatcr{#1}}\endgroup\defmacro}}% + +% Make @ a letter, so that we can make private-to-Texinfo macro names. +\edef\texiatcatcode{\the\catcode`\@} +\catcode `@=11\relax + +%%%%%%%%%%%%%% Code for > 10 arguments only %%%%%%%%%%%%%%%%%% + +% If there are 10 or more arguments, a different technique is used, where the +% hook remains in the body, and when macro is to be expanded the body is +% processed again to replace the arguments. +% +% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the +% argument N value and then \edef the body (nothing else will expand because of +% the catcode regime under which the body was input). +% +% If you compile with TeX (not eTeX), and you have macros with 10 or more +% arguments, no macro can have more than 256 arguments (else error). +% +% In case that there are 10 or more arguments we parse again the arguments +% list to set new definitions for the \macarg.BLAH macros corresponding to +% each BLAH argument. It was anyhow needed to parse already once this list +% in order to count the arguments, and as macros with at most 9 arguments +% are by far more frequent than macro with 10 or more arguments, defining +% twice the \macarg.BLAH macros does not cost too much processing power. +\def\parsemmanyargdef@@#1,{% + \if#1;\let\next=\relax + \else + \let\next=\parsemmanyargdef@@ + \edef\tempb{\eatspaces{#1}}% + \expandafter\def\expandafter\tempa + \expandafter{\csname macarg.\tempb\endcsname}% + % Note that we need some extra \noexpand\noexpand, this is because we + % don't want \the to be expanded in the \parsermacbody as it uses an + % \xdef . + \expandafter\edef\tempa + {\noexpand\noexpand\noexpand\the\toks\the\paramno}% + \advance\paramno by 1\relax + \fi\next} + + +\let\endargs@\relax +\let\nil@\relax +\def\nilm@{\nil@}% +\long\def\nillm@{\nil@}% + +% This macro is expanded during the Texinfo macro expansion, not during its +% definition. It gets all the arguments' values and assigns them to macros +% macarg.ARGNAME +% +% #1 is the macro name +% #2 is the list of argument names +% #3 is the list of argument values +\def\getargvals@#1#2#3{% + \def\macargdeflist@{}% + \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion. + \def\paramlist{#2,\nil@}% + \def\macroname{#1}% + \begingroup + \macroargctxt + \def\argvaluelist{#3,\nil@}% + \def\@tempa{#3}% + \ifx\@tempa\empty + \setemptyargvalues@ + \else + \getargvals@@ + \fi +} +\def\getargvals@@{% + \ifx\paramlist\nilm@ + % Some sanity check needed here that \argvaluelist is also empty. + \ifx\argvaluelist\nillm@ + \else + \errhelp = \EMsimple + \errmessage{Too many arguments in macro `\macroname'!}% + \fi + \let\next\macargexpandinbody@ + \else + \ifx\argvaluelist\nillm@ + % No more arguments values passed to macro. Set remaining named-arg + % macros to empty. + \let\next\setemptyargvalues@ + \else + % pop current arg name into \@tempb + \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}% + \expandafter\@tempa\expandafter{\paramlist}% + % pop current argument value into \@tempc + \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}% + \expandafter\@tempa\expandafter{\argvaluelist}% + % Here \@tempb is the current arg name and \@tempc is the current arg value. + % First place the new argument macro definition into \@tempd + \expandafter\macname\expandafter{\@tempc}% + \expandafter\let\csname macarg.\@tempb\endcsname\relax + \expandafter\def\expandafter\@tempe\expandafter{% + \csname macarg.\@tempb\endcsname}% + \edef\@tempd{\long\def\@tempe{\the\macname}}% + \push@\@tempd\macargdeflist@ + \let\next\getargvals@@ + \fi + \fi + \next +} + +\def\push@#1#2{% + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter#2% + \expandafter\expandafter\expandafter{% + \expandafter#1#2}% +} + +% Replace arguments by their values in the macro body, and place the result +% in macro \@tempa. +% +\def\macvalstoargs@{% + % To do this we use the property that token registers that are \the'ed + % within an \edef expand only once. So we are going to place all argument + % values into respective token registers. + % + % First we save the token context, and initialize argument numbering. + \begingroup + \paramno0\relax + % Then, for each argument number #N, we place the corresponding argument + % value into a new token list register \toks#N + \expandafter\putargsintokens@\saveparamlist@,;,% + % Then, we expand the body so that argument are replaced by their + % values. The trick for values not to be expanded themselves is that they + % are within tokens and that tokens expand only once in an \edef . + \edef\@tempc{\csname mac.\macroname .body\endcsname}% + % Now we restore the token stack pointer to free the token list registers + % which we have used, but we make sure that expanded body is saved after + % group. + \expandafter + \endgroup + \expandafter\def\expandafter\@tempa\expandafter{\@tempc}% + } + +% Define the named-macro outside of this group and then close this group. +% +\def\macargexpandinbody@{% + \expandafter + \endgroup + \macargdeflist@ + % First the replace in body the macro arguments by their values, the result + % is in \@tempa . + \macvalstoargs@ + % Then we point at the \norecurse or \gobble (for recursive) macro value + % with \@tempb . + \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname + % Depending on whether it is recursive or not, we need some tailing + % \egroup . + \ifx\@tempb\gobble + \let\@tempc\relax + \else + \let\@tempc\egroup + \fi + % And now we do the real job: + \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}% + \@tempd +} + +\def\putargsintokens@#1,{% + \if#1;\let\next\relax + \else + \let\next\putargsintokens@ + % First we allocate the new token list register, and give it a temporary + % alias \@tempb . + \toksdef\@tempb\the\paramno + % Then we place the argument value into that token list register. + \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname + \expandafter\@tempb\expandafter{\@tempa}% + \advance\paramno by 1\relax + \fi + \next +} + +% Trailing missing arguments are set to empty. +% +\def\setemptyargvalues@{% + \ifx\paramlist\nilm@ + \let\next\macargexpandinbody@ + \else + \expandafter\setemptyargvaluesparser@\paramlist\endargs@ + \let\next\setemptyargvalues@ + \fi + \next +} + +\def\setemptyargvaluesparser@#1,#2\endargs@{% + \expandafter\def\expandafter\@tempa\expandafter{% + \expandafter\def\csname macarg.#1\endcsname{}}% + \push@\@tempa\macargdeflist@ + \def\paramlist{#2}% +} + +% #1 is the element target macro +% #2 is the list macro +% #3,#4\endargs@ is the list value +\def\pop@#1#2#3,#4\endargs@{% + \def#1{#3}% + \def#2{#4}% +} +\long\def\longpop@#1#2#3,#4\endargs@{% + \long\def#1{#3}% + \long\def#2{#4}% +} + + +%%%%%%%%%%%%%% End of code for > 10 arguments %%%%%%%%%%%%%%%%%% + + +% This defines a Texinfo @macro or @rmacro, called by \parsemacbody. +% \macrobody has the body of the macro in it, with placeholders for +% its parameters, looking like "\xeatspaces{\hash 1}". +% \paramno is the number of parameters +% \paramlist is a TeX parameter text, e.g. "#1,#2,#3," +% There are four cases: macros of zero, one, up to nine, and many arguments. +% \xdef is used so that macro definitions will survive the file +% they're defined in: @include reads the file inside a group. +% +\def\defmacro{% + \let\hash=##% convert placeholders to macro parameter chars + \ifnum\paramno=1 + \def\xeatspaces##1{##1}% + % This removes the pair of braces around the argument. We don't + % use \eatspaces, because this can cause ends of lines to be lost + % when the argument to \eatspaces is read, leading to line-based + % commands like "@itemize" not being read correctly. + \else + \let\xeatspaces\relax % suppress expansion + \fi + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup + \noexpand\spaceisspace + \noexpand\endlineisspace + \noexpand\expandafter % skip any whitespace after the macro name. + \expandafter\noexpand\csname\the\macname @@@\endcsname}% + \expandafter\xdef\csname\the\macname @@@\endcsname{% + \egroup + \noexpand\scanmacro{\macrobody}}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname @@@\endcsname}% + \expandafter\xdef\csname\the\macname @@@\endcsname##1{% + \egroup + \noexpand\scanmacro{\macrobody}% + }% + \else % at most 9 + \ifnum\paramno<10\relax + % @MACNAME sets the context for reading the macro argument + % @MACNAME@@ gets the argument, processes backslashes and appends a + % comma. + % @MACNAME@@@ removes braces surrounding the argument list. + % @MACNAME@@@@ scans the macro body with arguments substituted. + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup + \noexpand\expandafter % This \expandafter skip any spaces after the + \noexpand\macroargctxt % macro before we change the catcode of space. + \noexpand\expandafter + \expandafter\noexpand\csname\the\macname @@\endcsname}% + \expandafter\xdef\csname\the\macname @@\endcsname##1{% + \noexpand\passargtomacro + \expandafter\noexpand\csname\the\macname @@@\endcsname{##1,}}% + \expandafter\xdef\csname\the\macname @@@\endcsname##1{% + \expandafter\noexpand\csname\the\macname @@@@\endcsname ##1}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname @@@@\endcsname\paramlist{% + \egroup\noexpand\scanmacro{\macrobody}}% + \else % 10 or more: + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\getargvals@{\the\macname}{\argl}% + }% + \global\expandafter\let\csname mac.\the\macname .body\endcsname\macrobody + \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble + \fi + \fi} + +\catcode `\@\texiatcatcode\relax % end private-to-Texinfo catcodes + +\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +{\catcode`\@=0 \catcode`\\=13 % We need to manipulate \ so use @ as escape +@catcode`@_=11 % private names +@catcode`@!=11 % used as argument separator + +% \passargtomacro#1#2 - +% Call #1 with a list of tokens #2, with any doubled backslashes in #2 +% compressed to one. +% +% This implementation works by expansion, and not execution (so we cannot use +% \def or similar). This reduces the risk of this failing in contexts where +% complete expansion is done with no execution (for example, in writing out to +% an auxiliary file for an index entry). +% +% State is kept in the input stream: the argument passed to +% @look_ahead, @gobble_and_check_finish and @add_segment is +% +% THE_MACRO ARG_RESULT ! {PENDING_BS} NEXT_TOKEN (... rest of input) +% +% where: +% THE_MACRO - name of the macro we want to call +% ARG_RESULT - argument list we build to pass to that macro +% PENDING_BS - either a backslash or nothing +% NEXT_TOKEN - used to look ahead in the input stream to see what's coming next + +@gdef@passargtomacro#1#2{% + @add_segment #1!{}@relax#2\@_finish\% +} +@gdef@_finish{@_finishx} @global@let@_finishx@relax + +% #1 - THE_MACRO ARG_RESULT +% #2 - PENDING_BS +% #3 - NEXT_TOKEN +% #4 used to look ahead +% +% If the next token is not a backslash, process the rest of the argument; +% otherwise, remove the next token. +@gdef@look_ahead#1!#2#3#4{% + @ifx#4\% + @expandafter@gobble_and_check_finish + @else + @expandafter@add_segment + @fi#1!{#2}#4#4% +} + +% #1 - THE_MACRO ARG_RESULT +% #2 - PENDING_BS +% #3 - NEXT_TOKEN +% #4 should be a backslash, which is gobbled. +% #5 looks ahead +% +% Double backslash found. Add a single backslash, and look ahead. +@gdef@gobble_and_check_finish#1!#2#3#4#5{% + @add_segment#1\!{}#5#5% +} + +@gdef@is_fi{@fi} + +% #1 - THE_MACRO ARG_RESULT +% #2 - PENDING_BS +% #3 - NEXT_TOKEN +% #4 is input stream until next backslash +% +% Input stream is either at the start of the argument, or just after a +% backslash sequence, either a lone backslash, or a doubled backslash. +% NEXT_TOKEN contains the first token in the input stream: if it is \finish, +% finish; otherwise, append to ARG_RESULT the segment of the argument up until +% the next backslash. PENDING_BACKSLASH contains a backslash to represent +% a backslash just before the start of the input stream that has not been +% added to ARG_RESULT. +@gdef@add_segment#1!#2#3#4\{% +@ifx#3@_finish + @call_the_macro#1!% +@else + % append the pending backslash to the result, followed by the next segment + @expandafter@is_fi@look_ahead#1#2#4!{\}@fi + % this @fi is discarded by @look_ahead. + % we can't get rid of it with \expandafter because we don't know how + % long #4 is. +} + +% #1 - THE_MACRO +% #2 - ARG_RESULT +% #3 discards the res of the conditional in @add_segment, and @is_fi ends the +% conditional. +@gdef@call_the_macro#1#2!#3@fi{@is_fi #1{#2}} + +} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% \braceorline MAC is used for a one-argument macro MAC. It checks +% whether the next non-whitespace character is a {. It sets the context +% for reading the argument (slightly different in the two cases). Then, +% to read the argument, in the whole-line case, it then calls the regular +% \parsearg MAC; in the lbrace case, it calls \passargtomacro MAC. +% +\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx} +\def\braceorlinexxx{% + \ifx\nchar\bgroup + \macroargctxt + \expandafter\passargtomacro + \else + \macrolineargctxt\expandafter\parsearg + \fi \macnamexxx} + + +% @alias. +% We need some trickery to remove the optional spaces around the equal +% sign. Make them active and then expand them all to nothing. +% +\def\alias{\parseargusing\obeyspaces\aliasxxx} +\def\aliasxxx #1{\aliasyyy#1\relax} +\def\aliasyyy #1=#2\relax{% + {% + \expandafter\let\obeyedspace=\empty + \addtomacrolist{#1}% + \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}% + }% + \next +} + + +\message{cross references,} + +\newwrite\auxfile +\newif\ifhavexrefs % True if xref values are known. +\newif\ifwarnedxrefs % True if we warned once that they aren't known. + +% @inforef is relatively simple. +\def\inforef #1{\inforefzzz #1,,,,**} +\def\inforefzzz #1,#2,#3,#4**{% + \putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, + node \samp{\ignorespaces#1{}}} + +% @node's only job in TeX is to define \lastnode, which is used in +% cross-references. The @node line might or might not have commas, and +% might or might not have spaces before the first comma, like: +% @node foo , bar , ... +% We don't want such trailing spaces in the node name. +% +\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse} +% +% also remove a trailing comma, in case of something like this: +% @node Help-Cross, , , Cross-refs +\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse} +\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}} + +\let\nwnode=\node +\let\lastnode=\empty + +% Write a cross-reference definition for the current node. #1 is the +% type (Ynumbered, Yappendix, Ynothing). +% +\def\donoderef#1{% + \ifx\lastnode\empty\else + \setref{\lastnode}{#1}% + \global\let\lastnode=\empty + \fi +} + +% @anchor{NAME} -- define xref target at arbitrary point. +% +\newcount\savesfregister +% +\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} +\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} +\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} + +% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an +% anchor), which consists of three parts: +% 1) NAME-title - the current sectioning name taken from \lastsection, +% or the anchor name. +% 2) NAME-snt - section number and type, passed as the SNT arg, or +% empty for anchors. +% 3) NAME-pg - the page number. +% +% This is called from \donoderef, \anchor, and \dofloat. In the case of +% floats, there is an additional part, which is not written here: +% 4) NAME-lof - the text as it should appear in a @listoffloats. +% +\def\setref#1#2{% + \pdfmkdest{#1}% + \iflinks + {% + \requireauxfile + \atdummies % preserve commands, but don't expand them + % match definition in \xrdef, \refx, \xrefX. + \def\value##1{##1}% + \edef\writexrdef##1##2{% + \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef + ##1}{##2}}% these are parameters of \writexrdef + }% + \toks0 = \expandafter{\lastsection}% + \immediate \writexrdef{title}{\the\toks0 }% + \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. + \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout + }% + \fi +} + +% @xrefautosectiontitle on|off says whether @section(ing) names are used +% automatically in xrefs, if the third arg is not explicitly specified. +% This was provided as a "secret" @set xref-automatic-section-title +% variable, now it's official. +% +\parseargdef\xrefautomaticsectiontitle{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETxref-automatic-section-title\endcsname + = \empty + \else\ifx\temp\offword + \expandafter\let\csname SETxref-automatic-section-title\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @xrefautomaticsectiontitle value `\temp', + must be on|off}% + \fi\fi +} + +% +% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is +% the node name, #2 the name of the Info cross-reference, #3 the printed +% node name, #4 the name of the Info file, #5 the name of the printed +% manual. All but the node name can be omitted. +% +\def\pxref{\putwordsee{} \xrefXX} +\def\xref{\putwordSee{} \xrefXX} +\def\ref{\xrefXX} + +\def\xrefXX#1{\def\xrefXXarg{#1}\futurelet\tokenafterxref\xrefXXX} +\def\xrefXXX{\expandafter\xrefX\expandafter[\xrefXXarg,,,,,,,]} +% +\newbox\toprefbox +\newbox\printedrefnamebox +\newbox\infofilenamebox +\newbox\printedmanualbox +% +\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup + \unsepspaces + % + % Get args without leading/trailing spaces. + \def\printedrefname{\ignorespaces #3}% + \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}% + % + \def\infofilename{\ignorespaces #4}% + \setbox\infofilenamebox = \hbox{\infofilename\unskip}% + % + \def\printedmanual{\ignorespaces #5}% + \setbox\printedmanualbox = \hbox{\printedmanual\unskip}% + % + % If the printed reference name (arg #3) was not explicitly given in + % the @xref, figure out what we want to use. + \ifdim \wd\printedrefnamebox = 0pt + % No printed node name was explicitly given. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax + % Not auto section-title: use node name inside the square brackets. + \def\printedrefname{\ignorespaces #1}% + \else + % Auto section-title: use chapter/section title inside + % the square brackets if we have it. + \ifdim \wd\printedmanualbox > 0pt + % It is in another manual, so we don't have it; use node name. + \def\printedrefname{\ignorespaces #1}% + \else + \ifhavexrefs + % We (should) know the real title if we have the xref values. + \def\printedrefname{\refx{#1-title}{}}% + \else + % Otherwise just copy the Info node name. + \def\printedrefname{\ignorespaces #1}% + \fi% + \fi + \fi + \fi + % + % Make link in pdf output. + \ifpdf + % For pdfTeX and LuaTeX + {\indexnofonts + \makevalueexpandable + \turnoffactive + % This expands tokens, so do it after making catcode changes, so _ + % etc. don't get their TeX definitions. This ignores all spaces in + % #4, including (wrongly) those in the middle of the filename. + \getfilename{#4}% + % + % This (wrongly) does not take account of leading or trailing + % spaces in #1, which should be ignored. + \setpdfdestname{#1}% + % + \ifx\pdfdestname\empty + \def\pdfdestname{Top}% no empty targets + \fi + % + \leavevmode + \startlink attr{/Border [0 0 0]}% + \ifnum\filenamelength>0 + goto file{\the\filename.pdf} name{\pdfdestname}% + \else + goto name{\pdfmkpgn{\pdfdestname}}% + \fi + }% + \setcolor{\linkcolor}% + \else + \ifx\XeTeXrevision\thisisundefined + \else + % For XeTeX + {\indexnofonts + \makevalueexpandable + \turnoffactive + % This expands tokens, so do it after making catcode changes, so _ + % etc. don't get their TeX definitions. This ignores all spaces in + % #4, including (wrongly) those in the middle of the filename. + \getfilename{#4}% + % + % This (wrongly) does not take account of leading or trailing + % spaces in #1, which should be ignored. + \setpdfdestname{#1}% + % + \ifx\pdfdestname\empty + \def\pdfdestname{Top}% no empty targets + \fi + % + \leavevmode + \ifnum\filenamelength>0 + % With default settings, + % XeTeX (xdvipdfmx) replaces link destination names with integers. + % In this case, the replaced destination names of + % remote PDFs are no longer known. In order to avoid a replacement, + % you can use xdvipdfmx's command line option `-C 0x0010'. + % If you use XeTeX 0.99996+ (TeX Live 2016+), + % this command line option is no longer necessary + % because we can use the `dvipdfmx:config' special. + \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A + << /S /GoToR /F (\the\filename.pdf) /D (\pdfdestname) >> >>}% + \else + \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A + << /S /GoTo /D (\pdfdestname) >> >>}% + \fi + }% + \setcolor{\linkcolor}% + \fi + \fi + {% + % Have to otherify everything special to allow the \csname to + % include an _ in the xref name, etc. + \indexnofonts + \turnoffactive + \def\value##1{##1}% + \expandafter\global\expandafter\let\expandafter\Xthisreftitle + \csname XR#1-title\endcsname + }% + % + % Float references are printed completely differently: "Figure 1.2" + % instead of "[somenode], p.3". \iffloat distinguishes them by + % \Xthisreftitle being set to a magic string. + \iffloat\Xthisreftitle + % If the user specified the print name (third arg) to the ref, + % print it instead of our usual "Figure 1.2". + \ifdim\wd\printedrefnamebox = 0pt + \refx{#1-snt}{}% + \else + \printedrefname + \fi + % + % If the user also gave the printed manual name (fifth arg), append + % "in MANUALNAME". + \ifdim \wd\printedmanualbox > 0pt + \space \putwordin{} \cite{\printedmanual}% + \fi + \else + % node/anchor (non-float) references. + % + % If we use \unhbox to print the node names, TeX does not insert + % empty discretionaries after hyphens, which means that it will not + % find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, + % this is a loss. Therefore, we give the text of the node name + % again, so it is as if TeX is seeing it for the first time. + % + \ifdim \wd\printedmanualbox > 0pt + % Cross-manual reference with a printed manual name. + % + \crossmanualxref{\cite{\printedmanual\unskip}}% + % + \else\ifdim \wd\infofilenamebox > 0pt + % Cross-manual reference with only an info filename (arg 4), no + % printed manual name (arg 5). This is essentially the same as + % the case above; we output the filename, since we have nothing else. + % + \crossmanualxref{\code{\infofilename\unskip}}% + % + \else + % Reference within this manual. + % + % _ (for example) has to be the character _ for the purposes of the + % control sequence corresponding to the node, but it has to expand + % into the usual \leavevmode...\vrule stuff for purposes of + % printing. So we \turnoffactive for the \refx-snt, back on for the + % printing, back off for the \refx-pg. + {\turnoffactive + % Only output a following space if the -snt ref is nonempty; for + % @unnumbered and @anchor, it won't be. + \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% + \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi + }% + % output the `[mynode]' via the macro below so it can be overridden. + \xrefprintnodename\printedrefname + % + % But we always want a comma and a space: + ,\space + % + % output the `page 3'. + \turnoffactive \refx{#1-pg}\putwordpage{}% + % Add a , if xref followed by a space + \if\space\noexpand\tokenafterxref ,% + \else\ifx\ \tokenafterxref ,% @TAB + \else\ifx\*\tokenafterxref ,% @* + \else\ifx\ \tokenafterxref ,% @SPACE + \else\ifx\ + \tokenafterxref ,% @NL + \else\ifx\tie\tokenafterxref ,% @tie + \fi\fi\fi\fi\fi\fi + \fi\fi + \fi + \endlink +\endgroup} + +% Output a cross-manual xref to #1. Used just above (twice). +% +% Only include the text "Section ``foo'' in" if the foo is neither +% missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply +% "see The Foo Manual", the idea being to refer to the whole manual. +% +% But, this being TeX, we can't easily compare our node name against the +% string "Top" while ignoring the possible spaces before and after in +% the input. By adding the arbitrary 7sp below, we make it much less +% likely that a real node name would have the same width as "Top" (e.g., +% in a monospaced font). Hopefully it will never happen in practice. +% +% For the same basic reason, we retypeset the "Top" at every +% reference, since the current font is indeterminate. +% +\def\crossmanualxref#1{% + \setbox\toprefbox = \hbox{Top\kern7sp}% + \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}% + \ifdim \wd2 > 7sp % nonempty? + \ifdim \wd2 = \wd\toprefbox \else % same as Top? + \putwordSection{} ``\printedrefname'' \putwordin{}\space + \fi + \fi + #1% +} + +% This macro is called from \xrefX for the `[nodename]' part of xref +% output. It's a separate macro only so it can be changed more easily, +% since square brackets don't work well in some documents. Particularly +% one that Bob is working on :). +% +\def\xrefprintnodename#1{「#1」} + +% Things referred to by \setref. +% +\def\Ynothing{} +\def\Yomitfromtoc{} +\def\Ynumbered{% + \ifnum\secno=0 + \putwordChapter@tie \the\chapno + \else \ifnum\subsecno=0 + \putwordSection@tie \the\chapno.\the\secno + \else \ifnum\subsubsecno=0 + \putwordSection@tie \the\chapno.\the\secno.\the\subsecno + \else + \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno + \fi\fi\fi +} +\def\Yappendix{% + \ifnum\secno=0 + \putwordAppendix@tie @char\the\appendixno{}% + \else \ifnum\subsecno=0 + \putwordSection@tie @char\the\appendixno.\the\secno + \else \ifnum\subsubsecno=0 + \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno + \else + \putwordSection@tie + @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno + \fi\fi\fi +} + +% \refx{NAME}{SUFFIX} - reference a cross-reference string named NAME. SUFFIX +% is output afterwards if non-empty. +\def\refx#1#2{% + \requireauxfile + {% + \indexnofonts + \otherbackslash + \def\value##1{##1}% + \expandafter\global\expandafter\let\expandafter\thisrefX + \csname XR#1\endcsname + }% + \ifx\thisrefX\relax + % If not defined, say something at least. + \angleleft un\-de\-fined\angleright + \iflinks + \ifhavexrefs + {\toks0 = {#1}% avoid expansion of possibly-complex value + \message{\linenumber Undefined cross reference `\the\toks0'.}}% + \else + \ifwarnedxrefs\else + \global\warnedxrefstrue + \message{Cross reference values unknown; you must run TeX again.}% + \fi + \fi + \fi + \else + % It's defined, so just use it. + \thisrefX + \fi + #2% Output the suffix in any case. +} + +% This is the macro invoked by entries in the aux file. Define a control +% sequence for a cross-reference target (we prepend XR to the control sequence +% name to avoid collisions). The value is the page number. If this is a float +% type, we have more work to do. +% +\def\xrdef#1#2{% + {% Expand the node or anchor name to remove control sequences. + % \turnoffactive stops 8-bit characters being changed to commands + % like @'e. \refx does the same to retrieve the value in the definition. + \indexnofonts + \turnoffactive + \def\value##1{##1}% + \xdef\safexrefname{#1}% + }% + % + \bgroup + \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% + \egroup + % We put the \gdef inside a group to avoid the definitions building up on + % TeX's save stack, which can cause it to run out of space for aux files with + % thousands of lines. \gdef doesn't use the save stack, but \csname does + % when it defines an unknown control sequence as \relax. + % + % Was that xref control sequence that we just defined for a float? + \expandafter\iffloat\csname XR\safexrefname\endcsname + % it was a float, and we have the (safe) float type in \iffloattype. + \expandafter\let\expandafter\floatlist + \csname floatlist\iffloattype\endcsname + % + % Is this the first time we've seen this float type? + \expandafter\ifx\floatlist\relax + \toks0 = {\do}% yes, so just \do + \else + % had it before, so preserve previous elements in list. + \toks0 = \expandafter{\floatlist\do}% + \fi + % + % Remember this xref in the control sequence \floatlistFLOATTYPE, + % for later use in \listoffloats. + \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0 + {\safexrefname}}% + \fi +} + +% If working on a large document in chapters, it is convenient to +% be able to disable indexing, cross-referencing, and contents, for test runs. +% This is done with @novalidate at the beginning of the file. +% +\newif\iflinks \linkstrue % by default we want the aux files. +\let\novalidate = \linksfalse + +% Used when writing to the aux file, or when using data from it. +\def\requireauxfile{% + \iflinks + \tryauxfile + % Open the new aux file. TeX will close it automatically at exit. + \immediate\openout\auxfile=\jobname.aux + \fi + \global\let\requireauxfile=\relax % Only do this once. +} + +% Read the last existing aux file, if any. No error if none exists. +% +\def\tryauxfile{% + \openin 1 \jobname.aux + \ifeof 1 \else + \readdatafile{aux}% + \global\havexrefstrue + \fi + \closein 1 +} + +\def\setupdatafile{% + \catcode`\^^@=\other + \catcode`\^^A=\other + \catcode`\^^B=\other + \catcode`\^^C=\other + \catcode`\^^D=\other + \catcode`\^^E=\other + \catcode`\^^F=\other + \catcode`\^^G=\other + \catcode`\^^H=\other + \catcode`\^^K=\other + \catcode`\^^L=\other + \catcode`\^^N=\other + \catcode`\^^P=\other + \catcode`\^^Q=\other + \catcode`\^^R=\other + \catcode`\^^S=\other + \catcode`\^^T=\other + \catcode`\^^U=\other + \catcode`\^^V=\other + \catcode`\^^W=\other + \catcode`\^^X=\other + \catcode`\^^Z=\other + \catcode`\^^[=\other + \catcode`\^^\=\other + \catcode`\^^]=\other + \catcode`\^^^=\other + \catcode`\^^_=\other + % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc. + % in xref tags, i.e., node names. But since ^^e4 notation isn't + % supported in the main text, it doesn't seem desirable. Furthermore, + % that is not enough: for node names that actually contain a ^ + % character, we would end up writing a line like this: 'xrdef {'hat + % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first + % argument, and \hat is not an expandable control sequence. It could + % all be worked out, but why? Either we support ^^ or we don't. + % + % The other change necessary for this was to define \auxhat: + % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter + % and then to call \auxhat in \setq. + % + \catcode`\^=\other + % + % Special characters. Should be turned off anyway, but... + \catcode`\~=\other + \catcode`\[=\other + \catcode`\]=\other + \catcode`\"=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\$=\other + \catcode`\#=\other + \catcode`\&=\other + \catcode`\%=\other + \catcode`+=\other % avoid \+ for paranoia even though we've turned it off + % + % This is to support \ in node names and titles, since the \ + % characters end up in a \csname. It's easier than + % leaving it active and making its active definition an actual \ + % character. What I don't understand is why it works in the *value* + % of the xrdef. Seems like it should be a catcode12 \, and that + % should not typeset properly. But it works, so I'm moving on for + % now. --karl, 15jan04. + \catcode`\\=\other + % + % @ is our escape character in .aux files, and we need braces. + \catcode`\{=1 + \catcode`\}=2 + \catcode`\@=0 +} + +\def\readdatafile#1{% +\begingroup + \setupdatafile + \input\jobname.#1 +\endgroup} + + +\message{insertions,} +% including footnotes. + +\newcount \footnoteno + +% The trailing space in the following definition for supereject is +% vital for proper filling; pages come out unaligned when you do a +% pagealignmacro call if that space before the closing brace is +% removed. (Generally, numeric constants should always be followed by a +% space to prevent strange expansion errors.) +\def\supereject{\par\penalty -20000\footnoteno =0 } + +% @footnotestyle is meaningful for Info output only. +\let\footnotestyle=\comment + +{\catcode `\@=11 +% +% Auto-number footnotes. Otherwise like plain. +\gdef\footnote{% + \global\advance\footnoteno by \@ne + \edef\thisfootno{$^{\the\footnoteno}$}% + % + % In case the footnote comes at the end of a sentence, preserve the + % extra spacing after we do the footnote number. + \let\@sf\empty + \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi + % + % Remove inadvertent blank space before typesetting the footnote number. + \unskip + \thisfootno\@sf + \dofootnote +}% + +% Don't bother with the trickery in plain.tex to not require the +% footnote text as a parameter. Our footnotes don't need to be so general. +% +% Oh yes, they do; otherwise, @ifset (and anything else that uses +% \parseargline) fails inside footnotes because the tokens are fixed when +% the footnote is read. --karl, 16nov96. +% +\gdef\dofootnote{% + \insert\footins\bgroup + % + % Nested footnotes are not supported in TeX, that would take a lot + % more work. (\startsavinginserts does not suffice.) + \let\footnote=\errfootnotenest + % + % We want to typeset this text as a normal paragraph, even if the + % footnote reference occurs in (for example) a display environment. + % So reset some parameters. + \hsize=\txipagewidth + \interlinepenalty\interfootnotelinepenalty + \splittopskip\ht\strutbox % top baseline for broken footnotes + \splitmaxdepth\dp\strutbox + \floatingpenalty\@MM + \leftskip\z@skip + \rightskip\z@skip + \spaceskip\z@skip + \xspaceskip\z@skip + \parindent\defaultparindent + % + \smallfonts \rm + % + % Because we use hanging indentation in footnotes, a @noindent appears + % to exdent this text, so make it be a no-op. makeinfo does not use + % hanging indentation so @noindent can still be needed within footnote + % text after an @example or the like (not that this is good style). + \let\noindent = \relax + % + % Hang the footnote text off the number. Use \everypar in case the + % footnote extends for more than one paragraph. + \everypar = {\hang}% + \textindent{\thisfootno}% + % + % Don't crash into the line above the footnote text. Since this + % expands into a box, it must come within the paragraph, lest it + % provide a place where TeX can split the footnote. + \footstrut + % + % Invoke rest of plain TeX footnote routine. + \futurelet\next\fo@t +} +}%end \catcode `\@=11 + +\def\errfootnotenest{% + \errhelp=\EMsimple + \errmessage{Nested footnotes not supported in texinfo.tex, + even though they work in makeinfo; sorry} +} + +\def\errfootnoteheading{% + \errhelp=\EMsimple + \errmessage{Footnotes in chapters, sections, etc., are not supported} +} + +% In case a @footnote appears in a vbox, save the footnote text and create +% the real \insert just after the vbox finished. Otherwise, the insertion +% would be lost. +% Similarly, if a @footnote appears inside an alignment, save the footnote +% text to a box and make the \insert when a row of the table is finished. +% And the same can be done for other insert classes. --kasal, 16nov03. +% +% Replace the \insert primitive by a cheating macro. +% Deeper inside, just make sure that the saved insertions are not spilled +% out prematurely. +% +\def\startsavinginserts{% + \ifx \insert\ptexinsert + \let\insert\saveinsert + \else + \let\checkinserts\relax + \fi +} + +% This \insert replacement works for both \insert\footins{foo} and +% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}. +% +\def\saveinsert#1{% + \edef\next{\noexpand\savetobox \makeSAVEname#1}% + \afterassignment\next + % swallow the left brace + \let\temp = +} +\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}} +\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1} + +\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi} + +\def\placesaveins#1{% + \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname + {\box#1}% +} + +% eat @SAVE -- beware, all of them have catcode \other: +{ + \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-) + \gdef\gobblesave @SAVE{} +} + +% initialization: +\def\newsaveins #1{% + \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}% + \next +} +\def\newsaveinsX #1{% + \csname newbox\endcsname #1% + \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts + \checksaveins #1}% +} + +% initialize: +\let\checkinserts\empty +\newsaveins\footins +\newsaveins\margin + + +% @image. We use the macros from epsf.tex to support this. +% If epsf.tex is not installed and @image is used, we complain. +% +% Check for and read epsf.tex up front. If we read it only at @image +% time, we might be inside a group, and then its definitions would get +% undone and the next image would fail. +\openin 1 = epsf.tex +\ifeof 1 \else + % Do not bother showing banner with epsf.tex v2.7k (available in + % doc/epsf.tex and on ctan). + \def\epsfannounce{\toks0 = }% + \input epsf.tex +\fi +\closein 1 +% +% We will only complain once about lack of epsf.tex. +\newif\ifwarnednoepsf +\newhelp\noepsfhelp{epsf.tex must be installed for images to + work. It is also included in the Texinfo distribution, or you can get + it from ftp://tug.org/tex/epsf.tex.} +% +\def\image#1{% + \ifx\epsfbox\thisisundefined + \ifwarnednoepsf \else + \errhelp = \noepsfhelp + \errmessage{epsf.tex not found, images will be ignored}% + \global\warnednoepsftrue + \fi + \else + \imagexxx #1,,,,,\finish + \fi +} +% +% Arguments to @image: +% #1 is (mandatory) image filename; we tack on .eps extension. +% #2 is (optional) width, #3 is (optional) height. +% #4 is (ignored optional) html alt text. +% #5 is (ignored optional) extension. +% #6 is just the usual extra ignored arg for parsing stuff. +\newif\ifimagevmode +\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup + \catcode`\^^M = 5 % in case we're inside an example + \normalturnoffactive % allow _ et al. in names + \def\xprocessmacroarg{\eatspaces}% in case we are being used via a macro + % If the image is by itself, center it. + \ifvmode + \imagevmodetrue + \else \ifx\centersub\centerV + % for @center @image, we need a vbox so we can have our vertical space + \imagevmodetrue + \vbox\bgroup % vbox has better behavior than vtop herev + \fi\fi + % + \ifimagevmode + \nobreak\medskip + % Usually we'll have text after the image which will insert + % \parskip glue, so insert it here too to equalize the space + % above and below. + \nobreak\vskip\parskip + \nobreak + \fi + % + % Leave vertical mode so that indentation from an enclosing + % environment such as @quotation is respected. + % However, if we're at the top level, we don't want the + % normal paragraph indentation. + % On the other hand, if we are in the case of @center @image, we don't + % want to start a paragraph, which will create a hsize-width box and + % eradicate the centering. + \ifx\centersub\centerV\else \noindent \fi + % + % Output the image. + \ifpdf + % For pdfTeX and LuaTeX <= 0.80 + \dopdfimage{#1}{#2}{#3}% + \else + \ifx\XeTeXrevision\thisisundefined + % For epsf.tex + % \epsfbox itself resets \epsf?size at each figure. + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt \epsfysize=#3\relax \fi + \epsfbox{#1.eps}% + \else + % For XeTeX + \doxeteximage{#1}{#2}{#3}% + \fi + \fi + % + \ifimagevmode + \medskip % space after a standalone image + \fi + \ifx\centersub\centerV \egroup \fi +\endgroup} + + +% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables, +% etc. We don't actually implement floating yet, we always include the +% float "here". But it seemed the best name for the future. +% +\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish} + +% There may be a space before second and/or third parameter; delete it. +\def\eatcommaspace#1, {#1,} + +% #1 is the optional FLOATTYPE, the text label for this float, typically +% "Figure", "Table", "Example", etc. Can't contain commas. If omitted, +% this float will not be numbered and cannot be referred to. +% +% #2 is the optional xref label. Also must be present for the float to +% be referable. +% +% #3 is the optional positioning argument; for now, it is ignored. It +% will somehow specify the positions allowed to float to (here, top, bottom). +% +% We keep a separate counter for each FLOATTYPE, which we reset at each +% chapter-level command. +\let\resetallfloatnos=\empty +% +\def\dofloat#1,#2,#3,#4\finish{% + \let\thiscaption=\empty + \let\thisshortcaption=\empty + % + % don't lose footnotes inside @float. + % + % BEWARE: when the floats start float, we have to issue warning whenever an + % insert appears inside a float which could possibly float. --kasal, 26may04 + % + \startsavinginserts + % + % We can't be used inside a paragraph. + \par + % + \vtop\bgroup + \def\floattype{#1}% + \def\floatlabel{#2}% + \def\floatloc{#3}% we do nothing with this yet. + % + \ifx\floattype\empty + \let\safefloattype=\empty + \else + {% + % the floattype might have accents or other special characters, + % but we need to use it in a control sequence name. + \indexnofonts + \turnoffactive + \xdef\safefloattype{\floattype}% + }% + \fi + % + % If label is given but no type, we handle that as the empty type. + \ifx\floatlabel\empty \else + % We want each FLOATTYPE to be numbered separately (Figure 1, + % Table 1, Figure 2, ...). (And if no label, no number.) + % + \expandafter\getfloatno\csname\safefloattype floatno\endcsname + \global\advance\floatno by 1 + % + {% + % This magic value for \lastsection is output by \setref as the + % XREFLABEL-title value. \xrefX uses it to distinguish float + % labels (which have a completely different output format) from + % node and anchor labels. And \xrdef uses it to construct the + % lists of floats. + % + \edef\lastsection{\floatmagic=\safefloattype}% + \setref{\floatlabel}{Yfloat}% + }% + \fi + % + % start with \parskip glue, I guess. + \vskip\parskip + % + % Don't suppress indentation if a float happens to start a section. + \restorefirstparagraphindent +} + +% we have these possibilities: +% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap +% @float Foo,lbl & no caption: Foo 1.1 +% @float Foo & @caption{Cap}: Foo: Cap +% @float Foo & no caption: Foo +% @float ,lbl & Caption{Cap}: 1.1: Cap +% @float ,lbl & no caption: 1.1 +% @float & @caption{Cap}: Cap +% @float & no caption: +% +\def\Efloat{% + \let\floatident = \empty + % + % In all cases, if we have a float type, it comes first. + \ifx\floattype\empty \else \def\floatident{\floattype}\fi + % + % If we have an xref label, the number comes next. + \ifx\floatlabel\empty \else + \ifx\floattype\empty \else % if also had float type, need tie first. + \appendtomacro\floatident{\tie}% + \fi + % the number. + \appendtomacro\floatident{\chaplevelprefix\the\floatno}% + \fi + % + % Start the printed caption with what we've constructed in + % \floatident, but keep it separate; we need \floatident again. + \let\captionline = \floatident + % + \ifx\thiscaption\empty \else + \ifx\floatident\empty \else + \appendtomacro\captionline{: }% had ident, so need a colon between + \fi + % + % caption text. + \appendtomacro\captionline{\scanexp\thiscaption}% + \fi + % + % If we have anything to print, print it, with space before. + % Eventually this needs to become an \insert. + \ifx\captionline\empty \else + \vskip.5\parskip + \captionline + % + % Space below caption. + \vskip\parskip + \fi + % + % If have an xref label, write the list of floats info. Do this + % after the caption, to avoid chance of it being a breakpoint. + \ifx\floatlabel\empty \else + % Write the text that goes in the lof to the aux file as + % \floatlabel-lof. Besides \floatident, we include the short + % caption if specified, else the full caption if specified, else nothing. + {% + \requireauxfile + \atdummies + % + \ifx\thisshortcaption\empty + \def\gtemp{\thiscaption}% + \else + \def\gtemp{\thisshortcaption}% + \fi + \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident + \ifx\gtemp\empty \else : \gtemp \fi}}% + }% + \fi + \egroup % end of \vtop + % + \checkinserts +} + +% Append the tokens #2 to the definition of macro #1, not expanding either. +% +\def\appendtomacro#1#2{% + \expandafter\def\expandafter#1\expandafter{#1#2}% +} + +% @caption, @shortcaption +% +\def\caption{\docaption\thiscaption} +\def\shortcaption{\docaption\thisshortcaption} +\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption} +\def\defcaption#1#2{\egroup \def#1{#2}} + +% The parameter is the control sequence identifying the counter we are +% going to use. Create it if it doesn't exist and assign it to \floatno. +\def\getfloatno#1{% + \ifx#1\relax + % Haven't seen this figure type before. + \csname newcount\endcsname #1% + % + % Remember to reset this floatno at the next chap. + \expandafter\gdef\expandafter\resetallfloatnos + \expandafter{\resetallfloatnos #1=0 }% + \fi + \let\floatno#1% +} + +% \setref calls this to get the XREFLABEL-snt value. We want an @xref +% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we +% first read the @float command. +% +\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}% + +% Magic string used for the XREFLABEL-title value, so \xrefX can +% distinguish floats from other xref types. +\def\floatmagic{!!float!!} + +% #1 is the control sequence we are passed; we expand into a conditional +% which is true if #1 represents a float ref. That is, the magic +% \lastsection value which we \setref above. +% +\def\iffloat#1{\expandafter\doiffloat#1==\finish} +% +% #1 is (maybe) the \floatmagic string. If so, #2 will be the +% (safe) float type for this float. We set \iffloattype to #2. +% +\def\doiffloat#1=#2=#3\finish{% + \def\temp{#1}% + \def\iffloattype{#2}% + \ifx\temp\floatmagic +} + +% @listoffloats FLOATTYPE - print a list of floats like a table of contents. +% +\parseargdef\listoffloats{% + \def\floattype{#1}% floattype + {% + % the floattype might have accents or other special characters, + % but we need to use it in a control sequence name. + \indexnofonts + \turnoffactive + \xdef\safefloattype{\floattype}% + }% + % + % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE. + \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax + \ifhavexrefs + % if the user said @listoffloats foo but never @float foo. + \message{\linenumber No `\safefloattype' floats to list.}% + \fi + \else + \begingroup + \leftskip=\tocindent % indent these entries like a toc + \let\do=\listoffloatsdo + \csname floatlist\safefloattype\endcsname + \endgroup + \fi +} + +% This is called on each entry in a list of floats. We're passed the +% xref label, in the form LABEL-title, which is how we save it in the +% aux file. We strip off the -title and look up \XRLABEL-lof, which +% has the text we're supposed to typeset here. +% +% Figures without xref labels will not be included in the list (since +% they won't appear in the aux file). +% +\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish} +\def\listoffloatsdoentry#1-title\finish{{% + % Can't fully expand XR#1-lof because it can contain anything. Just + % pass the control sequence. On the other hand, XR#1-pg is just the + % page number, and we want to fully expand that so we can get a link + % in pdf output. + \toksA = \expandafter{\csname XR#1-lof\endcsname}% + % + % use the same \entry macro we use to generate the TOC and index. + \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}% + \writeentry +}} + + +\message{localization,} + +% For single-language documents, @documentlanguage is usually given very +% early, just after @documentencoding. Single argument is the language +% (de) or locale (de_DE) abbreviation. +% +{ + \catcode`\_ = \active + \globaldefs=1 +\parseargdef\documentlanguage{% + \tex % read txi-??.tex file in plain TeX. + % Read the file by the name they passed if it exists. + \let_ = \normalunderscore % normal _ character for filename test + \openin 1 txi-#1.tex + \ifeof 1 + \documentlanguagetrywithoutunderscore #1_\finish + \else + \globaldefs = 1 % everything in the txi-LL files needs to persist + \input txi-#1.tex + \fi + \closein 1 + \endgroup % end raw TeX +} +% +% If they passed de_DE, and txi-de_DE.tex doesn't exist, +% try txi-de.tex. +% +\gdef\documentlanguagetrywithoutunderscore#1_#2\finish{% + \openin 1 txi-#1.tex + \ifeof 1 + \errhelp = \nolanghelp + \errmessage{Cannot read language file txi-#1.tex}% + \else + \globaldefs = 1 % everything in the txi-LL files needs to persist + \input txi-#1.tex + \fi + \closein 1 +} +}% end of special _ catcode +% +\newhelp\nolanghelp{The given language definition file cannot be found or +is empty. Maybe you need to install it? Putting it in the current +directory should work if nowhere else does.} + +% This macro is called from txi-??.tex files; the first argument is the +% \language name to set (without the "\lang@" prefix), the second and +% third args are \{left,right}hyphenmin. +% +% The language names to pass are determined when the format is built. +% See the etex.log file created at that time, e.g., +% /usr/local/texlive/2008/texmf-var/web2c/pdftex/etex.log. +% +% With TeX Live 2008, etex now includes hyphenation patterns for all +% available languages. This means we can support hyphenation in +% Texinfo, at least to some extent. (This still doesn't solve the +% accented characters problem.) +% +\catcode`@=11 +\def\txisetlanguage#1#2#3{% + % do not set the language if the name is undefined in the current TeX. + \expandafter\ifx\csname lang@#1\endcsname \relax + \message{no patterns for #1}% + \else + \global\language = \csname lang@#1\endcsname + \fi + % but there is no harm in adjusting the hyphenmin values regardless. + \global\lefthyphenmin = #2\relax + \global\righthyphenmin = #3\relax +} + +% XeTeX and LuaTeX can handle Unicode natively. +% Their default I/O uses UTF-8 sequences instead of a byte-wise operation. +% Other TeX engines' I/O (pdfTeX, etc.) is byte-wise. +% +\newif\iftxinativeunicodecapable +\newif\iftxiusebytewiseio + +\ifx\XeTeXrevision\thisisundefined + \ifx\luatexversion\thisisundefined + \txinativeunicodecapablefalse + \txiusebytewiseiotrue + \else + \txinativeunicodecapabletrue + \txiusebytewiseiofalse + \fi +\else + \txinativeunicodecapabletrue + \txiusebytewiseiofalse +\fi + +% Set I/O by bytes instead of UTF-8 sequence for XeTeX and LuaTex +% for non-UTF-8 (byte-wise) encodings. +% +\def\setbytewiseio{% + \ifx\XeTeXrevision\thisisundefined + \else + \XeTeXdefaultencoding "bytes" % For subsequent files to be read + \XeTeXinputencoding "bytes" % For document root file + % Unfortunately, there seems to be no corresponding XeTeX command for + % output encoding. This is a problem for auxiliary index and TOC files. + % The only solution would be perhaps to write out @U{...} sequences in + % place of non-ASCII characters. + \fi + + \ifx\luatexversion\thisisundefined + \else + \directlua{ + local utf8_char, byte, gsub = unicode.utf8.char, string.byte, string.gsub + local function convert_char (char) + return utf8_char(byte(char)) + end + + local function convert_line (line) + return gsub(line, ".", convert_char) + end + + callback.register("process_input_buffer", convert_line) + + local function convert_line_out (line) + local line_out = "" + for c in string.utfvalues(line) do + line_out = line_out .. string.char(c) + end + return line_out + end + + callback.register("process_output_buffer", convert_line_out) + } + \fi + + \txiusebytewiseiotrue +} + + +% Helpers for encodings. +% Set the catcode of characters 128 through 255 to the specified number. +% +\def\setnonasciicharscatcode#1{% + \count255=128 + \loop\ifnum\count255<256 + \global\catcode\count255=#1\relax + \advance\count255 by 1 + \repeat +} + +\def\setnonasciicharscatcodenonglobal#1{% + \count255=128 + \loop\ifnum\count255<256 + \catcode\count255=#1\relax + \advance\count255 by 1 + \repeat +} + +% @documentencoding sets the definition of non-ASCII characters +% according to the specified encoding. +% +\def\documentencoding{\parseargusing\filenamecatcodes\documentencodingzzz} +\def\documentencodingzzz#1{% + % + % Encoding being declared for the document. + \def\declaredencoding{\csname #1.enc\endcsname}% + % + % Supported encodings: names converted to tokens in order to be able + % to compare them with \ifx. + \def\ascii{\csname US-ASCII.enc\endcsname}% + \def\latnine{\csname ISO-8859-15.enc\endcsname}% + \def\latone{\csname ISO-8859-1.enc\endcsname}% + \def\lattwo{\csname ISO-8859-2.enc\endcsname}% + \def\utfeight{\csname UTF-8.enc\endcsname}% + % + \ifx \declaredencoding \ascii + \asciichardefs + % + \else \ifx \declaredencoding \lattwo + \iftxinativeunicodecapable + \setbytewiseio + \fi + \setnonasciicharscatcode\active + \lattwochardefs + % + \else \ifx \declaredencoding \latone + \iftxinativeunicodecapable + \setbytewiseio + \fi + \setnonasciicharscatcode\active + \latonechardefs + % + \else \ifx \declaredencoding \latnine + \iftxinativeunicodecapable + \setbytewiseio + \fi + \setnonasciicharscatcode\active + \latninechardefs + % + \else \ifx \declaredencoding \utfeight + \iftxinativeunicodecapable + % For native Unicode handling (XeTeX and LuaTeX) + \nativeunicodechardefs + \else + % For treating UTF-8 as byte sequences (TeX, eTeX and pdfTeX) + \setnonasciicharscatcode\active + % since we already invoked \utfeightchardefs at the top level + % (below), do not re-invoke it, otherwise our check for duplicated + % definitions gets triggered. Making non-ascii chars active is + % sufficient. + \fi + % + \else + \message{Ignoring unknown document encoding: #1.}% + % + \fi % utfeight + \fi % latnine + \fi % latone + \fi % lattwo + \fi % ascii + % + \ifx\XeTeXrevision\thisisundefined + \else + \ifx \declaredencoding \utfeight + \else + \ifx \declaredencoding \ascii + \else + \message{Warning: XeTeX with non-UTF-8 encodings cannot handle % + non-ASCII characters in auxiliary files.}% + \fi + \fi + \fi +} + +% emacs-page +% A message to be logged when using a character that isn't available +% the default font encoding (OT1). +% +\def\missingcharmsg#1{\message{Character missing, sorry: #1.}} + +% Take account of \c (plain) vs. \, (Texinfo) difference. +\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi} + +% First, make active non-ASCII characters in order for them to be +% correctly categorized when TeX reads the replacement text of +% macros containing the character definitions. +\setnonasciicharscatcode\active +% + +\def\gdefchar#1#2{% +\gdef#1{% + \ifpassthroughchars + \string#1% + \else + #2% + \fi +}} + +% Latin1 (ISO-8859-1) character definitions. +\def\latonechardefs{% + \gdefchar^^a0{\tie} + \gdefchar^^a1{\exclamdown} + \gdefchar^^a2{{\tcfont \char162}} % cent + \gdefchar^^a3{\pounds{}} + \gdefchar^^a4{{\tcfont \char164}} % currency + \gdefchar^^a5{{\tcfont \char165}} % yen + \gdefchar^^a6{{\tcfont \char166}} % broken bar + \gdefchar^^a7{\S} + \gdefchar^^a8{\"{}} + \gdefchar^^a9{\copyright{}} + \gdefchar^^aa{\ordf} + \gdefchar^^ab{\guillemetleft{}} + \gdefchar^^ac{\ensuremath\lnot} + \gdefchar^^ad{\-} + \gdefchar^^ae{\registeredsymbol{}} + \gdefchar^^af{\={}} + % + \gdefchar^^b0{\textdegree} + \gdefchar^^b1{$\pm$} + \gdefchar^^b2{$^2$} + \gdefchar^^b3{$^3$} + \gdefchar^^b4{\'{}} + \gdefchar^^b5{$\mu$} + \gdefchar^^b6{\P} + \gdefchar^^b7{\ensuremath\cdot} + \gdefchar^^b8{\cedilla\ } + \gdefchar^^b9{$^1$} + \gdefchar^^ba{\ordm} + \gdefchar^^bb{\guillemetright{}} + \gdefchar^^bc{$1\over4$} + \gdefchar^^bd{$1\over2$} + \gdefchar^^be{$3\over4$} + \gdefchar^^bf{\questiondown} + % + \gdefchar^^c0{\`A} + \gdefchar^^c1{\'A} + \gdefchar^^c2{\^A} + \gdefchar^^c3{\~A} + \gdefchar^^c4{\"A} + \gdefchar^^c5{\ringaccent A} + \gdefchar^^c6{\AE} + \gdefchar^^c7{\cedilla C} + \gdefchar^^c8{\`E} + \gdefchar^^c9{\'E} + \gdefchar^^ca{\^E} + \gdefchar^^cb{\"E} + \gdefchar^^cc{\`I} + \gdefchar^^cd{\'I} + \gdefchar^^ce{\^I} + \gdefchar^^cf{\"I} + % + \gdefchar^^d0{\DH} + \gdefchar^^d1{\~N} + \gdefchar^^d2{\`O} + \gdefchar^^d3{\'O} + \gdefchar^^d4{\^O} + \gdefchar^^d5{\~O} + \gdefchar^^d6{\"O} + \gdefchar^^d7{$\times$} + \gdefchar^^d8{\O} + \gdefchar^^d9{\`U} + \gdefchar^^da{\'U} + \gdefchar^^db{\^U} + \gdefchar^^dc{\"U} + \gdefchar^^dd{\'Y} + \gdefchar^^de{\TH} + \gdefchar^^df{\ss} + % + \gdefchar^^e0{\`a} + \gdefchar^^e1{\'a} + \gdefchar^^e2{\^a} + \gdefchar^^e3{\~a} + \gdefchar^^e4{\"a} + \gdefchar^^e5{\ringaccent a} + \gdefchar^^e6{\ae} + \gdefchar^^e7{\cedilla c} + \gdefchar^^e8{\`e} + \gdefchar^^e9{\'e} + \gdefchar^^ea{\^e} + \gdefchar^^eb{\"e} + \gdefchar^^ec{\`{\dotless i}} + \gdefchar^^ed{\'{\dotless i}} + \gdefchar^^ee{\^{\dotless i}} + \gdefchar^^ef{\"{\dotless i}} + % + \gdefchar^^f0{\dh} + \gdefchar^^f1{\~n} + \gdefchar^^f2{\`o} + \gdefchar^^f3{\'o} + \gdefchar^^f4{\^o} + \gdefchar^^f5{\~o} + \gdefchar^^f6{\"o} + \gdefchar^^f7{$\div$} + \gdefchar^^f8{\o} + \gdefchar^^f9{\`u} + \gdefchar^^fa{\'u} + \gdefchar^^fb{\^u} + \gdefchar^^fc{\"u} + \gdefchar^^fd{\'y} + \gdefchar^^fe{\th} + \gdefchar^^ff{\"y} +} + +% Latin9 (ISO-8859-15) encoding character definitions. +\def\latninechardefs{% + % Encoding is almost identical to Latin1. + \latonechardefs + % + \gdefchar^^a4{\euro{}} + \gdefchar^^a6{\v S} + \gdefchar^^a8{\v s} + \gdefchar^^b4{\v Z} + \gdefchar^^b8{\v z} + \gdefchar^^bc{\OE} + \gdefchar^^bd{\oe} + \gdefchar^^be{\"Y} +} + +% Latin2 (ISO-8859-2) character definitions. +\def\lattwochardefs{% + \gdefchar^^a0{\tie} + \gdefchar^^a1{\ogonek{A}} + \gdefchar^^a2{\u{}} + \gdefchar^^a3{\L} + \gdefchar^^a4{\missingcharmsg{CURRENCY SIGN}} + \gdefchar^^a5{\v L} + \gdefchar^^a6{\'S} + \gdefchar^^a7{\S} + \gdefchar^^a8{\"{}} + \gdefchar^^a9{\v S} + \gdefchar^^aa{\cedilla S} + \gdefchar^^ab{\v T} + \gdefchar^^ac{\'Z} + \gdefchar^^ad{\-} + \gdefchar^^ae{\v Z} + \gdefchar^^af{\dotaccent Z} + % + \gdefchar^^b0{\textdegree{}} + \gdefchar^^b1{\ogonek{a}} + \gdefchar^^b2{\ogonek{ }} + \gdefchar^^b3{\l} + \gdefchar^^b4{\'{}} + \gdefchar^^b5{\v l} + \gdefchar^^b6{\'s} + \gdefchar^^b7{\v{}} + \gdefchar^^b8{\cedilla\ } + \gdefchar^^b9{\v s} + \gdefchar^^ba{\cedilla s} + \gdefchar^^bb{\v t} + \gdefchar^^bc{\'z} + \gdefchar^^bd{\H{}} + \gdefchar^^be{\v z} + \gdefchar^^bf{\dotaccent z} + % + \gdefchar^^c0{\'R} + \gdefchar^^c1{\'A} + \gdefchar^^c2{\^A} + \gdefchar^^c3{\u A} + \gdefchar^^c4{\"A} + \gdefchar^^c5{\'L} + \gdefchar^^c6{\'C} + \gdefchar^^c7{\cedilla C} + \gdefchar^^c8{\v C} + \gdefchar^^c9{\'E} + \gdefchar^^ca{\ogonek{E}} + \gdefchar^^cb{\"E} + \gdefchar^^cc{\v E} + \gdefchar^^cd{\'I} + \gdefchar^^ce{\^I} + \gdefchar^^cf{\v D} + % + \gdefchar^^d0{\DH} + \gdefchar^^d1{\'N} + \gdefchar^^d2{\v N} + \gdefchar^^d3{\'O} + \gdefchar^^d4{\^O} + \gdefchar^^d5{\H O} + \gdefchar^^d6{\"O} + \gdefchar^^d7{$\times$} + \gdefchar^^d8{\v R} + \gdefchar^^d9{\ringaccent U} + \gdefchar^^da{\'U} + \gdefchar^^db{\H U} + \gdefchar^^dc{\"U} + \gdefchar^^dd{\'Y} + \gdefchar^^de{\cedilla T} + \gdefchar^^df{\ss} + % + \gdefchar^^e0{\'r} + \gdefchar^^e1{\'a} + \gdefchar^^e2{\^a} + \gdefchar^^e3{\u a} + \gdefchar^^e4{\"a} + \gdefchar^^e5{\'l} + \gdefchar^^e6{\'c} + \gdefchar^^e7{\cedilla c} + \gdefchar^^e8{\v c} + \gdefchar^^e9{\'e} + \gdefchar^^ea{\ogonek{e}} + \gdefchar^^eb{\"e} + \gdefchar^^ec{\v e} + \gdefchar^^ed{\'{\dotless{i}}} + \gdefchar^^ee{\^{\dotless{i}}} + \gdefchar^^ef{\v d} + % + \gdefchar^^f0{\dh} + \gdefchar^^f1{\'n} + \gdefchar^^f2{\v n} + \gdefchar^^f3{\'o} + \gdefchar^^f4{\^o} + \gdefchar^^f5{\H o} + \gdefchar^^f6{\"o} + \gdefchar^^f7{$\div$} + \gdefchar^^f8{\v r} + \gdefchar^^f9{\ringaccent u} + \gdefchar^^fa{\'u} + \gdefchar^^fb{\H u} + \gdefchar^^fc{\"u} + \gdefchar^^fd{\'y} + \gdefchar^^fe{\cedilla t} + \gdefchar^^ff{\dotaccent{}} +} + +% UTF-8 character definitions. +% +% This code to support UTF-8 is based on LaTeX's utf8.def, with some +% changes for Texinfo conventions. It is included here under the GPL by +% permission from Frank Mittelbach and the LaTeX team. +% +\newcount\countUTFx +\newcount\countUTFy +\newcount\countUTFz + +\gdef\UTFviiiTwoOctets#1#2{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\endcsname} +% +\gdef\UTFviiiThreeOctets#1#2#3{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname} +% +\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname} + +\gdef\UTFviiiDefined#1{% + \ifx #1\relax + \message{\linenumber Unicode char \string #1 not defined for Texinfo}% + \else + \expandafter #1% + \fi +} + +% Give non-ASCII bytes the active definitions for processing UTF-8 sequences +\begingroup + \catcode`\~13 + \catcode`\$12 + \catcode`\"12 + + % Loop from \countUTFx to \countUTFy, performing \UTFviiiTmp + % substituting ~ and $ with a character token of that value. + \def\UTFviiiLoop{% + \global\catcode\countUTFx\active + \uccode`\~\countUTFx + \uccode`\$\countUTFx + \uppercase\expandafter{\UTFviiiTmp}% + \advance\countUTFx by 1 + \ifnum\countUTFx < \countUTFy + \expandafter\UTFviiiLoop + \fi} + + % For bytes other than the first in a UTF-8 sequence. Not expected to + % be expanded except when writing to auxiliary files. + \countUTFx = "80 + \countUTFy = "C2 + \def\UTFviiiTmp{% + \gdef~{% + \ifpassthroughchars $\fi}}% + \UTFviiiLoop + + \countUTFx = "C2 + \countUTFy = "E0 + \def\UTFviiiTmp{% + \gdef~{% + \ifpassthroughchars $% + \else\expandafter\UTFviiiTwoOctets\expandafter$\fi}}% + \UTFviiiLoop + + \countUTFx = "E0 + \countUTFy = "F0 + \def\UTFviiiTmp{% + \gdef~{% + \ifpassthroughchars $% + \else\expandafter\UTFviiiThreeOctets\expandafter$\fi}}% + \UTFviiiLoop + + \countUTFx = "F0 + \countUTFy = "F4 + \def\UTFviiiTmp{% + \gdef~{% + \ifpassthroughchars $% + \else\expandafter\UTFviiiFourOctets\expandafter$\fi + }}% + \UTFviiiLoop +\endgroup + +\def\globallet{\global\let} % save some \expandafter's below + +% @U{xxxx} to produce U+xxxx, if we support it. +\def\U#1{% + \expandafter\ifx\csname uni:#1\endcsname \relax + \iftxinativeunicodecapable + % All Unicode characters can be used if native Unicode handling is + % active. However, if the font does not have the glyph, + % letters are missing. + \begingroup + \uccode`\.="#1\relax + \uppercase{.} + \endgroup + \else + \errhelp = \EMsimple + \errmessage{Unicode character U+#1 not supported, sorry}% + \fi + \else + \csname uni:#1\endcsname + \fi +} + +% These macros are used here to construct the name of a control +% sequence to be defined. +\def\UTFviiiTwoOctetsName#1#2{% + \csname u8:#1\string #2\endcsname}% +\def\UTFviiiThreeOctetsName#1#2#3{% + \csname u8:#1\string #2\string #3\endcsname}% +\def\UTFviiiFourOctetsName#1#2#3#4{% + \csname u8:#1\string #2\string #3\string #4\endcsname}% + +% For UTF-8 byte sequences (TeX, e-TeX and pdfTeX), +% provide a definition macro to replace a Unicode character; +% this gets used by the @U command +% +\begingroup + \catcode`\"=12 + \catcode`\<=12 + \catcode`\.=12 + \catcode`\,=12 + \catcode`\;=12 + \catcode`\!=12 + \catcode`\~=13 + \gdef\DeclareUnicodeCharacterUTFviii#1#2{% + \countUTFz = "#1\relax + \begingroup + \parseXMLCharref + + % Give \u8:... its definition. The sequence of seven \expandafter's + % expands after the \gdef three times, e.g. + % + % 1. \UTFviiTwoOctetsName B1 B2 + % 2. \csname u8:B1 \string B2 \endcsname + % 3. \u8: B1 B2 (a single control sequence token) + % + \expandafter\expandafter + \expandafter\expandafter + \expandafter\expandafter + \expandafter\gdef \UTFviiiTmp{#2}% + % + \expandafter\ifx\csname uni:#1\endcsname \relax \else + \message{Internal error, already defined: #1}% + \fi + % + % define an additional control sequence for this code point. + \expandafter\globallet\csname uni:#1\endcsname \UTFviiiTmp + \endgroup} + % + % Given the value in \countUTFz as a Unicode code point, set \UTFviiiTmp + % to the corresponding UTF-8 sequence. + \gdef\parseXMLCharref{% + \ifnum\countUTFz < "A0\relax + \errhelp = \EMsimple + \errmessage{Cannot define Unicode char value < 00A0}% + \else\ifnum\countUTFz < "800\relax + \parseUTFviiiA,% + \parseUTFviiiB C\UTFviiiTwoOctetsName.,% + \else\ifnum\countUTFz < "10000\relax + \parseUTFviiiA;% + \parseUTFviiiA,% + \parseUTFviiiB E\UTFviiiThreeOctetsName.{,;}% + \else + \parseUTFviiiA;% + \parseUTFviiiA,% + \parseUTFviiiA!% + \parseUTFviiiB F\UTFviiiFourOctetsName.{!,;}% + \fi\fi\fi + } + + % Extract a byte from the end of the UTF-8 representation of \countUTFx. + % It must be a non-initial byte in the sequence. + % Change \uccode of #1 for it to be used in \parseUTFviiiB as one + % of the bytes. + \gdef\parseUTFviiiA#1{% + \countUTFx = \countUTFz + \divide\countUTFz by 64 + \countUTFy = \countUTFz % Save to be the future value of \countUTFz. + \multiply\countUTFz by 64 + + % \countUTFz is now \countUTFx with the last 5 bits cleared. Subtract + % in order to get the last five bits. + \advance\countUTFx by -\countUTFz + + % Convert this to the byte in the UTF-8 sequence. + \advance\countUTFx by 128 + \uccode `#1\countUTFx + \countUTFz = \countUTFy} + + % Used to put a UTF-8 byte sequence into \UTFviiiTmp + % #1 is the increment for \countUTFz to yield a the first byte of the UTF-8 + % sequence. + % #2 is one of the \UTFviii*OctetsName macros. + % #3 is always a full stop (.) + % #4 is a template for the other bytes in the sequence. The values for these + % bytes is substituted in here with \uppercase using the \uccode's. + \gdef\parseUTFviiiB#1#2#3#4{% + \advance\countUTFz by "#10\relax + \uccode `#3\countUTFz + \uppercase{\gdef\UTFviiiTmp{#2#3#4}}} +\endgroup + +% For native Unicode handling (XeTeX and LuaTeX), +% provide a definition macro that sets a catcode to `other' non-globally +% +\def\DeclareUnicodeCharacterNativeOther#1#2{% + \catcode"#1=\other +} + +% https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_M +% U+0000..U+007F = https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block) +% U+0080..U+00FF = https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block) +% U+0100..U+017F = https://en.wikipedia.org/wiki/Latin_Extended-A +% U+0180..U+024F = https://en.wikipedia.org/wiki/Latin_Extended-B +% +% Many of our renditions are less than wonderful, and all the missing +% characters are available somewhere. Loading the necessary fonts +% awaits user request. We can't truly support Unicode without +% reimplementing everything that's been done in LaTeX for many years, +% plus probably using luatex or xetex, and who knows what else. +% We won't be doing that here in this simple file. But we can try to at +% least make most of the characters not bomb out. +% +\def\unicodechardefs{% + \DeclareUnicodeCharacter{00A0}{\tie}% + \DeclareUnicodeCharacter{00A1}{\exclamdown}% + \DeclareUnicodeCharacter{00A2}{{\tcfont \char162}}% 0242=cent + \DeclareUnicodeCharacter{00A3}{\pounds{}}% + \DeclareUnicodeCharacter{00A4}{{\tcfont \char164}}% 0244=currency + \DeclareUnicodeCharacter{00A5}{{\tcfont \char165}}% 0245=yen + \DeclareUnicodeCharacter{00A6}{{\tcfont \char166}}% 0246=brokenbar + \DeclareUnicodeCharacter{00A7}{\S}% + \DeclareUnicodeCharacter{00A8}{\"{ }}% + \DeclareUnicodeCharacter{00A9}{\copyright{}}% + \DeclareUnicodeCharacter{00AA}{\ordf}% + \DeclareUnicodeCharacter{00AB}{\guillemetleft{}}% + \DeclareUnicodeCharacter{00AC}{\ensuremath\lnot}% + \DeclareUnicodeCharacter{00AD}{\-}% + \DeclareUnicodeCharacter{00AE}{\registeredsymbol{}}% + \DeclareUnicodeCharacter{00AF}{\={ }}% + % + \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}% + \DeclareUnicodeCharacter{00B1}{\ensuremath\pm}% + \DeclareUnicodeCharacter{00B2}{$^2$}% + \DeclareUnicodeCharacter{00B3}{$^3$}% + \DeclareUnicodeCharacter{00B4}{\'{ }}% + \DeclareUnicodeCharacter{00B5}{$\mu$}% + \DeclareUnicodeCharacter{00B6}{\P}% + \DeclareUnicodeCharacter{00B7}{\ensuremath\cdot}% + \DeclareUnicodeCharacter{00B8}{\cedilla{ }}% + \DeclareUnicodeCharacter{00B9}{$^1$}% + \DeclareUnicodeCharacter{00BA}{\ordm}% + \DeclareUnicodeCharacter{00BB}{\guillemetright{}}% + \DeclareUnicodeCharacter{00BC}{$1\over4$}% + \DeclareUnicodeCharacter{00BD}{$1\over2$}% + \DeclareUnicodeCharacter{00BE}{$3\over4$}% + \DeclareUnicodeCharacter{00BF}{\questiondown}% + % + \DeclareUnicodeCharacter{00C0}{\`A}% + \DeclareUnicodeCharacter{00C1}{\'A}% + \DeclareUnicodeCharacter{00C2}{\^A}% + \DeclareUnicodeCharacter{00C3}{\~A}% + \DeclareUnicodeCharacter{00C4}{\"A}% + \DeclareUnicodeCharacter{00C5}{\AA}% + \DeclareUnicodeCharacter{00C6}{\AE}% + \DeclareUnicodeCharacter{00C7}{\cedilla{C}}% + \DeclareUnicodeCharacter{00C8}{\`E}% + \DeclareUnicodeCharacter{00C9}{\'E}% + \DeclareUnicodeCharacter{00CA}{\^E}% + \DeclareUnicodeCharacter{00CB}{\"E}% + \DeclareUnicodeCharacter{00CC}{\`I}% + \DeclareUnicodeCharacter{00CD}{\'I}% + \DeclareUnicodeCharacter{00CE}{\^I}% + \DeclareUnicodeCharacter{00CF}{\"I}% + % + \DeclareUnicodeCharacter{00D0}{\DH}% + \DeclareUnicodeCharacter{00D1}{\~N}% + \DeclareUnicodeCharacter{00D2}{\`O}% + \DeclareUnicodeCharacter{00D3}{\'O}% + \DeclareUnicodeCharacter{00D4}{\^O}% + \DeclareUnicodeCharacter{00D5}{\~O}% + \DeclareUnicodeCharacter{00D6}{\"O}% + \DeclareUnicodeCharacter{00D7}{\ensuremath\times}% + \DeclareUnicodeCharacter{00D8}{\O}% + \DeclareUnicodeCharacter{00D9}{\`U}% + \DeclareUnicodeCharacter{00DA}{\'U}% + \DeclareUnicodeCharacter{00DB}{\^U}% + \DeclareUnicodeCharacter{00DC}{\"U}% + \DeclareUnicodeCharacter{00DD}{\'Y}% + \DeclareUnicodeCharacter{00DE}{\TH}% + \DeclareUnicodeCharacter{00DF}{\ss}% + % + \DeclareUnicodeCharacter{00E0}{\`a}% + \DeclareUnicodeCharacter{00E1}{\'a}% + \DeclareUnicodeCharacter{00E2}{\^a}% + \DeclareUnicodeCharacter{00E3}{\~a}% + \DeclareUnicodeCharacter{00E4}{\"a}% + \DeclareUnicodeCharacter{00E5}{\aa}% + \DeclareUnicodeCharacter{00E6}{\ae}% + \DeclareUnicodeCharacter{00E7}{\cedilla{c}}% + \DeclareUnicodeCharacter{00E8}{\`e}% + \DeclareUnicodeCharacter{00E9}{\'e}% + \DeclareUnicodeCharacter{00EA}{\^e}% + \DeclareUnicodeCharacter{00EB}{\"e}% + \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}% + \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}% + \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}% + \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}% + % + \DeclareUnicodeCharacter{00F0}{\dh}% + \DeclareUnicodeCharacter{00F1}{\~n}% + \DeclareUnicodeCharacter{00F2}{\`o}% + \DeclareUnicodeCharacter{00F3}{\'o}% + \DeclareUnicodeCharacter{00F4}{\^o}% + \DeclareUnicodeCharacter{00F5}{\~o}% + \DeclareUnicodeCharacter{00F6}{\"o}% + \DeclareUnicodeCharacter{00F7}{\ensuremath\div}% + \DeclareUnicodeCharacter{00F8}{\o}% + \DeclareUnicodeCharacter{00F9}{\`u}% + \DeclareUnicodeCharacter{00FA}{\'u}% + \DeclareUnicodeCharacter{00FB}{\^u}% + \DeclareUnicodeCharacter{00FC}{\"u}% + \DeclareUnicodeCharacter{00FD}{\'y}% + \DeclareUnicodeCharacter{00FE}{\th}% + \DeclareUnicodeCharacter{00FF}{\"y}% + % + \DeclareUnicodeCharacter{0100}{\=A}% + \DeclareUnicodeCharacter{0101}{\=a}% + \DeclareUnicodeCharacter{0102}{\u{A}}% + \DeclareUnicodeCharacter{0103}{\u{a}}% + \DeclareUnicodeCharacter{0104}{\ogonek{A}}% + \DeclareUnicodeCharacter{0105}{\ogonek{a}}% + \DeclareUnicodeCharacter{0106}{\'C}% + \DeclareUnicodeCharacter{0107}{\'c}% + \DeclareUnicodeCharacter{0108}{\^C}% + \DeclareUnicodeCharacter{0109}{\^c}% + \DeclareUnicodeCharacter{010A}{\dotaccent{C}}% + \DeclareUnicodeCharacter{010B}{\dotaccent{c}}% + \DeclareUnicodeCharacter{010C}{\v{C}}% + \DeclareUnicodeCharacter{010D}{\v{c}}% + \DeclareUnicodeCharacter{010E}{\v{D}}% + \DeclareUnicodeCharacter{010F}{d'}% + % + \DeclareUnicodeCharacter{0110}{\DH}% + \DeclareUnicodeCharacter{0111}{\dh}% + \DeclareUnicodeCharacter{0112}{\=E}% + \DeclareUnicodeCharacter{0113}{\=e}% + \DeclareUnicodeCharacter{0114}{\u{E}}% + \DeclareUnicodeCharacter{0115}{\u{e}}% + \DeclareUnicodeCharacter{0116}{\dotaccent{E}}% + \DeclareUnicodeCharacter{0117}{\dotaccent{e}}% + \DeclareUnicodeCharacter{0118}{\ogonek{E}}% + \DeclareUnicodeCharacter{0119}{\ogonek{e}}% + \DeclareUnicodeCharacter{011A}{\v{E}}% + \DeclareUnicodeCharacter{011B}{\v{e}}% + \DeclareUnicodeCharacter{011C}{\^G}% + \DeclareUnicodeCharacter{011D}{\^g}% + \DeclareUnicodeCharacter{011E}{\u{G}}% + \DeclareUnicodeCharacter{011F}{\u{g}}% + % + \DeclareUnicodeCharacter{0120}{\dotaccent{G}}% + \DeclareUnicodeCharacter{0121}{\dotaccent{g}}% + \DeclareUnicodeCharacter{0122}{\cedilla{G}}% + \DeclareUnicodeCharacter{0123}{\cedilla{g}}% + \DeclareUnicodeCharacter{0124}{\^H}% + \DeclareUnicodeCharacter{0125}{\^h}% + \DeclareUnicodeCharacter{0126}{\missingcharmsg{H WITH STROKE}}% + \DeclareUnicodeCharacter{0127}{\missingcharmsg{h WITH STROKE}}% + \DeclareUnicodeCharacter{0128}{\~I}% + \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}% + \DeclareUnicodeCharacter{012A}{\=I}% + \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}% + \DeclareUnicodeCharacter{012C}{\u{I}}% + \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}% + \DeclareUnicodeCharacter{012E}{\ogonek{I}}% + \DeclareUnicodeCharacter{012F}{\ogonek{i}}% + % + \DeclareUnicodeCharacter{0130}{\dotaccent{I}}% + \DeclareUnicodeCharacter{0131}{\dotless{i}}% + \DeclareUnicodeCharacter{0132}{IJ}% + \DeclareUnicodeCharacter{0133}{ij}% + \DeclareUnicodeCharacter{0134}{\^J}% + \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}% + \DeclareUnicodeCharacter{0136}{\cedilla{K}}% + \DeclareUnicodeCharacter{0137}{\cedilla{k}}% + \DeclareUnicodeCharacter{0138}{\ensuremath\kappa}% + \DeclareUnicodeCharacter{0139}{\'L}% + \DeclareUnicodeCharacter{013A}{\'l}% + \DeclareUnicodeCharacter{013B}{\cedilla{L}}% + \DeclareUnicodeCharacter{013C}{\cedilla{l}}% + \DeclareUnicodeCharacter{013D}{L'}% should kern + \DeclareUnicodeCharacter{013E}{l'}% should kern + \DeclareUnicodeCharacter{013F}{L\U{00B7}}% + % + \DeclareUnicodeCharacter{0140}{l\U{00B7}}% + \DeclareUnicodeCharacter{0141}{\L}% + \DeclareUnicodeCharacter{0142}{\l}% + \DeclareUnicodeCharacter{0143}{\'N}% + \DeclareUnicodeCharacter{0144}{\'n}% + \DeclareUnicodeCharacter{0145}{\cedilla{N}}% + \DeclareUnicodeCharacter{0146}{\cedilla{n}}% + \DeclareUnicodeCharacter{0147}{\v{N}}% + \DeclareUnicodeCharacter{0148}{\v{n}}% + \DeclareUnicodeCharacter{0149}{'n}% + \DeclareUnicodeCharacter{014A}{\missingcharmsg{ENG}}% + \DeclareUnicodeCharacter{014B}{\missingcharmsg{eng}}% + \DeclareUnicodeCharacter{014C}{\=O}% + \DeclareUnicodeCharacter{014D}{\=o}% + \DeclareUnicodeCharacter{014E}{\u{O}}% + \DeclareUnicodeCharacter{014F}{\u{o}}% + % + \DeclareUnicodeCharacter{0150}{\H{O}}% + \DeclareUnicodeCharacter{0151}{\H{o}}% + \DeclareUnicodeCharacter{0152}{\OE}% + \DeclareUnicodeCharacter{0153}{\oe}% + \DeclareUnicodeCharacter{0154}{\'R}% + \DeclareUnicodeCharacter{0155}{\'r}% + \DeclareUnicodeCharacter{0156}{\cedilla{R}}% + \DeclareUnicodeCharacter{0157}{\cedilla{r}}% + \DeclareUnicodeCharacter{0158}{\v{R}}% + \DeclareUnicodeCharacter{0159}{\v{r}}% + \DeclareUnicodeCharacter{015A}{\'S}% + \DeclareUnicodeCharacter{015B}{\'s}% + \DeclareUnicodeCharacter{015C}{\^S}% + \DeclareUnicodeCharacter{015D}{\^s}% + \DeclareUnicodeCharacter{015E}{\cedilla{S}}% + \DeclareUnicodeCharacter{015F}{\cedilla{s}}% + % + \DeclareUnicodeCharacter{0160}{\v{S}}% + \DeclareUnicodeCharacter{0161}{\v{s}}% + \DeclareUnicodeCharacter{0162}{\cedilla{T}}% + \DeclareUnicodeCharacter{0163}{\cedilla{t}}% + \DeclareUnicodeCharacter{0164}{\v{T}}% + \DeclareUnicodeCharacter{0165}{\v{t}}% + \DeclareUnicodeCharacter{0166}{\missingcharmsg{H WITH STROKE}}% + \DeclareUnicodeCharacter{0167}{\missingcharmsg{h WITH STROKE}}% + \DeclareUnicodeCharacter{0168}{\~U}% + \DeclareUnicodeCharacter{0169}{\~u}% + \DeclareUnicodeCharacter{016A}{\=U}% + \DeclareUnicodeCharacter{016B}{\=u}% + \DeclareUnicodeCharacter{016C}{\u{U}}% + \DeclareUnicodeCharacter{016D}{\u{u}}% + \DeclareUnicodeCharacter{016E}{\ringaccent{U}}% + \DeclareUnicodeCharacter{016F}{\ringaccent{u}}% + % + \DeclareUnicodeCharacter{0170}{\H{U}}% + \DeclareUnicodeCharacter{0171}{\H{u}}% + \DeclareUnicodeCharacter{0172}{\ogonek{U}}% + \DeclareUnicodeCharacter{0173}{\ogonek{u}}% + \DeclareUnicodeCharacter{0174}{\^W}% + \DeclareUnicodeCharacter{0175}{\^w}% + \DeclareUnicodeCharacter{0176}{\^Y}% + \DeclareUnicodeCharacter{0177}{\^y}% + \DeclareUnicodeCharacter{0178}{\"Y}% + \DeclareUnicodeCharacter{0179}{\'Z}% + \DeclareUnicodeCharacter{017A}{\'z}% + \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}% + \DeclareUnicodeCharacter{017C}{\dotaccent{z}}% + \DeclareUnicodeCharacter{017D}{\v{Z}}% + \DeclareUnicodeCharacter{017E}{\v{z}}% + \DeclareUnicodeCharacter{017F}{\missingcharmsg{LONG S}}% + % + \DeclareUnicodeCharacter{01C4}{D\v{Z}}% + \DeclareUnicodeCharacter{01C5}{D\v{z}}% + \DeclareUnicodeCharacter{01C6}{d\v{z}}% + \DeclareUnicodeCharacter{01C7}{LJ}% + \DeclareUnicodeCharacter{01C8}{Lj}% + \DeclareUnicodeCharacter{01C9}{lj}% + \DeclareUnicodeCharacter{01CA}{NJ}% + \DeclareUnicodeCharacter{01CB}{Nj}% + \DeclareUnicodeCharacter{01CC}{nj}% + \DeclareUnicodeCharacter{01CD}{\v{A}}% + \DeclareUnicodeCharacter{01CE}{\v{a}}% + \DeclareUnicodeCharacter{01CF}{\v{I}}% + % + \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}% + \DeclareUnicodeCharacter{01D1}{\v{O}}% + \DeclareUnicodeCharacter{01D2}{\v{o}}% + \DeclareUnicodeCharacter{01D3}{\v{U}}% + \DeclareUnicodeCharacter{01D4}{\v{u}}% + % + \DeclareUnicodeCharacter{01E2}{\={\AE}}% + \DeclareUnicodeCharacter{01E3}{\={\ae}}% + \DeclareUnicodeCharacter{01E6}{\v{G}}% + \DeclareUnicodeCharacter{01E7}{\v{g}}% + \DeclareUnicodeCharacter{01E8}{\v{K}}% + \DeclareUnicodeCharacter{01E9}{\v{k}}% + % + \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}% + \DeclareUnicodeCharacter{01F1}{DZ}% + \DeclareUnicodeCharacter{01F2}{Dz}% + \DeclareUnicodeCharacter{01F3}{dz}% + \DeclareUnicodeCharacter{01F4}{\'G}% + \DeclareUnicodeCharacter{01F5}{\'g}% + \DeclareUnicodeCharacter{01F8}{\`N}% + \DeclareUnicodeCharacter{01F9}{\`n}% + \DeclareUnicodeCharacter{01FC}{\'{\AE}}% + \DeclareUnicodeCharacter{01FD}{\'{\ae}}% + \DeclareUnicodeCharacter{01FE}{\'{\O}}% + \DeclareUnicodeCharacter{01FF}{\'{\o}}% + % + \DeclareUnicodeCharacter{021E}{\v{H}}% + \DeclareUnicodeCharacter{021F}{\v{h}}% + % + \DeclareUnicodeCharacter{0226}{\dotaccent{A}}% + \DeclareUnicodeCharacter{0227}{\dotaccent{a}}% + \DeclareUnicodeCharacter{0228}{\cedilla{E}}% + \DeclareUnicodeCharacter{0229}{\cedilla{e}}% + \DeclareUnicodeCharacter{022E}{\dotaccent{O}}% + \DeclareUnicodeCharacter{022F}{\dotaccent{o}}% + % + \DeclareUnicodeCharacter{0232}{\=Y}% + \DeclareUnicodeCharacter{0233}{\=y}% + \DeclareUnicodeCharacter{0237}{\dotless{j}}% + % + \DeclareUnicodeCharacter{02DB}{\ogonek{ }}% + % + % Greek letters upper case + \DeclareUnicodeCharacter{0391}{{\it A}}% + \DeclareUnicodeCharacter{0392}{{\it B}}% + \DeclareUnicodeCharacter{0393}{\ensuremath{\mit\Gamma}}% + \DeclareUnicodeCharacter{0394}{\ensuremath{\mit\Delta}}% + \DeclareUnicodeCharacter{0395}{{\it E}}% + \DeclareUnicodeCharacter{0396}{{\it Z}}% + \DeclareUnicodeCharacter{0397}{{\it H}}% + \DeclareUnicodeCharacter{0398}{\ensuremath{\mit\Theta}}% + \DeclareUnicodeCharacter{0399}{{\it I}}% + \DeclareUnicodeCharacter{039A}{{\it K}}% + \DeclareUnicodeCharacter{039B}{\ensuremath{\mit\Lambda}}% + \DeclareUnicodeCharacter{039C}{{\it M}}% + \DeclareUnicodeCharacter{039D}{{\it N}}% + \DeclareUnicodeCharacter{039E}{\ensuremath{\mit\Xi}}% + \DeclareUnicodeCharacter{039F}{{\it O}}% + \DeclareUnicodeCharacter{03A0}{\ensuremath{\mit\Pi}}% + \DeclareUnicodeCharacter{03A1}{{\it P}}% + %\DeclareUnicodeCharacter{03A2}{} % none - corresponds to final sigma + \DeclareUnicodeCharacter{03A3}{\ensuremath{\mit\Sigma}}% + \DeclareUnicodeCharacter{03A4}{{\it T}}% + \DeclareUnicodeCharacter{03A5}{\ensuremath{\mit\Upsilon}}% + \DeclareUnicodeCharacter{03A6}{\ensuremath{\mit\Phi}}% + \DeclareUnicodeCharacter{03A7}{{\it X}}% + \DeclareUnicodeCharacter{03A8}{\ensuremath{\mit\Psi}}% + \DeclareUnicodeCharacter{03A9}{\ensuremath{\mit\Omega}}% + % + % Vowels with accents + \DeclareUnicodeCharacter{0390}{\ensuremath{\ddot{\acute\iota}}}% + \DeclareUnicodeCharacter{03AC}{\ensuremath{\acute\alpha}}% + \DeclareUnicodeCharacter{03AD}{\ensuremath{\acute\epsilon}}% + \DeclareUnicodeCharacter{03AE}{\ensuremath{\acute\eta}}% + \DeclareUnicodeCharacter{03AF}{\ensuremath{\acute\iota}}% + \DeclareUnicodeCharacter{03B0}{\ensuremath{\acute{\ddot\upsilon}}}% + % + % Standalone accent + \DeclareUnicodeCharacter{0384}{\ensuremath{\acute{\ }}}% + % + % Greek letters lower case + \DeclareUnicodeCharacter{03B1}{\ensuremath\alpha}% + \DeclareUnicodeCharacter{03B2}{\ensuremath\beta}% + \DeclareUnicodeCharacter{03B3}{\ensuremath\gamma}% + \DeclareUnicodeCharacter{03B4}{\ensuremath\delta}% + \DeclareUnicodeCharacter{03B5}{\ensuremath\epsilon}% + \DeclareUnicodeCharacter{03B6}{\ensuremath\zeta}% + \DeclareUnicodeCharacter{03B7}{\ensuremath\eta}% + \DeclareUnicodeCharacter{03B8}{\ensuremath\theta}% + \DeclareUnicodeCharacter{03B9}{\ensuremath\iota}% + \DeclareUnicodeCharacter{03BA}{\ensuremath\kappa}% + \DeclareUnicodeCharacter{03BB}{\ensuremath\lambda}% + \DeclareUnicodeCharacter{03BC}{\ensuremath\mu}% + \DeclareUnicodeCharacter{03BD}{\ensuremath\nu}% + \DeclareUnicodeCharacter{03BE}{\ensuremath\xi}% + \DeclareUnicodeCharacter{03BF}{{\it o}}% omicron + \DeclareUnicodeCharacter{03C0}{\ensuremath\pi}% + \DeclareUnicodeCharacter{03C1}{\ensuremath\rho}% + \DeclareUnicodeCharacter{03C2}{\ensuremath\varsigma}% + \DeclareUnicodeCharacter{03C3}{\ensuremath\sigma}% + \DeclareUnicodeCharacter{03C4}{\ensuremath\tau}% + \DeclareUnicodeCharacter{03C5}{\ensuremath\upsilon}% + \DeclareUnicodeCharacter{03C6}{\ensuremath\phi}% + \DeclareUnicodeCharacter{03C7}{\ensuremath\chi}% + \DeclareUnicodeCharacter{03C8}{\ensuremath\psi}% + \DeclareUnicodeCharacter{03C9}{\ensuremath\omega}% + % + % More Greek vowels with accents + \DeclareUnicodeCharacter{03CA}{\ensuremath{\ddot\iota}}% + \DeclareUnicodeCharacter{03CB}{\ensuremath{\ddot\upsilon}}% + \DeclareUnicodeCharacter{03CC}{\ensuremath{\acute o}}% + \DeclareUnicodeCharacter{03CD}{\ensuremath{\acute\upsilon}}% + \DeclareUnicodeCharacter{03CE}{\ensuremath{\acute\omega}}% + % + % Variant Greek letters + \DeclareUnicodeCharacter{03D1}{\ensuremath\vartheta}% + \DeclareUnicodeCharacter{03D6}{\ensuremath\varpi}% + \DeclareUnicodeCharacter{03F1}{\ensuremath\varrho}% + % + \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}% + \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}% + \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}% + \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}% + \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}% + \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}% + \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}% + \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}% + \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}% + \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}% + \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}% + \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}% + % + \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}% + \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}% + % + \DeclareUnicodeCharacter{1E20}{\=G}% + \DeclareUnicodeCharacter{1E21}{\=g}% + \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}% + \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}% + \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}% + \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}% + \DeclareUnicodeCharacter{1E26}{\"H}% + \DeclareUnicodeCharacter{1E27}{\"h}% + % + \DeclareUnicodeCharacter{1E30}{\'K}% + \DeclareUnicodeCharacter{1E31}{\'k}% + \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}% + \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}% + \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}% + \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}% + \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}% + \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}% + \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}% + \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}% + \DeclareUnicodeCharacter{1E3E}{\'M}% + \DeclareUnicodeCharacter{1E3F}{\'m}% + % + \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}% + \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}% + \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}% + \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}% + \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}% + \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}% + \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}% + \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}% + \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}% + \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}% + % + \DeclareUnicodeCharacter{1E54}{\'P}% + \DeclareUnicodeCharacter{1E55}{\'p}% + \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}% + \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}% + \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}% + \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}% + \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}% + \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}% + \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}% + \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}% + % + \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}% + \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}% + \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}% + \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}% + \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}% + \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}% + \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}% + \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}% + \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}% + \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}% + % + \DeclareUnicodeCharacter{1E7C}{\~V}% + \DeclareUnicodeCharacter{1E7D}{\~v}% + \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}% + \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}% + % + \DeclareUnicodeCharacter{1E80}{\`W}% + \DeclareUnicodeCharacter{1E81}{\`w}% + \DeclareUnicodeCharacter{1E82}{\'W}% + \DeclareUnicodeCharacter{1E83}{\'w}% + \DeclareUnicodeCharacter{1E84}{\"W}% + \DeclareUnicodeCharacter{1E85}{\"w}% + \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}% + \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}% + \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}% + \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}% + \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}% + \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}% + \DeclareUnicodeCharacter{1E8C}{\"X}% + \DeclareUnicodeCharacter{1E8D}{\"x}% + \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}% + \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}% + % + \DeclareUnicodeCharacter{1E90}{\^Z}% + \DeclareUnicodeCharacter{1E91}{\^z}% + \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}% + \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}% + \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}% + \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}% + \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}% + \DeclareUnicodeCharacter{1E97}{\"t}% + \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}% + \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}% + % + \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}% + \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}% + % + \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}% + \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}% + \DeclareUnicodeCharacter{1EBC}{\~E}% + \DeclareUnicodeCharacter{1EBD}{\~e}% + % + \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}% + \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}% + \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}% + \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}% + % + \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}% + \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}% + % + \DeclareUnicodeCharacter{1EF2}{\`Y}% + \DeclareUnicodeCharacter{1EF3}{\`y}% + \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}% + % + \DeclareUnicodeCharacter{1EF8}{\~Y}% + \DeclareUnicodeCharacter{1EF9}{\~y}% + % + % Punctuation + \DeclareUnicodeCharacter{2013}{--}% + \DeclareUnicodeCharacter{2014}{---}% + \DeclareUnicodeCharacter{2018}{\quoteleft{}}% + \DeclareUnicodeCharacter{2019}{\quoteright{}}% + \DeclareUnicodeCharacter{201A}{\quotesinglbase{}}% + \DeclareUnicodeCharacter{201C}{\quotedblleft{}}% + \DeclareUnicodeCharacter{201D}{\quotedblright{}}% + \DeclareUnicodeCharacter{201E}{\quotedblbase{}}% + \DeclareUnicodeCharacter{2020}{\ensuremath\dagger}% + \DeclareUnicodeCharacter{2021}{\ensuremath\ddagger}% + \DeclareUnicodeCharacter{2022}{\bullet{}}% + \DeclareUnicodeCharacter{202F}{\thinspace}% + \DeclareUnicodeCharacter{2026}{\dots{}}% + \DeclareUnicodeCharacter{2039}{\guilsinglleft{}}% + \DeclareUnicodeCharacter{203A}{\guilsinglright{}}% + % + \DeclareUnicodeCharacter{20AC}{\euro{}}% + % + \DeclareUnicodeCharacter{2192}{\expansion{}}% + \DeclareUnicodeCharacter{21D2}{\result{}}% + % + % Mathematical symbols + \DeclareUnicodeCharacter{2200}{\ensuremath\forall}% + \DeclareUnicodeCharacter{2203}{\ensuremath\exists}% + \DeclareUnicodeCharacter{2208}{\ensuremath\in}% + \DeclareUnicodeCharacter{2212}{\minus{}}% + \DeclareUnicodeCharacter{2217}{\ast}% + \DeclareUnicodeCharacter{221E}{\ensuremath\infty}% + \DeclareUnicodeCharacter{2225}{\ensuremath\parallel}% + \DeclareUnicodeCharacter{2227}{\ensuremath\wedge}% + \DeclareUnicodeCharacter{2229}{\ensuremath\cap}% + \DeclareUnicodeCharacter{2261}{\equiv{}}% + \DeclareUnicodeCharacter{2264}{\ensuremath\leq}% + \DeclareUnicodeCharacter{2265}{\ensuremath\geq}% + \DeclareUnicodeCharacter{2282}{\ensuremath\subset}% + \DeclareUnicodeCharacter{2287}{\ensuremath\supseteq}% + % + \DeclareUnicodeCharacter{2016}{\ensuremath\Vert}% + \DeclareUnicodeCharacter{2032}{\ensuremath\prime}% + \DeclareUnicodeCharacter{210F}{\ensuremath\hbar}% + \DeclareUnicodeCharacter{2111}{\ensuremath\Im}% + \DeclareUnicodeCharacter{2113}{\ensuremath\ell}% + \DeclareUnicodeCharacter{2118}{\ensuremath\wp}% + \DeclareUnicodeCharacter{211C}{\ensuremath\Re}% + \DeclareUnicodeCharacter{2127}{\ensuremath\mho}% + \DeclareUnicodeCharacter{2135}{\ensuremath\aleph}% + \DeclareUnicodeCharacter{2190}{\ensuremath\leftarrow}% + \DeclareUnicodeCharacter{2191}{\ensuremath\uparrow}% + \DeclareUnicodeCharacter{2193}{\ensuremath\downarrow}% + \DeclareUnicodeCharacter{2194}{\ensuremath\leftrightarrow}% + \DeclareUnicodeCharacter{2195}{\ensuremath\updownarrow}% + \DeclareUnicodeCharacter{2196}{\ensuremath\nwarrow}% + \DeclareUnicodeCharacter{2197}{\ensuremath\nearrow}% + \DeclareUnicodeCharacter{2198}{\ensuremath\searrow}% + \DeclareUnicodeCharacter{2199}{\ensuremath\swarrow}% + \DeclareUnicodeCharacter{21A6}{\ensuremath\mapsto}% + \DeclareUnicodeCharacter{21A9}{\ensuremath\hookleftarrow}% + \DeclareUnicodeCharacter{21AA}{\ensuremath\hookrightarrow}% + \DeclareUnicodeCharacter{21BC}{\ensuremath\leftharpoonup}% + \DeclareUnicodeCharacter{21BD}{\ensuremath\leftharpoondown}% + \DeclareUnicodeCharacter{21BE}{\ensuremath\upharpoonright}% + \DeclareUnicodeCharacter{21C0}{\ensuremath\rightharpoonup}% + \DeclareUnicodeCharacter{21C1}{\ensuremath\rightharpoondown}% + \DeclareUnicodeCharacter{21CC}{\ensuremath\rightleftharpoons}% + \DeclareUnicodeCharacter{21D0}{\ensuremath\Leftarrow}% + \DeclareUnicodeCharacter{21D1}{\ensuremath\Uparrow}% + \DeclareUnicodeCharacter{21D3}{\ensuremath\Downarrow}% + \DeclareUnicodeCharacter{21D4}{\ensuremath\Leftrightarrow}% + \DeclareUnicodeCharacter{21D5}{\ensuremath\Updownarrow}% + \DeclareUnicodeCharacter{21DD}{\ensuremath\leadsto}% + \DeclareUnicodeCharacter{2201}{\ensuremath\complement}% + \DeclareUnicodeCharacter{2202}{\ensuremath\partial}% + \DeclareUnicodeCharacter{2205}{\ensuremath\emptyset}% + \DeclareUnicodeCharacter{2207}{\ensuremath\nabla}% + \DeclareUnicodeCharacter{2209}{\ensuremath\notin}% + \DeclareUnicodeCharacter{220B}{\ensuremath\owns}% + \DeclareUnicodeCharacter{220F}{\ensuremath\prod}% + \DeclareUnicodeCharacter{2210}{\ensuremath\coprod}% + \DeclareUnicodeCharacter{2211}{\ensuremath\sum}% + \DeclareUnicodeCharacter{2213}{\ensuremath\mp}% + \DeclareUnicodeCharacter{2218}{\ensuremath\circ}% + \DeclareUnicodeCharacter{221A}{\ensuremath\surd}% + \DeclareUnicodeCharacter{221D}{\ensuremath\propto}% + \DeclareUnicodeCharacter{2220}{\ensuremath\angle}% + \DeclareUnicodeCharacter{2223}{\ensuremath\mid}% + \DeclareUnicodeCharacter{2228}{\ensuremath\vee}% + \DeclareUnicodeCharacter{222A}{\ensuremath\cup}% + \DeclareUnicodeCharacter{222B}{\ensuremath\smallint}% + \DeclareUnicodeCharacter{222E}{\ensuremath\oint}% + \DeclareUnicodeCharacter{223C}{\ensuremath\sim}% + \DeclareUnicodeCharacter{2240}{\ensuremath\wr}% + \DeclareUnicodeCharacter{2243}{\ensuremath\simeq}% + \DeclareUnicodeCharacter{2245}{\ensuremath\cong}% + \DeclareUnicodeCharacter{2248}{\ensuremath\approx}% + \DeclareUnicodeCharacter{224D}{\ensuremath\asymp}% + \DeclareUnicodeCharacter{2250}{\ensuremath\doteq}% + \DeclareUnicodeCharacter{2260}{\ensuremath\neq}% + \DeclareUnicodeCharacter{226A}{\ensuremath\ll}% + \DeclareUnicodeCharacter{226B}{\ensuremath\gg}% + \DeclareUnicodeCharacter{227A}{\ensuremath\prec}% + \DeclareUnicodeCharacter{227B}{\ensuremath\succ}% + \DeclareUnicodeCharacter{2283}{\ensuremath\supset}% + \DeclareUnicodeCharacter{2286}{\ensuremath\subseteq}% + \DeclareUnicodeCharacter{228E}{\ensuremath\uplus}% + \DeclareUnicodeCharacter{228F}{\ensuremath\sqsubset}% + \DeclareUnicodeCharacter{2290}{\ensuremath\sqsupset}% + \DeclareUnicodeCharacter{2291}{\ensuremath\sqsubseteq}% + \DeclareUnicodeCharacter{2292}{\ensuremath\sqsupseteq}% + \DeclareUnicodeCharacter{2293}{\ensuremath\sqcap}% + \DeclareUnicodeCharacter{2294}{\ensuremath\sqcup}% + \DeclareUnicodeCharacter{2295}{\ensuremath\oplus}% + \DeclareUnicodeCharacter{2296}{\ensuremath\ominus}% + \DeclareUnicodeCharacter{2297}{\ensuremath\otimes}% + \DeclareUnicodeCharacter{2298}{\ensuremath\oslash}% + \DeclareUnicodeCharacter{2299}{\ensuremath\odot}% + \DeclareUnicodeCharacter{22A2}{\ensuremath\vdash}% + \DeclareUnicodeCharacter{22A3}{\ensuremath\dashv}% + \DeclareUnicodeCharacter{22A4}{\ensuremath\ptextop}% + \DeclareUnicodeCharacter{22A5}{\ensuremath\bot}% + \DeclareUnicodeCharacter{22A8}{\ensuremath\models}% + \DeclareUnicodeCharacter{22B4}{\ensuremath\unlhd}% + \DeclareUnicodeCharacter{22B5}{\ensuremath\unrhd}% + \DeclareUnicodeCharacter{22C0}{\ensuremath\bigwedge}% + \DeclareUnicodeCharacter{22C1}{\ensuremath\bigvee}% + \DeclareUnicodeCharacter{22C2}{\ensuremath\bigcap}% + \DeclareUnicodeCharacter{22C3}{\ensuremath\bigcup}% + \DeclareUnicodeCharacter{22C4}{\ensuremath\diamond}% + \DeclareUnicodeCharacter{22C5}{\ensuremath\cdot}% + \DeclareUnicodeCharacter{22C6}{\ensuremath\star}% + \DeclareUnicodeCharacter{22C8}{\ensuremath\bowtie}% + \DeclareUnicodeCharacter{2308}{\ensuremath\lceil}% + \DeclareUnicodeCharacter{2309}{\ensuremath\rceil}% + \DeclareUnicodeCharacter{230A}{\ensuremath\lfloor}% + \DeclareUnicodeCharacter{230B}{\ensuremath\rfloor}% + \DeclareUnicodeCharacter{2322}{\ensuremath\frown}% + \DeclareUnicodeCharacter{2323}{\ensuremath\smile}% + % + \DeclareUnicodeCharacter{25A1}{\ensuremath\Box}% + \DeclareUnicodeCharacter{25B3}{\ensuremath\triangle}% + \DeclareUnicodeCharacter{25B7}{\ensuremath\triangleright}% + \DeclareUnicodeCharacter{25BD}{\ensuremath\bigtriangledown}% + \DeclareUnicodeCharacter{25C1}{\ensuremath\triangleleft}% + \DeclareUnicodeCharacter{25C7}{\ensuremath\Diamond}% + \DeclareUnicodeCharacter{2660}{\ensuremath\spadesuit}% + \DeclareUnicodeCharacter{2661}{\ensuremath\heartsuit}% + \DeclareUnicodeCharacter{2662}{\ensuremath\diamondsuit}% + \DeclareUnicodeCharacter{2663}{\ensuremath\clubsuit}% + \DeclareUnicodeCharacter{266D}{\ensuremath\flat}% + \DeclareUnicodeCharacter{266E}{\ensuremath\natural}% + \DeclareUnicodeCharacter{266F}{\ensuremath\sharp}% + \DeclareUnicodeCharacter{26AA}{\ensuremath\bigcirc}% + \DeclareUnicodeCharacter{27B9}{\ensuremath\rangle}% + \DeclareUnicodeCharacter{27C2}{\ensuremath\perp}% + \DeclareUnicodeCharacter{27E8}{\ensuremath\langle}% + \DeclareUnicodeCharacter{27F5}{\ensuremath\longleftarrow}% + \DeclareUnicodeCharacter{27F6}{\ensuremath\longrightarrow}% + \DeclareUnicodeCharacter{27F7}{\ensuremath\longleftrightarrow}% + \DeclareUnicodeCharacter{27FC}{\ensuremath\longmapsto}% + \DeclareUnicodeCharacter{29F5}{\ensuremath\setminus}% + \DeclareUnicodeCharacter{2A00}{\ensuremath\bigodot}% + \DeclareUnicodeCharacter{2A01}{\ensuremath\bigoplus}% + \DeclareUnicodeCharacter{2A02}{\ensuremath\bigotimes}% + \DeclareUnicodeCharacter{2A04}{\ensuremath\biguplus}% + \DeclareUnicodeCharacter{2A06}{\ensuremath\bigsqcup}% + \DeclareUnicodeCharacter{2A1D}{\ensuremath\Join}% + \DeclareUnicodeCharacter{2A3F}{\ensuremath\amalg}% + \DeclareUnicodeCharacter{2AAF}{\ensuremath\preceq}% + \DeclareUnicodeCharacter{2AB0}{\ensuremath\succeq}% + % + \global\mathchardef\checkmark="1370% actually the square root sign + \DeclareUnicodeCharacter{2713}{\ensuremath\checkmark}% +}% end of \unicodechardefs + +% UTF-8 byte sequence (pdfTeX) definitions (replacing and @U command) +% It makes the setting that replace UTF-8 byte sequence. +\def\utfeightchardefs{% + \let\DeclareUnicodeCharacter\DeclareUnicodeCharacterUTFviii + \unicodechardefs +} + +% Whether the active definitions of non-ASCII characters expand to +% non-active tokens with the same character code. This is used to +% write characters literally, instead of using active definitions for +% printing the correct glyphs. +\newif\ifpassthroughchars +\passthroughcharsfalse + +% For native Unicode handling (XeTeX and LuaTeX), +% provide a definition macro to replace/pass-through a Unicode character +% +\def\DeclareUnicodeCharacterNative#1#2{% + \catcode"#1=\active + \def\dodeclareunicodecharacternative##1##2##3{% + \begingroup + \uccode`\~="##2\relax + \uppercase{\gdef~}{% + \ifpassthroughchars + ##1% + \else + ##3% + \fi + } + \endgroup + } + \begingroup + \uccode`\.="#1\relax + \uppercase{\def\UTFNativeTmp{.}}% + \expandafter\dodeclareunicodecharacternative\UTFNativeTmp{#1}{#2}% + \endgroup +} + +% Native Unicode handling (XeTeX and LuaTeX) character replacing definition. +% It activates the setting that replaces Unicode characters. +\def\nativeunicodechardefs{% + \let\DeclareUnicodeCharacter\DeclareUnicodeCharacterNative + \unicodechardefs +} + +% For native Unicode handling (XeTeX and LuaTeX), +% make the character token expand +% to the sequences given in \unicodechardefs for printing. +\def\DeclareUnicodeCharacterNativeAtU#1#2{% + \def\UTFAtUTmp{#2} + \expandafter\globallet\csname uni:#1\endcsname \UTFAtUTmp +} + +% @U command definitions for native Unicode handling (XeTeX and LuaTeX). +\def\nativeunicodechardefsatu{% + \let\DeclareUnicodeCharacter\DeclareUnicodeCharacterNativeAtU + \unicodechardefs +} + +% US-ASCII character definitions. +\def\asciichardefs{% nothing need be done + \relax +} + +% define all Unicode characters we know about, for the sake of @U. +\iftxinativeunicodecapable + \nativeunicodechardefsatu +\else + \utfeightchardefs +\fi + + +% Make non-ASCII characters printable again for compatibility with +% existing Texinfo documents that may use them, even without declaring a +% document encoding. +% +\setnonasciicharscatcode \other + + +\message{formatting,} + +\newdimen\defaultparindent \defaultparindent = 15pt + +\chapheadingskip = 15pt plus 4pt minus 2pt +\secheadingskip = 12pt plus 3pt minus 2pt +\subsecheadingskip = 9pt plus 2pt minus 2pt + +% Prevent underfull vbox error messages. +\vbadness = 10000 + +% Don't be very finicky about underfull hboxes, either. +\hbadness = 6666 + +% Following George Bush, get rid of widows and orphans. +\widowpenalty=10000 +\clubpenalty=10000 + +% Use TeX 3.0's \emergencystretch to help line breaking, but if we're +% using an old version of TeX, don't do anything. We want the amount of +% stretch added to depend on the line length, hence the dependence on +% \hsize. We call this whenever the paper size is set. +% +\def\setemergencystretch{% + \ifx\emergencystretch\thisisundefined + % Allow us to assign to \emergencystretch anyway. + \def\emergencystretch{\dimen0}% + \else + \emergencystretch = .15\hsize + \fi +} + +% Parameters in order: 1) textheight; 2) textwidth; +% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip; +% 7) physical page height; 8) physical page width. +% +% We also call \setleading{\textleading}, so the caller should define +% \textleading. The caller should also set \parskip. +% +\def\internalpagesizes#1#2#3#4#5#6#7#8{% + \voffset = #3\relax + \topskip = #6\relax + \splittopskip = \topskip + % + \vsize = #1\relax + \advance\vsize by \topskip + \outervsize = \vsize + \advance\outervsize by 2\topandbottommargin + \txipageheight = \vsize + % + \hsize = #2\relax + \outerhsize = \hsize + \advance\outerhsize by 0.5in + \txipagewidth = \hsize + % + \normaloffset = #4\relax + \bindingoffset = #5\relax + % + \ifpdf + \pdfpageheight #7\relax + \pdfpagewidth #8\relax + % if we don't reset these, they will remain at "1 true in" of + % whatever layout pdftex was dumped with. + \pdfhorigin = 1 true in + \pdfvorigin = 1 true in + \else + \ifx\XeTeXrevision\thisisundefined + \special{papersize=#8,#7}% + \else + \pdfpageheight #7\relax + \pdfpagewidth #8\relax + % XeTeX does not have \pdfhorigin and \pdfvorigin. + \fi + \fi + % + \setleading{\textleading} + % + \parindent = \defaultparindent + \setemergencystretch +} + +% @letterpaper (the default). +\def\letterpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \textleading = 13.2pt + % + % If page is nothing but text, make it come out even. + \internalpagesizes{607.2pt}{6in}% that's 46 lines + {\voffset}{.25in}% + {\bindingoffset}{36pt}% + {11in}{8.5in}% +}} + +% Use @smallbook to reset parameters for 7x9.25 trim size. +\def\smallbook{{\globaldefs = 1 + \parskip = 2pt plus 1pt + \textleading = 12pt + % + \internalpagesizes{7.5in}{5in}% + {-.2in}{0in}% + {\bindingoffset}{16pt}% + {9.25in}{7in}% + % + \lispnarrowing = 0.3in + \tolerance = 700 + \contentsrightmargin = 0pt + \defbodyindent = .5cm +}} + +% Use @smallerbook to reset parameters for 6x9 trim size. +% (Just testing, parameters still in flux.) +\def\smallerbook{{\globaldefs = 1 + \parskip = 1.5pt plus 1pt + \textleading = 12pt + % + \internalpagesizes{7.4in}{4.8in}% + {-.2in}{-.4in}% + {0pt}{14pt}% + {9in}{6in}% + % + \lispnarrowing = 0.25in + \tolerance = 700 + \contentsrightmargin = 0pt + \defbodyindent = .4cm +}} + +% Use @afourpaper to print on European A4 paper. +\def\afourpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \textleading = 13.2pt + % + % Double-side printing via postscript on Laserjet 4050 + % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm. + % To change the settings for a different printer or situation, adjust + % \normaloffset until the front-side and back-side texts align. Then + % do the same for \bindingoffset. You can set these for testing in + % your texinfo source file like this: + % @tex + % \global\normaloffset = -6mm + % \global\bindingoffset = 10mm + % @end tex + \internalpagesizes{673.2pt}{160mm}% that's 51 lines + {\voffset}{\hoffset}% + {\bindingoffset}{44pt}% + {297mm}{210mm}% + % + \tolerance = 700 + \contentsrightmargin = 0pt + \defbodyindent = 5mm +}} + +% Use @afivepaper to print on European A5 paper. +% From romildo@urano.iceb.ufop.br, 2 July 2000. +% He also recommends making @example and @lisp be small. +\def\afivepaper{{\globaldefs = 1 + \parskip = 2pt plus 1pt minus 0.1pt + \textleading = 12.5pt + % + \internalpagesizes{160mm}{120mm}% + {\voffset}{\hoffset}% + {\bindingoffset}{8pt}% + {210mm}{148mm}% + % + \lispnarrowing = 0.2in + \tolerance = 800 + \contentsrightmargin = 0pt + \defbodyindent = 2mm + \tableindent = 12mm +}} + +% A specific text layout, 24x15cm overall, intended for A4 paper. +\def\afourlatex{{\globaldefs = 1 + \afourpaper + \internalpagesizes{237mm}{150mm}% + {\voffset}{4.6mm}% + {\bindingoffset}{7mm}% + {297mm}{210mm}% + % + % Must explicitly reset to 0 because we call \afourpaper. + \globaldefs = 0 +}} + +% Use @afourwide to print on A4 paper in landscape format. +\def\afourwide{{\globaldefs = 1 + \afourpaper + \internalpagesizes{241mm}{165mm}% + {\voffset}{-2.95mm}% + {\bindingoffset}{7mm}% + {297mm}{210mm}% + \globaldefs = 0 +}} + +% @pagesizes TEXTHEIGHT[,TEXTWIDTH] +% Perhaps we should allow setting the margins, \topskip, \parskip, +% and/or leading, also. Or perhaps we should compute them somehow. +% +\parseargdef\pagesizes{\pagesizesyyy #1,,\finish} +\def\pagesizesyyy#1,#2,#3\finish{{% + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi + \globaldefs = 1 + % + \parskip = 3pt plus 2pt minus 1pt + \setleading{\textleading}% + % + \dimen0 = #1\relax + \advance\dimen0 by \voffset + % + \dimen2 = \hsize + \advance\dimen2 by \normaloffset + % + \internalpagesizes{#1}{\hsize}% + {\voffset}{\normaloffset}% + {\bindingoffset}{44pt}% + {\dimen0}{\dimen2}% +}} + +% Set default to letter. +% +\letterpaper + +% Default value of \hfuzz, for suppressing warnings about overfull hboxes. +\hfuzz = 1pt + + +\message{and turning on texinfo input format.} + +\def^^L{\par} % remove \outer, so ^L can appear in an @comment + +% DEL is a comment character, in case @c does not suffice. +\catcode`\^^? = 14 + +% Define macros to output various characters with catcode for normal text. +\catcode`\"=\other \def\normaldoublequote{"} +\catcode`\$=\other \def\normaldollar{$}%$ font-lock fix +\catcode`\+=\other \def\normalplus{+} +\catcode`\<=\other \def\normalless{<} +\catcode`\>=\other \def\normalgreater{>} +\catcode`\^=\other \def\normalcaret{^} +\catcode`\_=\other \def\normalunderscore{_} +\catcode`\|=\other \def\normalverticalbar{|} +\catcode`\~=\other \def\normaltilde{~} + +% This macro is used to make a character print one way in \tt +% (where it can probably be output as-is), and another way in other fonts, +% where something hairier probably needs to be done. +% +% #1 is what to print if we are indeed using \tt; #2 is what to print +% otherwise. Since all the Computer Modern typewriter fonts have zero +% interword stretch (and shrink), and it is reasonable to expect all +% typewriter fonts to have this, we can check that font parameter. +% +\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} + +% Same as above, but check for italic font. Actually this also catches +% non-italic slanted fonts since it is impossible to distinguish them from +% italic fonts. But since this is only used by $ and it uses \sl anyway +% this is not a problem. +\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} + +% Set catcodes for Texinfo file + +% Active characters for printing the wanted glyph. +% Most of these we simply print from the \tt font, but for some, we can +% use math or other variants that look better in normal text. +% +\catcode`\"=\active +\def\activedoublequote{{\tt\char34}} +\let"=\activedoublequote +\catcode`\~=\active \def\activetilde{{\tt\char126}} \let~ = \activetilde +\chardef\hatchar=`\^ +\catcode`\^=\active \def\activehat{{\tt \hatchar}} \let^ = \activehat + +\catcode`\_=\active +\def_{\ifusingtt\normalunderscore\_} +\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } +\let\realunder=_ + +\catcode`\|=\active \def|{{\tt\char124}} + +\chardef \less=`\< +\catcode`\<=\active \def\activeless{{\tt \less}}\let< = \activeless +\chardef \gtr=`\> +\catcode`\>=\active \def\activegtr{{\tt \gtr}}\let> = \activegtr +\catcode`\+=\active \def+{{\tt \char 43}} +\catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix +\catcode`\-=\active \let-=\normaldash + + +% used for headline/footline in the output routine, in case the page +% breaks in the middle of an @tex block. +\def\texinfochars{% + \let< = \activeless + \let> = \activegtr + \let~ = \activetilde + \let^ = \activehat + \markupsetuplqdefault \markupsetuprqdefault + \let\b = \strong + \let\i = \smartitalic + % in principle, all other definitions in \tex have to be undone too. +} + +% Used sometimes to turn off (effectively) the active characters even after +% parsing them. +\def\turnoffactive{% + \normalturnoffactive + \otherbackslash +} + +\catcode`\@=0 + +% \backslashcurfont outputs one backslash character in current font, +% as in \char`\\. +\global\chardef\backslashcurfont=`\\ +\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work + +% \realbackslash is an actual character `\' with catcode other, and +% \doublebackslash is two of them (for the pdf outlines). +{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}} + +% In Texinfo, backslash is an active character; it prints the backslash +% in fixed width font. +\catcode`\\=\active % @ for escape char from now on. + +% Print a typewriter backslash. For math mode, we can't simply use +% \backslashcurfont: the story here is that in math mode, the \char +% of \backslashcurfont ends up printing the roman \ from the math symbol +% font (because \char in math mode uses the \mathcode, and plain.tex +% sets \mathcode`\\="026E). Hence we use an explicit \mathchar, +% which is the decimal equivalent of "715c (class 7, e.g., use \fam; +% ignored family value; char position "5C). We can't use " for the +% usual hex value because it has already been made active. + +@def@ttbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}} +@let@backslashchar = @ttbackslash % @backslashchar{} is for user documents. + +% \rawbackslash defines an active \ to do \backslashcurfont. +% \otherbackslash defines an active \ to be a literal `\' character with +% catcode other. We switch back and forth between these. +@gdef@rawbackslash{@let\=@backslashcurfont} +@gdef@otherbackslash{@let\=@realbackslash} + +% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of +% the literal character `\'. +% +{@catcode`- = @active + @gdef@normalturnoffactive{% + @passthroughcharstrue + @let-=@normaldash + @let"=@normaldoublequote + @let$=@normaldollar %$ font-lock fix + @let+=@normalplus + @let<=@normalless + @let>=@normalgreater + @let^=@normalcaret + @let_=@normalunderscore + @let|=@normalverticalbar + @let~=@normaltilde + @let\=@ttbackslash + @markupsetuplqdefault + @markupsetuprqdefault + @unsepspaces + } +} + +% If a .fmt file is being used, characters that might appear in a file +% name cannot be active until we have parsed the command line. +% So turn them off again, and have @fixbackslash turn them back on. +@catcode`+=@other @catcode`@_=@other + +% \enablebackslashhack - allow file to begin `\input texinfo' +% +% If a .fmt file is being used, we don't want the `\input texinfo' to show up. +% That is what \eatinput is for; after that, the `\' should revert to printing +% a backslash. +% If the file did not have a `\input texinfo', then it is turned off after +% the first line; otherwise the first `\' in the file would cause an error. +% This is used on the very last line of this file, texinfo.tex. +% We also use @c to call @fixbackslash, in case ends of lines are hidden. +{ +@catcode`@^=7 +@catcode`@^^M=13@gdef@enablebackslashhack{% + @global@let\ = @eatinput% + @catcode`@^^M=13% + @def@c{@fixbackslash@c}% + % Definition for the newline at the end of this file. + @def ^^M{@let^^M@secondlinenl}% + % Definition for a newline in the main Texinfo file. + @gdef @secondlinenl{@fixbackslash}% + % In case the first line has a whole-line command on it + @let@originalparsearg@parsearg + @def@parsearg{@fixbackslash@originalparsearg} +}} + +{@catcode`@^=7 @catcode`@^^M=13% +@gdef@eatinput input texinfo#1^^M{@fixbackslash}} + +% Emergency active definition of newline, in case an active newline token +% appears by mistake. +{@catcode`@^=7 @catcode13=13% +@gdef@enableemergencynewline{% + @gdef^^M{% + @par% + %@par% +}}} + + +@gdef@fixbackslash{% + @ifx\@eatinput @let\ = @ttbackslash @fi + @catcode13=5 % regular end of line + @enableemergencynewline + @let@c=@texinfoc + @let@parsearg@originalparsearg + % Also turn back on active characters that might appear in the input + % file name, in case not using a pre-dumped format. + @catcode`+=@active + @catcode`@_=@active + % + % If texinfo.cnf is present on the system, read it. + % Useful for site-wide @afourpaper, etc. This macro, @fixbackslash, gets + % called at the beginning of every Texinfo file. Not opening texinfo.cnf + % directly in this file, texinfo.tex, makes it possible to make a format + % file for Texinfo. + % + @openin 1 texinfo.cnf + @ifeof 1 @else @input texinfo.cnf @fi + @closein 1 +} + + +% Say @foo, not \foo, in error messages. +@escapechar = `@@ + +% These (along with & and #) are made active for url-breaking, so need +% active definitions as the normal characters. +@def@normaldot{.} +@def@normalquest{?} +@def@normalslash{/} + +% These look ok in all fonts, so just make them not special. +% @hashchar{} gets its own user-level command, because of #line. +@catcode`@& = @other @def@normalamp{&} +@catcode`@# = @other @def@normalhash{#} +@catcode`@% = @other @def@normalpercent{%} + +@let @hashchar = @normalhash + +@c Finally, make ` and ' active, so that txicodequoteundirected and +@c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we +@c don't make ` and ' active, @code will not get them as active chars. +@c Do this last of all since we use ` in the previous @catcode assignments. +@catcode`@'=@active +@catcode`@`=@active +@markupsetuplqdefault +@markupsetuprqdefault + +@c Local variables: +@c eval: (add-hook 'write-file-hooks 'time-stamp) +@c page-delimiter: "^\\\\message\\|emacs-page" +@c time-stamp-start: "def\\\\texinfoversion{" +@c time-stamp-format: "%:y-%02m-%02d.%02H" +@c time-stamp-end: "}" +@c End: + +@c vim:sw=2: + +@enablebackslashhack diff -Nru ddskk-16.2/doc/txi-ja.tex ddskk-16.2+0.20190423/doc/txi-ja.tex --- ddskk-16.2/doc/txi-ja.tex 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/doc/txi-ja.tex 2019-04-23 12:49:58.000000000 +0000 @@ -1,13 +1,12 @@ -% txi-ja.tex -- adaptation to Japanese for texinfo.tex. -% This is read when a source document says @documentlanguage ja -% (which might happen after another @documentlanguage). -% -% Copyright 1999, 2007, 2008 Free Software Foundation. +% $Id$ +% txi-ja.tex -- Japanese translations and font definitions for texinfo.tex. % +% Copyright 1999, 2007, 2008, 2016 Free Software Foundation, Inc. +% % 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 3 of the License, or -% (at your option) any later version. +% the Free Software Foundation; either version 3 of the license, 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 @@ -16,50 +15,474 @@ % % You should have received a copy of the GNU General Public License % along with this program. If not, see . +% +% Written by Masamichi Hosoda, 5 May 2016, + +\txisetlanguage{USenglish}{2}{3} + +\plainnonfrenchspacing + +\gdef\putwordAppendix{付録} +\gdef\putwordChapter{Chapter} +\gdef\putworderror{エラー} +\gdef\putwordfile{ファイル} +\gdef\putwordin{in} +\gdef\putwordIndexIsEmpty{(インデックスが空です)} +\gdef\putwordIndexNonexistent{(インデックスがありません)} +\gdef\putwordInfo{Info} +\gdef\putwordInstanceVariableof{Instance Variable of} +\gdef\putwordMethodon{Method on} +\gdef\putwordNoTitle{無題} +\gdef\putwordof{of} +\gdef\putwordon{on} +\gdef\putwordpage{ページ} +\gdef\putwordsection{section} +\gdef\putwordSection{Section} +\gdef\putwordsee{see} +\gdef\putwordSee{See} +\gdef\putwordShortTOC{簡単な目次} +\gdef\putwordTOC{目次} +% +\gdef\putwordMJan{1月} +\gdef\putwordMFeb{2月} +\gdef\putwordMMar{3月} +\gdef\putwordMApr{4月} +\gdef\putwordMMay{5月} +\gdef\putwordMJun{6月} +\gdef\putwordMJul{7月} +\gdef\putwordMAug{8月} +\gdef\putwordMSep{9月} +\gdef\putwordMOct{10月} +\gdef\putwordMNov{11月} +\gdef\putwordMDec{12月} +% +\gdef\putwordDefmac{マクロ} +\gdef\putwordDefspec{特殊フォーム} +\gdef\putwordDefvar{変数} +\gdef\putwordDefopt{ユーザオプション} +\gdef\putwordDeffunc{関数} + +% Produces Year Month Day style of output. +\def\today{% + \number\year 年\space + \ifcase\month + \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr + \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug + \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec + \fi + \space\number\day 日} + + +% +% Japanese font definitions +% + +\ifx\txijapackage\thisisundefined + \errmessage{Required CJK package is not found. + Use `texinfo-ja.tex' instead of `texinfo.tex'} +\else + + % + % For LuaTeX + % + \ifx\luatexversion\thisisundefined + \else + % Definitions for a main text size of 11pt. (The default in Texinfo.) + % Japanese font size is muliplied by 0.962216. + \let\definealphabetictextfontsizexi\definetextfontsizexi + \gdef\definetextfontsizexi{% + % Text fonts (11.2pt, magstep1). + \jfont\textmc{file:ipaexm.ttf:jfm=ujis} at 10.78pt + \jfont\textgt{file:ipaexg.ttf:jfm=ujis} at 10.78pt + + % Fonts for indices, footnotes, small examples (9pt). + \jfont\smallmc{file:ipaexm.ttf:jfm=ujis} at 8.66pt + \jfont\smallgt{file:ipaexg.ttf:jfm=ujis} at 8.66pt + + % Fonts for small examples (8pt). + \jfont\smallermc{file:ipaexm.ttf:jfm=ujis} at 7.70pt + \jfont\smallergt{file:ipaexg.ttf:jfm=ujis} at 7.70pt + + % Fonts for title page (20.4pt): + \jfont\titlemc{file:ipaexm.ttf:jfm=ujis} at 19.63pt + \jfont\titlegt{file:ipaexg.ttf:jfm=ujis} at 19.63pt + + % Chapter (and unnumbered) fonts (17.28pt). + \jfont\chapmc{file:ipaexm.ttf:jfm=ujis} at 16.63pt + \jfont\chapgt{file:ipaexg.ttf:jfm=ujis} at 16.63pt + + % Section fonts (14.4pt). + \jfont\secmc{file:ipaexm.ttf:jfm=ujis} at 13.86pt + \jfont\secgt{file:ipaexg.ttf:jfm=ujis} at 13.86pt + + % Subsection fonts (13.15pt). + \jfont\ssecmc{file:ipaexm.ttf:jfm=ujis} at 12.65pt + \jfont\ssecgt{file:ipaexg.ttf:jfm=ujis} at 12.65pt + + % Reduced fonts for @acro in text (10pt). + \jfont\reducedmc{file:ipaexm.ttf:jfm=ujis} at 9.62pt + \jfont\reducedgt{file:ipaexg.ttf:jfm=ujis} at 9.62pt + + % Fonts for short table of contents. + \jfont\shortcontmc{file:ipaexm.ttf:jfm=ujis} at 11.55pt + \jfont\shortcontgt{file:ipaexg.ttf:jfm=ujis} at 11.55pt + + \definealphabetictextfontsizexi + } -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% for dvipdfmx + % Definitions for a main text size of 10pt. + % Japanese font size is muliplied by 0.962216. + \let\definealphabetictextfontsizex\definetextfontsizex + \gdef\definetextfontsizex{% + % Text fonts (10pt). + \jfont\textmc{file:ipaexm.ttf:jfm=ujis} at 9.62pt + \jfont\textgt{file:ipaexg.ttf:jfm=ujis} at 9.62pt + + % Fonts for indices, footnotes, small examples (9pt). + \jfont\smallmc{file:ipaexm.ttf:jfm=ujis} at 8.66pt + \jfont\smallgt{file:ipaexg.ttf:jfm=ujis} at 8.66pt + + % Fonts for small examples (8pt). + \jfont\smallermc{file:ipaexm.ttf:jfm=ujis} at 7.70pt + \jfont\smallergt{file:ipaexg.ttf:jfm=ujis} at 7.70pt + + % Fonts for title page (20.4pt): + \jfont\titlemc{file:ipaexm.ttf:jfm=ujis} at 19.63pt + \jfont\titlegt{file:ipaexg.ttf:jfm=ujis} at 19.63pt + + % Chapter fonts (14.4pt). + \jfont\chapmc{file:ipaexm.ttf:jfm=ujis} at 13.86pt + \jfont\chapgt{file:ipaexg.ttf:jfm=ujis} at 13.86pt + + % Section fonts (12pt). + \jfont\secmc{file:ipaexm.ttf:jfm=ujis} at 11.55pt + \jfont\secgt{file:ipaexg.ttf:jfm=ujis} at 11.55pt + + % Subsection fonts (10pt). + \jfont\ssecmc{file:ipaexm.ttf:jfm=ujis} at 9.62pt + \jfont\ssecgt{file:ipaexg.ttf:jfm=ujis} at 9.62pt + + % Reduced fonts for @acro in text (9pt). + \jfont\reducedmc{file:ipaexm.ttf:jfm=ujis} at 8.66pt + \jfont\reducedgt{file:ipaexg.ttf:jfm=ujis} at 8.66pt + + % Fonts for short table of contents. + \jfont\shortcontmc{file:ipaexm.ttf:jfm=ujis} at 11.55pt + \jfont\shortcontgt{file:ipaexg.ttf:jfm=ujis} at 11.55pt -\def\csdef#1{\expandafter\def\csname#1\endcsname} + \definealphabetictextfontsizex + } -\gdef\usedvipdfmx{ + % Ignore LuaTeX-ja added line end comment + % https://osdn.jp/ticket/browse.php?group_id=5593&tid=36096 + % + % Re-define texinfo.tex's \parseargusing + \def\parseargusing#1#2{% + \def\argtorun{#2}% + \begingroup + \ifx\ltjlineendcomment\thisisundefined + % Ignore U+FFFFF for LuaTeX-ja <= 20160208.0 + \catcode"FFFFF=9 + \else + % Ignore the character \ltjlineendcomment for LuaTeX-ja > 20160208.0 + \catcode\ltjlineendcomment=9 + \fi + \obeylines + \spaceisspace + #1% + \parseargline\empty% Insert the \empty token, see \finishparsearg below. + } + % Re-define texinfo.tex's \comment + \def\comment{\begingroup \catcode`\^^M=\active% + \ifx\ltjlineendcomment\thisisundefined + % Ignore U+FFFFF for LuaTeX-ja <= 20160208.0 + \catcode"FFFFF=9% + \else + % Ignore the character \ltjlineendcomment for LuaTeX-ja > 20160208.0 + \catcode\ltjlineendcomment=9% + \fi + \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other\commentxxx}% + % Re-let \comment related macros + \let\setfilename=\comment + \let\dircategory=\comment + \let\definfoenclose=\comment + \let\footnotestyle=\comment + % Re-define texinfo.tex's \c + \def\c{\begingroup \catcode`\^^M=\active% + \ifx\ltjlineendcomment\thisisundefined + % Ignore U+FFFFF for LuaTeX-ja <= 20160208.0 + \catcode"FFFFF=9% + \else + % Ignore the character \ltjlineendcomment for LuaTeX-ja > 20160208.0 + \catcode\ltjlineendcomment=9% + \fi + \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% + \cxxx} + % Re-let \c related macro + \let\texinfoc=\c + \fi % LuaTeX + + % + % For XeTeX + % + \ifx\XeTeXrevision\thisisundefined + \else + % Fix some Japanese character class + % (unicode-letters.tex is wrong.) + \def\do#1{\XeTeXcharclass"#1=1 } + \do{3041}\do{3043}\do{3045}\do{3047}\do{3049}\do{3063} + \do{3083}\do{3085}\do{3087}\do{308E}\do{3095}\do{3096} + \do{30A1}\do{30A3}\do{30A5}\do{30A7}\do{30A9}\do{30C3} + \do{30E3}\do{30E5}\do{30E7}\do{30EE}\do{30F5}\do{30F6} + \do{30FC}\do{31F0}\do{31F1}\do{31F2}\do{31F3}\do{31F4} + \do{31F5}\do{31F6}\do{31F7}\do{31F8}\do{31F9}\do{31FA} + \do{31FB}\do{31FC}\do{31FD}\do{31FE}\do{31FF} + + % Add some character class + \do{2015}\do{2016}\do{2025}\do{2030}\do{2032}\do{2033} + \do{203B}\do{2103}\do{212B} + + \do{2500}\do{2501}\do{2502}\do{2503}\do{250C}\do{250F} + \do{2510}\do{2513}\do{2514}\do{2517}\do{2518}\do{251B} + \do{251C}\do{251D}\do{2520}\do{2523}\do{2524}\do{2525} + \do{2528}\do{252B}\do{252C}\do{252F}\do{2530}\do{2533} + \do{2534}\do{2537}\do{2538}\do{253B}\do{253C}\do{253F} + \do{2542}\do{254B} + + \do{25A0}\do{25A1}\do{25B2}\do{25B3}\do{25BC}\do{25BD} + \do{25C6}\do{25C7}\do{25CB}\do{25CE}\do{25CF}\do{25EF} + \do{2605}\do{2606}\do{2640}\do{2642} + + \do{3000} + + % Setting Japanese font instead of Chinese font + \def\setjafont#1{% + \let\zhfont#1\let\zhpunctfont#1% + \let\zhextafont#1\let\zhextbfont#1% + } + + % Definitions for a main text size of 11pt. (The default in Texinfo.) + % Japanese font size is muliplied by 0.962216. + \let\definealphabetictextfontsizexi\definetextfontsizexi + \gdef\definetextfontsizexi{% + % Text fonts (11.2pt, magstep1). + \font\textmczzz"[ipaexm.ttf]:mapping=tex-text" at 10.78pt + \font\textgtzzz"[ipaexg.ttf]:mapping=tex-text" at 10.78pt + \def\textmc{\setjafont\textmczzz} + \def\textgt{\setjafont\textgtzzz} + + % Fonts for indices, footnotes, small examples (9pt). + \font\smallmczzz"[ipaexm.ttf]:mapping=tex-text" at 8.66pt + \font\smallgtzzz"[ipaexg.ttf]:mapping=tex-text" at 8.66pt + \def\smallmc{\setjafont\smallmczzz} + \def\smallgt{\setjafont\smallgtzzz} + + % Fonts for small examples (8pt). + \font\smallermczzz"[ipaexm.ttf]:mapping=tex-text" at 7.70pt + \font\smallergtzzz"[ipaexg.ttf]:mapping=tex-text" at 7.70pt + \def\smallermc{\setjafont\smallermczzz} + \def\smallergt{\setjafont\smallergtzzz} + + % Fonts for title page (20.4pt): + \font\titlemczzz"[ipaexm.ttf]:mapping=tex-text" at 19.63pt + \font\titlegtzzz"[ipaexg.ttf]:mapping=tex-text" at 19.63pt + \def\titlemc{\setjafont\titlemczzz} + \def\titlegt{\setjafont\titlegtzzz} + + % Chapter (and unnumbered) fonts (17.28pt). + \font\chapmczzz"[ipaexm.ttf]:mapping=tex-text" at 16.63pt + \font\chapgtzzz"[ipaexg.ttf]:mapping=tex-text" at 16.63pt + \def\chapmc{\setjafont\chapmczzz} + \def\chapgt{\setjafont\chapgtzzz} + + % Section fonts (14.4pt). + \font\secmczzz"[ipaexm.ttf]:mapping=tex-text" at 13.86pt + \font\secgtzzz"[ipaexg.ttf]:mapping=tex-text" at 13.86pt + \def\secmc{\setjafont\secmczzz} + \def\secgt{\setjafont\secgtzzz} + + % Subsection fonts (13.15pt). + \font\ssecmczzz"[ipaexm.ttf]:mapping=tex-text" at 12.65pt + \font\ssecgtzzz"[ipaexg.ttf]:mapping=tex-text" at 12.65pt + \def\ssecmc{\setjafont\ssecmczzz} + \def\ssecgt{\setjafont\ssecgtzzz} + + % Reduced fonts for @acro in text (10pt). + \font\reducedmczzz"[ipaexm.ttf]:mapping=tex-text" at 9.62pt + \font\reducedgtzzz"[ipaexg.ttf]:mapping=tex-text" at 9.62pt + \def\reducedmc{\setjafont\reducedmczzz} + \def\reducedgt{\setjafont\reducedgtzzz} + + % Fonts for short table of contents. + \font\shortcontmczzz"[ipaexm.ttf]:mapping=tex-text" at 11.55pt + \font\shortcontgtzzz"[ipaexg.ttf]:mapping=tex-text" at 11.55pt + \def\shortcontmc{\setjafont\shortcontmczzz} + \def\shortcontgt{\setjafont\shortcontgtzzz} + + \definealphabetictextfontsizexi + } - \ifnum 42146=\euc"A4A2 \special{pdf:tounicode EUC-UCS2}\else - \special{pdf:tounicode 90ms-RKSJ-UCS2}\fi + % Definitions for a main text size of 10pt. + % Japanese font size is muliplied by 0.962216. + \let\definealphabetictextfontsizex\definetextfontsizex + \gdef\definetextfontsizex{% + % Text fonts (10pt). + \font\textmczzz"[ipaexm.ttf]:mapping=tex-text" at 9.62pt + \font\textgtzzz"[ipaexg.ttf]:mapping=tex-text" at 9.62pt + \def\textmc{\setjafont\textmczzz} + \def\textgt{\setjafont\textgtzzz} + + % Fonts for indices, footnotes, small examples (9pt). + \font\smallmczzz"[ipaexm.ttf]:mapping=tex-text" at 8.66pt + \font\smallgtzzz"[ipaexg.ttf]:mapping=tex-text" at 8.66pt + \def\smallmc{\setjafont\smallmczzz} + \def\smallgt{\setjafont\smallgtzzz} + + % Fonts for small examples (8pt). + \font\smallermczzz"[ipaexm.ttf]:mapping=tex-text" at 7.70pt + \font\smallergtzzz"[ipaexg.ttf]:mapping=tex-text" at 7.70pt + \def\smallermc{\setjafont\smallermczzz} + \def\smallergt{\setjafont\smallergtzzz} + + % Fonts for title page (20.4pt): + \font\titlemczzz"[ipaexm.ttf]:mapping=tex-text" at 19.63pt + \font\titlegtzzz"[ipaexg.ttf]:mapping=tex-text" at 19.63pt + \def\titlemc{\setjafont\titlemczzz} + \def\titlegt{\setjafont\titlegtzzz} + + % Chapter fonts (14.4pt). + \font\chapmczzz"[ipaexm.ttf]:mapping=tex-text" at 13.86pt + \font\chapgtzzz"[ipaexg.ttf]:mapping=tex-text" at 13.86pt + \def\chapmc{\setjafont\chapmczzz} + \def\chapgt{\setjafont\chapgtzzz} + + % Section fonts (12pt). + \font\secmczzz"[ipaexm.ttf]:mapping=tex-text" at 11.55pt + \font\secgtzzz"[ipaexg.ttf]:mapping=tex-text" at 11.55pt + \def\secmc{\setjafont\secmczzz} + \def\secgt{\setjafont\secgtzzz} + + % Subsection fonts (10pt). + \font\ssecmczzz"[ipaexm.ttf]:mapping=tex-text" at 9.62pt + \font\ssecgtzzz"[ipaexg.ttf]:mapping=tex-text" at 9.62pt + \def\ssecmc{\setjafont\ssecmczzz} + \def\ssecgt{\setjafont\ssecgtzzz} + + % Reduced fonts for @acro in text (9pt). + \font\reducedmczzz"[ipaexm.ttf]:mapping=tex-text" at 8.66pt + \font\reducedgtzzz"[ipaexg.ttf]:mapping=tex-text" at 8.66pt + \def\reducedmc{\setjafont\reducedmczzz} + \def\reducedgt{\setjafont\reducedgtzzz} + + % Fonts for short table of contents. + \font\shortcontmczzz"[ipaexm.ttf]:mapping=tex-text" at 11.55pt + \font\shortcontgtzzz"[ipaexg.ttf]:mapping=tex-text" at 11.55pt + \def\shortcontmc{\setjafont\shortcontmczzz} + \def\shortcontgt{\setjafont\shortcontgtzzz} - \global\pdfmakepagedesttrue - \gdef\pdfdest name##1 xyz{% - \iffinishedtitlepage\else - \special{pdf:dest (name##1) [\@thispage /XYZ \@xpos \@ypos]}% + \definealphabetictextfontsizex + } + + % Japanese line break settings + \XeTeXlinebreaklocale "ja_JP" + \XeTeXlinebreakskip=0em plus 0.1em minus 0.01em + \XeTeXlinebreakpenalty=0 + + % For copy & paste Unicode characters (XeTeX 0.99995+) + \ifx\XeTeXgenerateactualtext\thisisundefined + \else + \XeTeXgenerateactualtext=1 \fi - } - \gdef\dopdfoutline##1##2##3##4{% - \special{pdf:out [] ##2 << /Title (##1) /A << /S /GoTo /D (name##4) >> >> }% - } - - \gdef\entryaddpdfoutline##1##2{% - \global\cslet{orig##1}{##1}% - \csdef{##1}####1####2####3####4{% - \expandafter\empty\csname orig##1\endcsname{####1}{####2}{####3}{####4}% - \dopdfoutline{####1}{##2}{####3}{####4}% - } - } - - \entryaddpdfoutline{numchapentry}{1} - \entryaddpdfoutline{numsecentry}{2} - \entryaddpdfoutline{numsubsecentry}{3} - \entryaddpdfoutline{numsubsubsecentry}{4} - - \entryaddpdfoutline{unnchapentry}{1} - \entryaddpdfoutline{unnsecentry}{2} - \entryaddpdfoutline{unnsubsecentry}{3} - \entryaddpdfoutline{unnsubsubsecentry}{4} - - \entryaddpdfoutline{appentry}{1} - \let\appsecentry=\numsecentry - \let\appsubsecentry=\numsubsecentry - \let\appsubsubsecentry=\numsubsubsecentry + \fi % XeTeX + + \iftxinativeunicodecapable + + % Sync fonts + + \let\alphabeticrm\rm + \gdef\rm{\alphabeticrm\tenmc} + + \let\alphabeticit\it + \gdef\it{\alphabeticit\tenmc} + + \let\alphabeticsl\sl + \gdef\sl{\alphabeticsl\tengt} + + \let\alphabeticbf\bf + \gdef\bf{\alphabeticbf\tengt} + + \let\alphabetictt\tt + \gdef\tt{\alphabetictt\tengt} + + % Add fonts + + \let\alphabetictextfonts\textfonts + \gdef\textfonts{% + \alphabetictextfonts + \let\tenmc\textmc + \let\tengt\textgt + } + + \let\alphabetictitlefonts\titlefonts + \gdef\titlefonts{% + \alphabetictitlefonts + \let\tenmc\titlemc + \let\tengt\titlegt + } + + \let\alphabeticchapfonts\chapfonts + \gdef\chapfonts{% + \alphabeticchapfonts + \let\tenmc\chapmc + \let\tengt\chapgt + } + + \let\alphabeticsecfonts\secfonts + \gdef\secfonts{% + \alphabeticsecfonts + \let\tenmc\secmc + \let\tengt\secgt + } + + \let\alphabeticsubsecfonts\subsecfonts + \gdef\subsecfonts{% + \alphabeticsubsecfonts + \let\tenmc\ssecmc + \let\tengt\ssecgt + } + + \global\let\subsubsecfonts\subsecfonts + + \let\alphabeticreducedfonts\reducedfonts + \gdef\reducedfonts{% + \alphabeticreducedfonts + \let\tenmc\reducedmc + \let\tengt\reducedgt + } + + \let\alphabeticsmallfonts\smallfonts + \gdef\smallfonts{% + \alphabeticsmallfonts + \let\tenmc\smallmc + \let\tengt\smallgt + } + + \let\alphabeticsmallerfonts\smallerfonts + \gdef\smallerfonts{% + \alphabeticsmallerfonts + \let\tenmc\smallermc + \let\tengt\smallergt + } + + \let\smallexamplefonts\smallfonts + + % Reset fonts + + \globaldefs = 1 + \definetextfontsizexi + \globaldefs = 0 + + \fi % \iftxinativeunicodecapable -} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\fi % \ifx\txijapackage\thisisundefined diff -Nru ddskk-16.2/etc/ChangeLog ddskk-16.2+0.20190423/etc/ChangeLog --- ddskk-16.2/etc/ChangeLog 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/etc/ChangeLog 2019-04-23 12:49:58.000000000 +0000 @@ -1,3 +1,15 @@ +2018-07-23 Tsuyoshi Kitamoto + + * dot.skk: Update for markdown-mode. + +2018-07-22 Tsuyoshi Kitamoto + + * dot.skk: Update for orgtbl-mode. + +2017-03-12 Tsuyoshi Kitamoto + + * dot.skk: Update. + 2017-02-27 Tsuyoshi Kitamoto * dot.emacs: Update. diff -Nru ddskk-16.2/etc/dot.skk ddskk-16.2+0.20190423/etc/dot.skk --- ddskk-16.2/etc/dot.skk 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/etc/dot.skk 2019-04-23 12:49:58.000000000 +0000 @@ -184,6 +184,12 @@ ;; (setq skk-dcomp-multiple-activate t ;; skk-dcomp-multiple-rows 10) +;; 動的補完では、「見出し語を補完する」のではなく、 +;; 「先頭一致する見出し語に対応する候補」を複数表示する +(when skk-dcomp-multiple-activate + (require 'skk-pre-henkan) ; experimental/skk-pre-henkan.el + ) + ;;; ▽ほ*んとう-!- ;;; ほ んとう ;;; ほ かん @@ -663,14 +669,22 @@ ;; @@ skk-search-web.el ;; (setq skk-use-search-web t) -;; (add-to-list 'skk-search-prog-list -;; '(skk-search-web 'skk-google-cgi-api-for-japanese-input) -;; t) -;; 辞書登録モードに移ったときの初期値に Google サジェストを利用する -;; (setq skk-read-from-minibuffer-function -;; (lambda () -;; (car (skk-google-suggest skk-henkan-key)))) +(when skk-use-search-web + ;; ;; 辞書変換が尽きたら Google CGI API for Japanese Input による変換を実行 + ;; ;; https://www.google.co.jp/ime/cgiapi.html + ;; (add-to-list 'skk-search-prog-list + ;; '(skk-search-web 'skk-google-cgi-api-for-japanese-input) + ;; t) + + ;; ;; 辞書登録モードに移ったときの初期値に Google サジェストを利用する + ;; (setq skk-read-from-minibuffer-function + ;; (lambda () + ;; (car (skk-google-suggest skk-henkan-key)))) + + ;; ;; 動的補完 (Dynamic Completion) に Google サジェストを表示 + ;; (add-to-list 'skk-completion-prog-list '(skk-comp-google) t) + ) ;; @@ SKK abbrev mode ;; 見出し語の補完において Lisp シンボルも補完する @@ -730,4 +744,15 @@ ;; 日本語と英語の間に空白を自動挿入する ;; http://hins11.jugem.jp/?eid=47 +;;; orgtbl-mode +;;; http://mail.ring.gr.jp/skk/201807/msg00001.html +(skk-wrap-newline-command orgtbl-ret) +(defadvice org-delete-backward-char (around skk-ad activate) + (skk-delete-backward-char N) + ad-do-it) + +;;; markdown-mode +(skk-wrap-newline-command markdown-enter-key) + + ;;; dot.skk ends here diff -Nru ddskk-16.2/experimental/skk-pre-henkan.el ddskk-16.2+0.20190423/experimental/skk-pre-henkan.el --- ddskk-16.2/experimental/skk-pre-henkan.el 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/experimental/skk-pre-henkan.el 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,81 @@ +;;; skk-pre-henkan.el --- SKK $B8+=P$78l$NBe$o$j$K8uJd$rI=<((B -*- coding: iso-2022-jp -*- + +;; Copyright (C) 2017 Tsuyoshi Kitamoto + +;; Author: Tsuyoshi Kitamoto +;; Maintainer: SKK Development Team +;; Keywords: japanese, mule, input method + +;; This file is part of Daredevil SKK. + +;; Daredevil SKK 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. + +;; Daredevil SKK 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 Daredevil SKK, see the file COPYING. If not, write to +;; the Free Software Foundation Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: +;; skk-dcomp-multiple-get-candidates() +;; => skk-comp-get-candidate(first) +;; => when first setq skk-comp-first t +;; eval skk-completion-prog-list +;; setq skk-comp-first nil + +;; (defcustom skk-completion-prog-list '((skk-comp-by-history) +;; (skk-comp-from-jisyo skk-jisyo) +;; (skk-look-completion)) + +;;; How to use: +;; (require 'skk-pre-henkan) + +;;; Code: + +(setq skk-dcomp-activate nil) +(setq skk-completion-prog-list '((skk-pre-henkan))) + +;; internal variable. +(defvar skk-pre-henkan-candidates nil) + +(defun skk-pre-henkan () + "$B%j%9%H(B `skk-completion-prog-list' $B$NMWAG$H$7$F;HMQ(B." + ;; `skk-pre-henkan-candidates' $B$N(B car $B$rJV$9!#(B`skk-pre-henkan-candidates' $B$O=L$`!#(B + ;; `skk-comp-first' $B$,(B t $B$J$i!"?7$?$J(B `skk-pre-henkan-candidates' $B$r:n$k!#(B + (unless (string= skk-comp-key "") + (when skk-comp-first + (setq skk-pre-henkan-candidates (skk-pre-henkan-make-candidates))) + (prog1 + (car (skk-treat-strip-note-from-word (car skk-pre-henkan-candidates))) + (setq skk-pre-henkan-candidates (cdr skk-pre-henkan-candidates))))) + +(defun skk-pre-henkan-make-candidates () + "`skk-comp-key' $B$r%-! -;; Created: 1996/08/18 -;; Keywords: install, byte-compile, directory detection - -;; This file is part of APEL (A Portable Emacs Library). - -;; 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., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Code: - -(defvar default-load-path load-path - "*Base of `load-path'. -It is used as default value of target path to search file or -subdirectory under load-path.") - -;;; @ compile Emacs Lisp files -;;; - -(defun compile-elisp-module (module &optional path every-time) - (setq module (expand-file-name (symbol-name module) path)) - (let ((el-file (concat module ".el")) - (elc-file (concat module ".elc"))) - (if (or every-time - (file-newer-than-file-p el-file elc-file)) - (byte-compile-file el-file)))) - -(defun compile-elisp-modules (modules &optional path every-time) - (mapcar - (function - (lambda (module) - (compile-elisp-module module path every-time))) - modules)) - - -;;; @ install files -;;; - -(defvar install-overwritten-file-modes (+ (* 64 6)(* 8 4) 4)) ; 0644 - -(defun install-file (file src dest &optional move overwrite just-print) - (if just-print - (princ (format "%s -> %s\n" file dest)) - (let ((src-file (expand-file-name file src))) - (if (file-exists-p src-file) - (let ((full-path (expand-file-name file dest))) - (if (and (file-exists-p full-path) overwrite) - (delete-file full-path)) - (copy-file src-file full-path t t) - (set-file-modes full-path install-overwritten-file-modes) - (if move - (catch 'tag - (while (and (file-exists-p src-file) - (file-writable-p src-file)) - (condition-case err - (progn - (delete-file src-file) - (throw 'tag nil)) - (error (princ (format "%s\n" (nth 1 err)))))))) - (princ (format "%s -> %s\n" file dest))))))) - -(defun install-files (files src dest &optional move overwrite just-print) - (or just-print - (file-exists-p dest) - (make-directory dest t)) - (mapcar - (function - (lambda (file) - (install-file file src dest move overwrite just-print))) - files)) - - -;;; @@ install Emacs Lisp files -;;; - -(defun install-elisp-module (module src dest &optional just-print del-elc) - (let (el-file elc-file) - (let ((name (symbol-name module))) - (setq el-file (concat name ".el")) - (setq elc-file (concat name ".elc"))) - (let ((src-file (expand-file-name el-file src))) - (if (not (file-exists-p src-file)) - nil - (if just-print - (princ (format "%s -> %s\n" el-file dest)) - (let ((full-path (expand-file-name el-file dest))) - (if (file-exists-p full-path) - (delete-file full-path)) - (copy-file src-file full-path t t) - (set-file-modes full-path install-overwritten-file-modes) - (princ (format "%s -> %s\n" el-file dest))))) - (setq src-file (expand-file-name elc-file src)) - (if (not (file-exists-p src-file)) - (let ((full-path (expand-file-name elc-file dest))) - (if (and del-elc (file-exists-p full-path)) - (if just-print - (princ (format "%s -> to be deleted\n" full-path)) - (delete-file full-path) - (princ (format "%s -> deleted\n" full-path))))) - (if just-print - (princ (format "%s -> %s\n" elc-file dest)) - (let ((full-path (expand-file-name elc-file dest))) - (if (file-exists-p full-path) - (delete-file full-path)) - (copy-file src-file full-path t t) - (set-file-modes full-path install-overwritten-file-modes) - (catch 'tag - (while (file-exists-p src-file) - (condition-case err - (progn - (delete-file src-file) - (throw 'tag nil)) - (error (princ (format "%s\n" (nth 1 err))))))) - (princ (format "%s -> %s\n" elc-file dest)))))))) - -(defun install-elisp-modules (modules src dest &optional just-print del-elc) - (or just-print - (file-exists-p dest) - (make-directory dest t)) - (mapcar - (function - (lambda (module) - (install-elisp-module module src dest just-print del-elc))) - modules)) - - -;;; @ detect install path -;;; - -;; install to shared directory (maybe "/usr/local") -(defvar install-prefix - (if (or (<= emacs-major-version 18) - (featurep 'xemacs) - (featurep 'meadow) ; for Meadow - (and (eq system-type 'windows-nt) ; for NTEmacs - (>= emacs-major-version 20))) - (expand-file-name "../../.." exec-directory) - (expand-file-name "../../../.." data-directory))) - -(defvar install-elisp-prefix - (if (>= emacs-major-version 19) - "site-lisp" - ;; v18 does not have standard site directory. - "local.lisp")) - -;; Avoid compile warning. -(eval-when-compile (autoload 'replace-in-string "subr")) - -(defun install-detect-elisp-directory (&optional prefix elisp-prefix - allow-version-specific) - (or prefix - (setq prefix install-prefix)) - (or elisp-prefix - (setq elisp-prefix install-elisp-prefix)) - (or (catch 'tag - (let ((rest (delq nil (copy-sequence default-load-path))) - (regexp - (concat "^" - (regexp-quote (if (featurep 'xemacs) - ;; Handle backslashes (Windows) - (replace-in-string - (file-name-as-directory - (expand-file-name prefix)) - "\\\\" "/") - (file-name-as-directory - (expand-file-name prefix)))) - ".*/" - (regexp-quote - (if (featurep 'xemacs) - ;; Handle backslashes (Windows) - (replace-in-string elisp-prefix "\\\\" "/") - elisp-prefix)) - "/?$")) - dir) - (while rest - (setq dir (if (featurep 'xemacs) - ;; Handle backslashes (Windows) - (replace-in-string (car rest) "\\\\" "/") - (car rest))) - (if (string-match regexp dir) - (if (or allow-version-specific - (not (string-match (format "/%d\\.%d" - emacs-major-version - emacs-minor-version) - dir))) - (throw 'tag (car rest)))) - (setq rest (cdr rest))))) - (expand-file-name (concat (if (and (not (featurep 'xemacs)) - (or (>= emacs-major-version 20) - (and (= emacs-major-version 19) - (> emacs-minor-version 28)))) - "share/" - "lib/") - (cond - ((featurep 'xemacs) - (if (featurep 'mule) - "xmule/" - "xemacs/")) - ;; unfortunately, unofficial mule based on - ;; 19.29 and later use "emacs/" by default. - ((boundp 'MULE) "mule/") - ((boundp 'NEMACS) "nemacs/") - (t "emacs/")) - elisp-prefix) - prefix))) - -(defvar install-default-elisp-directory - (install-detect-elisp-directory)) - - -;;; @ for XEmacs package system -;;; - -(defun install-get-default-package-directory () - (let ((dirs (append - (cond - ((boundp 'early-package-hierarchies) - (append (if early-package-load-path - early-package-hierarchies) - (if late-package-load-path - late-package-hierarchies) - (if last-package-load-path - last-package-hierarchies)) ) - ((boundp 'early-packages) - (append (if early-package-load-path - early-packages) - (if late-package-load-path - late-packages) - (if last-package-load-path - last-packages)) )) - (if (and (boundp 'configure-package-path) - (listp configure-package-path)) - (delete "" configure-package-path)))) - dir) - (while (and (setq dir (car dirs)) - (not (file-exists-p dir))) - (setq dirs (cdr dirs))) - dir)) - -(defun install-update-package-files (package dir &optional just-print) - (cond - (just-print - (princ (format "Updating autoloads in directory %s..\n\n" dir)) - - (princ (format "Processing %s\n" dir)) - (princ "Generating custom-load.el...\n\n") - - (princ (format "Compiling %s...\n" - (expand-file-name "auto-autoloads.el" dir))) - (princ (format "Wrote %s\n" - (expand-file-name "auto-autoloads.elc" dir))) - - (princ (format "Compiling %s...\n" - (expand-file-name "custom-load.el" dir))) - (princ (format "Wrote %s\n" - (expand-file-name "custom-load.elc" dir)))) - (t - (if (fboundp 'batch-update-directory-autoloads) - ;; XEmacs 21.5.19 and newer. - (let ((command-line-args-left (list package dir))) - (batch-update-directory-autoloads)) - (setq autoload-package-name package) - (let ((command-line-args-left (list dir))) - (batch-update-directory))) - - (let ((command-line-args-left (list dir))) - (Custom-make-dependencies)) - - (byte-compile-file (expand-file-name "auto-autoloads.el" dir)) - (byte-compile-file (expand-file-name "custom-load.el" dir))))) - - -;;; @ Other Utilities -;;; - -(defun install-just-print-p () - (let ((flag (getenv "MAKEFLAGS")) - (case-fold-search nil)) - (princ (format "%s\n" flag)) - (if flag - (string-match "^\\(\\(--[^ ]+ \\)+-\\|[^ =-]\\)*n" flag)))) - - -;;; @ end -;;; - -(provide 'install) - -;;; install.el ends here diff -Nru ddskk-16.2/maint/install.el ddskk-16.2+0.20190423/maint/install.el --- ddskk-16.2/maint/install.el 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/maint/install.el 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,306 @@ +;;; install.el --- Emacs Lisp package install utility + +;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2006 +;; Free Software Foundation, Inc. + +;; Author: MORIOKA Tomohiko +;; Created: 1996/08/18 +;; Keywords: install, byte-compile, directory detection + +;; This file is part of APEL (A Portable Emacs Library). + +;; 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., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Code: + +(defvar default-load-path load-path + "*Base of `load-path'. +It is used as default value of target path to search file or +subdirectory under load-path.") + +;;; @ compile Emacs Lisp files +;;; + +(defun compile-elisp-module (module &optional path every-time) + (setq module (expand-file-name (symbol-name module) path)) + (let ((el-file (concat module ".el")) + (elc-file (concat module ".elc"))) + (if (or every-time + (file-newer-than-file-p el-file elc-file)) + (byte-compile-file el-file)))) + +(defun compile-elisp-modules (modules &optional path every-time) + (mapcar + (function + (lambda (module) + (compile-elisp-module module path every-time))) + modules)) + + +;;; @ install files +;;; + +(defvar install-overwritten-file-modes (+ (* 64 6)(* 8 4) 4)) ; 0644 + +(defun install-file (file src dest &optional move overwrite just-print) + (if just-print + (princ (format "%s -> %s\n" file dest)) + (let ((src-file (expand-file-name file src))) + (if (file-exists-p src-file) + (let ((full-path (expand-file-name file dest))) + (if (and (file-exists-p full-path) overwrite) + (delete-file full-path)) + (copy-file src-file full-path t t) + (set-file-modes full-path install-overwritten-file-modes) + (if move + (catch 'tag + (while (and (file-exists-p src-file) + (file-writable-p src-file)) + (condition-case err + (progn + (delete-file src-file) + (throw 'tag nil)) + (error (princ (format "%s\n" (nth 1 err)))))))) + (princ (format "%s -> %s\n" file dest))))))) + +(defun install-files (files src dest &optional move overwrite just-print) + (or just-print + (file-exists-p dest) + (make-directory dest t)) + (mapcar + (function + (lambda (file) + (install-file file src dest move overwrite just-print))) + files)) + + +;;; @@ install Emacs Lisp files +;;; + +(defun install-elisp-module (module src dest &optional just-print del-elc) + (let (el-file elc-file) + (let ((name (symbol-name module))) + (setq el-file (concat name ".el")) + (setq elc-file (concat name ".elc"))) + (let ((src-file (expand-file-name el-file src))) + (if (not (file-exists-p src-file)) + nil + (if just-print + (princ (format "%s -> %s\n" el-file dest)) + (let ((full-path (expand-file-name el-file dest))) + (if (file-exists-p full-path) + (delete-file full-path)) + (copy-file src-file full-path t t) + (set-file-modes full-path install-overwritten-file-modes) + (princ (format "%s -> %s\n" el-file dest))))) + (setq src-file (expand-file-name elc-file src)) + (if (not (file-exists-p src-file)) + (let ((full-path (expand-file-name elc-file dest))) + (if (and del-elc (file-exists-p full-path)) + (if just-print + (princ (format "%s -> to be deleted\n" full-path)) + (delete-file full-path) + (princ (format "%s -> deleted\n" full-path))))) + (if just-print + (princ (format "%s -> %s\n" elc-file dest)) + (let ((full-path (expand-file-name elc-file dest))) + (if (file-exists-p full-path) + (delete-file full-path)) + (copy-file src-file full-path t t) + (set-file-modes full-path install-overwritten-file-modes) + (catch 'tag + (while (file-exists-p src-file) + (condition-case err + (progn + (delete-file src-file) + (throw 'tag nil)) + (error (princ (format "%s\n" (nth 1 err))))))) + (princ (format "%s -> %s\n" elc-file dest)))))))) + +(defun install-elisp-modules (modules src dest &optional just-print del-elc) + (or just-print + (file-exists-p dest) + (make-directory dest t)) + (mapcar + (function + (lambda (module) + (install-elisp-module module src dest just-print del-elc))) + modules)) + + +;;; @ detect install path +;;; + +;; install to shared directory (maybe "/usr/local") +(defvar install-prefix + (if (or (<= emacs-major-version 18) + (featurep 'xemacs) + (featurep 'meadow) ; for Meadow + (and (eq system-type 'windows-nt) ; for NTEmacs + (>= emacs-major-version 20))) + (expand-file-name "../../.." exec-directory) + (expand-file-name "../../../.." data-directory))) + +(defvar install-elisp-prefix + (if (>= emacs-major-version 19) + "site-lisp" + ;; v18 does not have standard site directory. + "local.lisp")) + +;; Avoid compile warning. +(eval-when-compile (autoload 'replace-in-string "subr")) + +(defun install-detect-elisp-directory (&optional prefix elisp-prefix + allow-version-specific) + (or prefix + (setq prefix install-prefix)) + (or elisp-prefix + (setq elisp-prefix install-elisp-prefix)) + (or (catch 'tag + (let ((rest (delq nil (copy-sequence default-load-path))) + (regexp + (concat "^" + (regexp-quote (if (featurep 'xemacs) + ;; Handle backslashes (Windows) + (replace-in-string + (file-name-as-directory + (expand-file-name prefix)) + "\\\\" "/") + (file-name-as-directory + (expand-file-name prefix)))) + ".*/" + (regexp-quote + (if (featurep 'xemacs) + ;; Handle backslashes (Windows) + (replace-in-string elisp-prefix "\\\\" "/") + elisp-prefix)) + "/?$")) + dir) + (while rest + (setq dir (if (featurep 'xemacs) + ;; Handle backslashes (Windows) + (replace-in-string (car rest) "\\\\" "/") + (car rest))) + (if (string-match regexp dir) + (if (or allow-version-specific + (not (string-match (format "/%d\\.%d" + emacs-major-version + emacs-minor-version) + dir))) + (throw 'tag (car rest)))) + (setq rest (cdr rest))))) + (expand-file-name (concat (if (and (not (featurep 'xemacs)) + (or (>= emacs-major-version 20) + (and (= emacs-major-version 19) + (> emacs-minor-version 28)))) + "share/" + "lib/") + (cond + ((featurep 'xemacs) + (if (featurep 'mule) + "xmule/" + "xemacs/")) + ;; unfortunately, unofficial mule based on + ;; 19.29 and later use "emacs/" by default. + ((boundp 'MULE) "mule/") + ((boundp 'NEMACS) "nemacs/") + (t "emacs/")) + elisp-prefix) + prefix))) + +(defvar install-default-elisp-directory + (install-detect-elisp-directory)) + + +;;; @ for XEmacs package system +;;; + +(defun install-get-default-package-directory () + (let ((dirs (append + (cond + ((boundp 'early-package-hierarchies) + (append (if early-package-load-path + early-package-hierarchies) + (if late-package-load-path + late-package-hierarchies) + (if last-package-load-path + last-package-hierarchies)) ) + ((boundp 'early-packages) + (append (if early-package-load-path + early-packages) + (if late-package-load-path + late-packages) + (if last-package-load-path + last-packages)) )) + (if (and (boundp 'configure-package-path) + (listp configure-package-path)) + (delete "" configure-package-path)))) + dir) + (while (and (setq dir (car dirs)) + (not (file-exists-p dir))) + (setq dirs (cdr dirs))) + dir)) + +(defun install-update-package-files (package dir &optional just-print) + (cond + (just-print + (princ (format "Updating autoloads in directory %s..\n\n" dir)) + + (princ (format "Processing %s\n" dir)) + (princ "Generating custom-load.el...\n\n") + + (princ (format "Compiling %s...\n" + (expand-file-name "auto-autoloads.el" dir))) + (princ (format "Wrote %s\n" + (expand-file-name "auto-autoloads.elc" dir))) + + (princ (format "Compiling %s...\n" + (expand-file-name "custom-load.el" dir))) + (princ (format "Wrote %s\n" + (expand-file-name "custom-load.elc" dir)))) + (t + (if (fboundp 'batch-update-directory-autoloads) + ;; XEmacs 21.5.19 and newer. + (let ((command-line-args-left (list package dir))) + (batch-update-directory-autoloads)) + (setq autoload-package-name package) + (let ((command-line-args-left (list dir))) + (batch-update-directory))) + + (let ((command-line-args-left (list dir))) + (Custom-make-dependencies)) + + (byte-compile-file (expand-file-name "auto-autoloads.el" dir)) + (byte-compile-file (expand-file-name "custom-load.el" dir))))) + + +;;; @ Other Utilities +;;; + +(defun install-just-print-p () + (let ((flag (getenv "MAKEFLAGS")) + (case-fold-search nil)) + (princ (format "%s\n" flag)) + (if flag + (string-match "^\\(\\(--[^ ]+ \\)+-\\|[^ =-]\\)*n" flag)))) + + +;;; @ end +;;; + +(provide 'install) + +;;; install.el ends here diff -Nru ddskk-16.2/maint/.nosearch ddskk-16.2+0.20190423/maint/.nosearch --- ddskk-16.2/maint/.nosearch 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/maint/.nosearch 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,2 @@ +This file keeps the containing directory of the `load-path' +See `normal-top-level-add-subdirs-to-load-path's doc-string. diff -Nru ddskk-16.2/maint/ptexinfmt.el ddskk-16.2+0.20190423/maint/ptexinfmt.el --- ddskk-16.2/maint/ptexinfmt.el 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/maint/ptexinfmt.el 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,992 @@ +;;; ptexinfmt.el -- portable Texinfo formatter. + +;; Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, +;; 1994, 1995, 1996, 1997 Free Software Foundation, Inc. +;; Copyright (C) 1999 Yoshiki Hayashi +;; Copyright (C) 2000, 2001, 2002 TAKAHASHI Kaoru + +;; Author: TAKAHASHI Kaoru +;; Yoshiki Hayashi +;; Katsumi Yamaoka +;; Maintainer: TAKAHASHI Kaoru +;; Created: 7 Jul 2000 +;; Keywords: maint, tex, docs, emulation, compatibility + +;; 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., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; Original code: Yoshiki Hayashi +;; makeinfo.el (gnujdoc project) + +;; Support texinfmt.el 2.32 or later. + +;; Modified by Yamaoka not to use APEL functions. + +;; Unimplemented command: +;; @abbr +;; @float, @caption, @shortcaption, @listoffloats +;; @deftypecv[x] +;; @headitem +;; @comma{} +;; @quotation (optional arguments) +;; @acronym (optional argument) +;; @dofirstparagraphindent +;; @indent +;; @verbatiminclude +;; @\ +;; @definfoenclose +;; @deftypeivar +;; @deftypeop +;; @allowcodebreaks + +;;; Code: + +(require 'backquote) +(require 'texinfmt) + +;;; Broken +(defvar ptexinfmt-disable-broken-notice-flag t + "If non-nil disable notice, when call `ptexinfmt-broken-facility'. +This is last argument in `ptexinfmt-broken-facility'.") + +(put 'ptexinfmt-broken-facility 'lisp-indent-function 'defun) +(defmacro ptexinfmt-broken-facility (facility docstring assertion + &optional dummy) + "Declare a symbol FACILITY is broken if ASSERTION is nil. +DOCSTRING will be printed if ASSERTION is nil and +`ptexinfmt-disable-broken-notice-flag' is nil." + `(let ((facility ',facility) + (docstring ,docstring) + (assertion (eval ',assertion))) + (put facility 'broken (not assertion)) + (if assertion + nil + (put facility 'broken-docstring docstring) + (if ptexinfmt-disable-broken-notice-flag + nil + (message "BROKEN FACILITY DETECTED: %s" docstring))))) + +(put 'ptexinfmt-defun-if-broken 'lisp-indent-function 'defun) +(defmacro ptexinfmt-defun-if-broken (&rest args) + "Redefine a function just like `defun' if it is considered broken." + (let ((name (list 'quote (car args)))) + (setq args (cdr args)) + `(prog1 + ,name + (if (get ,name 'broken) + (defalias ,name + (function (lambda ,@args))))))) + +(put 'ptexinfmt-defun-if-void 'lisp-indent-function 'defun) +(defmacro ptexinfmt-defun-if-void (&rest args) + "Define a function just like `defun' unless it is already defined." + (let ((name (list 'quote (car args)))) + (setq args (cdr args)) + `(prog1 + ,name + (if (fboundp ,name) + nil + (defalias ,name + (function (lambda ,@args))))))) + +(put 'ptexinfmt-defvar-if-void 'lisp-indent-function 'defun) +(defmacro ptexinfmt-defvar-if-void (&rest args) + "Define a variable just like `defvar' unless it is already defined." + (let ((name (car args))) + (setq args (cdr args)) + `(prog1 + (defvar ,name) + (if (boundp ',name) + nil + (defvar ,name ,@args))))) + +;; sort -fd +(ptexinfmt-broken-facility texinfo-format-printindex + "Can't sort on Mule for Windows." + (if (and (memq system-type '(windows-nt ms-dos)) +;;; I don't know version threshold. +;;; (string< texinfmt-version "2.37 of 24 May 1997") + (boundp 'MULE) (not (featurep 'meadow))) ; Mule for Windows + nil + t)) + +;; @var +(ptexinfmt-broken-facility texinfo-format-var + "Don't perse @var argument." + (condition-case nil + (with-temp-buffer + (let (texinfo-enclosure-list texinfo-alias-list) + (texinfo-mode) + (insert "@var{@asis{foo}}\n") + (texinfo-format-expand-region (point-min) (point-max)) + t)) + (error nil))) + +;; @xref +(ptexinfmt-broken-facility texinfo-format-xref + "Can't format @xref, 1st argument is empty." + (condition-case nil + (with-temp-buffer + (let (texinfo-enclosure-list texinfo-alias-list) + (texinfo-mode) + (insert "@xref{, xref, , file}\n") + (texinfo-format-expand-region (point-min) (point-max)) + t)) + (error nil))) + +;; @uref +(ptexinfmt-broken-facility texinfo-format-uref + "Parse twice @uref argument." + (condition-case nil + (with-temp-buffer + (let (texinfo-enclosure-list texinfo-alias-list) + (texinfo-mode) + (insert "@uref{mailto:foo@@noncommand.example.com}\n") + (texinfo-format-expand-region (point-min) (point-max)) + t)) + (error nil))) + +;; @multitable +(ptexinfmt-broken-facility texinfo-multitable-widths + "`texinfo-multitable-widths' unsupport wide-char." + (if (fboundp 'texinfo-multitable-widths) + (with-temp-buffer + (let ((str "$BI}9-J8;z(B")) + (texinfo-mode) + (insert (format " {%s}\n" str)) + (goto-char (point-min)) + (if (= (car (texinfo-multitable-widths)) (length str)) + t + nil))) + ;; function definition is void + nil)) + +(ptexinfmt-broken-facility texinfo-multitable-item + "`texinfo-multitable-item' unsupport wide-char." + (not (get 'texinfo-multitable-widths 'broken))) + + +;;; Hardcopy and HTML (discard) +;; html +(put 'documentlanguage 'texinfo-format 'texinfo-discard-line-with-args) +(put 'documentencoding 'texinfo-format 'texinfo-discard-line-with-args) +(put 'documentdescription 'texinfo-format 'texinfo-discard-line-with-args) + +;; size +(put 'smallbook 'texinfo-format 'texinfo-discard-line) +(put 'letterpaper 'texinfo-format 'texinfo-discard-line) +(put 'afourpaper 'texinfo-format 'texinfo-discard-line) +(put 'afourlatex 'texinfo-format 'texinfo-discard-line) +(put 'afourwide 'texinfo-format 'texinfo-discard-line) +(put 'afivepaper 'texinfo-format 'texinfo-discard-line) +(put 'pagesizes 'texinfo-format 'texinfo-discard-line-with-args) + +;; style +(put 'setchapternewpage 'texinfo-format 'texinfo-discard-line-with-args) +(put 'kbdinputstyle 'texinfo-format 'texinfo-discard-line-with-args) + +;; flags +(put 'setcontentsaftertitlepage 'texinfo-format 'texinfo-discard-line) +(put 'setshortcontentsaftertitlepage 'texinfo-format 'texinfo-discard-line) +(put 'novalidate 'texinfo-format 'texinfo-discard-line-with-args) +(put 'frenchspacing 'texinfo-format 'texinfo-discard-line-with-args) + +;; head & foot +(put 'headings 'texinfo-format 'texinfo-discard-line-with-args) +(put 'evenfooting 'texinfo-format 'texinfo-discard-line-with-args) +(put 'evenheading 'texinfo-format 'texinfo-discard-line-with-args) +(put 'oddfooting 'texinfo-format 'texinfo-discard-line-with-args) +(put 'oddheading 'texinfo-format 'texinfo-discard-line-with-args) +(put 'everyfooting 'texinfo-format 'texinfo-discard-line-with-args) +(put 'everyheading 'texinfo-format 'texinfo-discard-line-with-args) + +;; misc +(put 'page 'texinfo-format 'texinfo-discard-line) +(put 'hyphenation 'texinfo-format 'texinfo-discard-command-and-arg) + +;; @slanted{} (makeinfo 4.8 or later) +(put 'slanted 'texinfo-format 'texinfo-format-noop) + +;; @sansserif{} (makeinfo 4.8 or later) +(put 'sansserif 'texinfo-format 'texinfo-format-noop) + +;; @tie{} (makeinfo 4.3 or later) +(put 'tie 'texinfo-format 'texinfo-format-tie) +(ptexinfmt-defun-if-void texinfo-format-tie () + (texinfo-parse-arg-discard) + (insert " ")) + + +;;; Directory File +;; @direcategory +(put 'dircategory 'texinfo-format 'texinfo-format-dircategory) +(ptexinfmt-defun-if-void texinfo-format-dircategory () + (let ((str (texinfo-parse-arg-discard))) + (delete-region (point) + (progn + (skip-chars-forward " ") + (point))) + (insert "INFO-DIR-SECTION " str "\n"))) + +;; @direntry +(put 'direntry 'texinfo-format 'texinfo-format-direntry) +(ptexinfmt-defun-if-void texinfo-format-direntry () + (texinfo-push-stack 'direntry nil) + (texinfo-discard-line) + (insert "START-INFO-DIR-ENTRY\n")) + +(put 'direntry 'texinfo-end 'texinfo-end-direntry) +(ptexinfmt-defun-if-void texinfo-end-direntry () + (texinfo-discard-command) + (insert "END-INFO-DIR-ENTRY\n\n") + (texinfo-pop-stack 'direntry)) + + +;;; Block Enclosing +;; @detailmenu ... @end detailmenu +(put 'detailmenu 'texinfo-format 'texinfo-discard-line) +(put 'detailmenu 'texinfo-end 'texinfo-discard-command) + +;; @smalldisplay ... @end smalldisplay +(put 'smalldisplay 'texinfo-format 'texinfo-format-example) +(put 'smalldisplay 'texinfo-end 'texinfo-end-example) + +;; @smallformat ... @end smallformat +(put 'smallformat 'texinfo-format 'texinfo-format-flushleft) +(put 'smallformat 'texinfo-end 'texinfo-end-flushleft) + +;; @cartouche ... @end cartouche +(put 'cartouche 'texinfo-format 'texinfo-discard-line) +(put 'cartouche 'texinfo-end 'texinfo-discard-command) + + +;;; Conditional +;; @ifnottex ... @end ifnottex (makeinfo 3.11 or later) +(put 'ifnottex 'texinfo-format 'texinfo-discard-line) +(put 'ifnottex 'texinfo-end 'texinfo-discard-command) + +;; @ifnothtml ... @end ifnothtml (makeinfo 3.11 or later) +(put 'ifnothtml 'texinfo-format 'texinfo-discard-line) +(put 'ifnothtml 'texinfo-end 'texinfo-discard-command) + +;; @ifnotplaintext ... @end ifnotplaintext (makeinfo 4.2 or later) +(put 'ifnotplaintext 'texinfo-format 'texinfo-discard-line) +(put 'ifnotplaintext 'texinfo-end 'texinfo-discard-command) + +;; @ifnotdocbook ... @end ifnotdocbook (makeinfo 4.7 or later) +(put 'ifnotdocbook 'texinfo-format 'texinfo-discard-line) +(put 'ifnotdocbook 'texinfo-end 'texinfo-discard-command) + +;; @ifnotinfo ... @end ifnotinfo (makeinfo 3.11 or later) +(put 'ifnotinfo 'texinfo-format 'texinfo-format-ifnotinfo) +(ptexinfmt-defun-if-void texinfo-format-ifnotinfo () + (delete-region texinfo-command-start + (progn (re-search-forward "@end ifnotinfo[ \t]*\n") + (point)))) + +;; @html ... @end html (makeinfo 3.11 or later) +(put 'html 'texinfo-format 'texinfo-format-html) +(ptexinfmt-defun-if-void texinfo-format-html () + (delete-region texinfo-command-start + (progn (re-search-forward "@end html[ \t]*\n") + (point)))) + +;; @docbook ... @end docbook (makeinfo 4.7 or later) +(put 'docbook 'texinfo-format 'texinfo-format-docbook) +(ptexinfmt-defun-if-void texinfo-format-docbook () + (delete-region texinfo-command-start + (progn (re-search-forward "@end docbook[ \t]*\n") + (point)))) + +;; @ifhtml ... @end ifhtml (makeinfo 3.8 or later) +(put 'ifhtml 'texinfo-format 'texinfo-format-ifhtml) +(defun texinfo-format-ifhtml () + (delete-region texinfo-command-start + (progn (re-search-forward "@end ifhtml[ \t]*\n") + (point)))) + +;; @ifplaintext ... @end ifplaintext (makeinfo 4.2 or later) +(put 'ifplaintext 'texinfo-format 'texinfo-format-ifplaintext) +(ptexinfmt-defun-if-void texinfo-format-ifplaintext () + (delete-region texinfo-command-start + (progn (re-search-forward "@end ifplaintext[ \t]*\n") + (point)))) + +;; @ifdocbook ... @end ifdocbook (makeinfo 4.7 or later) +(put 'ifdocbook 'texinfo-format 'texinfo-format-ifdocbook) +(ptexinfmt-defun-if-void texinfo-format-ifdocbook () + (delete-region texinfo-command-start + (progn (re-search-forward "@end ifdocbook[ \t]*\n") + (point)))) + + +;;; Marking +;; @indicateurl, @url, @env, @command, +(put 'env 'texinfo-format 'texinfo-format-code) +(put 'command 'texinfo-format 'texinfo-format-code) + +(put 'indicateurl 'texinfo-format 'texinfo-format-code) +(put 'url 'texinfo-format 'texinfo-format-uref) ; Texinfo 4.7 + +;; @acronym +(put 'acronym 'texinfo-format 'texinfo-format-var) + +(ptexinfmt-defun-if-broken texinfo-format-var () + (let ((arg (texinfo-parse-expanded-arg))) + (texinfo-discard-command) + (insert (upcase arg)))) + +;; @key +(put 'key 'texinfo-format 'texinfo-format-key) +(ptexinfmt-defun-if-void texinfo-format-key () + (insert (texinfo-parse-arg-discard)) + (goto-char texinfo-command-start)) + +;; @email{EMAIL-ADDRESS[, DISPLAYED-TEXT]} +(put 'email 'texinfo-format 'texinfo-format-email) +(ptexinfmt-defun-if-void texinfo-format-email () + "Format EMAIL-ADDRESS and optional DISPLAYED-TXT. +Insert < ... > around EMAIL-ADDRESS." + (let ((args (texinfo-format-parse-args))) + (texinfo-discard-command) + ;; if displayed-text + (if (nth 1 args) + (insert (nth 1 args) " <" (nth 0 args) ">") + (insert "<" (nth 0 args) ">")))) + +;; @option +(put 'option 'texinfo-format 'texinfo-format-option) +(ptexinfmt-defun-if-void texinfo-format-option () + "Insert ` ... ' around arg unless inside a table; in that case, no quotes." + ;; `looking-at-backward' not available in v. 18.57, 20.2 + ;; searched-for character is a control-H + (if (not (search-backward "\010" + (save-excursion (beginning-of-line) (point)) + t)) + (insert "`" (texinfo-parse-arg-discard) "'") + (insert (texinfo-parse-arg-discard))) + (goto-char texinfo-command-start)) + +;; @verb{TEXT} (makeinfo 4.1 or later) +(put 'verb 'texinfo-format 'texinfo-format-verb) +(ptexinfmt-defun-if-void texinfo-format-verb () + "Format text between non-quoted unique delimiter characters verbatim. +Enclose the verbatim text, including the delimiters, in braces. Print +text exactly as written (but not the delimiters) in a fixed-width. + +For example, @verb\{|@|\} results in @ and +@verb\{+@'e?`!`+} results in @'e?`!`." + + (let ((delimiter (buffer-substring-no-properties + (1+ texinfo-command-end) (+ 2 texinfo-command-end)))) + (unless (looking-at "{") + (error "Not found: @verb start brace")) + (delete-region texinfo-command-start (+ 2 texinfo-command-end)) + (search-forward delimiter)) + (delete-backward-char 1) + (unless (looking-at "}") + (error "Not found: @verb end brace")) + (delete-char 1)) + + +;;; @LaTeX, @registeredsymbol{} +(put 'LaTeX 'texinfo-format 'texinfo-format-LaTeX) +(ptexinfmt-defun-if-void texinfo-format-LaTeX () + (texinfo-parse-arg-discard) + (insert "LaTeX")) + +(put 'registeredsymbol 'texinfo-format 'texinfo-format-registeredsymbol) +(ptexinfmt-defun-if-void texinfo-format-registeredsymbol () + (texinfo-parse-arg-discard) + (insert "(R)")) + +;;; Accents and Special characters +;; @euro{} ==> Euro +(put 'euro 'texinfo-format 'texinfo-format-euro) +(ptexinfmt-defun-if-void texinfo-format-euro () + (texinfo-parse-arg-discard) + (insert "Euro ")) + +;; @pounds{} ==> # Pounds Sterling +(put 'pounds 'texinfo-format 'texinfo-format-pounds) +(ptexinfmt-defun-if-void texinfo-format-pounds () + (texinfo-parse-arg-discard) + (insert "#")) + +;; @ordf{} ==> a Spanish feminine +(put 'ordf 'texinfo-format 'texinfo-format-ordf) +(ptexinfmt-defun-if-void texinfo-format-ordf () + (texinfo-parse-arg-discard) + (insert "a")) + +;; @ordm{} ==> o Spanish masculine +(put 'ordm 'texinfo-format 'texinfo-format-ordm) +(ptexinfmt-defun-if-void texinfo-format-ordm () + (texinfo-parse-arg-discard) + (insert "o")) + +;; @OE{} ==> OE French-OE-ligature +(put 'OE 'texinfo-format 'texinfo-format-French-OE-ligature) +(ptexinfmt-defun-if-void texinfo-format-French-OE-ligature () + (insert "OE" (texinfo-parse-arg-discard)) + (goto-char texinfo-command-start)) + +;; @oe{} ==> oe +(put 'oe 'texinfo-format 'texinfo-format-French-oe-ligature) +(ptexinfmt-defun-if-void texinfo-format-French-oe-ligature () ; lower case + (insert "oe" (texinfo-parse-arg-discard)) + (goto-char texinfo-command-start)) + +;; @AA{} ==> AA Scandinavian-A-with-circle +(put 'AA 'texinfo-format 'texinfo-format-Scandinavian-A-with-circle) +(ptexinfmt-defun-if-void texinfo-format-Scandinavian-A-with-circle () + (insert "AA" (texinfo-parse-arg-discard)) + (goto-char texinfo-command-start)) + +;; @aa{} ==> aa +(put 'aa 'texinfo-format 'texinfo-format-Scandinavian-a-with-circle) +(ptexinfmt-defun-if-void texinfo-format-Scandinavian-a-with-circle () ; lower case + (insert "aa" (texinfo-parse-arg-discard)) + (goto-char texinfo-command-start)) + +;; @AE{} ==> AE Latin-Scandinavian-AE +(put 'AE 'texinfo-format 'texinfo-format-Latin-Scandinavian-AE) +(ptexinfmt-defun-if-void texinfo-format-Latin-Scandinavian-AE () + (insert "AE" (texinfo-parse-arg-discard)) + (goto-char texinfo-command-start)) + +;; @ae{} ==> ae +(put 'ae 'texinfo-format 'texinfo-format-Latin-Scandinavian-ae) +(ptexinfmt-defun-if-void texinfo-format-Latin-Scandinavian-ae () ; lower case + (insert "ae" (texinfo-parse-arg-discard)) + (goto-char texinfo-command-start)) + +;; @ss{} ==> ss German-sharp-S +(put 'ss 'texinfo-format 'texinfo-format-German-sharp-S) +(ptexinfmt-defun-if-void texinfo-format-German-sharp-S () + (insert "ss" (texinfo-parse-arg-discard)) + (goto-char texinfo-command-start)) + +;; @questiondown{} ==> ? upside-down-question-mark +(put 'questiondown 'texinfo-format 'texinfo-format-upside-down-question-mark) +(ptexinfmt-defun-if-void texinfo-format-upside-down-question-mark () + (insert "?" (texinfo-parse-arg-discard)) + (goto-char texinfo-command-start)) + +;; @exclamdown{} ==> ! upside-down-exclamation-mark +(put 'exclamdown 'texinfo-format 'texinfo-format-upside-down-exclamation-mark) +(ptexinfmt-defun-if-void texinfo-format-upside-down-exclamation-mark () + (insert "!" (texinfo-parse-arg-discard)) + (goto-char texinfo-command-start)) + +;; @L{} ==> L/ Polish suppressed-L (Lslash) +(put 'L 'texinfo-format 'texinfo-format-Polish-suppressed-L) +(ptexinfmt-defun-if-void texinfo-format-Polish-suppressed-L () + (insert (texinfo-parse-arg-discard) "/L") + (goto-char texinfo-command-start)) + +;; @l{} ==> l/ Polish suppressed-L (Lslash) (lower case) +(put 'l 'texinfo-format 'texinfo-format-Polish-suppressed-l-lower-case) +(ptexinfmt-defun-if-void texinfo-format-Polish-suppressed-l-lower-case () + (insert (texinfo-parse-arg-discard) "/l") + (goto-char texinfo-command-start)) + +;; @O{} ==> O/ Scandinavian O-with-slash +(put 'O 'texinfo-format 'texinfo-format-Scandinavian-O-with-slash) +(ptexinfmt-defun-if-void texinfo-format-Scandinavian-O-with-slash () + (insert (texinfo-parse-arg-discard) "O/") + (goto-char texinfo-command-start)) + +;; @o{} ==> o/ Scandinavian O-with-slash (lower case) +(put 'o 'texinfo-format 'texinfo-format-Scandinavian-o-with-slash-lower-case) +(ptexinfmt-defun-if-void texinfo-format-Scandinavian-o-with-slash-lower-case () + (insert (texinfo-parse-arg-discard) "o/") + (goto-char texinfo-command-start)) + +;; @,{c} ==> c, cedilla accent +(put '\, 'texinfo-format 'texinfo-format-cedilla-accent) +(ptexinfmt-defun-if-void texinfo-format-cedilla-accent () + (insert (texinfo-parse-arg-discard) ",") + (goto-char texinfo-command-start)) + + +;; @dotaccent{o} ==> .o overdot-accent +(put 'dotaccent 'texinfo-format 'texinfo-format-overdot-accent) +(ptexinfmt-defun-if-void texinfo-format-overdot-accent () + (insert "." (texinfo-parse-arg-discard)) + (goto-char texinfo-command-start)) + +;; @ubaraccent{o} ==> _o underbar-accent +(put 'ubaraccent 'texinfo-format 'texinfo-format-underbar-accent) +(ptexinfmt-defun-if-void texinfo-format-underbar-accent () + (insert "_" (texinfo-parse-arg-discard)) + (goto-char texinfo-command-start)) + +;; @udotaccent{o} ==> o-. underdot-accent +(put 'udotaccent 'texinfo-format 'texinfo-format-underdot-accent) +(ptexinfmt-defun-if-void texinfo-format-underdot-accent () + (insert (texinfo-parse-arg-discard) "-.") + (goto-char texinfo-command-start)) + +;; @H{o} ==> ""o long Hungarian umlaut +(put 'H 'texinfo-format 'texinfo-format-long-Hungarian-umlaut) +(ptexinfmt-defun-if-void texinfo-format-long-Hungarian-umlaut () + (insert "\"\"" (texinfo-parse-arg-discard)) + (goto-char texinfo-command-start)) + +;; @ringaccent{o} ==> *o ring accent +(put 'ringaccent 'texinfo-format 'texinfo-format-ring-accent) +(ptexinfmt-defun-if-void texinfo-format-ring-accent () + (insert "*" (texinfo-parse-arg-discard)) + (goto-char texinfo-command-start)) + +;; @tieaccent{oo} ==> [oo tie after accent +(put 'tieaccent 'texinfo-format 'texinfo-format-tie-after-accent) +(ptexinfmt-defun-if-void texinfo-format-tie-after-accent () + (insert "[" (texinfo-parse-arg-discard)) + (goto-char texinfo-command-start)) + +;; @u{o} ==> (o breve accent +(put 'u 'texinfo-format 'texinfo-format-breve-accent) +(ptexinfmt-defun-if-void texinfo-format-breve-accent () + (insert "(" (texinfo-parse-arg-discard)) + (goto-char texinfo-command-start)) + +;; @v{o} ==> i dotless i and dotless j +(put 'dotless 'texinfo-format 'texinfo-format-dotless) +(ptexinfmt-defun-if-void texinfo-format-dotless () + (insert (texinfo-parse-arg-discard)) + (goto-char texinfo-command-start)) + +;; @. +(put '\. 'texinfo-format 'texinfo-format-\.) +(ptexinfmt-defun-if-void texinfo-format-\. () + (texinfo-discard-command) + (insert ".")) + +;; @: +(put '\: 'texinfo-format 'texinfo-format-\:) +(ptexinfmt-defun-if-void texinfo-format-\: () + (texinfo-discard-command)) + +;; @- +(put '\- 'texinfo-format 'texinfo-format-soft-hyphen) +(ptexinfmt-defun-if-void texinfo-format-soft-hyphen () + (texinfo-discard-command)) + +;; @/ +(put '\/ 'texinfo-format 'texinfo-format-\/) +(ptexinfmt-defun-if-void texinfo-format-\/ () + (texinfo-discard-command)) + + +;;; Cross References +;; @ref, @xref +(put 'ref 'texinfo-format 'texinfo-format-xref) + +(ptexinfmt-defun-if-broken texinfo-format-xref () + (let ((args (texinfo-format-parse-args))) + (texinfo-discard-command) + (insert "*Note ") + (let ((fname (or (nth 1 args) (nth 2 args)))) + (if (null (or fname (nth 3 args))) + (insert (nth 0 args) "::") + (insert (or fname (nth 0 args)) ": ") + (if (nth 3 args) + (insert "(" (nth 3 args) ")")) + (unless (null (nth 0 args)) + (insert (nth 0 args))))))) + +;; @uref{URL [,TEXT] [,REPLACEMENT]} +(put 'uref 'texinfo-format 'texinfo-format-uref) +(ptexinfmt-defun-if-broken texinfo-format-uref () + "Format URL and optional URL-TITLE. +Insert ` ... ' around URL if no URL-TITLE argument; +otherwise, insert URL-TITLE followed by URL in parentheses." + (let ((args (texinfo-format-parse-args))) + (texinfo-discard-command) + ;; if url-title + (if (nth 1 args) + (insert (nth 1 args) " (" (nth 0 args) ")") + (insert "`" (nth 0 args) "'")))) + +;; @inforef +(put 'inforef 'texinfo-format 'texinfo-format-inforef) +(ptexinfmt-defun-if-void texinfo-format-inforef () + (let ((args (texinfo-format-parse-args))) + (texinfo-discard-command) + (if (nth 1 args) + (insert "*Note " (nth 1 args) ": (" (nth 2 args) ")" (car args)) + (insert "*Note " "(" (nth 2 args) ")" (car args) "::")))) + + +;; @anchor +;; don't emulation +;; If support @anchor for Mule 2.3, We must fix informat.el and info.el: +;; - Info-tagify suport @anthor-*-refill. +;; - info.el support Ref in Tag table. +(unless (get 'anchor 'texinfo-format) + (put 'anchor 'texinfo-format 'texinfo-discard-command-and-arg)) + + + +;;; New command definition +;; @alias NEW=EXISTING +(put 'alias 'texinfo-format 'texinfo-alias) +(ptexinfmt-defun-if-void texinfo-alias () + (let ((start (1- (point))) + args) + (skip-chars-forward " ") + (save-excursion (end-of-line) (setq texinfo-command-end (point))) + (if (not (looking-at "\\([^=]+\\)=\\(.*\\)")) + (error "Invalid alias command") + (setq texinfo-alias-list + (cons + (cons + (buffer-substring (match-beginning 1) (match-end 1)) + (buffer-substring (match-beginning 2) (match-end 2))) + texinfo-alias-list)) + (texinfo-discard-command)))) + + +;;; Indent +;; @exampleindent INDENT (makeinfo 4.0 or later) + +;; @paragraphindent INDENT (makeinfo 4.0 or later) +;; INDENT: asis, 0, n + +;; @firstparagraphindent WORD (makeinfo 4.6 or later) +;; WORD: none, insert + + + +;;; Special +;; @image{FILENAME [, WIDTH] [, HEIGHT]} +(put 'image 'texinfo-format 'texinfo-format-image) +(ptexinfmt-defun-if-void texinfo-format-image () + ;; I don't know makeinfo parse FILENAME. + (let ((args (texinfo-format-parse-args)) + filename) + (when (null (nth 0 args)) + (error "Invalid image command")) + (texinfo-discard-command) + ;; makeinfo uses FILENAME.txt + (setq filename (format "%s.txt" (nth 0 args))) + (message "Reading included file: %s" filename) + ;; verbatim for Info output + (goto-char (+ (point) (cadr (insert-file-contents filename)))) + (message "Reading included file: %s...done" filename))) + +;; @hyphenation command discards an argument within braces +(put 'hyphenation 'texinfo-format 'texinfo-discard-command-and-arg) +(ptexinfmt-defun-if-void texinfo-discard-command-and-arg () + "Discard both @-command and its argument in braces." + (goto-char texinfo-command-end) + (forward-list 1) + (setq texinfo-command-end (point)) + (delete-region texinfo-command-start texinfo-command-end)) + + +;;; @multitable ... @end multitable +(ptexinfmt-defvar-if-void texinfo-extra-inter-column-width 0 + "*Number of extra spaces between entries (columns) in @multitable.") + +(ptexinfmt-defvar-if-void texinfo-multitable-buffer-name + "*multitable-temporary-buffer*") +(ptexinfmt-defvar-if-void texinfo-multitable-rectangle-name + "texinfo-multitable-temp-") + +;; These commands are defined in texinfo.tex for printed output. +(put 'multitableparskip 'texinfo-format 'texinfo-discard-line-with-args) +(put 'multitableparindent 'texinfo-format 'texinfo-discard-line-with-args) +(put 'multitablecolmargin 'texinfo-format 'texinfo-discard-line-with-args) +(put 'multitablelinespace 'texinfo-format 'texinfo-discard-line-with-args) + +(put 'multitable 'texinfo-format 'texinfo-multitable) + +(ptexinfmt-defun-if-void texinfo-multitable () + "Produce multi-column tables." + +;; This function pushes information onto the `texinfo-stack'. +;; A stack element consists of: +;; - type-of-command, i.e., multitable +;; - the information about column widths, and +;; - the position of texinfo-command-start. +;; e.g., ('multitable (1 2 3 4) 123) +;; The command line is then deleted. + (texinfo-push-stack + 'multitable + ;; push width information on stack + (texinfo-multitable-widths)) + (texinfo-discard-line-with-args)) + +(put 'multitable 'texinfo-end 'texinfo-end-multitable) +(ptexinfmt-defun-if-void texinfo-end-multitable () + "Discard the @end multitable line and pop the stack of multitable." + (texinfo-discard-command) + (texinfo-pop-stack 'multitable)) + +(ptexinfmt-defun-if-broken texinfo-multitable-widths () + "Return list of widths of each column in a multi-column table." + (let (texinfo-multitable-width-list) + ;; Fractions format: + ;; @multitable @columnfractions .25 .3 .45 + ;; + ;; Template format: + ;; @multitable {Column 1 template} {Column 2} {Column 3 example} + ;; Place point before first argument + (skip-chars-forward " \t") + (cond + ;; Check for common misspelling + ((looking-at "@columnfraction ") + (error "In @multitable, @columnfractions misspelled")) + ;; Case 1: @columnfractions .25 .3 .45 + ((looking-at "@columnfractions") + (forward-word 1) + (while (not (eolp)) + (setq texinfo-multitable-width-list + (cons + (truncate + (1- + (* fill-column (read (get-buffer (current-buffer)))))) + texinfo-multitable-width-list)))) + ;; + ;; Case 2: {Column 1 template} {Column 2} {Column 3 example} + ((looking-at "{") + (let ((start-of-templates (point))) + (while (not (eolp)) + (skip-chars-forward " \t") + (let* ((start-of-template (1+ (point))) + (end-of-template + ;; forward-sexp works with braces in Texinfo mode + (progn (forward-sexp 1) (1- (point))))) + (setq texinfo-multitable-width-list + (cons (- (progn + (goto-char end-of-template) + (current-column)) + (progn + (goto-char start-of-template) + (current-column))) + texinfo-multitable-width-list)) + ;; Remove carriage return from within a template, if any. + ;; This helps those those who want to use more than + ;; one line's worth of words in @multitable line. + (narrow-to-region start-of-template end-of-template) + (goto-char (point-min)) + (while (search-forward "\n" nil t) + (delete-char -1)) + (goto-char (point-max)) + (widen) + (forward-char 1))))) + ;; + ;; Case 3: Trouble + (t + (error "\ +You probably need to specify column widths for @multitable correctly"))) + ;; Check whether columns fit on page. + (let ((desired-columns + (+ + ;; between column spaces + (length texinfo-multitable-width-list) + ;; additional between column spaces, if any + texinfo-extra-inter-column-width + ;; sum of spaces for each entry + (apply '+ texinfo-multitable-width-list)))) + (if (> desired-columns fill-column) + (error (format "\ +Multi-column table width, %d chars, is greater than page width, %d chars." + desired-columns fill-column)))) + texinfo-multitable-width-list)) + +;; @item A1 @tab A2 @tab A3 +(ptexinfmt-defun-if-void texinfo-multitable-extract-row () + "Return multitable row, as a string. +End of row is beginning of next @item or beginning of @end. +Cells within rows are separated by @tab." + (skip-chars-forward " \t") + (let* ((start (point)) + (end (progn + (re-search-forward "@item\\|@end") + (match-beginning 0))) + (row (progn (goto-char end) + (skip-chars-backward " ") + ;; remove whitespace at end of argument + (delete-region (point) end) + (buffer-substring start (point))))) + (delete-region texinfo-command-start end) + row)) + +(put 'multitable 'texinfo-item 'texinfo-multitable-item) +(ptexinfmt-defun-if-void texinfo-multitable-item () + "Format a row within a multicolumn table. +Cells in row are separated by @tab. +Widths of cells are specified by the arguments in the @multitable line. +All cells are made to be the same height. +This command is executed when texinfmt sees @item inside @multitable." + (let ((original-buffer (current-buffer)) + (table-widths (reverse (car (cdr (car texinfo-stack))))) + (existing-fill-column fill-column) + start + end + (table-column 0) + (table-entry-height 0) + ;; unformatted row looks like: A1 @tab A2 @tab A3 + ;; extract-row command deletes the source line in the table. + (unformated-row (texinfo-multitable-extract-row))) + ;; Use a temporary buffer + (set-buffer (get-buffer-create texinfo-multitable-buffer-name)) + (delete-region (point-min) (point-max)) + (insert unformated-row) + (goto-char (point-min)) +;; 1. Check for correct number of @tab in line. + (let ((tab-number 1)) ;; one @tab between two columns + (while (search-forward "@tab" nil t) + (setq tab-number (1+ tab-number))) + (if (/= tab-number (length table-widths)) + (error "Wrong number of @tab's in a @multitable row"))) + (goto-char (point-min)) +;; 2. Format each cell, and copy to a rectangle + ;; buffer looks like this: A1 @tab A2 @tab A3 + ;; Cell #1: format up to @tab + ;; Cell #2: format up to @tab + ;; Cell #3: format up to eob + (while (not (eobp)) + (setq start (point)) + (setq end (save-excursion + (if (search-forward "@tab" nil 'move) + ;; Delete the @tab command, including the @-sign + (delete-region + (point) + (progn (forward-word -1) (1- (point))))) + (point))) + ;; Set fill-column *wider* than needed to produce inter-column space + (setq fill-column (+ 1 + texinfo-extra-inter-column-width + (nth table-column table-widths))) + (narrow-to-region start end) + ;; Remove whitespace before and after entry. + (skip-chars-forward " ") + (delete-region (point) (save-excursion (beginning-of-line) (point))) + (goto-char (point-max)) + (skip-chars-backward " ") + (delete-region (point) (save-excursion (end-of-line) (point))) + ;; Temorarily set texinfo-stack to nil so texinfo-format-scan + ;; does not see an unterminated @multitable. + (let (texinfo-stack) ;; nil + (texinfo-format-scan)) + (let (fill-prefix) ;; no fill prefix + (fill-region (point-min) (point-max))) + (setq table-entry-height + (max table-entry-height (count-lines (point-min) (point-max)))) +;; 3. Move point to end of bottom line, and pad that line to fill column. + (goto-char (point-min)) + (forward-line (1- table-entry-height)) + (let* ((beg (point)) ;; beginning of line + ;; add one more space for inter-column spacing + (needed-whitespace + (1+ + (- fill-column + (progn + (end-of-line) + (current-column)))))) ;; end of existing line + (insert (make-string + (if (> needed-whitespace 0) needed-whitespace 1) + ? ))) + ;; now, put formatted cell into a rectangle + (set (intern (concat texinfo-multitable-rectangle-name + (int-to-string table-column))) + (extract-rectangle (point-min) (point))) + (delete-region (point-min) (point)) + (goto-char (point-max)) + (setq table-column (1+ table-column)) + (widen)) +;; 4. Add extra lines to rectangles so all are of same height + (let ((total-number-of-columns table-column) + (column-number 0) + here) + (while (> table-column 0) + (let ((this-rectangle (int-to-string table-column))) + (while (< (length this-rectangle) table-entry-height) + (setq this-rectangle (append this-rectangle '(""))))) + (setq table-column (1- table-column))) +;; 5. Insert formatted rectangles in original buffer + (switch-to-buffer original-buffer) + (open-line table-entry-height) + (while (< column-number total-number-of-columns) + (setq here (point)) + (insert-rectangle + (eval (intern + (concat texinfo-multitable-rectangle-name + (int-to-string column-number))))) + (goto-char here) + (end-of-line) + (setq column-number (1+ column-number)))) + (kill-buffer texinfo-multitable-buffer-name) + (setq fill-column existing-fill-column))) + + +(ptexinfmt-defun-if-broken texinfo-format-printindex () + (let ((indexelts (symbol-value + (cdr (assoc (texinfo-parse-arg-discard) + texinfo-indexvar-alist)))) + opoint) + (insert "\n* Menu:\n\n") + (setq opoint (point)) + (texinfo-print-index nil indexelts) + + (if (memq system-type '(vax-vms windows-nt ms-dos)) + (texinfo-sort-region opoint (point)) + (shell-command-on-region opoint (point) "sort -fd" 1)))) + +(ptexinfmt-broken-facility texinfo-format-end-node () + (with-temp-buffer + (insert (prin1-to-string (symbol-function 'texinfo-format-end-node))) + (goto-char (point-min)) + (not (search-forward "fill-paragraph" nil t nil)))) + +(ptexinfmt-defun-if-broken texinfo-format-end-node () + (let (start + (arg (texinfo-parse-line-arg))) + (texinfo-discard-command) ; remove or insert whitespace, as needed + (delete-region (save-excursion (skip-chars-backward " \t\n") (point)) + (point)) + (insert (format " (%d) " texinfo-footnote-number)) + ;;(fill-paragraph nil) + (save-excursion + (if (search-forward "\n--------- Footnotes ---------\n" nil t) + (progn ; already have footnote, put new one before end of node + (if (re-search-forward "^@node" nil 'move) + (forward-line -1)) + (setq start (point)) + (insert (format "\n(%d) %s\n" texinfo-footnote-number arg)) + (fill-region start (point))) + ;; else no prior footnote + (if (re-search-forward "^@node" nil 'move) + (forward-line -1)) + (insert "\n--------- Footnotes ---------\n") + (setq start (point)) + (insert (format "\n(%d) %s\n" texinfo-footnote-number arg)))))) + +(provide 'ptexinfmt) + +;;; ptexinfmt.el ends here diff -Nru ddskk-16.2/make1.bat ddskk-16.2+0.20190423/make1.bat --- ddskk-16.2/make1.bat 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/make1.bat 2019-04-23 12:49:58.000000000 +0000 @@ -33,7 +33,7 @@ echo what-where : print where to install echo clean : cleaning garbage file echo test : load test/all-tests.el and execute ert-run-tests-batch-and-exit -echo get : download jisyo files from openlab.jp +echo get : download jisyo files from skk-dev.github.io/dict/ goto pauseend :compile diff -Nru ddskk-16.2/Makefile ddskk-16.2+0.20190423/Makefile --- ddskk-16.2/Makefile 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/Makefile 2019-04-23 12:49:58.000000000 +0000 @@ -3,7 +3,7 @@ # Maintainer: SKK Development Team -VERSION = 16.2 +VERSION = 16.2.50 BZIP2 = bzip2 -9 DATE = date @@ -14,6 +14,10 @@ GZIP = gzip -9 MD5 = md5 RM = /bin/rm -f +TEXI2PDF = /usr/bin/texi2pdf +MAKEINFO = /usr/bin/makeinfo +DBTOEPUB = /usr/bin/dbtoepub +KINDLEGEN = $(HOME)/bin/kindlegen SNAPBASE = ddskk-`$(DATE) '+%Y%m%d'` TAR = gtar XEMACS = xemacs @@ -39,9 +43,48 @@ package: $(XEMACS) $(FLAGS) -f SKK-MK-compile-package -info: +.SUFFIXES: .org .texi .info .html .pdf + +.org.html: + $(EMACS) $(FLAGS) -f SKK-MK-export-to-html + +html: doc/skk.org doc/skk.html + +texi: doc/skk.org doc/skk.texi + +# skk.org -> skk.texi -> skk.info +.org.texi: + $(EMACS) $(FLAGS) -f SKK-MK-export-to-texinfo + +.texi.info: $(EMACS) $(FLAGS) -f SKK-MK-compile-info +info: doc/skk.info doc/skk.texi doc/skk.org + +# skk.org -> skk.texi -> skk.pdf +# based on http://www.trueroad.jp/2016/05/14-01.html +pdf: doc/skk.pdf doc/skk.texi doc/skk.org + +.texi.pdf: + $(EMACS) $(FLAGS) -f SKK-MK-edit-texi + cd doc; \ + PDFTEX=luatex $(TEXI2PDF) --output=skk.pdf tmp.texi; \ + $(RM) tmp.texi + +# skk.org -> skk.texi -> skk.xml -> skk.epub -> skk.mobi +.SUFFIXES: .xml .epub .mobi + +mobi: doc/skk.mobi doc/skk.epub doc/skk.xml doc/skk.texi doc/skk.org + +.texi.xml: + $(MAKEINFO) --docbook doc/skk.texi -o doc/ + +.xml.epub: + $(DBTOEPUB) -s doc/mobi.xsl doc/skk.xml -o doc/skk.epub + +.epub.mobi: + - $(KINDLEGEN) doc/skk.epub -verbose -locale ja -o skk.mobi + install: $(EMACS) $(FLAGS) -f SKK-MK-install @@ -72,7 +115,10 @@ clean: -$(RM) leim-list.el skk-autoloads.el skk-setup.el *.elc experimental/*.elc \ auto-autoloads.el custom-load.el ert.el \ - ./doc/skk.info* `find . -name '*~'` `find . -name '.*~'` `find . -name '.#*'` + ./doc/skk.info* ./doc/skk.html* ./doc/skk.pdf \ + ./doc/skk.xml ./doc/skk.epub ./doc/skk.mobi \ + ./doc/*.aux ./doc/*.cp* ./doc/*.fn* ./doc/*.ky* ./doc/*.log ./doc/*.toc ./doc/*.vr* \ + `find . -name '*~'` `find . -name '.*~'` `find . -name '.#*'` release: clean $(RM) ../ddskk-$(VERSION).tar.gz ../ddskk-$(VERSION).tar.bz2 ;\ diff -Nru ddskk-16.2/nicola/ChangeLog ddskk-16.2+0.20190423/nicola/ChangeLog --- ddskk-16.2/nicola/ChangeLog 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/nicola/ChangeLog 2019-04-23 12:49:58.000000000 +0000 @@ -1,3 +1,9 @@ +2017-03-12 Tsuyoshi Kitamoto + + * makeit.bat, make1.bat: New file for NTEmacs. + + * NICOLA-DDSKK-CFG (install-prefix): Modify for NTEmacs. + 2016-10-01 Tsuyoshi Kitamoto * .cvsignore: Remove file. diff -Nru ddskk-16.2/nicola/make1.bat ddskk-16.2+0.20190423/nicola/make1.bat --- ddskk-16.2/nicola/make1.bat 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/nicola/make1.bat 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,52 @@ +echo off +rem MAKE1.BAT for SKK. +rem Copyright (C) 1999 Yuh Ohmura, mailto:yutopia@y6.dion.ne.jp +rem +rem Author: Yuh Ohmura, mailto:yutopia@y6.dion.ne.jp +rem Maintainer: SKK Development Team mailto:skk@ring.gr.jp +rem Created: March 23, 1999 + +rem --- modified 2017/03/12, Tsuyoshi Kitamoto + +rem --- check calling from makeit.bat +if not "%SUBMAKEOK%"=="OK" goto prnusage +set SUBMAKEOK= + +rem argument check + +set arg1=%1 + +if "%arg1%"=="elc" goto compile +if "%arg1%"=="install" goto install +if "%arg1%"=="clean" goto clean + +echo Unrecognized argument: specify either +echo elc : byte compile +echo install : install +echo clean : cleaning garbage file +goto pauseend + +:compile +%EMACS% -batch -q -no-site-file -l NICOLA-DDSKK-MK -f compile-nicola-ddskk +goto end + +:install +%EMACS% -batch -q -no-site-file -l NICOLA-DDSKK-MK -f install-nicola-ddskk +goto end + +:clean +del *.elc auto-autoloads.el custom-load.el nicola-ddskk-autoloads.el + +goto end + +rem --- This file should not be executed by itself. Use makeit.bat. +:prnusage +echo This file should not be executed by itself. Use makeit.bat. + +rem --- If error occurs, stay display until any key is typed. +:pauseend +echo Type any key when you're done reading the error message. +pause + +:end + diff -Nru ddskk-16.2/nicola/makeit.bat ddskk-16.2+0.20190423/nicola/makeit.bat --- ddskk-16.2/nicola/makeit.bat 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/nicola/makeit.bat 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,209 @@ +@echo off +rem --- +rem --- common install batch file for Meadow & NTEmacs +rem --- 1999/07/07, Masaki YATSU mailto:yatsu@aurora.dti.ne.jp +rem --- cmail ML member +rem --- modified 1999/12/01, Yuh Ohmura, mailto:yutopia@y6.dion.ne.jp +rem --- modified 2000/12/26, Takeshi Morishima mailto:tm@interaccess.com + +set ELISPMK_APP=skk + +rem --- Japanese Comments: +rem --- +rem --- +rem --- ɂ‚Ă make1.bat ̃RgQƂĂD +rem --- makeit.bat ́A‹ϐݒ肵 make1.bat Ăяo܂B +rem --- +rem --- ϐݒ +rem --- ̃RĝƂɂ PREFIX, EMACS, EXEC_PREFIX, LISPDIR, +rem --- INFODIR, VERSION_SPECIFIC_LISPDIR ̊eϐCg̊‹ +rem --- KɍĐݒ肵ĂD +rem --- EMACS ̒lƂ emacs.exe w肷̂YȂ悤ɁD +rem --- +rem --- KXw肪I makeit.bat ͉̂ꂩ̃t@CƂ +rem --- Rs[ĂƂD悵Ďs܂B(AbvO[h +rem --- ̍ۂ makeit.bat ĕҏWKv܂.) D揇: +rem --- +rem --- 1-1. %HOME%\.elispmk.%ELISPMK_APP%.bat +rem --- 1-2. %HOME%\elisp\elispmk.%ELISPMK_APP%.bat +rem --- 1-3. %HOME%\config\elispmk.%ELISPMK_APP%.bat +rem --- 1-4. c:\Program Files\Meadow\elispmk.%ELISPMK_APP%.bat +rem --- 1-5. c:\Meadow\elispmk.%ELISPMK_APP%.bat +rem --- 1-6. d:\Meadow\elispmk.%ELISPMK_APP%.bat +rem --- +rem --- 2-1. %HOME%\.elispmk.bat +rem --- 2-2. %HOME%\elisp\elispmk.bat +rem --- 2-3. %HOME%\config\elispmk.bat +rem --- 2-4. c:\Program Files\Meadow\elispmk.bat +rem --- 2-5. c:\Meadow\elispmk.bat +rem --- 2-6. d:\Meadow\elispmk.bat +rem --- +rem --- ƂȂ܂B +rem --- +rem --- English Comments: +rem --- +rem --- Arguments +rem --- Please refer to comment section of make1.bat. Makeit.bat +rem --- will perform installation procedure by executing make1.bat. +rem --- +rem --- Specifying variables +rem --- After this comment section, PREFIX, EMACS, EXEC_PREFIX, +rem --- LISPDIR, INFODIR, VERSION_SPECIFIC_LISPDIR is defined using +rem --- 'set' batch command. Please specify them appropriately +rem --- according to your Emacs environment. Especially remember to set +rem --- the EMACS variable to emacs.exe. +rem --- +rem --- After modification, you may make a copy of makeit.bat as a pre- +rem --- configured file as one of the following name. Any future +rem --- execution of makeit.bat will automatically use this pre- +rem --- configured batch file instead of makeit.bat itself. (When +rem --- upgrading new distribution file for example, you do not have to +rem --- make modification to makeit.bat again.) A pre-configured batch +rem --- file is searched in order listed below: +rem --- +rem --- 1-1. %HOME%\.elispmk.%ELISPMK_APP%.bat +rem --- 1-2. %HOME%\elisp\elispmk.%ELISPMK_APP%.bat +rem --- 1-3. %HOME%\config\elispmk.%ELISPMK_APP%.bat +rem --- 1-4. c:\Program Files\Meadow\elispmk.%ELISPMK_APP%.bat +rem --- 1-5. c:\Meadow\elispmk.%ELISPMK_APP%.bat +rem --- 1-6. d:\Meadow\elispmk.%ELISPMK_APP%.bat +rem --- +rem --- 2-1. %HOME%\.elispmk.bat +rem --- 2-2. %HOME%\elisp\elispmk.bat +rem --- 2-3. %HOME%\config\elispmk.bat +rem --- 2-4. c:\Program Files\Meadow\elispmk.bat +rem --- 2-5. c:\Meadow\elispmk.bat +rem --- 2-6. d:\Meadow\elispmk.bat + +rem --- ϐݒ̗ (Example of variable definition) +rem --- c:\usr\emacs ɃCXg[Ă Emacs 24.4 gp +rem --- Ăꍇ̐ݒ. (An example of variable definition. In +rem --- this example, Emacs 24.4 installed in c:\usr\emacs directory +rem --- is used.) +rem --- set PREFIX= +rem --- set EMACS=c:\usr\bin\emacs.exe +rem --- set EXEC_PREFIX= +rem --- set LISPDIR= +rem --- set VERSION_SPECIFIC_LISPDIR= +rem --- set DEFAULT_MAKE_ARG=elc +rem --- Ŝ߃ftHg̒lׂ͂ċ󕶎ɂȂĂ܂B +rem --- Emacs 24.4 ȍ~͂܂ł Emacs ƃfBNg\ύXɂȂĂ܂B +rem --- CXg[[̓CXg[̃fBNg\IɌm܂̂ŁA +rem --- ɕKv̖ꍇ͏L̗ EMACS ݂̂ύXĉB +rem --- (To take a +rem --- safe side, default values are all set to null strings. Please +rem --- specify these variables accordingly for your system.) +rem --- ȂADEFAULT_MAKE_ARG ɉ”\Ȓl make1.bat 䗗B +rem --- (Please see make1.bat for possible values of DEFAULT_MAKE_ARG.) + +set PREFIX= +set EMACS= +set LISPDIR= +set DEFAULT_MAKE_ARG= + + +rem --- makeit.bat Ă΂Ăꍇ͍ċAĂяo make1 s +if not "%ELISPMK%"=="" goto execsubmk + +rem --- +set ELISPMK=%HOME%\.elispmk.%ELISPMK_APP%.bat +if exist %ELISPMK% goto execelmkb +set ELISPMK=%HOME%\elisp\elispmk.%ELISPMK_APP%.bat +if exist %ELISPMK% goto execelmkb +set ELISPMK=%HOME%\config\elispmk.%ELISPMK_APP%.bat +if exist %ELISPMK% goto execelmkb +set ELISPMK="c:\Program Files\Meadow\elispmk.%ELISPMK_APP%.bat" +if exist %ELISPMK% goto execelmkb +set ELISPMK=c:\Meadow\elispmk.%ELISPMK_APP%.bat +if exist %ELISPMK% goto execelmkb +set ELISPMK=d:\Meadow\elispmk.%ELISPMK_APP%.bat +if exist %ELISPMK% goto execelmkb +rem --- +set ELISPMK=%HOME%\.elispmk.bat +if exist %ELISPMK% goto execelmkb +set ELISPMK=%HOME%\elisp\elispmk.bat +if exist %ELISPMK% goto execelmkb +set ELISPMK=%HOME%\config\elispmk.bat +if exist %ELISPMK% goto execelmkb +set ELISPMK="c:\Program Files\Meadow\elispmk.bat" +if exist %ELISPMK% goto execelmkb +set ELISPMK=c:\Meadow\elispmk.bat +if exist %ELISPMK% goto execelmkb +set ELISPMK=d:\Meadow\elispmk.bat +if exist %ELISPMK% goto execelmkb + +echo ---- +echo INFORMATIVE: No pre-configured batch (e.g. ~/.elispmk.bat +echo INFORMATIVE: or ~/.elispmk.%ELISPMK_APP%.bat) found. +echo INFORMATIVE: You may create one for your convenience. +echo INFORMATIVE: See comments in makeit.bat. +echo ---- + +:execsubmk +set ELISPMK= +rem --- %EMACS% `͕s݂̏ꍇ̓G[I +if "%EMACS%"=="" goto errnotspecified +if not exist "%EMACS%" goto errnonexistent + +rem --- MAKE1.BAT Control +set SUBMAKEOK=OK + +echo ---- +echo Executing make1.bat in the current directory using the following env. +echo HOME=%HOME% +echo PREFIX=%PREFIX% +echo EMACS=%EMACS% +echo EXEC_PREFIX=%EXEC_PREFIX% +echo LISPDIR=%LISPDIR% +echo INFODIR=%INFODIR% +echo VERSION_SPECIFIC_LISPDIR=%VERSION_SPECIFIC_LISPDIR% +echo ---- + +set ARG=%1 +if "%ARG%"=="" set ARG=%DEFAULT_MAKE_ARG% + +echo Executing .\make1.bat with argument=%ARG% +.\make1.bat %ARG% + +echo Error: for some reason .\make1.bat could not be executed. +echo Please check if .\make1.bat exists and correct. +goto pauseend + +:execelmkb +echo ---- +echo Found %ELISPMK%. Executing it... +echo ---- +%ELISPMK% %1 +echo Error: for some reason %ELISPMK% could not be executed. +echo Please check if ELISPMK=%ELISPMK% exists and correct. +goto printenv + +rem --- %EMACS% ݒ肳ĂȂ +:errnotspecified +echo Error: Environment variable EMACS is not specified. +goto printenv + +rem --- %EMACS% ɐݒ肳Ăt@C݂Ȃ +:errnonexistent +echo Error: EMACS=%EMACS% does not exist. + +:printenv +echo ---- +echo Check correctness of the following environment variables. +echo HOME=%HOME% +echo PREFIX=%PREFIX% +echo EMACS=%EMACS% +echo EXEC_PREFIX=%EXEC_PREFIX% +echo LISPDIR=%LISPDIR% +echo INFODIR=%INFODIR% +echo VERSION_SPECIFIC_LISPDIR=%VERSION_SPECIFIC_LISPDIR% +echo DEFAULT_MAKE_ARG=%DEFAULT_MAKE_ARG% +echo See comments in makeit.bat and make1.bat for setup instruction. +echo ---- + +:pauseend +echo Type any key when you're done reading the error message. +pause + +rem --- end of makeit.bat +:end diff -Nru ddskk-16.2/nicola/NICOLA-DDSKK-CFG ddskk-16.2+0.20190423/nicola/NICOLA-DDSKK-CFG --- ddskk-16.2/nicola/NICOLA-DDSKK-CFG 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/nicola/NICOLA-DDSKK-CFG 2019-04-23 12:49:58.000000000 +0000 @@ -39,7 +39,10 @@ (if (boundp 'VERSION_SPECIFIC_LISPDIR) (add-to-list 'load-path VERSION_SPECIFIC_LISPDIR)) -(require 'install (expand-file-name "install.el" "..")) +(require 'install + (expand-file-name + (convert-standard-filename "maint/install.el") + (file-name-directory (directory-file-name default-directory)))) (defvar emacs-self-contained nil) @@ -49,7 +52,11 @@ (cond ((eq system-type 'windows-nt) ;; Meadow, NTEmacs (setq emacs-self-contained t) - (expand-file-name ".." exec-directory)) + (if (string-match "libexec" exec-directory) + (expand-file-name "share/emacs" + (expand-file-name "../../../../" exec-directory)) + (expand-file-name ".." exec-directory)) ) + ((eq system-type 'darwin) ;; Carbon Emacs or Cocoa Emacs (or system-default Emacs) (let ((dir (expand-file-name ".." data-directory))) @@ -58,8 +65,10 @@ (setq emacs-self-contained t) dir) (expand-file-name "../../.." dir)))) + ((featurep 'xemacs) (expand-file-name "../../.." exec-directory)) + (t (expand-file-name "../../../.." data-directory)))) diff -Nru ddskk-16.2/patches/emacs22-gtk-fix-dynamic-menus.diff ddskk-16.2+0.20190423/patches/emacs22-gtk-fix-dynamic-menus.diff --- ddskk-16.2/patches/emacs22-gtk-fix-dynamic-menus.diff 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/patches/emacs22-gtk-fix-dynamic-menus.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,172 +0,0 @@ -* Emacs should properly render dynamically generated menus. - Patch: fix-dynamic-menus.diff - Originally-reported-by: Baylis Shanks - Date: Sat, 10 Oct 2009 22:15:05 UTC - Added-by: Rob Browning - Backported-by: Reinhard Tartler - Status: incorporated upstream - Bug: 550541 - - This Debian patch is taken from this upstream commit: - - commit 3715ffe3e3b2c64d113bf26d94aab559f8559e83 - Author: Jan Djärv - Date: Wed Sep 2 17:03:20 2009 +0000 - - It was backported to emacs22 for the ubuntu package - ---- a/src/xfns.c -+++ b/src/xfns.c -@@ -369,10 +369,7 @@ x_any_window_to_frame (dpyinfo, wdesc) - #ifdef USE_GTK - GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc); - if (gwdesc != 0 -- && (gwdesc == x->widget -- || gwdesc == x->edit_widget -- || gwdesc == x->vbox_widget -- || gwdesc == x->menubar_widget)) -+ && gtk_widget_get_toplevel (gwdesc) == x->widget) - found = f; - #else - if (wdesc == XtWindow (x->widget) -@@ -393,54 +390,6 @@ x_any_window_to_frame (dpyinfo, wdesc) - return found; - } - --/* Likewise, but exclude the menu bar widget. */ -- --struct frame * --x_non_menubar_window_to_frame (dpyinfo, wdesc) -- struct x_display_info *dpyinfo; -- int wdesc; --{ -- Lisp_Object tail, frame; -- struct frame *f; -- struct x_output *x; -- -- if (wdesc == None) return 0; -- -- for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail)) -- { -- frame = XCAR (tail); -- if (!GC_FRAMEP (frame)) -- continue; -- f = XFRAME (frame); -- if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo) -- continue; -- x = f->output_data.x; -- /* This frame matches if the window is any of its widgets. */ -- if (x->hourglass_window == wdesc) -- return f; -- else if (x->widget) -- { --#ifdef USE_GTK -- GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc); -- if (gwdesc != 0 -- && (gwdesc == x->widget -- || gwdesc == x->edit_widget -- || gwdesc == x->vbox_widget)) -- return f; --#else -- if (wdesc == XtWindow (x->widget) -- || wdesc == XtWindow (x->column_widget) -- || wdesc == XtWindow (x->edit_widget)) -- return f; --#endif -- } -- else if (FRAME_X_WINDOW (f) == wdesc) -- /* A tooltip frame. */ -- return f; -- } -- return 0; --} -- - /* Likewise, but consider only the menu bar widget. */ - - struct frame * -@@ -468,15 +417,14 @@ x_menubar_window_to_frame (dpyinfo, wdes - if (x->menubar_widget) - { - GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc); -- int found = 0; - -- BLOCK_INPUT; -+ /* This gives false positives, but the rectangle check in xterm.c -+ where this is called takes care of that. */ - if (gwdesc != 0 - && (gwdesc == x->menubar_widget -- || gtk_widget_get_parent (gwdesc) == x->menubar_widget)) -- found = 1; -- UNBLOCK_INPUT; -- if (found) return f; -+ || gtk_widget_is_ancestor (x->menubar_widget, gwdesc) -+ || gtk_widget_is_ancestor (gwdesc, x->menubar_widget))) -+ return f; - } - #else - if (x->menubar_widget ---- a/src/xterm.c -+++ b/src/xterm.c -@@ -110,8 +110,6 @@ extern void xlwmenu_redisplay P_ ((Widge - #if defined (USE_X_TOOLKIT) || defined (USE_GTK) - - extern void free_frame_menubar P_ ((struct frame *)); --extern struct frame *x_menubar_window_to_frame P_ ((struct x_display_info *, -- int)); - #endif - - #ifdef USE_X_TOOLKIT -@@ -144,11 +142,6 @@ extern void _XEditResCheckMessages (); - - #endif /* USE_X_TOOLKIT */ - --#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK) --#define x_any_window_to_frame x_window_to_frame --#define x_top_window_to_frame x_window_to_frame --#endif -- - #ifdef USE_X_TOOLKIT - #include "widget.h" - #ifndef XtNinitialState -@@ -3788,7 +3781,14 @@ XTmouse_position (fp, insist, bar_window - - if (child == None || child == win) - break; -- -+#ifdef USE_GTK -+ /* We don't wan't to know the innermost window. We -+ want the edit window. For non-Gtk+ the innermost -+ window is the edit window. For Gtk+ it might not -+ be. It might be the tool bar for example. */ -+ if (x_window_to_frame (FRAME_X_DISPLAY_INFO (*fp), win)) -+ break; -+#endif - win = child; - parent_x = win_x; - parent_y = win_y; -@@ -3805,8 +3805,14 @@ XTmouse_position (fp, insist, bar_window - parent_{x,y} are invalid, but that's okay, because we'll - never use them in that case.) */ - -+#ifdef USE_GTK -+ /* We don't wan't to know the innermost window. We -+ want the edit window. */ -+ f1 = x_window_to_frame (FRAME_X_DISPLAY_INFO (*fp), win); -+#else - /* Is win one of our frames? */ - f1 = x_any_window_to_frame (FRAME_X_DISPLAY_INFO (*fp), win); -+#endif - - #ifdef USE_X_TOOLKIT - /* If we end up with the menu bar window, say it's not ---- a/src/xterm.h -+++ b/src/xterm.h -@@ -414,7 +414,7 @@ extern struct frame *x_window_to_frame P - - #if defined (USE_X_TOOLKIT) || defined (USE_GTK) - extern struct frame *x_any_window_to_frame P_ ((struct x_display_info *, int)); --extern struct frame *x_non_menubar_window_to_frame P_ ((struct x_display_info *, int)); -+extern struct frame *x_menubar_window_to_frame P_ ((struct x_display_info *, int)); - extern struct frame *x_top_window_to_frame P_ ((struct x_display_info *, int)); - #endif - diff -Nru ddskk-16.2/patches/README.ja ddskk-16.2+0.20190423/patches/README.ja --- ddskk-16.2/patches/README.ja 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/patches/README.ja 2019-04-23 12:49:58.000000000 +0000 @@ -1,11 +1,8 @@ -[emacs22-gtk-fix-dynamic-menus.diff] [emacs23_1-gtk-fix-dynamic-menus.diff] GTK 2.18 以降と Emacs の組合わせにて、メニューが更新されない問題に対す -るパッチ。修正前は SKK のメニューが表示されない。それぞれ Emacs 22 用、 -Emacs 23.1 用。 +るパッチ。修正前は SKK のメニューが表示されない。Emacs 23.1 用。 Cf. http://debbugs.gnu.org/cgi/bugreport.cgi?bug=4122 転載元 Ubuntu の diff より - http://archive.ubuntu.com/ubuntu/pool/universe/e/emacs22/emacs22_22.2-0ubuntu9.diff.gz http://archive.ubuntu.com/ubuntu/pool/main/e/emacs23/emacs23_23.1+1-4ubuntu7.diff.gz diff -Nru ddskk-16.2/ptexinfmt.el ddskk-16.2+0.20190423/ptexinfmt.el --- ddskk-16.2/ptexinfmt.el 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/ptexinfmt.el 1970-01-01 00:00:00.000000000 +0000 @@ -1,992 +0,0 @@ -;;; ptexinfmt.el -- portable Texinfo formatter. - -;; Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, -;; 1994, 1995, 1996, 1997 Free Software Foundation, Inc. -;; Copyright (C) 1999 Yoshiki Hayashi -;; Copyright (C) 2000, 2001, 2002 TAKAHASHI Kaoru - -;; Author: TAKAHASHI Kaoru -;; Yoshiki Hayashi -;; Katsumi Yamaoka -;; Maintainer: TAKAHASHI Kaoru -;; Created: 7 Jul 2000 -;; Keywords: maint, tex, docs, emulation, compatibility - -;; 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., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: - -;; Original code: Yoshiki Hayashi -;; makeinfo.el (gnujdoc project) - -;; Support texinfmt.el 2.32 or later. - -;; Modified by Yamaoka not to use APEL functions. - -;; Unimplemented command: -;; @abbr -;; @float, @caption, @shortcaption, @listoffloats -;; @deftypecv[x] -;; @headitem -;; @comma{} -;; @quotation (optional arguments) -;; @acronym (optional argument) -;; @dofirstparagraphindent -;; @indent -;; @verbatiminclude -;; @\ -;; @definfoenclose -;; @deftypeivar -;; @deftypeop -;; @allowcodebreaks - -;;; Code: - -(require 'backquote) -(require 'texinfmt) - -;;; Broken -(defvar ptexinfmt-disable-broken-notice-flag t - "If non-nil disable notice, when call `ptexinfmt-broken-facility'. -This is last argument in `ptexinfmt-broken-facility'.") - -(put 'ptexinfmt-broken-facility 'lisp-indent-function 'defun) -(defmacro ptexinfmt-broken-facility (facility docstring assertion - &optional dummy) - "Declare a symbol FACILITY is broken if ASSERTION is nil. -DOCSTRING will be printed if ASSERTION is nil and -`ptexinfmt-disable-broken-notice-flag' is nil." - `(let ((facility ',facility) - (docstring ,docstring) - (assertion (eval ',assertion))) - (put facility 'broken (not assertion)) - (if assertion - nil - (put facility 'broken-docstring docstring) - (if ptexinfmt-disable-broken-notice-flag - nil - (message "BROKEN FACILITY DETECTED: %s" docstring))))) - -(put 'ptexinfmt-defun-if-broken 'lisp-indent-function 'defun) -(defmacro ptexinfmt-defun-if-broken (&rest args) - "Redefine a function just like `defun' if it is considered broken." - (let ((name (list 'quote (car args)))) - (setq args (cdr args)) - `(prog1 - ,name - (if (get ,name 'broken) - (defalias ,name - (function (lambda ,@args))))))) - -(put 'ptexinfmt-defun-if-void 'lisp-indent-function 'defun) -(defmacro ptexinfmt-defun-if-void (&rest args) - "Define a function just like `defun' unless it is already defined." - (let ((name (list 'quote (car args)))) - (setq args (cdr args)) - `(prog1 - ,name - (if (fboundp ,name) - nil - (defalias ,name - (function (lambda ,@args))))))) - -(put 'ptexinfmt-defvar-if-void 'lisp-indent-function 'defun) -(defmacro ptexinfmt-defvar-if-void (&rest args) - "Define a variable just like `defvar' unless it is already defined." - (let ((name (car args))) - (setq args (cdr args)) - `(prog1 - (defvar ,name) - (if (boundp ',name) - nil - (defvar ,name ,@args))))) - -;; sort -fd -(ptexinfmt-broken-facility texinfo-format-printindex - "Can't sort on Mule for Windows." - (if (and (memq system-type '(windows-nt ms-dos)) -;;; I don't know version threshold. -;;; (string< texinfmt-version "2.37 of 24 May 1997") - (boundp 'MULE) (not (featurep 'meadow))) ; Mule for Windows - nil - t)) - -;; @var -(ptexinfmt-broken-facility texinfo-format-var - "Don't perse @var argument." - (condition-case nil - (with-temp-buffer - (let (texinfo-enclosure-list texinfo-alias-list) - (texinfo-mode) - (insert "@var{@asis{foo}}\n") - (texinfo-format-expand-region (point-min) (point-max)) - t)) - (error nil))) - -;; @xref -(ptexinfmt-broken-facility texinfo-format-xref - "Can't format @xref, 1st argument is empty." - (condition-case nil - (with-temp-buffer - (let (texinfo-enclosure-list texinfo-alias-list) - (texinfo-mode) - (insert "@xref{, xref, , file}\n") - (texinfo-format-expand-region (point-min) (point-max)) - t)) - (error nil))) - -;; @uref -(ptexinfmt-broken-facility texinfo-format-uref - "Parse twice @uref argument." - (condition-case nil - (with-temp-buffer - (let (texinfo-enclosure-list texinfo-alias-list) - (texinfo-mode) - (insert "@uref{mailto:foo@@noncommand.example.com}\n") - (texinfo-format-expand-region (point-min) (point-max)) - t)) - (error nil))) - -;; @multitable -(ptexinfmt-broken-facility texinfo-multitable-widths - "`texinfo-multitable-widths' unsupport wide-char." - (if (fboundp 'texinfo-multitable-widths) - (with-temp-buffer - (let ((str "$BI}9-J8;z(B")) - (texinfo-mode) - (insert (format " {%s}\n" str)) - (goto-char (point-min)) - (if (= (car (texinfo-multitable-widths)) (length str)) - t - nil))) - ;; function definition is void - nil)) - -(ptexinfmt-broken-facility texinfo-multitable-item - "`texinfo-multitable-item' unsupport wide-char." - (not (get 'texinfo-multitable-widths 'broken))) - - -;;; Hardcopy and HTML (discard) -;; html -(put 'documentlanguage 'texinfo-format 'texinfo-discard-line-with-args) -(put 'documentencoding 'texinfo-format 'texinfo-discard-line-with-args) -(put 'documentdescription 'texinfo-format 'texinfo-discard-line-with-args) - -;; size -(put 'smallbook 'texinfo-format 'texinfo-discard-line) -(put 'letterpaper 'texinfo-format 'texinfo-discard-line) -(put 'afourpaper 'texinfo-format 'texinfo-discard-line) -(put 'afourlatex 'texinfo-format 'texinfo-discard-line) -(put 'afourwide 'texinfo-format 'texinfo-discard-line) -(put 'afivepaper 'texinfo-format 'texinfo-discard-line) -(put 'pagesizes 'texinfo-format 'texinfo-discard-line-with-args) - -;; style -(put 'setchapternewpage 'texinfo-format 'texinfo-discard-line-with-args) -(put 'kbdinputstyle 'texinfo-format 'texinfo-discard-line-with-args) - -;; flags -(put 'setcontentsaftertitlepage 'texinfo-format 'texinfo-discard-line) -(put 'setshortcontentsaftertitlepage 'texinfo-format 'texinfo-discard-line) -(put 'novalidate 'texinfo-format 'texinfo-discard-line-with-args) -(put 'frenchspacing 'texinfo-format 'texinfo-discard-line-with-args) - -;; head & foot -(put 'headings 'texinfo-format 'texinfo-discard-line-with-args) -(put 'evenfooting 'texinfo-format 'texinfo-discard-line-with-args) -(put 'evenheading 'texinfo-format 'texinfo-discard-line-with-args) -(put 'oddfooting 'texinfo-format 'texinfo-discard-line-with-args) -(put 'oddheading 'texinfo-format 'texinfo-discard-line-with-args) -(put 'everyfooting 'texinfo-format 'texinfo-discard-line-with-args) -(put 'everyheading 'texinfo-format 'texinfo-discard-line-with-args) - -;; misc -(put 'page 'texinfo-format 'texinfo-discard-line) -(put 'hyphenation 'texinfo-format 'texinfo-discard-command-and-arg) - -;; @slanted{} (makeinfo 4.8 or later) -(put 'slanted 'texinfo-format 'texinfo-format-noop) - -;; @sansserif{} (makeinfo 4.8 or later) -(put 'sansserif 'texinfo-format 'texinfo-format-noop) - -;; @tie{} (makeinfo 4.3 or later) -(put 'tie 'texinfo-format 'texinfo-format-tie) -(ptexinfmt-defun-if-void texinfo-format-tie () - (texinfo-parse-arg-discard) - (insert " ")) - - -;;; Directory File -;; @direcategory -(put 'dircategory 'texinfo-format 'texinfo-format-dircategory) -(ptexinfmt-defun-if-void texinfo-format-dircategory () - (let ((str (texinfo-parse-arg-discard))) - (delete-region (point) - (progn - (skip-chars-forward " ") - (point))) - (insert "INFO-DIR-SECTION " str "\n"))) - -;; @direntry -(put 'direntry 'texinfo-format 'texinfo-format-direntry) -(ptexinfmt-defun-if-void texinfo-format-direntry () - (texinfo-push-stack 'direntry nil) - (texinfo-discard-line) - (insert "START-INFO-DIR-ENTRY\n")) - -(put 'direntry 'texinfo-end 'texinfo-end-direntry) -(ptexinfmt-defun-if-void texinfo-end-direntry () - (texinfo-discard-command) - (insert "END-INFO-DIR-ENTRY\n\n") - (texinfo-pop-stack 'direntry)) - - -;;; Block Enclosing -;; @detailmenu ... @end detailmenu -(put 'detailmenu 'texinfo-format 'texinfo-discard-line) -(put 'detailmenu 'texinfo-end 'texinfo-discard-command) - -;; @smalldisplay ... @end smalldisplay -(put 'smalldisplay 'texinfo-format 'texinfo-format-example) -(put 'smalldisplay 'texinfo-end 'texinfo-end-example) - -;; @smallformat ... @end smallformat -(put 'smallformat 'texinfo-format 'texinfo-format-flushleft) -(put 'smallformat 'texinfo-end 'texinfo-end-flushleft) - -;; @cartouche ... @end cartouche -(put 'cartouche 'texinfo-format 'texinfo-discard-line) -(put 'cartouche 'texinfo-end 'texinfo-discard-command) - - -;;; Conditional -;; @ifnottex ... @end ifnottex (makeinfo 3.11 or later) -(put 'ifnottex 'texinfo-format 'texinfo-discard-line) -(put 'ifnottex 'texinfo-end 'texinfo-discard-command) - -;; @ifnothtml ... @end ifnothtml (makeinfo 3.11 or later) -(put 'ifnothtml 'texinfo-format 'texinfo-discard-line) -(put 'ifnothtml 'texinfo-end 'texinfo-discard-command) - -;; @ifnotplaintext ... @end ifnotplaintext (makeinfo 4.2 or later) -(put 'ifnotplaintext 'texinfo-format 'texinfo-discard-line) -(put 'ifnotplaintext 'texinfo-end 'texinfo-discard-command) - -;; @ifnotdocbook ... @end ifnotdocbook (makeinfo 4.7 or later) -(put 'ifnotdocbook 'texinfo-format 'texinfo-discard-line) -(put 'ifnotdocbook 'texinfo-end 'texinfo-discard-command) - -;; @ifnotinfo ... @end ifnotinfo (makeinfo 3.11 or later) -(put 'ifnotinfo 'texinfo-format 'texinfo-format-ifnotinfo) -(ptexinfmt-defun-if-void texinfo-format-ifnotinfo () - (delete-region texinfo-command-start - (progn (re-search-forward "@end ifnotinfo[ \t]*\n") - (point)))) - -;; @html ... @end html (makeinfo 3.11 or later) -(put 'html 'texinfo-format 'texinfo-format-html) -(ptexinfmt-defun-if-void texinfo-format-html () - (delete-region texinfo-command-start - (progn (re-search-forward "@end html[ \t]*\n") - (point)))) - -;; @docbook ... @end docbook (makeinfo 4.7 or later) -(put 'docbook 'texinfo-format 'texinfo-format-docbook) -(ptexinfmt-defun-if-void texinfo-format-docbook () - (delete-region texinfo-command-start - (progn (re-search-forward "@end docbook[ \t]*\n") - (point)))) - -;; @ifhtml ... @end ifhtml (makeinfo 3.8 or later) -(put 'ifhtml 'texinfo-format 'texinfo-format-ifhtml) -(defun texinfo-format-ifhtml () - (delete-region texinfo-command-start - (progn (re-search-forward "@end ifhtml[ \t]*\n") - (point)))) - -;; @ifplaintext ... @end ifplaintext (makeinfo 4.2 or later) -(put 'ifplaintext 'texinfo-format 'texinfo-format-ifplaintext) -(ptexinfmt-defun-if-void texinfo-format-ifplaintext () - (delete-region texinfo-command-start - (progn (re-search-forward "@end ifplaintext[ \t]*\n") - (point)))) - -;; @ifdocbook ... @end ifdocbook (makeinfo 4.7 or later) -(put 'ifdocbook 'texinfo-format 'texinfo-format-ifdocbook) -(ptexinfmt-defun-if-void texinfo-format-ifdocbook () - (delete-region texinfo-command-start - (progn (re-search-forward "@end ifdocbook[ \t]*\n") - (point)))) - - -;;; Marking -;; @indicateurl, @url, @env, @command, -(put 'env 'texinfo-format 'texinfo-format-code) -(put 'command 'texinfo-format 'texinfo-format-code) - -(put 'indicateurl 'texinfo-format 'texinfo-format-code) -(put 'url 'texinfo-format 'texinfo-format-uref) ; Texinfo 4.7 - -;; @acronym -(put 'acronym 'texinfo-format 'texinfo-format-var) - -(ptexinfmt-defun-if-broken texinfo-format-var () - (let ((arg (texinfo-parse-expanded-arg))) - (texinfo-discard-command) - (insert (upcase arg)))) - -;; @key -(put 'key 'texinfo-format 'texinfo-format-key) -(ptexinfmt-defun-if-void texinfo-format-key () - (insert (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @email{EMAIL-ADDRESS[, DISPLAYED-TEXT]} -(put 'email 'texinfo-format 'texinfo-format-email) -(ptexinfmt-defun-if-void texinfo-format-email () - "Format EMAIL-ADDRESS and optional DISPLAYED-TXT. -Insert < ... > around EMAIL-ADDRESS." - (let ((args (texinfo-format-parse-args))) - (texinfo-discard-command) - ;; if displayed-text - (if (nth 1 args) - (insert (nth 1 args) " <" (nth 0 args) ">") - (insert "<" (nth 0 args) ">")))) - -;; @option -(put 'option 'texinfo-format 'texinfo-format-option) -(ptexinfmt-defun-if-void texinfo-format-option () - "Insert ` ... ' around arg unless inside a table; in that case, no quotes." - ;; `looking-at-backward' not available in v. 18.57, 20.2 - ;; searched-for character is a control-H - (if (not (search-backward "\010" - (save-excursion (beginning-of-line) (point)) - t)) - (insert "`" (texinfo-parse-arg-discard) "'") - (insert (texinfo-parse-arg-discard))) - (goto-char texinfo-command-start)) - -;; @verb{TEXT} (makeinfo 4.1 or later) -(put 'verb 'texinfo-format 'texinfo-format-verb) -(ptexinfmt-defun-if-void texinfo-format-verb () - "Format text between non-quoted unique delimiter characters verbatim. -Enclose the verbatim text, including the delimiters, in braces. Print -text exactly as written (but not the delimiters) in a fixed-width. - -For example, @verb\{|@|\} results in @ and -@verb\{+@'e?`!`+} results in @'e?`!`." - - (let ((delimiter (buffer-substring-no-properties - (1+ texinfo-command-end) (+ 2 texinfo-command-end)))) - (unless (looking-at "{") - (error "Not found: @verb start brace")) - (delete-region texinfo-command-start (+ 2 texinfo-command-end)) - (search-forward delimiter)) - (delete-backward-char 1) - (unless (looking-at "}") - (error "Not found: @verb end brace")) - (delete-char 1)) - - -;;; @LaTeX, @registeredsymbol{} -(put 'LaTeX 'texinfo-format 'texinfo-format-LaTeX) -(ptexinfmt-defun-if-void texinfo-format-LaTeX () - (texinfo-parse-arg-discard) - (insert "LaTeX")) - -(put 'registeredsymbol 'texinfo-format 'texinfo-format-registeredsymbol) -(ptexinfmt-defun-if-void texinfo-format-registeredsymbol () - (texinfo-parse-arg-discard) - (insert "(R)")) - -;;; Accents and Special characters -;; @euro{} ==> Euro -(put 'euro 'texinfo-format 'texinfo-format-euro) -(ptexinfmt-defun-if-void texinfo-format-euro () - (texinfo-parse-arg-discard) - (insert "Euro ")) - -;; @pounds{} ==> # Pounds Sterling -(put 'pounds 'texinfo-format 'texinfo-format-pounds) -(ptexinfmt-defun-if-void texinfo-format-pounds () - (texinfo-parse-arg-discard) - (insert "#")) - -;; @ordf{} ==> a Spanish feminine -(put 'ordf 'texinfo-format 'texinfo-format-ordf) -(ptexinfmt-defun-if-void texinfo-format-ordf () - (texinfo-parse-arg-discard) - (insert "a")) - -;; @ordm{} ==> o Spanish masculine -(put 'ordm 'texinfo-format 'texinfo-format-ordm) -(ptexinfmt-defun-if-void texinfo-format-ordm () - (texinfo-parse-arg-discard) - (insert "o")) - -;; @OE{} ==> OE French-OE-ligature -(put 'OE 'texinfo-format 'texinfo-format-French-OE-ligature) -(ptexinfmt-defun-if-void texinfo-format-French-OE-ligature () - (insert "OE" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @oe{} ==> oe -(put 'oe 'texinfo-format 'texinfo-format-French-oe-ligature) -(ptexinfmt-defun-if-void texinfo-format-French-oe-ligature () ; lower case - (insert "oe" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @AA{} ==> AA Scandinavian-A-with-circle -(put 'AA 'texinfo-format 'texinfo-format-Scandinavian-A-with-circle) -(ptexinfmt-defun-if-void texinfo-format-Scandinavian-A-with-circle () - (insert "AA" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @aa{} ==> aa -(put 'aa 'texinfo-format 'texinfo-format-Scandinavian-a-with-circle) -(ptexinfmt-defun-if-void texinfo-format-Scandinavian-a-with-circle () ; lower case - (insert "aa" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @AE{} ==> AE Latin-Scandinavian-AE -(put 'AE 'texinfo-format 'texinfo-format-Latin-Scandinavian-AE) -(ptexinfmt-defun-if-void texinfo-format-Latin-Scandinavian-AE () - (insert "AE" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @ae{} ==> ae -(put 'ae 'texinfo-format 'texinfo-format-Latin-Scandinavian-ae) -(ptexinfmt-defun-if-void texinfo-format-Latin-Scandinavian-ae () ; lower case - (insert "ae" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @ss{} ==> ss German-sharp-S -(put 'ss 'texinfo-format 'texinfo-format-German-sharp-S) -(ptexinfmt-defun-if-void texinfo-format-German-sharp-S () - (insert "ss" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @questiondown{} ==> ? upside-down-question-mark -(put 'questiondown 'texinfo-format 'texinfo-format-upside-down-question-mark) -(ptexinfmt-defun-if-void texinfo-format-upside-down-question-mark () - (insert "?" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @exclamdown{} ==> ! upside-down-exclamation-mark -(put 'exclamdown 'texinfo-format 'texinfo-format-upside-down-exclamation-mark) -(ptexinfmt-defun-if-void texinfo-format-upside-down-exclamation-mark () - (insert "!" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @L{} ==> L/ Polish suppressed-L (Lslash) -(put 'L 'texinfo-format 'texinfo-format-Polish-suppressed-L) -(ptexinfmt-defun-if-void texinfo-format-Polish-suppressed-L () - (insert (texinfo-parse-arg-discard) "/L") - (goto-char texinfo-command-start)) - -;; @l{} ==> l/ Polish suppressed-L (Lslash) (lower case) -(put 'l 'texinfo-format 'texinfo-format-Polish-suppressed-l-lower-case) -(ptexinfmt-defun-if-void texinfo-format-Polish-suppressed-l-lower-case () - (insert (texinfo-parse-arg-discard) "/l") - (goto-char texinfo-command-start)) - -;; @O{} ==> O/ Scandinavian O-with-slash -(put 'O 'texinfo-format 'texinfo-format-Scandinavian-O-with-slash) -(ptexinfmt-defun-if-void texinfo-format-Scandinavian-O-with-slash () - (insert (texinfo-parse-arg-discard) "O/") - (goto-char texinfo-command-start)) - -;; @o{} ==> o/ Scandinavian O-with-slash (lower case) -(put 'o 'texinfo-format 'texinfo-format-Scandinavian-o-with-slash-lower-case) -(ptexinfmt-defun-if-void texinfo-format-Scandinavian-o-with-slash-lower-case () - (insert (texinfo-parse-arg-discard) "o/") - (goto-char texinfo-command-start)) - -;; @,{c} ==> c, cedilla accent -(put '\, 'texinfo-format 'texinfo-format-cedilla-accent) -(ptexinfmt-defun-if-void texinfo-format-cedilla-accent () - (insert (texinfo-parse-arg-discard) ",") - (goto-char texinfo-command-start)) - - -;; @dotaccent{o} ==> .o overdot-accent -(put 'dotaccent 'texinfo-format 'texinfo-format-overdot-accent) -(ptexinfmt-defun-if-void texinfo-format-overdot-accent () - (insert "." (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @ubaraccent{o} ==> _o underbar-accent -(put 'ubaraccent 'texinfo-format 'texinfo-format-underbar-accent) -(ptexinfmt-defun-if-void texinfo-format-underbar-accent () - (insert "_" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @udotaccent{o} ==> o-. underdot-accent -(put 'udotaccent 'texinfo-format 'texinfo-format-underdot-accent) -(ptexinfmt-defun-if-void texinfo-format-underdot-accent () - (insert (texinfo-parse-arg-discard) "-.") - (goto-char texinfo-command-start)) - -;; @H{o} ==> ""o long Hungarian umlaut -(put 'H 'texinfo-format 'texinfo-format-long-Hungarian-umlaut) -(ptexinfmt-defun-if-void texinfo-format-long-Hungarian-umlaut () - (insert "\"\"" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @ringaccent{o} ==> *o ring accent -(put 'ringaccent 'texinfo-format 'texinfo-format-ring-accent) -(ptexinfmt-defun-if-void texinfo-format-ring-accent () - (insert "*" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @tieaccent{oo} ==> [oo tie after accent -(put 'tieaccent 'texinfo-format 'texinfo-format-tie-after-accent) -(ptexinfmt-defun-if-void texinfo-format-tie-after-accent () - (insert "[" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @u{o} ==> (o breve accent -(put 'u 'texinfo-format 'texinfo-format-breve-accent) -(ptexinfmt-defun-if-void texinfo-format-breve-accent () - (insert "(" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @v{o} ==> i dotless i and dotless j -(put 'dotless 'texinfo-format 'texinfo-format-dotless) -(ptexinfmt-defun-if-void texinfo-format-dotless () - (insert (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @. -(put '\. 'texinfo-format 'texinfo-format-\.) -(ptexinfmt-defun-if-void texinfo-format-\. () - (texinfo-discard-command) - (insert ".")) - -;; @: -(put '\: 'texinfo-format 'texinfo-format-\:) -(ptexinfmt-defun-if-void texinfo-format-\: () - (texinfo-discard-command)) - -;; @- -(put '\- 'texinfo-format 'texinfo-format-soft-hyphen) -(ptexinfmt-defun-if-void texinfo-format-soft-hyphen () - (texinfo-discard-command)) - -;; @/ -(put '\/ 'texinfo-format 'texinfo-format-\/) -(ptexinfmt-defun-if-void texinfo-format-\/ () - (texinfo-discard-command)) - - -;;; Cross References -;; @ref, @xref -(put 'ref 'texinfo-format 'texinfo-format-xref) - -(ptexinfmt-defun-if-broken texinfo-format-xref () - (let ((args (texinfo-format-parse-args))) - (texinfo-discard-command) - (insert "*Note ") - (let ((fname (or (nth 1 args) (nth 2 args)))) - (if (null (or fname (nth 3 args))) - (insert (nth 0 args) "::") - (insert (or fname (nth 0 args)) ": ") - (if (nth 3 args) - (insert "(" (nth 3 args) ")")) - (unless (null (nth 0 args)) - (insert (nth 0 args))))))) - -;; @uref{URL [,TEXT] [,REPLACEMENT]} -(put 'uref 'texinfo-format 'texinfo-format-uref) -(ptexinfmt-defun-if-broken texinfo-format-uref () - "Format URL and optional URL-TITLE. -Insert ` ... ' around URL if no URL-TITLE argument; -otherwise, insert URL-TITLE followed by URL in parentheses." - (let ((args (texinfo-format-parse-args))) - (texinfo-discard-command) - ;; if url-title - (if (nth 1 args) - (insert (nth 1 args) " (" (nth 0 args) ")") - (insert "`" (nth 0 args) "'")))) - -;; @inforef -(put 'inforef 'texinfo-format 'texinfo-format-inforef) -(ptexinfmt-defun-if-void texinfo-format-inforef () - (let ((args (texinfo-format-parse-args))) - (texinfo-discard-command) - (if (nth 1 args) - (insert "*Note " (nth 1 args) ": (" (nth 2 args) ")" (car args)) - (insert "*Note " "(" (nth 2 args) ")" (car args) "::")))) - - -;; @anchor -;; don't emulation -;; If support @anchor for Mule 2.3, We must fix informat.el and info.el: -;; - Info-tagify suport @anthor-*-refill. -;; - info.el support Ref in Tag table. -(unless (get 'anchor 'texinfo-format) - (put 'anchor 'texinfo-format 'texinfo-discard-command-and-arg)) - - - -;;; New command definition -;; @alias NEW=EXISTING -(put 'alias 'texinfo-format 'texinfo-alias) -(ptexinfmt-defun-if-void texinfo-alias () - (let ((start (1- (point))) - args) - (skip-chars-forward " ") - (save-excursion (end-of-line) (setq texinfo-command-end (point))) - (if (not (looking-at "\\([^=]+\\)=\\(.*\\)")) - (error "Invalid alias command") - (setq texinfo-alias-list - (cons - (cons - (buffer-substring (match-beginning 1) (match-end 1)) - (buffer-substring (match-beginning 2) (match-end 2))) - texinfo-alias-list)) - (texinfo-discard-command)))) - - -;;; Indent -;; @exampleindent INDENT (makeinfo 4.0 or later) - -;; @paragraphindent INDENT (makeinfo 4.0 or later) -;; INDENT: asis, 0, n - -;; @firstparagraphindent WORD (makeinfo 4.6 or later) -;; WORD: none, insert - - - -;;; Special -;; @image{FILENAME [, WIDTH] [, HEIGHT]} -(put 'image 'texinfo-format 'texinfo-format-image) -(ptexinfmt-defun-if-void texinfo-format-image () - ;; I don't know makeinfo parse FILENAME. - (let ((args (texinfo-format-parse-args)) - filename) - (when (null (nth 0 args)) - (error "Invalid image command")) - (texinfo-discard-command) - ;; makeinfo uses FILENAME.txt - (setq filename (format "%s.txt" (nth 0 args))) - (message "Reading included file: %s" filename) - ;; verbatim for Info output - (goto-char (+ (point) (cadr (insert-file-contents filename)))) - (message "Reading included file: %s...done" filename))) - -;; @hyphenation command discards an argument within braces -(put 'hyphenation 'texinfo-format 'texinfo-discard-command-and-arg) -(ptexinfmt-defun-if-void texinfo-discard-command-and-arg () - "Discard both @-command and its argument in braces." - (goto-char texinfo-command-end) - (forward-list 1) - (setq texinfo-command-end (point)) - (delete-region texinfo-command-start texinfo-command-end)) - - -;;; @multitable ... @end multitable -(ptexinfmt-defvar-if-void texinfo-extra-inter-column-width 0 - "*Number of extra spaces between entries (columns) in @multitable.") - -(ptexinfmt-defvar-if-void texinfo-multitable-buffer-name - "*multitable-temporary-buffer*") -(ptexinfmt-defvar-if-void texinfo-multitable-rectangle-name - "texinfo-multitable-temp-") - -;; These commands are defined in texinfo.tex for printed output. -(put 'multitableparskip 'texinfo-format 'texinfo-discard-line-with-args) -(put 'multitableparindent 'texinfo-format 'texinfo-discard-line-with-args) -(put 'multitablecolmargin 'texinfo-format 'texinfo-discard-line-with-args) -(put 'multitablelinespace 'texinfo-format 'texinfo-discard-line-with-args) - -(put 'multitable 'texinfo-format 'texinfo-multitable) - -(ptexinfmt-defun-if-void texinfo-multitable () - "Produce multi-column tables." - -;; This function pushes information onto the `texinfo-stack'. -;; A stack element consists of: -;; - type-of-command, i.e., multitable -;; - the information about column widths, and -;; - the position of texinfo-command-start. -;; e.g., ('multitable (1 2 3 4) 123) -;; The command line is then deleted. - (texinfo-push-stack - 'multitable - ;; push width information on stack - (texinfo-multitable-widths)) - (texinfo-discard-line-with-args)) - -(put 'multitable 'texinfo-end 'texinfo-end-multitable) -(ptexinfmt-defun-if-void texinfo-end-multitable () - "Discard the @end multitable line and pop the stack of multitable." - (texinfo-discard-command) - (texinfo-pop-stack 'multitable)) - -(ptexinfmt-defun-if-broken texinfo-multitable-widths () - "Return list of widths of each column in a multi-column table." - (let (texinfo-multitable-width-list) - ;; Fractions format: - ;; @multitable @columnfractions .25 .3 .45 - ;; - ;; Template format: - ;; @multitable {Column 1 template} {Column 2} {Column 3 example} - ;; Place point before first argument - (skip-chars-forward " \t") - (cond - ;; Check for common misspelling - ((looking-at "@columnfraction ") - (error "In @multitable, @columnfractions misspelled")) - ;; Case 1: @columnfractions .25 .3 .45 - ((looking-at "@columnfractions") - (forward-word 1) - (while (not (eolp)) - (setq texinfo-multitable-width-list - (cons - (truncate - (1- - (* fill-column (read (get-buffer (current-buffer)))))) - texinfo-multitable-width-list)))) - ;; - ;; Case 2: {Column 1 template} {Column 2} {Column 3 example} - ((looking-at "{") - (let ((start-of-templates (point))) - (while (not (eolp)) - (skip-chars-forward " \t") - (let* ((start-of-template (1+ (point))) - (end-of-template - ;; forward-sexp works with braces in Texinfo mode - (progn (forward-sexp 1) (1- (point))))) - (setq texinfo-multitable-width-list - (cons (- (progn - (goto-char end-of-template) - (current-column)) - (progn - (goto-char start-of-template) - (current-column))) - texinfo-multitable-width-list)) - ;; Remove carriage return from within a template, if any. - ;; This helps those those who want to use more than - ;; one line's worth of words in @multitable line. - (narrow-to-region start-of-template end-of-template) - (goto-char (point-min)) - (while (search-forward "\n" nil t) - (delete-char -1)) - (goto-char (point-max)) - (widen) - (forward-char 1))))) - ;; - ;; Case 3: Trouble - (t - (error "\ -You probably need to specify column widths for @multitable correctly"))) - ;; Check whether columns fit on page. - (let ((desired-columns - (+ - ;; between column spaces - (length texinfo-multitable-width-list) - ;; additional between column spaces, if any - texinfo-extra-inter-column-width - ;; sum of spaces for each entry - (apply '+ texinfo-multitable-width-list)))) - (if (> desired-columns fill-column) - (error (format "\ -Multi-column table width, %d chars, is greater than page width, %d chars." - desired-columns fill-column)))) - texinfo-multitable-width-list)) - -;; @item A1 @tab A2 @tab A3 -(ptexinfmt-defun-if-void texinfo-multitable-extract-row () - "Return multitable row, as a string. -End of row is beginning of next @item or beginning of @end. -Cells within rows are separated by @tab." - (skip-chars-forward " \t") - (let* ((start (point)) - (end (progn - (re-search-forward "@item\\|@end") - (match-beginning 0))) - (row (progn (goto-char end) - (skip-chars-backward " ") - ;; remove whitespace at end of argument - (delete-region (point) end) - (buffer-substring start (point))))) - (delete-region texinfo-command-start end) - row)) - -(put 'multitable 'texinfo-item 'texinfo-multitable-item) -(ptexinfmt-defun-if-void texinfo-multitable-item () - "Format a row within a multicolumn table. -Cells in row are separated by @tab. -Widths of cells are specified by the arguments in the @multitable line. -All cells are made to be the same height. -This command is executed when texinfmt sees @item inside @multitable." - (let ((original-buffer (current-buffer)) - (table-widths (reverse (car (cdr (car texinfo-stack))))) - (existing-fill-column fill-column) - start - end - (table-column 0) - (table-entry-height 0) - ;; unformatted row looks like: A1 @tab A2 @tab A3 - ;; extract-row command deletes the source line in the table. - (unformated-row (texinfo-multitable-extract-row))) - ;; Use a temporary buffer - (set-buffer (get-buffer-create texinfo-multitable-buffer-name)) - (delete-region (point-min) (point-max)) - (insert unformated-row) - (goto-char (point-min)) -;; 1. Check for correct number of @tab in line. - (let ((tab-number 1)) ;; one @tab between two columns - (while (search-forward "@tab" nil t) - (setq tab-number (1+ tab-number))) - (if (/= tab-number (length table-widths)) - (error "Wrong number of @tab's in a @multitable row"))) - (goto-char (point-min)) -;; 2. Format each cell, and copy to a rectangle - ;; buffer looks like this: A1 @tab A2 @tab A3 - ;; Cell #1: format up to @tab - ;; Cell #2: format up to @tab - ;; Cell #3: format up to eob - (while (not (eobp)) - (setq start (point)) - (setq end (save-excursion - (if (search-forward "@tab" nil 'move) - ;; Delete the @tab command, including the @-sign - (delete-region - (point) - (progn (forward-word -1) (1- (point))))) - (point))) - ;; Set fill-column *wider* than needed to produce inter-column space - (setq fill-column (+ 1 - texinfo-extra-inter-column-width - (nth table-column table-widths))) - (narrow-to-region start end) - ;; Remove whitespace before and after entry. - (skip-chars-forward " ") - (delete-region (point) (save-excursion (beginning-of-line) (point))) - (goto-char (point-max)) - (skip-chars-backward " ") - (delete-region (point) (save-excursion (end-of-line) (point))) - ;; Temorarily set texinfo-stack to nil so texinfo-format-scan - ;; does not see an unterminated @multitable. - (let (texinfo-stack) ;; nil - (texinfo-format-scan)) - (let (fill-prefix) ;; no fill prefix - (fill-region (point-min) (point-max))) - (setq table-entry-height - (max table-entry-height (count-lines (point-min) (point-max)))) -;; 3. Move point to end of bottom line, and pad that line to fill column. - (goto-char (point-min)) - (forward-line (1- table-entry-height)) - (let* ((beg (point)) ;; beginning of line - ;; add one more space for inter-column spacing - (needed-whitespace - (1+ - (- fill-column - (progn - (end-of-line) - (current-column)))))) ;; end of existing line - (insert (make-string - (if (> needed-whitespace 0) needed-whitespace 1) - ? ))) - ;; now, put formatted cell into a rectangle - (set (intern (concat texinfo-multitable-rectangle-name - (int-to-string table-column))) - (extract-rectangle (point-min) (point))) - (delete-region (point-min) (point)) - (goto-char (point-max)) - (setq table-column (1+ table-column)) - (widen)) -;; 4. Add extra lines to rectangles so all are of same height - (let ((total-number-of-columns table-column) - (column-number 0) - here) - (while (> table-column 0) - (let ((this-rectangle (int-to-string table-column))) - (while (< (length this-rectangle) table-entry-height) - (setq this-rectangle (append this-rectangle '(""))))) - (setq table-column (1- table-column))) -;; 5. Insert formatted rectangles in original buffer - (switch-to-buffer original-buffer) - (open-line table-entry-height) - (while (< column-number total-number-of-columns) - (setq here (point)) - (insert-rectangle - (eval (intern - (concat texinfo-multitable-rectangle-name - (int-to-string column-number))))) - (goto-char here) - (end-of-line) - (setq column-number (1+ column-number)))) - (kill-buffer texinfo-multitable-buffer-name) - (setq fill-column existing-fill-column))) - - -(ptexinfmt-defun-if-broken texinfo-format-printindex () - (let ((indexelts (symbol-value - (cdr (assoc (texinfo-parse-arg-discard) - texinfo-indexvar-alist)))) - opoint) - (insert "\n* Menu:\n\n") - (setq opoint (point)) - (texinfo-print-index nil indexelts) - - (if (memq system-type '(vax-vms windows-nt ms-dos)) - (texinfo-sort-region opoint (point)) - (shell-command-on-region opoint (point) "sort -fd" 1)))) - -(ptexinfmt-broken-facility texinfo-format-end-node () - (with-temp-buffer - (insert (prin1-to-string (symbol-function 'texinfo-format-end-node))) - (goto-char (point-min)) - (not (search-forward "fill-paragraph" nil t nil)))) - -(ptexinfmt-defun-if-broken texinfo-format-end-node () - (let (start - (arg (texinfo-parse-line-arg))) - (texinfo-discard-command) ; remove or insert whitespace, as needed - (delete-region (save-excursion (skip-chars-backward " \t\n") (point)) - (point)) - (insert (format " (%d) " texinfo-footnote-number)) - ;;(fill-paragraph nil) - (save-excursion - (if (search-forward "\n--------- Footnotes ---------\n" nil t) - (progn ; already have footnote, put new one before end of node - (if (re-search-forward "^@node" nil 'move) - (forward-line -1)) - (setq start (point)) - (insert (format "\n(%d) %s\n" texinfo-footnote-number arg)) - (fill-region start (point))) - ;; else no prior footnote - (if (re-search-forward "^@node" nil 'move) - (forward-line -1)) - (insert "\n--------- Footnotes ---------\n") - (setq start (point)) - (insert (format "\n(%d) %s\n" texinfo-footnote-number arg)))))) - -(provide 'ptexinfmt) - -;;; ptexinfmt.el ends here diff -Nru ddskk-16.2/READMEs/AUTHORS.ja ddskk-16.2+0.20190423/READMEs/AUTHORS.ja --- ddskk-16.2/READMEs/AUTHORS.ja 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/READMEs/AUTHORS.ja 2019-04-23 12:49:58.000000000 +0000 @@ -464,6 +464,8 @@ *** tar-util +*** experimental/skk-pre-henkan.el + *** 以下のプログラムへの改変 **** context-skk.el, skk-annotation.el, skk-gadget.el, skk-hint.el, skk-inline.el, diff -Nru ddskk-16.2/READMEs/ChangeLog ddskk-16.2+0.20190423/READMEs/ChangeLog --- ddskk-16.2/READMEs/ChangeLog 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/READMEs/ChangeLog 2019-04-23 12:49:58.000000000 +0000 @@ -1,6 +1,24 @@ +2019-04-14 Tsuyoshi Kitamoto + + * READMEs/history.md: Add new file. + +2019-02-18 Tsuyoshi Kitamoto + + * README.w32.ja.org: Fix url for CorvusSKK. + +2017-07-09 Tsuyoshi Kitamoto + + * NEWS.ja: Update. + +2017-03-12 Tsuyoshi Kitamoto + + * AUTHORS.ja, NEWS.ja: Update. + 2017-03-04 Tsuyoshi Kitamoto - * INSTALL, NEWS.ja: Update. + * ReleaseOperation.ja.md: Add new file. + + * NEWS.ja, CODENAME.ja, INSTALL, NEWS.ja: Update. 2017-02-27 Tsuyoshi Kitamoto diff -Nru ddskk-16.2/READMEs/CODENAME.ja ddskk-16.2+0.20190423/READMEs/CODENAME.ja --- ddskk-16.2/READMEs/CODENAME.ja 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/READMEs/CODENAME.ja 2019-04-23 12:49:58.000000000 +0000 @@ -93,9 +93,9 @@ 長万部 Oshamambe 15.2 二股 Futamata 16.1 -蕨岱 Warabitai 16.2 -黒松内 Kuromatsunai : -熱郛 Neppu +蕨岱 Warabitai 16.2 (2017-03-04) +黒松内 Kuromatsunai 16.3 +熱郛 Neppu : 目名 Mena 蘭越 Rankoshi 昆布 Kombu diff -Nru ddskk-16.2/READMEs/history.md ddskk-16.2+0.20190423/READMEs/history.md --- ddskk-16.2/READMEs/history.md 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/READMEs/history.md 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,194 @@ +## SKK の誕生秘話 + +以下は、「bit」(1991年,4月号)に掲載された佐藤雅彦氏の記事「かな漢字変換システム SKK」よりの引用です(強調、改行などは、読み易さのため後で付加したものです)。 + +文中において「筆者」とは、SKK の原作者、佐藤雅彦氏(京都大学名誉教授)を指します。 + +なお、引用については佐藤先生のご承諾を得ています。 + +> 筆者が **Nemacs の上で動く自分用のかな漢字変換プログラムをつくろう** と思いたった直接のきっかけは, 1987 年の 9 月から約 2 ヶ月フランスに出張することになったことである. フランスでの日本語環境をどうするかという問題が発生したのである. 当時の Unix 上の日本語環境がどうなっていたかというと, 電総研の半田剣一氏が中心になり GNU Emacs を日本語化した Nemacs はすでに使えるようになっていたが, その上での日本語入力環境を提供する **「たまご (EGG)」** はまだ配布されていなかった. (実際, たまごは SKK より数ヶ月遅れて JUNET で配布されるようになった.) したがって, 当時 Nemacs を用いて日本語入力を行うためには, かな漢字変換のためのフロントエンドプロセッサが必要であった. +> +> 筆者も, Nemacs で日本語入力を行うときは, Unix ワークステーションに PC からログインして, PC のかな漢字変換機能を用いて日本語入力を行っていた. 一方日本語の表示に関しては X ウィンドウのもとで kterm が利用できたので, Unix ワークステーションのモニターで問題なく表示できた. ということで, ラップトップ PC を持参すれば, フランスでも Unix ワークステーションの上で日本語環境をつくることができたのであるが, 当時のラップトップ PC はまだかなり重量があったのでこの考えはすてることにした. それに, PC のフロントエンドを必要とするということは, Unix の中で閉じた環境にならないので日本における環境としても不満であった. +> +> それでは, **Emacs Lisp でかな漢字変換プログラムをかけばよいのではないか** と考えた. これが可能ではないかと思うようになった原因のひとつは, その少し前に NTT の竹内郁雄氏が中心になって設計, 開発した **かな漢字変換システム Kanzen** を竹内氏の実演によりみたことがある. Kanzen はひとことでいうと漢字の開始点をローマ字入力を大文字にすることにより指定し, 文法的な解析は 1 文節だけ行うというかな漢字変換法である. こうして Kanzen の影響を受けて **SKK** のプログラムを **Emacs Lisp** で書き始めたのは **1987年の 7 月頃** であったと思う. ファイルに開発の記録を残すようにしたのは 8 月になってからであった. 他の仕事もしながら 2, 3 週間で一応動くものをつくろうと考えたので, 当然設計方針も簡単なものになった. + + +## "SKK = I" + +SKK の名前を考えたときに Combinatory Logic での有名な等式 SKK = I が念頭にあったのは事実です.ずい分昔に Henk Barendregt さんにこの話をしたこともありました.Combinatory Logic は一般にはあまり知られていないので簡単に紹介をしてみます. + +Combinatory Logic は,λ 計算と同様,すべての項 (term, 計算機の言葉で言えば,プログラムに相当するもの) が関数であるような体系である.Logic という名前がついているのは,その上に論理を展開することを目的としていたからであるが,論理の体系としては成功しなかった.しかし,λ 計算と密接な関係があることから,計算の体系としては重要なものである. + +Combinatory Logic の項 (combinator) は以下の文法規則で定義される. + + 項 ::= 変数 | 定数 | 項(項) + +すなわち,項は,変数であるか,定数であるか,(関数としての) 項 f に (引数としての) 項 a を適用した項 f(a) のいずれかである. 通常よく用いられる定数には S, K, I がある.したがって,たとえば,I, S, S(K), S(K)(K) はすべて上の定義により項になる. + +なお,通常,Combinatory Logic では f の a への適用 f(a) のことを適用の演算子 * を用いて f*a のように書いて,* は左に結合すると約束する.したがって,f*x*y と書けば,これは (f*x)*y のことであり,f*(x*y)のことではない.その上で,さらに,通常は,* も省略することを許しているので,今の例は fxy となる.しかし,ここでは,そのような省略はしない.fxy とは書かないで,f(x)(y) と書くことにする.ふつう,Combinatory Logic で SKK と書かれる項は,S(K)(K) のことである. + +Combinatory Logic の項は引数をひとつだけとるので,apply を用いて app を定義しておく.これにより,項 f(x) を Emacs Lisp で (app f x) と書くことができるようになる. + + (defun app (f x) (apply f (list x))) + +Combinatory Logic の定数 S は等式 S(f)(g)(x) = f(x)(g(x)) を満足する combinator として定義される. + + i.e., (app (app (app S f) g) x) = (app (app f x) (app g x)) + +λ 計算では S を以下のように定義できる ( λ 計算の解説は省略するが,第 0 近似としては Lisp だと思ってよい:-) もちろん,歴史的には λ 計算が Lisp に影響を与えているのであるが...). + + S = λ(f)[λ(g)[λ(x)[f(x)(g(x))]]] + +この S を Emacs Lisp で定義すると次のようになる. + + (defconst S + (lambda (f) `(lambda (g) (let ((f ,f)) + `(lambda (x) (app (app ,f x) (app ,g x))))))) + +3 つ目の引数 x がコピーされてふたつになることが S のポイントである. + +K combinator は等式 K(x)(y) = x を満足する定数として定義される. + + i.e., (app (app K x) y) = x + +λ 計算では K を以下のように定義できる. + + K = λ(x)[λ(y)[x]] + +この K を Emacs Lisp で定義すると次のようになる. + + (defconst K (lambda (x) `(lambda (y) ,x))) + +2 つ目の引数をすてることが K のポイントである. + +I combinator は恒等関数を表し,等式 I(x) = x を満足する. + + i.e., (app I x) = x + +λ 計算では I を以下のように定義できる. + + I = λ(x)[x] + +I を Emacs Lisp で定義すると次のようになる. + + (defconst I (lambda (x) x)) + +Combinatory Logic で S(K)(K) = I という等式が成り立つということの意味は,任意の combinator x に対して,S(K)(K)(x) を計算してみると + + S(K)(K)(x) = K(x)(K(x)) = x + +となり,I についても I(x) = x なので,どちらも,任意の入力 x について何も変更を加えないで x をそのまま出力する関数と考えられということである.日本語入力システム SKK という名前には,ユーザの頭の中にある日本語のテキストを,なるべくストレスなしに,そのままディスプレイに出力するプログラムにしたいという気持ちが込められている. + +Emacs Lisp でも S(K)(K) を以下のように定義することにより,恒等関数をつくることができる. + + (defconst SKK (app (app S K) K)) + +examples + + (app SKK 2) ;; -> 2 + (app I 2) ;; -> 2 + (app SKK "SKK") ;; -> "SKK" + (app I "SKK") ;; -> "SKK" + (equal SKK (app SKK SKK)) ;; -> t + (equal I (app I I)) ;; -> t + (equal SKK I) ;; -> nil となるのは,SKK と I はプログラムとしては同じふるまい + ;; をするが,コードとしては異るからである. + + (defun SKK (x) (app SKK x)) + (SKK 2) ;; -> 2 + (SKK "SKK") ;; -> "SKK" + +Combinatory Logic のすごいところは, S と K だけで計算可能な関数をすべて記述できるということです.あまりにすごいのでプログラミング言語として使う人はいないようです.これに対して,λ 計算は,同じようにすごい言語ですが,Lisp や型付の関数型言語として姿を変て現在もよく使われています.その理由は自然演繹とよばれる論理の体系との関係が深いからだと私は考えています. + +この小文の草稿について有益な質問,コメントを寄せてくださった中島幹夫氏に感謝します. + +Copyright (C) 2002 佐藤雅彦 (京都大学名誉教授) + + +## SKK の 25年 + +http://mail.ring.gr.jp/skk/201212/msg00007.html + +皆様, + +おかげさまで 1987年に Emacs の上で SKK が動くようになってから25年が過 +ぎました.私も相変わらず,昔の設定のまま SKK を使っています.最初の頃 +は,個人辞書への項目の追加に追われていましたが,最近では辞書に新しい登 +録をすることもほとんどなくなりました. + +最初は自分専用で開発したのですが,研究室や,外部の人にも使ってもらえる +ようになりました.現在出張でドイツにきていますが,数日前にあった日本人 +の研究者も,英語版の Ubuntu で SKK が問題なく使えているといっていまし +た.これも open source での開発の結果であると感謝しています. + +私事ですが,この3月末で京大を退職し,京都大学の名誉教授になりました.SKK +Openlab の記述を修正していただけるとありがたいです. + +なお,私の最終講義および関連行事の資料が以下にありますので,ご覧いただ +ければ幸いです.SKK についても少しだけですがふれています. + + http://www.sato.kuis.kyoto-u.ac.jp/~masahiko/taikan.html + +佐藤雅彦 + + +## SKK の歴史 + +| 西暦 | SKK | GNU Emacs (https://www.gnu.org/software/emacs/emacs.html) | XEmacs (http://www.xemacs.org/) | +| ------ | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------- | +| 1987 | 佐藤雅彦氏が SKK の開発に着手 (7月頃) | Nemacs 1.1 (Emacs 18.47) (06/12) | | +| 1988 | SKK 1.13 (04/22) | Nemacs 2.1 (06/15) | | +| 1989 | SKK 2.25 (04/15) | Nemacs 3.1 (06/14) | | +| 1990 | 東北大学において SKK メーリングリスト開設(4月頃)。 | Nemacs 3.3.2 (Emacs 18.55) (06/06) -- SKK 2.25 を収録 (世間では 3.47 と言われているが、肝心の Nemacs を展開すると 2.25 しか見当たらない)。 | | +| | SKK 3.47 (04/29) -- 送りありエントリの送り仮名サポートが実装される。 | | | +| 1991 | 雑誌「bit」が1991年4月号に佐藤氏のSKKに関する記事を掲載(4月頃)。 | Demacs 1.2.0 (Emacs 18.55) (12/12(?)) | | +| | SKK 4.33 (05/09) | | | +| 1992 | SKK 5.30 (05/09) -- このころから Mule 対応が進められる。 | Mule 0.9.0 Beta (03/04) | | +| | 辞書が、送りありエントリと送りなしエントリが一つのファイルに納めた形式になった。 | | | +| 1993 | SKK 6.32 (04/24) -- 変換時に個人辞書以外を検索する機能、Emacs のバッファに読み込んだ辞書のバイナリサーチ機能が実装される。 | | | +| 1994 | SKK 7.18 (06/07) | Mule 1.1 (Emacs 18.59) (02/08) | | +| | | Mule 2.0 (Emacs 19.25) (08/06) -- Emacs 19 になり GUI が進化。 | | +| 1995 | SKK 8.6 (05/17) -- Emacs 19 に対応した i-search 機能を搭載。 | Mule 2.3 (Emacs 19.28) (07/24) | | +| 1996 | 佐藤氏とともに開発の場が京大に移動。 | Mule 2.3 (Emacs 19.34) 非公式版 (8月(?))。 | | +| | | このころ FSF, XEmacs とも Mule の統合が行われた。 | | +| 1997 | SKK 9.6 (02/07) -- face を利用したカラフルな UI は SKK のイメージを変えた。 | Emacs 20.1 (MULE 3.0) (09/14) -- SKK 9.6 がそのままでは動かなかった。 | XEmacs 20.0 (02/09) | +| | SKK 10 の開発が始まる (2月頃) -- いわゆる「非公式」時代。 | | | +| | Mule, Emacs, XEmacs など多様な環境で動作することが求められるようになる。 | | | +| 1998 | SKK 10.39 (03/01) | Emacs 20.3 (MULE 4.0) (08/19) -- このバージョンにおける変更は SKK にとって重大で、一部では混乱がみられた。 | XEmacs 20.4 (02/23) -- SKK 10.38 を同梱。 | +| | SKK 10.44.8 (07/27) | | Mule をサポートした XEmacs にユーザが流れ始める。 | +| | APEL が採用される (10月頃) -- この頃から XEmacs での動作が安定し始める。 | | | +| 1999 | SKK 10.56 (10/23) | Emacs 20.4 (MULE 4.0) (07/12) -- 20.3 から 1, 2週間の予定が1 年近くかかってやっと安定。 | XEmacs 21.0.67 (03/25) | +| | SKK オープンラボ開設(11月頃) -- Daredevil SKK の開発を開始。京大の本家とは別の道を歩み始める。 | | | +| 2000 | SKK 10.62a (10/30) -- SKK 10 の開発が凍結され、Daredevil SKK が開発の幹に。 | Emacs 20.7 (MULE 4.0) (06/14) | | +| | 京大での開発終了が宣言される (11月頃)。 | | | +| 2001 | Daredevil SKK 11.4 (01/02) | Emacs 21.1 (MULE 5.0) (10/20) -- このころより GUI が強化され,XEmacs と遜色なくなってきた. | XEmacs 21.2.46 (03/21) (旧安定版) | +| | Daredevil SKK 11.5.2 (12/02) | | XEmacs 21.4.0 (04/16) (新安定版) | +| | Daredevil SKK 11.6.0 (12/16) | | XEmacs 21.5.1 (05/09) (開発版) | +| | Emacs 21 の GUI 強化に伴い XEmacs と同等の機能を実装 | | | +| 2002 | | Emacs 開発版が anonymous CVS で取得可能になる。 | | +| 2003 | Daredevil SKK 12.2.0 (08/03) | | | +| 2004 | Emacs 21 の tooltip の機能をいかした候補・注釈表示が 利用可能になった。 | | XEmacs 21.4.16 (12/11) | +| | 新しい学習機能 (skk-bayesian.el) | | XEmacs 21.5.18 (10/22) | +| 2005 | (uim や scim のめざましい発展) | Emacs 21.4 (MULE 5.0) (02/06) | | +| | 候補表示の装飾機能、インライン候補表示、サーバー補完機能に対応 など多数の機能追加 | | | +| | Emacs 22 対応の本格化 | | | +| 2006 | 補完機能の大幅な拡張 (プログラマブル補完、prefix 補完、 look の日本語対応、任意辞書補完機能など) | | XEmacs 21.4.20 (12/10) | +| 2007 | Daredevil SKK 13.1 (08/18) | Emacs 22.1 (MULE 5.0) (06/02) -- GTK 対応可能となる | XEmacs 21.5.28 (05/21) | +| 2008 | 動的補完が複数候補表示に対応、Sticky shift 的入力に対応 | Emacs 22.3 (MULE 5.0) (09/05) | XEmacs 21.4.22 (12/28) | +| 2009 | | Emacs 23.1 (MULE 6.0) (07/29) -- UNICODE 対応と内部コード変更 (utf-8-emacs)、Xft 対応、multi-tty 対応 | XEmacs 21.5.29 (05/18) | +| 2010 | Daredevil SKK 14.1 (09/15) -- CDB 辞書が直接検索可能、単漢字変換機能の改善 | Emacs 23.2 (MULE 6.0) (05/07) | | +| 2011 | Daredevil SKK 14.2 (01/01) -- GNU Emacs 22 以上で APEL は不要に | Emacs 23.3 (MULE 6.0) (03/10) | XEmacs 21.5.31 (04/29) | +| | Daredevil SKK 14.3 (07/01) | | | +| 2012 | Daredevil SKK 14.4 (01/01) -- アノテーション表示の強化。skk-search-web.el の追加。skk-show-mode.el の追加 | Emacs 23.4 (MULE 6.0) (01/29) | XEmacs 21.5.32 (08/02) | +| | SKK の 25年 (http://mail.ring.gr.jp/skk/201212/msg00007.html) | Emacs 24.1 (MULE 6.0) (06/10) | | +| | | Emacs 24.2 (MULE 6.0) (08/27) | | +| 2013 | Daredevil SKK 15.1 (03/16) -- GNU Emacs 21 のサポート廃止。新たな数値変換タイプ #8 を追加。新たな関数 skk-relative-date() を追加 | Emacs 24.3 (MULE 6.0) (03/11) -- フェイス modeline が削除され、以降はフェイス mode-line | XEmacs 21.5.33 (01/04) | +| | | | XEmacs 21.5.34 (06/24) | +| 2014 | Daredevil SKK 15.2 (11/24) | Emacs 24.4 (MULE 6.0) (10/20) -- eww, org8, nadvice.el, more. NTEmacs のディレクトリ構成が変更(Using the Posix configure script and Makefiles also means a change in the directory structure of the Emacs installation on Windows. It is now the same as on GNU and Unix systems.)。ddskk-15.2 で対策済み。 | | +| | 開発ツールを github へ変更 (12/21)。ddskk(旧main) skktools(旧tools) | | | +| 2015 | MELPA 登録。M-x list-packages でインストール可能に。 | Emacs 24.5 (MULE 6.0) (04/10) | | +| 2016 | Daredevil SKK 16.1 (10/01) -- GNU Emacs 25 対応など | Emacs 25.1 (MULE 6.0) (09/17) -- dynamic module, Xwidgets, more. | | +| 2017 | Daredevil SKK 16.2 (03/04) -- GNU Emacs 22 のサポート廃止。Ruby 2.4 対応など | Emacs 25.2 (04/21) | | +| | | Emacs 25.3 (09/11) | | +| 2018 | | Emacs 26.1 (05/28) | | +| 2019 | | Emacs 26.2 (04/12) | | diff -Nru ddskk-16.2/READMEs/NEWS.ja ddskk-16.2+0.20190423/READMEs/NEWS.ja --- ddskk-16.2/READMEs/NEWS.ja 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/READMEs/NEWS.ja 2019-04-23 12:49:58.000000000 +0000 @@ -1,4 +1,29 @@ -* 16.2 +* 16.3 + +** ドキュメント + +*** Org 形式へ移行 + +skk.texi から skk.org へ移行しました。 +これまでの skk.texi は obsolete-doc ディレクトリへ移しました。 + +*** html, PDF, mobi + +それぞれ make html, mahe pdf, make mobi で生成できます。 + +** 新機能 + +*** experimental/skk-pre-henkan.el + +*** NICOLA installer for NTEmacs + +NTEmacs 向けのインストーラ (makeit.bat) を用意しました。 + +** その他バグ修正など + +*** Fix #58 ... conflict key bind + +* 16.2 (2017-03-04) ** GNU Emacs 22 のサポートを終了しました diff -Nru ddskk-16.2/READMEs/README.w32.ja.org ddskk-16.2+0.20190423/READMEs/README.w32.ja.org --- ddskk-16.2/READMEs/README.w32.ja.org 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/READMEs/README.w32.ja.org 2019-04-23 12:49:58.000000000 +0000 @@ -265,7 +265,7 @@ CorvusSKK works as Text Input Processor (TIP) on Text Services Framework (TSF). - http://code.google.com/p/corvus-skk/ + https://nathancorvussolis.github.io/ --------- diff -Nru ddskk-16.2/READMEs/ReleaseOperation.ja.md ddskk-16.2+0.20190423/READMEs/ReleaseOperation.ja.md --- ddskk-16.2/READMEs/ReleaseOperation.ja.md 1970-01-01 00:00:00.000000000 +0000 +++ ddskk-16.2+0.20190423/READMEs/ReleaseOperation.ja.md 2019-04-23 12:49:58.000000000 +0000 @@ -0,0 +1,400 @@ +DDSKK リリース手順書 +==================== + +DDSKK 16.2(蕨岱 Warabitai)のリリース作業を例として、リリース手順書としてまとめ +ておきます。 + +**この文書は DDSKK の開発者・リリース担当者に向けたものです。** + +## 1. リリースのタイミング + +GNU Emacs の新メジャーバージョンがリリースされたときには、さほど遅れないタイミン +グで DDSKK も新版をリリースするように心掛けています。このリリースにおけるバージ +ョン番号は DDSKK `xx.y` の `xx` 部分をインクリメントします。 + +上記のタイミング以外でも DDSKK の新版をリリースすることがありますが、それは不定 +期です。このリリースにおけるバージョン番号は DDSKK `xx.y` の `y` 部分をインクリ +メントします + +ただし、過去のリリースは必ずしも上記ルールに沿ったものではありません。これまでの +リリース経過は次のドキュメントを参照してください。 + +[SKK の歴史 http://openlab.jp/skk/history-ja.html](http://openlab.jp/skk/history-ja.html) + +## 2. リリース前に向けた準備 + +リリースする DDSKK がサポートする emacsen を使用して、少なくとも make インストー +ルを試してください。 + +* GNU Emacs HEAD (26.0.50) +* GNU Emacs 23.1 (DDSKK 16.2 は GNU Emacs 22 はサポート対象外) +* XEmacs 21.5 (beta34) "kale" + +また、次版リリースに向けた準備中であることをメーリングリストでアナウンスします。 + +## 3. ドキュメントの整理 + +すべてのドキュメントを査読して内容を整理しましょう。特に、次のドキュメントは重点 +的に見直してください。 + +* READMEs/INSTALL +* READMEs/NEWS.ja +* doc/skk.texi + +いったん commit しておきます。 + + $ git add -u + $ git commit -v + $ git push + +## 4. 各ファイルのバージョン情報を修正 + +以下のファイルについて、リリース版の番号となるようバージョン情報を修正します。 + +* doc/skk.texi: 36 行目の `SKK-VERSION` +* Makefile: 6 行目の `VERSION` +* skk-version.el: 34 行目の `ver` +* ddskk-pkg.el: 8 行目 + + + diff --git a/Makefile b/Makefile + index 4836286..7beec60 100644 + --- a/Makefile + +++ b/Makefile + @@ -6 +6 @@ + -VERSION = 16.1.50 + +VERSION = 16.2 + + diff --git a/ddskk-pkg.el b/ddskk-pkg.el + index 402cfdc..4a82ab2 100644 + --- a/ddskk-pkg.el + +++ b/ddskk-pkg.el + @@ -8 +8 @@ + -(define-package "ddskk" "16.1.50" + +(define-package "ddskk" "16.2" + + diff --git a/doc/skk.texi b/doc/skk.texi + index d96fe6c..3262467 100644 + --- a/doc/skk.texi + +++ b/doc/skk.texi + @@ -36,2 +36,2 @@ + -@set SKK-VERSION 16.1.50 + -@set UPDATED Date: 2017/02/18 13:12:05 + +@set SKK-VERSION 16.2 + +@set UPDATED Date: 2017/03/04 + + diff --git a/skk-version.el b/skk-version.el + index b0e4041..d3f3bf6 100644 + --- a/skk-version.el + +++ b/skk-version.el + @@ -34 +34 @@ + - (let ((ver "16.1.50") + + (let ((ver "16.2") + +ChangeLog を修正します。 + +``` +2017-03-04 Tsuyoshi Kitamoto + * Version 16.2 Warabitai Released. + * Makefile, ddskk-pkg.el, skk-version.el: Bump SKK version to 16.2. +``` + +``` +2017-03-04 Tsuyoshi Kitamoto + * skk.texi: Bump SKK version to 16.2. +``` + +commit します。 + + $ git add -u + $ git commit -v + $ git push + +## 5. タグを打つ + +まずは、タグの現状を確認しましょう。 + + $ git tag + ddskk-16.1.50 + ddskk-16.1_Futamata + +新たなタグを打ち、github へ反映します。 + + $ git tag ddskk-16.2_Warabitai + $ git tag + ddskk-16.1.50 + ddskk-16.1_Futamata + ddskk-16.2_Warabitai + + $ git push --tags + Total 0 (delta 0), reused 0 (delta 0) + To github.com:skk-dev/ddskk.git + * [new tag] ddskk-16.2_Warabitai -> ddskk-16.2_Warabitai + +## 6. github でのリリース作業 + +https://github.com/skk-dev/ddskk を開き、タブ "n releases" を開きます。 + +先ほど打ったタグ `ddskk-16.2_Warabitai` が確認できたら、ボタン "Draft a new release" を +クリックします。 + +必要事項を入力して、画面下部のボタン "Publish release" を押す。 + +なお、あとから自由に編集することもできます。 + +## 7. openlab でのリリース作業 + +### (1) ファイルを配置する + +#### ア. 公開用アーカイブを配置する + +手元でアーカイブを作ります。 + + $ make release + /bin/rm -f leim-list.el skk-autoloads.el skk-setup.el *.elc experimental/*.elc \ + auto-autoloads.el custom-load.el ert.el \ + ./doc/skk.info* `find . -name '*~'` `find . -name '.*~'` `find . -name '.#*'` + /bin/rm -f ../ddskk-16.2.tar.gz ../ddskk-16.2.tar.bz2 ;\ + git archive --format=tar.gz --prefix=ddskk-16.2/ HEAD > ../ddskk-16.2.tar.gz ;\ + git archive --format=tar --prefix=ddskk-16.2/ HEAD | bzip2 -9 -c > ../ddskk-16.2.tar.bz2 ;\ + md5 ../ddskk-16.2.tar.bz2 > ../ddskk-16.2.tar.bz2.md5 ;\ + md5 ../ddskk-16.2.tar.gz > ../ddskk-16.2.tar.gz.md5 + $ cd .. + $ ls + ddskk-16.2.tar.bz2 + ddskk-16.2.tar.bz2.md5 + ddskk-16.2.tar.gz + ddskk-16.2.tar.gz.md5 + +アーカイブを openlab へ転送します + + $ scp ddskk-16.2.tar.gz* USERNAME@openlab.jp: + ddskk-16.2.tar.gz 100% 866KB 1.2MB/s 00:00 + ddskk-16.2.tar.gz.md5 100% 55 1.4KB/s 00:00 + +openlab へログインして、アーカイブを所定のディレクトリへ移します。 + + $ ssh USERNAME@openlab.jp + [USERNAME@openlab ~]$ mv ddskk-16.2.tar.gz* /circus/openlab/skk/maintrunk/ + +#### イ. PDF マニュアルを配置する + +手元でマニュアルの PDF 版を生成します。 + + $ cd doc + $ ./makepdf.sh + $ mv skk.pdf skk-16.2.pdf + +skk.pdf を openlab へ転送し、所定のディレクトリへ移します。 + + $ scp skk-16.2.pdf USERNAME@openlab.jp: + $ ssh USERNAME@openlab.jp + [USERNAME@openlab ~]$ mv skk-16.2.pdf /circus/openlab/skk/skk-manual + [USERNAME@openlab ~]$ cd /circus/openlab/skk/maintrunk/ + [USERNAME@openlab /circus/openlab/skk/maintrunk]$ ln -s ../skk-manual/skk-16.2.pdf skk-16.2.pdf + +### (2) WEB ページを更新する + +openlab 向け cvs 作業です。 + +#### トップページ + +ファイル `skk/web/index-j.html.in` と `skk/web/index.html.in` に、リリースアナウ +ンスを記載します。 + + Index: web/index-j.html.in + =================================================================== + RCS file: /circus/cvsroot/skk/web/index-j.html.in,v + retrieving revision 1.117 + diff -u -U 1 -r1.117 index-j.html.in + --- web/index-j.html.in 1 Oct 2016 08:56:05 -0000 1.117 + +++ web/index-j.html.in 4 Mar 2017 08:09:53 -0000 + @@ -34,2 +34,3 @@ +
    + +
  • elisp: Daredevil SKK 16.2 (蕨岱 Warabitai) をリリースしました。(2017-03-04) +
  • elisp: Daredevil SKK 16.1 (Futamata) をリリースしました。(2016-10-01) + + Index: web/index.html.in + =================================================================== + RCS file: /circus/cvsroot/skk/web/index.html.in,v + retrieving revision 1.116 + diff -u -U 1 -r1.116 index.html.in + --- web/index.html.in 1 Oct 2016 08:56:05 -0000 1.116 + +++ web/index.html.in 4 Mar 2017 08:09:53 -0000 + @@ -37,4 +37,5 @@ +
      + +
    • elisp: Daredevil SKK 16.2 released. (2017-03-04) +
    • elisp: Daredevil SKK 16.1 released. (2016-10-01) + +#### 歴史表 + +ファイル `skk/web/history-ja.html.in` と `skk/web/history.html.in` に、リリース +情報を記載します。 + + Index: web/history-ja.html.in + =================================================================== + RCS file: /circus/cvsroot/skk/web/history-ja.html.in,v + retrieving revision 1.72 + diff -u -U 1 -r1.72 history-ja.html.in + --- web/history-ja.html.in 4 Mar 2017 03:15:41 -0000 1.72 + +++ web/history-ja.html.in 4 Mar 2017 08:36:29 -0000 + @@ -291,5 +291,13 @@ + + + + + + + + + + + 2017 + + Daredevil SKK 16.2 (03/04) -- Ruby 2.4 対応など + + + + + 只今の L 辞書の候補数 + + - + + + + + Index: web/history.html.in + =================================================================== + RCS file: /circus/cvsroot/skk/web/history.html.in,v + retrieving revision 1.48 + diff -u -U 1 -r1.48 history.html.in + --- web/history.html.in 4 Mar 2017 03:15:41 -0000 1.48 + +++ web/history.html.in 4 Mar 2017 08:36:29 -0000 + @@ -291,2 +291,10 @@ + + + + + + + + + + + 2017 + + Daredevil SKK 16.2 (03/04) + + + + + Number of candidates today + +#### マニュアル + +ファイル `skk/web/doc-ja.html.in` と `skk/web/doc.html.in` に、7-(2) で公開し +た PDF へのリンクを記載します。 + + Index: web/doc-ja.html.in + =================================================================== + RCS file: /circus/cvsroot/skk/web/doc-ja.html.in,v + retrieving revision 1.15 + diff -u -U 1 -r1.15 doc-ja.html.in + --- web/doc-ja.html.in 1 Oct 2016 08:56:05 -0000 1.15 + +++ web/doc-ja.html.in 4 Mar 2017 08:00:26 -0000 + @@ -40,2 +40,3 @@ +
    • CVS trunk html (フレーム版) + +
    • DDSKK 16.2 pdf +
    • DDSKK 16.1 pdf + + Index: web/doc.html.in + =================================================================== + RCS file: /circus/cvsroot/skk/web/doc.html.in,v + retrieving revision 1.11 + diff -u -U 1 -r1.11 doc.html.in + --- web/doc.html.in 1 Oct 2016 08:56:05 -0000 1.11 + +++ web/doc.html.in 4 Mar 2017 08:00:26 -0000 + @@ -39,2 +39,3 @@ +
    • CVS trunk html (with frames) + +
    • DDSKK 16.2 pdf +
    • DDSKK 16.1 pdf + +#### cvs commit + +ChangeLog を付して cvs commit します。 + + $ cvs commit -m "Update for release 16.2" + +## 8. アナウンス + +メーリングリストで新版をリリースした旨をアナウンスしましょう。 + +## 9. 各ファイルのバージョン情報を修正 + +前章 (アナウンス) までで、いったんはリリース作業は完了です。 + +さて、リリース作業の後のソースコード変更は、次版リリース向け作業に当たります。 +そのため、開発版の番号を付しておきます。 + +* Makefile +* READMEs/CODENAME.ja +* READMEs/NEWS.ja +* ddskk-pkg.el +* doc/skk.texi +* skk-version.el + + + diff --git a/Makefile b/Makefile + index 7beec60..1eed6e7 100644 + --- a/Makefile + +++ b/Makefile + @@ -6 +6 @@ + -VERSION = 16.2 + +VERSION = 16.2.50 + + diff --git a/READMEs/CODENAME.ja b/READMEs/CODENAME.ja + index 599f1c0..4433740 100644 + --- a/READMEs/CODENAME.ja + +++ b/READMEs/CODENAME.ja + @@ -96,3 +96,3 @@ o 異なる路線で同じ駅を二度通過しても同じ Codename は 2 度 + -蕨岱 Warabitai 16.2 + -黒松内 Kuromatsunai : + -熱郛 Neppu + +蕨岱 Warabitai 16.2 (2017-03-04) + +黒松内 Kuromatsunai 16.3 + +熱郛 Neppu : + + diff --git a/READMEs/NEWS.ja b/READMEs/NEWS.ja + index f03283a..42b3cda 100644 + --- a/READMEs/NEWS.ja + +++ b/READMEs/NEWS.ja + @@ -1 +1,3 @@ + -* 16.2 + +* 16.3 + + + +* 16.2 (2017-03-04) + + diff --git a/ddskk-pkg.el b/ddskk-pkg.el + index 4a82ab2..cea056b 100644 + --- a/ddskk-pkg.el + +++ b/ddskk-pkg.el + @@ -8 +8 @@ + -(define-package "ddskk" "16.2" + +(define-package "ddskk" "16.2.50" + + diff --git a/doc/skk.texi b/doc/skk.texi + index 3262467..09bbd8d 100644 + --- a/doc/skk.texi + +++ b/doc/skk.texi + @@ -36 +36 @@ + -@set SKK-VERSION 16.2 + +@set SKK-VERSION 16.3 + + diff --git a/skk-version.el b/skk-version.el + index d3f3bf6..c0d0f20 100644 + --- a/skk-version.el + +++ b/skk-version.el + @@ -34 +34 @@ + - (let ((ver "16.2") + + (let ((ver "16.2.50") + @@ -45,2 +45,2 @@ + -(put 'skk-version 'codename "Warabitai") ; See also `READMEs/CODENAME.ja' + -(put 'skk-version 'codename-ja "蕨岱") + +(put 'skk-version 'codename "Kuromatsunai") ; See also `READMEs/CODENAME.ja' + +(put 'skk-version 'codename-ja "黒松内") + +ChangeLog も修正して commit します。 + +``` +2017-03-04 Tsuyoshi Kitamoto + * Makefile, ddskk-pkg.el, skk-version.el: Bump SKK version to 16.2.50. +``` + + $ git add -u + $ git commit -v + $ git push + +以上です。おつかれさまでした。 diff -Nru ddskk-16.2/skk-annotation.el ddskk-16.2+0.20190423/skk-annotation.el --- ddskk-16.2/skk-annotation.el 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/skk-annotation.el 2019-04-23 12:49:58.000000000 +0000 @@ -193,10 +193,12 @@ (autoload 'skk-lookup-get-content "skk-lookup") (autoload 'run-python "python") - (autoload 'python-send-command "python") - (autoload 'python-send-string "python") +; (autoload 'python-send-command "python") +; (autoload 'python-send-string "python") (autoload 'python-check-comint-prompt "python") - (autoload 'python-proc "python") +; (autoload 'python-proc "python") + (autoload 'python-shell-internal-get-or-create-process "python") + (autoload 'python-shell-get-process-name "python") (autoload 'html2text "html2text") (autoload 'html2text-delete-tags "html2text") (autoload 'url-hexify-string "url-util") @@ -703,14 +705,20 @@ $B%-!pJs8;(B URL $B$N%V%i%&%:!"$^$?$O(B $BJL$N>pJs8;$+$i$N0UL#WFM$9$k(B C-o $B$G$"$l$P!"(B + ;; browse-command $B$O(B skk-insert() $B$H$J$k!#(B SPC $B$b(B skk-insert() $B$G$"$k$?$a!"(B + ;; $B7k2L$H$7$F(B SPC $B$NBG80$G(B browse-command $B$H$J$C$F$7$^$&!#(B + ;; * skk-kakutei-key $B$,(B skk-insert() $B$J$N$O(B skk-compile-rule-list() $B;2>H$N$3$H!#(B + (it (key-binding skk-annotation-browse-key)) ; Fix #58 + (browse-command (if (eq 'skk-insert it) nil it)) ; Fix #58 (list (list copy-command browse-command)) event key command urls note cache char digit exit) (while (and (not exit) list - (or (memq this-command - '(skk-annotation-wikipedia-region-or-at-point - skk-annotation-lookup-region-or-at-point)) + (or (memq this-command '(skk-annotation-wikipedia-region-or-at-point + skk-annotation-lookup-region-or-at-point)) (eq skk-henkan-mode 'active)) (if digit t @@ -722,17 +730,14 @@ (progn (setq event (next-command-event) key (skk-event-key event) - command (key-binding - (if (featurep 'xemacs) event key))) + command (key-binding (if (featurep 'xemacs) event key))) ;; Return value of the following expression is important. (or (memq command list) (eq command 'digit-argument) - (memq command - '(skk-annotation-wikipedia-region-or-at-point - skk-annotation-lookup-region-or-at-point)) + (memq command '(skk-annotation-wikipedia-region-or-at-point + skk-annotation-lookup-region-or-at-point)) (equal (key-description key) - (key-description - skk-annotation-wikipedia-key)))) + (key-description skk-annotation-wikipedia-key)))) (quit (when (eval-when-compile (and (featurep 'xemacs) (= emacs-major-version 21) @@ -765,46 +770,43 @@ (when url (setq urls (cons url urls))))) (unless (equal annotation "") - (cond - (urls - (dolist (url urls) - (cond ((consp url) - (setq exit t) - (apply (car url) (cdr url))) - (t - (browse-url url)))) - (skk-message "$BCm digit 0) - (<= digit - (length skk-annotation-other-sources))) - (list (nth (1- digit) - skk-annotation-other-sources)) - skk-annotation-other-sources)) + (memq command '(skk-annotation-wikipedia-region-or-at-point + skk-annotation-lookup-region-or-at-point))) + (setq sources (if (and digit + (> digit 0) + (<= digit + (length skk-annotation-other-sources))) + (list (nth (1- digit) + skk-annotation-other-sources)) + skk-annotation-other-sources)) (setq event nil digit nil char nil) @@ -985,7 +987,7 @@ information etc. If PROC is non-nil, check the buffer for that process." (cond ((eval-when-compile (skkannot-emacs-24_3-or-later)) - (with-current-buffer (process-buffer (or proc (python-proc))) + (with-current-buffer (process-buffer (or proc (python-shell-internal-get-or-create-process))) (save-excursion (save-match-data (re-search-backward (concat python-shell-prompt-regexp " *\\=") @@ -1017,7 +1019,7 @@ (t ;; python + readline $B$G(B UTF-8 $B$NF~NO$r$9$k$?$a$K(B LANG $B$N@_Dj$,I,MW!#(B (let* ((env (getenv "LANG")) - python-buffer orig-py-buffer) + orig-py-buffer) (unless (eval-when-compile (skkannot-emacs-24_3-or-later)) ;; Emacs 24.2 or earlier (setq orig-py-buffer (default-value 'python-buffer))) @@ -1027,7 +1029,7 @@ (run-python skk-annotation-python-program t t)) (when (eval-when-compile (skkannot-emacs-24_3-or-later)) ;; Emacs 24.3 or later - (setq python-buffer (get-buffer (format "*%s*" python-shell-buffer-name)) + (setq python-buffer (get-buffer (format "*%s*" (python-shell-get-process-name t))) orig-py-buffer (default-value 'python-buffer))) (setenv "LANG" env) (with-current-buffer python-buffer @@ -1035,13 +1037,18 @@ (setq-default python-buffer orig-py-buffer) (setq python-buffer orig-py-buffer) (setq skkannot-py-buffer (current-buffer)) - ;; + (font-lock-mode 0) (set-buffer-multibyte t) (skk-process-kill-without-query (get-buffer-process (current-buffer))) (set-buffer-file-coding-system 'utf-8-emacs) - (set-buffer-process-coding-system 'utf-8-unix 'utf-8-unix) - ;; + + ;; Jan 15 2018, lisp/international/mule.el + ;; * (set-buffer-process-coding-system): Mark as interactive-only. + ;; * in Lisp code use 'set-process-coding-system' instead. + (set-process-coding-system (get-buffer-process (current-buffer)) + 'utf-8-unix 'utf-8-unix) + (skkannot-py-send-command "import DictionaryServices") (cond ((and wait (skkannot-sit-for 1.0)) (setq skkannot-remaining-delay @@ -1050,7 +1057,6 @@ (throw '$B<-=q(B nil)) (t nil)) - ;; skkannot-py-buffer))))) (defun skkannot-DictServ-cache (word truncate) diff -Nru ddskk-16.2/skk-comp.el ddskk-16.2+0.20190423/skk-comp.el --- ddskk-16.2/skk-comp.el 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/skk-comp.el 2019-04-23 12:49:58.000000000 +0000 @@ -96,8 +96,7 @@ ;; prefix $B$KBP1~$9$k!V$+$J!W(Betc. $B$,$"$l$P(B non-t ;; $BI{:nMQ$rH<$J$&%k!<%k$,;XDj$5$l$F$$$k$+$b$7$l$J$$$N$G!"(B ;; $B%G!<%?$,$"$k$+$I$&$+$N%A%'%C%/$N$_$K;H$&!#(B - (setq data - (skk-kana-cleanup 'force)) + (setq data (skk-kana-cleanup 'force)) (when (or skk-abbrev-mode (memq skk-comp-use-prefix '(nil kakutei-first))) (setq skk-comp-key (buffer-substring-no-properties @@ -190,7 +189,7 @@ (while (and (null cand) skk-current-completion-prog-list) (setq prog (car skk-current-completion-prog-list)) - (setq cand (eval prog) + (setq cand (eval prog) ; `skk-comp-key' $B$r%-!<$H$7$F!"J8;zNs$R$H$D$,La$k(B skk-comp-first nil) (unless cand (setq skk-current-completion-prog-list diff -Nru ddskk-16.2/skk-dcomp.el ddskk-16.2+0.20190423/skk-dcomp.el --- ddskk-16.2/skk-dcomp.el 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/skk-dcomp.el 2019-04-23 12:49:58.000000000 +0000 @@ -243,72 +243,78 @@ (declare-function skk-comp-get-candidate "skk-comp") (defun skk-dcomp-multiple-get-candidates (&optional same-key) (let (candidates) - (cond ( ;; $B?75,8!:w(B - (not same-key) - (setq skk-dcomp-multiple-select-index - ;; skk-comp $B$N(B C-u TAB $B$r9MN8$9$k(B - (if (and current-prefix-arg (listp current-prefix-arg)) 0 -1)) - (setq skk-dcomp-multiple-key - ;; skk-comp $B$N(B C-u TAB $B$r9MN8$9$k(B - (if (and current-prefix-arg (listp current-prefix-arg)) - skk-comp-key - (let ((key (buffer-substring-no-properties - skk-henkan-start-point (point)))) - (if skk-katakana - (skk-katakana-to-hiragana key) - key)))) - (setq skk-dcomp-multiple-prefix skk-prefix) - (setq skk-dcomp-multiple-search-done nil) - (let ( ;; `skk-comp-get-candidate' $B$KI,MW$J%G!<%?$rB+G{(B - (skk-comp-key skk-dcomp-multiple-key) - (skk-comp-prefix skk-dcomp-multiple-prefix) - ;; `skk-comp-get-candidate' $B$GCM$,JQ$o$C$F$7$^$&$?$aB+G{(B - (skk-current-completion-prog-list - skk-current-completion-prog-list) - (skk-server-completion-words skk-server-completion-words) - (skk-look-completion-words skk-look-completion-words) - (i 0) - cand) - (when (or skk-comp-use-prefix - ;; skk-comp-use-prefix $B$,(B nil $B$N>l9g!""&(Bn $B$J$I$O(B - ;; $BJd408uJd$r8!:w$7$J$$(B - (not (skk-get-kana skk-current-rule-tree))) - (skk-dcomp-save-point-in-jisyo-buffer - (while (and (< i skk-dcomp-multiple-rows) - (setq cand (skk-comp-get-candidate (zerop i)))) - (unless (member cand candidates) - (push cand candidates) - (incf i))))) - (setq candidates (nreverse candidates)) - (when (< i skk-dcomp-multiple-rows) - (setq skk-dcomp-multiple-search-done t)) - (setq skk-dcomp-multiple-candidates candidates))) - ;; $BA4$F8!:w:Q(B - (skk-dcomp-multiple-search-done - (setq candidates (skk-dcomp-multiple-extract-candidates - skk-dcomp-multiple-candidates - skk-dcomp-multiple-select-index))) - ;; $BA48!:w$9$k(B - ((and same-key - (< (1- (length skk-dcomp-multiple-candidates)) - skk-dcomp-multiple-select-index)) - (skk-dcomp-save-point-in-jisyo-buffer - (let ( ;; `skk-comp-get-all-candidates' $B$G6u$K$J$C$F$7$^$&$?$aB+G{(B - (skk-comp-kakutei-midasi-list skk-comp-kakutei-midasi-list) - (skk-server-completion-words skk-server-completion-words) - (skk-look-completion-words skk-look-completion-words)) - (setq skk-dcomp-multiple-candidates - (skk-comp-get-all-candidates skk-dcomp-multiple-key - skk-dcomp-multiple-prefix - skk-completion-prog-list)))) - (setq skk-dcomp-multiple-search-done t) - (setq skk-dcomp-multiple-select-index - (min skk-dcomp-multiple-select-index - (1- (length skk-dcomp-multiple-candidates)))) - (setq candidates (skk-dcomp-multiple-extract-candidates - skk-dcomp-multiple-candidates - skk-dcomp-multiple-select-index))) - (t (setq candidates skk-dcomp-multiple-candidates))) + (cond + ;; (1) $B?75,8!:w(B + ((not same-key) + (setq skk-dcomp-multiple-select-index + ;; skk-comp $B$N(B C-u TAB $B$r9MN8$9$k(B + (if (and current-prefix-arg (listp current-prefix-arg)) 0 -1)) + (setq skk-dcomp-multiple-key + ;; skk-comp $B$N(B C-u TAB $B$r9MN8$9$k(B + (if (and current-prefix-arg (listp current-prefix-arg)) + skk-comp-key + (let ((key (buffer-substring-no-properties + skk-henkan-start-point (point)))) + (if skk-katakana + (skk-katakana-to-hiragana key) + key)))) + (setq skk-dcomp-multiple-prefix skk-prefix) + (setq skk-dcomp-multiple-search-done nil) + (let ( ;; `skk-comp-get-candidate' $B$KI,MW$J%G!<%?$rB+G{(B + (skk-comp-key skk-dcomp-multiple-key) + (skk-comp-prefix skk-dcomp-multiple-prefix) + ;; `skk-comp-get-candidate' $B$GCM$,JQ$o$C$F$7$^$&$?$aB+G{(B + (skk-current-completion-prog-list + skk-current-completion-prog-list) + (skk-server-completion-words skk-server-completion-words) + (skk-look-completion-words skk-look-completion-words) + (i 0) + cand) + (when (or skk-comp-use-prefix + ;; skk-comp-use-prefix $B$,(B nil $B$N>l9g!""&(Bn $B$J$I$O(B + ;; $BJd408uJd$r8!:w$7$J$$(B + (not (skk-get-kana skk-current-rule-tree))) + (skk-dcomp-save-point-in-jisyo-buffer + (while (and (< i skk-dcomp-multiple-rows) + (setq cand (skk-comp-get-candidate (zerop i)))) + (unless (member cand candidates) + (push cand candidates) + (incf i))))) + (setq candidates (nreverse candidates)) + (when (< i skk-dcomp-multiple-rows) + (setq skk-dcomp-multiple-search-done t)) + (setq skk-dcomp-multiple-candidates candidates))) + + ;; (2) $BA4$F8!:w:Q(B + (skk-dcomp-multiple-search-done + (setq candidates (skk-dcomp-multiple-extract-candidates + skk-dcomp-multiple-candidates + skk-dcomp-multiple-select-index))) + + ;; (3) $BA48!:w$9$k(B (TAB $BO"BG$G7+$j1[$7$?$H$-(B) + ((and same-key + (< (1- (length skk-dcomp-multiple-candidates)) + skk-dcomp-multiple-select-index)) + (skk-dcomp-save-point-in-jisyo-buffer + (let ( ;; `skk-comp-get-all-candidates' $B$G6u$K$J$C$F$7$^$&$?$aB+G{(B + (skk-comp-kakutei-midasi-list skk-comp-kakutei-midasi-list) + (skk-server-completion-words skk-server-completion-words) + (skk-look-completion-words skk-look-completion-words)) + (setq skk-dcomp-multiple-candidates + (skk-comp-get-all-candidates skk-dcomp-multiple-key + skk-dcomp-multiple-prefix + skk-completion-prog-list)))) + (setq skk-dcomp-multiple-search-done t) + (setq skk-dcomp-multiple-select-index + (min skk-dcomp-multiple-select-index + (1- (length skk-dcomp-multiple-candidates)))) + (setq candidates (skk-dcomp-multiple-extract-candidates + skk-dcomp-multiple-candidates + skk-dcomp-multiple-select-index))) + + ;; (4) $BC1$J$k(B TAB $BBG80(B + (t + (setq candidates skk-dcomp-multiple-candidates))) (when candidates (append candidates (list (format " [ %s / %s ]" @@ -470,11 +476,17 @@ ad-do-it) (t (cond - ((or (eq skk-henkan-mode 'active) + ((or (eq skk-henkan-mode 'active) ; $B"'%b!<%I(B (skk-get-prefix skk-current-rule-tree) (not skk-comp-stack)) (skk-set-marker skk-dcomp-start-point nil) (skk-set-marker skk-dcomp-end-point nil)) + + ;; experimental/skk-pre-henkan.el + ((and (featurep 'skk-pre-henkan) + (eq last-command 'skk-comp-do)) + (skk-kakutei)) + ((skk-dcomp-marked-p) (skk-dcomp-face-off) (unless (member (this-command-keys) diff -Nru ddskk-16.2/skk-develop.el ddskk-16.2+0.20190423/skk-develop.el --- ddskk-16.2/skk-develop.el 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/skk-develop.el 2019-04-23 12:49:58.000000000 +0000 @@ -146,7 +146,7 @@ (defun skk-get-download (dir) "DIR." - (let ((url "http://openlab.ring.gr.jp/skk/dic/") + (let ((url "https://skk-dev.github.io/dict/") fn) (dolist (f skk-get-files) (setq fn (expand-file-name f dir)) diff -Nru ddskk-16.2/skk.el ddskk-16.2+0.20190423/skk.el --- ddskk-16.2/skk.el 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/skk.el 2019-04-23 12:49:58.000000000 +0000 @@ -194,6 +194,7 @@ (when (eval-when-compile (featurep 'xemacs)) (make-local-hook 'post-command-hook)) (add-hook 'post-command-hook 'skk-after-point-move nil 'local) + (skk-search-ja-dic-maybe t) (skk-j-mode-on) (run-hooks 'skk-mode-hook))) @@ -490,10 +491,6 @@ (define-key skk-j-mode-map skk-previous-completion-backtab-key #'skk-previous-comp-maybe)) ;; - (when (characterp (symbol-value 'skk-previous-candidate-char)) - (add-to-list 'skk-previous-candidate-keys - (skk-char-to-unibyte-string - (symbol-value 'skk-previous-candidate-char)))) (unless (featurep 'skk-kanagaki) (dolist (key skk-previous-candidate-keys) (define-key skk-j-mode-map key #'skk-previous-candidate))) @@ -1419,8 +1416,7 @@ (setq rule (cons key (cdr rule))))) (unless (or (not (stringp key)) (string-match "\\w" key) - (eq (key-binding key) - 'self-insert-command)) + (eq (key-binding key) 'self-insert-command)) (define-key skk-j-mode-map key 'skk-insert))) (when (stringp key) (skk-add-rule tree rule)))) @@ -2716,14 +2712,14 @@ \"word\" --> (\"word\" . nil) \"word;\" --> (\"word\" . \"\") \"word;note\" --> (\"word\" . \"note\") -" - (save-match-data - (let (cand note) - (if (string-match ";" word) - (setq cand (substring word 0 (match-beginning 0)) - note (substring word (match-end 0))) - (setq cand word)) - (cons cand note)))) +"(when word + (save-match-data + (let (cand note) + (if (string-match ";" word) + (setq cand (substring word 0 (match-beginning 0)) + note (substring word (match-end 0))) + (setq cand word)) + (cons cand note))))) (defun skk-kakutei (&optional arg word) "$B8=:_I=<($5$l$F$$$k8l$G3NDj$7!"<-=q$r99?7$9$k!#(B @@ -4800,7 +4796,9 @@ 0 (1- (length skk-henkan-key)))))) -(defun skk-search-ja-dic-maybe () +(defun skk-search-ja-dic-maybe (&optional check) + ;; `skk-search-prog-list' $B$N0lMWAG$H$7$F:nMQ$9$k$[$+!"(B + ;; skk-mode $B$KF~$k$?$S(B check $B$GI>2A$5$l$k!#(B (when (eval-when-compile (featurep 'emacs)) (unless (or (and (stringp skk-large-jisyo) (file-readable-p skk-large-jisyo)) @@ -4810,7 +4808,10 @@ (file-readable-p skk-cdb-large-jisyo)) skk-server-host skk-inhibit-ja-dic-search) - (skk-search-ja-dic)))) + (if check + (skk-message "$B<-=q$H$7$F(B leim/ja-dic $B$r;H$$$^$9(B" + "Use leim/ja-dic as dictionary") + (skk-search-ja-dic))))) (defun skk-search-with-suffix () (unless (or skk-henkan-okurigana diff -Nru ddskk-16.2/skk-gadget.el ddskk-16.2+0.20190423/skk-gadget.el --- ddskk-16.2/skk-gadget.el 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/skk-gadget.el 2019-04-23 12:49:58.000000000 +0000 @@ -169,13 +169,18 @@ (multiple-value-bind (year month day day-of-week hour minute second v) date-information (when gengo - (setq v (skk-ad-to-gengo-1 (string-to-number year)))) + (setq v (skk-ad-to-gengo-1 + (string-to-number year) nil + (string-to-number (nth 0 (cdr (assoc month skk-month-alist)))) + (string-to-number day)))) (setq year (if gengo (concat (if gengo-index (nth gengo-index (car v)) (caar v)) - (skk-num-exp (number-to-string (cdr v)) - num-type)) + (if (numberp (cdr v)) + (skk-num-exp (number-to-string (cdr v)) + num-type) + (cdr v))) (skk-num-exp year num-type))) (when month-alist-index (setq month (skk-num-exp (nth month-alist-index @@ -351,7 +356,7 @@ tail))) ;;;###autoload -(defun skk-ad-to-gengo-1 (ad &optional not-gannen) +(defun skk-ad-to-gengo-1 (ad &optional not-gannen month day) ;; AD is a number and NOT-GANNEN is a boolean optional ;; arg. ;; return a cons cell of which car is a Gengo list @@ -361,18 +366,24 @@ ;; return a value of which cdr is "$B85(B" (string). (when (>= 1866 ad) (skk-error "$BJ,$j$^$;$s(B" "Unknown year")) - (cons (cond ((>= 1911 ad) + (cons (cond ((or (< ad 1912) (and (= ad 1912) month (< month 7)) + (and (= ad 1912) month (= month 7) day (< day 30))) (setq ad (- ad 1867)) (cdr (assq 'meiji skk-gengo-alist))) - ((>= 1925 ad) + ((or (< ad 1926) (and (= ad 1926) month (< month 12)) + (and (= ad 1926) month (= month 12) day (< day 25))) (setq ad (- ad 1911)) (cdr (assq 'taisho skk-gengo-alist))) - ((>= 1988 ad) + ((or (< ad 1989) + (and (= ad 1989) month (= month 1) day (< day 8))) (setq ad (- ad 1925)) (cdr (assq 'showa skk-gengo-alist))) - (t + ((or (< ad 2019) (and (= ad 2019) month (< month 5))) (setq ad (- ad 1988)) - (cdr (assq 'heisei skk-gengo-alist)))) + (cdr (assq 'heisei skk-gengo-alist))) + (t + (setq ad (- ad 2018)) + (cdr (assq 'reiwa skk-gengo-alist)))) (cond (not-gannen ad) ((= ad 1) "$B85(B") (t ad)))) @@ -404,23 +415,16 @@ ((eq number 0) (skk-error "0 $BG/$O$"$jF@$J$$(B" "Cannot convert 0 year")) + ((member gengo '("$B$l$$$o(B" "$BNaOB(B")) + 2018) ((member gengo '("$B$X$$$;$$(B" "$BJ?@.(B")) 1988) ((member gengo '("$B$7$g$&$o(B" "$B> 64 number) - 1925 - (skk-error "$B> 15 number) - 1911 - (skk-error "$BBg@5$O(B 14 $BG/$^$G$G$9(B" - "The last year of Taisyo is 14"))) + 1911) ((member gengo '("$B$a$$$8(B" "$BL@<#(B")) - (if (> 45 number) - 1867 - (skk-error "$BL@<#$O(B 44 $BG/$^$G$G$9(B" - "The last year of Meiji is 44"))) + 1867) (t (skk-error "$BH=JLITG=$J859f$G$9!*(B" "Unknown Gengo!"))))) diff -Nru ddskk-16.2/skk-macs.el ddskk-16.2+0.20190423/skk-macs.el --- ddskk-16.2/skk-macs.el 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/skk-macs.el 2019-04-23 12:49:58.000000000 +0000 @@ -435,17 +435,17 @@ (x-display-color-p))))) (defun skk-char-to-unibyte-string (char) - ;; Warning: `string-make-unibyte' is an obsolete function (as of 26.1). - ;; use `encode-coding-string'. - (ignore-errors (cond ;; XEmacs ((eval-when-compile (featurep 'xemacs)) (char-to-string char)) - ;; GNU Emacs 26 $B$+$i(B + + ;; Warning: `string-make-unibyte' is an obsolete function (as of 26.1). + ;; use `encode-coding-string'. ((eval-when-compile (>= emacs-major-version 26)) - (encode-coding-string (char-to-string char) 'us-ascii)) + (encode-coding-string (char-to-string char) 'iso-8859-1)) + ;; GNU Emacs 25 $B$^$G(B (t (string-make-unibyte (char-to-string char)))))) diff -Nru ddskk-16.2/SKK-MK ddskk-16.2+0.20190423/SKK-MK --- ddskk-16.2/SKK-MK 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/SKK-MK 2019-04-23 12:49:58.000000000 +0000 @@ -89,7 +89,8 @@ (when (file-directory-p dir) (add-to-list 'load-path dir)))) -(require 'install (expand-file-name "install.el")) +(require 'install (expand-file-name + (convert-standard-filename "maint/install.el"))) (setq install-prefix (cond ((eq system-type 'windows-nt) @@ -196,6 +197,7 @@ (defvar SKK_INFO "skk.info") (defvar SKK_INFO_DIR_FILE nil) (defvar SKK_TEXIS '("skk.texi")) +(defvar SKK_ORG "skk.org") (defvar SKK_TUTORIALS '("SKK.tut" "SKK.tut.E" "NICOLA-SKK.tut" "skk.xpm")) (defvar SKK_DICTIONARIES '("SKK-JISYO.L" "SKK-JISYO.ML" "SKK-JISYO.M" "SKK-JISYO.S" "SKK-JISYO.JIS2" @@ -259,6 +261,7 @@ skk-correct skk-exsearch skk-exserv + skk-pre-henkan skk-rdbms skk-tutcdef skk-tutcode @@ -448,6 +451,89 @@ (compile-elisp-modules SKK_MODULES (expand-file-name ".")))) +(defun SKK-MK-export-to-html () + (when (and SKK_ORG + (file-exists-p (expand-file-name SKK_ORG DOCDIR))) + (require 'htmlize (expand-file-name "htmlize.el" DOCDIR)) + (let ((make-backup-files nil)) + (with-current-buffer + (find-file (expand-file-name SKK_ORG DOCDIR)) + (org-html-export-to-html)) + + (with-current-buffer + (find-file (expand-file-name "skk.html" DOCDIR)) + (when (version< org-version "9.0") + (goto-char (point-min)) + (let ((start (progn (search-forward "@ifinfo") (beginning-of-line) (point))) + (end (progn (search-forward "@end ifinfo") (point)))) + (delete-region start end))) + + (dolist (e '(("~,~" . ",") + ("n ' " . "n ' ") + (" RET" . " RET") + ("RET" . "RET") + ("^RET" . "RET") + (" SPC" . " SPC") + ("SPC" . "SPC") + ("^SPC" . "SPC") + (" TAB" . " TAB") + ("^TAB" . "TAB") + ("TAB" . "TAB") + ("^BS" . "BS") + + ("User Option: \\(.*\\)" . "User Option: \\1") + ("Function: \\(.*\\)" . "Function: \\1") + ("Variable: \\(.*\\)" . "Variable: \\1") + ("Key: \\([^,]*\\), \\(.*\\)" . "Key: \\1 (\\2)") + )) + (goto-char (point-min)) + (while (re-search-forward (car e) nil t) + (replace-match (cdr e)))) + + (basic-save-buffer))))) + +(defun SKK-MK-export-to-texinfo () + (when (and SKK_ORG + (file-exists-p (expand-file-name SKK_ORG DOCDIR))) + ;; https://github.com/magnars/dash.el + (require 'dash (expand-file-name "dash.el" DOCDIR)) + ;; https://github.com/tarsius/ox-texinfo-plus + (require 'ox-texinfo+ (expand-file-name "ox-texinfo+.el" DOCDIR)) + + (let ((org-texinfo-classes '(("info+" + "@documentencoding AUTO\n@documentlanguage AUTO" + ("@chapter %s" . "@chapter %s") + ("@section %s" . "@section %s") + ("@subsection %s" . "@subsection %s") + ("@subsubsection %s" . "@unnumberedsubsubsec %s") + ("@subsubsection %s" . "@unnumberedsubsubsec %s") + ))) + (make-backup-files nil)) + (with-current-buffer + (find-file (expand-file-name SKK_ORG DOCDIR)) + (org-texinfo-export-to-texinfo)) ; skk.texi $B$,J]B8$5$l$k(B ($B6/@)>e=q$-(B) + + (with-current-buffer + (find-file (expand-file-name "skk.texi" DOCDIR)) + (dolist (e '(("input texinfo" . "input texinfo-ja") + ("@c -*- texinfo -*-" . "@c -*- mode: texinfo; coding: utf-8 -*-\n\n@c ** This file was generated automatically by SKK-MK **\n") + ("@@ifinfo" . "@ifinfo") + ("@@end ifinfo" . "@end ifinfo") + ("@@ignore" . "@ignore") + ("@@end ignore" . "@end ignore") + ("@dircategory Emacs" . "@dircategory GNU Emacs Lisp\n@dircategory Emacs") + ("@end iftex" . "@end iftex\n@tex\n\\\\global\\\\def\\\\linkcolor{0 0 1}\n\\\\global\\\\def\\\\urlcolor{0 0 1}\n@end tex\n") + ("@menu" . "\n@menu") + ("n '" . "@code{n '}") + ("~,~" . "@code{,}") + ("{ } ^" . "@{ @} ^") + ("{$B%"%N%F!<%7%g%s(B}" . "@{$B%"%N%F!<%7%g%s(B@}") + )) + (goto-char (point-min)) + (while (search-forward (car e) nil t) + (replace-match (cdr e)))) + (basic-save-buffer))))) + (defun SKK-MK-compile-info () (when (and SKK_INFO (or (not (file-exists-p @@ -457,6 +543,24 @@ (expand-file-name SKK_INFO DOCDIR)))) (SKK-MK-texinfo-format SKK_TEXIS))) +(defun SKK-MK-edit-texi () + (when (file-exists-p (expand-file-name "skk.texi" DOCDIR)) + (with-current-buffer + (find-file (expand-file-name "skk.texi" DOCDIR)) + + (goto-char (point-min)) + (let ((start (progn (search-forward "@footnotestyle") (beginning-of-line) (point))) + (end (progn (end-of-line) (point)))) + (delete-region start end)) + + (dolist (e '(("@dircategory" . "@end direntry"))) + (goto-char (point-min)) + (let ((start (progn (search-forward (car e)) (beginning-of-line) (point))) + (end (progn (search-forward (cdr e)) (point)))) + (delete-region start end))) + (set-visited-file-name "tmp.texi") + (basic-save-buffer)))) + (defun SKK-MK-compile-package () (SKK-MK-generate-autoloads-el-package) (setq features (delq 'skk-autoloads features)) @@ -810,8 +914,10 @@ (defun SKK-MK-texinfo-format (targets) (let (;; Emacs20.2's default is 'raw-text-unix. (coding-system-for-write SKK-MK-texinfo-coding-system) + (make-backup-files nil) x obuf beg standard-output) - (require 'ptexinfmt (expand-file-name "ptexinfmt.el")) + (require 'ptexinfmt (expand-file-name + (convert-standard-filename "maint/ptexinfmt.el"))) (while targets (setq x (expand-file-name (car targets) DOCDIR)) (find-file x) diff -Nru ddskk-16.2/skk-search-web.el ddskk-16.2+0.20190423/skk-search-web.el --- ddskk-16.2/skk-search-web.el 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/skk-search-web.el 2019-04-23 12:49:58.000000000 +0000 @@ -52,16 +52,14 @@ ;; (lambda () ;; (car (skk-google-cgi-api-for-japanese-input skk-henkan-key)))) -;;; Requre -;; json.el $B$rI,MW$H$7$^$9!#(Bjson.el $B$O(B Emacs 23.1 $B$+$i$OI8=`$G$9!#(B -;; Emacs 22 $B$rMxMQ$7$F$$$kJ}$O!"(B -;; http://edward.oconnor.cx/elisp/json.el -;; $B$+$i(B json.el $B$r ("emacs" "emacs $B%3%^%s%I(B" "emacs windows" "emacs $B;H$$J}(B" "emacs $BJ8;z%3!<%I(B" ...) ;;; $B $B$5$s$,(B @@ -158,6 +156,22 @@ (defun skk-search-web (function) (funcall function skk-henkan-key)) +;; skk-comp, skk-dcomp, +(defvar skk-comp-google-candidates nil) + +(defun skk-comp-google () + ;; Howto use + ;; (add-to-list 'skk-completion-prog-list '(skk-comp-google) t) + (unless (string= skk-comp-key "") + (when skk-comp-first + (setq skk-comp-google-candidates (skk-comp-google-make-candidates))) + (prog1 + (car skk-comp-google-candidates) + (setq skk-comp-google-candidates (cdr skk-comp-google-candidates))))) + +(defun skk-comp-google-make-candidates () + (let ((key (car (split-string skk-comp-key "*" t)))) + (skk-google-suggest key))) (provide 'skk-search-web) diff -Nru ddskk-16.2/skk-vars.el ddskk-16.2+0.20190423/skk-vars.el --- ddskk-16.2/skk-vars.el 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/skk-vars.el 2019-04-23 12:49:58.000000000 +0000 @@ -1287,8 +1287,6 @@ '(repeat sexp)) :group 'skk-henkan) -(defvar skk-previous-candidate-char nil) - (make-obsolete-variable 'skk-previous-candidate-char 'skk-previous-candidate-keys "DDSKK 14.2") @@ -2891,8 +2889,7 @@ (const :tag "$BMxMQ$7$J$$(B" nil)) :group 'skk-annotation) -(defcustom skk-annotation-python-program (or (executable-find "python2.6") - (executable-find "python")) +(defcustom skk-annotation-python-program (executable-find "python") "*DictionaryServices $B$N$?$a$K5/F0$9$k(B python $B$N%U%!%$%kL>!#(B" :type '(radio (file) (const nil)) @@ -3661,8 +3658,8 @@ ;;; skk-gadget.el related. (defcustom skk-gengo-alist - '((heisei "$BJ?@.(B" "H") (showa "$B>>Fb(B") ;;;###autoload (defun skk-version (&optional without-codename) diff -Nru ddskk-16.2/tar-util.el ddskk-16.2+0.20190423/tar-util.el --- ddskk-16.2/tar-util.el 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/tar-util.el 2019-04-23 12:49:58.000000000 +0000 @@ -25,7 +25,7 @@ ;; ~/bar.el として保存します。 ;; ;; o (tar-list-files "~/temp/foo.tar") -;; アーカイブ foo.tar の中のファイル郡をリストで返します。 +;; アーカイブ foo.tar の中のファイル群をリストで返します。 ;;; shut up compiler warning. (eval-when-compile diff -Nru ddskk-16.2/vip.el ddskk-16.2+0.20190423/vip.el --- ddskk-16.2/vip.el 2017-03-04 05:21:04.000000000 +0000 +++ ddskk-16.2+0.20190423/vip.el 1970-01-01 00:00:00.000000000 +0000 @@ -1,3220 +0,0 @@ -;;; vip.el --- a VI Package for GNU Emacs - -;; Author: Masahiko Sato -;; Maintainer: SKK Development Team -;; Keywords: emulations -;; Previous versions: -;; Version 3.5: September 15, 1987 - -;; This file is part of GNU Emacs. - -;; GNU Emacs 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. - -;; GNU Emacs 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., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: - -;; A full-featured vi(1) emulator. -;; -;; Send suggestions and bug reports to one of the above addresses. -;; When you report a bug, be sure to include the version number of VIP and -;; Emacs you are using. - -;; Execute info command by typing "M-x info" to get information on VIP. - -;;; Code: -;; APEL 9.22 required. -(require 'poe) - -;; external variables -;; Not so easy to work on XEmacs... -;;(defconst vip-xemacs-p (string-match "XEmacs" emacs-version)) - -(defvar vip-insert-point nil - "Remember insert point as a marker. (Buffer-specific.)") - -(set-default 'vip-insert-point nil) -(make-variable-buffer-local 'vip-insert-point) - -(defvar vip-com-point nil - "Remember com point as a marker. (Buffer-specific.)") - -(set-default 'vip-com-point nil) -(make-variable-buffer-local 'vip-com-point) - -(defvar vip-current-mode nil - "Current mode. One of `emacs-mode', `vi-mode', `insert-mode'.") - -(make-variable-buffer-local 'vip-current-mode) -(setq-default vip-current-mode 'emacs-mode) - -(defvar vip-emacs-mode-line-buffer-identification nil - "Value of mode-line-buffer-identification in Emacs mode within vip.") -(make-variable-buffer-local 'vip-emacs-mode-line-buffer-identification) -(setq-default vip-emacs-mode-line-buffer-identification - '("Emacs: %17b")) - -(defvar vip-current-major-mode nil - "vip-current-major-mode is the major-mode vi considers it is now. -\(buffer specific\)") - -(make-variable-buffer-local 'vip-current-major-mode) - -(defvar vip-last-shell-com nil - "Last shell command executed by ! command.") - -(defvar vip-use-register nil - "Name of register to store deleted or yanked strings.") - -(defvar vip-d-com nil - "How to reexecute last destructive command. Value is list (M-COM VAL COM).") - -(defconst vip-shift-width 8 - "*The number of columns shifted by > and < command.") - -(defconst vip-re-replace nil - "*If t then do regexp replace, if nil then do string replace.") - -(defvar vip-d-char nil - "The character remembered by the vi \"r\" command.") - -(defvar vip-f-char nil - "For use by \";\" command.") - -(defvar vip-F-char nil - "For use by \".\" command.") - -(defvar vip-f-forward nil - "For use by \";\" command.") - -(defvar vip-f-offset nil - "For use by \";\" command.") - -(defconst vip-search-wrap-around t - "*if t, search wraps around.") - -(defconst vip-re-search nil - "*if t, search is reg-exp search, otherwise vanilla search.") - -(defvar vip-s-string nil - "Last vip search string.") - -(defvar vip-s-forward nil - "If t, search is forward.") - -(defconst vip-case-fold-search nil - "*If t, search ignores cases.") - -(defconst vip-re-query-replace nil - "*If t then do regexp replace, if nil then do string replace.") - -(defconst vip-open-with-indent nil - "*If t, indent when open a new line.") - -(defconst vip-help-in-insert-mode nil - "*If t then C-h is bound to help-command in insert mode. -If nil then it is bound to `delete-backward-char'.") - -(defvar vip-quote-string "> " - "String inserted at the beginning of region.") - -(defvar vip-tags-file-name "TAGS") - -(defvar vip-inhibit-startup-message nil) - -(defvar vip-startup-file (convert-standard-filename "~/.vip") - "Filename used as startup file for vip.") - -;; SKK related variables - -(defvar vip-skk-latin-mode nil) -(make-variable-buffer-local 'vip-skk-latin-mode) -(defvar vip-skk-j-mode nil) -(make-variable-buffer-local 'vip-skk-j-mode) -(defvar vip-skk-jisx0208-latin-mode nil) -(make-variable-buffer-local 'vip-skk-jisx0208-mode) -(defvar vip-skk-katakana nil) -(make-variable-buffer-local 'vip-skk-katakana) -(defvar vip-vi-mode nil) -(make-variable-buffer-local 'vip-vi-mode) -(defvar vip-insert-mode nil) -(make-variable-buffer-local 'vip-insert-mode) - - -;; basic set up -(defmacro vip-move-marker-locally (marker position &optional buffer) - (list 'progn - (list 'if (list 'not marker) - (list 'setq marker (list 'make-marker))) - (list 'set-marker marker position buffer))) - -(global-set-key "\C-z" 'vip-change-mode-to-vi) - -(defmacro vip-loop (count body) - "(COUNT BODY) Execute BODY COUNT times." - (list 'let (list (list 'count count)) - (list 'while (list '> 'count 0) - body - (list 'setq 'count (list '1- 'count))))) - -(defun vip-push-mark-silent (&optional location) - "Set mark at LOCATION (point, by default) and push old mark on mark ring. -No message." - (if (null (mark t)) - nil - (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring)) - (if (> (length mark-ring) mark-ring-max) - (progn - (move-marker (car (nthcdr mark-ring-max mark-ring)) nil) - (setcdr (nthcdr (1- mark-ring-max) mark-ring) nil)))) - (set-mark (or location (point)))) - -(defun vip-goto-col (arg) - "Go to ARG's column." - (interactive "P") - (let ((val (vip-p-val arg)) - (com (vip-getcom arg))) - (save-excursion - (end-of-line) - (if (> val (1+ (current-column))) (error ""))) - (if com (vip-move-marker-locally vip-com-point (point))) - (beginning-of-line) - (forward-char (1- val)) - (if com (vip-execute-com 'vip-goto-col val com)))) - -(defun vip-copy-keymap (map) - (if (null map) (make-sparse-keymap) (copy-keymap map))) - - -;; changing mode -;; the two useule functions below are taken from viper and -;; modified. - -(defun vip-normalize-minor-mode-map-alist () - (setq minor-mode-map-alist - (vip-append-filter-alist - (list - (cons 'vip-vi-mode vip-vi-mode-map) - (cons 'vip-insert-mode vip-insert-mode-map) - ) - minor-mode-map-alist))) - -;; Append LIS2 to LIS1, both alists, by side-effect and returns LIS1 -;; LIS2 is modified by filtering it: deleting its members of the form -;; \(car elt\) such that (car elt') is in LIS1. -(defun vip-append-filter-alist (lis1 lis2) - (let ((temp lis1) - elt) - ;;filter-append the second list - (while temp - ;; delete all occurrences - (while (setq elt (assoc (car (car temp)) lis2)) - (setq lis2 (delq elt lis2))) - (setq temp (cdr temp))) - (nconc lis1 lis2))) - -(defun vip-change-mode (new-mode) - "change mode to NEW-MODE. NEW-MODE will be either emacs-mode, vi-mode or - insert-mode." - (let ((skk-mode (if (boundp 'skk-mode) skk-mode nil))) - (cond ((eq new-mode 'vi-mode) - (if (eq vip-current-mode 'insert-mode) - (progn - (if skk-mode (vip-skk-mode-off)) - (vip-copy-region-as-kill (point) vip-insert-point) - (vip-repeat-insert-command)) - (if (eq vip-current-mode 'emacs-mode) - (setq vip-emacs-mode-line-buffer-identification - mode-line-buffer-identification))) - (vip-change-mode-line "Vi: ") - (setq vip-vi-mode t - vip-insert-mode nil) - ) - ((eq new-mode 'insert-mode) - (vip-move-marker-locally vip-insert-point (point)) - (if (eq vip-current-mode 'emacs-mode) - (setq vip-emacs-mode-line-buffer-identification - mode-line-buffer-identification)) - (vip-change-mode-line "Insrt") - (if skk-mode (vip-skk-mode-on)) - (setq vip-vi-mode nil - vip-insert-mode t)) - ((eq new-mode 'emacs-mode) - (vip-change-mode-line "Emacs:") - ;;(vip-skk-mode-off) - (setq vip-vi-mode nil - vip-insert-mode nil))) - (setq vip-current-mode new-mode) - (vip-normalize-minor-mode-map-alist) - (force-mode-line-update) - )) - -;; SKK related functions - -;;;###autoload -(defun vip-skk-mode (arg) - "Turn on both VIP-MODE and SKK-MODE. if ARG is nil, then toggle -SKK-MODE. Then, change mode to insert mode." - (interactive "P") - (or vip-current-mode (vip-mode)) - (cond ((eq vip-current-mode 'vi-mode) - (skk-mode arg) - (setq vip-skk-latin-mode skk-latin-mode - vip-skk-j-mode skk-j-mode - vip-skk-jisx0208-latin-mode skk-jisx0208-latin-mode - vip-skk-katakana skk-katakana) - (vip-change-mode-to-insert)) - ((eq vip-current-mode 'emacs-mode) - ;; in this case, alwasy enter skk mode - (skk-mode 1) - (vip-change-mode-to-insert)) - ((eq vip-current-mode 'insert-mode) - (skk-mode arg) - (vip-change-mode-to-insert)))) - -(defun vip-skk-mode-off () - (if skk-abbrev-mode (skk-j-mode-on)) - (let ((str (substring (skk-indicator-to-string - skk-modeline-input-mode t) 1))) - (setq vip-skk-latin-mode skk-latin-mode - vip-skk-j-mode skk-j-mode - vip-skk-jisx0208-latin-mode skk-jisx0208-latin-mode - vip-skk-katakana skk-katakana - vip-skk-input-mode-string) - (skk-kakutei) - (skk-mode-off) - (setq skk-modeline-input-mode - ;; There was no MODE argument...? - ;;(skk-mode-string-to-indicator (concat " [" str "]")) - (concat " [" str "]")))) - -(defun vip-skk-mode-on () - (add-hook 'pre-command-hook 'skk-pre-command nil 'local) - ;; we need to go back to the mode stored in VIP-SKK-*-MODE. - (cond (vip-skk-latin-mode (skk-latin-mode-on)) - (vip-skk-j-mode (skk-j-mode-on vip-skk-katakana)) - (vip-skk-jisx0208-latin-mode (skk-jisx0208-latin-mode-on)))) - -(require 'advice) -(defadvice skk-pre-command (around vip-ad activate) - (if (eq this-command 'vip-delete-backward-char) - ;; do nothing - nil - ad-do-it)) - -;; end SKK related functions - -(defun vip-copy-region-as-kill (beg end) - "If BEG and END do not belong to the same buffer, it copies empty region." - (condition-case nil - (copy-region-as-kill beg end) - (error (copy-region-as-kill beg beg)))) - -(defun vip-change-mode-line (string) - "Assuming that the mode line format contains the string \"Emacs:\", this -function replaces the string by \"Vi: \" etc." - (setq mode-line-buffer-identification - (if (string= string "Emacs:") - vip-emacs-mode-line-buffer-identification - (list (concat string " %12b"))))) - -;;;###autoload -(defun Vip-mode () - "Turn on VIP emulation of VI." - (interactive) - (if (not vip-inhibit-startup-message) - (progn - (switch-to-buffer "VIP Startup Message") - (erase-buffer) - (insert - "VIP is a Vi emulation package for GNU Emacs. VIP provides most Vi commands -including Ex commands. VIP is however different from Vi in several points. -You can get more information on VIP by: - 1. Typing `M-x info' and selecting menu item \"vip\". - 2. Typing `C-h k' followed by a key whose description you want. - 3. Printing VIP manual which can be found as GNU/man/vip.texinfo - 4. Printing VIP Reference Card which can be found as GNU/etc/vipcard.tex - -This startup message appears whenever you load VIP unless you type `y' now. -Type `n' to quit this window for now.\n") - (goto-char (point-min)) - (if (y-or-n-p "Inhibit VIP startup message? ") - (progn - (save-excursion - (set-buffer - (find-file-noselect - (substitute-in-file-name vip-startup-file))) - (goto-char (point-max)) - (insert "\n(setq vip-inhibit-startup-message t)\n") - (save-buffer) - (kill-buffer (current-buffer))) - (message "VIP startup message inhibited.") - (sit-for 2))) - (kill-buffer (current-buffer)) - (message "") - (setq vip-inhibit-startup-message t))) - (vip-change-mode-to-vi)) - -(defalias 'vip-mode 'Vip-mode) - -(defun vip-change-mode-to-vi () - "Change mode to vi mode." - (interactive) - (vip-change-mode 'vi-mode)) - -(defun vip-change-mode-to-insert () - "Change mode to insert mode." - (interactive) - (vip-change-mode 'insert-mode)) - -(defun vip-change-mode-to-emacs () - "Change mode to emacs mode." - (interactive) - (vip-change-mode 'emacs-mode)) - - -;; escape to emacs mode temporarily - -(defun vip-escape-to-emacs (arg &optional events) - "Escape to Emacs mode for one Emacs command. -ARG is used as the prefix value for the executed command. If -EVENTS is a list of events, which become the beginning of the command." - (interactive "P") - (let ((change-mode-to-vi nil) - (change-mode-to-insert nil) - (change-mode-to-emacs nil) - (save-vi-mode vip-vi-mode) - (save-insert-mode vip-insert-mode) - (old-buff (current-buffer)) - ) - (let (com key (vip-vi-mode nil) (vip-insert-mode nil)) - (if events (setq unread-command-events events)) - (setq prefix-arg arg) - ;;(use-local-map vip-emacs-local-map) - (unwind-protect - (setq com (key-binding (setq key - ;;(if vip-xemacs-p - ;; (read-key-sequence nil) - ;; (read-key-sequence nil t))))) - (read-key-sequence nil t)))) - nil) - (command-execute com prefix-arg) - (setq prefix-arg nil);; reset prefix arg - ) - ;; we must check if the current buffer is the same after executing - ;; the command. if not, we have to restore the values of - ;; VIP-VI-MODE and VIP-INSERT-MODE - (if (eq (current-buffer) old-buff) - ;; in case one of the values of CHANGE-MODE-TO-VI/INSERT/EMACS was - ;; changed dynamically in executing the command COM, then - ;; change mode to the specified mode. otherwise keep the mode. - (progn - (cond (change-mode-to-vi (vip-change-mode-to-vi)) - (change-mode-to-insert - (vip-change-mode-to-insert) - ) - (change-mode-to-emacs (vip-change-mode-to-emacs)) - (t (vip-change-mode vip-current-mode)))) - ;; since OLD-BUFF may not exist anymore, we have to first - ;; check if it still exists. we can check this by the function - ;; BUFFER-NAME which return nil for a killed buffer. - (if (buffer-name old-buff) - (save-excursion - (set-buffer old-buff) - (setq vip-vi-mode save-vi-mode - vip-insert-mode save-insert-mode))) - ;; in the new buffer we enter the mode spcified by - ;; the local value of VIP-CURRNT-MODE, unless CHANGE-MODE-TO-* - ;; is set - (cond (change-mode-to-vi (vip-change-mode-to-vi)) - (change-mode-to-insert (vip-change-mode-to-insert)) - (change-mode-to-emacs (vip-change-mode-to-emacs)) - (t (vip-change-mode vip-current-mode))) - ) - )) - -(defun vip-message-conditions (conditions) - "Print CONDITIONS as a message." - (let ((case (car conditions)) (msg (cdr conditions))) - (if (null msg) - (message "%s" case) - (message "%s %s" case (prin1-to-string msg))) - (ding))) - -(defun vip-ESC (arg) - "Emulate ESC key in Emacs mode." - (interactive "P") - (vip-escape-to-emacs arg '(?\e))) - -(defun vip-ctl-c (arg) - "Emulate C-c key in Emacs mode." - (interactive "P") - (vip-escape-to-emacs arg '(?\C-c))) - -(defun vip-ctl-x (arg) - "Emulate C-x key in Emacs mode." - (interactive "P") - (vip-escape-to-emacs arg '(?\C-x))) - -(defun vip-ctl-h (arg) - "Emulate C-h key in Emacs mode." - (interactive "P") - (vip-escape-to-emacs arg '(?\C-h))) - - -;; prefix argument for vi mode - -;; In vi mode, prefix argument is a dotted pair (NUM . COM) where NUM -;; represents the numeric value of the prefix argument and COM represents -;; command prefix such as "c", "d", "m" and "y". - -(defun vip-prefix-arg-value (char value com) - "Compute numeric prefix arg value. Invoked by CHAR. VALUE is the value -obtained so far, and COM is the command part obtained so far." - (while (and (>= char ?0) (<= char ?9)) - (setq value (+ (* (if (numberp value) value 0) 10) (- char ?0))) - (setq char (read-char))) - (setq prefix-arg value) - (if com (setq prefix-arg (cons prefix-arg com))) - (while (eq char ?U) - (vip-describe-arg prefix-arg) - (setq char (read-char))) - (setq unread-command-events (list char))) - -(defun vip-prefix-arg-com (char value com) - "Vi operator as prefix argument." - (let ((cont t)) - (while (and cont (memq char '(?c ?d ?y ?! ?< ?> ?= ?# ?r ?R ?\"))) - (if com - ;; this means that we already have a command character, so we - ;; construct a com list and exit while. however, if char is " - ;; it is an error. - (progn - ;; new com is (CHAR . OLDCOM) - (if (memq char '(?# ?\")) (error "")) - (setq com (cons char com)) - (setq cont nil)) - ;; if com is nil we set com as char, and read more. again, if char - ;; is ", we read the name of register and store it in vip-use-register. - ;; if char is !, =, or #, a complete com is formed so we exit while. - (cond ((memq char '(?! ?=)) - (setq com char) - (setq char (read-char)) - (setq cont nil)) - ((eq char ?#) - ;; read a char and encode it as com - (setq com (+ 128 (read-char))) - (setq char (read-char)) - (setq cont nil)) - ((memq char '(?< ?>)) - (setq com char) - (setq char (read-char)) - (if (eq com char) (setq com (cons char com))) - (setq cont nil)) - ((eq char ?\") - (let ((reg (read-char))) - (if (or (and (<= ?A reg) (<= reg ?z)) - (and (<= ?1 reg) (<= reg ?9))) - (setq vip-use-register reg) - (error "")) - (setq char (read-char)))) - (t - (setq com char) - (setq char (read-char))))))) - (if (atom com) - ;; com is a single char, so we construct prefix-arg - ;; and if char is ?, describe prefix arg, otherwise exit by - ;; pushing the char back - (progn - (setq prefix-arg (cons value com)) - (while (eq char ?U) - (vip-describe-arg prefix-arg) - (setq char (read-char))) - (setq unread-command-events (list char))) - ;; as com is non-nil, this means that we have a command to execute - (if (memq (car com) '(?r ?R)) - ;; execute appropriate region command. - (let ((char (car com)) (com (cdr com))) - (setq prefix-arg (cons value com)) - (if (eq char ?r) (vip-region prefix-arg) - (vip-Region prefix-arg)) - ;; reset prefix-arg - (setq prefix-arg nil)) - ;; otherwise, reset prefix arg and call appropriate command - (setq value (if (null value) 1 value)) - (setq prefix-arg nil) - (cond ((equal com '(?c . ?c)) (vip-line (cons value ?C))) - ((equal com '(?d . ?d)) (vip-line (cons value ?D))) - ((equal com '(?d . ?y)) (vip-yank-defun)) - ((equal com '(?y . ?y)) (vip-line (cons value ?Y))) - ((equal com '(?< . ?<)) (vip-line (cons value ?<))) - ((equal com '(?> . ?>)) (vip-line (cons value ?>))) - ((equal com '(?! . ?!)) (vip-line (cons value ?!))) - ((equal com '(?= . ?=)) (vip-line (cons value ?=))) - (t (error "")))))) - -(defun vip-describe-arg (arg) - (let (val com) - (setq val (vip-P-val arg) - com (vip-getcom arg)) - (if (null val) - (if (null com) - (message "Value is nil, and command is nil.") - (message "Value is nil, and command is %c." com)) - (if (null com) - (message "Value is %d, and command is nil." val) - (message "Value is %d, and command is %c." val com))))) - -(defun vip-digit-argument (arg) - "Begin numeric argument for the next command." - (interactive "P") - (vip-prefix-arg-value last-command-char nil - (if (consp arg) (cdr arg) nil))) - -(defun vip-command-argument (arg) - "Accept a motion command as an argument." - (interactive "P") - (condition-case conditions - (vip-prefix-arg-com - last-command-char - (cond ((null arg) nil) - ((consp arg) (car arg)) - ((numberp arg) arg) - (t (error "strange arg"))) - (cond ((null arg) nil) - ((consp arg) (cdr arg)) - ((numberp arg) nil) - (t (error "strange arg")))) - (quit - (setq vip-use-register nil) - (signal 'quit nil)))) - -(defun vip-p-val (arg) - "Get value part of prefix-argument ARG." - (cond ((null arg) 1) - ((consp arg) (if (null (car arg)) 1 (car arg))) - (t arg))) - -(defun vip-P-val (arg) - "Get value part of prefix-argument ARG." - (cond ((consp arg) (car arg)) - (t arg))) - -(defun vip-getcom (arg) - "Get com part of prefix-argument ARG." - (cond ((null arg) nil) - ((consp arg) (cdr arg)) - (t nil))) - -(defun vip-getCom (arg) - "Get com part of prefix-argument ARG and modify it." - (let ((com (vip-getcom arg))) - (cond ((eq com ?c) ?C) - ((eq com ?d) ?D) - ((eq com ?y) ?Y) - (t com)))) - - -;; repeat last destructive command - -(defun vip-append-to-register (reg start end) - "Append region to text in register REG. -START and END are buffer positions indicating what to append." - (set-register reg (concat (or (get-register reg) "") - (buffer-substring start end)))) - -(defun vip-execute-com (m-com val com) - "(M-COM VAL COM) Execute command COM. The list (M-COM VAL COM) is set -to vip-d-com for later use by vip-repeat" - (let ((reg vip-use-register)) - (if com - (cond ((eq com ?c) (vip-change vip-com-point (point))) - ((eq com (- ?c)) (vip-change-subr vip-com-point (point))) - ((eq (abs com) ?C) - (save-excursion - (set-mark vip-com-point) - (vip-enlarge-region (mark 'force) (point)) - (if vip-use-register - (progn - (cond ((and (<= ?a vip-use-register) - (<= vip-use-register ?z)) - (copy-to-register - vip-use-register (mark 'force) (point) nil)) - ((and (<= ?A vip-use-register) - (<= vip-use-register ?Z)) - (vip-append-to-register - (+ vip-use-register 32) (mark 'force) (point))) - (t (setq vip-use-register nil) - (error ""))) - (setq vip-use-register nil))) - (delete-region (mark 'force) (point))) - (open-line 1) - (if (eq com ?C) (vip-change-mode-to-insert) (yank))) - ((eq com ?d) - (if vip-use-register - (progn - (cond ((and (<= ?a vip-use-register) - (<= vip-use-register ?z)) - (copy-to-register - vip-use-register vip-com-point (point) nil)) - ((and (<= ?A vip-use-register) - (<= vip-use-register ?Z)) - (vip-append-to-register - (+ vip-use-register 32) vip-com-point (point))) - (t (setq vip-use-register nil) - (error ""))) - (setq vip-use-register nil))) - (setq last-command - (if (eq last-command 'd-command) 'kill-region nil)) - (kill-region vip-com-point (point)) - (setq this-command 'd-command)) - ((eq com ?D) - (save-excursion - (set-mark vip-com-point) - (vip-enlarge-region (mark 'force) (point)) - (if vip-use-register - (progn - (cond ((and (<= ?a vip-use-register) - (<= vip-use-register ?z)) - (copy-to-register - vip-use-register (mark 'force) (point) nil)) - ((and (<= ?A vip-use-register) - (<= vip-use-register ?Z)) - (vip-append-to-register - (+ vip-use-register 32) (mark 'force) (point))) - (t (setq vip-use-register nil) - (error ""))) - (setq vip-use-register nil))) - (setq last-command - (if (eq last-command 'D-command) 'kill-region nil)) - (kill-region (mark 'force) (point)) - (if (eq m-com 'vip-line) (setq this-command 'D-command))) - (back-to-indentation)) - ((eq com ?y) - (if vip-use-register - (progn - (cond ((and (<= ?a vip-use-register) - (<= vip-use-register ?z)) - (copy-to-register - vip-use-register vip-com-point (point) nil)) - ((and (<= ?A vip-use-register) - (<= vip-use-register ?Z)) - (vip-append-to-register - (+ vip-use-register 32) vip-com-point (point))) - (t (setq vip-use-register nil) - (error ""))) - (setq vip-use-register nil))) - (setq last-command nil) - (copy-region-as-kill vip-com-point (point)) - (goto-char vip-com-point)) - ((eq com ?Y) - (save-excursion - (set-mark vip-com-point) - (vip-enlarge-region (mark 'force) (point)) - (if vip-use-register - (progn - (cond ((and (<= ?a vip-use-register) - (<= vip-use-register ?z)) - (copy-to-register - vip-use-register (mark 'force) (point) nil)) - ((and (<= ?A vip-use-register) - (<= vip-use-register ?Z)) - (vip-append-to-register - (+ vip-use-register 32) (mark 'force) (point))) - (t (setq vip-use-register nil) - (error ""))) - (setq vip-use-register nil))) - (setq last-command nil) - (copy-region-as-kill (mark 'force) (point))) - (goto-char vip-com-point)) - ((eq (abs com) ?!) - (save-excursion - (set-mark vip-com-point) - (vip-enlarge-region (mark 'force) (point)) - (shell-command-on-region - (mark 'force) (point) - (if (eq com ?!) - (setq vip-last-shell-com (vip-read-string "!")) - vip-last-shell-com) - t))) - ((eq com ?=) - (save-excursion - (set-mark vip-com-point) - (vip-enlarge-region (mark 'force) (point)) - (if (> (mark 'force) (point)) (exchange-point-and-mark)) - (indent-region (mark 'force) (point) nil))) - ((eq com ?<) - (save-excursion - (set-mark vip-com-point) - (vip-enlarge-region (mark 'force) (point)) - (indent-rigidly (mark 'force) (point) (- vip-shift-width))) - (goto-char vip-com-point)) - ((eq com ?>) - (save-excursion - (set-mark vip-com-point) - (vip-enlarge-region (mark 'force) (point)) - (indent-rigidly (mark 'force) (point) vip-shift-width)) - (goto-char vip-com-point)) - ((>= com 128) - ;; this is special command # - (vip-special-prefix-com (- com 128))))) - (setq vip-d-com (list m-com val (if (memq com '(?c ?C ?!)) - (- com) com) - reg)))) - -(defun vip-repeat (arg) - "(ARG) Re-execute last destructive command. vip-d-com has the form -\(COM ARG CH REG), where COM is the command to be re-executed, ARG is the -argument for COM, CH is a flag for repeat, and REG is optional and if exists -is the name of the register for COM." - (interactive "P") - (if (eq last-command 'vip-undo) - ;; if the last command was vip-undo, then undo-more - (vip-undo-more) - ;; otherwise execute the command stored in vip-d-com. if arg is non-nil - ;; its prefix value is used as new prefix value for the command. - (let ((m-com (car vip-d-com)) - (val (vip-P-val arg)) - (com (car (cdr (cdr vip-d-com)))) - (reg (nth 3 vip-d-com))) - (if (null val) (setq val (car (cdr vip-d-com)))) - (if (null m-com) (error "No previous command to repeat.")) - (setq vip-use-register reg) - (funcall m-com (cons val com))))) - -(defun vip-special-prefix-com (char) - "This command is invoked interactively by the key sequence #" - (cond ((eq char ?c) - (downcase-region (min vip-com-point (point)) - (max vip-com-point (point)))) - ((eq char ?C) - (upcase-region (min vip-com-point (point)) - (max vip-com-point (point)))) - ((eq char ?g) - (set-mark vip-com-point) - (vip-global-execute)) - ((eq char ?q) - (set-mark vip-com-point) - (vip-quote-region)) - ((eq char ?s) (spell-region vip-com-point (point))))) - - -;; undoing - -(defun vip-undo () - "Undo previous change." - (interactive) - (message "undo!") - (undo-start) - (undo-more 2) - (setq this-command 'vip-undo)) - -(defun vip-undo-more () - "Continue undoing previous changes." - (message "undo more!") - (undo-more 1) - (setq this-command 'vip-undo)) - - -;; utilities - -(defun vip-string-tail (str) - (if (or (null str) (string= str "")) nil - (substring str 1))) - -(defun vip-yank-defun () - (mark-defun) - (copy-region-as-kill (point) (mark 'force))) - -(defun vip-enlarge-region (beg end) - "Enlarge region between BEG and END." - (if (< beg end) - (progn (goto-char beg) (set-mark end)) - (goto-char end) - (set-mark beg)) - (beginning-of-line) - (exchange-point-and-mark) - (if (or (not (eobp)) (not (bolp))) (next-line 1)) - (beginning-of-line) - (if (> beg end) (exchange-point-and-mark))) - -(defun vip-global-execute () - "Call last keyboad macro for each line in the region." - (if (> (point) (mark 'force)) (exchange-point-and-mark)) - (beginning-of-line) - (call-last-kbd-macro) - (while (< (point) (mark 'force)) - (forward-line 1) - (beginning-of-line) - (call-last-kbd-macro))) - -(defun vip-quote-region () - "Quote region by inserting the user supplied string at the beginning of -each line in the region." - (setq vip-quote-string - (let ((str - (vip-read-string (format "quote string \(default \"%s\"\): " - vip-quote-string)))) - (if (string= str "") vip-quote-string str))) - (vip-enlarge-region (point) (mark 'force)) - (if (> (point) (mark 'force)) (exchange-point-and-mark)) - (insert vip-quote-string) - (beginning-of-line) - (forward-line 1) - (while (and (< (point) (mark 'force)) (bolp)) - (insert vip-quote-string) - (beginning-of-line) - (forward-line 1))) - -(defun vip-end-with-a-newline-p (string) - "Check if the string ends with a newline." - (or (string= string "") - (eq (aref string (1- (length string))) ?\n))) - -(defun vip-read-string (prompt &optional init skk) - "Setup MINIBUFFER-LOCAL-MAP appropriately and call READ-STRING. If -SKK is on, then read string with SKK-J-MODE on." - (setq save-minibuffer-local-map (copy-keymap minibuffer-local-map)) - (let (str - (input-mode-str - (and (boundp 'skk-modeline-input-mode) - (skk-indicator-to-string skk-modeline-input-mode t)))) - (if (and skk (boundp 'skk-mode) skk-mode) - (add-hook 'minibuffer-setup-hook 'skk-j-mode-on)) - (define-key minibuffer-local-map "\C-h" 'backward-char) - (define-key minibuffer-local-map "\C-w" 'backward-word) - (define-key minibuffer-local-map "\e" 'exit-minibuffer) - (condition-case conditions - (setq str (read-string prompt init)) - (quit - (setq minibuffer-local-map save-minibuffer-local-map) - (if input-mode-str (setq skk-modeline-input-mode - (skk-mode-string-to-indicator input-mode-str))) - (signal 'quit nil))) - (setq minibuffer-local-map save-minibuffer-local-map) - (if input-mode-str (setq skk-modeline-input-mode - (skk-mode-string-to-indicator input-mode-str))) - str)) - - -;; insertion commands - -(defun vip-repeat-insert-command () - "This function is called when mode changes from insertion mode to -vi command mode. It will repeat the insertion command if original insertion -command was invoked with argument > 1." - (let ((i-com (car vip-d-com)) (val (car (cdr vip-d-com)))) - (if (and val (> val 1)) ;; first check that val is non-nil - (progn - (setq vip-d-com (list i-com (1- val) ?r)) - (vip-repeat nil) - (setq vip-d-com (list i-com val ?r)))))) - -(defun vip-insert (arg) "" - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (setq vip-d-com (list 'vip-insert val ?r)) - (if com (vip-loop val (yank)) - (vip-change-mode-to-insert)))) - -(defun vip-append (arg) - "Append after point." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (setq vip-d-com (list 'vip-append val ?r)) - (if (not (eolp)) (forward-char)) - (if (eq com ?r) - (vip-loop val (yank)) - (vip-change-mode-to-insert)))) - -(defun vip-Append (arg) - "Append at end of line." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (setq vip-d-com (list 'vip-Append val ?r)) - (end-of-line) - (if (eq com ?r) - (vip-loop val (yank)) - (vip-change-mode-to-insert)))) - -(defun vip-Insert (arg) - "Insert before first non-white." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (setq vip-d-com (list 'vip-Insert val ?r)) - (back-to-indentation) - (if (eq com ?r) - (vip-loop val (yank)) - (vip-change-mode-to-insert)))) - -(defun vip-open-line (arg) - "Open line below." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (setq vip-d-com (list 'vip-open-line val ?r)) - (let ((col (current-indentation))) - (if (eq com ?r) - (vip-loop val - (progn - (end-of-line) - (newline 1) - (if vip-open-with-indent (indent-to col)) - (yank))) - (end-of-line) - (newline 1) - (if vip-open-with-indent (indent-to col)) - (vip-change-mode-to-insert))))) - -(defun vip-Open-line (arg) - "Open line above." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (setq vip-d-com (list 'vip-Open-line val ?r)) - (let ((col (current-indentation))) - (if (eq com ?r) - (vip-loop val - (progn - (beginning-of-line) - (open-line 1) - (if vip-open-with-indent (indent-to col)) - (yank))) - (beginning-of-line) - (open-line 1) - (if vip-open-with-indent (indent-to col)) - (vip-change-mode-to-insert))))) - -(defun vip-open-line-at-point (arg) - "Open line at point." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (setq vip-d-com (list 'vip-open-line-at-point val ?r)) - (if (eq com ?r) - (vip-loop val - (progn - (open-line 1) - (yank))) - (open-line 1) - (vip-change-mode-to-insert)))) - -(defun vip-substitute (arg) - "Substitute characters." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (save-excursion - (set-mark (point)) - (forward-char val) - (if (eq com ?r) - (vip-change-subr (mark 'force) (point)) - (vip-change (mark 'force) (point)))) - (setq vip-d-com (list 'vip-substitute val ?r)))) - -(defun vip-substitute-line (arg) - "Substitute lines." - (interactive "p") - (vip-line (cons arg ?C))) - - -;; line command - -(defun vip-line (arg) - (let ((val (car arg)) (com (cdr arg))) - (vip-move-marker-locally vip-com-point (point)) - (next-line (1- val)) - (vip-execute-com 'vip-line val com))) - -(defun vip-yank-line (arg) - "Yank ARG lines (in vi's sense)" - (interactive "P") - (let ((val (vip-p-val arg))) - (vip-line (cons val ?Y)))) - - -;; region command - -(defun vip-region (arg) - (interactive "P") - (let ((val (vip-P-val arg)) - (com (vip-getcom arg))) - (vip-move-marker-locally vip-com-point (point)) - (exchange-point-and-mark) - (vip-execute-com 'vip-region val com))) - -(defun vip-Region (arg) - (interactive "P") - (let ((val (vip-P-val arg)) - (com (vip-getCom arg))) - (vip-move-marker-locally vip-com-point (point)) - (exchange-point-and-mark) - (vip-execute-com 'vip-Region val com))) - -(defun vip-replace-char (arg) - "Replace the following ARG chars by the character read." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (setq vip-d-com (list 'vip-replace-char val ?r)) - (vip-replace-char-subr (if (eq com ?r) vip-d-char (read-char)) val))) - -(defun vip-replace-char-subr (char arg) - (delete-char arg t) - (setq vip-d-char char) - (vip-loop (if (> arg 0) arg (- arg)) (insert char)) - (backward-char arg)) - -(defun vip-replace-string () - "Replace string. If you supply null string as the string to be replaced, -the query replace mode will toggle between string replace and regexp replace." - (interactive) - (let (str) - (setq str (vip-read-string - (if vip-re-replace "Replace regexp: " "Replace string: "))) - (if (string= str "") - (progn - (setq vip-re-replace (not vip-re-replace)) - (message "Replace mode changed to %s." - (if vip-re-replace "regexp replace" - "string replace"))) - (if vip-re-replace - ;; (replace-regexp - ;; str - ;; (vip-read-string (format "Replace regexp \"%s\" with: " str))) - (while (re-search-forward str nil t) - (replace-match (vip-read-string - (format "Replace regexp \"%s\" with: " str)) - nil nil)) - (replace-string - str - (vip-read-string (format "Replace \"%s\" with: " str))))))) - - -;; basic cursor movement. j, k, l, m commands. - -(defun vip-forward-char (arg) - "Move point right ARG characters (left if ARG negative).On reaching end -of buffer, stop and signal error." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (forward-char val) - (if com (vip-execute-com 'vip-forward-char val com)))) - -(defun vip-backward-char (arg) - "Move point left ARG characters (right if ARG negative). On reaching -beginning of buffer, stop and signal error." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (backward-char val) - (if com (vip-execute-com 'vip-backward-char val com)))) - - -;; word command - -(defun vip-forward-word (arg) - "Forward word." - (interactive "P") - (let ((val (vip-p-val arg)) - (com (vip-getcom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (forward-word val) - (skip-chars-forward " \t\n") - (if com - (progn - (if (eq (abs com) ?c) - (progn (backward-word 1) (forward-word 1))) - (if (memq com '(?d ?y)) - (progn - (backward-word 1) - (forward-word 1) - (skip-chars-forward " \t"))) - (vip-execute-com 'vip-forward-word val com))))) - -(defun vip-end-of-word (arg) - "Move point to end of current word." - (interactive "P") - (let ((val (vip-p-val arg)) - (com (vip-getcom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (forward-char) - (forward-word val) - (backward-char) - (if com - (progn - (forward-char) - (vip-execute-com 'vip-end-of-word val com))))) - -(defun vip-backward-word (arg) - "Backward word." - (interactive "P") - (let ((val (vip-p-val arg)) - (com (vip-getcom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (backward-word val) - (if com (vip-execute-com 'vip-backward-word val com)))) - -(defun vip-forward-Word (arg) - "Forward word delimited by white character." - (interactive "P") - (let ((val (vip-p-val arg)) - (com (vip-getcom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (re-search-forward "[^ \t\n]*[ \t\n]+" nil t val) - (if com - (progn - (if (eq (abs com) ?c) - (progn (backward-word 1) (forward-word 1))) - (if (memq com '(?d ?y)) - (progn - (backward-word 1) - (forward-word 1) - (skip-chars-forward " \t"))) - (vip-execute-com 'vip-forward-Word val com))))) - -(defun vip-end-of-Word (arg) - "Move forward to end of word delimited by white character." - (interactive "P") - (let ((val (vip-p-val arg)) - (com (vip-getcom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (forward-char) - (if (re-search-forward "[^ \t\n]+" nil t val) (backward-char)) - (if com - (progn - (forward-char) - (vip-execute-com 'vip-end-of-Word val com))))) - -(defun vip-backward-Word (arg) - "Backward word delimited by white character." - (interactive "P") - (let ((val (vip-p-val arg)) - (com (vip-getcom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (if (re-search-backward "[ \t\n]+[^ \t\n]+" nil t val) - (forward-char) - (goto-char (point-min))) - (if com (vip-execute-com 'vip-backward-Word val com)))) - -(defun vip-beginning-of-line (arg) - "Go to beginning of line." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (beginning-of-line val) - (if com (vip-execute-com 'vip-beginning-of-line val com)))) - -(defun vip-bol-and-skip-white (arg) - "Beginning of line at first non-white character." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (back-to-indentation) - (if com (vip-execute-com 'vip-bol-and-skip-white val com)))) - -(defun vip-goto-eol (arg) - "Go to end of line." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (end-of-line val) - (if com (vip-execute-com 'vip-goto-eol val com)))) - -(defun vip-next-line (arg) - "Go to next line." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getCom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (line-move val) - (setq this-command 'next-line) - (if com (vip-execute-com 'vip-next-line val com)))) - -(defun vip-next-line-at-bol (arg) - "Next line at beginning of line." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getCom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (next-line val) - (back-to-indentation) - (if com (vip-execute-com 'vip-next-line-at-bol val com)))) - -(defun vip-previous-line (arg) - "Go to previous line." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getCom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (next-line (- val)) - (setq this-command 'previous-line) - (if com (vip-execute-com 'vip-previous-line val com)))) - -(defun vip-previous-line-at-bol (arg) - "Previous line at beginning of line." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getCom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (next-line (- val)) - (back-to-indentation) - (if com (vip-execute-com 'vip-previous-line val com)))) - -(defun vip-change-to-eol (arg) - "Change to end of line." - (interactive "P") - (vip-goto-eol (cons arg ?c))) - -(defun vip-kill-line (arg) - "Delete line." - (interactive "P") - (vip-goto-eol (cons arg ?d))) - - -;; moving around - -(defun vip-goto-line (arg) - "Go to ARG's line. Without ARG go to end of buffer." - (interactive "P") - (let ((val (vip-P-val arg)) (com (vip-getCom arg))) - (vip-move-marker-locally vip-com-point (point)) - (set-mark (point)) - (if (null val) - (goto-char (point-max)) - (goto-char (point-min)) - (forward-line (1- val))) - (back-to-indentation) - (if com (vip-execute-com 'vip-goto-line val com)))) - -(defun vip-find-char (arg char forward offset) - "Find ARG's occurrence of CHAR on the current line. If FORWARD then -search is forward, otherwise backward. OFFSET is used to adjust point -after search." - (let ((arg (if forward arg (- arg))) point) - (save-excursion - (save-restriction - (if (> arg 0) - (narrow-to-region - ;; forward search begins here - (if (eolp) (error "") (point)) - ;; forward search ends here - (progn (next-line 1) (beginning-of-line) (point))) - (narrow-to-region - ;; backward search begins from here - (if (bolp) (error "") (point)) - ;; backward search ends here - (progn (beginning-of-line) (point)))) - ;; if arg > 0, point is forwarded before search. - (if (> arg 0) (goto-char (1+ (point-min))) - (goto-char (point-max))) - (let ((case-fold-search nil)) - (search-forward (char-to-string char) nil 0 arg)) - (setq point (point)) - (if (or (and (> arg 0) (eq point (point-max))) - (and (< arg 0) (eq point (point-min)))) - (error "")))) - (goto-char (+ point (if (> arg 0) (if offset -2 -1) (if offset 1 0)))))) - -(defun vip-find-char-forward (arg) - "Find char on the line. If called interactively read the char to find -from the terminal, and if called from vip-repeat, the char last used is -used. This behaviour is controlled by the sign of prefix numeric value." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (if (> val 0) - ;; this means that the function was called interactively - (setq vip-f-char (read-char) - vip-f-forward t - vip-f-offset nil) - (setq val (- val))) - (if com (vip-move-marker-locally vip-com-point (point))) - (vip-find-char val (if (> (vip-p-val arg) 0) vip-f-char vip-F-char) t nil) - (setq val (- val)) - (if com - (progn - (setq vip-F-char vip-f-char);; set new vip-F-char - (forward-char) - (vip-execute-com 'vip-find-char-forward val com))))) - -(defun vip-goto-char-forward (arg) - "Go up to char ARG forward on line." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (if (> val 0) - ;; this means that the function was called interactively - (setq vip-f-char (read-char) - vip-f-forward t - vip-f-offset t) - (setq val (- val))) - (if com (vip-move-marker-locally vip-com-point (point))) - (vip-find-char val (if (> (vip-p-val arg) 0) vip-f-char vip-F-char) t t) - (setq val (- val)) - (if com - (progn - (setq vip-F-char vip-f-char);; set new vip-F-char - (forward-char) - (vip-execute-com 'vip-goto-char-forward val com))))) - -(defun vip-find-char-backward (arg) - "Find char ARG on line backward." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (if (> val 0) - ;; this means that the function was called interactively - (setq vip-f-char (read-char) - vip-f-forward nil - vip-f-offset nil) - (setq val (- val))) - (if com (vip-move-marker-locally vip-com-point (point))) - (vip-find-char - val (if (> (vip-p-val arg) 0) vip-f-char vip-F-char) nil nil) - (setq val (- val)) - (if com - (progn - (setq vip-F-char vip-f-char);; set new vip-F-char - (vip-execute-com 'vip-find-char-backward val com))))) - -(defun vip-goto-char-backward (arg) - "Go up to char ARG backward on line." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (if (> val 0) - ;; this means that the function was called interactively - (setq vip-f-char (read-char) - vip-f-forward nil - vip-f-offset t) - (setq val (- val))) - (if com (vip-move-marker-locally vip-com-point (point))) - (vip-find-char val (if (> (vip-p-val arg) 0) vip-f-char vip-F-char) nil t) - (setq val (- val)) - (if com - (progn - (setq vip-F-char vip-f-char);; set new vip-F-char - (vip-execute-com 'vip-goto-char-backward val com))))) - -(defun vip-repeat-find (arg) - "Repeat previous find command." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (vip-find-char val vip-f-char vip-f-forward vip-f-offset) - (if com - (progn - (if vip-f-forward (forward-char)) - (vip-execute-com 'vip-repeat-find val com))))) - -(defun vip-repeat-find-opposite (arg) - "Repeat previous find command in the opposite direction." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (vip-find-char val vip-f-char (not vip-f-forward) vip-f-offset) - (if com - (progn - (if vip-f-forward (forward-char)) - (vip-execute-com 'vip-repeat-find-opposite val com))))) - - -;; window scrolling etc. - -(defun vip-other-window (arg) - "Switch to other window." - (interactive "p") - (other-window arg) - (or (not (eq vip-current-mode 'emacs-mode)) - (string= (buffer-name (current-buffer)) " *Minibuf-1*") - (vip-change-mode-to-vi))) - -(defun vip-window-top (arg) - "Go to home window line." - (interactive "P") - (let ((val (vip-p-val arg)) - (com (vip-getCom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (move-to-window-line (1- val)) - (if com (vip-execute-com 'vip-window-top val com)))) - -(defun vip-window-middle (arg) - "Go to middle window line." - (interactive "P") - (let ((val (vip-p-val arg)) - (com (vip-getCom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (move-to-window-line (+ (/ (1- (window-height)) 2) (1- val))) - (if com (vip-execute-com 'vip-window-middle val com)))) - -(defun vip-window-bottom (arg) - "Go to last window line." - (interactive "P") - (let ((val (vip-p-val arg)) - (com (vip-getCom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (move-to-window-line (- val)) - (if com (vip-execute-com 'vip-window-bottom val com)))) - -(defun vip-line-to-top (arg) - "Put current line on the home line." - (interactive "p") - (recenter (1- arg))) - -(defun vip-line-to-middle (arg) - "Put current line on the middle line." - (interactive "p") - (recenter (+ (1- arg) (/ (1- (window-height)) 2)))) - -(defun vip-line-to-bottom (arg) - "Put current line on the last line." - (interactive "p") - (recenter (- (window-height) (1+ arg)))) - - -;; paren match - -(defun vip-paren-match (arg) - "Go to the matching parenthesis." - (interactive "P") - (let ((com (vip-getcom arg))) - (if (numberp arg) - (if (or (> arg 99) (< arg 1)) - (error "Prefix must be between 1 and 99.") - (goto-char - (if (> (point-max) 80000) - (* (/ (point-max) 100) arg) - (/ (* (point-max) arg) 100))) - (back-to-indentation)) - (cond ((looking-at "[\(\[{]") - (if com (vip-move-marker-locally vip-com-point (point))) - (forward-sexp 1) - (if com - (vip-execute-com 'vip-paren-match nil com) - (backward-char))) - ((looking-at "[])}]") - (forward-char) - (if com (vip-move-marker-locally vip-com-point (point))) - (backward-sexp 1) - (if com (vip-execute-com 'vip-paren-match nil com))) - (t (error "")))))) - - -;; sentence and paragraph - -(defun vip-forward-sentence (arg) - "Forward sentence." - (interactive "P") - (let ((val (vip-p-val arg)) - (com (vip-getcom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (forward-sentence val) - (if com (vip-execute-com 'vip-forward-sentence nil com)))) - -(defun vip-backward-sentence (arg) - "Backward sentence." - (interactive "P") - (let ((val (vip-p-val arg)) - (com (vip-getcom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (backward-sentence val) - (if com (vip-execute-com 'vip-backward-sentence nil com)))) - -(defun vip-forward-paragraph (arg) - "Forward paragraph." - (interactive "P") - (let ((val (vip-p-val arg)) - (com (vip-getCom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (forward-paragraph val) - (if com (vip-execute-com 'vip-forward-paragraph nil com)))) - -(defun vip-backward-paragraph (arg) - "Backward paragraph." - (interactive "P") - (let ((val (vip-p-val arg)) - (com (vip-getCom arg))) - (if com (vip-move-marker-locally vip-com-point (point))) - (backward-paragraph val) - (if com (vip-execute-com 'vip-backward-paragraph nil com)))) - - -;; scrolling - -(defun vip-scroll (arg) - "Scroll to next screen." - (interactive "p") - (if (> arg 0) - (while (> arg 0) - (scroll-up) - (setq arg (1- arg))) - (while (> 0 arg) - (scroll-down) - (setq arg (1+ arg))))) - -(defun vip-scroll-back (arg) - "Scroll to previous screen." - (interactive "p") - (vip-scroll (- arg))) - -(defun vip-scroll-down (arg) - "Scroll up half screen." - (interactive "P") - (if (null arg) (scroll-down (/ (window-height) 2)) - (scroll-down arg))) - -(defun vip-scroll-down-one (arg) - "Scroll up one line." - (interactive "p") - (scroll-down arg)) - -(defun vip-scroll-up (arg) - "Scroll down half screen." - (interactive "P") - (if (null arg) (scroll-up (/ (window-height) 2)) - (scroll-up arg))) - -(defun vip-scroll-up-one (arg) - "Scroll down one line." - (interactive "p") - (scroll-up arg)) - - -;; splitting window - -(defun vip-buffer-in-two-windows () - "Show current buffer in two windows." - (interactive) - (delete-other-windows) - (split-window-vertically nil)) - - -;; searching - -(defun vip-search-forward (arg) - "Search a string forward. ARG is used to find the ARG's occurrence -of the string. Default is vanilla search. Search mode can be toggled by -giving null search string." - (interactive "P") - (let ((val (vip-P-val arg)) (com (vip-getcom arg))) - (setq vip-s-forward t - vip-s-string (if vip-re-search (vip-read-string "RE-/") - (vip-read-string "/" nil t))) - (if (string= vip-s-string "") - (progn - (setq vip-re-search (not vip-re-search)) - (message "Search mode changed to %s search." - (if vip-re-search "regular expression" - "vanilla"))) - (vip-search vip-s-string t val) - (if com - (progn - (vip-move-marker-locally vip-com-point (mark 'force)) - (vip-execute-com 'vip-search-next val com)))))) - -(defun vip-search-backward (arg) - "Search a string backward. ARG is used to find the ARG's occurrence -of the string. Default is vanilla search. Search mode can be toggled by -giving null search string." - (interactive "P") - (let ((val (vip-P-val arg)) (com (vip-getcom arg))) - (setq vip-s-forward nil - vip-s-string (vip-read-string (if vip-re-search "RE-?" "?") nil t)) - (if (string= vip-s-string "") - (progn - (setq vip-re-search (not vip-re-search)) - (message "Search mode changed to %s search." - (if vip-re-search "regular expression" - "vanilla"))) - (vip-search vip-s-string nil val) - (if com - (progn - (vip-move-marker-locally vip-com-point (mark 'force)) - (vip-execute-com 'vip-search-next val com)))))) - -(defun vip-search (string forward arg &optional no-offset init-point) - "(STRING FORWARD COUNT &optional NO-OFFSET) Search COUNT's occurrence of -STRING. Search will be forward if FORWARD, otherwise backward." - (let ((val (vip-p-val arg)) (com (vip-getcom arg)) - (null-arg (null (vip-P-val arg))) (offset (not no-offset)) - (case-fold-search vip-case-fold-search) - (start-point (or init-point (point)))) - (if forward - (condition-case conditions - (progn - (if (and offset (not (eobp))) (forward-char)) - (if vip-re-search - (progn - (re-search-forward string nil nil val) - (re-search-backward string)) - (search-forward string nil nil val) - (search-backward string)) - (push-mark start-point)) - (search-failed - (if (and null-arg vip-search-wrap-around) - (progn - (goto-char (point-min)) - (vip-search string forward (cons 1 com) t start-point)) - (goto-char start-point) - (signal 'search-failed (cdr conditions))))) - (condition-case conditions - (progn - (if vip-re-search - (re-search-backward string nil nil val) - (search-backward string nil nil val)) - (push-mark start-point)) - (search-failed - (if (and null-arg vip-search-wrap-around) - (progn - (goto-char (point-max)) - (vip-search string forward (cons 1 com) t start-point)) - (goto-char start-point) - (signal 'search-failed (cdr conditions)))))))) - -(defun vip-search-next (arg) - "Repeat previous search." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (if (null vip-s-string) (error "No previous search string.")) - (vip-search vip-s-string vip-s-forward arg) - (if com (vip-execute-com 'vip-search-next val com)))) - -(defun vip-search-Next (arg) - "Repeat previous search in the reverse direction." - (interactive "P") - (let ((val (vip-p-val arg)) (com (vip-getcom arg))) - (if (null vip-s-string) (error "No previous search string.")) - (vip-search vip-s-string (not vip-s-forward) arg) - (if com (vip-execute-com 'vip-search-Next val com)))) - - -;; visiting and killing files, buffers - -(defun vip-switch-to-buffer () - "Switch to buffer in the current window." - (interactive) - (let (buffer) - (setq buffer - (vip-read-buffer - (format "switch to buffer \(%s\): " - (buffer-name (other-buffer (current-buffer)))))) - (switch-to-buffer buffer) - (vip-change-mode-to-vi))) - -(defun vip-switch-to-buffer-other-window () - "Switch to buffer in another window." - (interactive) - (let (buffer) - (setq buffer - (vip-read-buffer - (format "Switch to buffer \(%s\): " - (buffer-name (other-buffer (current-buffer)))))) - (switch-to-buffer-other-window buffer) - (vip-change-mode-to-vi))) - -(defun vip-kill-buffer () - "Kill a buffer." - (interactive) - (let (buffer buffer-name) - (setq buffer-name - (vip-read-buffer - (format "Kill buffer \(%s\): " - (buffer-name (current-buffer))))) - (setq buffer - (if (null buffer-name) - (current-buffer) - (get-buffer buffer-name))) - (if (null buffer) (error "Buffer %s nonexistent." buffer-name)) - (if (or (not (buffer-modified-p buffer)) - (y-or-n-p "Buffer is modified, are you sure? ")) - (kill-buffer buffer) - (error "Buffer not killed.")))) - -(defun vip-read-file-name (prompt) - (let ((vip-vi-mode nil) (vip-insert-mode nil)) - (read-file-name prompt))) - -(defun vip-read-buffer (buffer) - (let ((vip-vi-mode nil) (vip-insert-mode nil)) - (read-buffer buffer))) - -(defun vip-find-file () - "Visit file in the current window." - (interactive) - (let (file) - (setq file (vip-read-file-name "visit file: ")) - (switch-to-buffer (find-file-noselect file)) - (vip-change-mode-to-vi))) - -(defun vip-find-file-other-window () - "Visit file in another window." - (interactive) - (let (file) - (setq file (vip-read-file-name "Visit file: ")) - (switch-to-buffer-other-window (find-file-noselect file)) - (vip-change-mode-to-vi))) - -(defun vip-info-on-file () - "Give information of the file associated to the current buffer." - (interactive) - (message "\"%s\" line %d of %d" - (if (buffer-file-name) (buffer-file-name) "") - (1+ (count-lines (point-min) - (save-excursion - (beginning-of-line) - (point)))) - (1+ (count-lines (point-min) (point-max))))) - - -;; yank and pop - -(defun vip-yank (text) - "yank TEXT silently." - (save-excursion - (vip-push-mark-silent (point)) - (insert text) - (exchange-point-and-mark)) - (skip-chars-forward " \t")) - -(defun vip-put-back (arg) - "Put back after point/below line." - (interactive "P") - (let ((val (vip-p-val arg)) - (text (if vip-use-register - (if (and (<= ?1 vip-use-register) (<= vip-use-register ?9)) - (current-kill (- vip-use-register ?1) 'do-not-rotate) - (get-register vip-use-register)) - (current-kill 0)))) - (if (null text) - (if vip-use-register - (let ((reg vip-use-register)) - (setq vip-use-register nil) - (error "Nothing in register %c" reg)) - (error ""))) - (setq vip-use-register nil) - (if (vip-end-with-a-newline-p text) - (progn - (next-line 1) - (beginning-of-line)) - (if (and (not (eolp)) (not (eobp))) (forward-char))) - (setq vip-d-com (list 'vip-put-back val nil vip-use-register)) - (vip-loop val (vip-yank text)))) - -(defun vip-Put-back (arg) - "Put back at point/above line." - (interactive "P") - (let ((val (vip-p-val arg)) - (text (if vip-use-register - (if (and (<= ?1 vip-use-register) (<= vip-use-register ?9)) - (current-kill (- vip-use-register ?1) 'do-not-rotate) - (get-register vip-use-register)) - (current-kill 0)))) - (if (null text) - (if vip-use-register - (let ((reg vip-use-register)) - (setq vip-use-register nil) - (error "Nothing in register %c" reg)) - (error ""))) - (setq vip-use-register nil) - (if (vip-end-with-a-newline-p text) (beginning-of-line)) - (setq vip-d-com (list 'vip-Put-back val nil vip-use-register)) - (vip-loop val (vip-yank text)))) - -(defun vip-delete-char (arg) - "Delete character." - (interactive "P") - (let ((val (vip-p-val arg))) - (setq vip-d-com (list 'vip-delete-char val nil)) - (if vip-use-register - (progn - (if (and (<= ?A vip-use-register) (<= vip-use-register ?Z)) - (vip-append-to-register - (+ vip-use-register 32) (point) (- (point) val)) - (copy-to-register vip-use-register (point) (- (point) val) nil)) - (setq vip-use-register nil))) - (delete-char val t))) - -(defun vip-delete-backward-char (arg) - "Delete previous character." - (interactive "P") - (let ((val (vip-p-val arg)) (skk-mode (if (boundp 'skk-mode) skk-mode nil))) - (setq vip-d-com (list 'vip-delete-backward-char val nil)) - (if vip-use-register - (progn - (if (and (<= ?A vip-use-register) (<= vip-use-register ?Z)) - (vip-append-to-register - (+ vip-use-register 32) (point) (+ (point) val)) - (copy-to-register vip-use-register (point) (+ (point) val) nil)) - (setq vip-use-register nil))) - (if skk-mode - (cond ((skk-get-prefix skk-current-rule-tree) - (skk-erase-prefix 'clean)) - ((eq skk-henkan-mode 'active) - (delete-backward-char val t) - (skk-kakutei)) - ((and (eq skk-henkan-mode 'on) - (>= skk-henkan-start-point (point))) - (skk-kakutei)) - (t - (delete-backward-char val t))) - (delete-backward-char val t)))) - - -;; join lines. - -(defun vip-join-lines (arg) - "Join this line to next, if ARG is nil. Otherwise, join ARG lines" - (interactive "*P") - (let ((val (vip-P-val arg))) - (setq vip-d-com (list 'vip-join-lines val nil)) - (vip-loop (if (null val) 1 (1- val)) - (progn - (end-of-line) - (if (not (eobp)) - (progn - (forward-line 1) - (delete-region (point) (1- (point))) - (fixup-whitespace))))))) - - -;; making small changes - -(defun vip-change (beg end) - (setq c-string - (vip-read-string (format "%s => " (buffer-substring beg end)) nil t)) - (vip-change-subr beg end)) - -(defun vip-change-subr (beg end) - (if vip-use-register - (progn - (copy-to-register vip-use-register beg end nil) - (setq vip-use-register nil))) - (kill-region beg end) - (setq this-command 'vip-change) - (insert c-string)) - - -;; query replace - -(defun vip-query-replace () - "Query replace. If you supply null string as the string to be replaced, -the query replace mode will toggle between string replace and regexp replace." - (interactive) - (let (str) - (setq str (if vip-re-query-replace - (vip-read-string "Query replace regexp: ") - (vip-read-string "Query replace: " nil t))) - (if (string= str "") - (progn - (setq vip-re-query-replace (not vip-re-query-replace)) - (message "Query replace mode changed to %s." - (if vip-re-query-replace "regexp replace" - "string replace"))) - (if vip-re-query-replace - (query-replace-regexp - str - (vip-read-string (format "Query replace regexp \"%s\" with: " str))) - (query-replace - str - (vip-read-string - (format "Query replace \"%s\" with: " str) nil t)))))) - - -;; marking - -(defun vip-mark-beginning-of-buffer () - (interactive) - (set-mark (point)) - (goto-char (point-min)) - (exchange-point-and-mark) - (message "mark set at the beginning of buffer")) - -(defun vip-mark-end-of-buffer () - (interactive) - (set-mark (point)) - (goto-char (point-max)) - (exchange-point-and-mark) - (message "mark set at the end of buffer")) - -(defun vip-mark-point (char) - (interactive "c") - (cond ((and (<= ?a char) (<= char ?z)) - (point-to-register (- char (- ?a ?\C-a)) nil)) - ((eq char ?<) (vip-mark-beginning-of-buffer)) - ((eq char ?>) (vip-mark-end-of-buffer)) - ((eq char ?.) (push-mark)) - ((eq char ?,) (set-mark-command 1)) - ((eq char ?D) (mark-defun)) - (t (error "")))) - -(defun vip-goto-mark (arg) - "Go to mark." - (interactive "P") - (let ((char (read-char)) (com (vip-getcom arg))) - (vip-goto-mark-subr char com nil))) - -(defun vip-goto-mark-and-skip-white (arg) - "Go to mark and skip to first non-white on line." - (interactive "P") - (let ((char (read-char)) (com (vip-getCom arg))) - (vip-goto-mark-subr char com t))) - -(defun vip-goto-mark-subr (char com skip-white) - (cond ((and (<= ?a char) (<= char ?z)) - (let ((buff (current-buffer))) - (if com (vip-move-marker-locally vip-com-point (point))) - (goto-char (register-to-point (- char (- ?a ?\C-a)))) - (if skip-white (back-to-indentation)) - (vip-change-mode-to-vi) - (if com - (if (eq buff (current-buffer)) - (vip-execute-com (if skip-white - 'vip-goto-mark-and-skip-white - 'vip-goto-mark) - nil com) - (switch-to-buffer buff) - (goto-char vip-com-point) - (vip-change-mode-to-vi) - (error ""))))) - ((and (not skip-white) (eq char ?`)) - (if com (vip-move-marker-locally vip-com-point (point))) - (exchange-point-and-mark) - (if com (vip-execute-com 'vip-goto-mark nil com))) - ((and skip-white (eq char ?')) - (if com (vip-move-marker-locally vip-com-point (point))) - (exchange-point-and-mark) - (back-to-indentation) - (if com (vip-execute-com 'vip-goto-mark-and-skip-white nil com))) - (t (error "")))) - -(defun vip-exchange-point-and-mark () - (interactive) - (exchange-point-and-mark) - (back-to-indentation)) - -(defun vip-keyboard-quit () - "Abort partially formed or running command." - (interactive) - (setq vip-use-register nil) - (keyboard-quit)) - -(defun vip-ctl-c-equivalent (arg) - "Emulate C-c in Emacs mode." - (interactive "P") - (vip-ctl-key-equivalent "\C-c" arg)) - -(defun vip-ctl-x-equivalent (arg) - "Emulate C-x in Emacs mode." - (interactive "P") - (vip-ctl-key-equivalent "\C-x" arg)) - -(defun vip-ctl-key-equivalent (key arg) - (let ((char (read-char))) - (if (and (<= ?A char) (<= char ?Z)) - (setq char (- char (- ?A ?\C-a)))) - (vip-escape-to-emacs arg (list (aref key 0) char)))) - -;; commands in insertion mode - -(defun vip-delete-backward-word (arg) - "Delete previous word." - (interactive "p") - (save-excursion - (set-mark (point)) - (backward-word arg) - (delete-region (point) (mark 'force)))) - - -;; key bindings - -(set 'vip-vi-mode-map (make-sparse-keymap)) - -(define-key vip-vi-mode-map "\C-a" 'beginning-of-line) -(define-key vip-vi-mode-map "\C-b" 'vip-scroll-back) -(define-key vip-vi-mode-map "\C-c" 'vip-ctl-c) -(define-key vip-vi-mode-map "\C-d" 'vip-scroll-up) -(define-key vip-vi-mode-map "\C-e" 'vip-scroll-up-one) -(define-key vip-vi-mode-map "\C-f" 'vip-scroll) -(define-key vip-vi-mode-map "\C-g" 'vip-keyboard-quit) -(define-key vip-vi-mode-map "\C-h" 'help-command) -(define-key vip-vi-mode-map "\C-m" 'vip-scroll-back) -(define-key vip-vi-mode-map "\C-n" 'vip-other-window) -(define-key vip-vi-mode-map "\C-o" 'vip-open-line-at-point) -(define-key vip-vi-mode-map "\C-u" 'vip-scroll-down) -(define-key vip-vi-mode-map "\C-x" 'vip-ctl-x) -(define-key vip-vi-mode-map "\C-y" 'vip-scroll-down-one) -(define-key vip-vi-mode-map "\C-z" 'vip-change-mode-to-emacs) -(define-key vip-vi-mode-map "\e" 'vip-ESC) - -(define-key vip-vi-mode-map " " 'vip-scroll) -(define-key vip-vi-mode-map "!" 'vip-command-argument) -(define-key vip-vi-mode-map "\"" 'vip-command-argument) -(define-key vip-vi-mode-map "#" 'vip-command-argument) -(define-key vip-vi-mode-map "$" 'vip-goto-eol) -(define-key vip-vi-mode-map "%" 'vip-paren-match) -(define-key vip-vi-mode-map "&" 'vip-nil) -(define-key vip-vi-mode-map "'" 'vip-goto-mark-and-skip-white) -(define-key vip-vi-mode-map "(" 'vip-backward-sentence) -(define-key vip-vi-mode-map ")" 'vip-forward-sentence) -(define-key vip-vi-mode-map "*" 'call-last-kbd-macro) -(define-key vip-vi-mode-map "+" 'vip-next-line-at-bol) -(define-key vip-vi-mode-map "," 'vip-repeat-find-opposite) -(define-key vip-vi-mode-map "-" 'vip-previous-line-at-bol) -(define-key vip-vi-mode-map "." 'vip-repeat) -(define-key vip-vi-mode-map "/" 'vip-search-forward) - -(define-key vip-vi-mode-map "0" 'vip-beginning-of-line) -(define-key vip-vi-mode-map "1" 'vip-digit-argument) -(define-key vip-vi-mode-map "2" 'vip-digit-argument) -(define-key vip-vi-mode-map "3" 'vip-digit-argument) -(define-key vip-vi-mode-map "4" 'vip-digit-argument) -(define-key vip-vi-mode-map "5" 'vip-digit-argument) -(define-key vip-vi-mode-map "6" 'vip-digit-argument) -(define-key vip-vi-mode-map "7" 'vip-digit-argument) -(define-key vip-vi-mode-map "8" 'vip-digit-argument) -(define-key vip-vi-mode-map "9" 'vip-digit-argument) - -(define-key vip-vi-mode-map ":" 'vip-ex) -(define-key vip-vi-mode-map ";" 'vip-repeat-find) -(define-key vip-vi-mode-map "<" 'vip-command-argument) -(define-key vip-vi-mode-map "=" 'vip-command-argument) -(define-key vip-vi-mode-map ">" 'vip-command-argument) -(define-key vip-vi-mode-map "?" 'vip-search-backward) -(define-key vip-vi-mode-map "@" 'vip-nil) - -(define-key vip-vi-mode-map "A" 'vip-Append) -(define-key vip-vi-mode-map "B" 'vip-backward-Word) -(define-key vip-vi-mode-map "C" 'vip-ctl-c-equivalent) -(define-key vip-vi-mode-map "D" 'vip-kill-line) -(define-key vip-vi-mode-map "E" 'vip-end-of-Word) -(define-key vip-vi-mode-map "F" 'vip-find-char-backward) -(define-key vip-vi-mode-map "G" 'vip-goto-line) -(define-key vip-vi-mode-map "H" 'vip-window-top) -(define-key vip-vi-mode-map "I" 'vip-Insert) -(define-key vip-vi-mode-map "J" 'vip-join-lines) -(define-key vip-vi-mode-map "K" 'vip-kill-buffer) -(define-key vip-vi-mode-map "L" 'vip-window-bottom) -(define-key vip-vi-mode-map "M" 'vip-window-middle) -(define-key vip-vi-mode-map "N" 'vip-search-Next) -(define-key vip-vi-mode-map "O" 'vip-Open-line) -(define-key vip-vi-mode-map "P" 'vip-Put-back) -(define-key vip-vi-mode-map "Q" 'vip-query-replace) -(define-key vip-vi-mode-map "R" 'vip-replace-string) -(define-key vip-vi-mode-map "S" 'vip-switch-to-buffer-other-window) -(define-key vip-vi-mode-map "T" 'vip-goto-char-backward) -(define-key vip-vi-mode-map "U" 'vip-nil) -(define-key vip-vi-mode-map "V" 'vip-find-file-other-window) -(define-key vip-vi-mode-map "W" 'vip-forward-Word) -(define-key vip-vi-mode-map "X" 'vip-ctl-x-equivalent) -(define-key vip-vi-mode-map "Y" 'vip-yank-line) -(define-key vip-vi-mode-map "ZZ" 'save-buffers-kill-emacs) - -(define-key vip-vi-mode-map "[" 'vip-nil) -(define-key vip-vi-mode-map "\\" 'vip-escape-to-emacs) -(define-key vip-vi-mode-map "]" 'vip-nil) -(define-key vip-vi-mode-map "^" 'vip-bol-and-skip-white) -(define-key vip-vi-mode-map "_" 'vip-nil) -(define-key vip-vi-mode-map "`" 'vip-goto-mark) - -(define-key vip-vi-mode-map "a" 'vip-append) -(define-key vip-vi-mode-map "b" 'vip-backward-word) -(define-key vip-vi-mode-map "c" 'vip-command-argument) -(define-key vip-vi-mode-map "d" 'vip-command-argument) -(define-key vip-vi-mode-map "e" 'vip-end-of-word) -(define-key vip-vi-mode-map "f" 'vip-find-char-forward) -(define-key vip-vi-mode-map "g" 'vip-info-on-file) -(define-key vip-vi-mode-map "h" 'vip-backward-char) -(define-key vip-vi-mode-map "i" 'vip-insert) -(define-key vip-vi-mode-map "j" 'vip-next-line) -(define-key vip-vi-mode-map "k" 'vip-previous-line) -(define-key vip-vi-mode-map "l" 'vip-forward-char) -(define-key vip-vi-mode-map "m" 'vip-mark-point) -(define-key vip-vi-mode-map "n" 'vip-search-next) -(define-key vip-vi-mode-map "o" 'vip-open-line) -(define-key vip-vi-mode-map "p" 'vip-put-back) -(define-key vip-vi-mode-map "q" 'vip-nil) -(define-key vip-vi-mode-map "r" 'vip-replace-char) -(define-key vip-vi-mode-map "s" 'vip-switch-to-buffer) -(define-key vip-vi-mode-map "t" 'vip-goto-char-forward) -(define-key vip-vi-mode-map "u" 'vip-undo) -(define-key vip-vi-mode-map "v" 'vip-find-file) -(define-key vip-vi-mode-map "w" 'vip-forward-word) -(define-key vip-vi-mode-map "x" 'vip-delete-char) -(define-key vip-vi-mode-map "y" 'vip-command-argument) -(define-key vip-vi-mode-map "zH" 'vip-line-to-top) -(define-key vip-vi-mode-map "zM" 'vip-line-to-middle) -(define-key vip-vi-mode-map "zL" 'vip-line-to-bottom) -(define-key vip-vi-mode-map "z\C-m" 'vip-line-to-top) -(define-key vip-vi-mode-map "z." 'vip-line-to-middle) -(define-key vip-vi-mode-map "z-" 'vip-line-to-bottom) - -(define-key vip-vi-mode-map "{" 'vip-backward-paragraph) -(define-key vip-vi-mode-map "|" 'vip-goto-col) -(define-key vip-vi-mode-map "}" 'vip-forward-paragraph) -(define-key vip-vi-mode-map "~" 'vip-nil) -(define-key vip-vi-mode-map "\177" 'vip-delete-backward-char) - -(set 'vip-insert-mode-map (make-sparse-keymap)) - -(define-key vip-insert-mode-map "\e" 'vip-change-mode-to-vi) -(define-key vip-insert-mode-map "\C-z" 'vip-ESC) -(define-key vip-insert-mode-map "\C-h" - (if vip-help-in-insert-mode 'help-command 'vip-delete-backward-char)) -(define-key vip-insert-mode-map "\C-w" 'vip-delete-backward-word) - -(define-key ctl-x-map "3" 'vip-buffer-in-two-windows) -(define-key ctl-x-map "\C-i" 'insert-file) - -(defun vip-version () - (interactive) - (message "VIP version 3.7 of August 22, 1999")) - -;; implement ex commands - -(defvar ex-token-type nil - "type of token. if non-nil, gives type of address. if nil, it -is a command.") - -(defvar ex-token nil - "value of token.") - -(defvar ex-addresses nil - "list of ex addresses") - -(defvar ex-flag nil - "flag for ex flag") - -(defvar ex-buffer nil - "name of ex buffer") - -(defvar ex-count nil - "value of ex count") - -(defvar ex-g-flag nil - "flag for global command") - -(defvar ex-g-variant nil - "if t global command is executed on lines not matching ex-g-pat") - -(defvar ex-reg-exp nil - "save reg-exp used in substitute") - -(defvar ex-repl nil - "replace pattern for substitute") - -(defvar ex-g-pat nil - "pattern for global command") - -(defvar ex-map (make-sparse-keymap) - "save commands for mapped keys") - -(defvar ex-tag nil - "save ex tag") - -(defvar ex-file nil) - -(defvar ex-variant nil) - -(defvar ex-offset nil) - -(defvar ex-append nil) - -(defun vip-nil () - (interactive) - (error "")) - -(defun vip-looking-back (str) - "returns t if looking back reg-exp STR before point." - (and (save-excursion (re-search-backward str nil t)) - (eq (point) (match-end 0)))) - -(defun vip-check-sub (str) - "check if ex-token is an initial segment of STR" - (let ((length (length ex-token))) - (if (and (<= length (length str)) - (string= ex-token (substring str 0 length))) - (setq ex-token str) - (setq ex-token-type "non-command")))) - -(defun vip-get-ex-com-subr () - "get a complete ex command" - (set-mark (point)) - (re-search-forward "[a-z][a-z]*") - (setq ex-token-type "command") - (setq ex-token (buffer-substring (point) (mark 'force))) - (exchange-point-and-mark) - (cond ((looking-at "a") - (cond ((looking-at "ab") (vip-check-sub "abbreviate")) - ((looking-at "ar") (vip-check-sub "args")) - (t (vip-check-sub "append")))) - ((looking-at "[bh]") (setq ex-token-type "non-command")) - ((looking-at "c") - (if (looking-at "co") (vip-check-sub "copy") - (vip-check-sub "change"))) - ((looking-at "d") (vip-check-sub "delete")) - ((looking-at "e") - (if (looking-at "ex") (vip-check-sub "ex") - (vip-check-sub "edit"))) - ((looking-at "f") (vip-check-sub "file")) - ((looking-at "g") (vip-check-sub "global")) - ((looking-at "i") (vip-check-sub "insert")) - ((looking-at "j") (vip-check-sub "join")) - ((looking-at "l") (vip-check-sub "list")) - ((looking-at "m") - (cond ((looking-at "map") (vip-check-sub "map")) - ((looking-at "mar") (vip-check-sub "mark")) - (t (vip-check-sub "move")))) - ((looking-at "n") - (if (looking-at "nu") (vip-check-sub "number") - (vip-check-sub "next"))) - ((looking-at "o") (vip-check-sub "open")) - ((looking-at "p") - (cond ((looking-at "pre") (vip-check-sub "preserve")) - ((looking-at "pu") (vip-check-sub "put")) - (t (vip-check-sub "print")))) - ((looking-at "q") (vip-check-sub "quit")) - ((looking-at "r") - (cond ((looking-at "rec") (vip-check-sub "recover")) - ((looking-at "rew") (vip-check-sub "rewind")) - (t (vip-check-sub "read")))) - ((looking-at "s") - (cond ((looking-at "se") (vip-check-sub "set")) - ((looking-at "sh") (vip-check-sub "shell")) - ((looking-at "so") (vip-check-sub "source")) - ((looking-at "st") (vip-check-sub "stop")) - (t (vip-check-sub "substitute")))) - ((looking-at "t") - (if (looking-at "ta") (vip-check-sub "tag") - (vip-check-sub "t"))) - ((looking-at "u") - (cond ((looking-at "una") (vip-check-sub "unabbreviate")) - ((looking-at "unm") (vip-check-sub "unmap")) - (t (vip-check-sub "undo")))) - ((looking-at "v") - (cond ((looking-at "ve") (vip-check-sub "version")) - ((looking-at "vi") (vip-check-sub "visual")) - (t (vip-check-sub "v")))) - ((looking-at "w") - (if (looking-at "wq") (vip-check-sub "wq") - (vip-check-sub "write"))) - ((looking-at "x") (vip-check-sub "xit")) - ((looking-at "y") (vip-check-sub "yank")) - ((looking-at "z") (vip-check-sub "z"))) - (exchange-point-and-mark)) - -(defun vip-get-ex-token () - "get an ex-token which is either an address or a command. -a token has type \(command, address, end-mark\) and value." - (save-window-excursion - (set-buffer " *ex-working-space*") - (skip-chars-forward " \t") - (cond ((looking-at "[k#]") - (setq ex-token-type "command") - (setq ex-token (char-to-string (following-char))) - (forward-char 1)) - ((looking-at "[a-z]") (vip-get-ex-com-subr)) - ((looking-at "\\.") - (forward-char 1) - (setq ex-token-type "dot")) - ((looking-at "[0-9]") - (set-mark (point)) - (re-search-forward "[0-9]*") - (setq ex-token-type - (cond ((string= ex-token-type "plus") "add-number") - ((string= ex-token-type "minus") "sub-number") - (t "abs-number"))) - (setq ex-token (string-to-number (buffer-substring (point) (mark 'force))))) - ((looking-at "\\$") - (forward-char 1) - (setq ex-token-type "end")) - ((looking-at "%") - (forward-char 1) - (setq ex-token-type "whole")) - ((looking-at "+") - (cond ((or (looking-at "+[-+]") (looking-at "+[\n|]")) - (forward-char 1) - (insert "1") - (backward-char 1) - (setq ex-token-type "plus")) - ((looking-at "+[0-9]") - (forward-char 1) - (setq ex-token-type "plus")) - (t - (error "Badly formed address")))) - ((looking-at "-") - (cond ((or (looking-at "-[-+]") (looking-at "-[\n|]")) - (forward-char 1) - (insert "1") - (backward-char 1) - (setq ex-token-type "minus")) - ((looking-at "-[0-9]") - (forward-char 1) - (setq ex-token-type "minus")) - (t - (error "Badly formed address")))) - ((looking-at "/") - (forward-char 1) - (set-mark (point)) - (let ((cont t)) - (while (and (not (eolp)) cont) - ;;(re-search-forward "[^/]*/") - (re-search-forward "[^/]*\\(/\\|\n\\)") - (if (not (vip-looking-back "[^\\\\]\\(\\\\\\\\\\)*\\\\/")) - (setq cont nil)))) - (backward-char 1) - (setq ex-token (buffer-substring (point) (mark 'force))) - (if (looking-at "/") (forward-char 1)) - (setq ex-token-type "search-forward")) - ((looking-at "\\?") - (forward-char 1) - (set-mark (point)) - (let ((cont t)) - (while (and (not (eolp)) cont) - ;;(re-search-forward "[^\\?]*\\?") - (re-search-forward "[^\\?]*\\(\\?\\|\n\\)") - (if (not (vip-looking-back "[^\\\\]\\(\\\\\\\\\\)*\\\\\\?")) - (setq cont nil)) - (backward-char 1) - (if (not (looking-at "\n")) (forward-char 1)))) - (setq ex-token-type "search-backward") - (setq ex-token (buffer-substring (1- (point)) (mark 'force)))) - ((looking-at ",") - (forward-char 1) - (setq ex-token-type "comma")) - ((looking-at ";") - (forward-char 1) - (setq ex-token-type "semi-colon")) - ((looking-at "[!=><&~]") - (setq ex-token-type "command") - (setq ex-token (char-to-string (following-char))) - (forward-char 1)) - ((looking-at "'") - (setq ex-token-type "goto-mark") - (forward-char 1) - (cond ((looking-at "'") (setq ex-token nil)) - ((looking-at "[a-z]") (setq ex-token (following-char))) - (t (error "Marks are ' and a-z"))) - (forward-char 1)) - ((looking-at "\n") - (setq ex-token-type "end-mark") - (setq ex-token "goto")) - (t - (error "illegal token"))))) - -(defun vip-ex (&optional string) - "ex commands within VIP." - (interactive) - (or string - (setq ex-g-flag nil - ex-g-variant nil)) - (let ((com-str (or string (vip-read-string ":"))) - (address nil) (cont t) (dot (point))) - (save-window-excursion - (set-buffer (get-buffer-create " *ex-working-space*")) - (delete-region (point-min) (point-max)) - (insert com-str "\n") - (goto-char (point-min))) - (setq ex-token-type "") - (setq ex-addresses nil) - (while cont - (vip-get-ex-token) - (cond ((or (string= ex-token-type "command") - (string= ex-token-type "end-mark")) - (if address (setq ex-addresses (cons address ex-addresses))) - (cond ((string= ex-token "global") - (ex-global nil) - (setq cont nil)) - ((string= ex-token "v") - (ex-global t) - (setq cont nil)) - (t - (vip-execute-ex-command) - (save-window-excursion - (set-buffer " *ex-working-space*") - (skip-chars-forward " \t") - (cond ((looking-at "|") - (forward-char 1)) - ((looking-at "\n") - (setq cont nil)) - (t (error "Extra character at end of a command"))))))) - ((string= ex-token-type "non-command") - (error (format "%s: Not an editor command" ex-token))) - ((string= ex-token-type "whole") - (setq ex-addresses - (cons (point-max) (cons (point-min) ex-addresses)))) - ((string= ex-token-type "comma") - (setq ex-addresses - (cons (if (null address) (point) address) ex-addresses))) - ((string= ex-token-type "semi-colon") - (if address (setq dot address)) - (setq ex-addresses - (cons (if (null address) (point) address) ex-addresses))) - (t (let ((ans (vip-get-ex-address-subr address dot))) - (if ans (setq address ans)))))))) - -(defun vip-get-ex-pat () - "get a regular expression and set ex-variant if found" - (save-window-excursion - (set-buffer " *ex-working-space*") - (skip-chars-forward " \t") - (if (looking-at "!") - (progn - (setq ex-g-variant (not ex-g-variant) - ex-g-flag (not ex-g-flag)) - (forward-char 1) - (skip-chars-forward " \t"))) - (if (looking-at "/") - (progn - (forward-char 1) - (set-mark (point)) - (let ((cont t)) - (while (and (not (eolp)) cont) - (re-search-forward "[^/]*\\(/\\|\n\\)") - ;;(re-search-forward "[^/]*/") - (if (not (vip-looking-back "[^\\\\]\\(\\\\\\\\\\)*\\\\/")) - (setq cont nil)))) - (setq ex-token - (if (= (mark 'force) (point)) "" - (buffer-substring (1- (point)) (mark 'force)))) - (backward-char 1)) - (setq ex-token nil)))) - -(defun vip-get-ex-command () - "get an ex command" - (save-window-excursion - (set-buffer " *ex-working-space*") - (if (looking-at "/") (forward-char 1)) - (skip-chars-forward " \t") - (cond ((looking-at "[a-z]") - (vip-get-ex-com-subr) - (if (string= ex-token-type "non-command") - (error "%s: not an editor command" ex-token))) - ((looking-at "[!=><&~]") - (setq ex-token (char-to-string (following-char))) - (forward-char 1)) - (t (error "Could not find an ex command"))))) - -(defun vip-get-ex-opt-gc () - "get an ex option g or c" - (save-window-excursion - (set-buffer " *ex-working-space*") - (if (looking-at "/") (forward-char 1)) - (skip-chars-forward " \t") - (cond ((looking-at "g") - (setq ex-token "g") - (forward-char 1) - t) - ((looking-at "c") - (setq ex-token "c") - (forward-char 1) - t) - (t nil)))) - -(defun vip-default-ex-addresses (&optional whole-flag) - "compute default addresses. whole-flag means whole buffer." - (cond ((null ex-addresses) - (setq ex-addresses - (if whole-flag - (cons (point-max) (cons (point-min) nil)) - (cons (point) (cons (point) nil))))) - ((null (cdr ex-addresses)) - (setq ex-addresses - (cons (car ex-addresses) ex-addresses))))) - -(defun vip-get-ex-address () - "get an ex-address as a marker and set ex-flag if a flag is found" - (let ((address (point-marker)) (cont t)) - (setq ex-token "") - (setq ex-flag nil) - (while cont - (vip-get-ex-token) - (cond ((string= ex-token-type "command") - (if (or (string= ex-token "print") (string= ex-token "list") - (string= ex-token "#")) - (progn - (setq ex-flag t) - (setq cont nil)) - (error "address expected"))) - ((string= ex-token-type "end-mark") - (setq cont nil)) - ((string= ex-token-type "whole") - (error "a trailing address is expected")) - ((string= ex-token-type "comma") - (error "Extra characters after an address")) - (t (let ((ans (vip-get-ex-address-subr address (point-marker)))) - (if ans (setq address ans)))))) - address)) - -(defun vip-get-ex-address-subr (old-address dot) - "returns an address as a point" - (let ((address nil)) - (if (null old-address) (setq old-address dot)) - (cond ((string= ex-token-type "dot") - (setq address dot)) - ((string= ex-token-type "add-number") - (save-excursion - (goto-char old-address) - (forward-line (if (= old-address 0) (1- ex-token) ex-token)) - (setq address (point-marker)))) - ((string= ex-token-type "sub-number") - (save-excursion - (goto-char old-address) - (forward-line (- ex-token)) - (setq address (point-marker)))) - ((string= ex-token-type "abs-number") - (save-excursion - (goto-char (point-min)) - (if (= ex-token 0) (setq address 0) - (forward-line (1- ex-token)) - (setq address (point-marker))))) - ((string= ex-token-type "end") - (setq address (point-max-marker))) - ((string= ex-token-type "plus") t);; do nothing - ((string= ex-token-type "minus") t);; do nothing - ((string= ex-token-type "search-forward") - (save-excursion - (ex-search-address t) - (setq address (point-marker)))) - ((string= ex-token-type "search-backward") - (save-excursion - (ex-search-address nil) - (setq address (point-marker)))) - ((string= ex-token-type "goto-mark") - (save-excursion - (if (null ex-token) - (exchange-point-and-mark) - (goto-char (register-to-point (- ex-token (- ?a ?\C-a))))) - (setq address (point-marker))))) - address)) - -(defun ex-search-address (forward) - "search pattern and set address" - (if (string= ex-token "") - (if (null vip-s-string) (error "No previous search string") - (setq ex-token vip-s-string)) - (setq vip-s-string ex-token)) - (if forward - (progn - (forward-line 1) - (re-search-forward ex-token)) - (forward-line -1) - (re-search-backward ex-token))) - -(defun vip-get-ex-buffer () - "get a buffer name and set ex-count and ex-flag if found" - (setq ex-buffer nil) - (setq ex-count nil) - (setq ex-flag nil) - (save-window-excursion - (set-buffer " *ex-working-space*") - (skip-chars-forward " \t") - (if (looking-at "[a-zA-Z]") - (progn - (setq ex-buffer (following-char)) - (forward-char 1) - (skip-chars-forward " \t"))) - (if (looking-at "[0-9]") - (progn - (set-mark (point)) - (re-search-forward "[0-9][0-9]*") - (setq ex-count (string-to-number (buffer-substring (point) (mark 'force)))) - (skip-chars-forward " \t"))) - (if (looking-at "[pl#]") - (progn - (setq ex-flag t) - (forward-char 1))) - (if (not (looking-at "[\n|]")) - (error "Illegal extra characters")))) - -(defun vip-get-ex-count () - (setq ex-variant nil - ex-count nil - ex-flag nil) - (save-window-excursion - (set-buffer " *ex-working-space*") - (skip-chars-forward " \t") - (if (looking-at "!") - (progn - (setq ex-variant t) - (forward-char 1))) - (skip-chars-forward " \t") - (if (looking-at "[0-9]") - (progn - (set-mark (point)) - (re-search-forward "[0-9][0-9]*") - (setq ex-count (string-to-number (buffer-substring (point) (mark 'force)))) - (skip-chars-forward " \t"))) - (if (looking-at "[pl#]") - (progn - (setq ex-flag t) - (forward-char 1))) - (if (not (looking-at "[\n|]")) - (error "Illegal extra characters")))) - -(defun vip-get-ex-file () - "get a file name and set ex-variant, ex-append and ex-offset if found" - (setq ex-file nil - ex-variant nil - ex-append nil - ex-offset nil) - (save-window-excursion - (set-buffer " *ex-working-space*") - (skip-chars-forward " \t") - (if (looking-at "!") - (progn - (setq ex-variant t) - (forward-char 1) - (skip-chars-forward " \t"))) - (if (looking-at ">>") - (progn - (setq ex-append t - ex-variant t) - (forward-char 2) - (skip-chars-forward " \t"))) - (if (looking-at "+") - (progn - (forward-char 1) - (set-mark (point)) - (re-search-forward "[ \t\n]") - (backward-char 1) - (setq ex-offset (buffer-substring (point) (mark 'force))) - (forward-char 1) - (skip-chars-forward " \t"))) - (set-mark (point)) - (re-search-forward "[ \t\n]") - (backward-char 1) - (setq ex-file (buffer-substring (point) (mark 'force))))) - -(defun vip-execute-ex-command () - "execute ex command using the value of addresses." - (cond ((string= ex-token "goto") (ex-goto)) - ((string= ex-token "copy") (ex-copy nil)) - ((string= ex-token "delete") (ex-delete)) - ((string= ex-token "edit") (ex-edit)) - ((string= ex-token "file") (vip-info-on-file)) - ;((string= ex-token "global") (ex-global nil)) - ((string= ex-token "join") (ex-line "join")) - ((string= ex-token "k") (ex-mark)) - ((string= ex-token "mark") (ex-mark)) - ((string= ex-token "map") (ex-map)) - ((string= ex-token "move") (ex-copy t)) - ((string= ex-token "put") (ex-put)) - ((string= ex-token "quit") (ex-quit)) - ((string= ex-token "read") (ex-read)) - ((string= ex-token "set") (ex-set)) - ((string= ex-token "shell") (ex-shell)) - ((string= ex-token "substitute") (ex-substitute)) - ((string= ex-token "stop") (suspend-emacs)) - ((string= ex-token "t") (ex-copy nil)) - ((string= ex-token "tag") (ex-tag)) - ((string= ex-token "undo") (vip-undo)) - ((string= ex-token "unmap") (ex-unmap)) - ;((string= ex-token "v") (ex-global t)) - ((string= ex-token "version") (vip-version)) - ((string= ex-token "visual") (ex-edit)) - ((string= ex-token "write") (ex-write nil)) - ((string= ex-token "wq") (ex-write t)) - ((string= ex-token "yank") (ex-yank)) - ((string= ex-token "!") (ex-command)) - ((string= ex-token "=") (ex-line-no)) - ((string= ex-token ">") (ex-line "right")) - ((string= ex-token "<") (ex-line "left")) - ((string= ex-token "&") (ex-substitute t)) - ((string= ex-token "~") (ex-substitute t t)) - ((or (string= ex-token "append") - (string= ex-token "args") - (string= ex-token "change") - (string= ex-token "insert") - (string= ex-token "open") - ) - (error "%s: no such command from VIP" ex-token)) - ((or (string= ex-token "abbreviate") - (string= ex-token "list") - (string= ex-token "next") - (string= ex-token "print") - (string= ex-token "preserve") - (string= ex-token "recover") - (string= ex-token "rewind") - (string= ex-token "source") - (string= ex-token "unabbreviate") - (string= ex-token "xit") - (string= ex-token "z") - ) - (error "%s: not implemented in VIP" ex-token)) - (t (error "%s: Not an editor command" ex-token)))) - -(defun ex-goto () - "ex goto command" - (if (null ex-addresses) - (setq ex-addresses (cons (point) nil))) - (push-mark (point)) - (goto-char (car ex-addresses)) - (beginning-of-line)) - -(defun ex-copy (del-flag) - "ex copy and move command. DEL-FLAG means delete." - (vip-default-ex-addresses) - (let ((address (vip-get-ex-address)) - (end (car ex-addresses)) (beg (car (cdr ex-addresses)))) - (goto-char end) - (save-excursion - (set-mark beg) - (vip-enlarge-region (mark 'force) (point)) - (if del-flag (kill-region (point) (mark 'force)) - (copy-region-as-kill (point) (mark 'force))) - (if ex-flag - (progn - (with-output-to-temp-buffer "*copy text*" - (princ - (if (or del-flag ex-g-flag ex-g-variant) - (current-kill 0) - (buffer-substring (point) (mark 'force))))) - (condition-case nil - (progn - (vip-read-string "[Hit return to continue] ") - (save-excursion (kill-buffer "*copy text*"))) - (quit - (save-excursion (kill-buffer "*copy text*")) - (signal 'quit nil)))))) - (if (= address 0) - (goto-char (point-min)) - (goto-char address) - (forward-line 1)) - (insert (current-kill 0)))) - -(defun ex-delete () - "ex delete" - (vip-default-ex-addresses) - (vip-get-ex-buffer) - (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses)))) - (if (> beg end) (error "First address exceeds second")) - (save-excursion - (vip-enlarge-region beg end) - (exchange-point-and-mark) - (if ex-count - (progn - (set-mark (point)) - (forward-line (1- ex-count))) - (set-mark end)) - (vip-enlarge-region (point) (mark 'force)) - (if ex-flag - ;; show text to be deleted and ask for confirmation - (progn - (with-output-to-temp-buffer " *delete text*" - (princ (buffer-substring (point) (mark 'force)))) - (condition-case conditions - (vip-read-string "[Hit return to continue] ") - (quit - (save-excursion (kill-buffer " *delete text*")) - (error ""))) - (save-excursion (kill-buffer " *delete text*"))) - (if ex-buffer - (if (and (<= ?A ex-buffer) (<= ex-buffer ?Z)) - (vip-append-to-register - (+ ex-buffer 32) (point) (mark 'force)) - (copy-to-register ex-buffer (point) (mark 'force) nil))) - (delete-region (point) (mark 'force)))))) - -(defun ex-edit () - "ex-edit" - (vip-get-ex-file) - (if (and (not ex-variant) (buffer-modified-p) buffer-file-name) - (error "No write since last change \(:e! overrides\)")) - (vip-change-mode-to-emacs) - (set-buffer - (find-file-noselect (concat default-directory ex-file))) - (vip-change-mode-to-vi) - (goto-char (point-min)) - (if ex-offset - (progn - (save-window-excursion - (set-buffer " *ex-working-space*") - (delete-region (point-min) (point-max)) - (insert ex-offset "\n") - (goto-char (point-min))) - (goto-char (vip-get-ex-address)) - (beginning-of-line)))) - -(defun ex-global (variant) - "ex global command" - (if (or ex-g-flag ex-g-variant) - (error "Global within global not allowed") - (if variant - (setq ex-g-flag nil - ex-g-variant t) - (setq ex-g-flag t - ex-g-variant nil))) - (vip-get-ex-pat) - (if (null ex-token) - (error "Missing regular expression for global command")) - (if (string= ex-token "") - (if (null vip-s-string) (error "No previous search string") - (setq ex-g-pat vip-s-string)) - (setq ex-g-pat ex-token - vip-s-string ex-token)) - (if (null ex-addresses) - (setq ex-addresses (list (point-max) (point-min)))) - (let ((marks nil) (mark-count 0) - com-str (end (car ex-addresses)) (beg (car (cdr ex-addresses)))) - (if (> beg end) (error "First address exceeds second")) - (save-excursion - (vip-enlarge-region beg end) - (exchange-point-and-mark) - (let ((cont t) (limit (point-marker))) - (exchange-point-and-mark) - ;; skip the last line if empty - (beginning-of-line) - (if (and (eobp) (not (bobp))) (backward-char 1)) - (while (and cont (not (bobp)) (>= (point) limit)) - (beginning-of-line) - (set-mark (point)) - (end-of-line) - (let ((found (re-search-backward ex-g-pat (mark 'force) t))) - (if (or (and ex-g-flag found) - (and ex-g-variant (not found))) - (progn - (end-of-line) - (setq mark-count (1+ mark-count)) - (setq marks (cons (point-marker) marks))))) - (beginning-of-line) - (if (bobp) (setq cont nil) - (forward-line -1) - (end-of-line))))) - (save-window-excursion - (set-buffer " *ex-working-space*") - (setq com-str (buffer-substring (1+ (point)) (1- (point-max))))) - (while marks - (goto-char (car marks)) - ; report progress of execution on a slow machine. - ;(message "Executing global command...") - ;(if (zerop (% mark-count 10)) - ;(message "Executing global command...%d" mark-count)) - (vip-ex com-str) - (setq mark-count (1- mark-count)) - (setq marks (cdr marks))))) - ;(message "Executing global command...done"))) - -(defun ex-line (com) - "ex line commands. COM is join, shift-right or shift-left." - (vip-default-ex-addresses) - (vip-get-ex-count) - (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))) point) - (if (> beg end) (error "First address exceeds second")) - (save-excursion - (vip-enlarge-region beg end) - (exchange-point-and-mark) - (if ex-count - (progn - (set-mark (point)) - (forward-line ex-count))) - (if ex-flag - ;; show text to be joined and ask for confirmation - (progn - (with-output-to-temp-buffer " *text*" - (princ (buffer-substring (point) (mark 'force)))) - (condition-case conditions - (progn - (vip-read-string "[Hit return to continue] ") - (ex-line-subr com (point) (mark 'force))) - (quit - (ding))) - (save-excursion (kill-buffer " *text*"))) - (ex-line-subr com (point) (mark 'force))) - (setq point (point))) - (goto-char (1- point)) - (beginning-of-line))) - -(defun ex-line-subr (com beg end) - (cond ((string= com "join") - (goto-char (min beg end)) - (while (and (not (eobp)) (< (point) (max beg end))) - (end-of-line) - (if (and (<= (point) (max beg end)) (not (eobp))) - (progn - (forward-line 1) - (delete-region (point) (1- (point))) - (if (not ex-variant) (fixup-whitespace)))))) - ((or (string= com "right") (string= com "left")) - (indent-rigidly - (min beg end) (max beg end) - (if (string= com "right") vip-shift-width (- vip-shift-width))) - (goto-char (max beg end)) - (end-of-line) - (forward-char 1)))) - -(defun ex-mark () - "ex mark" - (let (char) - (if (null ex-addresses) - (setq ex-addresses - (cons (point) nil))) - (save-window-excursion - (set-buffer " *ex-working-space*") - (skip-chars-forward " \t") - (if (looking-at "[a-z]") - (progn - (setq char (following-char)) - (forward-char 1) - (skip-chars-forward " \t") - (if (not (looking-at "[\n|]")) - (error "Extra characters at end of \"k\" command"))) - (if (looking-at "[\n|]") - (error "\"k\" requires a following letter") - (error "Mark must specify a letter")))) - (save-excursion - (goto-char (car ex-addresses)) - (point-to-register (- char (- ?a ?\C-a)) nil)))) - -(defun ex-map () - "ex map" - (let (char string) - (save-window-excursion - (set-buffer " *ex-working-space*") - (skip-chars-forward " \t") - (setq char (char-to-string (following-char))) - (forward-char 1) - (skip-chars-forward " \t") - (if (looking-at "[\n|]") (error "Missing rhs")) - (set-mark (point)) - (end-of-buffer) - (backward-char 1) - (setq string (buffer-substring (mark 'force) (point)))) - (if (not (lookup-key ex-map char)) - (define-key ex-map char - (or (lookup-key vip-vi-mode-map char) 'vip-nil))) - (define-key vip-vi-mode-map char - (eval - (list 'quote - (cons 'lambda - (list '(count) - '(interactive "p") - (list 'execute-kbd-macro string 'count)))))))) - -(defun ex-unmap () - "ex unmap" - (let (char) - (save-window-excursion - (set-buffer " *ex-working-space*") - (skip-chars-forward " \t") - (setq char (char-to-string (following-char))) - (forward-char 1) - (skip-chars-forward " \t") - (if (not (looking-at "[\n|]")) (error "Macro must be a character"))) - (if (not (lookup-key ex-map char)) - (error "That macro wasn't mapped")) - (define-key vip-vi-mode-map char (lookup-key ex-map char)) - (define-key ex-map char nil))) - -(defun ex-put () - "ex put" - (let ((point (if (null ex-addresses) (point) (car ex-addresses)))) - (vip-get-ex-buffer) - (setq vip-use-register ex-buffer) - (goto-char point) - (if (= point 0) (vip-Put-back 1) (vip-put-back 1)))) - -(defun ex-quit () - "ex quit" - (let (char) - (save-window-excursion - (set-buffer " *ex-working-space*") - (skip-chars-forward " \t") - (setq char (following-char))) - (if (eq char ?!) (kill-emacs t) (save-buffers-kill-emacs)))) - -(defun ex-read () - "ex read" - (let ((point (if (null ex-addresses) (point) (car ex-addresses))) - (variant nil) command file) - (goto-char point) - (if (not (= point 0)) (next-line 1)) - (beginning-of-line) - (save-window-excursion - (set-buffer " *ex-working-space*") - (skip-chars-forward " \t") - (if (looking-at "!") - (progn - (setq variant t) - (forward-char 1) - (skip-chars-forward " \t") - (set-mark (point)) - (end-of-line) - (setq command (buffer-substring (mark 'force) (point)))) - (set-mark (point)) - (re-search-forward "[ \t\n]") - (backward-char 1) - (setq file (buffer-substring (point) (mark 'force))))) - (if variant - (shell-command command t) - (insert-file file)))) - -(defun ex-set () - (eval (list 'setq - (read-variable "Variable: ") - (eval (read-minibuffer "Value: "))))) - -(defun ex-shell () - "ex shell" - (vip-change-mode-to-emacs) - (shell)) - -(defun ex-substitute (&optional repeat r-flag) - "ex substitute. -If REPEAT use previous reg-exp which is ex-reg-exp or -vip-s-string" - (let (pat repl (opt-g nil) (opt-c nil) (matched-pos nil)) - (if repeat (setq ex-token nil) (vip-get-ex-pat)) - (if (null ex-token) - (setq pat (if r-flag vip-s-string ex-reg-exp) - repl ex-repl) - (setq pat (if (string= ex-token "") vip-s-string ex-token)) - (setq vip-s-string pat - ex-reg-exp pat) - (vip-get-ex-pat) - (if (null ex-token) - (setq ex-token "" - ex-repl "") - (setq repl ex-token - ex-repl ex-token))) - (while (vip-get-ex-opt-gc) - (if (string= ex-token "g") (setq opt-g t) (setq opt-c t))) - (vip-get-ex-count) - (if ex-count - (save-excursion - (if ex-addresses (goto-char (car ex-addresses))) - (set-mark (point)) - (forward-line (1- ex-count)) - (setq ex-addresses (cons (point) (cons (mark 'force) nil)))) - (if (null ex-addresses) - (setq ex-addresses (cons (point) (cons (point) nil))) - (if (null (cdr ex-addresses)) - (setq ex-addresses (cons (car ex-addresses) ex-addresses))))) - ;(setq G opt-g) - (let ((beg (car ex-addresses)) (end (car (cdr ex-addresses))) - (cont t) eol-mark) - (save-excursion - (vip-enlarge-region beg end) - (let ((limit (save-excursion - (goto-char (max (point) (mark 'force))) - (point-marker)))) - (goto-char (min (point) (mark 'force))) - (while (< (point) limit) - (end-of-line) - (setq eol-mark (point-marker)) - (beginning-of-line) - (if opt-g - (progn - (while (and (not (eolp)) - (re-search-forward pat eol-mark t)) - (if (or (not opt-c) (y-or-n-p "Replace? ")) - (progn - (setq matched-pos (point)) - (replace-match repl)))) - (end-of-line) - (forward-char)) - (if (and (re-search-forward pat eol-mark t) - (or (not opt-c) (y-or-n-p "Replace? "))) - (progn - (setq matched-pos (point)) - (replace-match repl))) - (end-of-line) - (forward-char)))))) - (if matched-pos (goto-char matched-pos)) - (beginning-of-line) - (if opt-c (message "done")))) - -(defun ex-tag () - "ex tag" - (let (tag) - (save-window-excursion - (set-buffer " *ex-working-space*") - (skip-chars-forward " \t") - (set-mark (point)) - (skip-chars-forward "^ |\t\n") - (setq tag (buffer-substring (mark 'force) (point)))) - (if (not (string= tag "")) (setq ex-tag tag)) - (vip-change-mode-to-emacs) - (condition-case conditions - (progn - (if (string= tag "") - (find-tag ex-tag t) - (find-tag-other-window ex-tag)) - (vip-change-mode-to-vi)) - (error - (vip-change-mode-to-vi) - (vip-message-conditions conditions))))) - -(defun ex-write (q-flag) - "ex write" - (vip-default-ex-addresses t) - (vip-get-ex-file) - (if (string= ex-file "") - (progn - (if (null buffer-file-name) - (error "No file associated with this buffer")) - (setq ex-file buffer-file-name)) - (setq ex-file (expand-file-name ex-file))) - (if (and (not (string= ex-file (buffer-file-name))) - (file-exists-p ex-file) - (not ex-variant)) - (error "\"%s\" File exists - use w! to override" ex-file)) - (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses)))) - (if (> beg end) (error "First address exceeds second")) - (save-excursion - (vip-enlarge-region beg end) - (write-region (point) (mark 'force) ex-file ex-append t))) - (if (null buffer-file-name) (setq buffer-file-name ex-file)) - (if q-flag (save-buffers-kill-emacs))) - -(defun ex-yank () - "ex yank" - (vip-default-ex-addresses) - (vip-get-ex-buffer) - (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses)))) - (if (> beg end) (error "First address exceeds second")) - (save-excursion - (vip-enlarge-region beg end) - (exchange-point-and-mark) - (if (or ex-g-flag ex-g-variant) (error "Can't yank within global")) - (if ex-count - (progn - (set-mark (point)) - (forward-line (1- ex-count))) - (set-mark end)) - (vip-enlarge-region (point) (mark 'force)) - (if ex-flag (error "Extra characters at end of command")) - (if ex-buffer - (copy-to-register ex-buffer (point) (mark 'force) nil)) - (copy-region-as-kill (point) (mark 'force))))) - -(defun ex-command () - "execute shell command" - (let (command) - (save-window-excursion - (set-buffer " *ex-working-space*") - (skip-chars-forward " \t") - (set-mark (point)) - (end-of-line) - (setq command (buffer-substring (mark 'force) (point)))) - (if (null ex-addresses) - (shell-command command) - (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses)))) - (if (null beg) (setq beg end)) - (save-excursion - (goto-char beg) - (set-mark end) - (vip-enlarge-region (point) (mark 'force)) - (shell-command-on-region (point) (mark 'force) command t)) - (goto-char beg))))) - -(defun ex-line-no () - "print line number" - (message "%d" - (1+ (count-lines - (point-min) - (if (null ex-addresses) (point-max) (car ex-addresses)))))) - -(if (file-exists-p vip-startup-file) (load vip-startup-file)) - -(provide 'vip) -;;; vip.el ends here