]> git.donarmstrong.com Git - lilypond.git/blob - lilypond-font-lock.el
1646ad001b158a3c4ec6af5a0fa01a1efd29fcba
[lilypond.git] / lilypond-font-lock.el
1 ;;; lilypond-font-lock.el --- syntax coloring for LilyPond mode
2
3 ;; Copyright (C) 1992,1993,1994  Tim Peters
4
5 ;; Author: 2001: Heikki Junes
6 ;;  * Emacs-mode: new keywords, reserved words, notenames and brackets are
7 ;;    font-lock-keywords; implementation encourages spacing/indenting.
8 ;; Author: 1997: Han-Wen Nienhuys
9 ;; Author: 1995-1996 Barry A. Warsaw
10 ;;         1992-1994 Tim Peters
11 ;; Created:       Feb 1992
12 ;; Version:       0.0
13 ;; Last Modified: 1SEP2001
14 ;; Keywords: lilypond languages music notation
15
16 ;; This software is provided as-is, without express or implied
17 ;; warranty.  Permission to use, copy, modify, distribute or sell this
18 ;; software, without fee, for any purpose and by any individual or
19 ;; organization, is hereby granted, provided that the above copyright
20 ;; notice and this paragraph appear in all copies.
21
22 ;; This started out as a cannabalised version of python-mode.el, by hwn
23 ;; For changes see the LilyPond ChangeLog
24 ;;
25
26 ;; TODO:
27 ;;   - should handle block comments too.
28 ;;   - handle lexer modes (\header, \melodic, \lyric) etc.
29 ;;   - indentation
30
31 (defconst LilyPond-font-lock-keywords
32   (let* ((keywords '( ; need special order due to over[lapping] of words
33
34 "accepts" "addlyrics" "alternative" "apply" "arpeggio" "autoBeamOff"
35 "autoBeamOn" "autochange" "bar" "BarNumberingStaffContext" "break"
36 "breathe" "breve" "cadenzaOn" "cadenzaOff" "char" "chord" "chordmodifiers"
37 "ChordNamesContext" "chordstest" "chords" "clef" "cm" "commandspanrequest"
38 "consistsend" "consists" "context" "default" "denies" "different"
39 "dotsBoth" "dotsDown" "dotsUp" "duration" "dynamicscript" "dynamicUp"
40 "dynamicDown" "dynamicBoth" "EasyNotation" "elementdescriptions"
41 "emptyText" "extreme" "ex" "fatText" "fermata" "fff" "ff" "f" "font" "foo"
42 "glissando" "gliss" "grace" "grstaff" "hairyChord" "HaraKiriStaffContext"
43 "header" "hideStaffSwitch" "include" "in" "key" "linebreak" "longa"
44 "lyrics" "LyricsContext" "LyricsVoiceContext" "major" "mark" "melismaEnd"
45 "melisma" "midi" "minor" "mm" "musicalpitch" "m" "name" "newpage"
46 "noBreak" "noisebeat" "noise" "normalkey" "normalsize" "notenames" "notes"
47 "n" "onestaff" "oneVoice" "one" "OrchestralScoreContext" "outputproperty"
48 "override" "paperTwentysix" "paper" "partcombine" "partial" "penalty"
49 "PianoStaffContext" "pp" "property" "pt" "p" "relative" "remove" "repeat"
50 "restsII" "rests" "revert" "rhythm" "right" "scales" "scale" "scheme"
51 "score" "ScoreContext" "scpaper" "scriptBoth" "scriptDown" "scriptUp"
52 "script" "scscore" "sd" "sequential" "settings" "set" "sfz" "shitfOnnn"
53 "shitfOnn" "shitfOn" "shitfOff" "showStaffSwitch" "simultaneous" "skip"
54 "slurBoth" "slurDown" "slurUp" "slurDotted" "slurSolid" "small"
55 "spanrequest" "specialKey" "staccato" "StaffContext" "staffspace"
56 "stemBoth" "stemDown" "stemUp" "stpaper" "stscore" "stylesheet" "su"
57 "tempo" "tenuto" "textII" "textI" "textscript" "thenotes" "ThreadContext"
58 "threevoice" "tieBoth" "tieDown" "tieDotted" "tieSolid" "tieUp" "times"
59 "time" "tiny" "touch" "translator" "transpose" "tupletBoth" "tupletDown"
60 "tupletUp" "twovoicesteminvert" "twovoice" "two" "turnOff" "type" "t"
61 "unset" "version" "voiceB" "VoiceContext" "voiceC" "voiceD" "voiceE"
62 "voiceOne" "voiceTwo" "voiceThree" "voiceFour" "zagers" "zager" "zoger"
63
64                       ))
65
66   (reservedwords '(
67
68 "bass" "treble" "PianoStaff"
69
70                       ))
71
72        (kwregex (mapconcat (lambda (x) (concat "\\\\" x))  keywords "\\|"))
73        (rwregex (mapconcat (lambda (x) (concat "" x))  reservedwords "\\|"))
74 )
75
76     (list 
77 ;; Fonts in use (from GNU Emacs Lisp Reference Manual, elisp.ps):
78 ;; font-lock- comment / string / keyword / builtin / function-name / 
79 ;;            variable-name / type / constant / warning -face
80
81 ;; Using extra spaces was both easier to parse and looks better!
82 ;; highlight note grouping brackets; space around these { [ < brackets > ] }
83 ;;   make the text look {less[<messyand>]erronous}
84       '("\\([<{[]\\)[ \t]" 1 font-lock-warning-face)
85       '("\\([\]}>]\\)[ \t]" 1 font-lock-warning-face)
86       '("^\\([<{[]\\)[ \t]" 1 font-lock-warning-face)
87       '("^\\([\]}>]\\)[ \t]" 1 font-lock-warning-face)
88       '("\\([<{[]\\)$" 1 font-lock-warning-face)
89       '("\\([\]}>]\\)$" 1 font-lock-warning-face)
90
91 ;; highlight keywords; space after[ ]these commands /increases/readability
92       (concat "\\([_^]?\\(" kwregex "\\)\\)[ \t(]")
93       (concat "\\([_^]?\\(" kwregex "\\)\\)$")
94       '("\\([_^]?\\\\[a-zA-Z][a-zA-Z]*\\)" 1 font-lock-constant-face)
95       '("\\([a-zA-Z][_a-zA-Z]*\\)[ \t]*=[ \t]*" 1 font-lock-variable-name-face)
96       '("[ \t]*=[ \t]*\\([a-zA-Z][_a-zA-Z]*\\)[ \t(]" 1 font-lock-variable-name-face)
97       '("[ \t]*=[ \t]*\\([a-zA-Z][_a-zA-Z]*\\)$" 1 font-lock-variable-name-face)
98
99 ;; other reserved words
100       (cons (concat "\\(" rwregex "\\) ") 'font-lock-variable-name-face)
101       (cons (concat "\\(" rwregex "\\)$") 'font-lock-variable-name-face)
102
103 ;; highlight note names; separate notes from (other than ')'-type) brackets
104       '("[ )\t]\\(\\(\\(\\(do\\|re\\|mi\\|fa\\|sol\\|la\\|si\\)\\(b\\|bb\\|d\\|dd\\|s\\|ss\\)?\\)\\|\\([a-hsr]\\(f\\|ff\\|s\\|ss\\|flat\\|flatflat\\|sharp\\|sharpsharp\\|is[s]?\\|is[s]?is[s]?\\|es[s]?\\|es[s]?es[s]?\\)?\\)\\|\\(as\\(as\\|es\\)?\\)\\|\\(es\\(ses\\)?\\)\\|\\(bb\\)\\)[,']*\\(64\\|32\\|16\\|8\\|4\\|2\\|1\\)?[.]*\\)" 1 font-lock-type-face)
105
106       '("\\([(~)]\\)" 1 font-lock-builtin-face)
107
108       )
109     )
110   "Additional expressions to highlight in LilyPond mode.")
111
112 ;; define a mode-specific abbrev table for those who use such things
113 (defvar LilyPond-mode-abbrev-table nil
114   "Abbrev table in use in `LilyPond-mode' buffers.")
115
116 (define-abbrev-table 'LilyPond-mode-abbrev-table nil)
117
118 (defvar LilyPond-mode-syntax-table nil
119   "Syntax table used in `LilyPond-mode' buffers.")
120
121 ;;
122 (if LilyPond-mode-syntax-table
123     ()
124   (setq LilyPond-mode-syntax-table (make-syntax-table))
125   (mapcar (function
126            (lambda (x) (modify-syntax-entry
127                         (car x) (cdr x) LilyPond-mode-syntax-table)))
128           '(( ?\( . "()" ) ( ?\) . ")(" )   ; need matching parens for inline lisp
129             ( ?\[ . "." ) ( ?\] . "." )
130             ( ?\{ . "(}" ) ( ?\} . "){" )
131             ( ?\< . "(>" )( ?\> . ")>") 
132             ( ?\$ . "." ) ( ?\% . "." ) ( ?\& . "." )
133             ( ?\* . "." ) ( ?\+ . "." ) ( ?\- . "." )
134             ( ?\/ . "." )  ( ?\= . "." )
135             ( ?\| . "." ) (?\\ . "\\" )
136             ( ?\_ . "." )       
137             ( ?\' . "w")        
138             ( ?\" . "\"" )
139             ( ?\% . "<")
140             ( ?\n . ">")
141
142 ; FIXME
143 ;           ( ?%  .  ". 124b" )
144 ;           ( ?{  .  ". 23" )
145             ))
146
147   )     
148