Update of /project/lisppaste/cvsroot/lisppaste2
In directory clnet:/tmp/cvs-serv29290
Modified Files:
coloring-types.lisp
Log Message:
Haskell syntax coloring (thanks to Kristof Bastiaensen!)
--- /project/lisppaste/cvsroot/lisppaste2/coloring-types.lisp 2006/08/14 21:34:02 1.20
+++ /project/lisppaste/cvsroot/lisppaste2/coloring-types.lisp 2006/09/05 18:33:47 1.21
@@ -788,4 +788,176 @@
(if (member s *python-reserved-words* :test #'string=)
(format nil "<span class=\"symbol\">~A</span>"
s)
- s)))))
\ No newline at end of file
+ s)))))
+
+(defvar *haskell-open-parens* "([{")
+
+(defvar *haskell-close-parens* ")]}")
+
+(defvar *haskell-in-word*
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789")
+
+(defvar *haskell-begin-id* "abcdefghijklmnopqrstuvwxyz")
+
+(defvar *haskell-begin-cons* "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
+
+(defvar *haskell-in-symbol* "!#$%&*+./<=>?@\\^|-~:")
+
+(defvar *haskell-reserved-symbols*
+ '(".." "::" "@" "~" "=" "->" "<-" "|" "\\"))
+
+(defvar *haskell-reserved-words*
+ '("case" "class" "data" "default" "deriving" "do" "else" "if"
+ "import" "in" "infix" "infixl" "infixr" "instance" "let" "module"
+ "newtype" "of" "then" "type" "where"))
+
+(defvar *haskell-non-constituent*
+ '(#\space #\return #\tab #\newline #\{ #\} #\( #\) #\" #\[ #\]))
+
+(define-coloring-type :haskell "Haskell"
+ :modes (:normal :comment :multi-comment :string :char :identifier
+ :backquote :newline :symbol :parenlike :single-escape)
+ :default-mode :normal
+ :autodetect (lambda (text)
+ (search "haskell" text :test #'char-equal))
+ :transitions
+ (((:normal)
+ ((scan-any *haskell-in-word*)
+ (set-mode :identifier
+ :until (or (scan-any *haskell-non-constituent*)
+ (scan-any *haskell-in-symbol*))
+ :advancing nil))
+ ((scan "--")
+ (set-mode :comment
+ :until (scan-any '(#\return #\newline))
+ :advancing nil))
+ ((scan "{-")
+ (set-mode :multi-comment
+ :until (scan "-}")))
+ ((scan #\")
+ (set-mode :string
+ :until (scan #\")))
+ ((scan #\`)
+ (set-mode :backquote
+ :until (scan #\`)))
+ ((scan "'")
+ (set-mode :char
+ :until (scan #\')))
+ ((scan-any *haskell-in-symbol*)
+ (set-mode :symbol
+ :until (or (scan-any *haskell-non-constituent*)
+ (scan-any *haskell-in-word*)
+ (scan #\'))
+ :advancing nil))
+ ((or (scan-any *haskell-open-parens*)
+ (scan-any *haskell-close-parens*))
+ (set-mode :parenlike
+ :until (advance 1)
+ :advancing nil))
+ ((scan-any '(#\newline #\return))
+ (set-mode :newline
+ :until (advance 1)
+ :advancing nil)))
+ ((:string)
+ ((scan #\\)
+ (set-mode :single-escape
+ :until (advance 1))))
+ ((:char)
+ ((scan #\\)
+ (set-mode :single-escape
+ :until (advance 1)))))
+ :formatter-variables
+ ((paren-counter 0)
+ (beginning-of-line t))
+ :formatter-after-hook (lambda nil
+ (format nil "~{~A~}"
+ (loop for i from paren-counter downto 1
+ collect "</span></span>")))
+ :formatters
+ (((:normal)
+ (lambda (type s)
+ (declare (ignore type))
+ (cond (beginning-of-line
+ (setq beginning-of-line nil)
+ (if (char= (elt s 0) #\space)
+ (concatenate 'string " " (subseq s 1))
+ s))
+ (t s))))
+ ((:newline)
+ (lambda (type s)
+ (declare (ignore type))
+ (setq beginning-of-line t)
+ s))
+ ((:backquote)
+ (lambda (type s)
+ (declare (ignore type))
+ (setq beginning-of-line nil)
+ (if (find (elt s 1) *haskell-begin-cons*)
+ (format nil "<span class=\"variable\">~A</span>"
+ s)
+ (format nil "<span class=\"atom\">~A</span>"
+ s))))
+ ((:comment :multi-comment)
+ (lambda (type s)
+ (declare (ignore type))
+ (setq beginning-of-line nil)
+ (format nil "<span class=\"comment\">~A</span>"
+ s)))
+ ((:string)
+ (lambda (type s)
+ (declare (ignore type))
+ (setq beginning-of-line nil)
+ (format nil "<span class=\"string\">~A</span>"
+ s)))
+ ((:char)
+ (lambda (type s)
+ (declare (ignore type))
+ (setq beginning-of-line nil)
+ (format nil "<span class=\"character\">~A</span>"
+ s)))
+ ((:identifier)
+ (lambda (type s)
+ (declare (ignore type))
+ (prog1
+ (cond ((find (elt s 0) *haskell-begin-cons*)
+ (format nil "<span class=\"variable\">~A</span>" s))
+ ((member s *haskell-reserved-words* :test #'string=)
+ (format nil "<span class=\"keyword\">~A</span>" s))
+ (beginning-of-line
+ (format nil "<span class=\"function\">~A</span>" s))
+ (t s))
+ (setq beginning-of-line nil))))
+ ((:symbol)
+ (lambda (type s)
+ (declare (ignore type))
+ (setq beginning-of-line nil)
+ (cond ((member s *haskell-reserved-symbols* :test #'string=)
+ (format nil "<span class=\"keyword\">~A</span>" s))
+ ((char= (elt s 0) #\:)
+ (format nil "<span class=\"variable\">~A</span>" s))
+ (t (format nil "<span class=\"atom\">~A</span>" s)))))
+ ((:single-escape)
+ (lambda (type s)
+ (call-formatter (cdr type) s)))
+ ((:parenlike)
+ (lambda (type s)
+ (declare (ignore type))
+ (setq beginning-of-line nil)
+ (let ((open nil)
+ (count 0))
+ (if (eql (length s) 1)
+ (progn
+ (when (find (elt s 0) *haskell-open-parens*)
+ (setf open t)
+ (setf count (mod paren-counter 6))
+ (incf paren-counter))
+ (when (find (elt s 0) *haskell-close-parens*)
+ (setf open nil)
+ (decf paren-counter)
+ (setf count (mod paren-counter 6)))
+ (if open
+ (format nil "<span class=\"paren~A\">~A<span class=\"~A\">"
+ (1+ count) s *css-background-class*)
+ (format nil "</span>~A</span>"
+ s)))
+ s))))))
\ No newline at end of file