From: fred Date: Wed, 27 Mar 2002 00:02:10 +0000 (+0000) Subject: lilypond-1.3.103 X-Git-Tag: release/1.5.59~1170 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=26b45362182469172e436230f9e4386bde79104f;p=lilypond.git lilypond-1.3.103 --- diff --git a/CHANGES b/CHANGES index cf3d221a5c..7ef18f0c3b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,13 +1,43 @@ -1.3.101.jcn2 +1.3.102.jcn1 ============ +* Translated auto-beam properties to alist. + +* Rewrite of tfmtoafm in scm. + +* Rewrite of emacs LilyPond mode, based upon auctex interface. + +* Chord name fixes and additions (Atte Andr'e Jensen) + +* ly-get-mus-property, ly-set-mus-property: set properties of Music + +* Move Span_req::span_dir_ into Scheme + +* removed numberOfStaffLines, staffSpace. Use StaffSymbol \push +staff-space, line-count + +* removed minVerticalAlign, maxVerticalAlign; use VerticalAlignment +\push #'threshold = #(MIN . MAX) + +* \property tremoloFlags can be set anywhere now + +* \apply #function music + +* Bugfix: padding of dots. + +* Generate documentation for separate engravers as well as for contexts. + +* Move some reference manual into the SCM documentation system. + +* Bugfix: fixed hyphen spanners. + +1.3.102 +======= + * Fixed bracket, and made some other PostScript code fixes. * Silly font initialisation fix for paper19 non-feature. -1.3.101.uu1 -=========== - * Automatic engraver/property documentation infrastructure. * Fixed system-start braces diff --git a/Documentation/user/refman.itely b/Documentation/user/refman.itely index 7c318a22bb..af651ea05a 100644 --- a/Documentation/user/refman.itely +++ b/Documentation/user/refman.itely @@ -141,19 +141,11 @@ internal use. The following commands access the interpreter directly. @example - \scm @keyindex{scm} @var{scheme} ; + #@var{scheme} @end example Evaluates the specified Scheme code. The result is discarded. -@example -\scmfile@keyindex{scmfile} @var{filename}; -@end example - -Reads Scheme code from the specified file. The result is discarded. - - - Identifier assignments may appear at top level. Semicolons are forbidden after top level assignments. @@ -182,6 +174,8 @@ They cannot be nested. Keywords start with a backslash, followed by a number of lower case alphabetic characters. These are all the keywords. +[FIXME] + @example \accepts \addlyrics @@ -1040,24 +1034,23 @@ Beaming can be generated automatically; see section XREF-autobeam [FIXME]. [OUTDATED, FIXME] -To place tremolo marks +To place tremolo marks between notes, use @code{\repeat} with tremolo +style. @cindex tremolo beams - between two notes, begin -with `@code{[:}@var{length}' and end with `@code{]}'. Tremolo marks -will appear instead of beams. Putting more than two notes in such a -construction will produce odd effects. To create tremolo beams on a -single note, simply attach `@code{:}@var{length}' to the note itself -(see also section XREF-tremolo [FIXME]). + To create tremolo beams on a single note, simply attach +`@code{:}@var{length}' to the note itself (see also section +XREF-tremolo [FIXME]). -@ignore -@mu dela[fragment,verbatim,center] - [:16 e'1 g'] [:8 e'4 f'] + +@mudela[fragment,verbatim,center] + \repeat "tremolo" 8 { c16 d16 } + \repeat "tremolo" 4 { c16 d16 } @end mudela - -@mud ela[fragment,verbatim,center] - c'4:32 [:16 c'8 d'8] + +@mudela[fragment,verbatim,center] + c'4:32 @end mudela -@end ignore + @cindex --@@@code{-}@code{-} @@ -2246,85 +2239,6 @@ These are the contexts supplied with the package. They are defined in the initialization file @file{ly/engraver.ly}. @table @samp - @item @code{Grace}@indexcode{Grace} - The context for handling grace notes. It is instantiated - automatically when you use @code{\grace}. Basically, it is an - `embedded' miniature of the Score context. Since this context - needs special interaction with the rest of LilyPond, you should - not explicitly instantiate it. - - @item @code{LyricVoice}@indexcode{LyricVoice} - Corresponds to a voice with lyrics. Handles the printing of a - single line of lyrics. - - @item @code{Thread}@indexcode{Thread} - Handles note heads, and is contained in the Voice context. You - have to instantiate this explicitly if you want to adjust the - style of individual note heads. - - @item @code{Voice}@indexcode{Voice} - Corresponds to a voice on a staff. This context handles the - conversion of dynamic signs, stems, beams, super- and subscripts, - slurs, ties, and rests. - - You have to instantiate this explicitly if you want to have - multiple voices on the same staff. - - @item @code{ChordNamesVoice}@indexcode{ChordNamesVoice} - A voice with chord names. Handles printing of a line of chord - names. - - @item @code{ChordNames}@indexcode{ChordNames} - Typesets chord names. Can contain @code{ChordNamesVoice} - contexts. - - @item @code{Lyrics}@indexcode{Lyrics} - Typesets lyrics. It can contain @code{LyricVoice} contexts. - - @item @code{Staff}@indexcode{Staff} - Handles clefs, bar lines, keys, accidentals. It can contain - @code{Voice} contexts. - - @item @code{RhythmicStaff}@indexcode{RhythmicStaff} - A context like @code{Staff} but for printing rhythms. Pitches are - ignored; the notes are printed on one line. It can contain - @code{Voice} contexts. - - @item @code{GrandStaff}@indexcode{GrandStaff} - Contains @code{Staff} or @code{RhythmicStaff} contexts. It adds a - brace on the left side, grouping the staffs together. The bar - lines of the contained staffs are connected vertically. It can - contain @code{Staff} contexts. - - @item @code{PianoStaff}@indexcode{PianoStaff} - Just like @code{GrandStaff} but with @code{minVerticalAlign} set - equal to @code{maxVerticalAlign} so that interstaff beaming and - slurring can be used. - - @item @code{StaffGroup}@indexcode{StaffGroup} - Contains @code{Staff} or @code{RhythmicStaff} contexts. Adds a - bracket on the left side, grouping the staffs together. The bar - lines of the contained staffs are connected vertically. It can - contain @code{Staff}, @code{RhythmicStaff}, @code{GrandStaff}, or - @code{Lyrics} contexts. - - @item @code{ChoirStaff}@indexcode{ChoirStaff} - Identical to @code{StaffGroup} except that the contained staffs - are not connected vertically. - - @item @code{Score}@indexcode{Score} - This is the top level notation context. No other context can - contain a @code{Score} context. This context handles the - administration of time signatures. It also makes sure that items - such as clefs, time signatures, and key-signatures are aligned - across staffs. It can contain @code{Lyrics}, @code{Staff}, - @code{RhythmicStaff}, @code{GrandStaff}, @code{StaffGroup}, and - @code{ChoirStaff} contexts. - - You cannot explicitly instantiate a Score context (since it is - not contained in any other context). It is instantiated - automatically when an output definition (a @code{\score} or - @code{\paper} block) is processed. @end table @@ -2417,16 +2331,14 @@ where each of the items is one of dimensions will define the characeristics of all lines beyond those explicitly specified. - @item A font declaration. Its syntax is + @item \stylesheet declaration. Its syntax is @example - - @var{fontsize} @code{=} \font@keyindex{font} @var{fontname} + \stylesheet @var{scm} @end example - @var{fontsize} is an integer describing the font to be used. - 0 is the default font. @var{fontname} is the basename of - a font (usually a member of the Feta family). + + See font.scm for details of @var{scm} @end itemize @@ -2498,12 +2410,7 @@ Nevertheless, here are some variables you may want to use or change: case @code{interscoreline} specifies the minimum spacing. Defaults to 0. - @item @code{output}@indexcode{output} - Specifies an alternate name for the the output @file{s}. - A @file{.tex}, @file{.midi} or @file{.ps} extension will be - added to the string you specify. - - @item @code{rulethickness}@indexcode{rulethickness} + @item @code{stafflinethickness}@indexcode{stafflinethickness} Determines the thickness of staff and bar lines. @end table @@ -2676,143 +2583,6 @@ translator: @end quotation - -@node engravers, , , Reference Manual - -The engravers for paper output are: - -[incomplete, FIXME] - -@table @samp - @item @code{Bar_engraver}@indexcode{Bar_engraver} - Engraves bar lines. Normally in @code{Staff} and - @code{RhythmicStaff}. - - @item @code{Bar_number_engraver}@indexcode{Bar_number_engraver} - Engrave bar numbers. These numbers appear at the start of each - line. Part of @code{Score} context. - - @item @code{Beam_engraver}@indexcode{Beam_engraver} - Handles beam requests by engraving beams. Normally appears in - the @code{Voice} translator. If omitted, then notes will be - printed with flags instead of beams. - - @item @code{Beam_req_swallow_translator} - @indexcode{Beam_req_swallow_translator} - Swallows beam requests. In @code{LyricVoice}. - - @item @code{Chord_name_engraver}@indexcode{Chord_name_engraver} - Engraves chord names. Normally in @code{ChordNameVoice} . - - @item @code{Chord_tremolo_engraver}@indexcode{Chord_tremolo_engraver} - - @item @code{Clef_engraver}@indexcode{Clef_engraver} - Engraves the clef symbol. Normally in @code{Staff}. - - @item @code{Collision_engraver}@indexcode{Collision_engraver} - - @item @code{Dot_column_engraver}@indexcode{Dot_column_engraver} - Engraves dots on dotted notes shifted to the right of the note. - Normally in @code{Voice}. If omitted, then dots appear on top of - the notes. - - @item @code{Dynamic_engraver}@indexcode{Dynamic_engraver} - Engraves dynamics symbols. Normally in @code{Voice}. - - @item @code{Font_size_engraver}@indexcode{Font_size_engraver} - - @item @code{Key_engraver}@indexcode{Key_engraver} - Engraves the key signature. Normally in @code{Staff}. - - @item @code{Local_key_engraver}@indexcode{Local_key_engraver} - - @item @code{Lyric_engraver}@indexcode{Lyric_engraver} - Engraves lyrics. Normally in @code{LyricVoice}. - - @item @code{Multi_measure_rest_engraver} - @indexcode{Multi_measure_rest_engraver} - Engraves multi-measure rests that are produced with @code{R}. - Normally in @code{Voice}. - - @item @code{Piano_bar_engraver}@indexcode{Piano_bar_engraver} - - @item @code{Pitch_squash_engraver}@indexcode{Pitch_squash_engraver} - Treat all pitches as middle C. Used in @code{RhythmicStaff}. - Note that the notes move, but the locations of accidentals stay - the same. - - Vertical position of squashing can be controlled through -@indexcode{squashedPosition}. - - @item @code{Priority_horizontal_align_engraver} - @indexcode{Priority_horizontal_align_engraver} - - @item @code{Repeat_engraver}@indexcode{Repeat_engraver} - Handles repeats? In @code{Staff} and @code{RhythmicStaff}. - - @item @code{Rest_collision_engraver}@indexcode{Rest_collision_engraver} - Handles collisions of rests. In @code{Staff}. - - @item @code{Rest_engraver}@indexcode{Rest_engraver} - Engraves rests. Normally in @code{Voice}. - - @item @code{Rhythmic_column_engraver}@indexcode{Rhythmic_column_engraver} - - @item @code{Score_priority_engraver}@indexcode{Score_priority_engraver} - - @item @code{Script_engraver}@indexcode{Script_engraver} - Handles note ornaments generated by @code{\script}. Normally in - @code{Voice}. - - @item @code{Separating_line_group_engraver} - @indexcode{Separating_line_group_engraver} - - @item @code{Skip_req_swallow_translator} - @indexcode{Skip_req_swallow_translator} - - @item @code{Slur_engraver}@indexcode{Slur_engraver} - Engraves slurs. Normally in @code{Voice}. - - @item @code{Span_bar_engraver}@indexcode{Span_bar_engraver} - Engraves lines across multiple staffs. Normally in - @code{Staffgroup} and @code{GrandStaff}. Removing this from - @code{StaffGroup} gives the definition of @code{ChoirStaff}. - - @item @code{Span_score_bar_engraver}@indexcode{Span_score_bar_engraver} - - @item @code{Staff_group_bar_engraver}@indexcode{Staff_group_bar_engraver} - - @item @code{Instrument_name_engraver}@indexcode{Instrument_name_engraver} - Prints the name of the instrument (specified by - @code{Staff.instrument} and @code{Staff.instr}) at the left of the - staff. - - @item @code{Staff_sym_engraver}@indexcode{Staff_sym_engraver} - - @item @code{Stem_engraver}@indexcode{Stem_engraver} - Engraves stems. Normally in @code{Voice}. - - @item @code{Ties_engraver}@indexcode{Ties_engraver} - Engraves ties. Normally in @code{Voice}. - - @item @code{Time_signature_engraver}@indexcode{Time_signature_engraver} - Engraves the time signature. Normally in @code{Staff} and - @code{RhythmicStaff}. - - @item @code{Timing_engraver}@indexcode{Timing_engraver} - Responsible for synchronizing timing information from staffs. - Normally in @code{Score}. In order to create polyrhythmic music, - this engraver should be removed from @code{Score} and placed in - @code{Staff}. - - @item @code{Tuplet_engraver}@indexcode{Tuplet_engraver} - Engraves tuplet brackets? In @code{Staff}. - - @item @code{Vertical_align_engraver}@indexcode{Vertical_align_engraver} -@end table - - - @node Sound output, , , Reference Manual @section Sound output diff --git a/VERSION b/VERSION index e8e6aeb436..4f5c5d4af3 100644 --- a/VERSION +++ b/VERSION @@ -1,7 +1,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=3 -PATCH_LEVEL=102 +PATCH_LEVEL=103 MY_PATCH_LEVEL= # use the above to send patches: MY_PATCH_LEVEL is always empty for a diff --git a/lily/hyphen-engraver.cc b/lily/hyphen-engraver.cc index e18619c28a..e78882d3d1 100644 --- a/lily/hyphen-engraver.cc +++ b/lily/hyphen-engraver.cc @@ -55,7 +55,7 @@ void Hyphen_engraver::acknowledge_element (Score_element_info i) { // -> text-item - if (i.elem_l_->has_interface (ly_symbol2scm ("text-item-interface"))) + if (i.elem_l_->has_interface (ly_symbol2scm ("lyric-syllable-interface"))) { current_lyric_l_ = i.elem_l_; if (hyphen_p_ diff --git a/lilypond-font-lock.el b/lilypond-font-lock.el new file mode 100644 index 0000000000..c760f093a4 --- /dev/null +++ b/lilypond-font-lock.el @@ -0,0 +1,89 @@ +;; lilypond-font-lock.el + +;; Copyright (C) 1992,1993,1994 Tim Peters + +;; Author: 1997: Han-Wen Nienhuys +;; Author: 1995-1996 Barry A. Warsaw +;; 1992-1994 Tim Peters +;; Created: Feb 1992 +;; Version: 0.0 +;; Last Modified: 12SEP97 +;; Keywords: lilypond languages music notation + +;; This software is provided as-is, without express or implied +;; warranty. Permission to use, copy, modify, distribute or sell this +;; software, without fee, for any purpose and by any individual or +;; organization, is hereby granted, provided that the above copyright +;; notice and this paragraph appear in all copies. + +;; This started out as a cannabalised version of python-mode.el, by hwn +;; For changes see the LilyPond ChangeLog +;; +;; TODO: +;; - should handle block comments too. +;; - handle lexer modes (\header, \melodic, \lyric) etc. +;; - indentation +;; - notenames? +;; - fontlock: \melodic \melodic + +(defconst LilyPond-font-lock-keywords + (let* ((keywords '("spanrequest" "simultaneous" "sequential" "accepts" + "autochange" "alternative" "bar" "breathe" + "cadenza" "chordmodifiers" "chords" "clef" "cm" "consists" + "consistsend" "context" + "duration" "font" "grace" "header" "in" "lyrics" + "key" "keysignature" "mark" "musicalpitch" + "time" "times" "midi" "mm" "name" "notenames" + "notes" "partial" "paper" "penalty" "push" "pop" "property" "pt" + "relative" "remove" "repeat" "repetitions" "addlyrics" + "scm" "scmfile" "score" "script" + "shape" "skip" "textscript" "tempo" "translator" "transpose" + "type" "version" + )) + (kwregex (mapconcat (lambda (x) (concat "\\\\" x)) keywords "\\|"))) + + (list + (concat ".\\(" kwregex "\\)[^a-zA-Z]") + (concat "^\\(" kwregex "\\)[^a-zA-Z]") + '(".\\(\\\\[a-zA-Z][a-zA-Z]*\\)" 1 font-lock-variable-name-face) + '("^[\t ]*\\([a-zA-Z][_a-zA-Z]*\\) *=" 1 font-lock-variable-name-face) + )) + "Additional expressions to highlight in LilyPond mode.") + +;; define a mode-specific abbrev table for those who use such things +(defvar LilyPond-mode-abbrev-table nil + "Abbrev table in use in `LilyPond-mode' buffers.") + +(define-abbrev-table 'LilyPond-mode-abbrev-table nil) + +(defvar LilyPond-mode-syntax-table nil + "Syntax table used in `LilyPond-mode' buffers.") + +;; +(if LilyPond-mode-syntax-table + () + (setq LilyPond-mode-syntax-table (make-syntax-table)) + (mapcar (function + (lambda (x) (modify-syntax-entry + (car x) (cdr x) LilyPond-mode-syntax-table))) + '(( ?\( . "()" ) ( ?\) . ")(" ) ; need matching parens for inline lisp + ( ?\[ . "." ) ( ?\] . "." ) + ( ?\{ . "(}" ) ( ?\} . "){" ) + ( ?\< . "(>" )( ?\> . ")>") + ( ?\$ . "." ) ( ?\% . "." ) ( ?\& . "." ) + ( ?\* . "." ) ( ?\+ . "." ) ( ?\- . "." ) + ( ?\/ . "." ) ( ?\= . "." ) + ( ?\| . "." ) (?\\ . "\\" ) + ( ?\_ . "." ) + ( ?\' . "w") + ( ?\" . "\"" ) + ( ?\% . "<") + ( ?\n . ">") + +; FIXME +; ( ?% . ". 124b" ) +; ( ?{ . ". 23" ) + )) + + ) + diff --git a/lilypond-mode.el b/lilypond-mode.el index 65e7b340b0..8250db03fe 100644 --- a/lilypond-mode.el +++ b/lilypond-mode.el @@ -1,155 +1,88 @@ +;;; ;;; lilypond-mode.el --- Major mode for editing GNU LilyPond music scores +;;; +;;; source file of the GNU LilyPond music typesetter +;;; +;;; (c) 1999, 2000 Jan Nieuwenhuizen -;; Copyright (C) 1992,1993,1994 Tim Peters - -;; Author: 1999: Jan Nieuwenhuizen -;; Author: 1997: Han-Wen Nienhuys -;; Author: 1995-1996 Barry A. Warsaw -;; 1992-1994 Tim Peters -;; Created: Feb 1992 -;; Version: 0.0 -;; Last Modified: 12SEP97 -;; Keywords: mudela languages music - -;; This software is provided as-is, without express or implied -;; warranty. Permission to use, copy, modify, distribute or sell this -;; software, without fee, for any purpose and by any individual or -;; organization, is hereby granted, provided that the above copyright -;; notice and this paragraph appear in all copies. - -;; This started out as a cannabalised version of python-mode.el, by hwn -;; For changes see the LilyPond ChangeLog -;; -;; TODO: -;; * lily/ly/lilypond? -;; * syntax -;; - should handle block comments too. -;; - handle lexer modes (\header, \melodic, \lyric) etc. -;; - indentation -;; - notenames? -;; - fontlock: \melodic \melodic - - -(defconst lily-version "1.3.19" - "`lilypond-mode' version number.") - -(defconst lily-help-address "hanwen@cs.uu.nl" - "Address accepting submission of bug reports.") +;;; Inspired on auctex -(defconst lily-font-lock-keywords - (let* ((keywords '("spanrequest" "simultaneous" "sequential" "accepts" - "autochange" "alternative" "bar" "breathe" - "cadenza" "chordmodifiers" "chords" "clef" "cm" "consists" - "consistsend" "context" - "duration" "font" "grace" "header" "in" "lyrics" - "key" "keysignature" "mark" "musicalpitch" - "time" "times" "midi" "mm" "name" "notenames" - "notes" "partial" "paper" "penalty" "push" "pop" "property" "pt" - "relative" "remove" "repeat" "repetitions" "addlyrics" - "scm" "scmfile" "score" "script" - "shape" "skip" "textscript" "tempo" "translator" "transpose" - "type" "version" - )) - (kwregex (mapconcat (lambda (x) (concat "\\\\" x)) keywords "\\|"))) - - (list - (concat ".\\(" kwregex "\\)[^a-zA-Z]") - (concat "^\\(" kwregex "\\)[^a-zA-Z]") - '(".\\(\\\\[a-zA-Z][a-zA-Z]*\\)" 1 font-lock-variable-name-face) - '("^[\t ]*\\([a-zA-Z][_a-zA-Z]*\\) *=" 1 font-lock-variable-name-face) - )) - "Additional expressions to highlight in Mudela mode.") - -;; define a mode-specific abbrev table for those who use such things -(defvar lilypond-mode-abbrev-table nil - "Abbrev table in use in `lilypond-mode' buffers.") - -(define-abbrev-table 'lilypond-mode-abbrev-table nil) - -(defvar lilypond-mode-hook nil - "*Hook called by `lilypond-mode'.") - -(defvar lily-mode-syntax-table nil - "Syntax table used in `lilypond-mode' buffers.") - -;; -(if lily-mode-syntax-table - () - (setq lily-mode-syntax-table (make-syntax-table)) - (mapcar (function - (lambda (x) (modify-syntax-entry - (car x) (cdr x) lily-mode-syntax-table))) - '(( ?\( . "()" ) ( ?\) . ")(" ) ; need matching parens for inline lisp - ( ?\[ . "." ) ( ?\] . "." ) - ( ?\{ . "(}" ) ( ?\} . "){" ) - ( ?\< . "(>" )( ?\> . ")>") - ( ?\$ . "." ) ( ?\% . "." ) ( ?\& . "." ) - ( ?\* . "." ) ( ?\+ . "." ) ( ?\- . "." ) - ( ?\/ . "." ) ( ?\= . "." ) - ( ?\| . "." ) (?\\ . "\\" ) - ( ?\_ . "." ) - ( ?\' . "w") - ( ?\" . "\"" ) - ( ?\% . "<") - ( ?\n . ">") - -; FIXME -; ( ?% . ". 124b" ) -; ( ?{ . ". 23" ) - )) - - ) - -(defconst lily-imenu-generic-re "^\\([a-zA-Z_][a-zA-Z0-9_]*\\) *=" - "Regexp matching Identifier definitions.") -;; Sadly we need this for a macro in Emacs 19. -(eval-when-compile - ;; Imenu isn't used in XEmacs, so just ignore load errors. - (condition-case () - (require 'imenu) - (error nil))) +(load-file "lilypond-font-lock.el") -(defvar lily-imenu-generic-expression - (list (list nil lily-imenu-generic-re 1)) - "Expression for imenu") - - -;;; we're using some handy compile commands +(require 'easymenu) (require 'compile) -(defcustom lily-command "lilypond" - "* LilyPond executable." - :type 'string - :group 'lily) +(defconst LilyPond-version "1.3.103" + "`LilyPond-mode' version number.") -(defcustom lily-parameters "" - "*." - :type 'string - :group 'lily) +(defconst LilyPond-help-address "bug-gnu-music@gnu.org" + "Address accepting submission of bug reports.") -(defvar lily-regexp-alist +(defvar LilyPond-mode-hook nil + "*Hook called by `LilyPond-mode'.") + +(defvar LilyPond-regexp-alist '(("\\([a-zA-Z]?:?[^:( \t\n]+\\)[:( \t]+\\([0-9]+\\)[:) \t]" 1 2)) "Regexp used to match LilyPond errors. See `compilation-error-regexp-alist'.") -(defcustom lily-tex-command "tex" - "*." +(defcustom LilyPond-include-path ".:/tmp" + "* LilyPond include path." :type 'string - :group 'lily) + :group 'LilyPond) + + +(defun LilyPond-check-files (derived originals extensions) + "Check that DERIVED is newer than any of the ORIGINALS. +Try each original with each member of EXTENSIONS, in all directories +in LilyPond-include-path." + (let ((found nil) + (regexp (concat "\\`\\(" + (mapconcat (function (lambda (dir) + (regexp-quote (expand-file-name dir)))) + LilyPond-include-path "\\|") + "\\).*\\(" + (mapconcat 'regexp-quote originals "\\|") + "\\)\\.\\(" + (mapconcat 'regexp-quote extensions "\\|") + "\\)\\'")) + (buffers (buffer-list))) + (while buffers + (let* ((buffer (car buffers)) + (name (buffer-file-name buffer))) + (setq buffers (cdr buffers)) + (if (and name (string-match regexp name)) + (progn + (and (buffer-modified-p buffer) + (or (not LilyPond-save-query) + (y-or-n-p (concat "Save file " + (buffer-file-name buffer) + "? "))) + (save-excursion (set-buffer buffer) (save-buffer))) + (if (file-newer-than-file-p name derived) + (setq found t)))))) + found)) + +(defun LilyPond-running () + (let ((process (get-process "lilypond"))) + (and process + (eq (process-status process) 'run)))) -(defcustom lily-xdvi-command "xdvi" - "*." - :type 'string - :group 'lily) +(defun LilyPond-kill-job () + "Kill the currently running LilyPond job." + (interactive) + ;; What bout TeX, Xdvi? + (quit-process (get-process "lilypond") t)) -(defun lily-compile-file (command parameters file) - ;; Setting process-setup-function makes exit-message-function work - ;; even when async processes aren't supported. - (let ((command-args (concat command " " parameters " " file))) - (compile-internal command-args "No more errors" "LilyPond"))) +;; URG, should only run LilyPond-compile for LilyPond +;; not for tex,xdvi (ly2dvi?) +(defun LilyPond-compile-file (command name) + ;; We maybe should know what we run here (Lily, ly2dvi, tex) + ;; and adjust our error-matching regex ? + (compile-internal command "No more errors" name )) ;; do we still need this, now that we're using compile-internal? -(defun lily-save-buffer () +(defun LilyPond-save-buffer () (if (buffer-modified-p) (save-buffer))) ;;; return (dir base ext) @@ -164,155 +97,308 @@ (list dir (substring file 0 (- i 1)) (substring file i (length file))) (list dir file "")))) -;;;###autoload -(defun lily-eval-buffer () - "Run LilyPond on buffer." - (interactive) - (let ((buffer (buffer-name))) - (if (buffer-file-name) - (progn - (lily-save-buffer) - (lily-compile-file lily-command lily-parameters (buffer-file-name))) - (progn - (error "Buffer %s is not associated with a file" buffer) - (lily-eval-region (min-point) (max-point)))))) - -;;;###autoload -(defun lily-eval-region (start end) - "Run LilyPond on region." - (interactive "r") - (let ((basename "emacs-lily") - (suffix (if (string-match "^[\\]score" (buffer-substring start end)) - ".ly" - (if (< 50 (abs (- start end))) - ".fly" - ".sly")))) - (write-region start end (concat basename suffix) nil 'nomsg) - (lily-compile-file lily-command lily-parameters (concat basename suffix)))) - -(defun lily-running () - (let ((process (get-process "lilypond"))) - (and process - (eq (process-status process) 'run)))) -(defun lily-tex-file (basename) - (call-process lily-tex-command nil t nil basename)) - -(defun lily-xdvi-file (basename) - (let ((outbuf (get-buffer-create "*lily-xdvi*")) - (name "xdvi") - (command (concat lily-xdvi-command " " basename))) - (if (get-process "xdvi") - ;; Don't open new xdvi window, but force redisplay - ;; We could make this an option. - (signal-process (process-id (get-process "xdvi")) 'SIGUSR1) - (if (fboundp 'start-process) - (let* ((process-environment (cons "EMACS=t" process-environment)) - (proc (start-process-shell-command name outbuf command))) - ;;(set-process-sentinel proc 'compilation-sentinel) - ;;(set-process-filter proc 'compilation-filter) - (set-marker (process-mark proc) (point) outbuf)) - ;;(setq compilation-in-progress (cons proc compilation-in-progress))) - - ;; No asynchronous processes available. - (message "Executing `%s'..." command) - ;; Fake modeline display as if `start-process' were run. - (setq mode-line-process ":run") - (force-mode-line-update) - (sit-for 0) ; Force redisplay - (call-process shell-file-name nil outbuf nil "-c" command) - (message "Executing `%s'...done" command))))) - - -;;;###autoload -(defun lily-xdvi-buffer () - "Run LilyPond, TeX and Xdvi on buffer." - (interactive) +;; Should check whether in command-alist? +(defvar LilyPond-command-default "LilyPond") +;;;(make-variable-buffer-local 'LilyPond-command-last) - (let* ((split (split-file-name buffer-file-name)) - (dir (car split)) - (base (cadr split))) +(defvar LilyPond-command-current 'LilyPond-command-master) +;;;(make-variable-buffer-local 'LilyPond-command-master) - ;; we don't really need this... - (let ((tex (concat dir base ".tex")) - (dvi (concat dir base ".dvi"))) - (if (file-exists-p tex) (delete-file tex)) - (if (file-exists-p dvi) (delete-file dvi))) - (lily-eval-buffer) - (set-buffer "*lilypond*") - - ;;(setq default-directory dir) - (while (lily-running) - (continue-process (get-process "lilypond"))) - (sit-for 0) ; Force redisplay - - (if (= 0 (process-exit-status (get-process "lilypond"))) - (progn - (if (= 0 (lily-tex-file base)) - (lily-xdvi-file base)))))) - -;;;###autoload -(defun lily-xdvi-region (start end) - "Run LilyPond, TeX and Xdvi on region." - (interactive "r") +;; If non-nil, LilyPond-command-query will return the value of this +;; variable instead of quering the user. +(defvar LilyPond-command-force nil) - (let ((dir default-directory) - (base "emacs-lily")) - ;; we don't really need this... - (let ((tex (concat dir base ".tex")) - (dvi (concat dir base ".dvi"))) - (if (file-exists-p tex) (delete-file tex)) - (if (file-exists-p dvi) (delete-file dvi))) +;; This is the major configuration variable. +(defcustom LilyPond-command-alist + '( + ("LilyPond" . ("lilypond %s" . "TeX")) + ("TeX" . ("tex '\\nonstopmode\\input %t'" . "View")) - (lily-eval-region start end) - (set-buffer "*lilypond*") + ;; point-n-click (arg: exits upop USR1) + ("SmartView" . ("xdvi %d" . "LilyPond")) - ;;(setq default-directory dir) - (while (lily-running) - (continue-process (get-process "lilypond"))) - (sit-for 0) ; Force redisplay + ;; refreshes when kicked USR1 + ("View" . ("xdvik %d" . "LilyPond")) + ) + + "AList of commands to execute on the current document. + +The key is the name of the command as it will be presented to the +user, the value is a cons of the command string handed to the shell +after being expanded, and the next command to be executed upon +success. The expansion is done using the information found in +LilyPond-expand-list. +" + :group 'LilyPond + :type '(repeat (group (string :tag "Name") + (string :tag "Command") + (choice :tag "How" + :value LilyPond-run-command + (function-item LilyPond-run-command) + (function-item LilyPond-run-LilyPond) + (function :tag "Other")) + (boolean :tag "Prompt") + (sexp :format "End\n")))) + +;; drop this? +(defcustom LilyPond-file-extensions '(".ly" ".sly" ".fly") + "*File extensions used by manually generated TeX files." + :group 'LilyPond + :type '(repeat (string :format "%v"))) + + +(defcustom LilyPond-expand-alist + '( + ("%s" . ".ly") + ("%t" . ".tex") + ("%d" . ".dvi") + ("%p" . ".ps") + ) - (if (= 0 (process-exit-status (get-process "lilypond"))) - (progn - (if (= 0 (lily-tex-file base)) - (lily-xdvi-file base)))))) + "Alist of expansion strings for LilyPond command names." + :group 'LilyPond + :type '(repeat (group (string :tag "Key") + (sexp :tag "Expander") + (repeat :inline t + :tag "Arguments" + (sexp :format "%v"))))) + + +(defcustom LilyPond-command-Show "View" + "*The default command to show (view or print) a LilyPond file. +Must be the car of an entry in LilyPond-command-alist." + :group 'LilyPond + :type 'string) + (make-variable-buffer-local 'LilyPond-command-Show) + +(defcustom LilyPond-command-Print "Print" + "The name of the Print entry in LilyPond-command-Print." + :group 'LilyPond + :type 'string) + +(defun xLilyPond-compile-sentinel (process msg) + (if (and process + (= 0 (process-exit-status process))) + (setq LilyPond-command-default + (cddr (assoc LilyPond-command-default LilyPond-command-alist))))) + +;; FIXME: shouldn't do this for stray View/xdvi +(defun LilyPond-compile-sentinel (buffer msg) + (if (string-match "^finished" msg) + (setq LilyPond-command-default + (cddr (assoc LilyPond-command-default LilyPond-command-alist))))) + +;;(make-variable-buffer-local 'compilation-finish-function) +(setq compilation-finish-function 'LilyPond-compile-sentinel) + +(defun LilyPond-command-query (name) + "Query the user for what LilyPond command to use." + (let* ((default (cond ((if (string-equal name "emacs-lily") + (LilyPond-check-files (concat name ".tex") + (list name) + LilyPond-file-extensions) + ;; FIXME + (LilyPond-save-buffer) + ;;"LilyPond" + LilyPond-command-default)) + (t LilyPond-command-default))) + + (answer (or LilyPond-command-force + (completing-read + (concat "Command: (default " default ") ") + LilyPond-command-alist nil t)))) + + ;; If the answer is "LilyPond" it will not be expanded to "LilyPond" + (let ((answer (car-safe (assoc answer LilyPond-command-alist)))) + (if (and answer + (not (string-equal answer ""))) + answer + default)))) + + +;; FIXME: find ``\score'' in buffers / make settable? +(defun LilyPond-master-file () + ;; duh + (buffer-file-name)) + +(defun LilyPond-command-master () + "Run command on the current document." + (interactive) + (LilyPond-command (LilyPond-command-query (LilyPond-master-file)) + 'LilyPond-master-file)) + +(defun LilyPond-region-file (begin end) + (let ( + ;; (dir "/tmp/") + ;; urg + (dir "./") + (base "emacs-lily") + ;; Hmm + (ext (if (string-match "^[\\]score" (buffer-substring begin end)) + ".ly" + (if (< 50 (abs (- begin end))) + ".fly" + ".sly")))) + (concat dir base ext))) + +(defun LilyPond-command-region (begin end) + "Run LilyPond on the current region." + (interactive "r") + (write-region begin end (LilyPond-region-file begin end) nil 'nomsg) + (LilyPond-command (LilyPond-command-query + (LilyPond-region-file begin end)) + '(lambda () (LilyPond-region-file begin end)))) -;;;###autoload -(defun lily-kill-job () - "Kill the currently running LilyPond job." +(defun LilyPond-command-buffer () + "Run LilyPond on buffer." (interactive) - (quit-process (get-process "lilypond") t)) + (LilyPond-command-region (point-min) (point-max))) + +(defun LilyPond-command-expand (string file) + (let ((case-fold-search nil)) + (if (string-match "%" string) + (let* ((b (match-beginning 0)) + (e (+ b 2)) + (l (split-file-name file)) + (dir (car l)) + (base (cadr l))) + (LilyPond-command-expand + (concat (substring string 0 b) + dir + base + (let ((entry (assoc (substring string b e) + LilyPond-expand-alist))) + (if entry (cdr entry) "")) + (substring string e)) + file)) + string))) + +(defun LilyPond-command (name file) + "Run command NAME on the file you get by calling FILE. + +FILE is a function return a file name. It has one optional argument, +the extension to use on the file. + +Use the information in LilyPond-command-alist to determine how to run the +command." + + (let ((entry (assoc name LilyPond-command-alist))) + (if entry + (let ((command (LilyPond-command-expand (cadr entry) + (apply file nil)))) + (let* ( + (buffer-xdvi (get-buffer "*view*")) + (process-xdvi (if buffer-xdvi (get-buffer-process buffer-xdvi) nil))) + (if (and process-xdvi + (string-equal name "View")) + ;; Don't open new xdvi window, but force redisplay + ;; We could make this an option. + (signal-process (process-id process-xdvi) 'SIGUSR1) + (progn + (setq LilyPond-command-default name) + (LilyPond-compile-file command name)))))))) + +;; XEmacs stuff +;; Sadly we need this for a macro in Emacs 19. +(eval-when-compile + ;; Imenu isn't used in XEmacs, so just ignore load errors. + (condition-case () + (require 'imenu) + (error nil))) + -;; hmm -;; (kill-process (get-process "xdvi") t) +;;; Keymap -(defvar lily-mode-map () - "Keymap used in `lilypond-mode' buffers.") +(defvar LilyPond-mode-map () + "Keymap used in `LilyPond-mode' buffers.") ;; Note: if you make changes to the map, you must do -;; M-x set-variable lily-mode-map nil +;; M-x set-variable LilyPond-mode-map nil ;; M-x eval-buffer -;; M-x lilypond-mode +;; M-x LilyPond-mode ;; to let the changest take effect -(if lily-mode-map + +(if LilyPond-mode-map () - (setq lily-mode-map (make-sparse-keymap)) - (define-key lily-mode-map [f9] 'lily-eval-buffer) - (define-key lily-mode-map [f10] 'lily-xdvi-buffer) - (define-key lily-mode-map [S-f9] 'lily-eval-region) - (define-key lily-mode-map [S-f10] 'lily-xdvi-region) - ) - -(defun lilypond-mode () - "Major mode for editing Mudela files." + (setq LilyPond-mode-map (make-sparse-keymap)) + (define-key LilyPond-mode-map "\C-c\C-c" 'LilyPond-command-master) + (define-key LilyPond-mode-map "\C-c\C-r" 'LilyPond-command-region) + (define-key LilyPond-mode-map "\C-c\C-b" 'LilyPond-command-buffer) + (define-key LilyPond-mode-map "\C-c\C-k" 'LilyPond-kill-job) + ) + +;;; Menu Support + +(defun LilyPond-command-menu-entry (entry) + ;; Return LilyPond-command-alist ENTRY as a menu item. + (let ((name (car entry))) + (cond ((and (string-equal name LilyPond-command-Print) + LilyPond-printer-list) + (let ((command LilyPond-print-command) + (lookup 1)) + (append (list LilyPond-command-Print) + (mapcar 'LilyPond-command-menu-printer-entry + LilyPond-printer-list)))) + (t + (vector name (list 'LilyPond-command-menu name) t))))) + + +(easy-menu-define LilyPond-mode-menu + LilyPond-mode-map + "Menu used in LilyPond mode." + (append '("Command") + '(("Command on" + [ "Master File" LilyPond-command-select-master + :keys "C-c C-c" :style radio + :selected (eq LilyPond-command-current 'LilyPond-command-master) ] + [ "Buffer" LilyPond-command-select-buffer + :keys "C-c C-b" :style radio + :selected (eq LilyPond-command-current 'LilyPond-command-buffer) ] + [ "Region" LilyPond-command-select-region + :keys "C-c C-r" :style radio + :selected (eq LilyPond-command-current 'LilyPond-command-region) ])) + (let ((file 'LilyPond-command-on-current)) + (mapcar 'LilyPond-command-menu-entry LilyPond-command-alist)))) + + +(defconst LilyPond-imenu-generic-re "^\\([a-zA-Z_][a-zA-Z0-9_]*\\) *=" + "Regexp matching Identifier definitions.") + +(defvar LilyPond-imenu-generic-expression + (list (list nil LilyPond-imenu-generic-re 1)) + "Expression for imenu") + +(defun LilyPond-command-select-master () + (interactive) + (message "Next command will be on the master file") + (setq LilyPond-command-current 'LilyPond-command-master)) + +(defun LilyPond-command-select-buffer () + (interactive) + (message "Next command will be on the buffer") + (setq LilyPond-command-current 'LilyPond-command-buffer)) + +(defun LilyPond-command-select-region () + (interactive) + (message "Next command will be on the region") + (setq LilyPond-command-current 'LilPond-command-region)) + +(defun LilyPond-command-menu (name) + ;; Execute LilyPond-command-alist NAME from a menu. + (let ((LilyPond-command-force name)) + (funcall LilyPond-command-current))) + +(defun LilyPond-mode () + "Major mode for editing LilyPond music files." (interactive) ;; set up local variables (kill-all-local-variables) (make-local-variable 'font-lock-defaults) - (setq font-lock-defaults '(lily-font-lock-keywords)) + (setq font-lock-defaults '(LilyPond-font-lock-keywords)) (make-local-variable 'paragraph-separate) (setq paragraph-separate "^[ \t]*$") @@ -335,46 +421,27 @@ (make-local-variable 'block-comment-end) (setq block-comment-end "%}") - ;; (make-local-variable 'comment-column) - ;; (setq comment-column 40) - - (make-local-variable 'imenu-generic-expression) - (setq imenu-generic-expression lily-imenu-generic-expression) - (make-local-variable 'indent-line-function) (setq indent-line-function 'indent-relative-maybe) - ;; - (set-syntax-table lily-mode-syntax-table) - (setq major-mode 'lilypond-mode) - (setq mode-name "Mudela") - (setq local-abbrev-table lilypond-mode-abbrev-table) - (use-local-map lily-mode-map) - - ;; run the mode hook. lily-mode-hook use is deprecated - (run-hooks 'lilypond-mode-hook)) - - -(defun lily-keep-region-active () - ;; do whatever is necessary to keep the region active in XEmacs. - ;; Ignore byte-compiler warnings you might see. Also note that - ;; FSF's Emacs 19 does it differently and doesn't its policy doesn't - ;; require us to take explicit action. - (and (boundp 'zmacs-region-stays) - (setq zmacs-region-stays t))) - - -;;(defun lily-comment-region (beg end &optional arg) -;; "Like `comment-region' but uses double hash (`#') comment starter." -;; (interactive "r\nP") -;; (let ((comment-start lily-block-comment-prefix)) -;; (comment-region beg end arg))) - -(defun lily-version () - "Echo the current version of `lilypond-mode' in the minibuffer." + (set-syntax-table LilyPond-mode-syntax-table) + (setq major-mode 'LilyPond-mode) + (setq mode-name "LilyPond") + (setq local-abbrev-table LilyPond-mode-abbrev-table) + (use-local-map LilyPond-mode-map) + + (make-local-variable 'imenu-generic-expression) + (setq imenu-generic-expression LilyPond-imenu-generic-expression) + (imenu-add-to-menubar "Index") + + ;; run the mode hook. LilyPond-mode-hook use is deprecated + (run-hooks 'LilyPond-mode-hook)) + +(defun LilyPond-version () + "Echo the current version of `LilyPond-mode' in the minibuffer." (interactive) - (message "Using `lilypond-mode' version %s" lily-version) - (lily-keep-region-active)) + (message "Using `LilyPond-mode' version %s" LilyPond-version)) + +(provide 'LilyPond-mode) +;;; LilyPond-mode.el ends here -(provide 'lilypond-mode) -;;; lilypond-mode.el ends here diff --git a/make/lilypond.spec.in b/make/lilypond.spec.in index 8c6f52170d..bcd0bca7a7 100644 --- a/make/lilypond.spec.in +++ b/make/lilypond.spec.in @@ -94,6 +94,7 @@ fi %files # hairy to hook it in (possibly non-existing) emacs %doc lilypond-mode.el +%doc lilypond-font-lock.el %ifnos cygwin %{_prefix}/bin/abc2ly diff --git a/make/toplevel.make.in b/make/toplevel.make.in index 3e980b979f..b433213ffe 100644 --- a/make/toplevel.make.in +++ b/make/toplevel.make.in @@ -17,7 +17,7 @@ SCRIPTS = configure aclocal.m4 README_FILES = DEDICATION COPYING NEWS CHANGES ROADMAP README_TXT_FILES = AUTHORS.txt README.txt INSTALL.txt IN_FILES := $(wildcard *.in) -EXTRA_DIST_FILES = lilypond-mode.el vimrc VERSION $(README_FILES) $(SCRIPTS) $(IN_FILES) +EXTRA_DIST_FILES = lilypond-font-lock.el lilypond-mode.el vimrc VERSION $(README_FILES) $(SCRIPTS) $(IN_FILES) NON_ESSENTIAL_DIST_FILES = $(README_TXT_FILES) # bootstrap stepmake: