Autor Thema: TupletBracket in allgemeinem Text (\markup) und nicht in den Noten (GELÖST)  (Gelesen 2313 mal)

mgd

  • Member
Hallo Liste !

Ich schreibe mit lilypond Gesänge für Psalmen der Anglikanischen Kirche auf. Das klappt weitestgehend sehr gut. Aktuell habe ich ein Problem, dass ich gern lösen würde.

In den Psalmtexten, die unterhalb der Akkordlinie frei mit \markup { } notiert wird sind bisweilen Abschnitte mit Triolenklammern versehen, die damit eine Art Vortragsbezeichnung für diesen Abschnitt darstellen.

Die Verwendung von \tuplet ist jedoch offenbar nicht erlaubt.

Gibt es eine Möglichkeit, freien Text mit einer Triolenklammer zu versehen und wie ?

Vielen Dank,
Michael
« Letzte Änderung: Sonntag, 3. Mai 2015, 07:48 von mgd »

harm6

  • Member
Re: TupletBracket in allgemeinem Text (\markup) und nicht in den Noten
« Antwort #1 am: Samstag, 2. Mai 2015, 00:12 »
Hallo mgd,

willkommen im Forum.

Zitat
Die Verwendung von \tuplet ist jedoch offenbar nicht erlaubt.

Nicht ganz richtig
\new Lyrics \lyricmode { \tuplet 3/2 { foo4 bar buzz } }ist absolut korrekt.
Es wird nur keine TupletBracket geschrieben. Wenn man den entsprechenden Engraver reinhaut, so beklagt sich LilyPond:
Zitat
Warnung: omitting tuplet bracket with neither left nor right bound

Ob man die bounds manuell setzen kann, hab ich jetzt aber nicht geprüft...

Aber man kann ein markup-command bauen:
#(define-markup-command (single-hbracket layout props arg)
  (markup?)
  #:properties (
    (padding 0)
    (direction DOWN)
    (right-left-lengthen '(0 . 0))
    (potrusion 0.5)
    )
  #:category graphic
  (let* ((th 0.1) ;; todo: take from GROB.
         (m (interpret-markup layout props arg)))
         
   (define
     (add-bracket-to-stencil
       stil
       axis
       thick
       protrusion
       direction
       right-left-lengthen
       padding)
    "Add a bracket to @var{stil}, producing a new stencil."
    (let* ((ext
             (coord-translate
               (ly:stencil-extent stil axis)
               right-left-lengthen))
           (other-axis (lambda (a) (remainder (+ a 1) 2)))
           (bracket (ly:bracket axis ext thick (* -1 direction  protrusion))))
      (ly:stencil-combine-at-edge
        stil
        (other-axis axis)
        direction
        bracket
        padding)))
           
    (add-bracket-to-stencil
      m
      X
      th
      (+ potrusion (* 2.5 th))
      direction
      right-left-lengthen
      (+ padding th))))

\markup {
  one two three
  \single-hbracket \line { one two three }
  \override #'(direction . 1)
  \single-hbracket oneoneone
 
  \override #'(padding . 3)
  \single-hbracket twotwotwo
 
  \override #'(right-left-lengthen . (1 . -1))
  \override #'(potrusion . 1.2)
  \single-hbracket threethreethree
}

Basiert auf hbracket, gibt aber nur eine Klammer aus. Diverse Einstellmöglichkeiten sind vorhanden (siehe Beispiel)



HTH,
  Harm

mgd

  • Member
Re: TupletBracket in allgemeinem Text (\markup) und nicht in den Noten
« Antwort #2 am: Samstag, 2. Mai 2015, 10:20 »
Hallo Harm,

vielen Dank für dieses tolle Beispiel, wie extrem erweiterbar lilypond ist, wenn man "nur" ein wenig TeX (?) kann  :)

Deine single-hbracket leistet - bis auf die fehlende Beschriftung (fast immer eine "3") - genau, was ich zu erreichen versuche.

Mal abgesehen von dem notwendigen Erlernen diverser Details der verwendeten Sprache:
Wenn ich die single-hbracket um eine Beschriftung erweitern wollte, würde ich mir den Sourcecode von tuplet anschauen und versuchen, dort Codefragmente zu kannibalisieren ?

Oder wäre es letztlich zielführender zu versuchen, irgendwie die bounds "extern" und ohne Notenkontext zu setzen ?

Die Variante mit der single-hbracket gefällt mir so erst einmal deutlich besser, denn sie lässt sich einfach so in einem markup-Block verwenden. Legte ich einen Lyrics-Block an, müsste ich bzgl. der sonstigen Formatierungen vermutlich ganz erheblich herumtricksen.

Auf jeden Fall nochmals vielen Dank. Allein an diesem Schnipsel habe ich ein paar grundlegende Dinge gelernt :)

Michael

harm6

  • Member
