Autor Thema: 2.16.0: /fromproperty #'header:piece geht nicht in HeaderMarkup  (Gelesen 2670 mal)

martinmagtenor

  • Member
2.16.0: /fromproperty #'header:piece geht nicht in HeaderMarkup
« am: Mittwoch, 17. Oktober 2012, 20:04 »
Guten Abend,

bin neu hier und komme mit einem Kopfzeilen-Formatierungsproblem nicht weiter.

Es geht um ein mehrseitiges vierstimmiges Vokalwerk. Der Druck soll beidseitig erfolgen, dei Kopfzeile soll außen den Titel des Werkes und innen den jeweiligen Satzbezeichner führen. Ich habe eine Kontrolldatei und für jeden Satz eine eigene Datei.

Das Inhaltsverzeichnis funktioniert, nur der Satzbezeichner, den ich mit \fromproperty aus dem header-Objekt holen will bleibt leer.

Damit ich nicht so viel erklären muss, habe ich versucht, das auf ein minimales Code-Fragment einzudampfen:

\version "2.16.0"

%{
Zugriff auf #'header:piece geht nicht in odd/evenHeaderMarkup!
Inhaltsverzeichnis ist ok.
}%

\include "deutsch.ly"

\markuplist \table-of-contents

\header {
title = "Titel"
composer = "Komponist"
copyright = "Copyright"
} % header

% Jetzt kommen die einzelnen Sätze über Inkludierung.
% Damit ich den Satztitel micht mehrfach schreiben muss, übergebe ich eine
% Variable:
thisPiece = "Eins"
\include "eins.ly"

thisPiece = "Zwei"
\include "zwei.ly"

% usw.

% dann kommt die paper-Deklaration, die ich auf den relevanten Teil verkürze:

\paper {
oddHeaderMarkup = \markup { \fill-line { \fromproperty #'header:piece \null \fromproperty #'header:title } }
evenHeaderMarkup = \markup { \fill-line { \fromproperty #'header:title \null \fromproperty #'header:piece } }

} % paper

%{
  % Beispiel für eins.ly

\tocItem \markup \thisPiece

\score {
  \relative c { b a c h }
 \header {
  piece = \thisPiece
 } % header
} % score


}%

Bin für jeden Hinweis dankbar.

Schönen Abend
« Letzte Änderung: Mittwoch, 17. Oktober 2012, 20:06 von martinmagtenor »

harm6

  • Member
Re: 2.16.0: /fromproperty #'header:piece geht nicht in HeaderMarkup
« Antwort #1 am: Donnerstag, 18. Oktober 2012, 02:03 »
Hallo,

willkommen im Forum!

Zum Thema:
Das Problem gründet auf dem Unterschied von bookTitleMarkup und scoreTitleMarkup.

\fromproperty #'header: ... ruft die entsprechende Variable aus dem bookTitleMarkup auf. Das scoreTitleMarkup kann zwar eine `piece´-Angabe hinzufügen (oder auch überschreiben), da die page-header (und footer) jedoch vorher definiert sein müssen, greifen sie immer auf die Original-Variable aus dem Original-bookheader zu.
Wenn Du also
piece = "irgendwas"
im book-header definiertest, so wird immer "irgendwas" in die page-header geschrieben.

Zwei Lösungsmöglichkeiten:
a) Ein kleines feature welches ich vor ein paar Monaten als patch geschrieben habe: #(on-page <number>)
Hier handelt es sich um die Möglichkeit auf bestimmten, namentlich anzugebenden Seiten, bestimmte markups in die header/footer zu setzen.
Wenn Du mehrere, verschiedene markups auf verschiedenen Seiten haben willst, so benutze \line { ... }.
Du kannst in \paper eine Variable (als \markup { ...}) definieren, die alle diese Setzungen enthält und in den page-header-Definitionen einfach aufrufen.
Das Ganze ist allerdings nicht völlig automatisiert, aber man hat zumindest die Möglichkeit bestimmte Seiten anzusprechen.

\version "2.16.0"

\include "deutsch.ly"

\markuplist \table-of-contents

\pageBreak

 \header {
  title = "Titel"
  composer = "Komponist"
  copyright = "Copyright"
 } % header

% Jetzt kommen die einzelnen Sätze über Inkludierung.
% Damit ich den Satztitel micht mehrfach schreiben muss, übergebe ich eine
% Variable:
thisPiece¹ = "Eins"
%\include "eins.ly"

thisPiece² = "Zwei"
% \include "zwei.ly"

thisPiece³ = "Drei"
% \include "drei.ly"

% usw.

% dann kommt die paper-Deklaration,

\paper {
        myHeadersMarkup = \markup {
        \line {
                \on-the-fly #(on-page 2) \thisPiece¹
        \on-the-fly #(on-page 3) \thisPiece²
        \on-the-fly #(on-page 4) \thisPiece³
}
        }
        oddHeaderMarkup = \markup {
        \fill-line { 
                \on-the-fly #not-first-page
                        \box
                        \myHeadersMarkup
                        \on-the-fly #not-first-page
                        \fromproperty #'header:title
                }
        }
        evenHeaderMarkup = \markup {
                \fill-line {
                        \fromproperty #'header:title
                        \box
                        \myHeadersMarkup
                }
        }

} % paper

%%{
  % Beispiel für eins.ly

\tocItem \markup \thisPiece¹
\tocItem \markup \thisPiece²
\tocItem \markup \thisPiece³

\score {
  \relative c { b a c h }
 \header {
         piece = \thisPiece¹
 } % header
} % score
\pageBreak \markup \fill-line { \fontsize #6 "Page 3" }
\pageBreak \markup \fill-line { \fontsize #6 "Page 4" }
%}

b) \book und \bookpart
Du kannst in jedem bookpart (unabhängig von anderen bookparts) neue Definitionen von \paper, \layout, \header etc angeben.
Allerdings wird jeder bookpart auf einer neuen Seite begonnen. Ob das in Deinem Fall von Vorteil oder Nachteil ist kann ich natürlich nicht sagen.


Gruß,
  Harm

martinmagtenor

  • Member
Re: 2.16.0: /fromproperty #'header:piece geht nicht in HeaderMarkup
« Antwort #2 am: Donnerstag, 18. Oktober 2012, 20:08 »
Hallo,

danke für fundierte die Erläuterung. Dass die beiden header-Umgebungen je nach Kontext so strikt getrennt sind, war mir irgendwie entgangen. Das ist ja wirklich schade.

Bookpart kommt nicht infrage, weil ich Seitenwechsel zwischen den Sätzen überhaupt nicht brauchen kann.

Dein erster Vorschlag mit Deiner on-page-Funktion ist interessant, mir aber noch zu umständlich. Der Leidensdruck ist noch nicht groß genug.  ;-)

Insgesamt sträubt sich meine Programmiererseele noch gegen so einen Workaround. Noch spiele ich mit Skalierung und anderen Parametern und da müsste ich ja jedesmal alles nachjustieren.

Der Hinweis "[...] die page-header [...] jedoch vorher definiert sein müssen [...]" bringt mich nochmal auf den Gedanken, ob es keine Möglichkeit gibt, einer "späten" Auflösung der Verweise in dem Markup. Dann könnte sich der Inhalt unterwegs durchaus ändern.

Nun denn, mal sehen ...

Schönen Abend
   Martin

harm6

  • Member
Re: 2.16.0: /fromproperty #'header:piece geht nicht in HeaderMarkup
« Antwort #3 am: Freitag, 19. Oktober 2012, 20:59 »
Hallo Martin,

Zitat
Dein erster Vorschlag mit Deiner on-page-Funktion ist interessant, mir aber noch zu umständlich. Der Leidensdruck ist noch nicht groß genug.  ;-)
Insgesamt sträubt sich meine Programmiererseele noch gegen so einen Workaround.

Ist schon richtig, `on-page´ ist eigentlich nicht für diesen Zweck geschrieben worden. Wenn man es doch so einsetzt muß man natürlich immer wieder manuell eingreifen. :(

Zitat
Der Hinweis "[...] die page-header [...] jedoch vorher definiert sein müssen [...]" bringt mich nochmal auf den Gedanken, ob es keine Möglichkeit gibt, einer "späten" Auflösung der Verweise in dem Markup. Dann könnte sich der Inhalt unterwegs durchaus ändern.

Falls Dir da etwas gelingt, würde es mich sehr interessieren. Das Problem ist schon mehrfach aufgetaucht.



Gruß,
  Harm

martinmagtenor

  • Member
Re: 2.16.0: /fromproperty #'header:piece geht nicht in HeaderMarkup
« Antwort #4 am: Sonntag, 27. April 2014, 22:42 »
Das Thema lässt mir keine Ruhe und der Leidensdruck steigt ...

In der Zwischenzeit habe ich dies und das über Lilypond gelernt und verstehe die Problematik besser.

  • Anders als bei beim book-header gibt es bei den Score-Umgebungen keine feste Beziehung zwischen den Kopfzeilen einer Seite und dem Score. Das leuchtet dann ein, wenn man den Fall betrachtet, dass mehrere "kurze" Scores auf einer Seite sind. Auf welchen Score-Header soll sich dann ein fromproperty #'header:piece beziehen? Dafür gibt es also auf jeden Fall keine einfache Lösung.
  • Was will ich denn eigentlich haben? Ich will die Angabe, die im Inhaltsverzeichnis als "toc:text" abgerufen wird, in der Kopfzeile haben. Der Wechsel soll immer auf der Seite erfolgen, auf der der Score erscheint. Damit ist das vorher geschilderte Problem (mehrere Scores auf einer Seite) keines mehr, das letzte Score "gewinnt".
  • Von diesem Gedanken ausgehend -- und verleitet durch #'toc:page und #'toc:text in \tabel-of-contents vermutete ich, dass lilypond intern ein Objekt toc führt, in dem wie in einer Tabelle der Inhalt (toc:text) und die zugehörige Seite (toc:page) geführt sind. Wenn das so wäre, könnte man sich ja mit relativ einfachen Suchoperarationen, ausgehend von der aktuellen Seite #'page:page-number, den passenden Eintrag aus dem Inhaltsverzeichnis fischen und den gesuchte Text in der Kopfzeile einfügen.
  • Auch dieser Gedanke ist eine Sackgasse, soetwas wie dieses toc-Objekt gibt es zwar (toc-items), darin ist aber gar keine Seitenzahl abgelegt. Dieses Ding entspricht einer dreispaltigen Tabelle, in der ein Label (das auf den Herkunftsort zeigt, erzeugt mit \tocItem), der Markup-Bezeichner für das Inhaltsverzeichnis und der gewünschte Text enthalten sind. Das Inhaltsverzeichnis entsteht dadurch, dass \table-of-contents diese Tabelle zeilenweise in markups zerlegt und diese an \markuplist übergibt. Der Trick ist, dass durch eine verzögerte (delay) Auswertung in jedem Markup die zugehörige props-Umgebung um die Einträge toc:page und toc:text erweitert werden. Dadurch kann fromproperty auf dieses eine Paar (das in jeder Zeile nur einmal, aber dafür individuell existiert) zugreifen und es entsteht letztlich das Inhaltsverzeichnis.

    Das ist durchaus pfiffig und ein cleverer Ansatz, die Folgen der Seitenaufteilungsoptimierung zu umgehen, aber nicht einfach nachzuvollziehen.
  • Seiten, Seitenaufteilung und Seitennummern sind relativ flüchtige Informationen, wenn man, wie bei Lilypond, einem System die Hoheit über die Seitenaufteilung -- zumindest anteilig -- überlässt.
Also weiterhin keine einfache Lösung? Zumindest ohne Verständnis dieser verzögerten Auflösung (Wer oder was löst sie aus? Und wann?) ist hier kein Staat zu machen. Ich denke, hier kommt der in C++ geschriebene Lilypond-Kern ins Spiel.

Irgendwelche An- und Einsichten zum Thema? Entwickler-Doku?

Grüße
  Martin