home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcl / docs.lha / latexinfo / elisp / latexinfo.el < prev    next >
Encoding:
Text File  |  1992-02-24  |  81.0 KB  |  2,406 lines

  1. ;; Convert latexinfo files to info files.
  2. ;; Copyright (C) 1985, 1986, 1988 Free Software Foundation, Inc.
  3. ;; Copyleft  (C) 1988, 1989, 1990, 1991 Michael E. Clarkson
  4.  
  5. ;; This file is not yet a part of GNU Emacs.
  6.  
  7. ;; GNU Emacs is distributed in the hope that it will be useful,
  8. ;; but WITHOUT ANY WARRANTY.  No author or distributor
  9. ;; accepts responsibility to anyone for the consequences of using it
  10. ;; or for whether it serves any particular purpose or works at all,
  11. ;; unless he says so in writing.  Refer to the GNU Emacs General Public
  12. ;; License for full details.
  13.  
  14. ;; Everyone is granted permission to copy, modify and redistribute
  15. ;; GNU Emacs, but only under the conditions described in the
  16. ;; GNU Emacs General Public License.   A copy of this license is
  17. ;; supposed to have been given to you along with GNU Emacs so you
  18. ;; can know your rights and responsibilities.  It should be in a
  19. ;; file named COPYING.  Among other things, the copyright notice
  20. ;; and this notice must be preserved on all copies.
  21.  
  22. (defvar latexinfo-formats-directory
  23.   (file-name-as-directory (or (getenv "LATEXINFO") ".")))
  24.  
  25. (defvar latexinfo-texinputs
  26.   (let ((texinputs (or (getenv "TEXINPUTS")
  27.                (concat ".:" latexinfo-formats-directory
  28.                    ":/usr/local/lib/tex/inputs")))
  29.     (dirlist) (i 0) (l) (s) (sepchar ?:))
  30.     (if (eq system-type 'vax-vms) (setq sepchar ?,)) ; emacs.c
  31.     (setq l (length texinputs))
  32.     (while (< i l)
  33.       (setq s i)
  34.       (while (and (< i l) (not (char-equal (aref texinputs i) sepchar)))
  35.     (setq i (1+ i)))
  36.       (if (> i s)
  37.       (setq dirlist (append dirlist (list (substring texinputs s i)))))
  38.       (setq  i (1+ i)))
  39.     dirlist))
  40.  
  41. (defvar latexinfo-always-refill nil)
  42.  
  43. (if (not (memq latexinfo-formats-directory
  44.            load-path))
  45.     (setq load-path (cons
  46.              latexinfo-formats-directory
  47.              load-path)))
  48.  
  49. (if (not (memq "." load-path))    ; add the current directory to load-path
  50.     (setq load-path (cons "." load-path)))
  51.  
  52. (defvar latexinfo-known-document-styles
  53.       '(latexinfo 11pt 12pt twoside titlepage A4 a4 dina4 psfonts format))
  54.  
  55. (autoload 'latexinfo-mode "latexnfo-mde"
  56.         "Major mode for editing latexinfo files." t)
  57.  
  58. (autoload 'Info-tagify "informat" "Info Tagify" t)
  59. (autoload 'Info-split "informat" "Info Split" t)
  60.  
  61. (put 'latexinfoversion 'latexinfo-format 'latexinfo-format-latexinfoversion)
  62. (defun latexinfo-format-latexinfoversion ()
  63.   (latexinfo-parse-noarg)
  64.   (insert "1.7"))
  65.  
  66. (defvar latexinfo-vindex-old nil)
  67. (defvar latexinfo-findex-old nil)
  68. (defvar latexinfo-cindex-old nil)
  69. (defvar latexinfo-cpsubindex-old nil)
  70. (defvar latexinfo-pindex-old nil)
  71. (defvar latexinfo-tindex-old nil)
  72. (defvar latexinfo-kindex-old nil)
  73. (defvar latexinfo-refindex-old nil)
  74.  
  75. (defvar latexinfo-format-syntax-table nil)
  76.  
  77. (progn
  78.     (setq latexinfo-format-syntax-table (make-syntax-table))
  79.     (modify-syntax-entry ?* "w" latexinfo-format-syntax-table)
  80.     (modify-syntax-entry ?& "w" latexinfo-format-syntax-table)
  81.  
  82.     (modify-syntax-entry ?\\ "\\" latexinfo-format-syntax-table)
  83.     (modify-syntax-entry ?\^q "\\" latexinfo-format-syntax-table)
  84.  
  85.     (modify-syntax-entry ?{ "(}" latexinfo-format-syntax-table)
  86.     (modify-syntax-entry ?} "){" latexinfo-format-syntax-table)
  87.     (modify-syntax-entry ?\[ "(]" latexinfo-format-syntax-table) ; changed
  88.     (modify-syntax-entry ?\] ")[" latexinfo-format-syntax-table) ; changed
  89.  
  90.     (modify-syntax-entry ?\" " " latexinfo-format-syntax-table)
  91.     (modify-syntax-entry ?\( " " latexinfo-format-syntax-table)
  92.     (modify-syntax-entry ?\) " " latexinfo-format-syntax-table)
  93.  
  94.     ;; punctuation characters are important to \alwaysrefill
  95.     (modify-syntax-entry ?!  "." latexinfo-format-syntax-table)
  96.     (modify-syntax-entry ?.  "." latexinfo-format-syntax-table)
  97.     (modify-syntax-entry ?:  "." latexinfo-format-syntax-table)
  98.     (modify-syntax-entry ?\' "." latexinfo-format-syntax-table)
  99. )
  100.  
  101. (defun latexinfo-format-buffer (&optional notagify)
  102.   "Process the current buffer as latexinfo code, into an Info file.
  103. The Info file output is generated in a buffer visiting the Info file
  104. names specified in the \\setfilename command.
  105.  
  106. Non-nil argument (prefix, if interactive) means don't make tag table
  107. and don't split the file if large.  You can use Info-tagify and
  108. Info-split to do these manually.
  109.  
  110. Returns a list:
  111.  
  112.     (list outfile
  113.       latexinfo-cindex latexinfo-vindex latexinfo-findex 
  114.       latexinfo-pindex latexinfo-tindex latexinfo-kindex
  115.           latexinfo-refindex)"
  116.   (interactive "P")
  117.   (let ((lastmessage "Formatting Info file..."))
  118.     (message lastmessage)
  119.     (let ((retval (latexinfo-format-buffer-1)))
  120.       (setq latexinfo-cindex-old (nth 1 retval))
  121.       (setq latexinfo-vindex-old (nth 2 retval))
  122.       (setq latexinfo-findex-old (nth 3 retval))
  123.       (setq latexinfo-pindex-old (nth 4 retval))
  124.       (setq latexinfo-tindex-old (nth 5 retval))
  125.       (setq latexinfo-kindex-old (nth 6 retval))
  126.       (setq latexinfo-refindex-old (nth 7 retval)))
  127.     (if notagify nil (latexinfo-split))
  128.     (if (interactive-p) (message (concat lastmessage
  129.                      "done.  Now save it." "done.")))))
  130.  
  131. (defun latexinfo-split ()
  132.   (if (> (buffer-size) 30000)
  133.       (progn
  134.     (message (setq lastmessage "Making tags table for Info file..."))
  135.     (Info-tagify)))
  136.   (if (> (buffer-size) 100000)
  137.       (progn
  138.     (message (setq lastmessage "Splitting Info file..."))
  139.     (Info-split))))
  140.  
  141. (defun latexinfo-format-buffer-1 ()
  142.   (let (latexinfo-format-filename
  143.     latexinfo-example-start
  144.     latexinfo-command-start
  145.     latexinfo-command-end
  146.     latexinfo-command-name
  147.     latexinfo-last-node
  148.         latexinfo-last-node-pos
  149.     latexinfo-vindex
  150.     latexinfo-findex
  151.     latexinfo-cindex
  152.     latexinfo-cpsubindex
  153.     latexinfo-pindex
  154.     latexinfo-tindex
  155.     latexinfo-kindex
  156.     latexinfo-refindex
  157.     latexinfo-stack
  158.     latexinfo-node-names
  159.     (latexinfo-table-number 0)
  160.     (latexinfo-footnote-number 0)
  161.     outfile
  162.     (fill-column (1- fill-column))
  163.     (input-buffer (current-buffer))
  164.     (input-directory default-directory))
  165.     (save-excursion
  166.       (goto-char (point-min))
  167.       (re-search-forward "^\\\\setfilename")
  168.       (setq latexinfo-command-end (point))
  169.       (setq outfile (latexinfo-parse-line-arg)))
  170.     (find-file outfile)
  171.     (latexinfo-mode)
  172.     (set-syntax-table latexinfo-format-syntax-table)
  173.     (erase-buffer)
  174.     (insert-buffer-substring input-buffer)
  175.     (goto-char (point-min))
  176.     (latexinfo-run-documentstyle-hooks)
  177.     ;; Run this after latexinfo-run-documentstyle-hooks
  178.     (goto-char (point-min))
  179.     (re-search-forward "^\\\\setfilename")
  180.     (beginning-of-line)
  181.     (let ((end (point)))
  182.       (goto-char (point-min))
  183.       (if (re-search-forward "^\\\\alwaysrefill" end t)
  184.       (setq latexinfo-always-refill t)
  185.     (setq latexinfo-always-refill nil))
  186.       (delete-region (point-min) end))
  187.     ;; Remove \end{document} at end of file, if it is there.
  188.     (goto-char (point-max))
  189.     (if (search-backward "\\end{document}" nil t)
  190.     (delete-region (point) (point-max))
  191.       (error "Missing \\end{document}"))
  192.     ;; Make sure buffer ends in a newline.
  193.     (or (= (preceding-char) ?\n)
  194.     (insert "\n"))
  195.     ;; Scan the whole buffer, converting to Info format.
  196.     (goto-char (point-min))
  197.     (latexinfo-format-scan-noverbatim)
  198.     ;; Return data for indices.
  199.     (goto-char (point-min))
  200.     (list outfile
  201.       latexinfo-cindex latexinfo-vindex latexinfo-findex 
  202.       latexinfo-pindex latexinfo-tindex latexinfo-kindex
  203.           latexinfo-refindex)
  204.     ))
  205.  
  206. (defvar latexinfo-region-buffer-name "*Info Region*"
  207.   "*Name of the temporary buffer used by \\[latexinfo-format-region].")
  208.  
  209. (defun latexinfo-format-region (region-beginning region-ending)
  210.   "Convert the the current region of the Latexinfo file to Info format.
  211. This lets you see what that part of the file will look like in Info.
  212. The command is bound to \\[latexinfo-format-region].  The text that is
  213. converted to Info is stored in a temporary buffer."
  214.   (interactive "r")
  215.   (message "Converting region to Info format...")
  216.   (let (latexinfo-command-start
  217.     latexinfo-command-end
  218.     latexinfo-command-name
  219.     latexinfo-vindex
  220.     latexinfo-findex
  221.     latexinfo-cindex
  222.     latexinfo-pindex
  223.     latexinfo-tindex
  224.     latexinfo-kindex
  225.     latexinfo-refindex
  226.     latexinfo-stack
  227.     latexinfo-format-filename
  228.     latexinfo-example-start
  229.     latexinfo-last-node-pos
  230.     latexinfo-last-node
  231.     latexinfo-node-names
  232.     (latexinfo-table-number 0)
  233.     (latexinfo-footnote-number 0)
  234.     (fill-column (1- fill-column))
  235.     (input-buffer (current-buffer))
  236.     (input-directory default-directory)
  237.     filename-beginning
  238.     filename-ending)
  239.  
  240.     ;; Find a buffer to use.
  241.     (switch-to-buffer (get-buffer-create latexinfo-region-buffer-name))
  242.     ;; Insert the region into the buffer.
  243.     (erase-buffer)
  244.  
  245.     (save-excursion
  246.       (set-buffer input-buffer)
  247.       (save-excursion
  248.     (save-restriction
  249.       (widen)
  250.       (goto-char (point-min))
  251.       ;; Initialize the buffer with the filename
  252.       ;; or else explain that a filename is needed.
  253.       (or (re-search-forward "^\\\\setfilename"
  254.                  (save-excursion (forward-line 100) (point)) t)
  255.           (error "The latexinfo file needs a line saying: \\setfilename <name>"))
  256.       (beginning-of-line)
  257.       (setq filename-beginning (point))
  258.       (forward-line 1)
  259.       (setq filename-ending (point)))))
  260.  
  261.     ;; Insert the \\setfilename line into the buffer.
  262.     (insert-buffer-substring input-buffer
  263.                  (min filename-beginning region-beginning)  
  264.                  filename-ending)
  265.     
  266.     ;; Insert the region into the buffer.
  267.     (insert-buffer-substring input-buffer
  268.                  (max region-beginning filename-ending)
  269.                  region-ending)
  270.  
  271.     (latexinfo-mode)
  272.  
  273.     ;; Install a syntax table useful for scanning command operands.
  274.     (set-syntax-table latexinfo-format-syntax-table)
  275.     
  276.     ;; If the region includes the effective end of the data,
  277.     ;; discard everything after that.
  278.     (goto-char (point-max))
  279.     (if (search-backward "\\end{document}" nil t)
  280.     (delete-region (point) (point-max)))
  281.     ;; Make sure buffer ends in a newline.
  282.     (or (= (preceding-char) ?\n)
  283.     (insert "\n"))
  284.     (goto-char (point-max))
  285.     ;; Now convert for real.
  286.     (goto-char (point-min))
  287.     (latexinfo-format-scan-noverbatim)
  288.     (goto-char (point-min)))
  289.   )
  290.  
  291. ;; Only look at the beginning of the line to avoid \c \input{foo}
  292. (defvar latexinfo-special-regexp 
  293.   "^[ \t]*\\\\\\(begin{verbatim}\\|begin{smallverbatim}\\|verb\\|input{\\)")
  294.  
  295. (defun latexinfo-format-scan-noverbatim ()
  296.   (if (re-search-forward latexinfo-special-regexp nil t)
  297.       (let ((start (point-min))
  298.         (end nil)
  299.         str)
  300.     (goto-char start)
  301.     (while (re-search-forward latexinfo-special-regexp nil t)
  302.       (setq str (buffer-substring (match-beginning 0) (match-end 0)))
  303.       ;; Handle LaTeX \input{filename} commands by inserting them now.
  304.       ;; Only look at the beginning of the line to avoid \c \input{foo}
  305.       ;; Protect the verbatim areas from global substitutions.
  306.       (cond 
  307.        ((string-equal str "\\input{")
  308.         (latexinfo-insert-input-files)
  309.         )
  310.        ((string-equal str "\\begin{verbatim}")
  311.         (setq end (point))
  312.         (latexinfo-do-global-substitutions start end)
  313.         (re-search-forward "\\\\end{verbatim}" nil nil) 
  314.         (setq start (point))
  315.         )
  316.        ((string-equal str "\\begin{smallverbatim}")
  317.         (setq end (point))
  318.         (latexinfo-do-global-substitutions start end)
  319.         (re-search-forward "\\\\end{smallverbatim}" nil nil) 
  320.         (setq start (point))
  321.         )
  322.        ((string-equal str "\\verb")
  323.         (setq end (point))
  324.         (latexinfo-do-global-substitutions start end)
  325.         (setq str (buffer-substring (point) (1+ (point))))
  326.         (forward-char 1)
  327.         (search-forward str nil nil) 
  328.         (forward-char 1)
  329.         (setq start (point))
  330.         )
  331.        )
  332.       )
  333.     (if end (latexinfo-do-global-substitutions start (point-max)))
  334.     )
  335.     (latexinfo-do-global-substitutions (point-min) (point-max))
  336.     )
  337.   (latexinfo-format-scan))
  338.  
  339. (defun latexinfo-insert-input-files ()
  340.   (save-excursion
  341.     ;;    (skip-chars-forward " \t{")
  342.     (let ((file-name
  343.        (buffer-substring 
  344.         (point)
  345.         (progn (skip-chars-forward "^     }\n")
  346.            (point))))
  347.       (dirlist latexinfo-texinputs)
  348.       (the-file nil))
  349.       (while (and (not the-file) dirlist)
  350.     (let ((dir (car dirlist)))
  351.       (setq the-file  
  352.         (cond ((file-readable-p (expand-file-name
  353.                      file-name dir))
  354.                (expand-file-name file-name dir))
  355.               ((file-readable-p (expand-file-name
  356.                      (concat file-name ".tex") dir))
  357.                (expand-file-name
  358.             (concat file-name ".tex") dir))
  359.               (t nil)
  360.               ))
  361.       (setq dirlist (cdr dirlist))))
  362.       (setq file-name the-file)
  363.       (beginning-of-line 1)
  364.       (if (file-readable-p file-name)
  365.       (progn
  366.         (delete-region (point) (progn (forward-line 1) (point)))
  367.         (message "Inserting file %s..." file-name) (sit-for 1)
  368.         (insert-file file-name)
  369.         (message "Inserting file %s...done" file-name))
  370.     (error "I can't find the file %s" file-name))
  371.       )
  372.     )
  373.   )
  374.  
  375. (defun latexinfo-do-global-substitutions (min max)
  376.   (save-excursion
  377.     (narrow-to-region min max)
  378.     (goto-char (point-min))
  379.     (let ((start nil))
  380.       (while (re-search-forward "^\\\\begin{ignore}" nil t)
  381.     (beginning-of-line 1)
  382.     (setq start (point))
  383.     (re-search-forward "^\\\\end{ignore}" nil)
  384.     (forward-line 1)
  385.     (delete-region start (point))))
  386.     ;; LaTeX sometimes uses \\ to force a new-line
  387.     (goto-char (point-min))
  388.     (quietly-replace-regexp "\\\\\\\\$" "")
  389.     ;; Convert left and right quotes to typewriter font quotes.
  390.     (goto-char (point-min))
  391.     (while (search-forward "``" nil t)
  392.       (replace-match "\""))
  393.     (goto-char (point-min))
  394.     (while (search-forward "''" nil t)
  395.       (replace-match "\""))
  396.     (if latexinfo-always-refill
  397.     (latexinfo-do-refill)
  398.       )
  399.     (widen)
  400.     )
  401.   )
  402.  
  403. (defun latexinfo-do-refill ()
  404.   (let ((start (point-min))
  405.     (end nil))
  406.     (goto-char start)
  407.     (while (re-search-forward "^\\\\begin{menu}" nil t)
  408.       (narrow-to-region start (point))
  409.       ;; Would a regexp be too slow?
  410.       (goto-char (point-min))
  411.       (quietly-replace-string ".\n\n" ".\\refill\n\n" nil)
  412.       (goto-char (point-min))
  413.       (quietly-replace-string ":\n\n" ":\\refill\n\n" nil)
  414.       (goto-char (point-min))
  415.       (quietly-replace-string ".\n\\end" ".\\refill\n\\end" nil)
  416.       (narrow-to-region min max)
  417.       (re-search-forward "\\\\end{menu}" nil nil) 
  418.       (setq start (point))
  419.       )
  420.     )
  421.   )
  422.  
  423. (defun latexinfo-format-scan ()
  424.   ;; Scan for \\-commands.
  425.   (set-syntax-table latexinfo-format-syntax-table)
  426.   (goto-char (point-min))
  427.   (let ((foochar nil))
  428.     (while (search-forward "\\" nil t)
  429.     ;;; EMACS BUG (looking-at "[*{}^'` \t---.:%\"\\\\]") TRUE for &
  430.       ;; Handle a few special \-followed-by-one-char commands.
  431.       (setq foochar (following-char))
  432.       (cond ((memq foochar '(?* ?\\ ?- ?:))
  433.          ;; \* has no effect, since we are not filling.
  434.          ;; \" can't be reproduced on ascii terminals
  435.          (delete-region (1- (point)) (1+ (point))))
  436.         ((memq foochar '(?^ ?' ?` ?\"))
  437.          (latexinfo-parse-accent))
  438.         ((memq foochar '(?* ?\{ ?} ?^ ?\  ?\t ?\. ?: ?% ?\\))
  439.          ;; The other characters are simply quoted.  Delete the \.
  440.          (delete-char -1)
  441.          (forward-char 1))
  442.         (t
  443.          ;; \ is followed by a command-word; find the end of the word.
  444.          (setq latexinfo-command-start (1- (point)))
  445.          ;; (if (= (char-syntax (following-char)) ?w) . (forward-char 1))
  446.         (forward-word 1)
  447.         (setq latexinfo-command-end (point))
  448.         ;; Call the handler for this command.
  449.         (setq latexinfo-command-name
  450.           (intern (buffer-substring (1+ latexinfo-command-start)
  451.                         latexinfo-command-end)))
  452.         (let ((cmd (get latexinfo-command-name 'latexinfo-format)))
  453.           (if cmd (funcall cmd)
  454.         (latexinfo-unsupported))))
  455.       )
  456.     )
  457.   (cond (latexinfo-stack
  458.      (goto-char (nth 2 (car latexinfo-stack)))
  459.      (error "Unterminated \\begin{%s}" (car (car latexinfo-stack)))))
  460.   )
  461. )
  462.  
  463. (defun latexinfo-parse-accent ()
  464.   (latexinfo-delete-whitespace)
  465.   (cond ((looking-at ".{")
  466.      (delete-region (1- (point)) (+ 2 (point)))
  467.      (skip-chars-forward "^}")
  468.      (delete-char 1)        ; }
  469.      )
  470.     (t                ; this should not happen
  471.      (delete-region (1- (point)) (1+ (point)))        ; \c
  472.      )
  473.     )
  474.   )
  475.  
  476. (put 'begin 'latexinfo-format 'latexinfo-format-begin)
  477. (defun latexinfo-format-begin ()
  478.   (latexinfo-format-begin-end 'latexinfo-format))
  479.  
  480. (put 'end 'latexinfo-format 'latexinfo-format-end)
  481. (defun latexinfo-format-end ()
  482.   (latexinfo-format-begin-end 'latexinfo-end))
  483.  
  484. (defun latexinfo-format-begin-end (prop)
  485.   (setq latexinfo-command-name (intern (latexinfo-parse-line-arg)))
  486.   (setq cmd (get latexinfo-command-name prop))
  487.   (if cmd (funcall cmd)
  488.     (latexinfo-unsupported)))
  489.  
  490. (defvar latexinfo-format-syntax-table-a nil)
  491.  
  492. (progn
  493.   (setq latexinfo-format-syntax-table-a 
  494.     (copy-syntax-table latexinfo-format-syntax-table))
  495.   (modify-syntax-entry ?\[ "." latexinfo-format-syntax-table-a)
  496.   (modify-syntax-entry ?\] "." latexinfo-format-syntax-table-a)
  497.   )
  498.  
  499. ;;Fundamental change
  500. (defun safe-forward-list (arg)
  501.   (cond ((string-equal "}" arg)
  502.      (set-syntax-table latexinfo-format-syntax-table-a)
  503.      (forward-sexp 1)
  504.      (set-syntax-table latexinfo-format-syntax-table)
  505.      )
  506.     ((string-equal "]" arg)
  507.      (forward-list 1))
  508.     (t (forward-list 1))
  509.     )
  510.   )
  511.  
  512. (defun latexinfo-parse-line-arg ()
  513.   "Returns the command that takes up the rest of the line."
  514.   (goto-char latexinfo-command-end)
  515.   (let ((start (point)))
  516.     (cond ((looking-at " ")
  517.        (skip-chars-forward " ")
  518.        (setq start (point))
  519.        (end-of-line)
  520.            (skip-chars-backward " ")
  521.            (delete-region (point) (progn (end-of-line) (point)))
  522.        (setq latexinfo-command-end (1+ (point))))
  523.       ((looking-at "{")
  524.        (setq start (1+ (point)))
  525.        (safe-forward-list "}")
  526.        (setq latexinfo-command-end (point))
  527.        (forward-char -1))
  528.       ((looking-at "\\[")
  529.        (setq start (1+ (point)))
  530.        (safe-forward-list "]")
  531.        (setq latexinfo-command-end (point))
  532.        (forward-char -1))
  533.       (t
  534.        (error "Invalid latexinfo command arg format")))
  535.     (prog1 (buffer-substring start (point))
  536.        (if (eolp) (forward-char 1)))))
  537.  
  538. (defun latexinfo-parse-expanded-arg ()
  539.   (goto-char latexinfo-command-end)
  540.   (let ((start (point))
  541.     marker)
  542.     (cond ((looking-at " ")
  543.        (skip-chars-forward " ")
  544.        (setq start (point))
  545.        (end-of-line)
  546.        (setq latexinfo-command-end (1+ (point))))
  547.       ((or (looking-at "{") (looking-at "\\["))
  548.        (setq start (1+ (point)))
  549.        (forward-list 1)
  550.        (setq latexinfo-command-end (point))
  551.        (forward-char -1))
  552.       (t
  553.        (error "Invalid latexinfo command arg format")))
  554.     (setq marker (move-marker (make-marker) latexinfo-command-end))
  555.     (latexinfo-format-expand-region start (point))
  556.     (setq latexinfo-command-end (marker-position marker))
  557.     (move-marker marker nil)
  558.     (prog1 (buffer-substring start (point))
  559.        (if (eolp) (forward-char 1)))))
  560.  
  561. (defun latexinfo-parse-arg-discard ()
  562.   (prog1 (latexinfo-parse-line-arg)
  563.      (latexinfo-discard-command)))
  564.  
  565. (defun latexinfo-discard-command ()
  566.   ;;LaTeX gobbles the next whitespace. Should Info?
  567.   (delete-region latexinfo-command-start latexinfo-command-end))
  568.  
  569. (defun latexinfo-parse-noarg ()
  570.   (goto-char latexinfo-command-end)
  571.   (cond ((looking-at "{}") (delete-char 2))
  572.     ;; TeX gobbles the next whitespace.
  573.     ((eolp) (delete-char 1))
  574.     ((looking-at "[ \t]")
  575.      (setq latexinfo-command-end
  576.             (save-excursion
  577.               (skip-chars-forward " \t") (point))))
  578.     )
  579.   (delete-region latexinfo-command-start latexinfo-command-end)
  580.   )
  581.  
  582. ;; New parsing functions
  583. (defun latexinfo-parse-required-argument ()
  584.   ;; TeX gobbles the next whitespace.
  585.   (goto-char latexinfo-command-end)
  586.   (latexinfo-delete-whitespace)
  587.   (cond ((looking-at "{")
  588.      (setq latexinfo-command-end
  589.            (save-excursion
  590.          (forward-sexp 1) (point))))
  591.     (t (error "latexinfo-parse-required-argument: no argument provided"))
  592.     )
  593.   (prog1 (buffer-substring (1+ (point)) (1- latexinfo-command-end))
  594.     (latexinfo-delete-command ))
  595.   )
  596.  
  597. (defun latexinfo-delete-whitespace ()
  598.   (if (looking-at "[ \t\n]")
  599.       (delete-region (point) (save-excursion 
  600.                    (skip-chars-forward " \t\n")
  601.                    (point)))))
  602.  
  603. (defun latexinfo-insert-required-argument ()
  604.   (save-excursion (insert (latexinfo-parse-required-argument))))
  605.  
  606. (defun latexinfo-delete-command ()
  607.   (delete-region latexinfo-command-start latexinfo-command-end))
  608.  
  609. (defun latexinfo-format-expand-region (start end)
  610.   (save-restriction
  611.     (narrow-to-region start end)
  612.     (let (latexinfo-command-start
  613.       latexinfo-command-end
  614.       latexinfo-command-name
  615.       latexinfo-stack)
  616.       (latexinfo-format-scan))
  617.     (goto-char (point-max))))
  618.  
  619. (defun latexinfo-format-parse-line-args ()
  620.   (let ((start (1- (point)))
  621.     next beg end
  622.     args)
  623.     (skip-chars-forward " ")
  624.     (while (not (eolp))
  625.       (setq beg (point))
  626.       (re-search-forward "[\n,]")
  627.       (setq next (point))
  628.       (if (bolp) (setq next (1- next)))
  629.       (forward-char -1)
  630.       (skip-chars-backward " ")
  631.       (setq end (point))
  632.       (setq args (cons (if (> end beg) (buffer-substring beg end))
  633.                args))
  634.       (goto-char next)
  635.       (skip-chars-forward " "))
  636.     (if (eolp) (forward-char 1))
  637.     (setq latexinfo-command-end (point))
  638.     (nreverse args)))
  639.  
  640. (defun latexinfo-format-parse-args ()
  641.   (let ((start (1- (point)))
  642.     next beg end
  643.     args)
  644.     (search-forward "{")
  645.     (while (/= (preceding-char) ?\})
  646.       (skip-chars-forward " \t\n")
  647.       (setq beg (point))
  648.       (re-search-forward "[},]")
  649.       (setq next (point))
  650.       (forward-char -1)
  651.       (skip-chars-backward " \t\n")
  652.       (setq end (point))
  653.       (cond ((< beg end)
  654.          (goto-char beg)
  655.          (while (search-forward "\n" end t)
  656.            (replace-match " "))))
  657.       (setq args (cons (if (> end beg) (buffer-substring beg end))
  658.                args))
  659.       (goto-char next))
  660.     (if (eolp) (forward-char 1))
  661.     (setq latexinfo-command-end (point))
  662.     (nreverse args)))
  663.  
  664.  
  665.  
  666. (put 'document 'latexinfo-format 'latexinfo-discard-line)
  667. (put 'document 'latexinfo-end 'latexinfo-discard-line)
  668.  
  669. (put 'setfilename 'latexinfo-format 'latexinfo-format-setfilename)
  670. (defun latexinfo-format-setfilename ()
  671.   (let ((arg (latexinfo-parse-arg-discard)))
  672.     (setq latexinfo-format-filename
  673.       (file-name-nondirectory (expand-file-name arg)))
  674.     (insert "Info file: "
  675.         latexinfo-format-filename ",    -*-Text-*-\n"
  676.         "produced by latexinfo-format-buffer\nfrom "
  677.         (if (buffer-file-name input-buffer)
  678.         (concat "file: "
  679.             (file-name-sans-versions
  680.              (file-name-nondirectory
  681.               (buffer-file-name input-buffer))))
  682.           (concat "buffer " (buffer-name input-buffer)))
  683.         "\n\n")))
  684.  
  685. (put 'node 'latexinfo-format 'latexinfo-format-node)
  686. (defun latexinfo-format-node ()
  687.   (let* ((args (latexinfo-format-parse-line-args))
  688.      (name (nth 0 args))
  689.      (next (nth 1 args))
  690.      (prev (nth 2 args))
  691.      (up (nth 3 args)))
  692.     (latexinfo-discard-command)
  693.     (setq latexinfo-last-node name)
  694.     (let ((tem (downcase name)))
  695.       (if (assoc tem latexinfo-node-names)
  696.       (error "Duplicate node name: %s" name)
  697.     (setq latexinfo-node-names (cons tem latexinfo-node-names))))
  698.     (or (bolp)
  699.     (insert ?\n))
  700.     (insert "\^_\nFile: " latexinfo-format-filename
  701.         "  Node: " name)
  702.     (if prev
  703.     (insert ", Prev: " prev))
  704.     (if up
  705.     (insert ", Up: " up))
  706.     (if next
  707.     (insert ", Next: " next))
  708.     (insert ?\n)
  709.     (setq latexinfo-last-node-pos (point))
  710.     ))
  711.  
  712. (put 'menu 'latexinfo-format 'latexinfo-format-menu)
  713. (defun latexinfo-format-menu ()
  714.   (latexinfo-discard-line)
  715.   (insert "* Menu:\n\n"))
  716.  
  717. (put 'menu 'latexinfo-end 'latexinfo-discard-command)
  718.  
  719. (defun latexinfo-discard-line ()
  720.   (goto-char latexinfo-command-end)
  721.   (skip-chars-forward " \t")
  722.   (or (eolp)
  723.       (error "Extraneous text at end of command line."))
  724.   (delete-region latexinfo-command-start (progn (forward-line 1) (point))))
  725.  
  726. (defun latexinfo-discard-to-eoline ()
  727.   (goto-char latexinfo-command-end)
  728.   (skip-chars-forward " \t")
  729.   (or (eolp)
  730.       (error "Extraneous text at end of command line."))
  731.   (delete-region latexinfo-command-start (point)))
  732.  
  733. ; \xref {NODE, FNAME, NAME, FILE, DOCUMENT}
  734. ; -> *Note FNAME: (FILE)NODE
  735. ;   If FILE is missing,
  736. ;    *Note FNAME: NODE
  737. ;   If FNAME is empty and NAME is present
  738. ;    *Note NAME: Node
  739. ;   If both NAME and FNAME are missing
  740. ;    *Note NODE::
  741. ;   latexinfo ignores the DOCUMENT argument.
  742. ; -> See section <xref to NODE> [NAME, else NODE], page <xref to NODE>
  743. ;   If FILE is specified, (FILE)NODE is used for xrefs.
  744. ;   If fifth argument DOCUMENT is specified, produces
  745. ;    See section <xref to NODE> [NAME, else NODE], page <xref to NODE>
  746. ;    of DOCUMENT
  747. ; \nxref is a reference that does not put `See' or `see' in
  748. ;                  the hardcopy and is the same as \xref in Info
  749.  
  750. (put 'nxref 'latexinfo-format 'latexinfo-format-xref)
  751. (put 'xref 'latexinfo-format 'latexinfo-format-xref)
  752. (defun latexinfo-format-xref ()
  753.   (let ((args (latexinfo-format-parse-args)))
  754.     (latexinfo-discard-command)
  755.     (insert "*Note ")
  756.     (let ((fname (or (nth 1 args) (nth 2 args))))
  757.       (if (null (or fname (nth 3 args)))
  758.       (insert (car args) "::")
  759.     (insert (or fname (car args)) ": ")
  760.     (if (nth 3 args)
  761.         (insert "(" (nth 3 args) ")"))
  762.     (insert (car args))))))
  763.  
  764. (put 'pxref 'latexinfo-format 'latexinfo-format-pxref)
  765. (defun latexinfo-format-pxref ()
  766.   (latexinfo-format-xref)
  767.   (or (save-excursion
  768.     (forward-char -2)
  769.     (looking-at "::"))
  770.       (insert ".")))
  771.  
  772. ;\inforef{NODE, FNAME, FILE}
  773. ;Like \xref{NODE, FNAME,,FILE} in latexinfo.
  774. ;In LaTeX, generates "See Info file FILE, node NODE"
  775. (put 'inforef 'latexinfo-format 'latexinfo-format-inforef)
  776. (defun latexinfo-format-inforef ()
  777.   (let ((args (latexinfo-format-parse-args)))
  778.     (latexinfo-discard-command)
  779.     (if (nth 1 args)
  780.         (insert "*Note " (nth 1 args) ": (" (nth 2 args) ")" (car args))
  781.       (insert "*Note " "(" (nth 2 args) ")" (car args) "::"))))
  782.  
  783. (put 'appendix 'latexinfo-format 'latexinfo-parse-noarg)
  784. (put 'onecolumn 'latexinfo-format 'latexinfo-parse-noarg)
  785. (put 'twocolumn 'latexinfo-format 'latexinfo-parse-noarg)
  786. ;;(put 'threecolumn 'latexinfo-format 'latexinfo-parse-noarg)
  787.  
  788. (put 'chapter 'latexinfo-format 'latexinfo-format-chapter)
  789. (put 'chapter* 'latexinfo-format 'latexinfo-format-chapter)
  790. (put 'unnumbered 'latexinfo-format 'latexinfo-format-chapter)
  791. (defun latexinfo-format-chapter ()
  792.   (latexinfo-format-chapter-1 ?*))
  793.  
  794. (put 'section 'latexinfo-format 'latexinfo-format-section)
  795. (put 'section* 'latexinfo-format 'latexinfo-format-section)
  796. (put 'unnumberedsec 'latexinfo-format 'latexinfo-format-section)
  797. (defun latexinfo-format-section ()
  798.   (latexinfo-format-chapter-1 ?=))
  799.  
  800. (put 'subsection 'latexinfo-format 'latexinfo-format-subsection)
  801. (put 'subsection* 'latexinfo-format 'latexinfo-format-subsection)
  802. (put 'unnumberedsubsec 'latexinfo-format 'latexinfo-format-subsection)
  803. (defun latexinfo-format-subsection ()
  804.   (latexinfo-format-chapter-1 ?-))
  805.  
  806. (put 'subsubsection 'latexinfo-format 'latexinfo-format-subsubsection)
  807. (put 'subsubsection* 'latexinfo-format 'latexinfo-format-subsubsection)
  808. (put 'unnumberedsubsubsec 'latexinfo-format 'latexinfo-format-subsubsection)
  809. (defun latexinfo-format-subsubsection ()
  810.   (latexinfo-format-chapter-1 ?.))
  811.  
  812. (defun latexinfo-format-chapter-1 (belowchar)
  813.   (let ((arg (latexinfo-parse-arg-discard)))
  814.     (message "Formatting: %s ... " arg)    ; So we can see where we are.
  815.     (insert ?\n arg ?\n "\\SectionPAD " belowchar ?\n)
  816.     (if (not (looking-at "\n")) (insert "\n"))
  817.     (goto-char latexinfo-command-start)))
  818.  
  819. (put 'SectionPAD 'latexinfo-format 'latexinfo-format-sectionpad)
  820. (defun latexinfo-format-sectionpad ()
  821.   (let ((str (latexinfo-parse-arg-discard)))
  822.     (forward-char -1)
  823.     (let ((column (current-column)))
  824.       (forward-char 1)
  825.       (while (> column 0)
  826.     (insert str)
  827.     (setq column (1- column))))
  828.     (insert ?\n)
  829.     (if (not (looking-at "\n")) (insert "\n"))
  830. ))
  831.  
  832. (put 'paragraph 'latexinfo-format 'latexinfo-format-var)
  833. (put 'subparagraph 'latexinfo-format 'latexinfo-format-noop)
  834. (put 'paragraph* 'latexinfo-format 'latexinfo-format-var)
  835. (put 'subparagraph* 'latexinfo-format 'latexinfo-format-noop)
  836.  
  837. (put '\. 'latexinfo-format 'latexinfo-format-\.)
  838. (defun latexinfo-format-\. ()
  839.   (latexinfo-discard-command)
  840.   (insert "."))
  841.  
  842. (put '\\ 'latexinfo-format 'latexinfo-format-\\)
  843. (defun latexinfo-format-\\ ()
  844.   (latexinfo-discard-command)
  845.   (insert "\n"))
  846.  
  847. (put '\: 'latexinfo-format 'latexinfo-format-\:)
  848. (defun latexinfo-format-\: ()
  849.   (latexinfo-discard-command))
  850.  
  851. (put '_ 'latexinfo-format 'latexinfo-format-_)
  852. (defun latexinfo-format-_ ()
  853.   (latexinfo-parse-noarg)
  854.   (insert "_"))
  855.  
  856. (put '$ 'latexinfo-format 'latexinfo-format-$)
  857. (defun latexinfo-format-$ ()
  858.   (latexinfo-parse-noarg)
  859.   (insert "$"))
  860.  
  861. (put '@ 'latexinfo-format 'latexinfo-format-@)
  862. (defun latexinfo-format-@ ()
  863.   (latexinfo-parse-noarg)
  864.   (insert "@"))
  865.  
  866. (put '~ 'latexinfo-format 'latexinfo-format-~)
  867. (defun latexinfo-format-~ ()
  868.   (latexinfo-parse-noarg)
  869.   (insert "~"))
  870.  
  871. (put '^ 'latexinfo-format 'latexinfo-format-^)
  872. (defun latexinfo-format-^ ()
  873.   (latexinfo-parse-noarg)
  874.   (insert "^"))
  875.  
  876. (put '/ 'latexinfo-format 'latexinfo-format-/)
  877. (defun latexinfo-format-/ ()
  878.   (latexinfo-parse-noarg))
  879.  
  880. (put '\  'latexinfo-format 'latexinfo-format-space)
  881. (defun latexinfo-format-space ()
  882.   (latexinfo-parse-noarg)
  883.   (insert "    "))
  884.  
  885. ;; Use \tie when you need one.
  886. (put 'tie 'latexinfo-format 'latexinfo-format-tie)
  887. (defun latexinfo-format-tie ()
  888.   (latexinfo-parse-noarg)
  889.   (insert " "))
  890.  
  891. (put 'sp 'latexinfo-format 'latexinfo-format-sp)
  892. (defun latexinfo-format-sp ()
  893.   (let ((arg (read (latexinfo-parse-expanded-arg))))
  894.     (latexinfo-discard-command)
  895.     ;; Delete eol if the space command is the only thing on a line
  896.     (if (and (eolp) (bolp) (not (eobp))) (delete-char 1))
  897.     (while (> arg 0)
  898.       (insert "\n")
  899.       (setq arg (1- arg)))))
  900.  
  901. ;;; \footnote  and  \footnotestyle
  902.  
  903. ; In Latexinfo, footnotes are created with the `\footnote' command.
  904. ; This command is followed immediately by a left brace, then by the text of
  905. ; the footnote, and then by a terminating right brace.  The
  906. ; template for a footnote is:
  907. ;      \footnote{TEXT}
  908. ;
  909. ; Info has two footnote styles:
  910. ;    * In the End of node style, all the footnotes for a single node
  911. ;      are placed at the end of that node.  The footnotes are
  912. ;      separated from the rest of the node by a line of dashes with
  913. ;      the word `Footnotes' within it.
  914. ;    * In the Separate node style, all the footnotes for a single node
  915. ;      are placed in an automatically constructed node of their own.
  916.  
  917. ; Footnote style is specified by the \footnotestyle command, either
  918. ;    \footnotestyle{separate}
  919. ; or
  920. ;    \footnotestyle{end}
  921. ; The default is  separate
  922.  
  923. (defvar latexinfo-footnote-style "separate" 
  924.   "Footnote style, either separate or end.")
  925.  
  926. (put 'footnotestyle 'latexinfo-format 'latexinfo-footnotestyle)
  927. (defun latexinfo-footnotestyle ()
  928.   "Specify whether footnotes are at end of node or in separate nodes.
  929. Argument is either end or separate."
  930.   (setq latexinfo-footnote-style (latexinfo-parse-arg-discard)))
  931.  
  932. (defvar latexinfo-footnote-number)
  933.  
  934. (put 'footnote 'latexinfo-format 'latexinfo-format-footnote)
  935. (defun latexinfo-format-footnote ()
  936.   "Format a footnote in either end of node or separate node style.
  937. The   latexinfo-footnote-style  variable controls which style is used."
  938.   (setq latexinfo-footnote-number (1+ latexinfo-footnote-number))
  939.   (cond ((string= latexinfo-footnote-style "end")
  940.          (latexinfo-format-end-node))
  941.         ((string= latexinfo-footnote-style "separate")
  942.          (latexinfo-format-separate-node))))
  943.  
  944. (defun latexinfo-format-separate-node ()
  945.   "Format footnote in Separate node style, with notes in own node.
  946. The node is constructed automatically."
  947.   (let* (start
  948.          (arg (latexinfo-parse-line-arg))
  949.          (node-name-beginning
  950.           (save-excursion
  951.             (re-search-backward
  952.              "^File: \\w+\\(\\w\\|\\s_\\|\\.\\|,\\)*[ \t]+Node:")
  953.             (match-end 0)))
  954.          (node-name
  955.           (save-excursion
  956.             (buffer-substring
  957.              (progn (goto-char node-name-beginning) ; skip over node command
  958.                     (skip-chars-forward " \t")  ; and over spaces
  959.                     (point))
  960.              (if (search-forward
  961.                   ","
  962.                   (save-excursion (end-of-line) (point)) t) ; bound search
  963.                  (1- (point))
  964.                (end-of-line) (point))))))
  965.     (latexinfo-discard-command)  ; remove or insert whitespace, as needed
  966.     (delete-region (save-excursion (skip-chars-backward " \t\n") (point))
  967.                    (point))
  968.     (insert (format " (%d) (*Note %s-Footnotes::)"
  969.             latexinfo-footnote-number node-name))
  970.     (fill-paragraph nil)
  971.     (save-excursion
  972.     (if (re-search-forward "^\\\\node" nil 'move)
  973.         (forward-line -1))
  974.  
  975.     ;; two cases: for the first footnote, we must insert a node header;
  976.     ;; for the second and subsequent footnotes, we need only insert 
  977.     ;; the text of the  footnote.
  978.  
  979.     (if (save-excursion
  980.          (re-search-backward
  981.           (concat node-name "-Footnotes, Up: ")
  982.           node-name-beginning
  983.           t))
  984.         (progn   ; already at least one footnote
  985.           (setq start (point))
  986.           (insert (format "\n(%d)  %s\n" latexinfo-footnote-number arg))
  987.           (fill-region start (point)))
  988.       ;; else not yet a footnote
  989.       (insert "\n\^_\nFile: "  latexinfo-format-filename
  990.               "  Node: " node-name "-Footnotes, Up: " node-name "\n")
  991.       (setq start (point))
  992.       (insert (format "\n(%d)  %s\n" latexinfo-footnote-number arg))
  993.       (fill-region start (point))))))
  994.  
  995. (defun latexinfo-format-end-node ()
  996.   "Format footnote in the End of node style, with notes at end of node."
  997.   (let (start
  998.         (arg (latexinfo-parse-line-arg)))
  999.     (latexinfo-discard-command)  ; remove or insert whitespace, as needed
  1000.     (delete-region (save-excursion (skip-chars-backward " \t\n") (point))
  1001.                    (point))
  1002.     (insert (format " (%d) " latexinfo-footnote-number))
  1003.     (fill-paragraph nil)
  1004.     (save-excursion
  1005.       (if (search-forward "\n--------- Footnotes ---------\n" nil t)
  1006.           (progn ; already have footnote, put new one before end of node
  1007.             (if (re-search-forward "^\\\\node" nil 'move)
  1008.                 (forward-line -1))
  1009.             (setq start (point))
  1010.             (insert (format "\n(%d)  %s\n" latexinfo-footnote-number arg))
  1011.             (fill-region start (point)))
  1012.         ;; else no prior footnote
  1013.         (if (re-search-forward "^\\\\node" nil 'move)
  1014.             (forward-line -1))
  1015.         (insert "\n--------- Footnotes ---------\n")
  1016.         (setq start (point))
  1017.         (insert (format "\n(%d)  %s\n" latexinfo-footnote-number arg))))))
  1018.  
  1019.  
  1020. ;; \begin{itemize} pushes (itemize "COMMANDS" STARTPOS) on latexinfo-stack.
  1021. ;; \begin{enumerate} pushes (enumerate 0 STARTPOS).
  1022. ;; \item dispatches to the latexinfo-item prop of the first elt of the list.
  1023. ;; For itemize, this puts in and rescans the COMMANDS.
  1024. ;; For enumerate, this increments the number and puts it in.
  1025. ;; In either case, it puts a Backspace at the front of the line
  1026. ;; which marks it not to be indented later.
  1027. ;; All other lines get indented by 5 when the \end is reached.
  1028.  
  1029. (defvar latexinfo-stack-depth 0
  1030.   "Count of number of unpopped latexinfo-push-stack calls.
  1031. Used by \\refill indenting command to avoid indenting within lists, etc.")
  1032.  
  1033. (defun latexinfo-push-stack (check arg)
  1034.   (setq latexinfo-stack-depth (1+ latexinfo-stack-depth))
  1035.   (setq latexinfo-stack
  1036.     (cons (list check arg latexinfo-command-start)
  1037.           latexinfo-stack)))
  1038.  
  1039. (defun latexinfo-pop-stack (check)
  1040.   (setq latexinfo-stack-depth (1- latexinfo-stack-depth))
  1041.   (if (null latexinfo-stack)
  1042.       (error "Unmatched \\end{%s}" check))
  1043.   (if (not (eq (car (car latexinfo-stack)) check))
  1044.       (error "\\end{%s} matches \\begin{%s}"
  1045.          check (car (car latexinfo-stack))))
  1046.   (prog1 (cdr (car latexinfo-stack))
  1047.      (setq latexinfo-stack (cdr latexinfo-stack))))
  1048.  
  1049. (put 'itemize 'latexinfo-format 'latexinfo-itemize)
  1050. (defun latexinfo-itemize ()
  1051.   (latexinfo-push-stack 'itemize "*")
  1052.   (setq fill-column (- fill-column 5))
  1053.   (latexinfo-discard-line))
  1054.  
  1055. (put 'itemize 'latexinfo-end 'latexinfo-end-itemize)
  1056. (defun latexinfo-end-itemize ()
  1057.   (setq fill-column (+ fill-column 5))
  1058.   (latexinfo-discard-command)
  1059.   (let ((stacktop
  1060.      (latexinfo-pop-stack 'itemize)))
  1061.     (latexinfo-do-itemize (nth 1 stacktop))))
  1062.  
  1063. (put 'enumerate 'latexinfo-format 'latexinfo-enumerate)
  1064. (defun latexinfo-enumerate ()
  1065.   (latexinfo-push-stack 'enumerate 0)
  1066.   (setq fill-column (- fill-column 5))
  1067.   (latexinfo-discard-line))
  1068.  
  1069. (put 'enumerate 'latexinfo-end 'latexinfo-end-enumerate)
  1070. (defun latexinfo-end-enumerate ()
  1071.   (setq fill-column (+ fill-column 5))
  1072.   (latexinfo-discard-command)
  1073.   (let ((stacktop
  1074.      (latexinfo-pop-stack 'enumerate)))
  1075.     (latexinfo-do-itemize (nth 1 stacktop))))
  1076.  
  1077. (put 'center 'latexinfo-format 'latexinfo-format-center)
  1078. (defun latexinfo-format-center ()
  1079.   (latexinfo-push-stack 'center 0)
  1080.   (latexinfo-discard-line))
  1081.  
  1082. (put 'center 'latexinfo-end 'latexinfo-end-center)
  1083. (defun latexinfo-end-center ()
  1084.   (latexinfo-discard-command)
  1085.   (let ((stacktop
  1086.      (latexinfo-pop-stack 'center)))
  1087.     (latexinfo-do-center (nth 1 stacktop))))
  1088.  
  1089. (defun latexinfo-do-center (from)
  1090.   (let ((indent-tabs-mode nil))
  1091.     (if (not (or (eobp) (bolp))) (forward-line 1))
  1092.     (while (progn (forward-line -1)
  1093.           (>= (point) from))
  1094.       (let ((indent-tabs-mode nil))
  1095.     (center-line)))))
  1096.  
  1097. (put 'caption 'latexinfo-format 'latexinfo-caption)
  1098. (defun latexinfo-caption ()
  1099.     (insert
  1100.      (format "Table %d : %s" latexinfo-table-number
  1101.          (latexinfo-parse-arg-discard)))
  1102.     (center-line)
  1103.     (goto-char latexinfo-command-start))
  1104.  
  1105. ;;; Tables and figures
  1106. ;;; & is a special character for the tabular environment.  
  1107. ;;; Use \& if you want to insert an & in a table.
  1108. (put '& 'latexinfo-format 'latexinfo-format-&)
  1109. (defun latexinfo-format-& ()
  1110.   (if (not (assoc 'tabular latexinfo-stack)) ; if we're not inside tabular
  1111.       (progn
  1112.     (latexinfo-parse-noarg)
  1113.     (insert "&"))))
  1114.  
  1115.  
  1116. ;; Math tabular environments are ignored.
  1117. (put 'displaymath 'latexinfo-format 'latexinfo-format-displaymath)
  1118. (put 'displaymath 'latexinfo-end 'latexinfo-discard-command)
  1119. (defun latexinfo-format-displaymath ()
  1120.   (delete-region latexinfo-command-start
  1121.          (progn (re-search-forward "\\\\end[ {]displaymath[ }\n]")
  1122.             (point))))
  1123.  
  1124. (put 'equation 'latexinfo-format 'latexinfo-format-equation)
  1125. (put 'equation 'latexinfo-end 'latexinfo-discard-command)
  1126. (defun latexinfo-format-equation ()
  1127.   (delete-region latexinfo-command-start
  1128.          (progn (re-search-forward "\\\\end[ {]equation[ }\n]")
  1129.             (point))))
  1130.  
  1131. (put 'eqnarray 'latexinfo-format 'latexinfo-format-eqnarray)
  1132. (put 'eqnarray 'latexinfo-end 'latexinfo-discard-command)
  1133. (defun latexinfo-format-eqnarray ()
  1134.   (delete-region latexinfo-command-start
  1135.          (progn (re-search-forward "\\\\end[ {]eqnarray[ }\n]")
  1136.             (point))))
  1137.  
  1138.  
  1139. (put 'array 'latexinfo-format 'latexinfo-format-array)
  1140. (put 'array 'latexinfo-end 'latexinfo-discard-command)
  1141. (defun latexinfo-format-array ()
  1142.   (delete-region latexinfo-command-start
  1143.          (progn (re-search-forward "\\\\end[ {]array[ }\n]")
  1144.             (point))))
  1145.  
  1146.  
  1147.  
  1148. ;;; The tabular environment
  1149. (put 'tabular 'latexinfo-format 'latexinfo-format-tabular)
  1150. (put 'tabular 'latexinfo-end 'latexinfo-end-tabular)
  1151. (defun latexinfo-format-tabular ()
  1152.   (latexinfo-push-stack 'tabular nil)
  1153.   (latexinfo-discard-line-with-args))
  1154.  
  1155. (defun latexinfo-end-tabular ()
  1156.   (latexinfo-discard-command)
  1157.   (let ((stacktop
  1158.      (latexinfo-pop-stack 'tabular)))
  1159.     (latexinfo-do-tabular (nth 1 stacktop))))
  1160.  
  1161. (put 'hline 'latexinfo-format 'latexinfo-format-hline)
  1162. (put 'rule 'latexinfo-format 'latexinfo-format-hline)
  1163. (defun latexinfo-format-hline ()
  1164.     (let ((dashes (make-string fill-column ?-)))
  1165.       (latexinfo-discard-line-with-args)
  1166.       (if (not (bolp)) (insert "\n"))
  1167.       (insert dashes "\n")))
  1168.  
  1169. (defun latexinfo-do-tabular (from)
  1170.   (let ((end (point)))
  1171.     (save-excursion
  1172.       (narrow-to-region from end)
  1173.       (goto-char from)
  1174.       (while (search-forward "&" end t)
  1175.     (if (save-excursion
  1176.           (forward-char -2)
  1177.           (not (looking-at "\\\\")))
  1178.         (progn
  1179.           (delete-char -1)
  1180.           (insert " "))
  1181.       (progn
  1182.         (delete-char -2)
  1183.         (insert "&"))))
  1184.       (goto-char from)
  1185.       (quietly-replace-regexp "\\\\\\\\$" "")
  1186.       (untabify from end)
  1187.       ;; Give it some boundaries to protect from centering
  1188. ;;      (goto-char from)
  1189. ;;      (replace-regexp "^" "| ")
  1190.       (widen)
  1191.       )))
  1192.  
  1193. (put 'table 'latexinfo-format 'latexinfo-format-table)
  1194. (put 'table* 'latexinfo-format 'latexinfo-format-table)
  1195. (put 'table 'latexinfo-end 'latexinfo-discard-command)
  1196. (defun latexinfo-format-table ()
  1197.   (latexinfo-discard-line-with-args)
  1198.   (setq latexinfo-table-number (1+ latexinfo-table-number)))
  1199.  
  1200. ;; Figures are ignored for now
  1201. (put 'figure 'latexinfo-format 'latexinfo-format-figure)
  1202. (put 'figure* 'latexinfo-format 'latexinfo-format-figure)
  1203. (put 'figure 'latexinfo-end 'latexinfo-discard-command)
  1204. (defun latexinfo-format-figure ()
  1205.   (delete-region latexinfo-command-start
  1206.          (progn (re-search-forward "\\\\end[ {]figure[ }]*\n")
  1207.             (point))))
  1208.  
  1209. (put 'description 'latexinfo-format 'latexinfo-description)
  1210. (defun latexinfo-description ()
  1211.   (latexinfo-push-stack 'description "")
  1212.   (setq fill-column (- fill-column 5))
  1213.   (latexinfo-discard-line))
  1214.  
  1215. (put 'description 'latexinfo-end 'latexinfo-end-description)
  1216. (defun latexinfo-end-description ()
  1217.   (setq fill-column (+ fill-column 5))
  1218.   (latexinfo-discard-command)
  1219.   (let ((stacktop
  1220.      (latexinfo-pop-stack 'description)))
  1221.     (latexinfo-do-itemize (nth 1 stacktop))))
  1222.  
  1223. (put 'description 'latexinfo-item 'latexinfo-description-item)
  1224. (defun latexinfo-description-item ()
  1225.   (let ((arg (latexinfo-parse-arg-discard)))
  1226.     (insert ?\b arg "\n     \n"))
  1227.   (forward-line -2))
  1228.  
  1229. ;; At the \end, indent all the lines within the construct
  1230. ;; except those marked with backspace.  FROM says where
  1231. ;; construct started.
  1232. (defun latexinfo-do-itemize (from)
  1233.   (save-excursion
  1234.     (while (progn (forward-line -1)
  1235.           (>= (point) from))
  1236.       (if (= (following-char) ?\b)
  1237.       (save-excursion
  1238.         (delete-char 1)
  1239.         (end-of-line)
  1240.         (delete-char 6))
  1241.     (save-excursion 
  1242.       ;; not  delete trailing whitespace
  1243.       (and nil (if (looking-at "[ \t]")
  1244.                (delete-region (point) 
  1245.                       (progn (skip-chars-forward " \t") 
  1246.                          (point)))))
  1247.       (insert "     "))))))
  1248.  
  1249. (put 'item 'latexinfo-format 'latexinfo-item)
  1250. (defun latexinfo-item ()
  1251.   (funcall (get (car (car latexinfo-stack)) 'latexinfo-item)))
  1252.  
  1253. (put 'itemize 'latexinfo-item 'latexinfo-itemize-item)
  1254. (defun latexinfo-itemize-item ()
  1255.   (latexinfo-parse-noarg)
  1256.   (insert "\b   " (nth 1 (car latexinfo-stack)) " \n")
  1257.   (forward-line -1))
  1258.  
  1259. (put 'enumerate 'latexinfo-item 'latexinfo-enumerate-item)
  1260. (defun latexinfo-enumerate-item ()
  1261.   (latexinfo-parse-noarg)
  1262.   (let ((next (1+ (car (cdr (car latexinfo-stack))))))
  1263.     (setcar (cdr (car latexinfo-stack)) next)
  1264.     (insert ?\b (format "%3d. " next) ?\n))
  1265.   (forward-line -1))
  1266.  
  1267.  
  1268. (put 'ifinfo 'latexinfo-format 'latexinfo-discard-line)
  1269. (put 'ifinfo 'latexinfo-end 'latexinfo-discard-command)
  1270.  
  1271. (put 'iftex 'latexinfo-format 'latexinfo-format-iftex)
  1272. (defun latexinfo-format-iftex ()
  1273.   (delete-region latexinfo-command-start
  1274.          (progn (re-search-forward "\\\\end[ {]iftex[ }\n]")
  1275.             (point))))
  1276.  
  1277. (put 'tex 'latexinfo-format 'latexinfo-format-tex)
  1278. (defun latexinfo-format-tex ()
  1279.   (delete-region latexinfo-command-start
  1280.          (progn (re-search-forward "\\end[ {]tex[     }\n]")
  1281.             (point))))
  1282.  
  1283. (put 'ignore 'latexinfo-format 'latexinfo-format-ignore)
  1284. (defun latexinfo-format-ignore ()
  1285.   (delete-region latexinfo-command-start
  1286.          (progn (re-search-forward "\\\\end[ {]ignore[     }\n]")
  1287.             (point))))
  1288.  
  1289. (put 'endignore 'latexinfo-format 'latexinfo-discard-line)
  1290.  
  1291. (put 'VAR 'latexinfo-format 'latexinfo-format-var)
  1292. (put 'var 'latexinfo-format 'latexinfo-format-var)
  1293. (defun latexinfo-format-var ()
  1294.   (insert (upcase (latexinfo-parse-arg-discard)))
  1295.   (goto-char latexinfo-command-start))
  1296.  
  1297. (put 'b 'latexinfo-format 'latexinfo-format-noop)
  1298. (put 'r 'latexinfo-format 'latexinfo-format-noop)
  1299. (put 'scap 'latexinfo-format 'latexinfo-format-noop)
  1300. (put 'n 'latexinfo-format 'latexinfo-format-noop)
  1301. (put 't 'latexinfo-format 'latexinfo-format-noop)
  1302. (put 'i 'latexinfo-format 'latexinfo-format-noop)
  1303. (put 'key 'latexinfo-format 'latexinfo-format-noop)
  1304. (put 'dmn 'latexinfo-format 'latexinfo-format-noop)
  1305. (put 'w 'latexinfo-format 'latexinfo-format-noop)
  1306.  
  1307. (defun latexinfo-format-noop ()
  1308.   (insert (latexinfo-parse-arg-discard))
  1309.   (goto-char latexinfo-command-start))
  1310.  
  1311. (put 'CODE 'latexinfo-format 'latexinfo-format-code)
  1312. (put 'code 'latexinfo-format 'latexinfo-format-code)
  1313. (put 'samp 'latexinfo-format 'latexinfo-format-code)
  1314. (put 'file 'latexinfo-format 'latexinfo-format-code)
  1315. (put 'kbd 'latexinfo-format 'latexinfo-format-code)
  1316. (defun latexinfo-format-code ()
  1317.   (insert "`" (latexinfo-parse-arg-discard) "'")
  1318.   (goto-char latexinfo-command-start))
  1319.  
  1320. (put 'emph 'latexinfo-format 'latexinfo-format-emph)
  1321. (put 'strong 'latexinfo-format 'latexinfo-format-emph)
  1322. (defun latexinfo-format-emph ()
  1323.   (insert "*" (latexinfo-parse-arg-discard) "*")
  1324.   (goto-char latexinfo-command-start))
  1325.  
  1326. (put 'defn 'latexinfo-format 'latexinfo-format-defn)
  1327. (put 'dfn 'latexinfo-format 'latexinfo-format-defn)
  1328. (defun latexinfo-format-defn ()
  1329.   (insert "\"" (latexinfo-parse-arg-discard) "\"")
  1330.   (goto-char latexinfo-command-start))
  1331.  
  1332. (put 'bullet 'latexinfo-format 'latexinfo-format-bullet)
  1333. (defun latexinfo-format-bullet ()
  1334.   (latexinfo-parse-noarg)
  1335.   (insert "*"))
  1336.  
  1337. (put 'smallexample 'latexinfo-format 'latexinfo-format-example)
  1338. (put 'example 'latexinfo-format 'latexinfo-format-example)
  1339. (put 'quotation 'latexinfo-format 'latexinfo-format-example)
  1340. (put 'quote 'latexinfo-format 'latexinfo-format-example)
  1341. (put 'abstract 'latexinfo-format 'latexinfo-format-example)
  1342. (put 'display 'latexinfo-format 'latexinfo-format-example)
  1343. (defun latexinfo-format-example ()
  1344.   (latexinfo-push-stack 'example nil)
  1345.   (setq fill-column (- fill-column 5))
  1346.   (latexinfo-discard-to-eoline))
  1347.  
  1348. (put 'smallexample 'latexinfo-end 'latexinfo-end-example)
  1349. (put 'example 'latexinfo-end 'latexinfo-end-example)
  1350. (put 'quotation 'latexinfo-end 'latexinfo-end-example)
  1351. (put 'quote 'latexinfo-end 'latexinfo-end-example)
  1352. (put 'abstract 'latexinfo-end 'latexinfo-end-example)
  1353. (put 'display 'latexinfo-end 'latexinfo-end-example)
  1354. (defun latexinfo-end-example ()
  1355.   (setq fill-column (+ fill-column 5))
  1356.   (latexinfo-discard-command)
  1357.   (let ((stacktop
  1358.      (latexinfo-pop-stack 'example)))
  1359.     (latexinfo-do-itemize (nth 1 stacktop))))
  1360.  
  1361.  
  1362. (put 'smalllisp 'latexinfo-format 'latexinfo-format-lisp)
  1363. (put 'lisp 'latexinfo-format 'latexinfo-format-lisp)
  1364. (defun latexinfo-format-lisp ()
  1365.   (latexinfo-push-stack 'lisp nil)
  1366.   (setq fill-column (- fill-column 5))
  1367.   (latexinfo-discard-to-eoline))
  1368.  
  1369. (put 'smalllisp 'latexinfo-end 'latexinfo-end-lisp)
  1370. (put 'lisp 'latexinfo-end 'latexinfo-end-lisp)
  1371. (defun latexinfo-end-lisp ()
  1372.   (setq fill-column (+ fill-column 5))
  1373.   (latexinfo-discard-command)
  1374.   (let ((stacktop
  1375.      (latexinfo-pop-stack 'lisp)))
  1376.     (untabify (nth 1 stacktop) (point))
  1377.     (latexinfo-do-itemize (nth 1 stacktop))))
  1378.  
  1379. (put 'exdent 'latexinfo-format 'latexinfo-format-exdent)
  1380. (defun latexinfo-format-exdent ()
  1381.   (latexinfo-discard-command)
  1382.   (delete-region (point)
  1383.          (progn
  1384.           (skip-chars-forward " ")
  1385.           (point)))
  1386.   (insert ?\b)
  1387.   ;; Cancel out the deletion that latexinfo-do-itemize
  1388.   ;; is going to do at the end of this line.
  1389.   (save-excursion
  1390.     (end-of-line)
  1391.     (insert "\n     ")))
  1392.  
  1393. (put 'smallverbatim 'latexinfo-format 'latexinfo-format-smallverbatim)
  1394. (put 'smallverbatim 'latexinfo-end 'latexinfo-end-smallverbatim)
  1395. (defun latexinfo-end-smallverbatim ()
  1396.   (error "Nested verbatim environments are not supported"))
  1397.  
  1398. (put 'verbatim 'latexinfo-format 'latexinfo-format-verbatim)
  1399. (defun latexinfo-format-verbatim ()
  1400.   (latexinfo-discard-line)
  1401.   (untabify (point)
  1402.         (progn (re-search-forward  "\\\\end{verbatim}" nil nil)
  1403.            (point)))
  1404.   (beginning-of-line 1)
  1405.   (delete-region (point) (save-excursion (forward-line 1) (point))))
  1406.  
  1407. (put 'smallverbatim 'latexinfo-format 'latexinfo-format-smallverbatim)
  1408. (defun latexinfo-format-smallverbatim ()
  1409.   (latexinfo-discard-line)
  1410.   (untabify (point)
  1411.         (progn (re-search-forward  "\\\\end{smallverbatim}" nil nil)
  1412.            (point)))
  1413.   (beginning-of-line 1)
  1414.   (delete-region (point) (save-excursion (forward-line 1) (point))))
  1415.   
  1416.  
  1417. (put 'verbatimfile 'latexinfo-format 'latexinfo-format-verbatimfile)
  1418. (defun latexinfo-format-verbatimfile ()
  1419.   (let ((from (point)))
  1420.     (forward-char 1)
  1421.     (latexinfo-insert-input-files)
  1422.     (untabify (point)
  1423.           (progn     (re-search-forward  "\\\\end{verbatim}" nil nil)
  1424.             (point)))
  1425.     (beginning-of-line 1)
  1426.     (delete-region (point) (save-excursion (forward-line 1) (point)))))
  1427.  
  1428. (put 'smallverbatimfile 'latexinfo-format 'latexinfo-format-smallverbatimfile)
  1429. (defun latexinfo-format-smallverbatimfile ()
  1430.   (let ((from (point)))
  1431.     (forward-char 1)
  1432.     (latexinfo-insert-input-files)
  1433.     (untabify (point)
  1434.           (progn     (re-search-forward  "\\\\end{smallverbatim}" nil nil)
  1435.             (point)))
  1436.     (beginning-of-line 1)
  1437.     (delete-region (point) (save-excursion (forward-line 1) (point)))))
  1438.  
  1439. (put 'verbatim 'latexinfo-end 'latexinfo-end-verbatim)
  1440. (defun latexinfo-end-verbatim ()
  1441.   (error "Nested verbatim environments are not supported"))
  1442.  
  1443. (put 'verb 'latexinfo-format 'latexinfo-format-verb)
  1444. (defun latexinfo-format-verb ()
  1445.   "Handle the LaTeX \\verb command."
  1446.    (delete-region latexinfo-command-start latexinfo-command-end)
  1447.    (let ((the-char (buffer-substring (point) (+ 1 (point)))))
  1448.      (delete-char 1)
  1449.      (skip-chars-forward (concat "^" the-char))
  1450.      (delete-char 1)
  1451.      )
  1452.    )
  1453.  
  1454.  
  1455. ; The \cartouche command is a noop in Info; in a printed manual,
  1456. ; it makes a box with rounded corners.
  1457. (put 'cartouche 'latexinfo-format 'latexinfo-discard-line)
  1458. (put 'cartouche 'latexinfo-end 'latexinfo-discard-command)
  1459.  
  1460. ;;; flushleft and format environments
  1461. ; The flushleft environment command left justifies every line but leaves the
  1462. ; right end ragged.  As far as Info is concerned, \flushleft is a
  1463. ; `do-nothing' command.
  1464. ; The \begin{format} command is similar to \begin{example} except that
  1465. ; it does not indent; this means that in Info, format is similar to flushleft.
  1466.  
  1467. (put 'format 'latexinfo-format 'latexinfo-format-flushleft)
  1468. (put 'flushleft 'latexinfo-format 'latexinfo-format-flushleft)
  1469. (defun latexinfo-format-flushleft ()
  1470.   (latexinfo-discard-line))
  1471.  
  1472. (put 'format 'latexinfo-end 'latexinfo-end-flushleft)
  1473. (put 'flushleft 'latexinfo-end 'latexinfo-end-flushleft)
  1474. (defun latexinfo-end-flushleft ()
  1475.   (latexinfo-discard-command))
  1476.  
  1477.  
  1478. ;;; \begin{flushright}
  1479. ; The \begin{flushright} command right justifies every line but leaves the
  1480. ; left end ragged.  Spaces and tabs at the right ends of lines are
  1481. ; removed so that visible text lines up on the right side.
  1482.  
  1483. (put 'flushright 'latexinfo-format 'latexinfo-format-flushright)
  1484. (defun latexinfo-format-flushright ()
  1485.   (latexinfo-push-stack 'flushright nil)
  1486.   (latexinfo-discard-line))
  1487.  
  1488. (put 'flushright 'latexinfo-end 'latexinfo-end-flushright)
  1489. (defun latexinfo-end-flushright ()
  1490.   (latexinfo-discard-command)
  1491.   (let ((stacktop
  1492.          (latexinfo-pop-stack 'flushright)))
  1493.     (latexinfo-do-flushright (nth 1 stacktop))))
  1494.  
  1495. (defun latexinfo-do-flushright (from)
  1496.   (save-excursion
  1497.     (while (progn (forward-line -1)
  1498.           (>= (point) from))
  1499.       (beginning-of-line)
  1500.       (insert
  1501.        (make-string
  1502.     (- fill-column
  1503.        (save-excursion
  1504.          (end-of-line) 
  1505.          (skip-chars-backward " \t")
  1506.          (delete-region (point) (progn (end-of-line) (point)))
  1507.          (current-column)))  
  1508.     ? )))))
  1509.  
  1510. (put 'beforenoterule 'latexinfo-format 'latexinfo-format-hline)
  1511. (put 'afternoterule 'latexinfo-format 'latexinfo-format-hline)
  1512. (put 'betweennoterule 'latexinfo-format 'latexinfo-format-hline)
  1513.  
  1514. (put 'implementation 'latexinfo-format 'latexinfo-format-note)
  1515. (put 'rationale 'latexinfo-format 'latexinfo-format-note)
  1516. (put 'sideremark 'latexinfo-format 'latexinfo-format-note)
  1517. (put 'note 'latexinfo-format 'latexinfo-format-note)
  1518. (defun latexinfo-format-note ()
  1519.   (latexinfo-push-stack 'example nil)
  1520.   (setq fill-column (- fill-column 5))
  1521.   (latexinfo-discard-line)
  1522. )
  1523.  
  1524. (put 'implementation 'latexinfo-end 'latexinfo-end-note)
  1525. (put 'rationale 'latexinfo-end 'latexinfo-end-note)
  1526. (put 'sideremark 'latexinfo-end 'latexinfo-end-note)
  1527. (put 'note 'latexinfo-end 'latexinfo-end-note)
  1528. (defun latexinfo-end-note ()
  1529.   (setq fill-column (+ fill-column 5))
  1530.   (latexinfo-discard-command)
  1531.   (let ((stacktop
  1532.      (latexinfo-pop-stack 'example)))
  1533.     (latexinfo-do-itemize (nth 1 stacktop)))
  1534. )
  1535.  
  1536. ;;; \ctrl, \TeX, \copyright, \minus, \dots
  1537. (put 'ctrl 'latexinfo-format 'latexinfo-format-ctrl)
  1538. (defun latexinfo-format-ctrl ()
  1539.   (let ((str (latexinfo-parse-arg-discard)))
  1540.     (insert "^" str)))
  1541.     ;;    (insert (logand 31 (aref str 0)))))
  1542.  
  1543. (put 'TeX 'latexinfo-format 'latexinfo-format-TeX)
  1544. (defun latexinfo-format-TeX ()
  1545.   (latexinfo-parse-noarg)
  1546.   (insert "TeX"))
  1547.  
  1548. (put 'copyright 'latexinfo-format 'latexinfo-format-copyright)
  1549. (defun latexinfo-format-copyright ()
  1550.   (latexinfo-parse-noarg)
  1551.   (insert "(C)"))
  1552.  
  1553. (put 'minus 'latexinfo-format 'latexinfo-format-minus)
  1554. (defun latexinfo-format-minus ()
  1555.   (latexinfo-parse-noarg)
  1556.   (insert "-"))
  1557.  
  1558. (put 'DOTS 'latexinfo-format 'latexinfo-format-dots)
  1559. (put 'dots 'latexinfo-format 'latexinfo-format-dots)
  1560. (defun latexinfo-format-dots ()
  1561.   (latexinfo-parse-noarg)
  1562.   (insert "..."))
  1563.  
  1564. ;;; Refilling and indenting:  \refill, \paragraphindent, \noindent
  1565. ;;; Indent only those paragraphs that are refilled as a result of an
  1566. ;;; \refill command.  
  1567.  
  1568. ;    * If the value is `asis', do not change the existing indentation at
  1569. ;      the starts of paragraphs.
  1570.  
  1571. ;    * If the value zero, delete any existing indentation.
  1572.  
  1573. ;    * If the value is greater than zero, indent each paragraph by that
  1574. ;      number of spaces.
  1575.  
  1576. ;;; But do not refill paragraphs with an \refill command that are
  1577. ;;; preceded by \noindent or are part of a table, list, or deffn.
  1578.  
  1579. (defvar latexinfo-paragraph-indent "asis"
  1580.   "Number of spaces for \\refill to indent a paragraph; else to leave as is.")
  1581.  
  1582. (put 'paragraphindent 'latexinfo-format 'latexinfo-paragraphindent)
  1583. (defun latexinfo-paragraphindent ()
  1584.   "Specify the number of spaces for \refill to indent a paragraph.
  1585. Default is to leave the number of spaces as is."
  1586.   (let ((arg  (latexinfo-parse-arg-discard)))
  1587.     (if (string= "asis" arg)
  1588.         (setq latexinfo-paragraph-indent "asis")
  1589.       (setq latexinfo-paragraph-indent (string-to-int arg)))))
  1590.  
  1591. (put 'refill 'latexinfo-format 'latexinfo-format-refill)
  1592. (defun latexinfo-format-refill ()
  1593.   "Refill paragraph. Also, indent first line as set by \\paragraphindent.
  1594. Default is to leave paragraph indentation as is."
  1595.   (latexinfo-discard-command)
  1596.   (forward-paragraph -1)     
  1597.   (if (looking-at "[ \t\n]*$") (forward-line 1))
  1598.   ;; Do not indent if an entry in a list, table, or deffn,
  1599.   ;; or if paragraph is preceded by \noindent.
  1600.   ;; Otherwise, indent
  1601.   (cond 
  1602.    ;; delete a \\noindent line and do not indent paragraph
  1603.    ((save-excursion (forward-line -1)
  1604.                     (looking-at "^\\\\noindent")) 
  1605.     (forward-line -1)
  1606.     (delete-region (point) (progn (forward-line 1) (point))))
  1607.    ;; do nothing if "asis"
  1608.    ((equal latexinfo-paragraph-indent "asis"))
  1609.    ;; do no indenting in list, etc.
  1610.    ((> latexinfo-stack-depth 0))   
  1611.    ;; otherwise delete existing whitespace and indent
  1612.    (t 
  1613.     (delete-region (point) (progn (skip-chars-forward " \t") (point)))
  1614.     (insert (make-string latexinfo-paragraph-indent ? ))))
  1615.   (forward-paragraph 1) 
  1616.   (forward-line -1)
  1617.   (end-of-line)
  1618.   (fill-paragraph nil))
  1619.  
  1620. (put 'noindent 'latexinfo-format 'latexinfo-noindent)
  1621. (defun latexinfo-noindent ()  
  1622.   (save-excursion 
  1623.     (forward-paragraph 1)
  1624.     (if (search-backward "\\refill"
  1625.                             (save-excursion (forward-line -1) (point)) t)
  1626.         () ; leave \noindent command so \refill command knows not to indent
  1627.       ;; else
  1628.       (latexinfo-discard-line))))
  1629.  
  1630.  
  1631. ;; Index generation
  1632.  
  1633. (put 'vindex 'latexinfo-format 'latexinfo-format-vindex)
  1634. (defun latexinfo-format-vindex ()
  1635.   (latexinfo-index 'latexinfo-vindex))
  1636.  
  1637. (put 'cindex 'latexinfo-format 'latexinfo-format-cindex)
  1638. (defun latexinfo-format-cindex ()
  1639.   (latexinfo-index 'latexinfo-cindex))
  1640.  
  1641. (put 'findex 'latexinfo-format 'latexinfo-format-findex)
  1642. (defun latexinfo-format-findex ()
  1643.   (latexinfo-index 'latexinfo-findex))
  1644.  
  1645. (put 'pindex 'latexinfo-format 'latexinfo-format-pindex)
  1646. (defun latexinfo-format-pindex ()
  1647.   (latexinfo-index 'latexinfo-pindex))
  1648.  
  1649. (put 'tindex 'latexinfo-format 'latexinfo-format-tindex)
  1650. (defun latexinfo-format-tindex ()
  1651.   (latexinfo-index 'latexinfo-tindex))
  1652.  
  1653. (put 'kindex 'latexinfo-format 'latexinfo-format-kindex)
  1654. (defun latexinfo-format-kindex ()
  1655.   (latexinfo-index 'latexinfo-kindex))
  1656.  
  1657. (put 'label 'latexinfo-format 'latexinfo-format-refindex)
  1658. (defun latexinfo-format-refindex ()
  1659.   (latexinfo-index 'latexinfo-refindex))
  1660.  
  1661. (defun latexinfo-index (indexvar)
  1662.   (let ((arg (latexinfo-parse-expanded-arg)))
  1663.     (latexinfo-discard-command)
  1664.     ;; Delete eol if the index command is the only thing on a line
  1665.     (if (and (eolp) (bolp) (not (eobp))) (delete-char 1))
  1666.     (set indexvar
  1667.      (cons (list arg
  1668.                      latexinfo-last-node
  1669.                      ;; Region formatting may not provide last node position.
  1670.              (if latexinfo-last-node-pos
  1671.                          (1+ (count-lines latexinfo-last-node-pos (point)))
  1672.                        1))
  1673.            (symbol-value indexvar)))))
  1674.  
  1675. (put 'pageref 'latexinfo-format 'latexinfo-format-ref)
  1676. (put 'ref 'latexinfo-format 'latexinfo-format-ref)
  1677. (defun latexinfo-format-ref ()
  1678.   (latexinfo-format-do-ref 
  1679.    (latexinfo-parse-arg-discard) 'latexinfo-refindex))
  1680.  
  1681. (defun latexinfo-format-do-ref (arg index)
  1682.   (let ((entry (assoc arg (symbol-value index))))
  1683.     (if (and entry (cdr entry) (car (cdr entry)))
  1684.     (insert "*Note " (car (cdr entry)) "::")
  1685.       (let ((entry (assoc arg (symbol-value 
  1686.                    (intern (concat (symbol-name index) "-old"))))))
  1687.     (if (and entry (cdr entry) (car (cdr entry)))
  1688.         (insert "*Note " (car (cdr entry)) "::")
  1689.       (insert "?"))))))
  1690.  
  1691. (defconst latexinfo-indexvar-alist
  1692.   '(("cp" . latexinfo-cindex)
  1693.     ("fn" . latexinfo-findex)
  1694.     ("vr" . latexinfo-vindex)
  1695.     ("tp" . latexinfo-tindex)
  1696.     ("pg" . latexinfo-pindex)
  1697.     ("ky" . latexinfo-kindex)))
  1698.  
  1699. (put 'printindex 'latexinfo-format 'latexinfo-format-printindex)
  1700. (defun latexinfo-format-printindex ()
  1701.   (let ((indexelts (symbol-value
  1702.             (cdr (assoc (latexinfo-parse-arg-discard)
  1703.                 latexinfo-indexvar-alist))))
  1704.     opoint)
  1705.     (insert "\n* Menu:\n\n")
  1706.     (setq opoint (point))
  1707.     (latexinfo-print-index nil indexelts)
  1708.     (if (eq system-type 'vax-vms) 
  1709.     (latexinfo-sort-region opoint (point))
  1710.       (shell-command-on-region opoint (point) "sort -fd" 1))))
  1711.  
  1712. (defun latexinfo-print-index (file indexelts)
  1713.   (while indexelts
  1714.     (if (stringp (car (car indexelts)))
  1715.     (insert "* " (car (car indexelts))
  1716.         ": " (if file (concat "(" file ")") "")
  1717.         (nth 1 (car indexelts)) ".\n")
  1718.       ;; index entries from \include'd file
  1719.       (latexinfo-print-index (nth 1 (car indexelts))
  1720.                (nth 2 (car indexelts))))
  1721.     (setq indexelts (cdr indexelts))))
  1722.  
  1723.  
  1724. ;;;; Lisp Definitions have been moved out into the elisp style.
  1725.  
  1726. ;;; \set, \clear, \ifset, \ifclear
  1727.  
  1728. ;; If a flag is set with \set FLAG, then text between \ifset and \end
  1729. ;; ifset is formatted normally, but if the flag is is cleared with
  1730. ;; \clear FLAG, then the text is not formatted; it is ignored.
  1731.  
  1732. ;; If a flag is cleared with \clear FLAG, then text between \ifclear
  1733. ;; and \end ifclear is formatted normally, but if the flag is is set with
  1734. ;; \set FLAG, then the text is not formatted; it is ignored.  \ifclear
  1735. ;; is the opposite of \ifset.
  1736.  
  1737. (put 'clear 'latexinfo-format 'latexinfo-clear)
  1738. (defun latexinfo-clear ()
  1739.   "Clear the value of the flag."
  1740.   (let ((arg (latexinfo-parse-line-arg)))
  1741.     (if (not (boundp (intern arg)))
  1742.       (error  "\\clear flag `%s' is not defined by a \\set command." arg))
  1743.     (latexinfo-discard-command)
  1744.     (set (intern arg) nil)))
  1745.  
  1746. (put 'set 'latexinfo-format 'latexinfo-set)
  1747. (defun latexinfo-set ()
  1748.   "Set the value of the flag."
  1749.   (let ((arg (latexinfo-parse-arg-discard)))
  1750.     (make-local-variable (intern arg))
  1751.     (set (intern arg) t)))
  1752.  
  1753. (put 'ifset 'latexinfo-end 'latexinfo-discard-command)
  1754. (put 'ifset 'latexinfo-format 'latexinfo-if-set)
  1755. (defun latexinfo-if-set ()
  1756.   "If set, continue formatting; else do not format region up to \\end{ifset}"
  1757.   (let ((arg (latexinfo-parse-line-arg)))
  1758.     (if (not (boundp (intern arg)))
  1759.       (error  "\\ifset flag `%s' is not defined by a \\set command." arg))
  1760.     (latexinfo-discard-command)
  1761.     (if  (symbol-value (intern arg))
  1762.         ;; (message  "%s is true." arg)
  1763.         () 
  1764.       ;; (message  "%s is false." arg)
  1765.       (delete-region latexinfo-command-start
  1766.                      (progn (re-search-forward "\\\\end[ {]ifset[ }\t]*\n")
  1767.                             (point))))))
  1768.  
  1769. (put 'ifclear 'latexinfo-end 'latexinfo-discard-command)
  1770. (put 'ifclear 'latexinfo-format 'latexinfo-if-clear)
  1771. (defun latexinfo-if-clear ()
  1772.   "If clear, do not format up to \\end{ifclear}; else continue formatting."
  1773.   (let ((arg (latexinfo-parse-line-arg)))
  1774.     (if (not (boundp (intern arg)))
  1775.       (error  "\\ifclear flag `%s' is not defined by a \\set command." arg))
  1776.     (latexinfo-discard-command)
  1777.     (if  (symbol-value (intern arg))
  1778.       (delete-region latexinfo-command-start
  1779.                      (progn (re-search-forward "\\\\end[ {]ifset[ }\t]*\n")
  1780.                             (point))))))
  1781.  
  1782. ;; process included files
  1783. (put 'include 'latexinfo-format 'latexinfo-format-include)
  1784. (defun latexinfo-format-include ()
  1785.   (let ((filename (latexinfo-parse-arg-discard))
  1786.     (default-directory input-directory)
  1787.     subindex)
  1788.     (setq subindex
  1789.       (save-excursion
  1790.         (progn (find-file
  1791.             (cond ((file-readable-p filename)
  1792.                filename)
  1793.               ((file-readable-p (concat filename ".latexinfo"))
  1794.                (concat filename ".latexinfo"))
  1795.               ((file-readable-p (concat filename ".tex"))
  1796.                (concat filename ".tex"))
  1797.               ((file-readable-p filename)
  1798.                filename)
  1799.               (t (error "\\include'd file %s not found"
  1800.                     filename))))
  1801.            (latexinfo-format-buffer-1))))
  1802.     (latexinfo-subindex 'latexinfo-vindex (car subindex) (nth 1 subindex))
  1803.     (latexinfo-subindex 'latexinfo-findex (car subindex) (nth 2 subindex))
  1804.     (latexinfo-subindex 'latexinfo-cindex (car subindex) (nth 3 subindex))
  1805.     (latexinfo-subindex 'latexinfo-pindex (car subindex) (nth 4 subindex))
  1806.     (latexinfo-subindex 'latexinfo-tindex (car subindex) (nth 5 subindex))
  1807.     (latexinfo-subindex 'latexinfo-kindex (car subindex) (nth 6 subindex))))
  1808.  
  1809. (defun latexinfo-subindex (indexvar file content)
  1810.   (set indexvar (cons (list 'recurse file content)
  1811.               (symbol-value indexvar))))
  1812.  
  1813. ;; Sort an index which is in the current buffer between START and END.
  1814. ;; Used on VMS, where the `sort' utility is not available.
  1815. (defun latexinfo-sort-region (start end)
  1816.   (require 'sort)
  1817.   (save-restriction
  1818.     (narrow-to-region start end)
  1819.     (sort-subr nil 'forward-line 'end-of-line 'latexinfo-sort-startkeyfun)))
  1820.  
  1821. ;; Subroutine for sorting an index.
  1822. ;; At start of a line, return a string to sort the line under.
  1823. (defun latexinfo-sort-startkeyfun ()
  1824.   (let ((line
  1825.      (buffer-substring (point) (save-excursion (end-of-line) (point)))))
  1826.     ;; Canonicalize whitespace and eliminate funny chars.
  1827.     (while (string-match "[ \t][ \t]+\\|[^a-z0-9 ]+" line)
  1828.       (setq line (concat (substring line 0 (match-beginning 0))
  1829.              " "
  1830.              (substring line (match-end 0) (length line)))))
  1831.     line))
  1832.  
  1833. ;; Some cannot be handled - just ignore them and junk the line
  1834.  
  1835. (defun latexinfo-unsupported ()
  1836.   (message "Unsupported LaTeXinfo command: %s"
  1837.    (buffer-substring latexinfo-command-start latexinfo-command-end))
  1838.   (latexinfo-parse-noarg)
  1839.   )
  1840.  
  1841. (defun batch-latexinfo-format ()
  1842.   "Runs  latexinfo-format-buffer  on the files remaining on the command line.
  1843. Must be used only with -batch, and kills emacs on completion.
  1844. Each file will be processed even if an error occurred previously.
  1845. For example, invoke
  1846.   \"emacs -batch -funcall batch-latexinfo-format $docs/ ~/*.tex\"."
  1847.   (if (not noninteractive)
  1848.       (error "batch-latexinfo-format may only be used -batch."))
  1849.   (let ((version-control t)
  1850.     (auto-save-default nil)
  1851.     (find-file-run-dired nil)
  1852.     (kept-old-versions 259259)
  1853.     (kept-new-versions 259259))
  1854.     (let ((error 0)
  1855.       file
  1856.       (files ()))
  1857.       (while command-line-args-left
  1858.     (setq file (expand-file-name (car command-line-args-left)))
  1859.     (cond ((not (file-exists-p file))
  1860.            (message ">> %s does not exist!" file)
  1861.            (setq error 1
  1862.              command-line-args-left (cdr command-line-args-left)))
  1863.           ((file-directory-p file)
  1864.            (setq command-line-args-left
  1865.              (nconc (directory-files file)
  1866.                 (cdr command-line-args-left))))
  1867.           (t
  1868.            (setq files (cons file files)
  1869.              command-line-args-left (cdr command-line-args-left)))))
  1870.       (while files
  1871.     (setq file (car files)
  1872.           files (cdr files))
  1873.     (condition-case err
  1874.         (progn
  1875.           (if buffer-file-name (kill-buffer (current-buffer)))
  1876.           (find-file file)
  1877.           (buffer-flush-undo (current-buffer))
  1878.           (set-buffer-modified-p nil)
  1879.           (latexinfo-mode)
  1880.           (message "Latexinfo formatting %s..." file)
  1881.           (latexinfo-format-buffer nil)
  1882.           (if (buffer-modified-p)
  1883.           (progn (message "Saving modified %s" (buffer-file-name))
  1884.              (save-buffer))))
  1885.       (error
  1886.        (message ">> Error: %s" (prin1-to-string err))
  1887.        (message ">>  point at")
  1888.        (let ((s (buffer-substring (point)
  1889.                       (min (+ (point) 100)
  1890.                        (point-max))))
  1891.          (tem 0))
  1892.          (while (setq tem (string-match "\n+" s tem))
  1893.            (setq s (concat (substring s 0 (match-beginning 0))
  1894.                    "\n>>  "
  1895.                    (substring s (match-end 0)))
  1896.              tem (1+ tem)))
  1897.          (message ">>  %s" s)))
  1898.       (setq error 1)))
  1899.       (kill-emacs error))))
  1900.  
  1901. ;;; LaTeX additions
  1902.  
  1903. (defun latexinfo-run-documentstyle-hooks ()
  1904.   "Foreach \\documentstyle-argument DOCSTYLE, look for DOCSTYLE-fmt.[el,elc]
  1905. in the current directory or load-path. If DOCSTYLE-fmt-hook is bound, run it."
  1906.   (goto-char (point-min))
  1907.   (search-forward "\\documentstyle")
  1908.   (if (looking-at "\\[")
  1909.       (let ((begin (1+ (point)))
  1910.             (end (save-excursion (search-forward "]") (point)))
  1911.             (options-list nil))
  1912.         (if (null latexinfo-formats-directory)
  1913.             (setq latexinfo-formats-directory default-directory))
  1914.         (while (re-search-forward ",\\|]" end t)
  1915.           (setq options-list (cons (buffer-substring begin (1- (point)))
  1916.                    options-list))
  1917.           (setq begin (point)))
  1918.         (setq options-list (nreverse options-list))
  1919.         (while options-list
  1920.       (let ((option (car options-list))
  1921.                 (filename nil))
  1922.             (if (not (memq (intern option) latexinfo-known-document-styles))
  1923.                 (progn
  1924.                   (message "Checking formatting option %s" option) ;(sit-for 2)
  1925.                   (if (load (concat option "-fmt") t) ; dont report errors
  1926.                       (let ((option-symbol
  1927.                              (intern (concat option "-fmt-hook"))))
  1928.             (if (fboundp option-symbol)
  1929.                 (progn
  1930.                   (message "Running %s formatting hooks" option)
  1931.                   (sit-for 1) 
  1932.                   (funcall option-symbol)))
  1933.                         (message (concat "Done loading file %s" option))
  1934.                     ; (sit-for 1) ; we want it fast
  1935.                         )
  1936.                     (message (concat option "-fmt not found"))
  1937.                     )
  1938.                   )
  1939.               )
  1940.         (setq options-list (cdr options-list)))))))
  1941.  
  1942. (put 'BACK 'latexinfo-format 'latexinfo-format-backslash)
  1943. (put 'back 'latexinfo-format 'latexinfo-format-backslash)
  1944. (defun latexinfo-format-backslash ()
  1945.   "replace \\back by \\"
  1946.   (latexinfo-parse-noarg)
  1947.   (insert "\\"))
  1948.  
  1949. (put 'same 'latexinfo-format 'latexinfo-discard-command)
  1950. (put 'same 'latexinfo-end 'latexinfo-discard-command)
  1951.  
  1952. (put 'cite 'latexinfo-format 'latexinfo-format-cite)
  1953. (defun latexinfo-format-cite ()
  1954.   (if (looking-at "[\\[]")
  1955.       (save-excursion
  1956.     (let ((here (point)) (str nil))
  1957.           (forward-sexp 1)
  1958.           (setq str (buffer-substring (1+ here) (- (point) 1)))
  1959.           (delete-region here (point))
  1960.           (if (eolp) (delete-char 1))
  1961.           (insert "[" (latexinfo-parse-arg-discard) ", " str "]")))
  1962.     (insert "[" (latexinfo-parse-arg-discard) "]"))
  1963.   (goto-char latexinfo-command-start))
  1964.  
  1965. (put 'hfill 'latexinfo-format 'latexinfo-format-hfill)
  1966. (defun latexinfo-format-hfill ()
  1967.   (latexinfo-parse-arg-discard)
  1968.   (insert-char ?\  (- fill-column
  1969.               (save-excursion
  1970.             (end-of-line 1)
  1971.             (current-column)))))
  1972.  
  1973. (put 'S 'latexinfo-format 'latexinfo-format-S)
  1974. (defun latexinfo-format-S ()
  1975.   (latexinfo-parse-noarg)
  1976.   (insert "Section"))
  1977.  
  1978. ;;; Some European support
  1979.  
  1980. ;;; \ss
  1981. (put 'ss 'latexinfo-format 'latexinfo-format-ss)
  1982. (defun latexinfo-format-ss ()
  1983.   (latexinfo-parse-noarg)
  1984.   (insert "ss"))
  1985.  
  1986. (put 'LaTeX 'latexinfo-format 'latexinfo-format-LaTeX)
  1987. (defun latexinfo-format-LaTeX ()
  1988.   (latexinfo-parse-noarg)
  1989.   (insert "LaTeX"))
  1990.  
  1991. (put 'BibTeX 'latexinfo-format 'latexinfo-format-BibTeX)
  1992. (defun latexinfo-format-BibTeX ()
  1993.   (latexinfo-parse-noarg)
  1994.   (insert "BibTeX"))
  1995.  
  1996. (put 'arrow 'latexinfo-format 'latexinfo-format-arrow)
  1997. (put 'result 'latexinfo-format 'latexinfo-format-arrow)
  1998. (defun latexinfo-format-arrow ()
  1999.   (latexinfo-parse-noarg)
  2000.   (insert "=> "))
  2001.  
  2002. (put 'leq 'latexinfo-format 'latexinfo-format-leq)
  2003. (defun latexinfo-format-leq ()
  2004.   (latexinfo-parse-noarg)
  2005.   (insert "<="))
  2006.  
  2007. (put 'geq 'latexinfo-format 'latexinfo-format-geq)
  2008. (defun latexinfo-format-geq ()
  2009.   (latexinfo-parse-noarg)
  2010.   (insert ">="))
  2011.  
  2012. (put 'pi 'latexinfo-format 'latexinfo-format-pi)
  2013. (defun latexinfo-format-pi ()
  2014.   (latexinfo-parse-noarg)
  2015.   (insert "pi"))
  2016.  
  2017. (put 'quad 'latexinfo-format 'latexinfo-format-quad)
  2018. (defun latexinfo-format-quad ()
  2019.   (latexinfo-parse-noarg)
  2020.   (insert "    "))
  2021.  
  2022. (put 'qquad 'latexinfo-format 'latexinfo-format-qquad)
  2023. (defun latexinfo-format-qquad ()
  2024.   (latexinfo-parse-noarg)
  2025.   (insert "      "))
  2026.  
  2027. (put 'pm 'latexinfo-format 'latexinfo-format-pm)
  2028. (defun latexinfo-format-pm ()
  2029.   (latexinfo-parse-noarg)
  2030.   (insert "+/-"))
  2031.  
  2032. ;;; Glyphs: \equiv, \error, etc
  2033.  
  2034. ;; \equiv           to show that two expressions are equivalent
  2035. ;; \error           to show an error message
  2036. ;; \expansion       to show what a macro expands to
  2037. ;; \point           to show the location of point in an example
  2038. ;; \print           to show what an evaluated expression prints
  2039. ;; \result          to indicate the value returned by an expression
  2040.  
  2041. (put 'equiv 'latexinfo-format 'latexinfo-format-equiv)
  2042. (defun latexinfo-format-equiv ()
  2043.   "Indicate the exact equivalence of two forms; special glyph: =="
  2044.   (latexinfo-parse-noarg)
  2045.   (insert "=="))
  2046.  
  2047. (put 'error 'latexinfo-format 'latexinfo-format-error)
  2048. (defun latexinfo-format-error ()
  2049.   "Indicate that the following text is an error message: error-->"
  2050.   (latexinfo-parse-noarg)
  2051.   (insert "error-->"))
  2052.  
  2053. (put 'expansion 'latexinfo-format 'latexinfo-format-expansion)
  2054. (defun latexinfo-format-expansion ()
  2055.   "Indicate the result of a macro expansion; special glyph: ==>"
  2056.   (latexinfo-parse-noarg)
  2057.   (insert "==>"))
  2058.  
  2059. (put 'point 'latexinfo-format 'latexinfo-format-point)
  2060. (defun latexinfo-format-point ()
  2061.   "Indicate the position of point; special glyph: -!-"
  2062.   (latexinfo-parse-noarg)
  2063.   (insert "-!-"))
  2064.  
  2065. (put 'print 'latexinfo-format 'latexinfo-format-print)
  2066. (defun latexinfo-format-print ()
  2067.   "Indicate printed output; special glyph: -|"
  2068.   (latexinfo-parse-noarg)
  2069.   (insert "-|"))
  2070.  
  2071.  
  2072. (put 'c 'latexinfo-format 'latexinfo-discard-commment-line)
  2073. (put 'comment 'latexinfo-format 'latexinfo-discard-commment-line)
  2074. (defun latexinfo-discard-commment-line ()
  2075.   "Discards commment lines, but tries to be more TeX like by deleting 
  2076. the following whitespace."
  2077.   (latexinfo-discard-line-with-args)
  2078.   (latexinfo-delete-whitespace)
  2079.   )
  2080.  
  2081. ;; Lots of bolio constructs do nothing in latexinfo.
  2082. (defun latexinfo-discard-line-with-args ()
  2083.   (goto-char latexinfo-command-start)
  2084.   (delete-region (point) (progn (forward-line 1) (point))))
  2085.  
  2086. (put 'need 'latexinfo-format 'latexinfo-discard-line-with-args)
  2087. (put 'newindex 'latexinfo-format 'latexinfo-discard-line-with-args)
  2088. (put 'synindex 'latexinfo-format 'latexinfo-discard-line-with-args)
  2089. (put 'syncodeindex 'latexinfo-format 'latexinfo-discard-line-with-args)
  2090. (put 'parindent 'latexinfo-format 'latexinfo-discard-line-with-args)
  2091. (put 'lispnarrowing 'latexinfo-format 'latexinfo-discard-line-with-args)
  2092. (put 'itemindent 'latexinfo-format 'latexinfo-discard-line-with-args)
  2093.  
  2094. (put 'PROTECT 'latexinfo-format 'latexinfo-parse-protected-argument)
  2095. (put 'protect 'latexinfo-format 'latexinfo-parse-protected-argument)
  2096. (defun latexinfo-parse-protected-argument ()
  2097.   ;; TeX gobbles the next whitespace.
  2098.   (goto-char latexinfo-command-end)
  2099.   (latexinfo-delete-whitespace)
  2100.   (cond ((looking-at "{")
  2101.      (setq latexinfo-command-end
  2102.            (save-excursion
  2103.          (forward-sexp 1) (point))))
  2104.     )
  2105.   (insert (prog1 (buffer-substring (1+ (point)) (1- latexinfo-command-end))
  2106.     (latexinfo-delete-command)))
  2107.   )
  2108.  
  2109. (put 'protect 'latexinfo-format 'latexinfo-parse-noarg)
  2110. (put 'PROTECT 'latexinfo-format 'latexinfo-parse-noarg)
  2111.  
  2112. ;; LaTeX noops
  2113. (put 'hsize 'latexinfo-format 'latexinfo-discard-line-with-args)
  2114. (put 'clearpage 'latexinfo-format 'latexinfo-discard-line-with-args)
  2115. (put 'newpage 'latexinfo-format 'latexinfo-discard-line-with-args)
  2116. (put 'includeonly 'latexinfo-format 'latexinfo-discard-line-with-args)
  2117.  
  2118. (put 'cleardoublepage 'latexinfo-format 'latexinfo-discard-line-with-args)
  2119. (put 'tableofcontents 'latexinfo-format 'latexinfo-discard-line-with-args)
  2120. (put 'listoftables 'latexinfo-format 'latexinfo-discard-line-with-args)
  2121. (put 'listoffigures 'latexinfo-format 'latexinfo-discard-line-with-args)
  2122. (put 'vspace 'latexinfo-format 'latexinfo-discard-line-with-args)
  2123. (put 'vspace* 'latexinfo-format 'latexinfo-discard-line-with-args)
  2124. (put 'markboth 'latexinfo-format 'latexinfo-discard-line-with-args)
  2125. (put 'markright 'latexinfo-format 'latexinfo-discard-line-with-args)
  2126. (put 'index 'latexinfo-format 'latexinfo-parse-arg-discard)
  2127. (put 'bibliographystyle 'latexinfo-format 'latexinfo-discard-line-with-args)
  2128. (put 'pagestyle 'latexinfo-format 'latexinfo-discard-line-with-args)
  2129. (put 'pagenumbering 'latexinfo-format 'latexinfo-discard-line-with-args)
  2130. (put 'part 'latexinfo-format 'latexinfo-discard-line-with-args)
  2131.  
  2132. (put 'cpsubindex 'latexinfo-format 'latexinfo-discard-line-with-args)
  2133.  
  2134. ;;; Catchall for latexinfo-format-region
  2135. (put 'documentstyle 'latexinfo-format 'latexinfo-discard-line-with-args)
  2136.  
  2137. ;;; Titlepage commands 
  2138.  
  2139. ;; Author
  2140. (put 'author 'latexinfo-format 'latexinfo-format-author)
  2141. (defun latexinfo-format-author ()
  2142.   (latexinfo-format-atd "author"))
  2143.  
  2144. (put 'and 'latexinfo-format 'latexinfo-format-and)
  2145. ;; This should really only be valid in titles.
  2146. (defun latexinfo-format-and ()
  2147.   (latexinfo-parse-noarg)
  2148.   (insert ?\n))
  2149.  
  2150. ;; title
  2151. (put 'title 'latexinfo-format 'latexinfo-format-title)
  2152. (defun latexinfo-format-title ()
  2153.   (latexinfo-format-atd "title"))
  2154.  
  2155. (put 'date 'latexinfo-format 'latexinfo-format-date)
  2156. (defun latexinfo-format-date ()
  2157.   (latexinfo-format-atd "date"))
  2158.  
  2159. (defun latexinfo-format-atd (atd)
  2160.   (delete-region latexinfo-command-start latexinfo-command-end)
  2161.   (latexinfo-push-stack 'center 0)
  2162.   (if (looking-at "{")
  2163.       (save-excursion
  2164.     (let ((here (point)) (str nil))
  2165.       (forward-sexp 1)
  2166.       (delete-char -1)
  2167.       (insert ?\n "\\end{center}")
  2168.       (goto-char here)
  2169.       (delete-char 1))
  2170.     (goto-char latexinfo-command-start))
  2171.     (error "No argument specified to the %s command" atd))
  2172.   )
  2173.  
  2174. ;;\today
  2175. (put 'today 'latexinfo-format 'latexinfo-format-today)
  2176. (defun latexinfo-format-today ()
  2177.   (delete-region latexinfo-command-start latexinfo-command-end)  
  2178.   (let* ((date-string (current-time-string))
  2179.      (month-alist   '(("Jan" . "January") ("Feb" . "February") 
  2180.               ("Mar" . "March") ("Apr" . "April")
  2181.               ("May" . "May") ("Jun" . "June") 
  2182.               ("Jul" . "July") ("Aug" . "August")
  2183.               ("Sep" . "September") ("Oct" . "October")
  2184.               ("Nov" . "November") ("Dec" . "December")))
  2185.      )
  2186.     (string-match "\\(...\\) \\(...\\) \\(..\\).*\\(19..\\)"
  2187.           (current-time-string) nil)
  2188.     (insert
  2189.      (concat (cdr (assoc (substring date-string 
  2190.                     (match-beginning 2) (match-end 2))
  2191.              month-alist))
  2192.          " " (substring date-string (match-beginning 3) (match-end 3))
  2193.          ", " (substring date-string (match-beginning 4) (match-end 4))
  2194.          ))
  2195.     )
  2196.   )
  2197.  
  2198. (put 'maketitle 'latexinfo-format 'latexinfo-format-maketitle)
  2199. (defun latexinfo-format-maketitle ()
  2200.   (latexinfo-parse-noarg))
  2201.  
  2202. (put 'finalout 'latexinfo-format 'latexinfo-format-finalout)
  2203. (defun latexinfo-format-finalout ()
  2204.   (latexinfo-parse-noarg))
  2205.  
  2206. (put 'sloppy 'latexinfo-format 'latexinfo-format-sloppy)
  2207. (defun latexinfo-format-sloppy ()
  2208.   (latexinfo-parse-noarg))
  2209.  
  2210. ;;; Bibliography
  2211. (put 'bibliography 'latexinfo-format 'latexinfo-format-bibliography)
  2212. (defun latexinfo-format-bibliography ()
  2213.   (let* ((arg (latexinfo-parse-arg-discard))
  2214.      (latexinfo-bbl-filename  (expand-file-name (concat arg ".bbl")))
  2215.      (here (point)))
  2216.     (eat-sexp)
  2217.     ;; This should be a chapter or a section.
  2218.     (insert "\\chapter*{References}" ?\n ?\n)
  2219.     (if (file-exists-p latexinfo-bbl-filename)
  2220.     (progn
  2221.       (insert-file latexinfo-bbl-filename)
  2222.       (exchange-point-and-mark)
  2223.       (narrow-to-region here (point))
  2224.       (goto-char (point-min))
  2225.       (quietly-replace-string "{\\em " "\\var{")
  2226.       (goto-char (point-min))
  2227.       (quietly-replace-string "{\\it " "\\emph{")
  2228.       (goto-char (point-min))
  2229.       (quietly-replace-string "{ " "\\r{")
  2230.       (widen)
  2231.       (goto-char latexinfo-command-start)
  2232.       )
  2233.       (message "Formatted bibliography file not found: %s" latexinfo-bbl-filename))
  2234.     )
  2235.   )
  2236.  
  2237. (put 'thebibliography 'latexinfo-format 'latexinfo-thebibliography)
  2238. (defun latexinfo-thebibliography ()
  2239.   (if (looking-at "}") (forward-char 1))
  2240.   (eat-sexp)
  2241.   (latexinfo-push-stack 'description "")
  2242.   (setq fill-column (- fill-column 5))
  2243.   (latexinfo-discard-line))
  2244.  
  2245. (put 'thebibliography 'latexinfo-end 'latexinfo-end-description)
  2246. (put 'bibitem 'latexinfo-format 'latexinfo-description-bibitem)
  2247. (defun latexinfo-description-bibitem ()
  2248.   (if (looking-at "}") (forward-char 1))
  2249.   (eat-sexp)
  2250.   (let ((arg (latexinfo-parse-arg-discard)))
  2251.     (insert ?\b arg "\n     \n"))
  2252.   (forward-line -2))
  2253.  
  2254. (put 'newblock 'latexinfo-format 'latexinfo-parse-noarg)
  2255.  
  2256. (defun eat-sexp ()
  2257.   (delete-region (point) (save-excursion (forward-sexp 1) (point))))
  2258.  
  2259. (provide 'latexinfo)
  2260.  
  2261. ;;; Shut Emacs up about setting the mark.
  2262. (defun quietly-replace-string (from-string to-string &optional delimited)
  2263.   "\
  2264. Replace occurrences of FROM-STRING with TO-STRING.
  2265. Preserve case in each match if  case-replace  and  case-fold-search
  2266. are non-nil and FROM-STRING has no uppercase letters.
  2267. Third arg DELIMITED (prefix arg if interactive) non-nil means replace
  2268. only matches surrounded by word boundaries."
  2269.   (quietly-perform-replace from-string to-string nil nil delimited)
  2270.   )
  2271.  
  2272. (defun quietly-replace-regexp (regexp to-string &optional delimited)
  2273.   "\
  2274. Replace things after point matching REGEXP with TO-STRING.
  2275. Preserve case in each match if case-replace and case-fold-search
  2276. are non-nil and REGEXP has no uppercase letters.
  2277. Third arg DELIMITED (prefix arg if interactive) non-nil means replace
  2278. only matches surrounded by word boundaries.
  2279. In TO-STRING, \\& means insert what matched REGEXP,
  2280. and \\=\\<n> means insert what matched <n>th \\(...\\) in REGEXP."
  2281.   (quietly-perform-replace regexp to-string nil t delimited)
  2282.   )
  2283.  
  2284.  
  2285. (defun quietly-push-mark (&optional location nomsg)
  2286.   "Set mark at LOCATION (point, by default) and push old mark on mark ring.
  2287. Displays \"Mark set\" unless the optional second arg NOMSG is non-nil."
  2288.   (if (null (mark))
  2289.       nil
  2290.     (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
  2291.     (if (> (length mark-ring) mark-ring-max)
  2292.         (progn
  2293.           (move-marker (car (nthcdr mark-ring-max mark-ring)) nil)
  2294.           (setcdr (nthcdr (1- mark-ring-max) mark-ring) nil))))
  2295.   (set-mark (or location (point)))
  2296.   )
  2297.  
  2298.  
  2299. (defun quietly-perform-replace (from-string to-string
  2300.                 query-flag regexp-flag delimited-flag)
  2301.   (let ((nocasify (not (and case-fold-search case-replace
  2302.                 (string-equal from-string
  2303.                       (downcase from-string)))))
  2304.     (literal (not regexp-flag))
  2305.     (search-function (if regexp-flag 're-search-forward 'search-forward))
  2306.     (search-string from-string)
  2307.     (keep-going t)
  2308.     (lastrepl nil))            ;Position after last match considered.
  2309.     (if delimited-flag
  2310.     (setq search-function 're-search-forward
  2311.           search-string (concat "\\b"
  2312.                     (if regexp-flag from-string
  2313.                       (regexp-quote from-string))
  2314.                     "\\b")))
  2315.     (quietly-push-mark (point) t)
  2316.     (quietly-push-mark (point) t)
  2317.     (while (and keep-going
  2318.         (not (eobp))
  2319.         (progn
  2320.          (set-mark (point))
  2321.          (funcall search-function search-string nil t)))
  2322.       ;; Don't replace the null string 
  2323.       ;; right after end of previous replacement.
  2324.       (if (eq lastrepl (point))
  2325.       (forward-char 1)
  2326.     (undo-boundary)
  2327.     (if (not query-flag)
  2328.         (replace-match to-string nocasify literal)
  2329.       (let (done replaced)
  2330.         (while (not done)
  2331.           ;; Preserve the match data.  Process filters and sentinels
  2332.           ;; could run inside read-char..
  2333.           (let ((data (match-data))
  2334.             (help-form
  2335.              '(concat "Query replacing "
  2336.                   (if regexp-flag "regexp " "")
  2337.                   from-string " with " to-string ".\n\n"
  2338.                   (substitute-command-keys query-replace-help))))
  2339.         (setq char help-char)
  2340.         (while (= char help-char)
  2341.           (message "Query replacing %s with %s: " from-string to-string)
  2342.           (setq char (read-char))
  2343.           (if (= char ??)
  2344.               (setq unread-command-char help-char char help-char)))
  2345.         (store-match-data data))
  2346.           (cond ((or (= char ?\e)
  2347.              (= char ?q))
  2348.              (setq keep-going nil)
  2349.              (setq done t))
  2350.             ((= char ?^)
  2351.              (goto-char (mark))
  2352.              (setq replaced t))
  2353.             ((or (= char ?\ )
  2354.              (= char ?y))
  2355.              (or replaced
  2356.              (replace-match to-string nocasify literal))
  2357.              (setq done t))
  2358.             ((= char ?\.)
  2359.              (or replaced
  2360.              (replace-match to-string nocasify literal))
  2361.              (setq keep-going nil)
  2362.              (setq done t))
  2363.             ((= char ?\,)
  2364.              (if (not replaced)
  2365.              (progn
  2366.                (replace-match to-string nocasify literal)
  2367.                (setq replaced t))))
  2368.             ((= char ?!)
  2369.              (or replaced
  2370.              (replace-match to-string nocasify literal))
  2371.              (setq done t query-flag nil))
  2372.             ((or (= char ?\177)
  2373.              (= char ?n))
  2374.              (setq done t))
  2375.             ((= char ?\C-l)
  2376.              (recenter nil))
  2377.             ((= char ?\C-r)
  2378.              (store-match-data
  2379.                (prog1 (match-data)
  2380.              (save-excursion (recursive-edit)))))
  2381.             ((= char ?\C-w)
  2382.              (delete-region (match-beginning 0) (match-end 0))
  2383.              (store-match-data
  2384.                (prog1 (match-data)
  2385.              (save-excursion (recursive-edit))))
  2386.              (setq replaced t))
  2387.             (t
  2388.              (setq keep-going nil)
  2389.              (setq unread-command-char char)
  2390.              (setq done t))))))
  2391.     (setq lastrepl (point))))
  2392.     (pop-mark)
  2393.     keep-going))
  2394.  
  2395.  
  2396. ;; The overall process is one of:
  2397. ;;  (latexinfo-insert-node-lines (point-min) (point-max) t)
  2398. ;;  (mark-whole-buffer)
  2399. ;;  (latexinfo-sequential-node-update t)
  2400. ;;  (latexinfo-all-menus-update)
  2401. ;;  (latexinfo-master-menu nil)
  2402. ;;  (latexinfo-format-buffer t)