2015-09-19 1:05 GMT+02:00 <[email protected]>:
> On 2015-09-19 00:13, David Kastrup wrote:
>>
>> Noeck <[email protected]> writes:
>>
>>> Having different *input* syntax for different people according to their
>>> taste is more complicated and it's doubtable that this is a good aim for
>>> LilyPond. Exchanging code gets more complicated and small snippets are
>>> not necessarily self-consistent. You always would have to specify the
>>> definitions. One example where it is possible is the input language of
>>> notes (e.g. \language english): In my German (\language deutsch) code <c
>>> e g b> is a C7 chord not a Cmaj7. For note names I like that.
>>> What I am trying to say: Adjustable input syntax also makes life more
>>> complicated in other circumstances.
>>
>> \language is usually a closed set, so editors like Frescobaldi can be
>> taught to convert from one to another. Conversions of freely
>> user-defined syntaxes is something entirely else, though.
>>
> My imagination of the procedure is, as I wrote before, not to change
> anything internal of LilyPond, but to use some kind of pre processor. This
> should, by means of a translation table, take my input and translate it into
> LP code. So when I write c:sus this will be changed to e.g. c:sus4 (or
> perhaps c:1.4.5) before it is dealt with by LP, and when I write c:5 it is
> translated into c:1.5.
>
> However because of the discussion which has followed my question, I begin to
> believe that the answer is no. Such a pre processor does not exist today.
> /Kaj
Such a preprocessor does not exist yet.
Ofc someone could write a script to transform your input _before_
LilyPond will see it, but why?
Instead I tackled 'construct-chord-elements' from chord-entry.scm to
do what you want.
Making equivalent:
\transpose c cis'
\chordmode {
\powerChords
c:sus
c:5
c:5-
c:5+
}
\transpose c cis'
\chordmode {
\powerChords
c:sus4
c^3
c:5-
c:5+
}
png attached
Limitation:
c:sus will not accept any additional argument after sus, c:7sus will
work, though.
I tried to make it available from inside a user-file, juggling around
module-this-and-that. It needs to be known in lily-imports.cc. But
without success.
Honestly, even if possible, it's beyond my skills.
Thus, you have to put it in chord-entry.scm. Best for now: rename the
current 'construct-chord-elements' to something else and paste the
attached code in there then.
Please note, it's not really tested.
Actually my OS is heavily broken, likely I'll need to do a complete
new set up, which I will not tackle before having done a thorough
back-up.
But up to now I have not found the time to buy a backup-disk ...
More, I'm not able to use git sufficiently atm, thus, if someone wants
to turn the code into a patch, please do.
HTH,
Harm
(define-public (construct-chord-elements root duration modifications)
"Build a chord on root using modifiers in @var{modifications}.
@code{NoteEvents} have duration @var{duration}.
Notes: Natural 11 is left from chord if not explicitly specified.
Entry point for the parser."
(let* (
;;;; changed:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(modifications
(if (and (member sus-modifier modifications)
(null? (cdr (member sus-modifier modifications))))
(append
modifications
(list (ly:make-pitch 0 3)))
modifications))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(flat-mods (flatten-list modifications))
(base-chord (stack-thirds (ly:make-pitch 0 4 0) the-canonical-chord))
(complete-chord '())
(bass #f)
(inversion #f)
(lead-mod #f)
(explicit-11 #f)
;;;; changed:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(explicit-5 #f)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(start-additions #t))
(define (interpret-inversion chord mods)
"Read /FOO part. Side effect: INVERSION is set."
(if (and (> (length mods) 1) (eq? (car mods) 'chord-slash))
(begin
(set! inversion (cadr mods))
(set! mods (cddr mods))))
(interpret-bass chord mods))
(define (interpret-bass chord mods)
"Read /+FOO part. Side effect: BASS is set."
(if (and (> (length mods) 1) (eq? (car mods) 'chord-bass))
(begin
(set! bass (cadr mods))
(set! mods (cddr mods))))
(if (pair? mods)
(ly:warning (_ "Spurious garbage following chord: ~A") mods))
chord)
(define (interpret-removals chord mods)
(define (inner-interpret chord mods)
(if (and (pair? mods) (ly:pitch? (car mods)))
(inner-interpret (remove-step (+ 1 (ly:pitch-steps (car mods))) chord)
(cdr mods))
(interpret-inversion chord mods)))
(if (and (pair? mods) (eq? (car mods) 'chord-caret))
(inner-interpret chord (cdr mods))
(interpret-inversion chord mods)))
(define (interpret-additions chord mods)
"Interpret additions. TODO: should restrict modifier use?"
;;;; TODO reflect explicit-5 here as well?
(cond ((null? mods) chord)
((ly:pitch? (car mods))
(if (= (pitch-step (car mods)) 11)
(set! explicit-11 #t))
(interpret-additions (cons (car mods) (remove-step (pitch-step (car mods)) chord))
(cdr mods)))
((procedure? (car mods))
(interpret-additions ((car mods) chord)
(cdr mods)))
(else (interpret-removals chord mods))))
(define (pitch-octavated-strictly-below p root)
"return P, but octavated, so it is below ROOT"
(ly:make-pitch (+ (ly:pitch-octave root)
(if (> (ly:pitch-notename root)
(ly:pitch-notename p))
0 -1))
(ly:pitch-notename p)
(ly:pitch-alteration p)))
(define (process-inversion complete-chord)
"Take out inversion from COMPLETE-CHORD, and put it at the bottom.
Return (INVERSION . REST-OF-CHORD).
Side effect: put original pitch in INVERSION.
If INVERSION is not in COMPLETE-CHORD, it will be set as a BASS, overriding
the bass specified.
"
(let* ((root (car complete-chord))
(inv? (lambda (y)
(and (= (ly:pitch-notename y)
(ly:pitch-notename inversion))
(= (ly:pitch-alteration y)
(ly:pitch-alteration inversion)))))
(rest-of-chord (remove inv? complete-chord))
(inversion-candidates (filter inv? complete-chord))
(down-inversion (pitch-octavated-strictly-below inversion root)))
(if (pair? inversion-candidates)
(set! inversion (car inversion-candidates))
(begin
(set! bass inversion)
(set! inversion #f)))
(if inversion
(cons down-inversion rest-of-chord)
rest-of-chord)))
;; root is always one octave too low.
;; something weird happens when this is removed,
;; every other chord is octavated. --hwn... hmmm.
(set! root (ly:pitch-transpose root (ly:make-pitch 1 0 0)))
;; skip the leading : , we need some of the stuff following it.
(if (pair? flat-mods)
(if (eq? (car flat-mods) 'chord-colon)
(set! flat-mods (cdr flat-mods))
(set! start-additions #f)))
;; remember modifier
(if (and (pair? flat-mods) (procedure? (car flat-mods)))
(begin
(set! lead-mod (car flat-mods))
(set! flat-mods (cdr flat-mods))))
;; extract first number if present, and build pitch list.
(if (and (pair? flat-mods)
(ly:pitch? (car flat-mods))
(not (eq? lead-mod sus-modifier)))
(begin
(if (= (pitch-step (car flat-mods)) 11)
(set! explicit-11 #t))
(display-scheme-music
(if (ly:pitch? (car flat-mods))
(ly:pitch-alteration (car flat-mods))
)
)
;;;; changed
;;;;;;;;;;;;;;;;;;;;;;;;;;
(if (and (= (pitch-step (car flat-mods)) 5)
(= 0 (ly:pitch-alteration (car flat-mods))))
(set! explicit-5 #t))
;;;;;;;;;;;;;;;;;;;;;;;;;;
(set! base-chord
(stack-thirds (car flat-mods) the-canonical-chord))
(set! flat-mods (cdr flat-mods))))
;; apply modifier
(if (procedure? lead-mod)
(set! base-chord (lead-mod base-chord)))
(set! complete-chord
(if start-additions
(interpret-additions base-chord flat-mods)
(interpret-removals base-chord flat-mods)))
(set! complete-chord (sort complete-chord ly:pitch<?))
;; If natural 11 + natural 3 is present, but not given explicitly,
;; we remove the 11.
(if (and (not explicit-11)
(get-step 11 complete-chord)
(get-step 3 complete-chord)
(= 0 (ly:pitch-alteration (get-step 11 complete-chord)))
(= 0 (ly:pitch-alteration (get-step 3 complete-chord))))
(set! complete-chord (remove-step 11 complete-chord)))
;;;; changed
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; If 5 is the one and only modifier, remove the 3
(if (and explicit-5 (null? flat-mods))
(set! complete-chord (remove-step 3 complete-chord)))
;;;;;;;;;;;;;;;;;;;;;;;;;
;; must do before processing inversion/bass, since they are
;; not relative to the root.
(set! complete-chord (map (lambda (x) (ly:pitch-transpose x root))
complete-chord))
(if inversion
(set! complete-chord (process-inversion complete-chord)))
(if bass
(set! bass (pitch-octavated-strictly-below bass root)))
(if #f
(begin
(write-me "\n*******\n" flat-mods)
(write-me "root: " root)
(write-me "base chord: " base-chord)
(write-me "complete chord: " complete-chord)
(write-me "inversion: " inversion)
(write-me "bass: " bass)))
(if inversion
(make-chord-elements (cdr complete-chord) bass duration (car complete-chord)
inversion)
(make-chord-elements complete-chord bass duration #f #f))))
_______________________________________________
lilypond-user mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/lilypond-user