Autor Thema: Lilypond Funktion, die einen Text ausgibt (GELÖST)  (Gelesen 4332 mal)

Manuela

  • Member
Lilypond Funktion, die einen Text ausgibt (GELÖST)
« am: Montag, 30. März 2015, 19:47 »
Ich weiß nicht genau, wie ich es formulieren soll. Ich bräuchte einen Text in Abhängigkeit von der Tonart, etwa so
s8^\markup {\abs-fontsize #11 {\bold  "A-Dur._" \italic  "La majeur._  A major."}}
            s8 * 11 \bar ".."
den ich dann in einen Score einfügen kann. Derzeit versuche ich, Scheme zu begreifen, damit sollte es möglich sein, aber derzeit tappe ich noch im Dunkeln.

Es sollte dann so aussehen:
\new Voice {
\key d \major
meinTextdur(d)
\key d \minor
meinTextmoll(d)
...
\new Voice {
            s8^\markup {\abs-fontsize #11 {\bold  "D-Dur._" \italic  "Ré majeur._  D major."}}
            s8 * 11 \bar ".."
            s8^\markup {\abs-fontsize #11 {\bold  "D-Moll._" \italic  "Ré mineur._  D minor."}}
            s8 * 5
            \noBreak s8 * 6
            \bar "|."
            s8^\markup {\abs-fontsize #11 {\bold  "A-Dur._" \italic  "La majeur._  A major."}}
            s8 * 11 \bar ".."
            s8^\markup {\abs-fontsize #11 {\bold  "A-Moll._" \italic  "La mineur._  A minor."}}
            s8 * 5
            \noBreak s8 * 6
            \bar "|."
            s8^\markup {\abs-fontsize #11 {\bold  "E-Dur._" \italic  "Mi majeur._  E major."}}
            s8 * 11 \bar ".."
            s8^\markup {\abs-fontsize #11 {\bold  "E-Moll._" \italic  "Mi mineur._  E minor."}}
            s8 * 5
            \noBreak s8 * 6
            \bar "|."

Ich hoffe, ich habe mich verständlich ausgedrückt,
danke
« Letzte Änderung: Mittwoch, 18. Mai 2016, 16:11 von Manuela »

harm6

  • Member
Re: Lilypond Funktion, die einen Text ausgibt
« Antwort #1 am: Montag, 30. März 2015, 20:17 »
Hallo Manuela,

Zitat
Ich hoffe, ich habe mich verständlich ausgedrückt

hm, so ganz verstanden habe ich es noch nicht.

Hilft
http://lsr.di.unimi.it/LSR/Item?u=1&id=856
?
Oder soll das ganze an beliebiger Stelle in den Notentext eingefügt werden.
Falls ja wie hoch soll der Grad an Automatisierung sein?

Vorstellbar ist eine Eingabe von
\meinText "d" "Dur"
mit der Ausgabe:
\markup {\abs-fontsize #11 {\bold  "D-Dur._" \italic  "Ré majeur._  D major."}}

Oder \meinText könnte auslesen in welcher Tonart die Stelle an der er eingefügt wird gerade ist.
Ist natürlich immer eine Frage des Aufwands. ;)

Gruß,
  Harm

Manuela

  • Member
Re: Lilypond Funktion, die einen Text ausgibt
« Antwort #2 am: Dienstag, 31. März 2015, 12:50 »
Danke Harm.

Das deckt möglicherweise schon meine Anforderungen ab. Vielleicht habe ich auch zu kompliziert gedacht und es lässt sich mit \chordmode lösen,
« Letzte Änderung: Mittwoch, 1. April 2015, 10:29 von Manuela »

harm6

  • Member
Re: Lilypond Funktion, die einen Text ausgibt
« Antwort #3 am: Mittwoch, 1. April 2015, 21:10 »
Hallo Manuela,

wie gesagt, alles eine Frage des Aufwands.

Hier eine vollautomatisierte, transponierbare Fassung.
Die Anwendung sollte sich aus dem Beispiel ergeben.
Manche Setzung ist natürlich Geschmackssache.

Da der Code etwas länger geworden ist, habe ich ihn auch angehängt, zusammen mit einem png.
Es zeigt aber nur den ersten Test, falls Du den kompletten einkommentierst, erhälst Du vier Seiten.

\version "2.19.17"

%% Nicer output while debugging:
%#(use-modules (ice-9 pretty-print))

%% LIMITATION: can't distuingish between minor- and aeolian-scale

scales = 
#(list major minor ionian locrian aeolian mixolydian lydian phrygian dorian)

scales-names =
#'(major minor ionian locrian aeolian mixolydian lydian phrygian dorian)

german-scale-names =
#'(Dur Moll Ionisch Lokrisch Äolisch Mixolydisch Lydisch Phrygisch Dorisch)

french-scale-names =
#'(majeur mineur ionien locrien éolien mixolydien lydien phrygien dorien)

#(define (define-grob-property symbol type? description)
  (if (not (equal? (object-property symbol 'backend-doc) #f))
      (ly:error (_ "symbol ~S redefined") symbol))

  (set-object-property! symbol 'backend-type? type?)
  (set-object-property! symbol 'backend-doc description)
  symbol)

#(for-each
  (lambda (x)
    (apply define-grob-property x))
    `((annotate-key
      ,boolean?
      "Print a markup annotation with the actual used key
in german, french, english")))

#(define (alteration->text-accidental-markup alteration)
  (make-smaller-markup
   (make-raise-markup
    (if (= alteration FLAT)
        0.3
        0.6)
    (make-musicglyph-markup
     (assoc-get alteration standard-alteration-glyph-name-alist "")))))

#(define (accidental->markup alteration)
  "Return accidental markup for ALTERATION."
  (if (= alteration 0)
      (make-line-markup (list empty-markup))
      (make-line-markup
        (list
          (alteration->text-accidental-markup alteration)
          (make-hspace-markup 0.1)))))

#(define-public (note-name->string pitch)
  "Return pitch markup for @var{pitch}."
  (make-concat-markup
   (list
    (make-simple-markup
      (vector-ref #("C" "D" "E" "F" "G" "A" "B") (ly:pitch-notename pitch)))
    (accidental->markup (ly:pitch-alteration pitch)))))
       
#(define (note-name->german-string pitch)
  "Return string for @var{pitch}, using German note names."
  (define (pitch-alteration-semitones pitch)
   (inexact->exact (round (* (ly:pitch-alteration pitch) 2))))

  (let* ((name (ly:pitch-notename pitch))
         (alt-semitones  (pitch-alteration-semitones pitch))
         (n-a (if (equal? (cons name alt-semitones) '(6 . -1))
                  (cons 7 alt-semitones)
                  (cons name alt-semitones))))
   (string-append
       (vector-ref #("C" "D" "E" "F" "G" "A" "H" "B") (car n-a))
     (let ((alteration (/ (cdr n-a) 2)))
       (cond
          ((and (= alteration FLAT) (= (car n-a) 7)) 
            "")
          ((and (= alteration FLAT) (or (= (car n-a) 5) (= (car n-a) 2) ))
            "s")
          ((= alteration FLAT) "es")
          ((and (= alteration DOUBLE-FLAT) (or (= (car n-a) 5)(= (car n-a) 2)))
            "ses")
          ((= alteration DOUBLE-FLAT)
            "eses")
          ((= alteration SHARP)
            "is")
          ((= alteration DOUBLE-SHARP)
            "isis")
          (else ""))))))
           
#(define (note-name->french-string pitch)
  "Return string for @var{pitch}, using French note names."

  (let* ((name (ly:pitch-notename pitch))
         (alteration (ly:pitch-alteration pitch)))
    (string-append
        (vector-ref #("Do" "Ré" "Mi" "Fa" "Sol" "La" "Si") name)
        (cond
           ((= alteration FLAT) "-bémol")
           ((= alteration DOUBLE-FLAT) "-double bémol")
           ((= alteration SHARP) "-diése")
           ((= alteration DOUBLE-SHARP) "-double diése")
           (else "")))))
                 
annotate-key-engraver =
#(lambda (context)
 (let ((tonic '())
       (scale-name '())
       (german-scale-name '())
       (french-scale-name '())
       (annotate-key-tweak? #f))
         
  `((listeners
      (rhythmic-event
        .
        ,(lambda (engraver event)
          (if (null? tonic)
              (ly:warning (_ "\tno \\key set, skipping"))
              (let* ((new-text-script-grob
                       (ly:engraver-make-grob engraver 'TextScript event))
                     (german-root-name (note-name->german-string (car tonic)))
                     (french-root-name (note-name->french-string (car tonic)))
                     (english-root-name (note-name->string (car tonic)))
                     (annotate-key?
                       (ly:grob-property new-text-script-grob 'annotate-key)))
                       
                (if (and annotate-key? (not (null? annotate-key?)))
                    (ly:grob-set-property! new-text-script-grob 'text                     
                      (format-key-info-markup
                        german-root-name german-scale-name
                        french-root-name french-scale-name
                        english-root-name scale-name))
                    (ly:grob-suicide! new-text-script-grob))))))
               
      (key-change-event
        .
        ,(lambda (engraver event)
          (let* ((context (ly:translator-context engraver))
                 (pitch-alist (ly:event-property event 'pitch-alist))
                 (tonic-pitch (ly:context-property context 'tonic))
                 (c0-pitch-list
                   (ly:transpose-key-alist pitch-alist
                        (ly:pitch-diff (ly:make-pitch 0 0 0) tonic-pitch)))
                 (pos-scales-from-right (length (member c0-pitch-list scales)))
                 (scale
                   (car (take-right scales-names pos-scales-from-right)))
                 (german-scale
                   (car (take-right german-scale-names pos-scales-from-right)))
                 (french-scale
                   (car (take-right french-scale-names pos-scales-from-right))))
            ;; clear the following variables before proceeding
            (set! tonic '())
            (set! scale-name '())
            (set! german-scale-name '())
            (set! french-scale-name '())
           
            ;; newly assign them
            (set! tonic (cons tonic-pitch tonic))
            (set! scale-name scale)
            (set! german-scale-name german-scale)
            (set! french-scale-name french-scale))))
       
      (text-script-event
        .
        ,(lambda (engraver event)
          (if (null? tonic)
              (ly:warning (_ "\tno \\key set, skipping"))
              (let* ((tweaks (ly:event-property event 'tweaks))
                     (new-text-script-grob
                       (ly:engraver-make-grob engraver 'TextScript event))
                     (direction
                       (ly:event-property event 'direction 1))
                     (german-root-name (note-name->german-string (car tonic)))
                     (french-root-name (note-name->french-string (car tonic)))
                     (english-root-name (note-name->string (car tonic))))

                (if (member '(annotate-key . #t) tweaks)
                    (set! annotate-key-tweak? #t))
             
                (if annotate-key-tweak?
                    (begin
                      (ly:grob-set-property! new-text-script-grob 'direction
                        direction)
                      (ly:grob-set-property! new-text-script-grob 'text                   
                        (format-key-info-markup
                          german-root-name german-scale-name
                          french-root-name french-scale-name
                          english-root-name scale-name)))
                    (ly:grob-suicide! new-text-script-grob))
                   
                (set! annotate-key-tweak? #f)))))))))
               
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#(define format-key-info-markup
   (lambda (root-1 scale-1 root-2 scale-2 root-3 scale-3)
     (markup
       #:bold
       (let ((german-strg
               (format #f "~a-~a_"
                 root-1
                 (symbol->string scale-1))))
         (if (eq? scale-1 'Moll)
             (string-downcase german-strg)
             german-strg))
       #:italic
       (format #f "~a ~a_"
         root-2
         (symbol->string scale-2))
       #:italic
       #:concat (
           root-3
           " "
           (symbol->string scale-3)))))
           

%% Short-cut for \once \override ...
annotateKey =
\once \override TextScript.annotate-key = ##t

%% Short-cut for \tweak ...
annotateKeyTweak =
#(define-event-function (parser location)()
#{
  -\tweak #'annotate-key ##t -""
#})

music =
  <<
    \new Voice
      \relative c' {
        \key d \major
        d1
        \key d \minor
        d
        \key e \minor
        e
        e
      }
  \new Voice
    \with {
      \override TextScript.direction = #UP
      \consists #annotate-key-engraver
    }
      {
        \key d \major
        \annotateKey
        s1
        \key d \minor
        s_\annotateKeyTweak
        \key e \minor
        s2
        \annotateKey
        s
        s1
      }
  >>


  \new Staff { \music \bar "||" \break \transpose c d \music }

%{
%% Testing all key-names up to DOUBLEFLAT and DOUBLESHARP ones
%% Will ofcourse return some warnings, because TRIPLEFLAT and TRIPLESHARP
%% are not implemented in LilyPond

multipleTransposes =
#(define-music-function (parser location m music)(ly:music? ly:music?)
   (music-clone m
    'elements
    (map (lambda (pitch)
  (ly:music-property #{ \transpose c $pitch $music #} 'element))
         (event-chord-pitches m))))

%% Examples

phrase =
\new Voice \with { \consists #annotate-key-engraver }
\relative c {
  \key c \major
  c'1\annotateKeyTweak
  \key a \minor
  \annotateKey a'
  \break
}

\new Staff
\multipleTransposes
  {
    c cis d dis e eis f fis g gis a ais b bis c
    c ces b bes a aes g ges f fes e ees d des c
    cisis disis eisis fisis gisis aisis bisis
    ceses deses eeses feses geses aeses beses
  }
  \phrase
%}


HTH,
  Harm

Manuela

  • Member
Re: Lilypond Funktion, die einen Text ausgibt
« Antwort #4 am: Donnerstag, 2. April 2015, 09:32 »
Ich weiß nicht, was ich sagen soll, welche Mühe du dir machst, fühle dich virtuell mit einem großen Blumenstrauß bedacht  :)

Manuela

  • Member
Re: Lilypond Funktion, die einen Text ausgibt
« Antwort #5 am: Freitag, 13. Mai 2016, 14:46 »
Hallo Harm,

jetzt habe ich diesen Code wieder ausgegraben, nochmals vielen Dank für deine Bemühungen.  :)

Ginge es, den ausgegebenen Text variabel zu gestalten? Die Übersetzung in die verschiedenen Sprachen würde ich nicht brauchen.

Aufruf etwa so:

\TextWithKey es " mein Text"
Ausgabe

mein Text Es-Dur
« Letzte Änderung: Freitag, 13. Mai 2016, 14:55 von Manuela »

harm6

  • Member
Re: Lilypond Funktion, die einen Text ausgibt
« Antwort #6 am: Samstag, 14. Mai 2016, 17:38 »
Zitat
Die Übersetzung in die verschiedenen Sprachen würde ich nicht brauchen.

Aus diesem Grund habe ich die procedure `format-key-info-markup' separat codiert und nicht in den engraver integriert. Kannst Du nach Deinen Wünschen ersetzen, sie muß aber denselben Namen bekommen und dieselben Argumente haben. Beispiel weiter unten.

Zitat
Ginge es, den ausgegebenen Text variabel zu gestalten?

Wahrscheinlich ist es am besten den zusätzlichen Text später hinzuzufügen. Zu diesem Zweck habe ich die einfachen Originalaufrufe, durch Funktionen ersetzt.

Also:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Formatting-procedures, each should be named `format-key-info-markup' and
%% needs six arguments: root-1 scale-1 root-2 scale-2 root-3 scale-3
%% (un-)comment what you (dis-)like
%%
%{
%% format key in certain way, outputting german/english/french
#(define format-key-info-markup
   (lambda (root-1 scale-1 root-2 scale-2 root-3 scale-3)
     (markup
       #:bold
       (let ((german-strg
               (format #f "~a-~a_"
                 root-1
                 (symbol->string scale-1))))
         (if (eq? scale-1 'Moll)
             (string-downcase german-strg)
             german-strg))
       #:italic
       (format #f "~a ~a_"
         root-2
         (symbol->string scale-2))
       #:italic
       #:concat (
           root-3
           " "
           (symbol->string scale-3)))))
%} 
%% format key in certain way, outputting german only
#(define format-key-info-markup
   (lambda (root-1 scale-1 root-2 scale-2 root-3 scale-3)
     (markup
       #:bold
       (let ((german-strg
               (format #f "~a-~a"
                 root-1
                 (symbol->string scale-1))))
         (if (eq? scale-1 'Moll)
             (string-downcase german-strg)
             german-strg)))))
           

%% music-function adding some text before
annotateKey =
#(define-music-function (mrkp)(markup?)
#{
  \once \override TextScript.before-line-breaking =
  #(lambda (grob)
    (ly:grob-set-property! grob 'text
      (markup #:line (mrkp (ly:grob-property grob 'text)))))
  \once \override TextScript.annotate-key = ##t
#})

%% tweak adding some text before
annotateKeyTweak =
#(define-event-function (my-mrkp)(markup?)
#{
  -\tweak #'before-line-breaking
    #(lambda (grob)
      (let ((mrkp (ly:grob-property grob 'text "")))
       (if (and (string? mrkp) (string-null? mrkp))
           #f
           (ly:grob-set-property! grob 'text
             (markup #:line (my-mrkp (ly:grob-property grob 'text)))))))
  -\tweak #'annotate-key ##t
  -""
#})

music =
  <<
    \new Voice
      \relative c' {
        \key d \major
        d1
        \key d \minor
        d
        \key e \minor
        e
        e
      }
  \new Voice
    \with {
      \override TextScript.direction = #UP
      \consists #annotate-key-engraver
    }
      {
      \textLengthOn
        \key d \major
        \annotateKey \markup \bold \italic "My-Text"
        s1
        \key d \minor
        s_\annotateKeyTweak \markup \with-color #blue "my-tweak-text"
        \key e \minor
        s2
        \annotateKey \markup \rounded-box "My-other-text"
        s
        s1
      }
  >>


\new Staff { \music \bar "||" \break \mark "transposed:" \transpose c d \music }

Alles davor bleibt wie gehabt.

Gruß,
  Harm

Manuela

  • Member
Re: Lilypond Funktion, die einen Text ausgibt
« Antwort #7 am: Sonntag, 15. Mai 2016, 10:09 »
Danke Harm.

Sry dass ich dich so belästigen muss  :) Aber du kannst einfach viel schneller und besser Scheme programmieren als ich. Falls du mal VB oder SQL-Code brauchst, wende dich vertrauensvoll an mich  ;)

Ich hätte mir vorgestellt, dass der Pitch einfach als Parameter mitgegeben wird und dann mittransponiert wird. Geht wahrscheinlich nicht so einfach. Ich werde mal schauen, dass ich mit dem vorliegenden Code zurecht komme, inzwischen spreche ich schon ein bisschen Scheme  ;). Wenngleich die Vergessenskurve wesentlich steiler verläuft als die Lernkurve.

Falls ich noch Anliegen habe, werde ich dich nochmals auf diesen Thread zurückkommen. Wenn ich darf  :D

harm6

  • Member
Re: Lilypond Funktion, die einen Text ausgibt
« Antwort #8 am: Sonntag, 15. Mai 2016, 19:48 »
Zitat von: Manuela
Ich hätte mir vorgestellt, dass der Pitch einfach als Parameter mitgegeben wird und dann mittransponiert wird. Geht wahrscheinlich nicht so einfach.

Du kannst einen pitch nicht so einfach in ein markup setzen.
Man kann natürlich einen kompletten score mit Note(n) in ein markup setzen, evtl alles ausschließen bzw verbergen was stört.
Aber das wird nicht mittranspomiert werden:

\transpose c cis {
  a''-\markup \score { { c'1 } }
}

Stattdessen brauchst Du den Namen des Pitches. Der ist allerdings ein symbol.

Am einfachsten:
#(use-modules (scm display-lily))

{
  a''1-\markup #(symbol->string (note-name->lily-string #{ c' #}))
}

Aber auch jetzt ist der Inhalt des markup nicht transponierbar.

Man könnte natürlich Funktionalität schaffen, welche aus dem markup, via parent-tree auf den tonic-pitch schaut und daraus eine mögliche Transponierung ableitet.

Dann bist Du fast bei dem Code den ich oben gepostet habe, nur das dieser nicht zurückschaut, sondern das gewünschte markup von vornherein richtig erschafft.

Ich sehe da keinen Vorteil (obwohl ich es nicht ausprobiert habe), sondern eher Nachteile.

Zitat
Falls ich noch Anliegen habe, werde ich dich nochmals auf diesen Thread zurückkommen. Wenn ich darf

Aber natürlich :D

Gruß,
  Harm

Manuela

  • Member
Re: Lilypond Funktion, die einen Text ausgibt
« Antwort #9 am: Montag, 16. Mai 2016, 12:45 »
Es ist soweit, ich mache meine Drohung wahr  ;)

Mein Ziel ist, alles in einen transponierbaren Musikausdruck zu verpacken. Klappt soweit ganz gut, nur sind nach dem \pageBreak die Notenzeilen verschwunden  :(
Sicher nur eine Kleinigkeit, aber ich sehe den Wald nicht mehr...

Update: ich bin inzwischen selbst draufgekommen, ich muss stoppStaff und startStaff eingeben, dann klappt es.

So geht's:

\version "2.19.37"

scales =
#(list major minor ionian locrian aeolian mixolydian lydian phrygian dorian)

scales-names =
#'(major minor ionian locrian aeolian mixolydian lydian phrygian dorian)

german-scale-names =
#'(Dur Moll Ionisch Lokrisch Äolisch Mixolydisch Lydisch Phrygisch Dorisch)

french-scale-names =
#'(majeur mineur ionien locrien éolien mixolydien lydien phrygien dorien)

#(define (define-grob-property symbol type? description)
   (if (not (equal? (object-property symbol 'backend-doc) #f))
       (ly:error (_ "symbol ~S redefined") symbol))

   (set-object-property! symbol 'backend-type? type?)
   (set-object-property! symbol 'backend-doc description)
   symbol)

#(for-each
  (lambda (x)
    (apply define-grob-property x))
  `((annotate-key
     ,boolean?
     "Print a markup annotation with the actual used key
in german, french, english")))

#(define (alteration->text-accidental-markup alteration)
   (make-smaller-markup
    (make-raise-markup
     (if (= alteration FLAT)
         0.3
         0.6)
     (make-musicglyph-markup
      (assoc-get alteration standard-alteration-glyph-name-alist "")))))

#(define (accidental->markup alteration)
   "Return accidental markup for ALTERATION."
   (if (= alteration 0)
       (make-line-markup (list empty-markup))
       (make-line-markup
        (list
         (alteration->text-accidental-markup alteration)
         (make-hspace-markup 0.1)))))

#(define-public (note-name->string pitch)
   "Return pitch markup for @var{pitch}."
   (make-concat-markup
    (list
     (make-simple-markup
      (vector-ref #("C" "D" "E" "F" "G" "A" "B") (ly:pitch-notename pitch)))
     (accidental->markup (ly:pitch-alteration pitch)))))

#(define (note-name->german-string pitch)
   "Return string for @var{pitch}, using German note names."
   (define (pitch-alteration-semitones pitch)
     (inexact->exact (round (* (ly:pitch-alteration pitch) 2))))

   (let* ((name (ly:pitch-notename pitch))
          (alt-semitones  (pitch-alteration-semitones pitch))
          (n-a (if (equal? (cons name alt-semitones) '(6 . -1))
                   (cons 7 alt-semitones)
                   (cons name alt-semitones))))
     (string-append
      (vector-ref #("C" "D" "E" "F" "G" "A" "H" "B") (car n-a))
      (let ((alteration (/ (cdr n-a) 2)))
        (cond
         ((and (= alteration FLAT) (= (car n-a) 7))
          "")
         ((and (= alteration FLAT) (or (= (car n-a) 5) (= (car n-a) 2) ))
          "s")
         ((= alteration FLAT) "es")
         ((and (= alteration DOUBLE-FLAT) (or (= (car n-a) 5)(= (car n-a) 2)))
          "ses")
         ((= alteration DOUBLE-FLAT)
          "eses")
         ((= alteration SHARP)
          "is")
         ((= alteration DOUBLE-SHARP)
          "isis")
         (else ""))))))

#(define (note-name->french-string pitch)
   "Return string for @var{pitch}, using French note names."

   (let* ((name (ly:pitch-notename pitch))
          (alteration (ly:pitch-alteration pitch)))
     (string-append
      (vector-ref #("Do" "Ré" "Mi" "Fa" "Sol" "La" "Si") name)
      (cond
       ((= alteration FLAT) "-bémol")
       ((= alteration DOUBLE-FLAT) "-double bémol")
       ((= alteration SHARP) "-diése")
       ((= alteration DOUBLE-SHARP) "-double diése")
       (else "")))))

annotate-key-engraver =
#(lambda (context)
   (let ((tonic '())
         (scale-name '())
         (german-scale-name '())
         (french-scale-name '())
         (annotate-key-tweak? #f))

     `((listeners
        (rhythmic-event
         .
         ,(lambda (engraver event)
            (if (null? tonic)
                (ly:warning (_ "\tno \\key set, skipping"))
                (let* ((new-text-script-grob
                        (ly:engraver-make-grob engraver 'TextScript event))
                       (german-root-name (note-name->german-string (car tonic)))
                       (french-root-name (note-name->french-string (car tonic)))
                       (english-root-name (note-name->string (car tonic)))
                       (annotate-key?
                        (ly:grob-property new-text-script-grob 'annotate-key)))

                  (if (and annotate-key? (not (null? annotate-key?)))
                      (ly:grob-set-property! new-text-script-grob 'text
                        (format-key-info-markup
                         german-root-name german-scale-name
                         french-root-name french-scale-name
                         english-root-name scale-name))
                      (ly:grob-suicide! new-text-script-grob))))))

        (key-change-event
         .
         ,(lambda (engraver event)
            (let* ((context (ly:translator-context engraver))
                   (pitch-alist (ly:event-property event 'pitch-alist))
                   (tonic-pitch (ly:context-property context 'tonic))
                   (c0-pitch-list
                    (ly:transpose-key-alist pitch-alist
                      (ly:pitch-diff (ly:make-pitch 0 0 0) tonic-pitch)))
                   (pos-scales-from-right (length (member c0-pitch-list scales)))
                   (scale
                    (car (take-right scales-names pos-scales-from-right)))
                   (german-scale
                    (car (take-right german-scale-names pos-scales-from-right)))
                   (french-scale
                    (car (take-right french-scale-names pos-scales-from-right))))
              ;; clear the following variables before proceeding
              (set! tonic '())
              (set! scale-name '())
              (set! german-scale-name '())
              (set! french-scale-name '())

              ;; newly assign them
              (set! tonic (cons tonic-pitch tonic))
              (set! scale-name scale)
              (set! german-scale-name german-scale)
              (set! french-scale-name french-scale))))

        (text-script-event
         .
         ,(lambda (engraver event)
            (if (null? tonic)
                (ly:warning (_ "\tno \\key set, skipping"))
                (let* ((tweaks (ly:event-property event 'tweaks))
                       (new-text-script-grob
                        (ly:engraver-make-grob engraver 'TextScript event))
                       (direction
                        (ly:event-property event 'direction 1))
                       (german-root-name (note-name->german-string (car tonic)))
                       (french-root-name (note-name->french-string (car tonic)))
                       (english-root-name (note-name->string (car tonic))))

                  (if (member '(annotate-key . #t) tweaks)
                      (set! annotate-key-tweak? #t))

                  (if annotate-key-tweak?
                      (begin
                       (ly:grob-set-property! new-text-script-grob 'direction
                         direction)
                       (ly:grob-set-property! new-text-script-grob 'text
                         (format-key-info-markup
                          german-root-name german-scale-name
                          french-root-name french-scale-name
                          english-root-name scale-name)))
                      (ly:grob-suicide! new-text-script-grob))

                  (set! annotate-key-tweak? #f)))))))))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% Short-cut for \once \override ...

#(define format-key-info-markup
   (lambda (root-1 scale-1 root-2 scale-2 root-3 scale-3)
     (markup
      ;#:bold
      (let ((german-strg
             (format #f "~a"
               root-1
               (symbol->string scale-1))))
        (if (eq? scale-1 'Moll)
            german-strg
            german-strg)))))

%% music-function adding some text before
annotateKey =
#(define-music-function (mrkp)(markup?)
   #{
     \once \override TextScript.before-line-breaking =
     #(lambda (grob)
        (ly:grob-set-property! grob 'text
          (markup #:line (mrkp (ly:grob-property grob 'text)))))
     \once \override TextScript.annotate-key = ##t
   #})

MeinHeader =
#(define-music-function (Pitch mkup mus)
   (ly:pitch? markup? ly:music?)
   #{ <<
     \new Voice \with {
       \override TextScript.direction = #UP
       \override TextScript.padding = #0
       \consists #annotate-key-engraver
     }
     {
       \stopStaff
       \override  Staff.StaffSymbol.line-count = #0
       \startStaff
       \textLengthOn
       \key $Pitch \major
       \annotateKey \markup "annotateKey " s1 s1-$mkup
     }
      >>
      <<
        \new Voice {
          \break
         \stopStaff
          \revert Staff.StaffSymbol.line-count
          \startStaff
           $mus
        }
      >>
   #}
   )

Musik =
<<
  \new Voice
  {
    <<
      \new Voice
      {
        \key c \major
        c''1 d'' e''  \bar "|." \break
      }
      \new ChordNames
      {
        c1 d e \bar "|." \break
      }
    >>
  }
>>

\score {
  {
    \MeinHeader c "test"  \Musik
    \pageBreak
    \MeinHeader d "test"  \Musik
  }
}
« Letzte Änderung: Montag, 16. Mai 2016, 13:09 von Manuela »

Manuela

  • Member
Re: Lilypond Funktion, die einen Text ausgibt
« Antwort #10 am: Montag, 16. Mai 2016, 13:31 »
Zu früh gefreut!!! Jetzt sind die Notenschlüssel und Vorzeichen auf der 2. Seite verschwunden  :( :( :(

Die Definition des annotateKey-Engravers lasse der Übersichtlichkeit halber weg

Update: Voice durch \Staff ersetzt, dann klappt es!

MeinHeader =
#(define-music-function (Pitch mkup mus)
   (ly:pitch? markup? ly:music?)
   #{ <<
     \new Voice \with {
       \override TextScript.direction = #UP
       \override TextScript.padding = #0
       \consists #annotate-key-engraver
     }
     {
       \omit Staff.KeySignature
       \omit Staff.Clef
       \omit Staff.TimeSignature
       \omit Staff.BarNumber
       \omit Staff.BarLine
       \stopStaff
       \override  Staff.StaffSymbol.line-count = #0
       \startStaff
       \textLengthOn
       \key $Pitch \major
       \annotateKey \markup "annotateKey " s1 s1-$mkup s1 s1
       %\revert Staff.StaffSymbol.line-count bewirkt nix
     }
      >>
      <<
        \new Voice \with { %% hier Staff, dann klappt's!
          \consists "Clef_engraver"  %% nutzt nix!!!
          \consists "Key_engraver"   %% nutzt nix!!!
         } {
          \break
          \stopStaff
          \revert Staff.StaffSymbol.line-count
          \startStaff
          $mus
        }
      >>
   #}
   )

Musik =
<<
  \new Voice
  {
    <<
      \new Voice
      {
        \key c \major
        c''1  \bar "|." \break
      }
    >>
  }
>>

\score {
  {
    \MeinHeader c "test"  \Musik
    \pageBreak
    \MeinHeader d "test"  \Musik
  }
}
« Letzte Änderung: Montag, 16. Mai 2016, 13:40 von Manuela »