Autor Thema: \markup-Text ins Notensystem verschieben  (Gelesen 2045 mal)

Radler

  • Member
\markup-Text ins Notensystem verschieben
« am: Sonntag, 30. Oktober 2016, 18:50 »
Hallo liebe Lilypondianer,

in Notation.PDF habe ich es nicht gefunden, in Learning, Usage und Internals auch nicht.
Aber vielleicht weiß es einer von Euch?

Für die unaufmerksamen Musiker möchte ich an neuralgischen Stellen anzeigen, dass sich die (vorher seeehr lange gehaltene Note) ändert, am liebsten mit einem Richtungspfeil: ↘ und ↙ bieten sich an.
Leider gelingt es mir nur, diesen Pfeil über oder unter das Notensystem (mit den fünf waagerechten Strichen) zu setzen. Ich möchte ihn aber gern mitten rein haben.

Kann jemand helfen?

Vielen Dank und viele Grüße
von Radler

PS:
Das ist ein Sonderfall von einem allgemeinen Problem, das ich habe:
  • Ich habe ein LayoutObject, weiß aber nicht, wie es heißt (z.B. das, was ich hinter \markup in geschweifte Klammern und Hochkommata schreibe.
  • Wenn ich es (irgenwoher doch) weiß, weiß ich nicht, welche layout-property ich dafür setzen kann
  • Wenn ich es (irgenwoher doch) weiß, weiß ich nicht, welche values ich dafür setzen kann (Wertevorrat; aber den könnte ich mir vielleicht irgendwie heraus-experimentieren)
Als layout-property nehme ich Y-offset an. Aber das hilft mir nicht weiter.

Vermutlich gibt es irgendwo in der Dokumentation eine übersichtliche und unmittelbar verständliche Liste. Aber ich habe sie nicht gefunden.
Kann jemand helfen?

harm6

  • Member
Re: \markup-Text ins Notensystem verschieben
« Antwort #1 am: Sonntag, 30. Oktober 2016, 21:04 »
Hallo Radler,

Deine post-scriptum-Fragen sind mir nicht alle klar.

Aber zunächst zum Namen von layout-objekten, bzw grobs.
Benutze \displayMusic
{
\displayMusic
s^"xy"
}
führt im Terminal zu:
Zitat
(make-music
  'SkipEvent
  'articulations
  (list (make-music
          'TextScriptEvent
          'direction
          1
          'text
          "xy"))
  'duration
  (ly:make-duration 1))
Das musik-event heißt also TextScriptEvent. Nun schau in die IR.
http://lilypond.org/doc/v2.19/Documentation/internals-big-page#textscriptevent

Nun finde raus welcher engraver hier zuständig ist (Text_engraver) und folge dem link:
http://lilypond.org/doc/v2.19/Documentation/internals-big-page#text_005fengraver
Dort kannst Du dann unter anderem lesen:
"This engraver creates the following layout object(s):
TextScript."
Folge dem link:
http://lilypond.org/doc/v2.19/Documentation/internals-big-page#textscript
Dort siehst Du dann welche grob-properties mit welchen Werten gesetzt sind und was sie machen. (Das sind aber lange nicht alle die theoretisch möglich sind.)
Aber am Ende siehst Du auch:
"This object supports the following interface(s): font-interface, grob-interface, instrument-specific-markup-interface, item-interface, outside-staff-interface, self-alignment-interface, side-position-interface, text-interface and text-script-interface. "

Z.B. das font-interface ermöglicht Dir:
\override TextScript.font-name = "Purisa"
usw.

Alle Möglichkeiten bei allen grobs immer wieder erneut anzugeben würde den Rahmen dieses file sprengen. Besser Du lernst, wie Du die nötigen Informationen nachschlägst.

Zum eigentlichen Problem.
TextScript ist ein outside-staff-object, siehe auch:
http://lilypond.org/doc/v2.19/Documentation/notation-big-page#vertical-collision-avoidance

Um das "rückgängig" zu machen setze staff-padding und outside-staff-priority als '(). Dann fällt der Text auf die Mittellinie und kann von dort mittels Y-offset wieder verschoben werden.

\score
{
  \new Staff
  {
    <<
      \new Voice
      {
        c''2 g'
      }
      \new Voice
      { % Dieser Pfeil sollte INNERHALB des Notensystems
        % etwa auf der Höhe von c''2 beginnen und schräg nach unten Richtung g' zeigen
        s4
        \once \override TextScript.staff-padding = #'()
        \once \override TextScript.outside-staff-priority = #'()
        \once \override TextScript.Y-offset = -0.75
        s2.^\markup{"↘"}
      }
    >>
  }
}

Falls Du sowas häufiger brauchst kannst Du auch eine Funktion definieren:
pfeil =
#(define-event-function (val mus) (number? ly:music?)
#{
-\tweak staff-padding #'()
-\tweak outside-staff-priority #'()
-\tweak Y-offset $val
$mus
#})

\header
{
  %hilfreiche Sonderzeichen (UTF-8)
  %áàåãóòœúùéèíìñ„“‚’–→←↑↓↘↙↖↗…½¼¾  % ʒ - wie g in Regie; ã - nasaliertes a
}
\score
{
  \new Staff
  {
    <<
      \new Voice
      {
        c''2 g'
        c'' f'
      }
      \new Voice
      { % Dieser Pfeil sollte INNERHALB des Notensystems
        % etwa auf der Höhe von c''2 beginnen und schräg nach unten Richtung g' zeigen
        s4
        \once \override TextScript.staff-padding = #'()
        \once \override TextScript.outside-staff-priority = #'()
        \once \override TextScript.Y-offset = -0.75
        s2.^\markup{"↘"}
        s4 s2.\pfeil #-1.75 -"↘"
      }
    >>
  }
}

Allerdings wirst Du Probleme bekommen den Text vor eine Note zu schieben.
Da gibts verschiedene Möglichkeiten, hier eine die StrokeFinger mißbraucht:

\layout {
\context {
\Voice
\override StrokeFinger.digit-names = ##("p" "i" "m" "a" "x" "↘" "↗")
strokeFingerOrientations = #'(left)
}
}

#(define RH rightHandFinger)

\new Voice {
    c''2 -\tweak font-size #1 -\tweak Y-offset #0.5 \RH #6
    g'
    c'' -\tweak font-size #1 -\tweak Y-offset #-0.5 \RH #7
    f'
  }



Gruß,
  Harm

Manuela

  • Member
Re: \markup-Text ins Notensystem verschieben
« Antwort #2 am: Sonntag, 30. Oktober 2016, 21:06 »
Jetzt gebe ich auch noch meinen Senf dazu.

Das gesuchte Objekt heißt m.E. TextScript.

Und hier eine quick-and-dirty Lösung:

\override TextScript.extra-offset = #'(1 . -2)
Einfach ausprobieren, welche Werte passen. Der erste Wert ist in horizontaler Richtung, der zweite in vertikaler.

harm6

  • Member
Re: \markup-Text ins Notensystem verschieben
« Antwort #3 am: Sonntag, 30. Oktober 2016, 21:23 »
'extra-offset ist nur was für spezielle Fälle oder als allerletztes Mittel.
Es wirkt erst nachdem jedwedes spacing berechnet wurde, das spacing wird nicht revidiert.

Vergleiche den output von
{
c''1
\break
\override TextScript.extra-offset = #'(40 . -25.5)
c''^\markup \override #'(box-padding . 20) \box "x"
}
und
{
c''1
\break
\override TextScript.outside-staff-priority = #'()
\override TextScript.staff-padding = #'()
\override TextScript.X-offset = 40
\override TextScript.Y-offset = -0.5
c''^\markup \override #'(box-padding . 20) \box "x"
}

Im anghängten Bild siehst Du oben extra-offset, weiter unten zweimal das andere coding.

Gruß,
  Harm

Manuela

  • Member
Re: \markup-Text ins Notensystem verschieben
« Antwort #4 am: Montag, 31. Oktober 2016, 07:40 »
Deswegen auch "quick & dirty"  ;)

Radler

  • Member
Re: \markup-Text ins Notensystem verschieben
« Antwort #5 am: Montag, 31. Oktober 2016, 16:33 »
Hallo Harm, hallo Manuela, vielen Dank Euch beiden!

Harms Erläuterungen zur Referenzinformation werde ich mir an die Pinn-Wand hängen.
Ich muss aber zugeben, dass ich Deine Lösung auch mit der Referenzinformation nicht verstanden habe. Geschweige denn, dass ich sie selber hätte entwickeln können.

Aber das "Vorsagen" hat mir über das Problem hinweg geholfen, und dafür danke ich sehr!

Unten findet Ihr noch ein bisschen Input von mir: \displayMusic wirft eine exception, die aber wohl mit dem Pfeil-Zeichen (UTF-8) zusammenhängt. Wenn ich den Befehl an andere Stelle schiebe, kommt zwar Output, der aber nicht zu mir spricht. Die Referenz-Information ist sehr knapp. Aber den Grob-Typ kann ich erkennen. Das ist doch schon mal was!

Für unbedarfte Benutzer wie mich von Interesse: Die "hingefummelten" Pfeile sind nicht \transpose-sensitiv, bleiben also auf ihrer Höhe, auch wenn alles um sie herum steigt oder fällt. Man kann zwar die Pfeilspitze auf Linie oder Zwischenraum der nächsten Note zeigen lassen, aber \transpose um mehr als Prime macht das wieder kaputt.
Das aber, wie gesagt, nur zur Vervollständigung. Die Lösung hilft mir sehr!

