Manual de LaTeX/Listados de código/Listados con listings

El paquete listings, modo de uso editar

El paquete listings es el de uso habitual para la adición de código fuente de múltiples lenguajes de programación en un documento. Su funcionamiento es parecido al paquete verbatim.

Para utilizar este paquete, se debe utilizar:

\usepackage{listings}

Este paquete permite el resaltado de los lenguajes de programación más comunes, además de ser configurable. Lo único que se necesita es utilizar el entorno lstlisting:

\begin{lstlisting}
El código se inserta aquí.
\end{lstlisting}

También es posible, y es muy útil, insertar desde un fichero de código fuente. Esto facilita al máximo las modificaciones y pruebas del código a insertar mientras aún lo estás editando ya que las modificaciones que se hagan en el código se reflejarán de forma automática en el documento LaTeX (principio DRY):


\lstinputlisting{nombre_fichero_codigo.py}

En este ejemplo se insertaría un fichero de código en Python. Lo relevante es que se puede incluir cualquier fichero indicando su nombre completo. El lenguaje que se reconoce no depende de la extensión del fichero ni de ninguna indicación interna al mismo, sino que depende de los ajustes que haya establecido para este paquete en el documento. Por ejemplo, para especificar que se trata del lenguaje Python es necesario expresar lo siguiente:

\lstinputlisting[language=Python]{nombre_fichero_codigo.py}

También es posible seleccionar qué líneas se desean incluir:


\lstinputlisting[language=Python, firstline=37, lastline=45]{nombre_fichero_codigo.py}

Lo que es muy útil para mostrar en el documento solamente aquello que sea relevante del código fuente. Si se omiten alguno de estos parámetros, firstline o lastline, que se deben mostrar todas las líneas desde el comienzo o hasta el final, respectivamente.

El siguiente es un documento completo que inserta un programa en Pascal:

\documentclass{article}
\usepackage{listings}             % Incluye el paquete listings
\usepackage[spanish]{babel}
\usepackage[T1]{fontenc}

\begin{document}
\lstset{language=Pascal}          % Establece el lenguaje por defecto. Se puede cambiar para cada bloque de código insertado

\begin{lstlisting}[frame=single]  % Inicia el bloque de código
for i:=maxint to 0 do
begin
{ no hace nada }
end;
Write("Insensible a las mayúsculas");
Write("en las palabras reservadas de Pascal.");
\end{lstlisting}

\end{document}


 

Lenguajes soportados editar

El paquete listings es capaz de resaltar los siguientes lenguajes:

ABAP2,4, ACSL, Ada4, Algol4, Ant, Assembler2,4, Awk4, bash, Basic2,4, C#5, C++4, C4, Caml4, Clean, Cobol4, Comal, csh, Delphi, Eiffel, Elan, erlang, Euphoria, Fortran4, GCL, Gnuplot, Haskell, HTML, IDL4, inform, Java4, JVMIS, ksh, Lisp4, Logo, Lua2, make4, Mathematica1,4, Matlab, Mercury, MetaPost, Miranda, Mizar, ML, Modelica3, Modula-2, MuPAD, NASTRAN, Oberon-2, Objective C5 , OCL4, Octave, Oz, Pascal4, Perl, PHP, PL/I, Plasm, POV, Prolog, Promela, Python, R, Reduce, Rexx, RSL, Ruby, S4, SAS, Scilab, sh, SHELXL, Simula4, SQL, tcl4, TeX4, VBScript, Verilog, VHDL4, VRML4, XML, XSLT.

Para algunos de ellos, se permiten diferentes dialectos. Para más información, utiliza la documentación que viene con el paquete, debería estar en tu distribución, bajo el nombre listings-*.dvi.


Notas
  1. Soporta Mathematica solamente si se trata de un fichero en texto plano. No se pueden incluir ficheros *.NB., sin embargo, Mathematica puede exportar ficheros fuente formateados para su uso en LaTeX.
  2. En estos lenguajes es obligatorio especificar el dialecto del lenguaje (por ejemplo: language={[x86masm]Assembler}).
  3. Modelica se soporta mediante el paquete dtsyntax disponible aquí.
  4. Para estos lenguajes hay múltiples dialectos soportados: C, por ejemplo, puede ser ANSI, Handel, Objective y Sharp. Ver p. 12 del manual de listings para una introducción a esto.
  5. Definido como un dialecto de otro lenguaje.

Parámetros de configuración editar

Se pueden modificar los parámetros que afectan a cómo se muestra el código. Estos parámetros de configuración se pueden insertar en cualquier parte del documento, antes o después de \begin{document}). A continuación se muestra un ejemplo con todos los parámetros que se puede utilizar como base para modificarlo según las necesidades. El significado de cada parámetro se explica en la propia línea como un comentario.

\documentclass[a4paper,12pt]{article}
\usepackage[spanish]{babel}
\usepackage[T1]{fontenc}

\usepackage{listings}
\usepackage{color}

