Commit | Line | Data |
---|---|---|
62fc0b71 SM |
1 | ;;; bibtex-style.el --- Major mode for BibTeX Style files |
2 | ||
5df4f04c | 3 | ;; Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. |
62fc0b71 SM |
4 | |
5 | ;; Author: Stefan Monnier <monnier@iro.umontreal.ca> | |
f0fd77be | 6 | ;; Keywords: tex |
62fc0b71 | 7 | |
1fecc8fe GM |
8 | ;; This file is part of GNU Emacs. |
9 | ||
10 | ;; GNU Emacs is free software: you can redistribute it and/or modify | |
62fc0b71 | 11 | ;; it under the terms of the GNU General Public License as published by |
1fecc8fe GM |
12 | ;; the Free Software Foundation, either version 3 of the License, or |
13 | ;; (at your option) any later version. | |
62fc0b71 | 14 | |
1fecc8fe | 15 | ;; GNU Emacs is distributed in the hope that it will be useful, |
62fc0b71 SM |
16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | ;; GNU General Public License for more details. | |
19 | ||
20 | ;; You should have received a copy of the GNU General Public License | |
1fecc8fe | 21 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
62fc0b71 SM |
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 | ||
62fc0b71 SM |
66 | ;;;###autoload |
67 | (define-derived-mode bibtex-style-mode nil "BibStyle" | |
68 | "Major mode for editing BibTeX style files." | |
69 | (set (make-local-variable 'comment-start) "%") | |
70 | (set (make-local-variable 'outline-regexp) "^[a-z]") | |
71 | (set (make-local-variable 'imenu-generic-expression) | |
72 | '((nil "\\<\\(FUNCTION\\|MACRO\\)\\s-+{\\([^}\n]+\\)}" 2))) | |
73 | (set (make-local-variable 'indent-line-function) 'bibtex-style-indent-line) | |
74 | (set (make-local-variable 'parse-sexp-ignore-comments) t) | |
75 | (setq font-lock-defaults | |
76 | '(bibtex-style-font-lock-keywords nil t | |
77 | ((?. . "w"))))) | |
78 | ||
79 | (defun bibtex-style-indent-line () | |
80 | "Indent current line of BibTeX Style code." | |
81 | (interactive) | |
82 | (let* ((savep (point)) | |
83 | (indent (condition-case nil | |
84 | (save-excursion | |
85 | (forward-line 0) | |
86 | (skip-chars-forward " \t") | |
87 | (if (>= (point) savep) (setq savep nil)) | |
88 | (max (bibtex-style-calculate-indentation) 0)) | |
89 | (error 0)))) | |
90 | (if savep | |
91 | (save-excursion (indent-line-to indent)) | |
92 | (indent-line-to indent)))) | |
93 | ||
94 | (defcustom bibtex-style-indent-basic 2 | |
95 | "Basic amount of indentation to use in BibTeX Style mode." | |
8e788369 DN |
96 | :version "22.2" |
97 | :type 'integer | |
98 | :group 'bibtex) | |
62fc0b71 SM |
99 | |
100 | (defun bibtex-style-calculate-indentation (&optional virt) | |
101 | (or | |
102 | ;; Stick the first line at column 0. | |
103 | (and (= (point-min) (line-beginning-position)) 0) | |
104 | ;; Commands start at column 0. | |
105 | (and (looking-at (regexp-opt bibtex-style-commands 'words)) 0) | |
106 | ;; Trust the current indentation, if such info is applicable. | |
107 | (and virt (save-excursion (skip-chars-backward " \t{") (bolp)) | |
108 | (current-column)) | |
109 | ;; Put leading close-paren where the matching open brace would be. | |
110 | (and (looking-at "}") | |
111 | (condition-case nil | |
112 | (save-excursion | |
113 | (up-list -1) | |
114 | (bibtex-style-calculate-indentation 'virt)) | |
115 | (scan-error nil))) | |
116 | ;; Align leading "if$" with previous command. | |
117 | (and (looking-at "if\\$") | |
118 | (condition-case nil | |
119 | (save-excursion | |
120 | (backward-sexp 3) | |
121 | (bibtex-style-calculate-indentation 'virt)) | |
122 | (scan-error | |
123 | ;; There is no command before the "if$". | |
124 | (condition-case nil | |
125 | (save-excursion | |
126 | (up-list -1) | |
127 | (+ bibtex-style-indent-basic | |
128 | (bibtex-style-calculate-indentation 'virt))) | |
129 | (scan-error nil))))) | |
130 | ;; Right after an opening brace. | |
131 | (condition-case err (save-excursion (backward-sexp 1) nil) | |
132 | (scan-error (goto-char (nth 2 err)) | |
133 | (+ bibtex-style-indent-basic | |
134 | (bibtex-style-calculate-indentation 'virt)))) | |
135 | ;; Default, align with previous command. | |
136 | (let ((fai ;; First arm of an "if$". | |
137 | (condition-case nil | |
138 | (save-excursion | |
139 | (forward-sexp 2) | |
140 | (forward-comment (point-max)) | |
141 | (looking-at "if\\$")) | |
142 | (scan-error nil)))) | |
143 | (save-excursion | |
144 | (condition-case err | |
145 | (while (progn | |
146 | (backward-sexp 1) | |
147 | (save-excursion (skip-chars-backward " \t{") (not (bolp))))) | |
148 | (scan-error nil)) | |
149 | (+ (current-column) | |
150 | (if (or fai (looking-at "ENTRY")) bibtex-style-indent-basic 0)))))) | |
151 | ||
152 | ||
153 | (provide 'bibtex-style) | |
154 | ;; arch-tag: b20ad41a-fd36-466e-8fd2-cc6137f9c55c | |
155 | ;;; bibtex-style.el ends here |