changeset 81309:3c5f8082a98a

New file.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Mon, 11 Jun 2007 22:02:21 +0000
parents 16181a4d64bf
children 30c952927a0a
files etc/NEWS lisp/ChangeLog lisp/textmodes/bibtex-style.el
diffstat 3 files changed, 160 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/etc/NEWS	Mon Jun 11 20:08:49 2007 +0000
+++ b/etc/NEWS	Mon Jun 11 22:02:21 2007 +0000
@@ -35,9 +35,7 @@
 
 * New Modes and Packages in Emacs 23.1
 
-** css-mode to edit Cascading Style Sheets.
-
-** socks.el (which had been part of W3) is now part of Emacs.
+** bibtex-style-mode helps you write BibTeX's *.bst files.
 
 
 * Changes in Specialized Modes and Packages in Emacs 23.1
--- a/lisp/ChangeLog	Mon Jun 11 20:08:49 2007 +0000
+++ b/lisp/ChangeLog	Mon Jun 11 22:02:21 2007 +0000
@@ -1,3 +1,7 @@
+2007-06-11  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* textmodes/bibtex-style.el: New file.
+
 2007-06-11  Riccardo Murri  <riccardo.murri@gmail.com>
 
 	* vc-bzr.el: New file.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/textmodes/bibtex-style.el	Mon Jun 11 22:02:21 2007 +0000
@@ -0,0 +1,155 @@
+;;; bibtex-style.el --- Major mode for BibTeX Style files
+
+;; Copyright (C) 2005  Stefan Monnier
+
+;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
+;; Keywords: 
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Done: font-lock, imenu, outline, commenting, indentation.
+;; Todo: tab-completion.
+;; Bugs:
+
+;;; Code:
+
+(defvar bibtex-style-mode-syntax-table
+  (let ((st (make-syntax-table)))
+    (modify-syntax-entry ?%  "<" st)
+    (modify-syntax-entry ?\n ">" st)
+    (modify-syntax-entry ?\{ "(}" st)
+    (modify-syntax-entry ?\} "){" st)
+    (modify-syntax-entry ?\" "\"" st)
+    (modify-syntax-entry ?.  "_" st)
+    (modify-syntax-entry ?'  "'" st)
+    (modify-syntax-entry ?#  "'" st)
+    (modify-syntax-entry ?*  "." st)
+    (modify-syntax-entry ?=  "." st)
+    (modify-syntax-entry ?$  "_" st)
+    st))
+
+
+(defconst bibtex-style-commands
+  '("ENTRY" "EXECUTE" "FUNCTION" "INTEGERS" "ITERATE" "MACRO" "READ"
+    "REVERSE" "SORT" "STRINGS"))
+
+(defconst bibtex-style-functions
+  ;; From http://www.eeng.dcu.ie/local-docs/btxdocs/btxhak/btxhak/node4.html.
+  '("<" ">" "=" "+" "-" "*" ":="
+    "add.period$" "call.type$" "change.case$" "chr.to.int$" "cite$"
+    "duplicate$" "empty$" "format.name$" "if$" "int.to.chr$" "int.to.str$"
+    "missing$" "newline$" "num.names$" "pop$" "preamble$" "purify$" "quote$"
+    "skip$" "stack$" "substring$" "swap$" "text.length$" "text.prefix$"
+    "top$" "type$" "warning$" "while$" "width$" "write$"))
+
+(defvar bibtex-style-font-lock-keywords
+  `((,(regexp-opt bibtex-style-commands 'words) . font-lock-keyword-face)
+    ("\\w+\\$" . font-lock-keyword-face)
+    ("\\<\\(FUNCTION\\|MACRO\\)\\s-+{\\([^}\n]+\\)}"
+     (2 font-lock-function-name-face))))
+
+;;;###autoload (add-to-list 'auto-mode-alist '("\\.bst\\'" . bibtex-style-mode))
+
+;;;###autoload
+(define-derived-mode bibtex-style-mode nil "BibStyle"
+  "Major mode for editing BibTeX style files."
+  (set (make-local-variable 'comment-start) "%")
+  (set (make-local-variable 'outline-regexp) "^[a-z]")
+  (set (make-local-variable 'imenu-generic-expression)
+       '((nil "\\<\\(FUNCTION\\|MACRO\\)\\s-+{\\([^}\n]+\\)}" 2)))
+  (set (make-local-variable 'indent-line-function) 'bibtex-style-indent-line)
+  (set (make-local-variable 'parse-sexp-ignore-comments) t)
+  (setq font-lock-defaults
+	'(bibtex-style-font-lock-keywords nil t
+	  ((?. . "w")))))
+
+(defun bibtex-style-indent-line ()
+  "Indent current line of BibTeX Style code."
+  (interactive)
+  (let* ((savep (point))
+	 (indent (condition-case nil
+		     (save-excursion
+		       (forward-line 0)
+		       (skip-chars-forward " \t")
+		       (if (>= (point) savep) (setq savep nil))
+		       (max (bibtex-style-calculate-indentation) 0))
+		   (error 0))))
+    (if savep
+	(save-excursion (indent-line-to indent))
+      (indent-line-to indent))))
+
+(defcustom bibtex-style-indent-basic 2
+  "Basic amount of indentation to use in BibTeX Style mode."
+  :type 'integer)
+
+(defun bibtex-style-calculate-indentation (&optional virt)
+  (or
+   ;; Stick the first line at column 0.
+   (and (= (point-min) (line-beginning-position)) 0)
+   ;; Commands start at column 0.
+   (and (looking-at (regexp-opt bibtex-style-commands 'words)) 0)
+   ;; Trust the current indentation, if such info is applicable.
+   (and virt (save-excursion (skip-chars-backward " \t{") (bolp))
+	(current-column))
+   ;; Put leading close-paren where the matching open brace would be.
+   (and (looking-at "}")
+	(condition-case nil
+	    (save-excursion
+	      (up-list -1)
+	      (bibtex-style-calculate-indentation 'virt))
+	  (scan-error nil)))
+   ;; Align leading "if$" with previous command.
+   (and (looking-at "if\\$")
+	(condition-case nil
+	    (save-excursion
+	      (backward-sexp 3)
+	      (bibtex-style-calculate-indentation 'virt))
+	  (scan-error
+	   ;; There is no command before the "if$".
+	   (condition-case nil
+	       (save-excursion
+		 (up-list -1)
+		 (+ bibtex-style-indent-basic
+		    (bibtex-style-calculate-indentation 'virt)))
+	     (scan-error nil)))))
+   ;; Right after an opening brace.
+   (condition-case err (save-excursion (backward-sexp 1) nil)
+     (scan-error (goto-char (nth 2 err))
+		 (+ bibtex-style-indent-basic
+		    (bibtex-style-calculate-indentation 'virt))))
+   ;; Default, align with previous command.
+   (let ((fai ;; First arm of an "if$".
+	  (condition-case nil
+	      (save-excursion
+		(forward-sexp 2)
+		(forward-comment (point-max))
+		(looking-at "if\\$"))
+	    (scan-error nil))))
+     (save-excursion
+       (condition-case err
+	   (while (progn
+		    (backward-sexp 1)
+		    (save-excursion (skip-chars-backward " \t{") (not (bolp)))))
+	 (scan-error nil))
+       (+ (current-column)
+	  (if (or fai (looking-at "ENTRY")) bibtex-style-indent-basic 0))))))
+
+
+(provide 'bibtex-style)
+;; arch-tag: b20ad41a-fd36-466e-8fd2-cc6137f9c55c
+;;; bibtex-style.el ends here