From adc404bea89a029726c30857b9d6469de0592cf5 Mon Sep 17 00:00:00 2001 From: bg66 Date: Sun, 21 Oct 2007 01:55:15 +0000 Subject: [PATCH] * mixi-ja.texi: New file. * infohack.el: Ditto. * ptexinfmt.el: Ditto. * Makefile.am (EXTRA_DIST): Add texinfo files. (info_TEXINFOS): New variable. (install): Depend install-info. (install-package): Make info file. (%.info): New rule. --- .cvsignore | 5 + ChangeLog | 11 + Makefile.am | 11 +- infohack.el | 177 ++++++++ mixi-ja.texi | 1377 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ptexinfmt.el | 1025 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 2604 insertions(+), 2 deletions(-) create mode 100644 infohack.el create mode 100755 mixi-ja.texi create mode 100644 ptexinfmt.el diff --git a/.cvsignore b/.cvsignore index 4529f65..25e8a68 100644 --- a/.cvsignore +++ b/.cvsignore @@ -12,3 +12,8 @@ config.cache COPYING INSTALL COMPILE +texinfo.tex +*.info* +mdate-sh +stamp-vti +version.texi diff --git a/ChangeLog b/ChangeLog index 425faad..71fc05a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2007-10-21 OHASHI Akira + + * mixi-ja.texi: New file. + * infohack.el: Ditto. + * ptexinfmt.el: Ditto. + * Makefile.am (EXTRA_DIST): Add texinfo files. + (info_TEXINFOS): New variable. + (install): Depend install-info. + (install-package): Make info file. + (%.info): New rule. + 2007-10-18 OHASHI Akira * mixi-atom.el: Fix expressions of the copyright notices. diff --git a/Makefile.am b/Makefile.am index 135a52a..999e190 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,9 +1,12 @@ CONTRIB = contrib/atom.cgi contrib/atom.sh -EXTRA_DIST = INSTALL-CVS ChangeLog @MODULES_ALL@ $(CONTRIB) +EXTRA_DIST = INSTALL-CVS ChangeLog @MODULES_ALL@ $(CONTRIB) \ + infohack.el ptexinfmt.el texinfo.tex CLEANFILES = auto-autoloads.el custom-load.el *.elc DISTCLEANFILES = COMPILE AUTOMAKE_OPTIONS = no-dependencies +info_TEXINFOS = mixi-ja.texi + FLAGS ?= -batch -q -no-site-file all: elc @@ -11,7 +14,7 @@ all: elc elc: $(EMACS) $(FLAGS) -l COMPILE -f mixi-compile -install: elc +install: elc install-info $(EMACS) $(FLAGS) -l COMPILE -f mixi-install $(lispdir) package: @@ -19,6 +22,7 @@ package: install-package: package $(XEMACS) $(FLAGS) -l COMPILE -f mixi-install-package $(PACKAGEDIR) + $(MAKE) infodir=$(PACKAGEDIR)/info install compile-individually: @for i in `$(EMACS) $(FLAGS) -l COMPILE -f mixi-examine`; do \ @@ -27,3 +31,6 @@ compile-individually: $(EMACS) $(FLAGS) -l COMPILE \ -f mixi-compile-module $$i; \ done + +%.info: %.texi + $(EMACS) $(FLAGS) -l ./infohack.el -f batch-makeinfo $< diff --git a/infohack.el b/infohack.el new file mode 100644 index 0000000..9b4af97 --- /dev/null +++ b/infohack.el @@ -0,0 +1,177 @@ +;;; infohack.el --- a hack to format info file. +;; Copyright (C) 2001 Free Software Foundation, Inc. + +;; Author: Shenghuo Zhu +;; Keywords: info + +;; 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: + +;;; Code: + +;(let ((default-directory (expand-file-name "../lisp/")) +; (features (cons 'w3-forms (copy-sequence features)))) +; ;; Adjust `load-path' for APEL. +; (load-file "dgnushack.el")) +(load-file (expand-file-name "ptexinfmt.el" "./")) + +(defun infohack-remove-unsupported () + (goto-char (point-min)) + (while (re-search-forward "@\\(end \\)?ifnottex" nil t) + (replace-match "")) + (goto-char (point-min)) + (while (search-forward "\n@iflatex\n" nil t) + (delete-region (1+ (match-beginning 0)) + (search-forward "\n@end iflatex\n")))) + +(defun infohack (file) + (let ((dest-directory default-directory) + (max-lisp-eval-depth (max max-lisp-eval-depth 600)) + coding-system) + (find-file file) + (setq buffer-read-only nil) + (setq coding-system (if (boundp 'buffer-file-coding-system) + buffer-file-coding-system + file-coding-system)) + (infohack-remove-unsupported) + (texinfo-every-node-update) + (texinfo-format-buffer t) ;; Don't save any file. + (setq default-directory dest-directory) + (setq buffer-file-name + (expand-file-name (file-name-nondirectory buffer-file-name) + default-directory)) + (setq buffer-file-coding-system coding-system + file-coding-system coding-system) + (if (> (buffer-size) 100000) + (Info-split)) + (save-buffer))) + +(eval-and-compile + (when (string-match "windows-nt\\|os/2\\|emx\\|cygwin" + (symbol-name system-type)) + (defun subst-char-in-region (START END FROMCHAR TOCHAR &optional NOUNDO) + "From START to END, replace FROMCHAR with TOCHAR each time it occurs. +If optional arg NOUNDO is non-nil, don't record this change for undo +and don't mark the buffer as really changed. +Both characters must have the same length of multi-byte form." + (let ((original-buffer-undo-list buffer-undo-list) + (modified (buffer-modified-p))) + (if NOUNDO + (setq buffer-undo-list t)) + (goto-char START) + (let ((from (char-to-string FROMCHAR)) + (to (char-to-string TOCHAR))) + (while (search-forward from END t) + (replace-match to t t))) + (if NOUNDO + (progn (setq buffer-undo-list original-buffer-undo-list) + (set-buffer-modidifed-p modified))))))) + +(defun batch-makeinfo () + "Emacs makeinfo in batch mode." + (infohack-texi-format (car command-line-args-left) + (car (cdr command-line-args-left))) + (setq command-line-args-left nil)) + + +(defun infohack-texi-format (file &optional addsuffix) + (let ((auto-save-default nil) + (find-file-run-dired nil) + coding-system-for-write + output-coding-system + (error 0)) + (condition-case err + (progn + (find-file file) + (setq buffer-read-only nil) + (buffer-disable-undo (current-buffer)) + (if (boundp 'MULE) + (setq output-coding-system file-coding-system) + (setq coding-system-for-write buffer-file-coding-system)) + ;; Remove ignored areas first. + (while (re-search-forward "^@ignore[\t\r ]*$" nil t) + (delete-region (match-beginning 0) + (if (re-search-forward + "^@end[\t ]+ignore[\t\r ]*$" nil t) + (1+ (match-end 0)) + (point-max)))) + (infohack-remove-unsupported) + (goto-char (point-min)) + ;; Add suffix if it is needed. + (when (and addsuffix + (re-search-forward "^@setfilename[\t ]+\\([^\t\n ]+\\)" + nil t) + (not (string-match "\\.info$" (match-string 1)))) + (insert ".info") + (goto-char (point-min))) + ;; process @include before updating node + ;; This might produce some problem if we use @lowersection or + ;; such. + (let ((input-directory default-directory) + (texinfo-command-end)) + (while (re-search-forward "^@include" nil t) + (setq texinfo-command-end (point)) + (let ((filename (concat input-directory + (texinfo-parse-line-arg)))) + (re-search-backward "^@include") + (delete-region (point) (save-excursion + (forward-line 1) + (point))) + (message "Reading included file: %s" filename) + (save-excursion + (save-restriction + (narrow-to-region + (point) (+ (point) + (car (cdr (insert-file-contents filename))))) + (goto-char (point-min)) + ;; Remove `@setfilename' line from included file, + ;; if any, so @setfilename command not duplicated. + (if (re-search-forward "^@setfilename" + (save-excursion + (forward-line 100) + (point)) + t) + (progn + (beginning-of-line) + (delete-region (point) (save-excursion + (forward-line 1) + (point)))))))))) + (texinfo-mode) + (texinfo-every-node-update) + (set-buffer-modified-p nil) + (message "texinfo formatting %s..." file) + (texinfo-format-buffer nil) + (if (buffer-modified-p) + (progn (message "Saving modified %s" (buffer-file-name)) + (save-buffer)))) + (error + (message ">> Error: %s" (prin1-to-string err)) + (message ">> point at") + (let ((s (buffer-substring (point) (min (+ (point) 100) (point-max)))) + (tem 0)) + (while (setq tem (string-match "\n+" s tem)) + (setq s (concat (substring s 0 (match-beginning 0)) + "\n>> " + (substring s (match-end 0))) + tem (1+ tem))) + (message ">> %s" s)) + (setq error 1))) + (kill-emacs error))) + +;;; infohack.el ends here diff --git a/mixi-ja.texi b/mixi-ja.texi new file mode 100755 index 0000000..4de4e4f --- /dev/null +++ b/mixi-ja.texi @@ -0,0 +1,1377 @@ +\input texinfo @c -*- mode: texinfo; coding: iso-2022-jp -*- +@c %**start of header +@setfilename mixi-ja.info +@settitle mixi.el --- API libraries for accessing to mixi +@c %**end of header +@c @documentlanguage ja +@include version.texi +@c @syncodeindex pg cp +@finalout + +@dircategory GNU Emacs Lisp +@direntry +* mixi-ja: (mixi-ja). API libraries for accessing to mixi +@end direntry + +@copying +Copyright @copyright{} 2007 @w{OHASHI Akira}. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.1 or +any later version published by the Free Software Foundation; with no +Invariant Sections, with no Front-Cover Texts, and with no Back-Cover +Texts. A copy of the license is included in the section entitled "GNU +Free Documentation License". +@end quotation +@end copying + +@ifinfo +このファイルは Emacs で mixi にアクセスするための Emacs Lisp ライブラリ +mixi.el に関するマニュアルです。 + +@insertcopying +@end ifinfo + +@titlepage +@title mixi.el ユーザマニュアル +@subtitle for version @value{VERSION}, @value{UPDATED} + +@author by OHASHI Akira +@page + +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@summarycontents + +@ifnottex +@node Top +@top mixi.el ユーザマニュアル + +このマニュアルでは mixi.el バージョン @value{VERSION} について解説します。 +@end ifnottex + +@menu +* 概要:: +* 必要な物:: +* インストール:: +* 同梱されているアプリケーション:: +* mixi.el API:: +* カスタマイズ:: +* 良くある質問と答え:: +* バグレポート:: +* 概念索引:: +* 関数索引:: +* 変数索引:: +@end menu + +@node 概要 +@chapter 概要 + +mixi.el とは Emacs 上で mixi の各種情報を閲覧、または日記などの投稿を行 +なえるようにするための Emacs Lisp ライブラリです。 + +閲覧機能の基本的な動作原理は以下のようになっています。 + +@enumerate +@item +mixi へ HTTP アクセスする (必要ならログインを実行する) +@item +必要とするページを取得する +@item +取得されたページを解析する +@item +解析結果を @ref{mixi オブジェクト} に格納して返却する +@end enumerate + +@noindent +取得されたページを解析する際、正規表現を用いて日付や本文などの必要な要素 +のみを切り出します。 +この作業は mixi の出力する HTML ページの構造に強く依存しているため、mixi +側がレイアウトやデザインの変更を実施した場合は正常に動作しなくなることが +あります。 + +@node 必要な物 +@chapter 必要な物 +@cindex backend +@cindex バックエンド + +mixi.el は mixi へアクセスするために以下のライブラリ、または外部アプリケー +ションを使用します。 +必ず以下のうちのどれか一つはインストールしておかなければいけません。 + +@itemize @bullet +@item @uref{http://emacs-w3m.namazu.org/, emacs-w3m} +@item @file{url.el} (Emacs 22 以降に付属の物でないと正常に動かないかもし +れません) +@item @uref{http://curl.haxx.se/, cURL} +@end itemize + +使用するライブラリまたは外部アプリケーションのことを@dfn{バックエンド}と +呼びます。どのバックエンドを使用するかは環境を調査して自動的に決定されま +すが、@ref{mixi-backend} で変更することもできます。 + +@node インストール +@chapter インストール + +最初に、配布された mixi.el の tarball を以下のように適当な場所で展開し、 +作成された @file{mixi} ディレクトリへ移動してください。 + +@cartouche +@example +% tar zxf mixi-el-1.0.0.tar.gz +% cd mixi-el-1.0.0 +@end example +@end cartouche + +@noindent +もしあなたが mixi.el を CVS から取得したのであれば、@code{configure} +スクリプトを生成するために以下を実行する必要があります。 + +@cartouche +@example +% autoreconf -f -i +@end example +@end cartouche + +@noindent +後は以下を実行することによりインストールが完了します。 + +@cartouche +@example +% ./configure +% make +% make install (root権限が必要になるかもしれません) +@end example +@end cartouche + +@noindent +すべての Emacs Lisp ファイルと info ファイルが適切なディレクトリにイン +ストールされているはずです。 + +mixi.el には mixi.el で用意されている API を使用して実装したいくつかの +アプリケーションが同梱されています。 +これらのアプリケーションの中にはあなたが必要としない物も含まれているか +もしれません。 +また、使用している環境によっては自動で決定されるインストール先が不都合 +な場合があるかもしれません。 +これらの問題を解消するためにあなたは @code{configure} スクリプトに引数 +を与えることができます。 +使用可能な引数については以下を実行してヘルプで確認してください。 + +@cartouche +@example +% ./configure --help +@end example +@end cartouche + +@node 同梱されているアプリケーション +@chapter 同梱されているアプリケーション + +mixi.el には mixi.el で用意されている API を使用して実装したいくつかの +アプリケーションが同梱されています。この章でそれらを簡単に紹介します。 + +@table @code +@item sb-mixi.el +@uref{http://gnus.org/, Gnus}、@uref{http://www.gohome.org/wl/, +Wanderlust}、@uref{http://www.mew.org/, Mew} のような Shimbun 対応のメー +ラで mixi の記事を見ることができるようになります。 + +@item mixi-gnus.el +@itemx mixi-wl.el +Gnus と Wanderlust からそれぞれ mixi に投稿できるようになります。 + +@item riece-mixi.el +@uref{http://www.nongnu.org/riece/, Riece} に mixi の新着記事チェック +機能などを追加します。 + +@item mixi-atom.el +RSS リーダで読み込める Atom Syndication Format で mixi の記事を出力し +ます。 + +@item mixi-ticker.el +mixi の新着記事をミニバッファにティッカー表示します。 +@end table + +@node mixi.el API +@chapter mixi.el API + +この章では mixi.el で扱うデータ形式と API について解説します。 + +@menu +* mixi オブジェクト:: +* 一覧取得関数:: +* 投稿用関数:: +* その他の関数:: +@end menu + +@node mixi オブジェクト +@section mixi オブジェクト +@cindex mixi オブジェクト +@cindex オブジェクト + +mixi.el ではマイミクシィや日記、コミュニティ、トピックなどを @dfn{mixi +オブジェクト}という独自のデータ形式で管理しています。mixi.el API の各種 +取得関数ではこの mixi オブジェクト形式のリストが返却され、日記取得関数な +ど引数を取る関数を使用する際にもまた mixi オブジェクト形式で引数を与えな +ければいけません。 + +mixi オブジェクトは正確にはマイミクシィや日記などでそれぞれデータ形式が +異なります。それは各オブジェクトが持っている情報 (マイミクシィなら名前や +ニックネーム、日記ならタイトルや本文など) が異なるためです。 +mixi オブジェクトはオブジェクト指向プログラムでいうところのインスタンス +のように扱うように実装されており、そのオブジェクトが持つ情報を取得あるい +は設定するためにアクセサメソッドのように使うことができる関数が用意されて +います。 + +mixi オブジェクトは各オブジェクト専用のオブジェクト生成関数を使用して生 +成することができます。 +ただし、オブジェクトを生成しただけではまだ mixi のサイトへのアクセスは発 +生しません。これは、一覧取得関数を実行したときなどに大量のサイトアクセス +が発生して時間が掛かってしまうのを防ぐためです。 +この仕組みは GoF のデザインパターンのうちの Proxy パターン (必要になって +から作る) から発想を得ました。 + +@cartouche +@example +(setq my-friend (mixi-make-friend "XXXXX")) + @result{} friend オブジェクト (この時点ではまだサイトにはアクセスし + ていません) + +(mixi-friend-nick my-friend) + @result{} ニックネーム (このとき初めてサイトアクセスが発生します) + +(mixi-friend-name my-friend) + @result{} 名前 (上記のサイトアクセスで全情報を取得しているので、もう + サイトにはアクセスしません) +@end example +@end cartouche + +以降の小節で各 mixi オブジェクトについて解説します。 + +@subsection friend オブジェクト +@cindex friend オブジェクト + +マイミクシィを表すオブジェクトです。 +以下の関数を使用することにより friend オブジェクトを生成することができま +す。 + +@defun mixi-make-friend id +friend オブジェクトを生成します。 +引数にはマイミクシィの ID を文字列で指定してください。 +@end defun + +@subsubsection アクセサメソッド + +friend オブジェクトの各種情報を取得するためのアクセサメソッドの一覧を以 +下に解説します。 + +@defun mixi-friend-id friend +ID を返却します。 +@end defun + +@defun mixi-friend-nick friend +ニックネームを返却します。 +@end defun + +@defun mixi-friend-name friend +名前を返却します。 +@end defun + +@defun mixi-friend-sex friend +性別を返却します。 +@end defun + +@defun mixi-friend-address friend +現住所を返却します。 +@end defun + +@defun mixi-friend-age friend +年齢を返却します。 +@end defun + +@defun mixi-friend-birthday friend +誕生日を返却します。 +@end defun + +@defun mixi-friend-blood-type friend +血液型を返却します。 +@end defun + +@defun mixi-friend-birthplace friend +出身地を返却します。 +@end defun + +@defun mixi-friend-hobby friend +趣味を返却します。 +@end defun + +@defun mixi-friend-job friend +職業を返却します。 +@end defun + +@defun mixi-friend-organization friend +所属を返却します。 +@end defun + +@defun mixi-friend-profile friend +自己紹介を返却します。 +@end defun + +@subsection log オブジェクト +@cindex log オブジェクト + +足あとを表すオブジェクトです。 +このオブジェクトを直接生成することは無いと思います。 + +@subsubsection アクセサメソッド + +log オブジェクトの各種情報を取得するためのアクセサメソッドの一覧を以下に +解説します。 + +@defun mixi-log-friend log +足あとのマイミクシィを返却します。 +@end defun + +@defun mixi-log-time log +足あとの日時を返却します。 +@end defun + +@subsection diary オブジェクト +@cindex diary オブジェクト + +日記を表すオブジェクトです。 +以下の関数を使用することにより diary オブジェクトを生成することができま +す。 + +@defun mixi-make-diary owner id +diary オブジェクトを生成します。 +引数には作成者を表す friend オブジェクトと日記の ID を文字列で指定してく +ださい。 +@end defun + +@subsubsection アクセサメソッド + +diary オブジェクトの各種情報を取得するためのアクセサメソッドの一覧を以下 +に解説します。 + +@defun mixi-diary-owner diary +作成者を返却します。 +@end defun + +@defun mixi-diary-id diary +ID を返却します。 +@end defun + +@defun mixi-diary-comment-count diary +コメント数を返却します。 +@end defun + +@defun mixi-diary-time diary +時刻を返却します。 +@end defun + +@defun mixi-diary-title diary +タイトルを返却します。 +@end defun + +@defun mixi-diary-content diary +本文を返却します。 +本文には HTML タグが含まれている可能性があります。それらを取り除くために +@ref{mixi-remove-markup} を使用することができます。 +@end defun + +@subsection community オブジェクト +@cindex community オブジェクト + +コミュニティを表すオブジェクトです。 +以下の関数を使用することにより community オブジェクトを生成することがで +きます。 + +@defun mixi-make-community id +community オブジェクトを生成します。 +引数にはコミュニティの ID を文字列で指定してください。 +@end defun + +@subsubsection アクセサメソッド + +community オブジェクトの各種情報を取得するためのアクセサメソッドの一覧を +以下に解説します。 + +@defun mixi-community-id community +ID を返却します。 +@end defun + +@defun mixi-community-name community +名前を返却します。 +@end defun + +@defun mixi-community-birthday community +開設日を返却します。 +@end defun + +@defun mixi-community-owner community +管理人を返却します。 +@end defun + +@defun mixi-community-category community +カテゴリを返却します。 +@end defun + +@defun mixi-community-members community +人数を返却します。 +@end defun + +@defun mixi-community-open-level community +参加条件と公開レベルを返却します。 +@end defun + +@defun mixi-community-authority community +トピック作成の権限を返却します。 +@end defun + +@defun mixi-community-description community +説明を返却します。 +説明には HTML タグが含まれている可能性があります。それらを取り除くために +@ref{mixi-remove-markup} を使用することができます。 +@end defun + +@subsection topic オブジェクト +@cindex topic オブジェクト + +トピックを表すオブジェクトです。 +以下の関数を使用することにより topic オブジェクトを生成することができま +す。 + +@defun mixi-make-topic community id +topic オブジェクトを生成します。 +引数にはトピックが属するコミュニティを表す community オブジェクトとトピッ +クの ID を文字列で指定してください。 +@end defun + +@subsubsection アクセサメソッド + +topic オブジェクトの各種情報を取得するためのアクセサメソッドの一覧を以下 +に解説します。 + +@defun mixi-topic-community topic +属するコミュニティを返却します。 +@end defun + +@defun mixi-topic-id topic +ID を返却します。 +@end defun + +@defun mixi-topic-comment-count topic +コメント数を返却します。 +@end defun + +@defun mixi-topic-time topic +時刻を返却します。 +@end defun + +@defun mixi-topic-title topic +タイトルを返却します。 +@end defun + +@defun mixi-topic-owner topic +作成者を返却します。 +@end defun + +@defun mixi-topic-content topic +本文を返却します。 +本文には HTML タグが含まれている可能性があります。それらを取り除くために +@ref{mixi-remove-markup} を使用することができます。 +@end defun + +@subsection event オブジェクト +@cindex event オブジェクト + +イベントを表すオブジェクトです。 +以下の関数を使用することにより event オブジェクトを生成することができま +す。 + +@defun mixi-make-event community id +event オブジェクトを生成します。 +引数には属するコミュニティを表す community オブジェクトと ID を文字列形 +式で指定してください。 +@end defun + +@subsubsection アクセサメソッド + +event オブジェクトの各種情報を取得するためのアクセサメソッドの一覧を以下 +に解説します。 + +@defun mixi-event-community event +属するコミュニティを返却します。 +@end defun + +@defun mixi-event-id event +ID を返却します。 +@end defun + +@defun mixi-event-comment-count event +コメント数を返却します。 +@end defun + +@defun mixi-event-time event +時刻を返却します。 +@end defun + +@defun mixi-event-title event +タイトルを返却します。 +@end defun + +@defun mixi-event-owner event +作成者を返却します。 +@end defun + +@defun mixi-event-date event +開催日時を返却します。 +@end defun + +@defun mixi-event-place event +開催場所を返却します。 +@end defun + +@defun mixi-event-detail event +詳細を返却します。 +@end defun + +@defun mixi-event-limit event +募集期限を返却します。 +@end defun + +@defun mixi-event-members event +参加者を返却します。 +@end defun + +@subsection comment オブジェクト +@cindex comment オブジェクト + +コメントを表すオブジェクトです。 +このオブジェクトを直接生成することは無いと思います。 + +@subsubsection アクセサメソッド + +comment オブジェクトの各種情報を取得するためのアクセサメソッドの一覧を以 +下に解説します。 + +@defun mixi-comment-parent comment +属する親オブジェクト (日記/トピック/イベント) を返却します。 +@end defun + +@defun mixi-comment-owner comment +作成者を返却します。 +@end defun + +@defun mixi-comment-time comment +時刻を返却します。 +@end defun + +@defun mixi-comment-content comment +本文を返却します。 +本文には HTML タグが含まれている可能性があります。それらを取り除くために +@ref{mixi-remove-markup} を使用することができます。 +@end defun + +@subsection message オブジェクト +@cindex message オブジェクト + +メッセージを表すオブジェクトです。 +このオブジェクトを直接生成することは無いと思います。 + +@subsubsection アクセサメソッド + +message オブジェクトの各種情報を取得するためのアクセサメソッドの一覧を以 +下に解説します。 + +@defun mixi-message-id message +ID を返却します。 +@end defun + +@defun mixi-message-box message +種類を返却します。 +@table @asis +@item inbox +受信箱 +@item outbox +送信済み +@item savebox +下書き保存箱 +@item thrash +ごみ箱 +@end table +@end defun + +@defun mixi-message-owner message +作成者を返却します。 +@end defun + +@defun mixi-message-title message +タイトルを返却します。 +@end defun + +@defun mixi-message-time message +時刻を返却します。 +@end defun + +@defun mixi-message-content message +本文を返却します。 +本文には HTML タグが含まれている可能性があります。それらを取り除くために +@ref{mixi-remove-markup} を使用することができます。 +@end defun + +@subsection introduction オブジェクト +@cindex introduction オブジェクト + +紹介文を表すオブジェクトです。 +このオブジェクトを直接生成することは無いと思います。 + +@subsubsection アクセサメソッド + +introduction オブジェクトの各種情報を取得するためのアクセサメソッドの一 +覧を以下に解説します。 + +@defun mixi-introduction-parent introduction +紹介されている人を返却します。 +@end defun + +@defun mixi-introduction-owner introduction +作成者を返却します。 +@end defun + +@defun mixi-introduction-content introduction +紹介文を返却します。 +紹介文には HTML タグが含まれている可能性があります。それらを取り除くため +に @ref{mixi-remove-markup} を使用することができます。 +@end defun + +@subsection news オブジェクト +@cindex news オブジェクト + +ニュースを表すオブジェクトです。 +このオブジェクトを直接生成することは無いと思います。 + +@subsubsection アクセサメソッド + +news オブジェクトの各種情報を取得するためのアクセサメソッドの一覧を以下 +に解説します。 + +@defun mixi-news-media-id news +メディア ID を返却します。 +@end defun + +@defun mixi-news-id news +ID を返却します。 +@end defun + +@defun mixi-news-media news +メディアを返却します。 +@end defun + +@defun mixi-news-time news +日時を返却します。 +@end defun + +@defun mixi-news-title news +タイトルを返却します。 +@end defun + +@defun mixi-news-content news +本文を返却します。 +本文には HTML タグが含まれている可能性があります。それらを取り除くために +@ref{mixi-remove-markup} を使用することができます。 +@end defun + +@node 一覧取得関数 +@section 一覧取得関数 + +一覧取得関数では mixi のさまざまな情報を mixi オブジェクトのリスト形式で +取得することができます。 + +@defun mixi-get-friends &rest friend-or-range +マイミクシィ一覧を取得します。 +@var{friend-or-range} は friend オブジェクトまたは数値を指定することがで +きます。 +friend オブジェクトを指定した場合はそのオブジェクトで指定した人のマイミ +クシィ一覧を取得します。friend オブジェクトを指定しなかった場合は +@emph{自分}のマイミクシィ一覧を取得します。 +数値を指定した場合は最大でこの数のマイミクシィのみを取得します。 +friend オブジェクトと数値は同時に指定することもできます。 + +@cartouche +@example +(mixi-get-friends) + @result{} 自分のマイミクシィすべて + +(mixi-get-friends 5) + @result{} 自分のマイミクシィ最大で 5 人分のみ + +(mixi-get-friends friend) + @result{} friend さんのマイミクシィすべて + +(mixi-get-friends friend 10) + @result{} friend さんのマイミクシィ最大で 10 人分のみ +@end example +@end cartouche +@end defun + +@defun mixi-get-favorites &optional range +お気に入り一覧を取得します。 +@var{range} は数値を指定することができます。 +@var{range} を指定した場合は最大でこの数のお気に入りのみを取得します。 + +@cartouche +@example +(mixi-get-favorites) + @result{} お気に入りすべて + +(mixi-get-favorites 5) + @result{} お気に入り最大で 5 件分のみ +@end example +@end cartouche +@end defun + +@defun mixi-get-logs &optional range +足あと一覧を取得します。 +@var{range} は数値を指定することができます。 +@var{range} を指定した場合は最大でこの数の足あとのみを取得します。 + +@cartouche +@example +(mixi-get-logs) + @result{} 足あとすべて + +(mixi-get-logs 5) + @result{} 足あと最大で 5 件分のみ +@end example +@end cartouche +@end defun + +@defun mixi-get-diaries &rest friend-or-range +日記一覧を取得します。 +@var{friend-or-range} は friend オブジェクトまたは数値を指定することがで +きます。 +friend オブジェクトを指定した場合はそのオブジェクトで指定した人の日記一 +覧を取得します。friend オブジェクトを指定しなかった場合は@emph{自分}の日 +記一覧を取得します。 +数値を指定した場合は最大でこの数の日記のみを取得します。 +friend オブジェクトと数値は同時に指定することもできます。 + +@cartouche +@example +(mixi-get-diaries) + @result{} 自分の日記すべて + +(mixi-get-diaries 5) + @result{} 自分の日記最大で 5 件分のみ + +(mixi-get-diaries friend) + @result{} friend さんの日記すべて + +(mixi-get-diaries friend 10) + @result{} friend さんの日記最大で 10 件分のみ +@end example +@end cartouche +@end defun + +@defun mixi-get-new-diaries &optional range +マイミクシィ最新日記一覧を取得します。 +@var{range} は数値を指定することができます。 +@var{range} を指定した場合は最大でこの数のマイミクシィ最新日記のみを取得 +します。 + +@cartouche +@example +(mixi-get-new-diaries) + @result{} マイミクシィ最新日記すべて + +(mixi-get-new-diaries 5) + @result{} マイミクシィ最新日記最大で 5 件分のみ +@end example +@end cartouche +@end defun + +@defun mixi-search-diaries keyword &optional range +新着日記検索結果一覧を取得します。 +@var{keyword} は検索したいキーワードを指定してください。 +@var{range} は数値を指定することができます。 +@var{range} を指定した場合は最大でこの数の検索結果のみを取得します。 + +@cartouche +@example +(mixi-search-diaries "mixi.el") + @result{} @samp{mixi.el} で検索した新着日記すべて + +(mixi-search-diaries "mixi.el" 5) + @result{} @samp{mixi.el} で検索した新着日記最大で 5 件分 +@end example +@end cartouche +@end defun + +@defun mixi-get-communities &rest friend-or-range +コミュニティ一覧を取得します。 +@var{friend-or-range} は friend オブジェクトまたは数値を指定することがで +きます。 +friend オブジェクトを指定した場合はそのオブジェクトで指定した人のコミュ +ニティ一覧を取得します。friend オブジェクトを指定しなかった場合は +@emph{自分}のコミュニティ一覧を取得します。 +数値を指定した場合は最大でこの数のコミュニティのみを取得します。 +friend オブジェクトと数値は同時に指定することもできます。 + +@cartouche +@example +(mixi-get-communities) + @result{} 自分のコミュニティすべて + +(mixi-get-communities 5) + @result{} 自分のコミュニティ最大で 5 件分のみ + +(mixi-get-communities friend) + @result{} friend さんのコミュニティすべて + +(mixi-get-communities friend 10) + @result{} friend さんのコミュニティ最大で 10 件分のみ +@end example +@end cartouche +@end defun + +@defun mixi-search-communities keyword &optional range +コミュニティ検索結果一覧を取得します。 +@var{keyword} は検索したいキーワードを指定してください。 +@var{range} は数値を指定することができます。 +@var{range} を指定した場合は最大でこの数の検索結果のみを取得します。 + +@cartouche +@example +(mixi-search-communities "mixi.el") + @result{} @samp{mixi.el} で検索したコミュニティすべて + +(mixi-search-communities "mixi.el" 5) + @result{} @samp{mixi.el} で検索したコミュニティ最大で 5 件分 +@end example +@end cartouche +@end defun + +@defun mixi-get-bbses community &optional range +掲示板 (トピック/イベント) 一覧を取得します。 +@var{community} は community オブジェクトを指定してください。 +@var{range} は数値を指定することができます。 +@var{range} を指定した場合は最大でこの数の掲示板のみを取得します。 + +@cartouche +@example +(mixi-get-bbses community) + @result{} community の掲示板すべて + +(mixi-get-bbses community 5) + @result{} community の掲示板最大で 5 件分のみ +@end example +@end cartouche +@end defun + +@defun mixi-get-new-bbses &optional range +コミュニティ最新書き込み一覧を取得します。 +@var{range} は数値を指定することができます。 +@var{range} を指定した場合は最大でこの数の書き込みのみを取得します。 + +@cartouche +@example +(mixi-get-new-bbses) + @result{} コミュニティ最新書き込みすべて + +(mixi-get-new-bbses 5) + @result{} コミュニティ最新書き込み最大で 5 件分のみ +@end example +@end cartouche +@end defun + +@defun mixi-search-bbses keyword &optional range +掲示板検索結果一覧を取得します。 +@var{keyword} は検索したいキーワードを指定してください。 +@var{range} は数値を指定することができます。 +@var{range} を指定した場合は最大でこの数の検索結果のみを取得します。 + +@cartouche +@example +(mixi-search-bbses "mixi.el") + @result{} @samp{mixi.el} で検索した掲示板すべて + +(mixi-search-bbses "mixi.el" 5) + @result{} @samp{mixi.el} で検索した掲示板最大で 5 件分 +@end example +@end cartouche +@end defun + +@defun mixi-get-comments parent &optional range +コメント一覧を取得します。 +@var{parent} は以下のいずれかを指定してください。 +@itemize @bullet +@item diary オブジェクト +@item topic オブジェクト +@item event オブジェクト +@end itemize +@var{range} は数値を指定することができます。 +@var{range} を指定した場合は最大でこの数のコメントのみを取得します。 + +@cartouche +@example +(mixi-get-comments diary) + @result{} diary のコメント日記すべて + +(mixi-get-comments topic) + @result{} topic のコメント最大で 5 件分のみ +@end example +@end cartouche +@end defun + +@defun mixi-get-new-comments &optional range +日記コメント記入履歴一覧を取得します。 +@var{range} は数値を指定することができます。 +@var{range} を指定した場合は最大でこの数の日記のみを取得します。 + +@cartouche +@example +(mixi-get-new-comments) + @result{} 日記コメント記入履歴すべて + +(mixi-get-new-comments 5) + @result{} 日記コメント記入履歴最大で 5 件分のみ +@end example +@end cartouche +@end defun + +@defun mixi-get-new-bbs-comments &optional range +コミュニティコメント記入履歴一覧を取得します。 +@var{range} は数値を指定することができます。 +@var{range} を指定した場合は最大でこの数の書き込みのみを取得します。 + +@cartouche +@example +(mixi-get-new-bbs-comments) + @result{} コミュニティコメント記入履歴すべて + +(mixi-get-new-bbs-comments 5) + @result{} コミュニティコメント記入履歴最大で 5 件分のみ +@end example +@end cartouche +@end defun + +@defun mixi-get-messages &rest box-or-range +メッセージ一覧を取得します。 +@var{box-or-range} はメッセージの種類を表す以下のいずれかまたは数値を指 +定することができます。 +@table @asis +@item inbox +受信箱 +@item outbox +送信済み +@item savebox +下書き保存箱 +@item thrash +ごみ箱 +@end table +メッセージの種類を指定した場合は指定したメッセージ一覧を取得します。メッ +セージの種類を指定しなかった場合は@emph{受信箱}のメッセージ一覧を取得し +ます。 +数値を指定した場合は最大でこの数のメッセージのみを取得します。 +メッセージの種類と数値は同時に指定することもできます。 + +@cartouche +@example +(mixi-get-messages) + @result{} 受信箱のメッセージすべて + +(mixi-get-messages 'outbox) + @result{} 送信済みのメッセージすべて + +(mixi-get-messages 'savebox 5) + @result{} 下書き保存箱のメッセージ最大で 5 件分のみ +@end example +@end cartouche +@end defun + +@defun mixi-get-introductions &rest friend-or-range +紹介文一覧を取得します。 +@var{friend-or-range} は friend オブジェクトまたは数値を指定することがで +きます。 +friend オブジェクトを指定した場合はそのオブジェクトで指定したマイミクシィ +の紹介文一覧を取得します。friend オブジェクトを指定しなかった場合は +@emph{自分}の紹介文一覧を取得します。 +数値を指定した場合は最大でこの数の紹介文のみを取得します。 +friend オブジェクトと数値は同時に指定することもできます。 + +@cartouche +@example +(mixi-get-introductions) + @result{} 自分の紹介文すべて + +(mixi-get-introductions 5) + @result{} 自分の紹介文最大で 5 人分のみ + +(mixi-get-introductions friend) + @result{} friend さんの紹介文すべて + +(mixi-get-introductions friend 10) + @result{} friend さんの紹介文最大で 10 人分のみ +@end example +@end cartouche +@end defun + +@defun mixi-get-news category sort &optional range +ニュース一覧を取得します。 +@var{category} はカテゴリを表す以下のいずれかを指定してください。 +@table @asis +@item domestic +国内 +@item politics +政治 +@item economy +経済 +@item area +地域 +@item abroad +海外 +@item sports +スポーツ +@item entertainment +エンターテインメント +@item IT +IT・テクノロジー +@end table +@var{sort} は種類を表す以下のいずれかを指定してください。 +@table @asis +@item newest +最新のニュース +@item pickup +注目のニュース +@end table +@var{range} は数値を指定することができます。 +@var{range} を指定した場合は最大でこの数のニュースのみを取得します。 + +@cartouche +@example +(mixi-get-news 'domestic 'newest) + @result{} 国内の最新ニュースすべて + +(mixi-get-introductions 'politics 'pickup 5) + @result{} 政治の注目ニュース最大で 5 件分のみ +@end example +@end cartouche +@end defun + +@node 投稿用関数 +@section 投稿用関数 + +投稿用関数を使用することにより日記の作成やコメントの投稿などが行なえます。 + +@defun mixi-post-diary title content +日記を投稿します。 +引数にはタイトルと本文を指定してください。 + +@cartouche +@example +(mixi-post-diary "タイトル" "本文") + @result{} 不定 +@end example +@end cartouche +@end defun + +@defun mixi-post-topic community title content +トピックを投稿します。 +引数には投稿するコミュニティを表す community オブジェクトとタイトル、本 +文を指定してください。 + +@cartouche +@example +(mixi-post-topic community "タイトル" "本文") + @result{} 不定 +@end example +@end cartouche +@end defun + +@defun mixi-post-comment parent content +コメントを投稿します。 +引数には投稿する親オブジェクト (日記/トピック/イベント) と本文を指定して +ください。 + +@cartouche +@example +(mixi-post-comment diary "本文") + @result{} 不定 +@end example +@end cartouche +@end defun + +@defun mixi-post-message friend title content +メッセージを送信します。 +引数には送信相手を表す friend オブジェクトとタイトル、本文を指定してくだ +さい。 + +@cartouche +@example +(mixi-post-message friend "タイトル" "本文") + @result{} 不定 +@end example +@end cartouche +@end defun + +@node その他の関数 +@section その他の関数 + +@defun mixi-login &optional email password +mixi にログインします。 +@var{email} と @var{password} が指定されていた場合はそれらの値をログイン +時の E-mail とパスワードとして使用します。 +指定されていなかった場合は @ref{mixi-default-email} と +@ref{mixi-default-password} の値を使用します。 +これらの値も指定されていなかった場合は、対話的に入力が求められます。 + +@cartouche +@example +(mixi-login) + @result{} 自分を表す friend オブジェクト +@end example +@end cartouche + +各種情報取得関数を実行した際、もし mixi にログインしていなかった場合は自 +動的に @code{mixi-login} が実行されるので、明示的にログイン関数を実行す +る必要はありません。 +@end defun + +@defun mixi-logout +mixi からログアウトします。 + +@cartouche +@example +(mixi-logout) + @result{} 不定 +@end example +@end cartouche +@end defun + +@anchor{mixi-remove-markup} +@defun mixi-remove-markup string + +diary オブジェクトの本文などは HTML タグが含まれたままの状態で取得されま +す。この関数を使用することにより、それらの文字列から HTML タグを取り除く +ことができます。@footnote{ただし、現在この関数は正常にすべてのタグを取り +除くことができません。} + +@cartouche +@example +(mixi-remove-markup (mixi-diary-content diary)) + @result{} タグ取り除き済み文字列 +@end example +@end cartouche +@end defun + +@node カスタマイズ +@chapter カスタマイズ +@cindex ユーザオプション + +mixi.el にはユーザが動作をカスタマイズするためのいくつかの変数が用意され +ています。単一のオプションを指定してカスタマイズするためには @kbd{M-x +customize-option} を、グループ (mixi.el の場合のグループは @code{mixi}) +に属するすべてのオプションを変更するためには @kbd{M-x customize-group} +を使用することができます。 + +@section ユーザオプション一覧 + +@defopt mixi-url +mixi のサイトの URL を指定します。 +@end defopt + +@defopt mixi-directory +キャッシュファイルやクッキーなどを格納するためのディレクトリを指定します。 +@end defopt + +@defopt mixi-coding-system +mixi の web ページで使用されているコーディングシステムを指定します。 +@end defopt + +@defopt mixi-curl-program +バックエンドとして @code{curl} を使う場合の起動するプログラム名を指定し +ます。 +@end defopt + +@defopt mixi-curl-cookie-file +バックエンドとして @code{curl} を使う場合のクッキーファイルを指定します。 +@end defopt + +@anchor{mixi-backend} +@defopt mixi-backend +使用するバックエンドを指定します。 + +@table @asis +@item w3m +Emacs Lisp プログラム @code{emacs-w3m} を使用します。 +@item url +Emacs に同梱されている @file{url.el} を使用します。 +@item curl +外部プログラム @code{curl} を使用します。 +@end table + +バックエンドを明示的に指定しなかった場合は上記表の上から順番に自動的に決 +定されます。 +@end defopt + +@anchor{mixi-login-use-ssl} +@defopt mixi-login-use-ssl +mixi にログインする際に SSL を使用するかどうかを指定します。 +SSL を使用する場合は、バックエンドが @code{url} のときは外部プログラムと +して @code{gnutls-cli} あるいは @code{openssl} コマンドが必要になり、バッ +クエンドが @code{w3m} のときは @option{-with-ssl} でコンパイルされた +@code{w3m} コマンドが必要になります。 +@end defopt + +@anchor{mixi-default-email} +@defopt mixi-default-email +mixi にログインする必要が出た場合に使用するメールアドレスを指定します。 +この値を指定していない場合は、対話的に入力が求められます。 +@end defopt + +@anchor{mixi-default-password} +@defopt mixi-default-password +mixi にログインする必要が出た場合に使用するパスワードを指定します。 +この値を指定していない場合は、対話的に入力が求められます。 +@end defopt + +@defopt mixi-accept-adult-contents +アダルトカテゴリのコミュニティを閲覧しても問題ないかどうかを指定します。 +@end defopt + +@defopt mixi-continuously-access-interval +mixi のサイトは自動ツールなどで短時間に連続してアクセスした場合、その接 +続を拒否する旨のメッセージを表示します。 +接続を拒否された場合に待機する@emph{秒数}を指定します。 +@end defopt + +@defopt mixi-cache-expires +mixi オブジェクトのキャッシュの有効期限を指定します。 + +@table @asis +@item 数値 +有効期限を指定した数値秒に設定します。 +@item t +常に期限切れとして扱います。 +@item nil +常に期限が切れていない物として扱います。 +@end table +@end defopt + +@defopt mixi-cache-use-file +mixi オブジェクトのキャッシュをファイルとして保存するかどうかを指定しま +す。@footnote{ただし、現在この機能は実装されていません。} +@end defopt + +@node 良くある質問と答え +@chapter 良くある質問と答え +@cindex FAQ +@cindex Tips + +この章ではよく聞かれる質問に対する答えと便利な設定例を紹介します。 + +@section Cannot retrieve というエラーが出ます + +なんらかの原因により mixi のサイトに接続できなかった場合、以下のようなエ +ラーが発生することがあるかもしれません。 + +@example +mixi-url-retrieve: [mixi] Cannot retrieve: http://@dots{} +@end example + +@noindent +そのような場合は以下を確認してみてください。 + +@itemize +@item 通信回線に異常がないかどうか +@item mixi のサイトがメンテ中あるいはダウンしていないかどうか +@item 使用しているバックエンドでエラーで示されたページにアクセスできるか +どうか +@end itemize + +@section セキュリティが心配なので SSL でログインしたいのですが + +@ref{mixi-login-use-ssl} を @code{t} に設定することで SSL でログインする +ように設定できます。 + +@node バグレポート +@chapter バグレポート + +mixi.el を使用していると予期せぬエラーが表示されたり、あるいはあなたの期 +待した動作をしないことがあるかもしれません。mixi.el を最新版にしてもなお +問題が解消されない場合、それは mixi.el の不具合の可能性があります。 + +@section エラーが表示される場合 + +エラーが表示される場合はバックトレースを取得してデバッグにご協力ください。 +バックトレースの取得方法は以下の URL が参考になります。 + +@uref{http://www.jpl.org/elips/BUGS-ja.html, +プログラムの作者にバグを知らせる方法 (初心者向け)} + +バックトレースが取得できたらそれをなんらかの方法で作者に届ける必要があり +ますが、残念なことに mixi のメッセージはファイルの添付ができません。 +メール、どこかのアップローダ、Web サイト、FTP サイト、手段はなんでも構い +ませんので、なんらかの方法で作者までそれを届けてください。 +さらに、同じ不具合で困っている人が他にもいるかもしれませんので、エラーの +内容を +@uref{http://mixi.jp/view_community.pl?id=1596390, mixi.el コミュニティ} +内の@emph{不具合報告}トピックへも投稿してください。 + +なお、バックトレース内には表示しようとしていた mixi ページの内容が含まれ +ています。できるだけプライバシー上問題ないと判断される再現手順でのバック +トレース取得をお願いします。下手に内容を改ざんされますとデバッグに支障を来 +たす可能性がありますのでご注意ください。 + +@section 期待した動作をしない場合 + +仕様か不具合かは分からないけれど期待した動作をしない場合、最低限以下の内 +容をできるだけ詳細で具体的に +@uref{http://mixi.jp/view_community.pl?id=1596390, mixi.el コミュニティ} +内の@emph{不具合報告}トピックへ投稿してください。 + +@itemize @bullet +@item どういう動作を期待して +@item どういう操作を行なったが +@item どういう結果が得られた +@end itemize + +@section 不具合対応におけるお願い + +不具合の報告を受けたらできるだけ早急に確認したいとは思いますが、平日昼間 +の仕事をしている間や、休日遊びに行っている間などは対応が遅れることがあり +ます。さらに、24 時間自分の自由に触れる PC の前にいるわけでもありません。 +ですので「不具合報告トピックに投稿したのにまったく反応が無い」などと言っ +た理由で足あとをつけまくって粘着したり、メッセージを送ってきたりしないで +ください。 + +さらに、私は mixi.el と Gnus を常時起動したままにして mixi に自動でアク +セスしています。 +最終ログインが 5 分以内などとなっていても PC の前にいるとは限りませんの +で「mixi 見てるのにまったく反応が無い」などと言った理由で足あとをつけま +くって粘着したり、メッセージを送ってきたりしないでください。 + +@node 概念索引 +@unnumbered 概念索引 +@printindex cp + +@node 関数索引 +@unnumbered 関数索引 +@printindex fn + +@node 変数索引 +@unnumbered 変数索引 +@printindex vr + +@contents + +@bye + +@c Local Variables: +@c fill-column: 72 +@c End: diff --git a/ptexinfmt.el b/ptexinfmt.el new file mode 100644 index 0000000..4904f03 --- /dev/null +++ b/ptexinfmt.el @@ -0,0 +1,1025 @@ +;;; 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 '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 "幅広文字")) + (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)))))) + + +;; @copying ... @end copying +;; that Emacs 21.4 and lesser and XEmacs don't support. +(if (fboundp 'texinfo-copying) + nil + (defvar texinfo-copying-text "" + "Text of the copyright notice and copying permissions.") + + (defun texinfo-copying () + "Copy the copyright notice and copying permissions from the Texinfo file, +as indicated by the @copying ... @end copying command; +insert the text with the @insertcopying command." + (let ((beg (progn (beginning-of-line) (point))) + (end (progn (re-search-forward "^@end copying[ \t]*\n") (point)))) + (setq texinfo-copying-text + (buffer-substring-no-properties + (save-excursion (goto-char beg) (forward-line 1) (point)) + (save-excursion (goto-char end) (forward-line -1) (point)))) + (delete-region beg end))) + + (defun texinfo-insertcopying () + "Insert the copyright notice and copying permissions from the Texinfo file, +which are indicated by the @copying ... @end copying command." + (insert (concat "\n" texinfo-copying-text))) + + (defadvice texinfo-format-scan (before expand-@copying-section activate) + "Extract @copying and replace @insertcopying with it." + (goto-char (point-min)) + (when (search-forward "@copying" nil t) + (texinfo-copying)) + (while (search-forward "@insertcopying" nil t) + (delete-region (match-beginning 0) (match-end 0)) + (texinfo-insertcopying)))) + +(provide 'ptexinfmt) + +;;; ptexinfmt.el ends here -- 1.7.10.4