Ach so, noch eine Frage: Kann man die Funktion auch dazu bringen, einen - tja, wie nennt man das? - "Ausdruck" (expression) zu akzeptieren, etwa \pfeil #-1.75 -\bold{"↘"}? (Also: so wie es hier steht, funktioniert es nicht. Das sagt mir mein Lilypond-Compiler. Es soll nur andeuten, was ich mit "Ausdruck" meine.)

\header
{
  %hilfreiche Sonderzeichen (UTF-8)
  %áàåãóòœúùéèíìñ„“‚’–→←↑↓↘↙↖↗…½¼¾  % ʒ - wie g in Regie; ã - nasaliertes a
}
\score
{ %\transpose c f,
  \new Staff
  {
    <<
      \new Voice
      {
        c''2 g'
      }
      \new Voice
      { % Dieser Pfeil sollte INNERHALB des Notensystems
        % etwa auf der Höhe von c''2 beginnen und schräg nach unten Richtung g' zeigen
       
        s4
        \once \override TextScript.staff-padding = #'()
        \once \override TextScript.outside-staff-priority = #'()
        \once \override TextScript.Y-offset = #-0.75 % ACHTUNG: Y-offset ist NICHT transpose-sensitive!
        \displayMusic
        s2.^\markup{"↘"}
      }
    >>
  }
}
\version "2.19.49"
Der trace stack:
Traceback (most recent call last):
  File "C:\Program Files (x86)\Frescobaldi\frescobaldi_app\job.py", line 265, in _readstdout
    self.message(self.decoder_stdout(output, self.decode_errors)[0], STDOUT)
  File "C:\Program Files (x86)\Frescobaldi\frescobaldi_app\job.py", line 213, in message
    self.output(text, type)
  File "C:\Program Files (x86)\Frescobaldi\frescobaldi_app\signals.py", line 191, in emit
    l.call(args, kwargs)
  File "C:\Program Files (x86)\Frescobaldi\frescobaldi_app\signals.py", line 308, in call
    return self.func(obj, *args[self.argslice], **kwargs)
  File "C:\Program Files (x86)\Frescobaldi\frescobaldi_app\log.py", line 85, in write
    self.writeMessage(message, type)
  File "C:\Program Files (x86)\Frescobaldi\frescobaldi_app\logtool\logwidget.py", line 130, in writeMessage
    message = message.encode('latin1').decode('utf-8')
  File "C:\Python27\lib\encodings\utf_8.py", line 16, in decode
