emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to find someone working on a (mixed) major mode for LilyPond?


From: David Kastrup
Subject: Re: How to find someone working on a (mixed) major mode for LilyPond?
Date: Sun, 13 Sep 2015 19:06:52 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux)

Richard Stallman <address@hidden> writes:

> [[[ To any NSA and FBI agents reading my email: please consider    ]]]
> [[[ whether defending the US Constitution against all enemies,     ]]]
> [[[ foreign or domestic, requires you to follow Snowden's example. ]]]
>
> I think it would be really good to make progress in dual-language
> editing in Emacs, especially if we can improve the general facilities
> so as to make such modes easier to write.
>
> I urge people to help you in this project.

To illustrate: here is an extract from ly/music-functions-init.ly:

compoundMeter =
#(define-music-function (args) (pair?)
  (_i "Create compound time signatures. The argument is a Scheme list of
lists. Each list describes one fraction, with the last entry being the
denominator, while the first entries describe the summands in the
enumerator. If the time signature consists of just one fraction,
the list can be given directly, i.e. not as a list containing a single list.
For example, a time signature of (3+1)/8 + 2/4 would be created as
@code{\\compoundMeter #'((3 1 8) (2 4))}, and a time signature of (3+2)/8
as @code{\\compoundMeter #'((3 2 8))} or shorter
@code{\\compoundMeter #'(3 2 8)}.")
  (let* ((mlen (calculate-compound-measure-length args))
         (beat (calculate-compound-base-beat args))
         (beatGrouping (calculate-compound-beat-grouping args))
         (timesig (cons (ly:moment-main-numerator mlen)
                        (ly:moment-main-denominator mlen))))
  #{
    \once \override Timing.TimeSignature.stencil = #(lambda (grob)
      (grob-interpret-markup grob (make-compound-meter-markup args)))
    \set Timing.timeSignatureFraction = #timesig
    \set Timing.baseMoment = #beat
    \set Timing.beatStructure = #beatGrouping
    \set Timing.beamExceptions = #'()
    \set Timing.measureLength = #mlen
  #} ))

It defines a command \compoundMeter that can be used in LilyPond
passages according to the instructions in the gettext-enabled DOC
string.  At the first # the parser is thrown into Scheme mode and reads
one sexp (incidentally ending at the end of the quoted passage).  The
body of the let* is a "music expression" in LilyPond syntax bracketed in
#{...#}.  It contains various Scheme expressions again, namely
#(lambda...), #beat, #beatGrouping, #'() and #mlen.  Again, following
any of the # one sexp is read and then syntax returns to Lilypond.

For something like SMIE, one would likely regard all of #sexp as a
single token, but this token is Scheme syntax internally and should
(apart from any included #{...#} of course) ideally be totally the same
as Emacs' Scheme mode.  In LilyPond mode itself, however, ( and ) are
not matched delimiters.

When used, \compoundMeter is followed by one LilyPond expression obeying
the predicate pair?.  That can be something like #'(...) (list or dotted
pair/list), but it can also be something like 3/4 (which is LilyPond
shordhand for #'(3 . 4)).  3/4 cannot be represented as Scheme #3/4
since that would make it indistinguishable from 6/8 which is a different
musical meter altogether.  There are similar equivalences all around:
instead of \once \override Timing.TimeSignature.stencil = ##f you could
write #(once (property-override '(Timing TimeSignature stencil) #f))
for the equivalent effect.

So a typical LilyPond file is going back and forth between Scheme and
LilyPond a whole lot: most numeric expressions are entered in Scheme
mode, and pretty much any control structure or expression while any
music content inside of such structures is then delivered via #{...#} in
LilyPond mode.

As a result, there are a whole lot of Scheme/LilyPond syntax transitions
in a typical file.  And it would be really nice to use scheme-mode for
the Scheme parts without incurring a large overhead for switching
between the principal modes.

-- 
David Kastrup



reply via email to

[Prev in Thread] Current Thread [Next in Thread]