\definecolor{miverde}{rgb}{0,0.6,0}
\definecolor{migris}{rgb}{0.5,0.5,0.5}
\definecolor{mimalva}{rgb}{0.58,0,0.82}

\lstset{ %
  backgroundcolor=\color{white},   % Indica el color de fondo; necesita que se añada \usepackage{color} o \usepackage{xcolor}
  basicstyle=\footnotesize,        % Fija el tamaño del tipo de letra utilizado para el código
  breakatwhitespace=false,         % Activarlo para que los saltos automáticos solo se apliquen en los espacios en blanco
  breaklines=true,                 % Activa el salto de línea automático
  captionpos=b,                    % Establece la posición de la leyenda del cuadro de código
  commentstyle=\color{miverde},    % Estilo de los comentarios
  deletekeywords={...},            % Si se quiere eliminar palabras clave del lenguaje
  escapeinside={\%*}{*)},          % Si quieres incorporar LaTeX dentro del propio código
  extendedchars=true,              % Permite utilizar caracteres extendidos no-ASCII; solo funciona para codificaciones de 8-bits; para UTF-8 no funciona. En xelatex necesita estar a true para que funcione.
  frame=single,	                   % Añade un marco al código
  keepspaces=true,                 % Mantiene los espacios en el texto. Es útil para mantener la indentación del código(puede necesitar columns=flexible).
  keywordstyle=\color{blue},       % estilo de las palabras clave
  language=Pascal,                 % El lenguaje del código
  otherkeywords={*,...},           % Si se quieren añadir otras palabras clave al lenguaje
  numbers=left,                    % Posición de los números de línea (none, left, right).
  numbersep=5pt,                   % Distancia de los números de línea al código
  numberstyle=\small\color{migris}, % Estilo para los números de línea
  rulecolor=\color{black},         % Si no se activa, el color del marco puede cambiar en los saltos de línea entre textos que sea de otro color, por ejemplo, los comentarios, que están en verde en este ejemplo
  showspaces=true,                % Si se activa, muestra los espacios con guiones bajos; sustituye a 'showstringspaces'
  showstringspaces=false,          % subraya solamente los espacios que estén en una cadena de esto
  showtabs=true,                  % muestra las tabulaciones que existan en cadenas de texto con guión bajo
  stepnumber=2,                    % Muestra solamente los números de línea que corresponden a cada salto. En este caso: 1,3,5,...
  stringstyle=\color{mimalva},     % Estilo de las cadenas de texto
  tabsize=2,	                   % Establece el salto de las tabulaciones a 2 espacios
  title=\lstname                   % muestra el nombre de los ficheros incluidos al utilizar \lstinputlisting; también se puede utilizar en el parámetro caption
}
\begin{document}

\begin{lstlisting}[frame=single]  % Inicia el bloque de código
  for i:=maxint to 0 do
  begin
  { 	comentario
      %* \textbf{texto en negrita} *)
    no	hace nada }
  end;
  Write('Insensible a las mayúsculas');
  Write('en las palabras reservadas de Pascal.');
\end{lstlisting}
\end{document}
escapeinside

El parámetro escapeinside necesita explicación. La opción escapeinside={A}{B} define los delimitadores de inicio y fin que se utilizarán para permitir la introducción de código LaTeX entre el código, en este caso, que todo el código entre "A" y "B" será interpretado como código LaTeX utilizando el estilo vigente en el entorno listings. En este ejemplo, se interpretan como código LaTeX a partir de %*, hasta que se encuentre el cierre con *).

Hay muchas más opciones, se recomienda revisar la documentación oficial.

Definición de estilos editar

Este paquete permite definir estilos. Es decir, perfiles que definen un conjunto de parámetros.

Por ejemplo:

\lstdefinestyle{customc}{
  belowcaptionskip=1\baselineskip,
  breaklines=true,
  frame=L,
  xleftmargin=\parindent,
  language=C,
  showstringspaces=false,
  basicstyle=\footnotesize\ttfamily,
  keywordstyle=\bfseries\color{green!40!black},
  commentstyle=\itshape\color{purple!40!black},
  identifierstyle=\color{blue},
  stringstyle=\color{orange},
}

\lstdefinestyle{customasm}{
  belowcaptionskip=1\baselineskip,
  frame=L,
  xleftmargin=\parindent,
  language=[x86masm]Assembler,
  basicstyle=\footnotesize\ttfamily,
  commentstyle=\itshape\color{purple!40!black},
}

\lstset{escapechar=@,style=customc}

En este ejemplo, se definen dos estilos y se establece uno de ellos 'customc' como el estilo por defecto y la @ como el carácter de escape.

Se puede utilizar así:

\begin{lstlisting}
#include <stdio.h>
#define N 10
/* Comentario en un
 * bloque*/

int main()
{
    int i;

    // Line comment.
    puts("¡Hola Mundo!");
    
    for (i = 0; i < N; i++)
    {
        puts("¡LaTeX también es genial para los programadores!");
    }

    return 0;
}
\end{lstlisting}

