X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scm%2Ftranslation-functions.scm;h=a535497962c07b9ae8ca5d79d1faf3901d1b7e10;hb=d11dbf277719c0179c5520154c925839d969a535;hp=d373da0eebcc0079c2e0c8d0e76a747ceba38742;hpb=9203eadca5bcb79415060f8488889706a9c8e62a;p=lilypond.git diff --git a/scm/translation-functions.scm b/scm/translation-functions.scm index d373da0eeb..a535497962 100644 --- a/scm/translation-functions.scm +++ b/scm/translation-functions.scm @@ -276,6 +276,10 @@ dot placement entries." along with @var{minimum-fret}, @var{maximum-stretch}, and @var{tuning}. Returns a list of @code{(string fret finger) lists." + + (define restrain-open-strings (ly:context-property context + 'restrainOpenStrings + #f)) (define specified-frets '()) (define free-strings (iota (length tuning) 1)) @@ -326,7 +330,8 @@ if no string-number is present." #t (map (lambda (specced-fret) (or (eq? 0 specced-fret) - (eq? 0 fret) + (and (not restrain-open-strings) + (eq? 0 fret)) (>= maximum-stretch (abs (- fret specced-fret))))) specified-frets)))) @@ -334,7 +339,9 @@ if no string-number is present." "Can @var{pitch} be played on @var{string}, given already placed notes?" (let* ((fret (calc-fret pitch string tuning))) - (and (or (eq? fret 0) (>= fret minimum-fret)) + (and (or (and (not restrain-open-strings) + (eq? fret 0)) + (>= fret minimum-fret)) (close-enough fret)))) (define (open-string string pitch) @@ -658,3 +665,39 @@ only ~a fret labels provided") (= 0 (modulo count n))) (define-public (all-repeat-counts-visible count context) #t) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; make-engraver helper macro + +(defmacro-public make-engraver forms + "Helper macro for creating Scheme engravers. + +The usual form for an engraver is an association list (or alist) +mapping symbols to either anonymous functions or to another such +alist. + +@code{make-engraver} accepts forms where the first element is either +an argument list starting with the respective symbol, followed by the +function body (comparable to the way @code{define} is used for +defining functions), or a single symbol followed by subordinate forms +in the same manner. You can also just make an alist pair +literally (the @samp{car} is quoted automatically) as long as the +unevaluated @samp{cdr} is not a pair. This is useful if you already +have defined your engraver functions separately. + +Symbols mapping to a function would be @code{initialize}, +@code{start-translation-timestep}, @code{process-music}, +@code{process-acknowledged}, @code{stop-translation-timestep}, and +@code{finalize}. Symbols mapping to another alist specified in the +same manner are @code{listeners} with the subordinate symbols being +event classes, and @code{acknowledgers} and @code{end-acknowledgers} +with the subordinate symbols being interfaces." + (let loop ((forms forms)) + (if (cheap-list? forms) + `(list + ,@(map (lambda (form) + (if (pair? (car form)) + `(cons ',(caar form) (lambda ,(cdar form) ,@(cdr form))) + `(cons ',(car form) ,(loop (cdr form))))) + forms)) + forms)))