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