Mercurial > emacs
comparison lisp/textmodes/tex-mode.el @ 37896:5cc52d5c2f2b
(tex-mode-syntax-table): Add ^.
(tex-font-lock-keywords-1, tex-font-lock-keywords-2):
Allow spaces around macro arguments.
(tex-mode-map): Inherit from text-mode-map, but rebind \t to
indent-for-tab-command.
(latex-mode-map, plain-tex-mode-map): New keymaps.
Inherit from tex-mode-map.
(tex-common-initialization): Don't setup the keymap any more
since it's now done right by define-derived-mode.
(latex-mode): Set skeleton-end-hook to nil.
(latex-skeleton-end-hook): Remove.
(tex-latex-block, latex-insert-item): Simplify.
(latex-syntax-after): Use following-char rather than char-after.
(tex-discount-args-cmds, tex-count-words): New functions.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Fri, 25 May 2001 22:08:34 +0000 |
parents | 595ee2f062cf |
children | 0f57d8b106f1 |
comparison
equal
deleted
inserted
replaced
37895:41ca5705b623 | 37896:5cc52d5c2f2b |
---|---|
279 (?~ . " ") | 279 (?~ . " ") |
280 (?$ . "$$") | 280 (?$ . "$$") |
281 (?\\ . "/") | 281 (?\\ . "/") |
282 (?\" . ".") | 282 (?\" . ".") |
283 (?& . ".") | 283 (?& . ".") |
284 (?_ . ".")) | 284 (?_ . ".") |
285 (?^ . ".")) | |
285 "Syntax table used while in TeX mode.") | 286 "Syntax table used while in TeX mode.") |
286 | 287 |
287 ;;;; | 288 ;;;; |
288 ;;;; Imenu support | 289 ;;;; Imenu support |
289 ;;;; | 290 ;;;; |
435 "setlength" "addtolength" "settowidth") | 436 "setlength" "addtolength" "settowidth") |
436 t)) | 437 t)) |
437 (includes (regexp-opt | 438 (includes (regexp-opt |
438 '("input" "include" "includeonly" "bibliography" | 439 '("input" "include" "includeonly" "bibliography" |
439 "epsfig" "psfig" "epsf" "nofiles" "usepackage" | 440 "epsfig" "psfig" "epsf" "nofiles" "usepackage" |
441 "documentstyle" "documentclass" "verbatiminput" | |
440 "includegraphics" "includegraphics*") | 442 "includegraphics" "includegraphics*") |
441 t)) | 443 t)) |
442 ;; Miscellany. | 444 ;; Miscellany. |
443 (slash "\\\\") | 445 (slash "\\\\") |
444 (opt "\\(\\[[^]]*\\]\\)?") | 446 (opt " *\\(\\[[^]]*\\] *\\)*") |
447 ;; This would allow highlighting \newcommand\CMD but requires | |
448 ;; adapting subgroup numbers below. | |
449 ;; (arg "\\(?:{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)\\|\\\\[a-z*]+\\)")) | |
445 (arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)")) | 450 (arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)")) |
446 (list | 451 (list |
447 ;; Heading args. | 452 ;; Heading args. |
448 (list (concat slash headings "\\*?" opt arg) | 453 (list (concat slash headings "\\*?" opt arg) |
449 ;; If ARG ends up matching too much (if the {} don't match, f.ex) | 454 ;; If ARG ends up matching too much (if the {} don't match, f.ex) |
454 ;; a lot more, which might suddenly include a comment | 459 ;; a lot more, which might suddenly include a comment |
455 ;; so you get things highlighted bold when you type them | 460 ;; so you get things highlighted bold when you type them |
456 ;; but they get turned back to normal a little while later | 461 ;; but they get turned back to normal a little while later |
457 ;; because "there's already a face there". | 462 ;; because "there's already a face there". |
458 ;; Using `keep' works around this un-intuitive behavior as well | 463 ;; Using `keep' works around this un-intuitive behavior as well |
459 ;; as improves the behavior in the very rare case where you do have | 464 ;; as improves the behavior in the very rare case where you do |
460 ;; a comment in ARG. | 465 ;; have a comment in ARG. |
461 3 'font-lock-function-name-face 'keep) | 466 3 'font-lock-function-name-face 'keep) |
467 (list (concat slash "\\(re\\)?newcommand\\** *\\(\\\\[A-Za-z@]+\\)") | |
468 2 'font-lock-function-name-face 'keep) | |
462 ;; Variable args. | 469 ;; Variable args. |
463 (list (concat slash variables arg) 2 'font-lock-variable-name-face) | 470 (list (concat slash variables " *" arg) 2 'font-lock-variable-name-face) |
464 ;; Include args. | 471 ;; Include args. |
465 (list (concat slash includes opt arg) 3 'font-lock-builtin-face) | 472 (list (concat slash includes opt arg) 3 'font-lock-builtin-face) |
466 ;; Definitions. I think. | 473 ;; Definitions. I think. |
467 '("^[ \t]*\\\\def\\\\\\(\\(\\w\\|@\\)+\\)" | 474 '("^[ \t]*\\\\def *\\\\\\(\\(\\w\\|@\\)+\\)" |
468 1 font-lock-function-name-face)))) | 475 1 font-lock-function-name-face)))) |
469 "Subdued expressions to highlight in TeX modes.") | 476 "Subdued expressions to highlight in TeX modes.") |
470 | 477 |
471 (defconst tex-font-lock-keywords-2 | 478 (defconst tex-font-lock-keywords-2 |
472 (append tex-font-lock-keywords-1 | 479 (append tex-font-lock-keywords-1 |
479 (type (regexp-opt '("texttt" "textmd" "textrm" "textsf") t)) | 486 (type (regexp-opt '("texttt" "textmd" "textrm" "textsf") t)) |
480 ;; | 487 ;; |
481 ;; Names of commands whose arg should be fontified as a citation. | 488 ;; Names of commands whose arg should be fontified as a citation. |
482 (citations (regexp-opt | 489 (citations (regexp-opt |
483 '("label" "ref" "pageref" "vref" "eqref" | 490 '("label" "ref" "pageref" "vref" "eqref" |
484 "cite" "nocite" "index" "glossary" | 491 "cite" "nocite" "index" "glossary" "bibitem" |
485 ;; These are text, rather than citations. | 492 ;; These are text, rather than citations. |
486 ;; "caption" "footnote" "footnotemark" "footnotetext" | 493 ;; "caption" "footnote" "footnotemark" "footnotetext" |
487 ) | 494 ) |
488 t)) | 495 t)) |
489 ;; | 496 ;; |
490 ;; Names of commands that should be fontified. | 497 ;; Names of commands that should be fontified. |
491 (specials (regexp-opt | 498 (specials (regexp-opt |
492 '("\\" | 499 '("\\" "\\*" ;; "-" |
493 "linebreak" "nolinebreak" "pagebreak" "nopagebreak" | 500 "linebreak" "nolinebreak" "pagebreak" "nopagebreak" |
494 "newline" "newpage" "clearpage" "cleardoublepage" | 501 "newline" "newpage" "clearpage" "cleardoublepage" |
495 "displaybreak" "allowdisplaybreaks" "enlargethispage") | 502 "displaybreak" "allowdisplaybreaks" "enlargethispage") |
496 t)) | 503 t)) |
497 (general "\\([a-zA-Z@]+\\**\\|[^ \t\n]\\)") | 504 (general "\\([a-zA-Z@]+\\**\\|[^ \t\n]\\)") |
498 ;; | 505 ;; |
499 ;; Miscellany. | 506 ;; Miscellany. |
500 (slash "\\\\") | 507 (slash "\\\\") |
501 (opt "\\(\\[[^]]*\\]\\)?") | 508 (opt " *\\(\\[[^]]*\\] *\\)*") |
502 (arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)")) | 509 (arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)")) |
503 (list | 510 (list |
504 ;; | 511 ;; |
505 ;; Citation args. | 512 ;; Citation args. |
506 (list (concat slash citations opt arg) 3 'font-lock-constant-face) | 513 (list (concat slash citations opt arg) 3 'font-lock-constant-face) |
514 ;; | |
515 ;; Text between `` quotes ''. | |
516 (cons (concat (regexp-opt `("``" "\"<" "\"`" "<<" "") t) | |
517 "[^'\">]+" ;a bit pessimistic | |
518 (regexp-opt `("''" "\">" "\"'" ">>" "") t)) | |
519 'font-lock-string-face) | |
507 ;; | 520 ;; |
508 ;; Command names, special and general. | 521 ;; Command names, special and general. |
509 (cons (concat slash specials) 'font-lock-warning-face) | 522 (cons (concat slash specials) 'font-lock-warning-face) |
510 (concat slash general) | 523 (concat slash general) |
511 ;; | 524 ;; |
512 ;; Font environments. It seems a bit dubious to use `bold' etc. faces | 525 ;; Font environments. It seems a bit dubious to use `bold' etc. faces |
513 ;; since we might not be able to display those fonts. | 526 ;; since we might not be able to display those fonts. |
514 (list (concat slash bold arg) 2 '(quote bold) 'append) | 527 (list (concat slash bold " *" arg) 2 '(quote bold) 'append) |
515 (list (concat slash italic arg) 2 '(quote italic) 'append) | 528 (list (concat slash italic " *" arg) 2 '(quote italic) 'append) |
516 ;; (list (concat slash type arg) 2 '(quote bold-italic) 'append) | 529 ;; (list (concat slash type arg) 2 '(quote bold-italic) 'append) |
517 ;; | 530 ;; |
518 ;; Old-style bf/em/it/sl. Stop at `\\' and un-escaped `&', for tables. | 531 ;; Old-style bf/em/it/sl. Stop at `\\' and un-escaped `&', for tables. |
519 (list (concat "\\\\\\(\\(bf\\)\\|em\\|it\\|sl\\)\\>" | 532 (list (concat "\\\\\\(\\(bf\\)\\|em\\|it\\|sl\\)\\>" |
520 "\\(\\([^}&\\]\\|\\\\[^\\]\\)+\\)") | 533 "\\(\\([^}&\\]\\|\\\\[^\\]\\)+\\)") |
560 (define-key keymap [menu-bar tex tex-view] | 573 (define-key keymap [menu-bar tex tex-view] |
561 '(menu-item "Tex View" tex-view :enable (stringp tex-print-file)))) | 574 '(menu-item "Tex View" tex-view :enable (stringp tex-print-file)))) |
562 | 575 |
563 (defvar tex-mode-map | 576 (defvar tex-mode-map |
564 (let ((map (make-sparse-keymap))) | 577 (let ((map (make-sparse-keymap))) |
578 (set-keymap-parent map text-mode-map) | |
565 (tex-define-common-keys map) | 579 (tex-define-common-keys map) |
566 (define-key map "\"" 'tex-insert-quote) | 580 (define-key map "\"" 'tex-insert-quote) |
567 (define-key map "(" 'skeleton-pair-insert-maybe) | 581 (define-key map "(" 'skeleton-pair-insert-maybe) |
568 (define-key map "{" 'skeleton-pair-insert-maybe) | 582 (define-key map "{" 'skeleton-pair-insert-maybe) |
569 (define-key map "[" 'skeleton-pair-insert-maybe) | 583 (define-key map "[" 'skeleton-pair-insert-maybe) |
570 (define-key map "$" 'skeleton-pair-insert-maybe) | 584 (define-key map "$" 'skeleton-pair-insert-maybe) |
571 (define-key map "\n" 'tex-terminate-paragraph) | 585 (define-key map "\n" 'tex-terminate-paragraph) |
586 (define-key map "\t" 'indent-for-tab-command) | |
572 (define-key map "\M-\r" 'latex-insert-item) | 587 (define-key map "\M-\r" 'latex-insert-item) |
573 (define-key map "\C-c}" 'up-list) | 588 (define-key map "\C-c}" 'up-list) |
574 (define-key map "\C-c{" 'tex-insert-braces) | 589 (define-key map "\C-c{" 'tex-insert-braces) |
575 (define-key map "\C-c\C-r" 'tex-region) | 590 (define-key map "\C-c\C-r" 'tex-region) |
576 (define-key map "\C-c\C-b" 'tex-buffer) | 591 (define-key map "\C-c\C-b" 'tex-buffer) |
591 '(menu-item "TeX Region" tex-region :enable mark-active)) | 606 '(menu-item "TeX Region" tex-region :enable mark-active)) |
592 (define-key map [menu-bar tex tex-buffer] | 607 (define-key map [menu-bar tex tex-buffer] |
593 '("TeX Buffer" . tex-buffer)) | 608 '("TeX Buffer" . tex-buffer)) |
594 (define-key map [menu-bar tex tex-file] '("TeX File" . tex-file)) | 609 (define-key map [menu-bar tex tex-file] '("TeX File" . tex-file)) |
595 map) | 610 map) |
596 "Keymap for TeX modes.") | 611 "Keymap shared by TeX modes.") |
612 | |
613 (defvar latex-mode-map | |
614 (let ((map (make-sparse-keymap))) | |
615 (set-keymap-parent map tex-mode-map) | |
616 map) | |
617 "Keymap for `latex-mode'. See also `tex-mode-map'.") | |
618 | |
619 (defvar plain-tex-mode-map | |
620 (let ((map (make-sparse-keymap))) | |
621 (set-keymap-parent map tex-mode-map) | |
622 map) | |
623 "Keymap for `plain-tex-mode'. See also `tex-mode-map'.") | |
597 | 624 |
598 (defvar tex-shell-map | 625 (defvar tex-shell-map |
599 (let ((m (make-sparse-keymap))) | 626 (let ((m (make-sparse-keymap))) |
600 (set-keymap-parent m shell-mode-map) | 627 (set-keymap-parent m shell-mode-map) |
601 (tex-define-common-keys m) | 628 (tex-define-common-keys m) |
614 (defvar tex-latex-face-alist | 641 (defvar tex-latex-face-alist |
615 `((italic . "{\\em ") | 642 `((italic . "{\\em ") |
616 ,@tex-face-alist) | 643 ,@tex-face-alist) |
617 "Alist of face and LaTeX font name for facemenu.") | 644 "Alist of face and LaTeX font name for facemenu.") |
618 | 645 |
619 ;;; This would be a lot simpler if we just used a regexp search, | 646 ;; This would be a lot simpler if we just used a regexp search, |
620 ;;; but then it would be too slow. | 647 ;; but then it would be too slow. |
621 ;;;###autoload | 648 ;;;###autoload |
622 (defun tex-mode () | 649 (defun tex-mode () |
623 "Major mode for editing files of input for TeX, LaTeX, or SliTeX. | 650 "Major mode for editing files of input for TeX, LaTeX, or SliTeX. |
624 Tries to determine (by looking at the beginning of the file) whether | 651 Tries to determine (by looking at the beginning of the file) whether |
625 this file is for plain TeX, LaTeX, or SliTeX and calls `plain-tex-mode', | 652 this file is for plain TeX, LaTeX, or SliTeX and calls `plain-tex-mode', |
674 | 701 |
675 Use \\[tex-validate-buffer] to check buffer for paragraphs containing | 702 Use \\[tex-validate-buffer] to check buffer for paragraphs containing |
676 mismatched $'s or braces. | 703 mismatched $'s or braces. |
677 | 704 |
678 Special commands: | 705 Special commands: |
679 \\{tex-mode-map} | 706 \\{plain-tex-mode-map} |
680 | 707 |
681 Mode variables: | 708 Mode variables: |
682 tex-run-command | 709 tex-run-command |
683 Command string used by \\[tex-region] or \\[tex-buffer]. | 710 Command string used by \\[tex-region] or \\[tex-buffer]. |
684 tex-directory | 711 tex-directory |
722 | 749 |
723 Use \\[tex-validate-buffer] to check buffer for paragraphs containing | 750 Use \\[tex-validate-buffer] to check buffer for paragraphs containing |
724 mismatched $'s or braces. | 751 mismatched $'s or braces. |
725 | 752 |
726 Special commands: | 753 Special commands: |
727 \\{tex-mode-map} | 754 \\{latex-mode-map} |
728 | 755 |
729 Mode variables: | 756 Mode variables: |
730 latex-run-command | 757 latex-run-command |
731 Command string used by \\[tex-region] or \\[tex-buffer]. | 758 Command string used by \\[tex-region] or \\[tex-buffer]. |
732 tex-directory | 759 tex-directory |
784 (set (make-local-variable 'indent-line-function) 'latex-indent) | 811 (set (make-local-variable 'indent-line-function) 'latex-indent) |
785 (set (make-local-variable 'fill-indent-according-to-mode) t) | 812 (set (make-local-variable 'fill-indent-according-to-mode) t) |
786 (set (make-local-variable 'outline-regexp) latex-outline-regexp) | 813 (set (make-local-variable 'outline-regexp) latex-outline-regexp) |
787 (set (make-local-variable 'outline-level) 'latex-outline-level) | 814 (set (make-local-variable 'outline-level) 'latex-outline-level) |
788 (set (make-local-variable 'forward-sexp-function) 'latex-forward-sexp) | 815 (set (make-local-variable 'forward-sexp-function) 'latex-forward-sexp) |
789 (set (make-local-variable 'skeleton-end-hook) 'latex-skeleton-end-hook) | 816 (set (make-local-variable 'skeleton-end-hook) nil) |
790 (run-hooks 'tex-mode-hook)) | 817 (run-hooks 'tex-mode-hook)) |
791 | 818 |
792 ;;;###autoload | 819 ;;;###autoload |
793 (define-derived-mode slitex-mode latex-mode "SliTeX" | 820 (define-derived-mode slitex-mode latex-mode "SliTeX" |
794 "Major mode for editing files of input for SliTeX. | 821 "Major mode for editing files of input for SliTeX. |
806 | 833 |
807 Use \\[tex-validate-buffer] to check buffer for paragraphs containing | 834 Use \\[tex-validate-buffer] to check buffer for paragraphs containing |
808 mismatched $'s or braces. | 835 mismatched $'s or braces. |
809 | 836 |
810 Special commands: | 837 Special commands: |
811 \\{tex-mode-map} | 838 \\{slitex-mode-map} |
812 | 839 |
813 Mode variables: | 840 Mode variables: |
814 slitex-run-command | 841 slitex-run-command |
815 Command string used by \\[tex-region] or \\[tex-buffer]. | 842 Command string used by \\[tex-region] or \\[tex-buffer]. |
816 tex-directory | 843 tex-directory |
833 `tex-shell-hook' is run." | 860 `tex-shell-hook' is run." |
834 (setq tex-command slitex-run-command) | 861 (setq tex-command slitex-run-command) |
835 (setq tex-start-of-header "\\\\documentstyle{slides}\\|\\\\documentclass{slides}")) | 862 (setq tex-start-of-header "\\\\documentstyle{slides}\\|\\\\documentclass{slides}")) |
836 | 863 |
837 (defun tex-common-initialization () | 864 (defun tex-common-initialization () |
838 (use-local-map tex-mode-map) | |
839 (set-syntax-table tex-mode-syntax-table) | 865 (set-syntax-table tex-mode-syntax-table) |
840 ;; Regexp isearch should accept newline and formfeed as whitespace. | 866 ;; Regexp isearch should accept newline and formfeed as whitespace. |
841 (set (make-local-variable 'search-whitespace-regexp) "[ \t\r\n\f]+") | 867 (set (make-local-variable 'search-whitespace-regexp) "[ \t\r\n\f]+") |
842 ;; A line containing just $$ is treated as a paragraph separator. | 868 ;; A line containing just $$ is treated as a paragraph separator. |
843 (set (make-local-variable 'paragraph-start) | 869 (set (make-local-variable 'paragraph-start) |
1051 (setq inside t))))) | 1077 (setq inside t))))) |
1052 inside)) | 1078 inside)) |
1053 | 1079 |
1054 (defvar latex-block-default "enumerate") | 1080 (defvar latex-block-default "enumerate") |
1055 | 1081 |
1056 (defun latex-skeleton-end-hook () | 1082 ;; Like tex-insert-braces, but for LaTeX. |
1057 (unless (or (eolp) (save-excursion (move-to-left-margin) | |
1058 (not (looking-at paragraph-separate)))) | |
1059 (newline-and-indent))) | |
1060 | |
1061 ;;; Like tex-insert-braces, but for LaTeX. | |
1062 (define-skeleton tex-latex-block | 1083 (define-skeleton tex-latex-block |
1063 "Create a matching pair of lines \\begin[OPT]{NAME} and \\end{NAME} at point. | 1084 "Create a matching pair of lines \\begin[OPT]{NAME} and \\end{NAME} at point. |
1064 Puts point on a blank line between them." | 1085 Puts point on a blank line between them." |
1065 (let ((choice (completing-read (format "LaTeX block name [%s]: " | 1086 (let ((choice (completing-read (format "LaTeX block name [%s]: " |
1066 latex-block-default) | 1087 latex-block-default) |
1072 (unless (or (member choice standard-latex-block-names) | 1093 (unless (or (member choice standard-latex-block-names) |
1073 (member choice latex-block-names)) | 1094 (member choice latex-block-names)) |
1074 ;; Remember new block names for later completion. | 1095 ;; Remember new block names for later completion. |
1075 (push choice latex-block-names)) | 1096 (push choice latex-block-names)) |
1076 choice) | 1097 choice) |
1077 (unless (save-excursion (beginning-of-line) (looking-at "[ \t]*$")) '\n) | 1098 \n "\\begin{" str ?\} |
1078 "\\begin{" str ?\} | |
1079 ?\[ (skeleton-read "[options]: ") & ?\] | -1 | 1099 ?\[ (skeleton-read "[options]: ") & ?\] | -1 |
1080 > \n _ \n | 1100 > \n _ \n |
1081 "\\end{" str ?\} >) | 1101 "\\end{" str ?\} > \n) |
1082 | 1102 |
1083 (define-skeleton latex-insert-item | 1103 (define-skeleton latex-insert-item |
1084 "Insert a \item macro." | 1104 "Insert a \item macro." |
1085 nil | 1105 nil |
1086 (unless (save-excursion (beginning-of-line) (looking-at "[ \t]*$")) '\n) | 1106 \n "\\item " >) |
1087 "\\item " >) | |
1088 | 1107 |
1089 | 1108 |
1090 ;;;; | 1109 ;;;; |
1091 ;;;; LaTeX syntax navigation | 1110 ;;;; LaTeX syntax navigation |
1092 ;;;; | 1111 ;;;; |
1168 (goto-char pos) | 1187 (goto-char pos) |
1169 (signal (car err) (cdr err)))))) | 1188 (signal (car err) (cdr err)))))) |
1170 | 1189 |
1171 (defun latex-syntax-after () | 1190 (defun latex-syntax-after () |
1172 "Like (char-syntax (char-after)) but aware of multi-char elements." | 1191 "Like (char-syntax (char-after)) but aware of multi-char elements." |
1173 (if (looking-at "\\\\end\\>") ?\) (char-syntax (char-after)))) | 1192 (if (looking-at "\\\\end\\>") ?\) (char-syntax (following-char)))) |
1174 | 1193 |
1175 (defun latex-skip-close-parens () | 1194 (defun latex-skip-close-parens () |
1176 "Like (skip-syntax-forward \" )\") but aware of multi-char elements." | 1195 "Like (skip-syntax-forward \" )\") but aware of multi-char elements." |
1177 (let ((forward-sexp-function nil)) | 1196 (let ((forward-sexp-function nil)) |
1178 (while (progn (skip-syntax-forward " )") | 1197 (while (progn (skip-syntax-forward " )") |
1202 (re-search-forward "\\\\begin\\(\\s *{[^}\n]*}\\)") | 1221 (re-search-forward "\\\\begin\\(\\s *{[^}\n]*}\\)") |
1203 (setq text (buffer-substring (match-beginning 1) (match-end 1)))) | 1222 (setq text (buffer-substring (match-beginning 1) (match-end 1)))) |
1204 (indent-to indentation) | 1223 (indent-to indentation) |
1205 (insert "\\end" text) | 1224 (insert "\\end" text) |
1206 (if new-line-needed (insert ?\n)))) | 1225 (if new-line-needed (insert ?\n)))) |
1226 | |
1227 (defconst tex-discount-args-cmds | |
1228 '("begin" "end" "input" "special" "cite" "ref" "include" "includeonly" | |
1229 "documentclass" "usepackage" "label") | |
1230 "TeX commands whose arguments should not be counted as text.") | |
1231 | |
1232 (defun tex-count-words (begin end) | |
1233 "Count the number of words in the buffer." | |
1234 (interactive | |
1235 (if (and transient-mark-mode mark-active) | |
1236 (list (region-beginning) (region-end)) | |
1237 (list (point-min) (point-max)))) | |
1238 ;; TODO: skip comments and math and maybe some environments. | |
1239 (save-excursion | |
1240 (goto-char begin) | |
1241 (let ((count 0)) | |
1242 (while (and (< (point) end) (re-search-forward "\\<" end t)) | |
1243 (if (not (eq (char-syntax (preceding-char)) ?/)) | |
1244 (progn | |
1245 ;; Don't count single-char words. | |
1246 (unless (looking-at ".\\>") (incf count)) | |
1247 (forward-char 1)) | |
1248 (let ((cmd | |
1249 (buffer-substring-no-properties | |
1250 (point) (progn (when (zerop (skip-chars-forward "a-zA-Z@")) | |
1251 (forward-char 1)) | |
1252 (point))))) | |
1253 (when (member cmd tex-discount-args-cmds) | |
1254 (skip-chars-forward "*") | |
1255 (forward-comment (point-max)) | |
1256 (when (looking-at "\\[") | |
1257 (forward-sexp 1) | |
1258 (forward-comment (point-max))) | |
1259 (if (not (looking-at "{")) | |
1260 (forward-char 1) | |
1261 (forward-sexp 1)))))) | |
1262 (message "%s words" count)))) | |
1263 | |
1264 | |
1207 | 1265 |
1208 ;;; Invoking TeX in an inferior shell. | 1266 ;;; Invoking TeX in an inferior shell. |
1209 | 1267 |
1210 ;;; Why use a shell instead of running TeX directly? Because if TeX | 1268 ;; Why use a shell instead of running TeX directly? Because if TeX |
1211 ;;; gets stuck, the user can switch to the shell window and type at it. | 1269 ;; gets stuck, the user can switch to the shell window and type at it. |
1212 | 1270 |
1213 ;;; The utility functions: | 1271 ;; The utility functions: |
1214 | 1272 |
1215 (define-derived-mode tex-shell shell-mode "TeX-Shell" | 1273 (define-derived-mode tex-shell shell-mode "TeX-Shell" |
1216 (compilation-shell-minor-mode t)) | 1274 (compilation-shell-minor-mode t)) |
1217 | 1275 |
1218 ;;;###autoload | 1276 ;;;###autoload |