| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 25 |
|
|---|
| 26 |
|
|---|
| 27 |
|
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 |
|
|---|
| 31 |
|
|---|
| 32 |
|
|---|
| 33 |
|
|---|
| 34 |
|
|---|
| 35 |
|
|---|
| 36 |
|
|---|
| 37 |
|
|---|
| 38 |
|
|---|
| 39 |
|
|---|
| 40 |
|
|---|
| 41 |
|
|---|
| 42 |
|
|---|
| 43 |
|
|---|
| 44 |
|
|---|
| 45 |
|
|---|
| 46 |
|
|---|
| 47 |
|
|---|
| 48 |
|
|---|
| 49 |
|
|---|
| 50 |
(require 'compile) |
|---|
| 51 |
(require 'info) |
|---|
| 52 |
|
|---|
| 53 |
(defvar tex-end-of-header) |
|---|
| 54 |
(defvar tex-start-of-header) |
|---|
| 55 |
|
|---|
| 56 |
|
|---|
| 57 |
(defgroup makeinfo nil |
|---|
| 58 |
"Run makeinfo conveniently." |
|---|
| 59 |
:group 'docs) |
|---|
| 60 |
|
|---|
| 61 |
|
|---|
| 62 |
(defcustom makeinfo-run-command "makeinfo" |
|---|
| 63 |
"*Command used to run `makeinfo' subjob. |
|---|
| 64 |
The name of the file is appended to this string, separated by a space." |
|---|
| 65 |
:type 'string |
|---|
| 66 |
:group 'makeinfo) |
|---|
| 67 |
|
|---|
| 68 |
(defcustom makeinfo-options "--fill-column=70" |
|---|
| 69 |
"*String containing options for running `makeinfo'. |
|---|
| 70 |
Do not include `--footnote-style' or `--paragraph-indent'; |
|---|
| 71 |
the proper way to specify those is with the Texinfo commands |
|---|
| 72 |
`@footnotestyle` and `@paragraphindent'." |
|---|
| 73 |
:type 'string |
|---|
| 74 |
:group 'makeinfo) |
|---|
| 75 |
|
|---|
| 76 |
(require 'texinfo) |
|---|
| 77 |
|
|---|
| 78 |
(defvar makeinfo-compilation-process nil |
|---|
| 79 |
"Process that runs `makeinfo'. Should start out nil.") |
|---|
| 80 |
|
|---|
| 81 |
(defvar makeinfo-temp-file nil |
|---|
| 82 |
"Temporary file name used for text being sent as input to `makeinfo'.") |
|---|
| 83 |
|
|---|
| 84 |
(defvar makeinfo-output-file-name nil |
|---|
| 85 |
"Info file name used for text output by `makeinfo'.") |
|---|
| 86 |
|
|---|
| 87 |
(defvar makeinfo-output-node-name nil |
|---|
| 88 |
"Node name to visit in output file, for `makeinfo-buffer'.") |
|---|
| 89 |
|
|---|
| 90 |
|
|---|
| 91 |
|
|---|
| 92 |
|
|---|
| 93 |
(defun makeinfo-region (region-beginning region-end) |
|---|
| 94 |
"Make Info file from region of current Texinfo file, and switch to it. |
|---|
| 95 |
|
|---|
| 96 |
This command does not offer the `next-error' feature since it would |
|---|
| 97 |
apply to a temporary file, not the original; use the `makeinfo-buffer' |
|---|
| 98 |
command to gain use of `next-error'." |
|---|
| 99 |
|
|---|
| 100 |
(interactive "r") |
|---|
| 101 |
(let (filename-or-header |
|---|
| 102 |
filename-or-header-beginning |
|---|
| 103 |
filename-or-header-end) |
|---|
| 104 |
|
|---|
| 105 |
|
|---|
| 106 |
|
|---|
| 107 |
|
|---|
| 108 |
(setq makeinfo-temp-file |
|---|
| 109 |
(concat |
|---|
| 110 |
(make-temp-file |
|---|
| 111 |
(substring (buffer-file-name) |
|---|
| 112 |
0 |
|---|
| 113 |
(or (string-match "\\.tex" (buffer-file-name)) |
|---|
| 114 |
(length (buffer-file-name))))) |
|---|
| 115 |
".texinfo")) |
|---|
| 116 |
|
|---|
| 117 |
(save-excursion |
|---|
| 118 |
(save-restriction |
|---|
| 119 |
(widen) |
|---|
| 120 |
(goto-char (point-min)) |
|---|
| 121 |
(let ((search-end (save-excursion (forward-line 100) (point)))) |
|---|
| 122 |
|
|---|
| 123 |
|
|---|
| 124 |
(if (re-search-forward |
|---|
| 125 |
"^@setfilename[ \t]+\\([^ \t\n]+\\)[ \t]*" |
|---|
| 126 |
search-end t) |
|---|
| 127 |
(setq makeinfo-output-file-name |
|---|
| 128 |
(buffer-substring (match-beginning 1) (match-end 1))) |
|---|
| 129 |
(error |
|---|
| 130 |
"The texinfo file needs a line saying: @setfilename <name>")) |
|---|
| 131 |
|
|---|
| 132 |
|
|---|
| 133 |
(goto-char (point-min)) |
|---|
| 134 |
(if (and |
|---|
| 135 |
(prog1 |
|---|
| 136 |
(search-forward tex-start-of-header search-end t) |
|---|
| 137 |
(beginning-of-line) |
|---|
| 138 |
|
|---|
| 139 |
(setq filename-or-header-beginning (point))) |
|---|
| 140 |
(prog1 |
|---|
| 141 |
(search-forward tex-end-of-header nil t) |
|---|
| 142 |
(beginning-of-line) |
|---|
| 143 |
|
|---|
| 144 |
(setq filename-or-header-end (point)))) |
|---|
| 145 |
|
|---|
| 146 |
|
|---|
| 147 |
(write-region |
|---|
| 148 |
(min filename-or-header-beginning region-beginning) |
|---|
| 149 |
filename-or-header-end |
|---|
| 150 |
makeinfo-temp-file nil nil) |
|---|
| 151 |
|
|---|
| 152 |
|
|---|
| 153 |
(goto-char (point-min)) |
|---|
| 154 |
(search-forward "@setfilename" search-end t) |
|---|
| 155 |
(beginning-of-line) |
|---|
| 156 |
(setq filename-or-header-beginning (point)) |
|---|
| 157 |
(forward-line 1) |
|---|
| 158 |
(setq filename-or-header-end (point)) |
|---|
| 159 |
(write-region |
|---|
| 160 |
(min filename-or-header-beginning region-beginning) |
|---|
| 161 |
filename-or-header-end |
|---|
| 162 |
makeinfo-temp-file nil nil)) |
|---|
| 163 |
|
|---|
| 164 |
|
|---|
| 165 |
(write-region |
|---|
| 166 |
(max region-beginning filename-or-header-end) |
|---|
| 167 |
region-end |
|---|
| 168 |
makeinfo-temp-file t nil) |
|---|
| 169 |
|
|---|
| 170 |
|
|---|
| 171 |
(save-excursion |
|---|
| 172 |
(makeinfo-compile |
|---|
| 173 |
(concat makeinfo-run-command |
|---|
| 174 |
" " |
|---|
| 175 |
makeinfo-options |
|---|
| 176 |
" " |
|---|
| 177 |
makeinfo-temp-file) |
|---|
| 178 |
t |
|---|
| 179 |
'makeinfo-compilation-sentinel-region))))))) |
|---|
| 180 |
|
|---|
| 181 |
(defun makeinfo-next-error (arg reset) |
|---|
| 182 |
"This function is used to disable `next-error' if the user has |
|---|
| 183 |
used `makeinfo-region'. Since the compilation process is used on |
|---|
| 184 |
a temporary file in that case, calling `next-error' would give |
|---|
| 185 |
nonsensical results." |
|---|
| 186 |
(error "Use `makeinfo-buffer' to gain use of the `next-error' command")) |
|---|
| 187 |
|
|---|
| 188 |
|
|---|
| 189 |
|
|---|
| 190 |
|
|---|
| 191 |
|
|---|
| 192 |
(defun makeinfo-compile (command disable-errors sentinel) |
|---|
| 193 |
(let ((buffer (compilation-start command))) |
|---|
| 194 |
(with-current-buffer buffer |
|---|
| 195 |
(setq next-error-function |
|---|
| 196 |
(if disable-errors |
|---|
| 197 |
'makeinfo-next-error |
|---|
| 198 |
'compilation-next-error-function))) |
|---|
| 199 |
(set-process-sentinel (get-buffer-process buffer) sentinel))) |
|---|
| 200 |
|
|---|
| 201 |
|
|---|
| 202 |
|
|---|
| 203 |
|
|---|
| 204 |
|
|---|
| 205 |
(defun makeinfo-compilation-sentinel-region (proc msg) |
|---|
| 206 |
"Sentinel for `makeinfo-compile' run from `makeinfo-region'." |
|---|
| 207 |
(compilation-sentinel proc msg) |
|---|
| 208 |
(when (memq (process-status proc) '(signal exit)) |
|---|
| 209 |
(if (file-exists-p makeinfo-temp-file) |
|---|
| 210 |
(delete-file makeinfo-temp-file)) |
|---|
| 211 |
|
|---|
| 212 |
(let ((buffer (get-file-buffer makeinfo-output-file-name))) |
|---|
| 213 |
(if buffer |
|---|
| 214 |
(with-current-buffer buffer |
|---|
| 215 |
(revert-buffer t t)) |
|---|
| 216 |
(setq buffer (find-file-noselect makeinfo-output-file-name))) |
|---|
| 217 |
(if (window-dedicated-p (selected-window)) |
|---|
| 218 |
(switch-to-buffer-other-window buffer) |
|---|
| 219 |
(switch-to-buffer buffer))) |
|---|
| 220 |
(goto-char (point-min)))) |
|---|
| 221 |
|
|---|
| 222 |
(defun makeinfo-current-node () |
|---|
| 223 |
"Return the name of the node containing point, in a texinfo file." |
|---|
| 224 |
(save-excursion |
|---|
| 225 |
(end-of-line) |
|---|
| 226 |
(if (re-search-backward "^@node\\s-+\\([^,\n]+\\)" (point-min) t) |
|---|
| 227 |
(match-string 1) |
|---|
| 228 |
"Top"))) |
|---|
| 229 |
|
|---|
| 230 |
(defun makeinfo-buffer () |
|---|
| 231 |
"Make Info file from current buffer. |
|---|
| 232 |
|
|---|
| 233 |
Use the \\[next-error] command to move to the next error |
|---|
| 234 |
\(if there are errors\)." |
|---|
| 235 |
|
|---|
| 236 |
(interactive) |
|---|
| 237 |
(cond ((null buffer-file-name) |
|---|
| 238 |
(error "Buffer not visiting any file")) |
|---|
| 239 |
((buffer-modified-p) |
|---|
| 240 |
(if (y-or-n-p "Buffer modified; do you want to save it? ") |
|---|
| 241 |
(save-buffer)))) |
|---|
| 242 |
|
|---|
| 243 |
|
|---|
| 244 |
|
|---|
| 245 |
(save-excursion |
|---|
| 246 |
(goto-char (point-min)) |
|---|
| 247 |
(let ((search-end (save-excursion (forward-line 100) (point)))) |
|---|
| 248 |
(if (re-search-forward |
|---|
| 249 |
"^@setfilename[ \t]+\\([^ \t\n]+\\)[ \t]*" |
|---|
| 250 |
search-end t) |
|---|
| 251 |
(setq makeinfo-output-file-name |
|---|
| 252 |
(expand-file-name |
|---|
| 253 |
(buffer-substring (match-beginning 1) (match-end 1)))) |
|---|
| 254 |
(error |
|---|
| 255 |
"The texinfo file needs a line saying: @setfilename <name>")))) |
|---|
| 256 |
(setq makeinfo-output-node-name (makeinfo-current-node)) |
|---|
| 257 |
|
|---|
| 258 |
(save-excursion |
|---|
| 259 |
(makeinfo-compile |
|---|
| 260 |
(concat makeinfo-run-command " " makeinfo-options |
|---|
| 261 |
" " buffer-file-name) |
|---|
| 262 |
nil |
|---|
| 263 |
'makeinfo-compilation-sentinel-buffer))) |
|---|
| 264 |
|
|---|
| 265 |
(defun makeinfo-compilation-sentinel-buffer (proc msg) |
|---|
| 266 |
"Sentinel for `makeinfo-compile' run from `makeinfo-buffer'." |
|---|
| 267 |
(compilation-sentinel proc msg) |
|---|
| 268 |
(when (memq (process-status proc) '(signal exit)) |
|---|
| 269 |
(when (file-exists-p makeinfo-output-file-name) |
|---|
| 270 |
(Info-revert-find-node |
|---|
| 271 |
makeinfo-output-file-name makeinfo-output-node-name)))) |
|---|
| 272 |
|
|---|
| 273 |
(defun makeinfo-recenter-compilation-buffer (linenum) |
|---|
| 274 |
"Redisplay `*compilation*' buffer so most recent output can be seen. |
|---|
| 275 |
The last line of the buffer is displayed on |
|---|
| 276 |
line LINE of the window, or centered if LINE is nil." |
|---|
| 277 |
(interactive "P") |
|---|
| 278 |
(let ((makeinfo-buffer (get-buffer "*compilation*")) |
|---|
| 279 |
(old-buffer (current-buffer))) |
|---|
| 280 |
(if (null makeinfo-buffer) |
|---|
| 281 |
(message "No *compilation* buffer") |
|---|
| 282 |
(pop-to-buffer makeinfo-buffer) |
|---|
| 283 |
(bury-buffer makeinfo-buffer) |
|---|
| 284 |
(goto-char (point-max)) |
|---|
| 285 |
(recenter (if linenum |
|---|
| 286 |
(prefix-numeric-value linenum) |
|---|
| 287 |
(/ (window-height) 2))) |
|---|
| 288 |
(pop-to-buffer old-buffer) |
|---|
| 289 |
))) |
|---|
| 290 |
|
|---|
| 291 |
|
|---|
| 292 |
(provide 'makeinfo) |
|---|
| 293 |
|
|---|
| 294 |
|
|---|
| 295 |
|
|---|
| 296 |
|
|---|