Re: TupletBracket in allgemeinem Text (\markup) und nicht in den Noten
« Antwort #3 am: Samstag, 2. Mai 2015, 22:38 »
Zitat
vielen Dank für dieses tolle Beispiel, wie extrem erweiterbar lilypond ist, wenn man "nur" ein wenig TeX (?) kann
Die LilyPond-Erweiterungssprache ist guile, ein Dialekt von scheme, welches seinerseits ein Dialekt von lisp ist.
Meistens wird verkürzend nur von scheme gesprochen.

Zitat
Wenn ich die single-hbracket um eine Beschriftung erweitern wollte, würde ich mir den Sourcecode von tuplet anschauen und versuchen, dort Codefragmente zu kannibalisieren ?
Nicht ganz.
Das markup-command single-hbracket hat mit dem grob TupletBracket, außer das beide eine gedruckte Klammer erzeugen, nichts gemein.
Außerdem sind wesentliche Teile für TupletBracket in .cc-files und damit für den user nicht erreichbar.

Stattdessen kann man aber das markup-command ausbauen:

\version "2.19.18"

#(define-markup-command (single-hbracket layout props arg-for-bracket arg)
  (markup? markup?)
  #:properties ((padding 0)
                (direction DOWN)
                (right-left-lengthen '(0 . 0))
                (potrusion 0.5))
  #:category graphic
  (let* ((th 0.1) ;; todo: take from GROB.
         (m (interpret-markup layout props arg))
         (stil-add (interpret-markup layout props arg-for-bracket)))
         
   (define
     (add-bracket-to-stencil
       stil add-to-bracket-stil
       axis thick
       protrusion direction
       right-left-lengthen padding)
    "Add a bracket to @var{stil}, producing a new stencil."
    (let* ((ext
             (coord-translate
               (ly:stencil-extent stil axis)
               right-left-lengthen))
           (other-axis (lambda (a) (remainder (+ a 1) 2)))
           (bracket (ly:bracket axis ext thick (* -1 direction  protrusion)))
           (bracket-length
             (interval-length (ly:stencil-extent bracket X)))
           (bracket
             (ly:stencil-add
               bracket
               (stencil-whiteout
                 (ly:stencil-translate-axis
                   (centered-stencil add-to-bracket-stil)
                   (+ (/ bracket-length 2) (car right-left-lengthen))
                   X)))))
      (ly:stencil-combine-at-edge
        stil
        (other-axis axis)
        direction
        bracket
        padding)))
           
    (add-bracket-to-stencil
      m stil-add
      X th
      (+ potrusion (* 2.5 th)) direction
      right-left-lengthen (+ padding th))))
     
%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLES
%%%%%%%%%%%%%%%%%%%%%%%%%
     

\markup {
  one two three
 
  \single-hbracket " 3 " \line { one two three }
 
 
  \override #'(direction . 1)
  \single-hbracket \tiny \italic " 3 " oneoneone
 
 
  \override #'(padding . 3)
  \single-hbracket
    \concat {
        " 3 "
        \raise #0.7
          \override #'(style . mensural) \note #"breve" #1
        \hspace #0.7
    }
    twotwotwo
 
   
  \override #'(right-left-lengthen . (1 . -1))
  \override #'(potrusion . 1.2)
  \single-hbracket " 3:2 " threethreethree
}

png im Amhang

HTH,
  Harm


mgd

  • Member
Re: TupletBracket in allgemeinem Text (\markup) und nicht in den Noten
« Antwort #4 am: Sonntag, 3. Mai 2015, 07:47 »
Tja, was kann ich sagen...vielen Dank. Problem gelöst.

erich

  • Member
Ich liebe Latex und möchte es beim mathematischen Formelsatz nicht missen, und ich liebe LilyPond, wenn es um das reine Notenschreiben geht; wenn es aber um die Feinheiten beim MarkUp geht,
lasse ich die Noten lieber im SVG-Format ausgeben und bearbeite sie dann mit Inkscape.

Um bei Harms Beispiel zu bleiben, hier eine kleine Weiterverarbeitung

mgd

  • Member
Das ist natürlich auch eine Möglichkeit. Ich persönlich liebe es allerdings, wenn die Dinge skriptgesteuert möglichst automatisch und vor allem ohne zusätzliches manuelles Eingreifen ein akzeptables Ergebnis liefern.

Ich habe jetzt ein wenig mit Harm's Funktion Erfahrung sammeln können und stelle fest, in 99.x% aller Fälle brauche ich für die Beschriftung der Klammer das folgende markup:
\fontsize #-3 \italic " 3 "
Also dachte ich, ich tausche die Reihenfolge der Parameter in der Funktion single-hbracket und mache arg-for-bracket optional mit obigem default Wert.

Aber offensichtlich bin ich mit den Feinheiten der gemischten Lilypond und Scheme Syntax noch nicht hinreichend vertraut, um das syntaktisch korrekt aufzuschreiben.

