Markup: Absolute Positionierung [GELÖST]

Begonnen von ingmar, Samstag, 27. Mai 2017, 08:42

« vorheriges - nächstes »

ingmar

hallo,


\markup geht normalerweise davon aus, dass verschieden formatierter Text fortlaufend geschrieben werden soll.

Ein anderer Fall liegt aber vor, wenn einzelne Elemente auf einem Blatt angeordnet werden sollen - etwa auf einem Titelblatt Komponist, Werktitel und Verlag - jeder dieser Blocks an einer ganz bestimmten Stelle. Nach dem ersten Block könnte man also eine Anzahl von Zeilendurchschüssen verwenden und dahinter den zweiten positionieren, aber das bleibt immer manuelle Bastelei; ist der Titel mal zweizeilig, verschiebt sich alles, was dahinter kommt.

Ich habe den Befehl \overlay gefunden, der nach meinem Verständnis ermöglichen sollte, drei Schichten unabhängig von einander zu positionieren. Aber er ist kaum dokumentiert und funktioniert absolut nicht so, wie ich mir das vorstelle:


\version "2.19.37"
\markup \overlay {
{ \line { "erste Zeile"}}
{ \vspace #20 \line { "zweite Zeile" }}
{ \vspace #60 \line { "dritte Zeile" }}
}


Frage: Wie muss man \overlay richtig anwenden? Gibt es eventuell elegantere Möglichkeiten?


EDIT:
\translate gestattet eine absolute Positionierung, und hier ist \overlay notwendig, damit die Elemente unabhängig angeordnet werden:


\markup \overlay {
{ \line { "erste Zeile"}}
{ \translate #'(12 . 70) \line { "zweite Zeile" }}
{ \translate #'(40 . 20) { "dritte Zeile" }}
}


Soweit also gelöst! Für mich ist aber offen, warum \overlay im ersten Beispiel nicht richtig arbeitet. Weiß das jemand?


Danke, Gruß,
--ingmar

harm6

Zitat
Für mich ist aber offen, warum \overlay im ersten Beispiel nicht richtig arbeitet.

\overlay hat genau das gemacht was Du ihm aufgetragen hast.

D.h.
Die markups für "erste Zeile" "zweite Zeile" "dritte Zeile" \vspace #20 \vspace #60 sind übereinander gelegt. In Ermangelung anderer Anweisungen alles ausgerichtet an der baseline. Diese baseline wird allerdings durch \vspace #60 nach unten aus einem A4-Blatt herausgeschoben.

Um das sichtbar zu machen:


#(set-default-paper-size "a3")

\markup \overlay \box {
{ \line { "erste Zeile"}}
{ \vspace #20 \line { "zweite Zeile" }}
{ \vspace #60 \line { "dritte Zeile" }}
}


(Das \box-markup-command angewendet auf \vspace führt allerdings zu Protesten von LilyPond.)

Also keine Fehlfunktion, allerdings ist \vspace hier völlig ungeeignet um Abstände zu setzen. Wie Du schon selbst heraus gefunden hast ist \translate das Mittel der Wahl.


Gruß,
  Harm

ingmar

Hallo, danke für die Antwort!

Ich hätte halt erwartet, dass \overlay die drei Zeilen übereinander (aufeinander) anordnet, die durch geschweifte Klammern als die drei anzusprechenden Elemente gekennzeichnet sind:

* schreib "erste Zeile"
* geh 20 Einheiten nach unten, und schreib dort "zweite Zeile"
* geh 60 Einheiten nach unten, und schreib dort "dritte Zeile"

Offenbar hält sich \overlay nicht an diese drei Elemente und klopft die Hierarchie platt, um dann fünf gleichberechtigte Elemente zu haben und diese aufeinander zu schreiben. Das war's, was mich irritiert hatte - was genau sind die Elemente, die \overlay als ganze Einheiten respektier? Warum haben die geschweiften Klammern keinen Effekt? Das ist, was ich nicht verstehe, und was die Doku anscheinend auch nicht hergibt.

Aber egal - eine Lösung hatte ich ja gefunden.

Gruß,
--ingmar

harm6

Hallo ingmar,

hier liegt ein grundlegendes Verständnisproblem vor.

Die Klammern {} im markup haben keinerlei hierarchische Bedeutung, niemals und nie gehabt.
Vielmehr definieren sie eine markup-list.

Sofern dem nichts entgegensteht werden alle markup-Befehle auf alle Elemente dieser Liste angewendet.
Vergleiche:

\markup \rotate #10 \box { xx yy zz pp qq }
\markup \rotate #10 \box { xx { yy zz } { pp qq } }

Beides resultiert in exakt demselben output.

Es kann natürlich sein das ein anderer Befehl aus einer markup-list bereits ein fertiges, einzelnes markup gemacht hat, dann wird ein vorangestellter Befehl natürlich nur auf dieses einzelne markup angewendet und nicht auf die Elemente aus denen es ursprünglich gebildet worden war:

\markup \rotate #10 \box { xx \line { yy zz } \concat { pp qq } }


In Deinem Beispiel sind die Klammern die Du zur vermeintlichen Etablierung einer Hierarchie gesetzt hast also völlig ohne Funktion, da es kein markup-command gibt welches aus dieser markup-Liste ein einzelnes markup macht, stattdessen bleibt es eine Liste.
Siehe auch:

\markup
  \column {
    xx
    { yy zz }
    {  pp qq }
  }


Im übrigen ist \line { "erste Zeile"} ebenfalls reichlich doppelt gemoppelt. { "erste Zeile"} ist heir eine markup-Liste, die ein einziges Element enthält diese Element ist aber bereits ein string. Welchen Du aus zwei Wörten direkt beim input geformt hattest.
Also reicht entweder
\markup "erste Zeile"
oder
\markup \line { erste Zeile }
Natürlich ist der Unterschied für \fill-line schon bedeutsam ;)

Zusammenfassung:
\overlay wirkt auf alle Elemente der ihm gegebenen markup-list.
Alle Elemente werden übereinander geschrieben, ähnlich wie \combine nur das eine Liste von markups bearbeitet wird.
Ein Element einer markup-Liste ist ein markup. Markup-commands die eine markup-liste als Argument erwarten, geben ein markup zurück. Also z.B. line, fill-line, column etc.

Es gibt natürlich noch markup-list-commands, bei denen sieht die Sache etwas anders aus...,

Gruß,
  Harm



ingmar