summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Sceaux <nicolas.sceaux@free.fr>2007-06-17 13:19:27 +0200
committerNicolas Sceaux <nicolas.sceaux@free.fr>2007-06-17 13:19:27 +0200
commit7c24df07725a38d5643efe86b23c26dec71058fa (patch)
tree081558acf23622692908420af0017c7df7d9c9f0
parent13162805e256027a2f0ced8947a58da5b8c526d1 (diff)
Automatic table of contents:
- markups used for building the table of contents (its title, the text/page-number lines) are defined as \paper variables, like the titling markups; - A music function is defined to place a label and push a (label paper-markup-variable text-markup) element to a list of toc items; - a \table-of-contents markup list command reads this toc items list to generate the table of contents.
-rw-r--r--Documentation/user/non-music.itely171
-rw-r--r--input/regression/page-label.ly58
-rw-r--r--input/regression/toc.ly29
-rw-r--r--ly/declarations-init.ly1
-rw-r--r--ly/toc-init.ly59
-rw-r--r--scm/define-markup-commands.scm2
6 files changed, 244 insertions, 76 deletions
diff --git a/Documentation/user/non-music.itely b/Documentation/user/non-music.itely
index 2ee1f37f3b..536780c36f 100644
--- a/Documentation/user/non-music.itely
+++ b/Documentation/user/non-music.itely
@@ -482,6 +482,7 @@ some pieces include a lot more information.
* Creating titles::
* Custom titles::
* Reference to page numbers::
+* Table of contents::
@end menu
@@ -742,26 +743,30 @@ command, either at top-level or inside music. This label can then be
refered to in a markup, to get the number of the page where the marked
point is placed, using the @code{\page-ref} markup command.
-@verbatim
-\label #'firstScore
-\score {
- {
- c'1
- \mark A \label #'markA
- c'
+@lilypond[verbatim,line-width=11.0\cm]
+\header { tagline = ##f }
+\book {
+ \label #'firstScore
+ \score {
+ {
+ c'1
+ \pageBreak \mark A \label #'markA
+ c'
+ }
}
-}
-\markup { The first score is on page \page-ref #'firstScore "0" "?" }
-\markup { Mark A is on page \page-ref #'markA "0" "?" }
-@end verbatim
+ \markup { The first score begins on page \page-ref #'firstScore "0" "?" }
+ \markup { Mark A is on page \page-ref #'markA "0" "?" }
+}
+@end lilypond
The @code{\page-ref} markup command takes three arguments:
@enumerate
-@item the label, a scheme symbol, eg. #'firstScore
+@item the label, a scheme symbol, eg. @code{#'firstScore};
@item a markup that will be used as a gauge to estimate the dimensions
-of the markup
-@item a markup that will be used if the label is not known
+of the markup;
+@item a markup that will be used in place of the page number if the label
+is not known;
@end enumerate
The reason why a gauge is needed is that, at the time markups are
@@ -772,53 +777,125 @@ the markup have to be known before, so a gauge is used to decide these
dimensions. If the book has between 10 and 99 pages, it may be "00",
ie. a two digit number.
-@code{\label} and @code{\page-ref} can be used to build a table of contents:
-
-@verbatim
-#(set-default-paper-size "a6")
+@refcommands
-#(define-markup-command (toc-line layout props label text) (symbol? markup?)
- (interpret-markup layout props
- (markup #:fill-line (text #:page-ref label "8" "?"))))
+@funindex \label
+@code{\label}
+@funindex \page-ref
+@code{\page-ref}
-\markup \column {
- \large \fill-line { \null "Table of contents" \null }
- \hspace #1
- \toc-line #'toc "Table of contents"
- \toc-line #'scoreI "First Score"
- \toc-line #'markA \line { \hspace #3 Mark A }
- \toc-line #'scoreII "Second Score"
-} \label #'toc
+@node Table of contents
+@subsection Table of contents
+A table of contents is included using the @code{\markuplines \table-of-contents}
+command. The elements which should appear in the table of contents are
+entered with the @code{\tocItem} command, which may be used either at
+top-level, or inside a music expression.
+@verbatim
+\markuplines \table-of-contents
\pageBreak
+\tocItem \markup "First score"
+\score {
+ {
+ c' % ...
+ \tocItem \markup "Some particular point in the first score"
+ d' % ...
+ }
+}
+
+\tocItem \markup "Second score"
\score {
- {
- c'1 \break
- \mark A \label #'markA
- c'1
+ {
+ e' % ...
}
- \header { piece = "First score" }
-} \label #'scoreI
+}
+@end verbatim
-\pageBreak
+The markups which are used to format the table of contents are defined
+in the @code{\paper} block. The default ones are @code{tocTitleMarkup},
+for formatting the title of the table, and @code{tocItemMarkup}, for
+formatting the toc elements, composed of the element title and page
+number. These variables may be changed by the user:
-\score {
- { d' }
- \header { piece = "Second score" }
-} \label #'scoreII
+@verbatim
+\paper {
+ %% Translate the toc title into French:
+ tocTitleMarkup = \markup \huge \column {
+ \fill-line { \null "Table des matières" \null }
+ \hspace #1
+ }
+ %% use larfer font size
+ tocItemMarkup = \markup \large \fill-line {
+ \fromproperty #'toc:text \fromproperty #'toc:page
+ }
+}
@end verbatim
-In this example, a @code{\toc-line} markup command is defined to build
-the table of content items. As this example has less than 10 pages, the
-gauge used by @code{\page-ref} has a single digit.
+Note how the toc element text and page number are refered to in
+the @code{tocItemMarkup} definition.
+
+New commands and markups may also be defined to build more elaborated
+table of contents:
+@itemize @bullet
+@item first, define a new markup variable in the @code{\paper} block
+@item then, define a music function which aims at adding a toc element
+using this markup paper variable.
+@end itemize
+
+In the following example, a new style is defined for entering act names
+in the table of contents of an opera:
+
+@verbatim
+\paper {
+ tocActMarkup = \markup \large \column {
+ \hspace #1
+ \fill-line { \null \italic \fromproperty #'toc:text \null }
+ \hspace #1
+ }
+}
+
+tocAct =
+#(define-music-function (parser location text) (markup?)
+ (add-toc-item! 'tocActMarkup text))
+@end verbatim
+
+@lilypond[line-width=11.0\cm]
+\header { tagline = ##f }
+\paper {
+ tocActMarkup = \markup \large \column {
+ \hspace #1
+ \fill-line { \null \italic \fromproperty #'toc:text \null }
+ \hspace #1
+ }
+}
+
+tocAct =
+#(define-music-function (parser location text) (markup?)
+ (add-toc-item! 'tocActMarkup text))
+
+\book {
+ \markuplines \table-of-contents
+ \tocAct \markup { Atto Primo }
+ \tocItem \markup { Coro. Viva il nostro Alcide }
+ \tocItem \markup { Cesare. Presti omai l'Egizzia terra }
+ \tocAct \markup { Atto Secondo }
+ \tocItem \markup { Sinfonia }
+ \tocItem \markup { Cleopatra. V'adoro, pupille, saette d'Amore }
+ \markup \null
+}
+@end lilypond
+
+@seealso
+
+Init files: @file{ly/@/toc@/-init@/.ly}.
@refcommands
-@funindex \label
-@code{\label}
-@funindex \page-ref
-@code{\page-ref}
+@funindex \table-of-contents
+@code{\table-of-contents}
+@funindex \tocItem
+@code{\tocItem}
@node MIDI output
@section MIDI output
diff --git a/input/regression/page-label.ly b/input/regression/page-label.ly
index 6f1e5c8e88..cb023872dc 100644
--- a/input/regression/page-label.ly
+++ b/input/regression/page-label.ly
@@ -11,34 +11,36 @@ and refered to in markups."
(interpret-markup layout props
(markup #:fill-line (text #:page-ref label "8" "?"))))
-\markup \huge \fill-line { \null "Title Page" \null }
-
-\pageBreak
-
-\label #'toc
-\markup \column {
- \large \fill-line { \null "Table of contents" \null }
- \toc-line #'toc "Table of contents"
- \toc-line #'firstScore "First Score"
- \toc-line #'markA "Mark A"
- \toc-line #'markB "Mark B"
- \toc-line #'markC "Mark C"
- \toc-line #'unknown "Unknown label"
-}
+\book {
+ \markup \huge \fill-line { \null "Title Page" \null }
+
+ \pageBreak
+
+ \label #'toc
+ \markup \column {
+ \large \fill-line { \null "Table of contents" \null }
+ \toc-line #'toc "Table of contents"
+ \toc-line #'firstScore "First Score"
+ \toc-line #'markA "Mark A"
+ \toc-line #'markB "Mark B"
+ \toc-line #'markC "Mark C"
+ \toc-line #'unknown "Unknown label"
+ }
-\pageBreak
-
-\label #'firstScore
-\score {
- { c'2 c'
- \mark \markup { A (page \concat { \page-ref #'markA "0" "?" ) }} \label #'markA
- c' c'
- \pageBreak
- \mark "B" \label #'markB
- d' d'
- d' d'
- \once \override Score . RehearsalMark #'break-visibility = #begin-of-line-invisible
- \mark "C" \label #'markC
+ \pageBreak
+
+ \label #'firstScore
+ \score {
+ { c'2 c'
+ \mark \markup { A (page \concat { \page-ref #'markA "0" "?" ) }} \label #'markA
+ c' c'
+ \pageBreak
+ \mark "B" \label #'markB
+ d' d'
+ d' d'
+ \once \override Score . RehearsalMark #'break-visibility = #begin-of-line-invisible
+ \mark "C" \label #'markC
+ }
+ \header { piece = "First score" }
}
- \header { piece = "First score" }
} \ No newline at end of file
diff --git a/input/regression/toc.ly b/input/regression/toc.ly
new file mode 100644
index 0000000000..e6164ea602
--- /dev/null
+++ b/input/regression/toc.ly
@@ -0,0 +1,29 @@
+\version "2.11.26"
+
+\header {
+ texidoc = "A table of contents is included using
+@code{\\markuplines \\table-of-contents}. The toc items are added with
+the @code{\\tocItem} command."
+}
+
+#(set-default-paper-size "a6")
+
+\book {
+ \markuplines \table-of-contents
+ \pageBreak
+
+ \tocItem \markup "The first score"
+ \score {
+ {
+ c'1 \pageBreak
+ \mark "A" \tocItem \markup "Mark A"
+ d'
+ }
+ }
+ \pageBreak
+ \tocItem \markup "The second score"
+ \score {
+ { e' }
+ \header { piece = "Second score" }
+ }
+} \ No newline at end of file
diff --git a/ly/declarations-init.ly b/ly/declarations-init.ly
index 364068c043..b8c36e4f33 100644
--- a/ly/declarations-init.ly
+++ b/ly/declarations-init.ly
@@ -10,6 +10,7 @@ maxima = #(ly:make-duration -3 0)
\include "markup-init.ly"
\include "music-functions-init.ly"
+\include "toc-init.ly"
%% default note names are dutch
\include "nederlands.ly"
diff --git a/ly/toc-init.ly b/ly/toc-init.ly
new file mode 100644
index 0000000000..334c983d0b
--- /dev/null
+++ b/ly/toc-init.ly
@@ -0,0 +1,59 @@
+\version "2.11.26"
+
+%% defined later, in a closure
+#(define-public (add-toc-item! markup-symbol text)
+ #f)
+#(define-public (toc-items)
+ #f)
+
+#(let ((toc-item-list (list)))
+ (set! add-toc-item!
+ (lambda (markup-symbol text)
+ (let ((label (gensym "toc")))
+ (set! toc-item-list
+ (cons (list label markup-symbol text)
+ toc-item-list))
+ (make-music 'EventChord
+ 'page-marker #t
+ 'page-label label
+ 'elements (list (make-music 'LabelEvent
+ 'page-label label))))))
+ (set! toc-items (lambda ()
+ (reverse toc-item-list))))
+
+\paper {
+ tocTitleMarkup = \markup \huge \column {
+ \fill-line { \null "Table of Contents" \null }
+ \hspace #1
+ }
+ tocItemMarkup = \markup \fill-line {
+ \fromproperty #'toc:text \fromproperty #'toc:page
+ }
+}
+
+#(define-markup-list-command (table-of-contents layout props) ()
+ "Outputs the table of contents, using the paper variable
+@code{tocTitleMarkup} for its title, then the list of lines
+built using the @code{tocItem} music function
+Usage: @code{\\markuplines \\table-of-contents}"
+ (cons (interpret-markup layout props
+ (ly:output-def-lookup layout 'tocTitleMarkup))
+ (space-lines (chain-assoc-get 'baseline-skip props)
+ (map (lambda (toc-item)
+ (let ((label (car toc-item))
+ (toc-markup (cadr toc-item))
+ (text (caddr toc-item)))
+ (interpret-markup
+ layout
+ (cons (list (cons 'toc:page
+ (markup #:page-ref label "XXX" "?"))
+ (cons 'toc:text text))
+ props)
+ (ly:output-def-lookup layout toc-markup))))
+ (toc-items)))))
+
+tocItem =
+#(define-music-function (parser location text) (markup?)
+ "Add a line to the table of content, using the @code{tocItemMarkup} paper
+variable markup"
+ (add-toc-item! 'tocItemMarkup text))
diff --git a/scm/define-markup-commands.scm b/scm/define-markup-commands.scm
index 956bd817bf..5405aff312 100644
--- a/scm/define-markup-commands.scm
+++ b/scm/define-markup-commands.scm
@@ -1493,7 +1493,7 @@ when @var{label} is not found."
;; Markup list commands
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(define (space-lines baseline-skip lines)
+(define-public (space-lines baseline-skip lines)
(map (lambda (line)
(stack-lines DOWN 0.0 (/ baseline-skip 2.0)
(list (ly:make-stencil "" (cons 0 0) (cons 0 0))