Subject: [LilyPond] Table des matières en colonnes

From: Ben via LilyPond <[email-masked]>
Date: Wed, 26 Mar 2025 21:47:48 +0000

Bonjour, 

Je me permets de relancer juste pour préciser que la fonction ne marche pas dans tous les cas.

Intégré dans mon code, soit le titre de la table des matières prend toute une page et repousse la table à la suivante, soit, si je le mets à "" et mets à la place un oddHeaderMarkup, la deuxième colonne ne le voit pas et se superpose par-dessus. 

Mais ce n'est pas très grave…

---
Pour poster dans ce sujet, visitez la [page du sujet](https://lilypond.community/t/table-des-matieres-en-colonnes/4978/14).

Pour créer un nouveau sujet, écrivez à [[email-masked]](mailto:[email-masked]) ou visitez la [page d'accueil de lilypond.community](https://lilypond.community).

---

From: Jean Abou Samra via LilyPond <[email-masked]>
Date: Thu, 27 Mar 2025 02:12:07 +0000

Bizarre. Un exemple ?

---
Pour poster dans ce sujet, visitez la [page du sujet](https://lilypond.community/t/table-des-matieres-en-colonnes/4978/15).

---

From: Vincent Gay via LilyPond <[email-masked]>
Date: Thu, 27 Mar 2025 07:22:15 +0000

J'utilise cette fonction depuis que Jean l'a développé, avec 2 ou 3 colonnes, et je n'ai jamais rencontré ce problème...
Un exemple ?

*De : *Ben via LilyPond <[email-masked]>
*À : [email-masked]
*Date : *26 mars 2025 22:47:46
*Objet : *[LilyPond] Table des matières en colonnes

> [Image]*Ben[https://lilypond.community/u/ben]* *Ben*
> Mars 26
> Bonjour,
> 
> ----------------------------------------
> 
> Pour poster dans ce sujet, visitez la
> *page du sujet[https://lilypond.community/t/table-des-matieres-en-colonnes/4978/14]*
> .
> 
> Pour créer un nouveau sujet, écrivez à [email-masked]* ou visitez la *page d'accueil de lilypond.community[https://lilypond.community]*.
> 
> 
> 
> Pour vous désabonner de ces e-mails, modifiez vos *préférences[https://lilypond.community/my/preferences/emails]*.
> 

-- 
Vincent Gay
Envoyé depuis mon saxo-phone

---
Pour poster dans ce sujet, visitez la [page du sujet](https://lilypond.community/t/table-des-matieres-en-colonnes/4978/16).

---

From: Ben via LilyPond <[email-masked]>
Date: Thu, 27 Mar 2025 09:28:07 +0000

Merci pour vos réponses!

C'est un peu compliqué de donner directement mon code, j'ai pas mal d'includes, etc. 

Mais si je reprends le code de Jean et que je mets par exemple en commentaire le \tocAct, le saut de page apparaît avec le titre, comme c'est le cas chez moi:

\bookpart {
  $@(map (lambda (i)
           (let ((sym (gensym "act")))
             #{
 %              \tocAct #sym #(format #f "Pièce ~a" i)
               \tocItem #(list sym 'sheet) "Lead sheet"
               \tocItem #(list sym 'bass) "Bass line"
               c'
               #}))
         (iota 300 1))
}

> Le 27 mars 2025 à 08:22, Vincent Gay via LilyPond <[email-masked]> a écrit :
> 
> 	Vincent Gay  <https://lilypond.community/u/vincent>Vincent
> Mars 27
> *De : *Ben via LilyPond [email-masked] <mailto:[email-masked]>
> *À : [email-masked] <mailto:[email-masked]>
> [Image]Ben[https://lilypond.community/u/ben] Ben
> Mars 26
> Bonjour,
> 
> page du sujet[https://lilypond.community/t/table-des-matieres-en-colonnes/4978/14]
> .
> 
> Pour créer un nouveau sujet, écrivez à [email-masked] <mailto:[email-masked]> ou visitez la page d'accueil de lilypond.community[https://lilypond.community <https://lilypond.community/>].
> 
> 
> 
> Pour vous désabonner de ces e-mails, modifiez vos préférences[https://lilypond.community/my/preferences/emails].
> --
> Vincent Gay
> Pour poster dans ce sujet, visitez la page du sujet <https://lilypond.community/t/table-des-matieres-en-colonnes/4978/16>.
> 
> Pour créer un nouveau sujet, écrivez à [email-masked] <mailto:[email-masked]> ou visitez la page d'accueil de lilypond.community <https://lilypond.community/>.
> 
> Réponses précédentes
> 
> 	Jean Abou Samra <https://lilypond.community/u/jeanas> jeanas
> Mars 27
> Bizarre. Un exemple ?
> 
> 	Ben <https://lilypond.community/u/ben> Ben
> Mars 26
> Bonjour,
> 
> 	Gilles <https://lilypond.community/u/yagloops> Yagloops
> Août 30, 2022
> (1+ ∞)
> 
> 
> ··· (cliquer pour plus de détails) <https://lilypond.community/t/table-des-matieres-en-colonnes/4978/13>
> 	Jacques Menu <https://lilypond.community/u/jacquesmenu> jacquesmenu
> Août 30, 2022
> Il faudrait un jour que je compte le nombre de choses que je peux faire grâce à Jean et que je n'aurai jamais pu faire sans lui.
> J’ai fait le calcul pour nous tous : ∞
> 
> JM
> 
> 	Jean Abou Samra <https://lilypond.community/u/jeanas> jeanas
> Août 29, 2022
> J'ai fini par trouver une solution qui me plaît assez. La voici
> en pièce jointe.
> Merci Jean.
> 
> je n'ai pas compris ce que signifie
> 
> %% Attention : s'il y a plusieurs éléments à l'intérieur du tocActMarkup,
> %% ne pas faire \new-toc-group { ... } mais \new-toc-group \line { ... }
> De quels genre d'éléments peut-il s'agir ?
> Je veux dire qu'il faut donner seulement un argument à
> \new-toc-group, pas plusieurs arguments entre accolades.
> 
> OK :
> 
> \new-toc-group \italic ...
> 
> Pas OK :
> 
> \new-toc-group { ... }
> 
> OK :
> 
> \new-toc-group \line { ... }
> 
> Dans le même tonneau, il arrive que les gens soient surpris par la
> différence de rendu entre ces deux lignes, ou ne comprennent pas ce
> qu'il faut pour obtenir le rendu de la deuxième :
> 
> \markup \rotate #30 { a b c d }
> \markup \rotate #30 \line { a b c d }
> 
> Car si \fonction est une fonction pour markups qui accepte un argument
> de type markup (plus précisément son dernier argument),
> 
> \fonction [arguments] { plusieurs markups }
> 
> est une sorte d'équivalent à
> 
> { \fonction [arguments] markup1 \fonction [arguments] markup2 ... }
> 
> Le code
> 
> \markup \rotate #30 { a b c d }
> 
> fait la même chose que
> 
> \markup { \rotate #30 a \rotate #30 b \rotate #30 c \rotate #30 d }
> 
> Et avec \new-toc-group, ça ne va pas parce que cette commande ajoute
> une sorte de marqueur qui identifie un tocAct, et le marqueur doit
> se trouver sur le markup entier.
> 
> Pour l'heure j'ai fait avec ce que j'avais et ça marche bien. J'essaierai avec 3 colonnes quand j'aurai intégré suffisamment de morceaux mais c'est assez long car j'ai plusieurs versions de grilles harmoniques et je dois tout convertir à la main. Sans compter les \mark qui ne fonctionnent plus bien avec \polyMark.
> Ah oui, j'avais oublié cette histoire de polymarks (enfin non, je n'ai
> pas oublié \textMark et \textEndMark dont nous discutions sur lilypond-devel,
> mais j'avais oublié que tu avais besoin d'un polymark qui marche aussi
> avec \mark en attendant). Deux minutes, je te fais ça (et je le poste dans
> le fil qui va bien).
> 
> Jean
> 
> ··· (cliquer pour plus de détails) <https://lilypond.community/t/table-des-matieres-en-colonnes/4978/11>
> Pour poster dans ce sujet, visitez la page du sujet <https://lilypond.community/t/table-des-matieres-en-colonnes/4978/16>.
> 
> Pour créer un nouveau sujet, écrivez à [email-masked] <mailto:[email-masked]> ou visitez la page d'accueil de lilypond.community <https://lilypond.community/>.
> 
> 
> 
> Pour vous désabonner de ces e-mails, modifiez vos préférences <https://lilypond.community/my/preferences/emails>.
>

---
Pour poster dans ce sujet, visitez la [page du sujet](https://lilypond.community/t/table-des-matieres-en-colonnes/4978/17).

---

From: Jean Abou Samra via LilyPond <[email-masked]>
Date: Thu, 27 Mar 2025 19:19:07 +0000

Hum, je crois que j'ai dû oublier des espacements, probablement celui entre la marge du haut et le titre, dans le calcul de l'espace libre, donc mon code met parfois un peu trop de lignes pour cet espace.

Comme je n'ai pas trop le temps, je vous suggère juste de remplacer

```
         (height (- (ly:output-def-lookup layout 'paper-height)
                    (ly:output-def-lookup layout 'top-margin)
                    (ly:output-def-lookup layout 'bottom-margin))))
```

par

```
         (height (- (ly:output-def-lookup layout 'paper-height) 30.0)))
```

où la valeur 30.0 est à ajuster : avec cette valeur assez grande, il restera de l'espace en bas, diminuez-la progressivement jusqu'à ce que les entrées de la table des matières arrivent à peu près à la marge inférieure.

---
Pour poster dans ce sujet, visitez la [page du sujet](https://lilypond.community/t/table-des-matieres-en-colonnes/4978/18).

---

From: Ben via LilyPond <[email-masked]>
Date: Thu, 27 Mar 2025 20:19:22 +0000

Cela ne change rien, mais ne vous stressez pas, je vais continuer avec une seule colonne, et à l'occasion, je ferai un script python qui placera judicieusement des \markup. 

> Le 27 mars 2025 à 20:18, Jean Abou Samra via LilyPond <[email-masked]> a écrit :
> 
> Pour poster dans ce sujet, visitez la page du sujet <https://lilypond.community/t/table-des-matieres-en-colonnes/4978/18>.
> 
> Pour poster dans ce sujet, visitez la page du sujet <https://lilypond.community/t/table-des-matieres-en-colonnes/4978/18>.
> 

---
Pour poster dans ce sujet, visitez la [page du sujet](https://lilypond.community/t/table-des-matieres-en-colonnes/4978/19).

---

From: Jean Abou Samra via LilyPond <[email-masked]>
Date: Thu, 27 Mar 2025 20:23:18 +0000

Tiens, bizarre. Même en mettant une valeur vraiment grande ? Dans ce cas, ça doit être autre chose, mais difficile de savoir sans exemple (mais si c'est plus simple pour vous de contourner que d'extraire un exemple, je comprends complètement).

---
Pour poster dans ce sujet, visitez la [page du sujet](https://lilypond.community/t/table-des-matieres-en-colonnes/4978/20).

---

From: Ben via LilyPond <[email-masked]>
Date: Thu, 27 Mar 2025 20:39:11 +0000

J'ai le problème avec votre code, où j'ai remplacé les trois lignes height et mis un % sur le \tocAct, voir ci-dessous.

Après, c'est une question de temps: si quelqu'un trouve la solution en 5 minutes et que le code survit aux màj, autant utiliser le travail déjà fait, mais sinon, je préfère investir quelques heures en python que des semaines en scheme, d'autant que j'ai déjà programmé des indexes de cette manière et que cela fonctionne bien. 

\version "2.24.1"
% Voir https://lists.gnu.org/archive/html/lilypond-user-fr/2022-08/msg00074.html
% et https://gitlab.com/lilypond/lilypond/-/issues/6355
#(let ((default-table-of-contents make-table-of-contents-markup-list))
   (define-markup-list-command (table-of-contents layout props) ()
     (let* ((result (interpret-markup-list layout props (default-table-of-contents)))
            (alist (ly:output-def-lookup layout 'label-alist-table))
            (parent (ly:output-def-parent layout)))
       (when (not (null? parent))
         (ly:output-def-set-variable! parent 'label-alist-table alist))
       result)))

#(use-modules (ice-9 match))

#(define (group-to-fill-partial-sums lst weight threshold initial)
   (let loop ((lst lst)
              (i 0)
              (partial-sum (initial 0))
              (acc '()))
     (match lst
       (()
        (reverse! (map reverse! acc)))
       ((elt . rest)
        (let* ((elt-weight (weight elt))
               (new-sum (+ partial-sum elt-weight)))
          (cond
           ((null? acc)
            (loop rest i new-sum (list (list elt))))
           ((<= new-sum threshold)
            (loop rest i new-sum (cons (cons elt (car acc))
                                            (cdr acc))))
           (else
            (loop rest
                  (1+ i)
                  (+ (initial (1+ i))
                     elt-weight)
                  (cons (list elt)
                        acc)))))))))

#(define (index-map f . lsts)
   (let loop ((lsts lsts)
              (i 0))
     (if (any null? lsts)
         '()
         (cons (apply f i (map car lsts))
               (loop (map cdr lsts)
                     (1+ i))))))

#(ly:register-stencil-expression 'new-toc-group)
#(define-markup-command (new-toc-group layout props arg) (markup?)
   (let* ((stil (interpret-markup layout props arg))
          (expr (ly:stencil-expr stil))
          (x (ly:stencil-extent stil X))
          (y (ly:stencil-extent stil Y)))
     (ly:make-stencil `(new-toc-group ,expr)
                      x
                      y)))

#(define-markup-list-command (multicolumn-toc layout props columns) (index?)
   #:properties ((baseline-skip)
                 (padding 5)
                 (line-width))
   (let ((width (/ (- line-width (* padding (1- columns)))
                     columns))
 (height (- (ly:output-def-lookup layout 'paper-height) 30.0)))
     (let ((mkup (ly:output-def-lookup layout 'tocItemMarkup)))
       (ly:output-def-set-variable! layout 'tocItemMarkup (make-override-markup
                                                           `(line-width . ,width)
                                                           mkup)))
     (match-let*
           (((title . ungrouped-stils)
             (interpret-markup-list layout
                                    props
                                    (make-table-of-contents-markup-list)))
            (stils
             (let loop ((ungrouped-stils ungrouped-stils)
                        (group '())
                        (acc '()))
               (match ungrouped-stils
                 (()
                  (reverse!
                   (map (lambda (group-elts)
                          (let ((rev-group-elts (reverse! group-elts)))
                            (stack-stencils Y DOWN baseline-skip rev-group-elts)))
                        (cons group acc))))
                 ((stil . rest)
                  (match (ly:stencil-expr stil)
                    (('new-toc-group expr)
                     (let* ((x (ly:stencil-extent stil X))
                            (y (ly:stencil-extent stil Y))
                            (unwrapped (ly:make-stencil expr x y)))
                       (loop rest
                             (list unwrapped)
                             (cons group acc))))
                    (_
                     (loop rest
                           (cons stil group)
                           acc)))))))
            (split (group-to-fill-partial-sums
                    stils
                    (lambda (stil)
                      (+ (interval-length (ly:stencil-extent stil Y))
                         baseline-skip))
                    height
                    (let ((title-height (interval-length (ly:stencil-extent title Y))))
                      (lambda (i)
                        (if (< i columns)
                            title-height
                            0)))))
            (cols (group-to-fill-partial-sums
                   split
                   (const 1)
                   columns
                   (const 0))))
       (cons title
             (map (lambda (page-cols)
                    (apply ly:stencil-add
                           (index-map
                            (lambda (i col-stils)
                              (ly:stencil-translate-axis
                               (stack-stencils Y DOWN baseline-skip col-stils)
                               (* i (+ width padding))
                               X))
                            page-cols)))
                  cols)))))

\paper {
  ragged-last-bottom = ##t
  ragged-last = ##f
  %% Attention : s'il y a plusieurs éléments à l'intérieur du tocActMarkup,
  %% ne pas faire \new-toc-group { ... } mais \new-toc-group \line { ... }
  tocActMarkup = \markup \new-toc-group \line {
    \vspace #1
    \hspace #-4
    \italic \fromproperty #'toc:text
  }
  tocItemMarkup = \markup
  \fontsize #-2
  \fill-line {
    \fill-with-pattern #1.5 #CENTER .
    \line {
      \hspace #-6.5 %% Cancelling the first level's tocIndentMarkup
      \fromproperty #'toc:indent \fromproperty #'toc:text
      \hspace #2
    }
    \fromproperty #'toc:page
  }
  tocTitleMarkup =
  \markup {
    \column {
      \vspace #3
      \fill-line { \fontsize #9 "My Real Book" }
       \vspace #1
      \fill-line { \fontsize #3 "For C Instruments" }
       \vspace #2
    }
  }
}

tocAct =
#(define-music-function (label text) (symbol-list-or-symbol? markup?)
   (add-toc-item! 'tocActMarkup text label))

\bookpart {
  \paper {
    left-margin = 20
    right-margin = 15
  }
  \markuplist
  % les \override sont facultatifs
  \override #'(padding . 10)
  \override #'(baseline-skip . 1)
  \multicolumn-toc #4
}

\bookpart {
  $@(map (lambda (i)

> Le 27 mars 2025 à 21:23, Jean Abou Samra via LilyPond <[email-masked]> a écrit :
> 
> Pour poster dans ce sujet, visitez la page du sujet <https://lilypond.community/t/table-des-matieres-en-colonnes/4978/20>.
> 
> Pour poster dans ce sujet, visitez la page du sujet <https://lilypond.community/t/table-des-matieres-en-colonnes/4978/20>.
> 

---
Pour poster dans ce sujet, visitez la [page du sujet](https://lilypond.community/t/table-des-matieres-en-colonnes/4978/21).

---

From: Jean Abou Samra via LilyPond <[email-masked]>
Date: Thu, 27 Mar 2025 20:52:01 +0000

Là, c'est normal par contre : le code demande à ce que chaque groupe indivisible d'entrées de la table des matières (qui ne doit pas être séparé entre plusieurs colonnes) soit démarré par un `\new-toc-group`. Comme vous avez enlevé le `\tocAct` et que le `\new-toc-group` est dans le `tocActMarkup`, il n'y a plus de `\new-toc-group` du tout, donc non seulement la table des matières se retrouve sur la deuxième page, mais surtout elle ne se répartit plus en colonnes du tout, ce que vous pouvez régler en changeant le `tocItemMarkup = \markup` en `tocItemMarkup = \markup \new-toc-group` si vous n'avez pas comme Vincent de groupes indivisibles (comme les parties de différents instruments pour une même pièce).

---
Pour poster dans ce sujet, visitez la [page du sujet](https://lilypond.community/t/table-des-matieres-en-colonnes/4978/22).

---

From: Ben via LilyPond <[email-masked]>
Date: Fri, 28 Mar 2025 10:22:07 +0000

D'accord, alors j'ai essayé de modifier votre code, pour qu'il se rapproche du mien:

- j'ai effacé le \paper du début
- j'ai commenté les premières lignes qui ne changent rien à la compilation (ont-elles encore une utilité?)
- j'ai regroupé les instructions \paper de la fin et je les ai modifiées. 
- j'ai mis le \tocAct en commentaire et ajouté \new-to-group au tocItemMarkup
- j'ai ajouté un \paper avec un autre formatage

Cela donne le même résultat que dans mon code, avec un problème de chevauchement. 

Et si je veux activer le \toAct, je ne comprends pas comment je peux transposer la ligne  \tocAct #sym #(format #f "Pièce ~a" i) dans mon code, j'ai essayé probablement à tord avec \tocAct "act" "Titre".

J'ai aussi essayé (height (- (ly:output-def-lookup layout 'paper-height) 30.0))), mais cela ne résout pas le chevauchement.

\version "2.24.1"

% Voir https://lists.gnu.org/archive/html/lilypond-user-fr/2022-08/msg00074.html
% et https://gitlab.com/lilypond/lilypond/-/issues/6355
% #(let ((default-table-of-contents make-table-of-contents-markup-list))
%    (define-markup-list-command (table-of-contents layout props) ()
%      (let* ((result (interpret-markup-list layout props (default-table-of-contents)))
%             (alist (ly:output-def-lookup layout 'label-alist-table))
%             (parent (ly:output-def-parent layout)))
%        (when (not (null? parent))
%          (ly:output-def-set-variable! parent 'label-alist-table alist))
%        result)))
% 
% #(use-modules (ice-9 match))

tocAct =

#(set! paper-alist (cons '("Legal Landscape" . (cons (* 356 mm) (* 216 mm))) paper-alist))

\paper {
  #(set-paper-size "Legal Landscape")
  ragged-bottom = ##t
  print-page-number = ##f
  top-margin = 1\mm
  bottom-margin = 1\mm
  top-system-spacing.basic-distance = 1
  top-markup-spacing.basic-distance = 1
  left-margin = 7\mm
  right-margin = 7\mm
  inner-margin = 1\mm
  outer-margin = 1\mm
  binding-offset = 1\mm
}

\bookpart 
{
  \paper
  {
    oddHeaderMarkup = \markup "Test"
    evenHeaderMarkup = \oddHeaderMarkup
    oddFooterMarkup = ""
    evenFooterMarkup = ""
    %% Attention : s'il y a plusieurs éléments à l'intérieur du tocActMarkup,
    %% ne pas faire \new-toc-group { ... } mais \new-toc-group \line { ... }
    tocActMarkup =  \markup \new-toc-group \line { \large \bold \vspace #2 \fromproperty #'toc:text }  
  tocItemMarkup = \markup \new-toc-group  { \fromproperty #'toc:text   }
  tocTitleMarkup =  ""
}
\markuplist
% les \override sont facultatifs
\override #'(padding . 10)
\override #'(baseline-skip . 1)
\multicolumn-toc #4
}

\bookpart {
  $@(map (lambda (i)
  (let ((sym (gensym "act")))
  #{
     \tocAct #sym #(format #f "Pièce ~a" i)
    \tocItem #(list sym 'sheet) "Lead sheet"
    \tocItem #(list sym 'bass) "Bass line"
    c'
    #}))
  (iota 300 1))
}

---
Pour poster dans ce sujet, visitez la [page du sujet](https://lilypond.community/t/table-des-matieres-en-colonnes/4978/23).

---

From: Ben via LilyPond <[email-masked]>
Date: Tue, 01 Apr 2025 13:00:23 +0000

Finalement, j'ai écrit un script python pour générer ma table des matières.

Le rendu me convient bien, j'ai pu aussi solutionner qu'une catégorie ne s'affiche pas en fin de colonne, s'il n'y a pas au moins un élément en-dessous.

Et comme je compilais déjà le recueil avec un script, cela s'intègre de manière transparente. 

Ce n'est pas aussi élégant que le Scheme, mais pour avoir lu la documentation fort bien faite de Jean, le problème est qu'il manque toute l'intégration avec Lilypond. 

Or, vu la courbe d'apprentissage, je pense que cela ne vaut la peine que si l'on envisage de participer activement au développement de Lilypond.

---
Pour poster dans ce sujet, visitez la [page du sujet](https://lilypond.community/t/table-des-matieres-en-colonnes/4978/24).