Hier nochmal die originale Funktion:
\version "2.18.2
#(define-markup-command (single-hbracket layout props arg-for-bracket arg)
  (markup? markup?)
  #:properties ((padding 0)
                (direction UP)
                (right-left-lengthen '(-0.3 . 0.3))
                (potrusion 0.3))
  #:category graphic
  (let* ((th 0.1) ;; todo: take from GROB.
         (m (interpret-markup layout props arg))
         (stil-add (interpret-markup layout props arg-for-bracket)))

   (define
     (add-bracket-to-stencil
       stil add-to-bracket-stil
       axis thick
       protrusion direction
       right-left-lengthen padding)
    "Add a bracket to @var{stil}, producing a new stencil."
    (let* ((ext
             (coord-translate
               (ly:stencil-extent stil axis)
               right-left-lengthen))
           (other-axis (lambda (a) (remainder (+ a 1) 2)))
           (bracket (ly:bracket axis ext thick (* -1 direction  protrusion)))
           (bracket-length
             (interval-length (ly:stencil-extent bracket X)))
           (bracket
             (ly:stencil-add
               bracket
               (stencil-whiteout
                 (ly:stencil-translate-axis
                   (centered-stencil add-to-bracket-stil)
                   (+ (/ bracket-length 2) (car right-left-lengthen))
                   X)))))
      (ly:stencil-combine-at-edge
        stil
        (other-axis axis)
        direction
        bracket
        padding)))

    (add-bracket-to-stencil
      m stil-add
      X th
      (+ potrusion (* 2.5 th)) direction
      right-left-lengthen (+ padding th))))

\markup {
  one two three

  \single-hbracket \line { one two three }
  \single-hbracket \line { one two three } " 2 "
}

Bei meinen Experimenten hatte ich lediglich den Kopf variiert, daher folgen hier auch nur die betroffenen vorderen Zeilen:
#(define-markup-command (single-hbracket layout props arg arg-for-bracket)
  (markup? markup? #"\\fontsize #-3 \\italic \" 3 \"")
#(define-markup-command (single-hbracket layout props arg arg-for-bracket)
  (markup? markup? "\\fontsize #-3 \\italic \" 3 \"")
#(define-markup-command (single-hbracket layout props arg)
  (markup?)
  #:properties ((padding 0)
                (direction UP)
                (right-left-lengthen '(-0.3 . 0.3))
                (potrusion 0.3)
                (arg-for-bracket "\\fontsize #-3 \\italic \" 3 \""))

Keine der Versionen funktioniert, wenngleich die letzte wenigstens syntaktisch korrekt ist. Semantisch allerdings nicht :)

Wie schreibe ich das korrekt auf ?

Liebe Grüße,
Michael
« Letzte Änderung: Freitag, 29. Mai 2015, 16:09 von mgd »

harm6

  • Member
Hallo Michael,

das macro 'define-markup-command' akzeptiert keine optionalen Argumente, afaik.

Du kannst aber vorgehen wie folgt. Allerdings beschleicht mich ein Zweifel, ob es nicht irgenwann zu viel wird immer neue, bislang unbekannte properties einzuführen. Möglicherweise protestiert LilyPond irgenwann.

\version "2.19.18"

#(define-markup-command (single-hbracket layout props arg)
  (markup?)
  #:properties ((padding 0)
                (direction UP)
                (right-left-lengthen '(-0.3 . 0.3))
                (potrusion 0.3)
                (arg-for-bracket (markup #:fontsize -3 #:italic " 3 ")))

               
               
  #:category graphic
  (let* ((th 0.1) ;; todo: take from GROB.
         (m (interpret-markup layout props arg))
         (stil-add (interpret-markup layout props arg-for-bracket)))
         
   (define
     (add-bracket-to-stencil
       stil add-to-bracket-stil
       axis thick
       protrusion direction
       right-left-lengthen padding)
    "Add a bracket to @var{stil}, producing a new stencil."
    (let* ((ext
             (coord-translate
               (ly:stencil-extent stil axis)
               right-left-lengthen))
           (other-axis (lambda (a) (remainder (+ a 1) 2)))
           (bracket (ly:bracket axis ext thick (* -1 direction  protrusion)))
           (bracket-length
             (interval-length (ly:stencil-extent bracket X)))
           (bracket
             (ly:stencil-add
               bracket
               (stencil-whiteout
                 (ly:stencil-translate-axis
                   (centered-stencil add-to-bracket-stil)
                   (+ (/ bracket-length 2) (car right-left-lengthen))
                   X)))))
      (ly:stencil-combine-at-edge
        stil
        (other-axis axis)
        direction
        bracket
        padding)))
           
    (add-bracket-to-stencil
      m stil-add
      X th
      (+ potrusion (* 2.5 th)) direction
      right-left-lengthen (+ padding th))))
     
%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLES
%%%%%%%%%%%%%%%%%%%%%%%%%
     
\markup {
  \single-hbracket \line { one two three }
 
  \override #`(arg-for-bracket . ,(markup #:fontsize -3 #:italic " foo "))
  \single-hbracket threethreethree
}

HTH,
  Harm

mgd

  • Member
Vielen Dank Harm,

das ist genau das, was ich suchte. Zumindest bei der Anwendung, die ich aktuell für dieses Konstrukt habe, werde ich das arg-for-bracket so gut wie nie überschreiben. Und dann spart diese Version doch ein wenig Code in der Datei und macht das Ganze insbesondere lesbarer :)

Vielen Dank,
Michael