Estrazione iniziale da una parola

  • Creatore
    Topic
  • #15016
    DMW
      Up
      0
      Down
      ::


      Salve,

      Mi serve una macro che, data una parola, possa estrarre la sua iniziale.

      Mi spiego meglio:

      Ho una parola, esempio Italia, memorizzata in un comando
      `
      \newcommand{\parola}{Italia}`

      Ora, utilizzando questa macro, il risultato deve essere I oppure i.
      `
      \estraiiniziale{\parola}`

      Ciao

      Andrea

    Visualizzazione 15 filoni di risposte
    • Autore
      Risposte
      • #15017
        Up
        0
        Down
        ::

        Mi serve una macro che, data una parola, possa estrarre la sua iniziale.

        Mi spiego meglio:

        Ho una parola, esempio Italia, memorizzata in un comando
        `
        \newcommand{\parola}{Italia}`

        Ora, utilizzando questa macro, il risultato deve essere I oppure i.
        `
        \estraiiniziale{\parola}`

        `\makeatletter
        \def\estraiiniziale#1{\expandafter\separa#1\@del}
        \def\separa#1#2\@del{#1}
        \makeatother`
        Probabilmente in LaTeX c’è già qualcosa di simile, ma non ho voglia di andarlo a cercare. 🙂

        Come funziona?

        La macro \separa ha due argomenti, il primo non delimitato, il secondo delimitato da \@del. Supponiamo di scrivere \estraiiniziale{\parola}. Questo viene sostituito da
        `\expandafter\separa\parola\@del`
        A questo punto viene espanso \expandafter che provoca l’espansione di \parola; la lista di token diventa
        `\separa Italia\@del`
        Il primo token che segue \separa è il primo argomento, tutto il resto, fino a \@del, il secondo.

        Ciao
        Enrico

      • #15018
        DMW
          Up
          0
          Down
          ::

          Mi serve una macro che, data una parola, possa estrarre la sua iniziale.

          Mi spiego meglio:

          Ho una parola, esempio Italia, memorizzata in un comando
          `
          \newcommand{\parola}{Italia}`

          Ora, utilizzando questa macro, il risultato deve essere I oppure i.
          `
          \estraiiniziale{\parola}`

          `\makeatletter
          \def\estraiiniziale#1{\expandafter\separa#1\@del}
          \def\separa#1#2\@del{#1}
          \makeatother`
          Probabilmente in LaTeX c’è già qualcosa di simile, ma non ho voglia di andarlo a cercare. 🙂

          Come funziona?

          La macro \separa ha due argomenti, il primo non delimitato, il secondo delimitato da \@del. Supponiamo di scrivere \estraiiniziale{\parola}. Questo viene sostituito da
          `\expandafter\separa\parola\@del`
          A questo punto viene espanso \expandafter che provoca l’espansione di \parola; la lista di token diventa
          `\separa Italia\@del`
          Il primo token che segue \separa è il primo argomento, tutto il resto, fino a \@del, il secondo.

          Ciao
          Enrico

          Perfetto, grazie.

          Ciao

          Andrea

        • #15019
          Up
          0
          Down
          ::

          `\makeatletter
          \def\estraiiniziale#1{\expandafter\separa#1\@del}
          \def\separa#1#2\@del{#1}
          \makeatother`
          Probabilmente in LaTeX c’è già qualcosa di simile, ma non ho voglia di andarlo a cercare. 🙂

          Perfetto, grazie.

          Naturalmente la parte di servizio c’era già in LaTeX:
          `\makeatletter
          \newcommand\estraiiniziale[1]{\expandafter\@car#1\@nil}
          \newcommand\togliiniziale[1]{\expandafter\@cdr#1\@nil}
          \makeatother`
          Ciao
          Enrico

        • #15020
          DMW
            Up
            0
            Down
            ::


            Grazie ancora.

            Approfitto delle tue capacità mistiche.
            Per prima cosa, si possono modificare, rispettivamente, le macro precedenti in modo da estrarre e togliere le prime n lettere?

            Inoltre, ti chiedo se c’è un modo per trasformare le parole come segue.

            Vorrei mettere in risalto le prime tre lettere della parola
            da Italia a Italia, oppure, ancora meglio, vorrei una macro che esalti le prime n lettere.
            Esempio:
            `
            \esaltaprime[5]{Italia}
            `
            mi deve dare Italia

            e un’altra macro che esalti le ultime n.
            Esempio
            `
            \esaltaultime[4]{Italia}
            `
            mi dere fornire Italia

            Scusami se abuso della tua pazienza e delle tue capacità.

            Ciao

            Andrea

          • #15021
            Up
            0
            Down
            ::

            Grazie ancora.

            Approfitto delle tue capacità mistiche.
            Per prima cosa, si possono modificare, rispettivamente, le macro precedenti in modo da estrarre e togliere le prime n lettere?

            Inoltre, ti chiedo se c’è un modo per trasformare le parole come segue.

            Vorrei mettere in risalto le prime tre lettere della parola
            da Italia a Italia, oppure, ancora meglio, vorrei una macro che esalti le prime n lettere.
            Esempio:
            `
            \esaltaprime[5]{Italia}
            `
            mi deve dare Italia

            e un’altra macro che esalti le ultime n.
            Esempio
            `
            \esaltaultime[4]{Italia}
            `
            mi dere fornire Italia

            `\documentclass[a4paper]{article}

            \makeatletter
            \newcount\split@count

            \def\@split#1#2{\split@count=#1\relax
            \def\split@start{}%
            \edef\split@end{#2}%
            \loop\ifnum\split@count>0
            \edef\split@start{\split@start\expandafter\@car\split@end\@nil}%
            \edef\split@end{\expandafter\@cdr\split@end\@nil}%
            \ifx\split@end\empty
            \split@count=0
            \else
            \advance\split@count-1
            \fi
            \repeat}

            \def\@reverse#1{%
            \edef\@temp{#1}%
            \def\@esrever{}%
            \loop\unless\ifx\@temp\empty
            \edef\@esrever{\expandafter\@car\@temp\@nil\@esrever}%
            \edef\@temp{\expandafter\@cdr\@temp\@nil}%
            \repeat}

            \newcommand{\esaltaprime}[2][0]{%
            \@split{#1}{#2}%
            \textbf{\split@start}{\split@end}}

            \newcommand{\esaltaultime}[2][0]{%
            \@reverse{#2}\@split{#1}{\@esrever}%
            \@reverse{\split@end}\@esrever%
            \@reverse{\split@start}\textbf{\@esrever}}
            \makeatother

            \def\parola{Italia}

            \begin{document}

            \esaltaprime[3]{\parola}

            \esaltaprime[7]{\parola}

            \esaltaprime[7]{Cercopiteco}

            \esaltaprime{Italia}

            \esaltaultime[4]{Cercopiteco}

            \end{document}`
            Limitazioni: il secondo argomento deve essere una stringa di caratteri ASCII a 7 bit oppure un comando la cui espansione sia tale.

            Sto lavorandoci su per eliminare la limitazione e accettare input a 8 bit

            Ciao
            Enrico

          • #15022
            Up
            0
            Down
            ::


            Eliminate alcune restrizioni. I caratteri accentati possono essere usati nell’argomento di \esaltaprime e \esaltaultime, ma non al primo posto; in tal caso occorre “nascondere” l’accento in una macro, si veda l’esempio con \accento; attenzione: non con UTF8, spiacente. 🙂 L’attento lettore noterà l’uso delle primitive di e-TeX \detokenize, \scantokens e \unless. 🙂
            `\documentclass[a4paper]{article}
            \usepackage[latin1]{inputenc}

            \makeatletter
            \newcount\split@count

            \def\@split#1#2{\split@count=#1\relax
            \def\split@start{}%
            \edef\split@end{\detokenize\expandafter{#2}}%
            \loop\ifnum\split@count>0
            \edef\split@start{\split@start\expandafter\@car\split@end\@nil}%
            \edef\split@end{\expandafter\@cdr\split@end\@nil}%
            \ifx\split@end\empty
            \split@count=0
            \else
            \advance\split@count-1
            \fi
            \repeat}

            \def\@reverse#1{%
            \edef\@temp{\detokenize\expandafter{#1}}%
            \def\@esrever{}%
            \loop\unless\ifx\@temp\empty
            \edef\@esrever{\expandafter\@car\@temp\@nil\@esrever}%
            \edef\@temp{\expandafter\@cdr\@temp\@nil}%
            \repeat}

            \newcommand{\esaltaprime}[2][0]{%
            \@split{#1}{#2}%
            \textbf{\scantokens\expandafter{\split@start}\unskip}%
            \scantokens\expandafter{\split@end}\unskip}

            \newcommand{\esaltaultime}[2][0]{%
            \@reverse{#2}\@split{#1}{\@esrever}%
            \@reverse{\split@end}\scantokens\expandafter{\@esrever}\unskip%
            \@reverse{\split@start}\textbf{\scantokens\expandafter{\@esrever}\unskip}}
            \makeatother

            \newcommand\parola{Italia}
            \newcommand\accento{àncora}

            \begin{document}
            \esaltaprime[3]{\accento}

            \esaltaprime[4]{ancóra} Ciao

            \esaltaprime[3]{\parola} Ciao

            \esaltaprime[7]{\parola}

            \esaltaprime[7]{Cercopiteco}

            \esaltaprime{Italia}

            \esaltaultime[4]{Cercopiteco}

            \esaltaultime[2]{lassù}

            \end{document}`
            A parte le questioni più TeXniche, la faccenda è abbastanza semplice. La macro \@split raccoglie i primi n caratteri (n è il valore dato come primo argomento) uno alla volta e definisce le due macro \split@start e \split@end, che contengono prima e seconda parte della stringa data come secondo argomento. Se n è maggiore della lunghezza della stringa, il ciclo si interrompe e la seconda parte sarà vuota.

            Per evidenziare gli ultimi n token della stringa come si fa? Si applica \@split alla stringa rovesciata. Il funzionamento di \@reverse è facile: aggiungo, ovviamente da destra a sinistra, a \@esrever un carattere alla volta, prendendo quello iniziale e ripetendo finché la stringa diventa vuota.

            Lascio come esercizio di scrivere la stessa cosa con una macro ricorsiva. 😀

            Ciao
            Enrico

          • #15023
            Up
            0
            Down
            ::


            Che ne dici di un altro pacchetto?

          • #15024
            DMW
              Up
              0
              Down
              ::

              Eliminate alcune restrizioni. I caratteri accentati possono essere usati nell’argomento di \esaltaprime e \esaltaultime, ma non al primo posto; in tal caso occorre “nascondere” l’accento in una macro, si veda l’esempio con \accento; attenzione: non con UTF8, spiacente. 🙂 L’attento lettore noterà l’uso delle primitive di e-TeX \detokenize, \scantokens e \unless. 🙂
              `\documentclass[a4paper]{article}
              \usepackage[latin1]{inputenc}

              \makeatletter
              \newcount\split@count

              \def\@split#1#2{\split@count=#1\relax
              \def\split@start{}%
              \edef\split@end{\detokenize\expandafter{#2}}%
              \loop\ifnum\split@count>0
              \edef\split@start{\split@start\expandafter\@car\split@end\@nil}%
              \edef\split@end{\expandafter\@cdr\split@end\@nil}%
              \ifx\split@end\empty
              \split@count=0
              \else
              \advance\split@count-1
              \fi
              \repeat}

              \def\@reverse#1{%
              \edef\@temp{\detokenize\expandafter{#1}}%
              \def\@esrever{}%
              \loop\unless\ifx\@temp\empty
              \edef\@esrever{\expandafter\@car\@temp\@nil\@esrever}%
              \edef\@temp{\expandafter\@cdr\@temp\@nil}%
              \repeat}

              \newcommand{\esaltaprime}[2][0]{%
              \@split{#1}{#2}%
              \textbf{\scantokens\expandafter{\split@start}\unskip}%
              \scantokens\expandafter{\split@end}\unskip}

              \newcommand{\esaltaultime}[2][0]{%
              \@reverse{#2}\@split{#1}{\@esrever}%
              \@reverse{\split@end}\scantokens\expandafter{\@esrever}\unskip%
              \@reverse{\split@start}\textbf{\scantokens\expandafter{\@esrever}\unskip}}
              \makeatother

              \newcommand\parola{Italia}
              \newcommand\accento{àncora}

              \begin{document}
              \esaltaprime[3]{\accento}

              \esaltaprime[4]{ancóra} Ciao

              \esaltaprime[3]{\parola} Ciao

              \esaltaprime[7]{\parola}

              \esaltaprime[7]{Cercopiteco}

              \esaltaprime{Italia}

              \esaltaultime[4]{Cercopiteco}

              \esaltaultime[2]{lassù}

              \end{document}`
              A parte le questioni più TeXniche, la faccenda è abbastanza semplice. La macro \@split raccoglie i primi n caratteri (n è il valore dato come primo argomento) uno alla volta e definisce le due macro \split@start e \split@end, che contengono prima e seconda parte della stringa data come secondo argomento. Se n è maggiore della lunghezza della stringa, il ciclo si interrompe e la seconda parte sarà vuota.

              Per evidenziare gli ultimi n token della stringa come si fa? Si applica \@split alla stringa rovesciata. Il funzionamento di \@reverse è facile: aggiungo, ovviamente da destra a sinistra, a \@esrever un carattere alla volta, prendendo quello iniziale e ripetendo finché la stringa diventa vuota.

              Lascio come esercizio di scrivere la stessa cosa con una macro ricorsiva. 😀

              Ciao
              Enrico

              Sei un mago. 😀 😀

              Fai una cosa, aggiungi queste ultime cinque macro, così il servizio è completo:
              `
              \estraiprime[n]{} \estraiultime[n]{}
              `
              Poi le complementari
              `
              \togliprime[n]{} \togliultime[n]{}
              `

              ed infine

              `
              \inverti{}% inverte l'ordine da parola a alorap, questa mi è venuta in mente ora.
              `

              Ciao e grazie ancora

              Andrea

              PS: sono d’accordo con Lapo, quando hai tempo potresti creare un altro utilissimo pacchetto.

            • #15025
              DMW
                Up
                0
                Down
                ::


                Enrico,

                Ho modificato le tue macro e sono arrivato qui:
                `
                \makeatletter
                ……
                \newcommand{\estraiprime}[2][0]{%
                \@split{#1}{#2}%
                \scantokens\expandafter{\split@start}\unskip%
                }
                \newcommand{\estraiultime}[2][0]{%
                \@reverse{#2}\@split{#1}{\@esrever}%
                \@reverse{\split@start}\scantokens\expandafter{\@esrever}\unskip}

                \newcommand{\togliprime}[2][0]{%
                \@split{#1}{#2}%
                \scantokens\expandafter{\split@end}\unskip}

                \newcommand{\togliultime}[2][0]{%
                \@reverse{#2}\@split{#1}{\@esrever}%
                \@reverse{\split@end}\scantokens\expandafter{\@esrever}\unskip%
                }
                \makeatother`

                Indica se c’è qualche correzione da fare
                Resta in ballo la macro \inverti

                Ciao

                Andrea

              • #15026
                Up
                0
                Down
                ::

                Enrico,

                Ho modificato le tue macro e sono arrivato qui:
                `
                \makeatletter
                ……
                \newcommand{\estraiprime}[2][0]{%
                \@split{#1}{#2}%
                \scantokens\expandafter{\split@start}\unskip%
                }
                \newcommand{\estraiultime}[2][0]{%
                \@reverse{#2}\@split{#1}{\@esrever}%
                \@reverse{\split@start}\scantokens\expandafter{\@esrever}\unskip}

                \newcommand{\togliprime}[2][0]{%
                \@split{#1}{#2}%
                \scantokens\expandafter{\split@end}\unskip}

                \newcommand{\togliultime}[2][0]{%
                \@reverse{#2}\@split{#1}{\@esrever}%
                \@reverse{\split@end}\scantokens\expandafter{\@esrever}\unskip%
                }
                \makeatother`

                Indica se c’è qualche correzione da fare
                Resta in ballo la macro \inverti

                Versione senza accenti:
                `\newcommand{\inverti}[1]{\@reverse{#1}\@esrever}`
                Versione con accenti:
                `\newcommand{\inverti}[1]{%
                \@reverse{#1}\scantokens\expandafter{\@esrever}\unskip}`
                Ciao
                Enrico

              • #15027
                DMW
                  Up
                  0
                  Down
                  ::


                  Perfetto,

                  Grazie mille per la disponibilità.

                  Andrea

                • #15028
                  DMW
                    Up
                    0
                    Down
                    ::


                    Riprendo questo topic perché mi servono altre funzioni.

                    \esaltacarattere che si comporti in questo modo:
                    `
                    \esaltacarattere[3]{Italia}`

                    mi deve dare It\textbf{a}lia. Cioè identico a \esaltaprime ma deve esaltare sono il carattere numero 3, cioè la a.

                    E poi \estraicarattere
                    `
                    \estraicarattere[3]{Italia}`

                    che mi deve dare a cioè la lettera numero 3.

                    Ciao

                    Andrea

                  • #15029
                    Up
                    0
                    Down
                    ::

                    Riprendo questo topic perché mi servono altre funzioni.

                    \esaltacarattere che si comporti in questo modo:
                    `\esaltacarattere[3]{Italia}`
                    mi deve dare It\textbf{a}lia. Cioè identico a \esaltaprime ma deve esaltare sono il carattere numero 3, cioè la a.

                    E poi \estraicarattere
                    `\estraicarattere[3]{Italia}`
                    che mi deve dare a cioè la lettera numero 3.

                    Lo dico sempre che non ti applichi! 😀
                    `\newcommand\esaltacarattere[2][1]{%
                    \count@=#1\relax
                    \advance\count@-1\relax
                    \@split{\the\count@}{#2}%
                    \split@start\esaltaprime[1]{\split@end}}

                    \newcommand\estraicarattere[2][1]{%
                    \count@=#1\relax
                    \advance\count@-1\relax
                    \@split{\the\count@}{#2}%
                    \estraiprime[1]{\split@end}}`
                    Ovviamente danno errore se cerchi di eseguire le operazioni su una lettera oltre il termine della parola. Puoi curare questo modificando la definizione di \@split:
                    `\def\@split#1#2{\split@count=#1\relax
                    \def\split@start{}%
                    \edef\split@end{\detokenize\expandafter{#2}\noexpand\empty}%
                    \loop\ifnum\split@count>0
                    \edef\split@start{\split@start\expandafter\@car\split@end\@nil}%
                    \edef\split@end{\expandafter\@cdr\split@end\@nil}%
                    \ifx\split@end\empty
                    \split@count=0
                    \GenericError{\space\space\space\@spaces\@spaces\@spaces}
                    {Splitting error}
                    {You probably went beyond the string length.}
                    {The number you gave is too big for the requested operation}%
                    \else
                    \advance\split@count-1
                    \fi
                    \repeat}`
                    Naturalmente anche \esaltaprime[7]{Italia} darà errore, adesso.

                    Ciao
                    Enrico

                  • #15030
                    DMW
                      Up
                      0
                      Down
                      ::


                      Che vuoi farci, sono un testone 😀

                      Grazie tante.

                    • #15031
                      DMW
                        Up
                        0
                        Down
                        ::


                        Prof,

                        In riferimento alle macro precedenti, quelle senza errore, è possibile includere anche gli spazi?
                        Esempio
                        `
                        \esaltaprime[5]{Io sono}
                        `

                        mi deve esaltare le prime 5, inclusi, o esclusi, gli spazi che restano invariati.

                        Cioè mi deve dare Io sono o Io sono

                        Analogamente le altre.

                        Non mi dire che non mi applico perché non ho idea di come si faccia.:oops:

                        Ciao

                        Andrea

                      • #15032
                        Up
                        0
                        Down
                        ::

                        Prof,

                        In riferimento alle macro precedenti, quelle senza errore, è possibile includere anche gli spazi?
                        Esempio
                        `
                        \esaltaprime[5]{Io sono}
                        `

                        mi deve esaltare le prime 5, inclusi, o esclusi, gli spazi che restano invariati.

                        Cioè mi deve dare Io sono o Io sono

                        Analogamente le altre.

                        Non mi dire che non mi applico perché non ho idea di come si faccia.:oops:

                        Trattare con gli spazi è mooooolto complicato. Una soluzione per includere spazi fra le lettere da esaltare è di usare ~. Per non includerli devi avere pazienza.

                        Ciao
                        Enrico

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

                    Go to top