Deutsches Lilypond Forum (Archiv)
Allgemein => Fragen zu Funktionen => Thema gestartet von: mgd am Freitag, 1. Mai 2015, 19:07
-
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
-
Hallo mgd,
willkommen im Forum.
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:
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
-
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
-
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.
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
-
Tja, was kann ich sagen...vielen Dank. Problem gelöst.
-
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
-
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
-
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
-
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