Pagine

sabato 7 febbraio 2009

Codice di programmazione dentro un file Latex/LyX

Premessa

Può essere necessario, lavorando con LaTeX o LyX inserire all'interno del testo del documento alcune parti nelle quali si vuole mantenere la formattazione originale senza alcun intervento del motore LaTeX.
Un classico esempio è l'inserimento di codice di programmazione dentro un documento LaTeX.
Questo può presentare spazi o tabulazioni che verrebbero ignorati oppure simboli come le parentesi graffe, per fare un esempio, che sarebbero male interpretate dal motore generando errori.

Prima soluzione

Per risolvere questo problema, in prima istanza, si può utilizzare l'ambiente verbatim.
Questo ambiente consente di inserire del codice o qualsiasi testo mantenendo la formattazione originale.
Un esempio banale può essere:

\begin{verbatim}

int i=0;
int c=0;
for(i=0;i<=33;i++){
print "Prova di valore su I": $i;
}
\end{verbatim}

In questo modo tutto ciò che sta dentro l'ambiente verbatim non viene analizzato dal motore che lo riproporrà così come lo abbiamo scritto.
Questo ambiente va benissimo in svariate occasioni ma di seguito vedremo una soluzione più accattivante.

Soluzione più elegante

Recentemente, su forum del Gruppo italiano utilizzatori LaTeX, ho scoperto l'esistenza del ambiente lstlisting che ha proprio lo scopo di permettere l'inserimento di codice dentro un documento.
Premetto che consiglio la lettura del documento per altro molto scorrevole.
Potete trovarlo cliccando qui
Il pacchetto va scaricato opportunamente ma non si ritiene questa la sede per spiegare il metodo dato che cambia a seconda della distribuzione LaTeX e dal sistema operativo.
La prima cosa da fare è aggiungere il pacchetto nel preambolo:

\usepackage{listings} %Per inserire codice
\usepackage[usenames]{color} %Per permettere la colorazione dei caratteri

A questo punto possiamo procedere come segue nel testo:

\begin{lstlisting}[caption={Programma Blink, "Hello World!"}]
CODICE PROGRAMMA...
\end{lstlisting}

Il pacchetto, però, se utilizzato semplicemente in questo modo non darebbe molto valore aggiunto se confrontato con verbatim.
Al contrario da a mio avviso tre grossi vantaggi:
  • Permette di evidenziare le parole chiave all'interno del listato
  • Permette la creazione di nuovi ambienti ad hoc
  • Permette la creazione di codice all'interno di oggetti mobili
Nel esempio che segue, creiamo grazie al pacchetto, un nuovo ambiente e nel testo si andrà ad utilizzare tutte le volte necessarie.

\lstnewenvironment{codice_arduino}[1][]
{\lstset{basicstyle=\small\ttfamily, columns=fullflexible,
keywordstyle=\color{red}\bfseries, commentstyle=\color{blue},
language=C++, basicstyle=\small,
numbers=left, numberstyle=\tiny,
stepnumber=2, numbersep=5pt, frame=shadowbox, float=*, #1}}{}

Questo codice può essere inserito nel preambolo e permette di creare un ambiente nel quale:
  • il carattere è più piccolo del resto del corpo e con carattere appartenente alla famiglia ttf \lstset{basicstyle=\small\ttfamily;
  • con le colonne allineate a sinistra e non giustificate in modo da mantenere l'allineamento del codice rispetto tabulazioni o spazi columns=fullflexible;
  • le parole chiave siano di colore rosso e grassetto keywordstyle=\color{red}\bfseries;
  • i commenti siano colore blue commentstyle=\color{blue};
  • il linguaggio sia il C++ language=C++,
  • che ci siano i numeri sulla sinistra del listato più piccoli rispetto al listato numbers=left, numberstyle=\tiny, stepnumber=2, numbersep=5pt,
  • che ci sia una cornice tutto intorno al listato frame=shadowbox,
  • che il listato sia flottante rispetto al testo float=*,
  • dove l'utente possa eventualmente specificare altre opzioni come, ad esempio, la didascalia #1
Il codice che seguirà nel testo permette di utilizzare questo nuovo ambiente che ho chiamato codice_arduino in maniera trasparente ed eventualmente posso aggiungere valori opzionali.
Segue codice esplicativo:

\begin{codice_arduino}[caption={Programma Blink, "Hello World!"}]
/* Blinking LED
* ------------
*/

int ledPin = 13; // LED connected to digital pin 13

void setup()
{
pinMode(ledPin, OUTPUT); // sets the digital pin as output
}

void loop()
{
digitalWrite(ledPin, HIGH); // sets the LED on
delay(1000); // waits for a second
digitalWrite(ledPin, LOW); // sets the LED off
delay(1000); // waits for a second
}
\end{codice_arduino}

Il risultato è il seguente:

6 commenti:

  1. Ciao!
    Grazie per la guida!

    Spero di ricevere risposta anche se il post è di qualche anno fa.

    Ho dei piccoli problemi.
    Ho copiato il codice che hai messo a disposizione per la modifica del comportamento, ma il testo del codice non mi appare della famiglia ttf e la colorazione non segue il linguaggio R (ho modificato language=R).

    Credo di non aver capito cosa scrivere in
    \usepackage[usenames]{color}

    Grazie per l'attenzione
    Francesca

    RispondiElimina
    Risposte
    1. Come non detto ;)
      Ho risolto, c'è un piccolo errore nel codice postato.
      C'è due volte \basicstyle.
      1' -> \basicstyle=\small\ttfamily
      2' -> \basicstyle=\small
      In compilazione ovviamente prendeva il secondo caso e quindi non metteva il ttfamily!

      Un saluto a tutti ;)

      Elimina
    2. Grazie a te per la segnalazione e soprattutto la correzione. Appena ho un attimo sistemò il codice :-)

      Elimina
  2. Ciao grazie del post, ma inserendolo in una parte di testo me lo posiziona sempre in alto alla pagina, spazio in fondo c'è ma lui mi mette lo stesso prima il codice e poi il testo invece dovrebbe essere il testo e dopo nello spazio che rimane(c'è nè abbastanza) il codice..

    RispondiElimina
  3. Salve, ma la "caption" non può comparire sotto il codice e non sopra?
    Grazie

    RispondiElimina
  4. Ciao!
    Ho usato il newenvironment e l'aspetto del mio codice è notevolmente migliorato, ma continuo ad avere il probelma delle bad boxes. Il mio codice ha righe molto lunghe e latex non va a capo.
    Esiste una soluzione?

    RispondiElimina