UnicodeDecodeError: 'utf8' codec can't decode byte 0xe2 in position 184: invalid continuation byte

harm6

  • Member
Re: \markup-Text ins Notensystem verschieben
« Antwort #6 am: Montag, 31. Oktober 2016, 23:33 »
Zitat
Ich muss aber zugeben, dass ich Deine Lösung auch mit der Referenzinformation nicht verstanden habe.
Welche? Ich hab' drei gepostet, auch wenn zwei de facto sehr ähnlich sind.

Zitat
Unten findet Ihr noch ein bisschen Input von mir: \displayMusic wirft eine exception, die aber wohl mit dem Pfeil-Zeichen (UTF-8) zusammenhängt.

Offensichtlich verwendest Du Frescobaldi. Bitte teste mal die direkte Kompilation via Terminal um ein Frescobaldiproblem auszuschließen.
Bei mir seh' ich im Terminal:
Zitat
(make-music
  'SkipEvent
  'articulations
  (list (make-music
          'TextScriptEvent
          'direction
          1
          'text
          (markup #:line (#:simple "�\x86�"))))
  'duration
  (ly:make-duration 1 1))
Aber keinen error.

Zitat
Für unbedarfte Benutzer wie mich von Interesse: Die "hingefummelten" Pfeile sind nicht \transpose-sensitiv, bleiben also auf ihrer Höhe, auch wenn alles um sie herum steigt oder fällt. Man kann zwar die Pfeilspitze auf Linie oder Zwischenraum der nächsten Note zeigen lassen, aber \transpose um mehr als Prime macht das wieder kaputt.
Das ist kein Wunder.
Einerseits wird hat das SkipEvent an dem das TextScript hängt ja gar keine Tonhöhe, die transponiert werden könnte. Andererseits, selbst wenn, die overrides für TextScript wirken sich absolut aus, nicht relativ zum nicht damit in Verbindung stehenden Notenkopf.
Dazu müßtest Du den Pfeil direkt abhängig vom Notenkopf machen auch was die Verschiebung in Y-Achse angeht. Tatsächlich hatte ich ja schon gezeigt, daß man auch StrokeFinger hacken kann, das ist transposierbar ;)

Zitat
Kann man die Funktion auch dazu bringen, einen - tja, wie nennt man das? - "Ausdruck" (expression) zu akzeptieren, etwa \pfeil #-1.75 -\bold{"↘"}?

Entweder Du erweiterst die Funktion ->pfeilII
Oder Du übergibst ein bold-markup an die Funktion

pfeil =
#(define-event-function (val mus) (number? ly:music?)
#{
-\tweak staff-padding #'()
-\tweak outside-staff-priority #'()
-\tweak Y-offset $val
$mus
#})

pfeilII =
#(define-event-function (val fnt-series mus) (number? symbol? ly:music?)
#{
-\tweak staff-padding #'()
-\tweak outside-staff-priority #'()
-\tweak Y-offset $val
-\tweak font-series $fnt-series
$mus
#})

\header
{
  %hilfreiche Sonderzeichen (UTF-8)
  %áàåãóòœúùéèíìñ„“‚’–→←↑↓↘↙↖↗…½¼¾  % ʒ - wie g in Regie; ã - nasaliertes a
}
\score
{
  \new Staff
  {
    <<
      \new Voice
      {
        c''2 g'
        c'' f'
      }
      \new Voice
      { % Dieser Pfeil sollte INNERHALB des Notensystems
        % etwa auf der Höhe von c''2 beginnen und schräg nach unten Richtung g' zeigen
        s4
        s2.\pfeil #-0.75 -\markup \bold "↘"
        s4 s2.\pfeilII #-1.75 #'bold -"↘"
      }
    >>
  }
}

Gruß,
  Harm