Synch with No Gnus (201101241956).
[elisp/gnus-doc-ja.git] / infohack.el
1 ;;; infohack.el --- a hack to format info file.
2 ;; Copyright (C)  2001, 2003, 2004, 2008, 2009  Free Software Foundation, Inc.
3
4 ;; Author: Shenghuo Zhu <zsh@cs.rochester.edu>
5 ;; Keywords: info
6
7 ;; This file is part of GNU Emacs.
8
9 ;; GNU Emacs is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; any later version.
13
14 ;; GNU Emacs is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
21 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 ;; Boston, MA 02110-1301, USA.
23
24 ;;; Commentary:
25
26 ;;; Code:
27
28 (load-file (expand-file-name "ptexinfmt.el" "./"))
29
30 (defun infohack-remove-unsupported ()
31   (goto-char (point-min))
32   (while (re-search-forward "@\\(end \\)?ifnottex" nil t) 
33     (replace-match ""))
34   (goto-char (point-min))
35   (while (search-forward "\n@iflatex\n" nil t)
36     (delete-region (1+ (match-beginning 0))
37                    (search-forward "\n@end iflatex\n"))))
38
39 (defun infohack-include-files ()
40   "Insert @include files."
41   (goto-char (point-min))
42   (set-syntax-table texinfo-format-syntax-table)
43   (let (start texinfo-command-end filename)
44     (while (re-search-forward "^@include" nil t)
45       (setq start (match-beginning 0)
46             texinfo-command-end (point)
47             filename (texinfo-parse-line-arg))
48       (delete-region start (point-at-bol 2))
49       (message "Reading included file: %s" filename)
50       (save-excursion
51         (save-restriction
52           (narrow-to-region
53            (point)
54            (+ (point) (car (cdr (insert-file-contents filename)))))
55           (goto-char (point-min))
56           ;; Remove `@setfilename' line from included file, if any,
57           ;; so @setfilename command not duplicated.
58           (if (re-search-forward "^@setfilename" (point-at-eol 100) t)
59               (delete-region (point-at-bol 1)
60                              (point-at-bol 2))))))))
61
62 (defun infohack (file)
63   (let ((dest-directory default-directory)
64         (max-lisp-eval-depth (max max-lisp-eval-depth 600))
65         coding-system)
66     ;; Emacs 21.3 doesn't support @documentencoding
67     (unless (get 'documentencoding 'texinfo-format)
68       (put 'documentencoding 'texinfo-format 
69            'texinfo-discard-line-with-args))
70     (find-file file)
71     (setq buffer-read-only nil)
72     (setq coding-system buffer-file-coding-system)
73     (infohack-remove-unsupported)
74     (infohack-include-files)
75     (texinfo-every-node-update) 
76     (texinfo-format-buffer t) ;; Don't save any file.
77     (setq default-directory dest-directory)
78     (setq buffer-file-name 
79           (expand-file-name (file-name-nondirectory buffer-file-name)
80                             default-directory))
81     (setq buffer-file-coding-system coding-system)
82     (if (> (buffer-size) (if (boundp 'Info-split-threshold)
83                              (+ 50000 Info-split-threshold)
84                            100000))
85         (Info-split))
86     (save-buffer)))
87
88 (eval-and-compile
89   (when (string-match "windows-nt\\|os/2\\|emx\\|cygwin"
90                       (symbol-name system-type))
91     (defun subst-char-in-region (START END FROMCHAR TOCHAR &optional NOUNDO)
92       "From START to END, replace FROMCHAR with TOCHAR each time it occurs.
93 If optional arg NOUNDO is non-nil, don't record this change for undo
94 and don't mark the buffer as really changed.
95 Both characters must have the same length of multi-byte form."
96       (let ((original-buffer-undo-list buffer-undo-list)
97             (modified (buffer-modified-p)))
98         (if NOUNDO
99             (setq buffer-undo-list t))
100         (goto-char START)
101         (let ((from (char-to-string FROMCHAR))
102               (to (char-to-string TOCHAR)))
103           (while (search-forward from END t)
104             (replace-match to t t)))
105         (if NOUNDO
106             (progn (setq buffer-undo-list original-buffer-undo-list)
107                    (set-buffer-modidifed-p modified)))))))
108
109 (defun batch-makeinfo ()
110   "Emacs makeinfo in batch mode."
111   (infohack-texi-format (car command-line-args-left)
112                         (car (cdr command-line-args-left)))
113   (setq command-line-args-left nil))
114
115 \f
116 (require 'bytecomp)
117
118 ;; Reduce the number of split Info files.
119 (unless (boundp 'Info-split-threshold)
120   (if (featurep 'xemacs)
121       (if (load "informat.el" t t)
122           (let* ((fn (symbol-function 'Info-split))
123                  (fns (prin1-to-string fn)))
124             (load "informat.elc" t t)
125             (when (and (string-match "\\([\t\n ]+\\)50000\\([\t\n )]+\\)" fns)
126                        (condition-case nil
127                            (setq fn (byte-compile
128                                      (read (replace-match "\\1262144\\2"
129                                                           nil nil fns))))
130                          (error nil))
131                        (fset 'Info-split fn)))))
132     (require 'informat)
133     (let* ((fn (symbol-function 'Info-split))
134            (fns (prin1-to-string fn)))
135       (when (string-match "\\([\t\n ]+\\)50000\\([\t\n ]+\\)" fns)
136         (condition-case nil
137             (fset 'Info-split (read (replace-match "\\1262144\\2"
138                                                    nil nil fns)))
139           (error
140            (fset 'Info-split fn)))))))
141
142 (defun infohack-texi-format (file &optional addsuffix)
143   (let ((auto-save-default nil)
144         (find-file-run-dired nil)
145         (coding-system-for-read (if (featurep 'xemacs)
146                                     'iso-2022-7bit
147                                   coding-system-for-read))
148         coding-system-for-write
149         (error 0))
150     (condition-case err
151         (progn
152           (find-file file)
153           (setq buffer-read-only nil)
154           (buffer-disable-undo (current-buffer))
155           (setq coding-system-for-write buffer-file-coding-system)
156           ;; Remove ignored areas.
157           (goto-char (point-min))
158           (while (re-search-forward "^@ignore[\t\r ]*$" nil t)
159             (delete-region (match-beginning 0)
160                            (if (re-search-forward
161                                 "^@end[\t ]+ignore[\t\r ]*$" nil t)
162                                (1+ (match-end 0))
163                              (point-max))))
164           ;; Remove unsupported commands.
165           (infohack-remove-unsupported)
166           ;; Add suffix if it is needed.
167           (goto-char (point-min))
168           (when (and addsuffix
169                      (re-search-forward "^@setfilename[\t ]+\\([^\t\n ]+\\)"
170                                         nil t)
171                      (not (string-match "\\.info$" (match-string 1))))
172             (insert ".info"))
173           (infohack-include-files)
174           (texinfo-every-node-update)
175           (set-buffer-modified-p nil)
176           (message "texinfo formatting %s..." file)
177           (let ((si:message (symbol-function 'message))
178                 (coding (or (and (string-match "\\`Japanese"
179                                                current-language-environment)
180                                  (boundp 'locale-coding-system)
181                                  locale-coding-system)
182                             'iso-2022-7bit)))
183             ;; Encode messages to terminal.
184             (fset
185              'message
186              (byte-compile
187               (if (featurep 'xemacs)
188                   `(lambda (fmt &rest args)
189                      (unless (and (string-equal fmt "%s clean")
190                                   (equal (car args) buffer-file-name))
191                        (funcall ,si:message "%s"
192                                 (encode-coding-string (apply 'format fmt args)
193                                                       ',coding))))
194                 `(lambda (fmt &rest args)
195                    (funcall ,si:message "%s"
196                             (encode-coding-string (apply 'format fmt args)
197                                                   ',coding))))))
198             (unwind-protect
199                 (texinfo-format-buffer nil)
200               (fset 'message si:message)))
201           (if (buffer-modified-p)
202               (progn (message "Saving modified %s" (buffer-file-name))
203                      (save-buffer))))
204       (error
205        (message ">> Error: %s" (prin1-to-string err))
206        (message ">>  point at")
207        (let ((s (buffer-substring (point) (min (+ (point) 100) (point-max))))
208              (tem 0))
209          (while (setq tem (string-match "\n+" s tem))
210            (setq s (concat (substring s 0 (match-beginning 0))
211                            "\n>>  "
212                            (substring s (match-end 0)))
213                  tem (1+ tem)))
214          (message ">>  %s" s))
215        (setq error 1)))
216     (kill-emacs error)))
217
218 ;;; infohack.el ends here