\lstinputlisting[caption=Scheduler, style=customc]{hello.c}

El trozo de código C se imprimirá como:

 

El código se ha compilado con XeLaTeX para facilitar que las exclamaciones funcionen en el trozo de código C.


Inclusión de ficheros automática editar

Si se tiene un conjunto de ficheros de código fuente para incluir, se puede uno encontrar repitiendo una y otra vez el mismo texto LaTeX Aquí es donde las macros muestran toda su potencia:

\newcommand{\includecode}[2][c]{\lstinputlisting[caption=#2, escapechar=, style=custom#1]{#2}<!---->}
% ...

\includecode{sched.c}
\includecode[asm]{sched.s}
% ...

\lstlistoflistings

Con este ejemplo, se crea un comando para facilitar al máximo la inclusión de código. Se establece un estilo por defecto para que sea customc. Todos los listados tendrán su nombre el el título: no hay que escribir el nombre del fichero dos veces gracias a la macro.

Problemas de codificación (¡¡¡IMPORTANTE EN ESPAÑOL!!!) editar

En el ejemplo anterior, para evitar el problema de codificación que surge con LaTeX y el uso de utf8 dentro de listings, se ha compilado los ejemplos con XeLaTeX.

El problema es que, por defecto, listings no soporta codificación multibyte para el código fuente.

Para poder manejar UTF-8, resulta necesario decirle a listings cómo interpretar los caracteres especiales que surjan entre el código fuente, mediante la definición de los mismos.

Esto se puede hacer de la siguiente forma:

\lstset{literate=
  {á}{{\'a}}1 {é}{{\'e}}1 {í}{{\'i}}1 {ó}{{\'o}}1 {ú}{{\'u}}1
  {Á}{{\'A}}1 {É}{{\'E}}1 {Í}{{\'I}}1 {Ó}{{\'O}}1 {Ú}{{\'U}}1
  {à}{{\`a}}1 {è}{{\`e}}1 {ì}{{\`i}}1 {ò}{{\`o}}1 {ù}{{\`u}}1
  {À}{{\`A}}1 {È}{{\'E}}1 {Ì}{{\`I}}1 {Ò}{{\`O}}1 {Ù}{{\`U}}1
  {ä}{{\"a}}1 {ë}{{\"e}}1 {ï}{{\"i}}1 {ö}{{\"o}}1 {ü}{{\"u}}1
  {Ä}{{\"A}}1 {Ë}{{\"E}}1 {Ï}{{\"I}}1 {Ö}{{\"O}}1 {Ü}{{\"U}}1
  {â}{{\^a}}1 {ê}{{\^e}}1 {î}{{\^i}}1 {ô}{{\^o}}1 {û}{{\^u}}1
  {Â}{{\^A}}1 {Ê}{{\^E}}1 {Î}{{\^I}}1 {Ô}{{\^O}}1 {Û}{{\^U}}1
  {ã}{{\~a}}1 {}{{\~e}}1 {ĩ}{{\~i}}1 {õ}{{\~o}}1 {ũ}{{\~u}}1
  {Ã}{{\~A}}1 {}{{\~E}}1 {Ĩ}{{\~I}}1 {Õ}{{\~O}}1 {Ũ}{{\~U}}1
  {œ}{{\oe}}1 {Œ}{{\OE}}1 {æ}{{\ae}}1 {Æ}{{\AE}}1 {ß}{{\ss}}1
  {ű}{{\H{u}}}1 {Ű}{{\H{U}}}1 {ő}{{\H{o}}}1 {Ő}{{\H{O}}}1
  {ç}{{\c c}}1 {Ç}{{\c C}}1 {ø}{{\o}}1 {å}{{\r a}}1 {Å}{{\r A}}1
  {}{{\euro}}1 {£}{{\pounds}}1 {«}{{\guillemotleft}}1
  {»}{{\guillemotright}}1 {ñ}{{\~n}}1 {Ñ}{{\~N}}1 {¿}{{?`}}1 {¡}{{!`}}1 
}

La tabla anterior cubre la mayoría de los caracteres de los idiomas latinos:

Para una explicación más detallada del uso de literate se puede revisar la sección 6.4 en la Documentación de listings.

Otra posibilidad es sustituir el paquete \usepackage{listings} (en el preámbulo) por \usepackage{listingsutf8}.

Personalización de los títulos editar

Se pueden tener unos títulos (caption y/o title) muy avanzados gracias al paquete caption. Veamos un ejemplo de uso con listings.

\usepackage{caption}
\usepackage{listings}

\DeclareCaptionFont{white}{ \color{white} }
\DeclareCaptionFormat{listing}{
  \colorbox[cmyk]{0.43, 0.35, 0.35,0.01 }{
    \parbox{\textwidth}{\hspace{15pt}#1#2#3}
  }
}
\captionsetup[lstlisting]{ format=listing, labelfont=white, textfont=white, singlelinecheck=false, margin=0pt, font={bf,footnotesize} }

% ...

\lstinputlisting[caption=My caption]{sourcefile.lang}