root/trunk/lisp/textmodes/bibtex-style.el

Revision 4220, 5.4 kB (checked in by miyoshi, 9 months ago)

Sync up with Emacs22.2.

Line 
1 ;;; bibtex-style.el --- Major mode for BibTeX Style files
2
3 ;; Copyright (C) 2005,2007, 2008  Free Software Foundation, Inc.
4
5 ;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
6 ;; Keywords:
7
8 ;; This file is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
12
13 ;; This file is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
20 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 ;; Boston, MA 02110-1301, USA.
22
23 ;;; Commentary:
24
25 ;; Done: font-lock, imenu, outline, commenting, indentation.
26 ;; Todo: tab-completion.
27 ;; Bugs:
28
29 ;;; Code:
30
31 (defvar bibtex-style-mode-syntax-table
32   (let ((st (make-syntax-table)))
33     (modify-syntax-entry ?%  "<" st)
34     (modify-syntax-entry ?\n ">" st)
35     (modify-syntax-entry ?\{ "(}" st)
36     (modify-syntax-entry ?\} "){" st)
37     (modify-syntax-entry ?\" "\"" st)
38     (modify-syntax-entry ?.  "_" st)
39     (modify-syntax-entry ?'  "'" st)
40     (modify-syntax-entry ?#  "'" st)
41     (modify-syntax-entry ?*  "." st)
42     (modify-syntax-entry ?=  "." st)
43     (modify-syntax-entry ?$  "_" st)
44     st))
45
46
47 (defconst bibtex-style-commands
48   '("ENTRY" "EXECUTE" "FUNCTION" "INTEGERS" "ITERATE" "MACRO" "READ"
49     "REVERSE" "SORT" "STRINGS"))
50
51 (defconst bibtex-style-functions
52   ;; From http://www.eeng.dcu.ie/local-docs/btxdocs/btxhak/btxhak/node4.html.
53   '("<" ">" "=" "+" "-" "*" ":="
54     "add.period$" "call.type$" "change.case$" "chr.to.int$" "cite$"
55     "duplicate$" "empty$" "format.name$" "if$" "int.to.chr$" "int.to.str$"
56     "missing$" "newline$" "num.names$" "pop$" "preamble$" "purify$" "quote$"
57     "skip$" "stack$" "substring$" "swap$" "text.length$" "text.prefix$"
58     "top$" "type$" "warning$" "while$" "width$" "write$"))
59
60 (defvar bibtex-style-font-lock-keywords
61   `((,(regexp-opt bibtex-style-commands 'words) . font-lock-keyword-face)
62     ("\\w+\\$" . font-lock-keyword-face)
63     ("\\<\\(FUNCTION\\|MACRO\\)\\s-+{\\([^}\n]+\\)}"
64      (2 font-lock-function-name-face))))
65
66 ;;;###autoload (add-to-list 'auto-mode-alist '("\\.bst\\'" . bibtex-style-mode))
67
68 ;;;###autoload
69 (define-derived-mode bibtex-style-mode nil "BibStyle"
70   "Major mode for editing BibTeX style files."
71   (set (make-local-variable 'comment-start) "%")
72   (set (make-local-variable 'outline-regexp) "^[a-z]")
73   (set (make-local-variable 'imenu-generic-expression)
74        '((nil "\\<\\(FUNCTION\\|MACRO\\)\\s-+{\\([^}\n]+\\)}" 2)))
75   (set (make-local-variable 'indent-line-function) 'bibtex-style-indent-line)
76   (set (make-local-variable 'parse-sexp-ignore-comments) t)
77   (setq font-lock-defaults
78         '(bibtex-style-font-lock-keywords nil t
79           ((?. . "w")))))
80
81 (defun bibtex-style-indent-line ()
82   "Indent current line of BibTeX Style code."
83   (interactive)
84   (let* ((savep (point))
85          (indent (condition-case nil
86                      (save-excursion
87                        (forward-line 0)
88                        (skip-chars-forward " \t")
89                        (if (>= (point) savep) (setq savep nil))
90                        (max (bibtex-style-calculate-indentation) 0))
91                    (error 0))))
92     (if savep
93         (save-excursion (indent-line-to indent))
94       (indent-line-to indent))))
95
96 (defcustom bibtex-style-indent-basic 2
97   "Basic amount of indentation to use in BibTeX Style mode."
98   :version "22.2"
99   :type 'integer
100   :group 'bibtex)
101
102 (defun bibtex-style-calculate-indentation (&optional virt)
103   (or
104    ;; Stick the first line at column 0.
105    (and (= (point-min) (line-beginning-position)) 0)
106    ;; Commands start at column 0.
107    (and (looking-at (regexp-opt bibtex-style-commands 'words)) 0)
108    ;; Trust the current indentation, if such info is applicable.
109    (and virt (save-excursion (skip-chars-backward " \t{") (bolp))
110         (current-column))
111    ;; Put leading close-paren where the matching open brace would be.
112    (and (looking-at "}")
113         (condition-case nil
114             (save-excursion
115               (up-list -1)
116               (bibtex-style-calculate-indentation 'virt))
117           (scan-error nil)))
118    ;; Align leading "if$" with previous command.
119    (and (looking-at "if\\$")
120         (condition-case nil
121             (save-excursion
122               (backward-sexp 3)
123               (bibtex-style-calculate-indentation 'virt))
124           (scan-error
125            ;; There is no command before the "if$".
126            (condition-case nil
127                (save-excursion
128                  (up-list -1)
129                  (+ bibtex-style-indent-basic
130                     (bibtex-style-calculate-indentation 'virt)))
131              (scan-error nil)))))
132    ;; Right after an opening brace.
133    (condition-case err (save-excursion (backward-sexp 1) nil)
134      (scan-error (goto-char (nth 2 err))
135                  (+ bibtex-style-indent-basic
136                     (bibtex-style-calculate-indentation 'virt))))
137    ;; Default, align with previous command.
138    (let ((fai ;; First arm of an "if$".
139           (condition-case nil
140               (save-excursion
141                 (forward-sexp 2)
142                 (forward-comment (point-max))
143                 (looking-at "if\\$"))
144             (scan-error nil))))
145      (save-excursion
146        (condition-case err
147            (while (progn
148                     (backward-sexp 1)
149                     (save-excursion (skip-chars-backward " \t{") (not (bolp)))))
150          (scan-error nil))
151        (+ (current-column)
152           (if (or fai (looking-at "ENTRY")) bibtex-style-indent-basic 0))))))
153
154
155 (provide 'bibtex-style)
156 ;; arch-tag: b20ad41a-fd36-466e-8fd2-cc6137f9c55c
157 ;;; bibtex-style.el ends here
158
Note: See TracBrowser for help on using the browser.