Tikz: Numero di elementi in una lista separata da virgole

  • Creatore
    Topic
  • #118297
    Up
    0
    Down
    ::


    Ho scritto una funzione che distribuisce in orizzontale gli elementi passati in un parametro.

    Esempio minimale:
    `
    \documentclass[a4paper,12pt]{article}
    \usepackage[utf8]{inputenc}
    \usepackage{tikz}

    \newcommand{\distribuzione}[3]{% Distribuzione di elementi su un asse
    \def \dimx{#1}
    \def \numpunti{#2}
    \def \labpunti{#3}
    \begin{tikzpicture}
    \pgfmathparse{\dimx*2 / (\numpunti+1)} \let\largx\pgfmathresult
    \foreach \li [count = \i] in \labpunti{
    \draw (\i*\largx-\dimx, -.2) — (\i*\largx-\dimx, .2)
    node [above] {\(\li\)};}
    \draw [->] (-\dimx, 0) — (\dimx, 0);
    \end{tikzpicture}
    }

    \begin{document}

    \distribuzione{6}{5}{a, b, c, d, e}

    \end{document}

    `

    Fa quello che voglio, ma io vorrei semplificare la funzione passandole solo il primo e l’ultimo parametro, infatti il secondo non è altro che il numero di elementi contenuti nella lista seguente.
    Sarebbe più logico chiamare la funzione distribuzione passandole solo il primo e l’ultimo parametro:

    `
    \distribuzione{6}{a, b, c, d, e}
    `

    e la funzione dovrebbe arrangiarsi a trovare quanti elementi sono contenuti nel secondo parametro.

    Ho cercato in Internet, ma ho trovato soluzioni che mi sono sembrate contorte.

    Non esiste in LaTeX / Tikz una funzione predefinita che data una lista separata da virgole, restituisca la sua lunghezza?

    C’è un modo semplice per farlo?

    Grazie per l’attenzione e per le eventuali indicazioni.

    Daniele

Visualizzazione 3 filoni di risposte
  • Autore
    Risposte
    • #118298
      Up
      0
      Down
      ::


      Ho trovato questi due modi per calcolare la lunghezza di una lista separata da virgole:

      `
      \makeatletter
      \newcommand{\lengtha}[1]{%
      \@tempcnta\z@
      \@for\@tempa:=#1\do{\advance\@tempcnta\@ne}
      \the\@tempcnta
      }
      \makeatother

      \usepackage{xstring}
      \newcommand{\lengthb}[1]{%
      \StrCount{#1,}{,}%
      }

      \begin{document}
      Con la funzione \verb|\lengtha|

      \def \mylist{0,1,54,1,3}
      \{\mylist\} has length \lengtha{\mylist}.

      \def \mylist{,,,}
      \{\mylist\} has length \lengtha{\mylist}.

      \vspace{1em}
      Con la funzione \verb|\lengthb|

      \def \mylist{0,1,54,1,3, 7}
      \{\mylist\} has length \lengthb{\mylist}.

      \def \mylist{,,}
      \{\mylist\} has length \lengthb{\mylist}.
      \end{document}
      `

      Il primo mi sembra una formula magica il secondo richiede la lettura di una libreria…

      Ora provo ad applicarli al mio problema originale.

    • #118299
      Up
      0
      Down
      ::


      Le due funzioni precedenti funzionano nel semplice documento precedente, ma non vanno quanto tento di usarle per risolvere il mio problema:

      `
      \documentclass{article}

      \usepackage{comment}
      \usepackage[utf8]{inputenc}
      \usepackage{tikz}

      \makeatletter
      \newcommand{\lengtha}[1]{%
      \@tempcnta\z@
      \@for\@tempa:=#1\do{\advance\@tempcnta\@ne}
      \the\@tempcnta
      }
      \makeatother

      \usepackage{xstring}
      \newcommand{\lengthb}[1]{%
      \StrCount{#1,}{,}%
      }

      \newcommand{\distribuzione}[2]{% Distribuzione di elementi su un asse
      \def \dimx{#1}
      \def \labpunti{#2}
      \def \numpunti{\lengtha{#2}}
      % \def \numpunti{\lengthb{#2}}
      \begin{tikzpicture}
      \node at (0, 2) {\numpunti};
      \pgfmathparse{\dimx*2 / (\numpunti+1)} \let\largx\pgfmathresult;
      \foreach \li [count = \i] in \labpunti{
      \draw (\i*\largx-\dimx, -.2) — (\i*\largx-\dimx, .2)
      node [above] {\(\li\)};}
      \draw [->] (-\dimx, 0) — (\dimx, 0);
      \end{tikzpicture}
      }
      `

      Se uso `lengtha` ottengo il seguente messaggio:

      `
      ! Missing \endcsname inserted.
      `

      Se uso `lengthb` ottengo il seguente messaggio:

      `
      ! Undefined control sequence.
      \xs_StrCount__ …f \xs_arg_ii {#2}\edef \xs_call
      {\noexpand \xs_testopt {\n…
      `

      E a questo punto la mia ignoranza di LaTeX e la cripticità dei messaggi di errore hanno il sopravvento.

      Qualche suggerimento?

      Grazie per l’attenzione e una buona giornata.

    • #118300
      Up
      0
      Down
      ::


      Ti serve contare il numero di elementi in una lista di oggetti separati da virgole? Si può fare facilmente con [tt]expl3[/math].

      `
      \documentclass[a4paper,12pt]{article}
      \usepackage{tikz}
      \usepackage{xparse}

      \ExplSyntaxOn
      \NewExpandableDocumentCommand{\lengthofclist}{m}
      {
      \clist_count:n { #1 }
      }
      \ExplSyntaxOff

      \newcommand{\distribuzione}[2]{% Distribuzione di elementi su un asse
      \begin{tikzpicture}
      \pgfmathsetmacro\largx{(#1)*2 / (\lengthofclist{#2}+1)}
      \foreach \li [count = \i] in {#2} {
      \draw (\i*\largx-#1, -.2) — (\i*\largx-#1, .2) node [above] {\(\li\)};
      }
      \draw [->] (-#1, 0) — (#1, 0);
      \end{tikzpicture}%
      }

      \begin{document}

      \distribuzione{6}{a, b, c, d, e}

      \distribuzione{6}{a, b, c, d}

      \end{document}
      `

      [attachment=2457]Screenshot2020-07-05at12.37.36.png[/attachment]

      Non vedo motivo di definire [tt]\dimx[/tt] e [tt]\labpunti[/tt].

      Perché il tentativo con [tt]xstring[/tt] non funziona? Perché [tt]\StrCount[/tt] non è espandibile, mentre [tt]\clist_count:n[/tt] lo è.

      Ciao
      Enrico

      Attachments:
      You must be logged in to view attached files.
    • #118301
      robitex
      Amministratore del forum
        Up
        0
        Down
        ::


        Ciao.
        Peccato non avere il tempo di presentare una soluzione in LuaLaTeX.
        Così, lascio un promemoria.
        R.

    Visualizzazione 3 filoni di risposte
    • Devi essere connesso per rispondere a questo topic.

    Go to top