2010-03-05 8 views
8

Tengo un documento LaTeX que es básicamente un gran entorno enumerate, con algunos cientos de elementos. Quiero poder emitir un comando comoSeleccione solo algunos elementos de una lista en LaTeX

\printitems{2,5,12,45-48} 

que dará salida solo a los elementos solicitados.

Un comando similar \onlyslides es una parte de slides.cls, pero no puedo entender qué sucede allí y adaptarlo a mis necesidades.

puedo sustituir la lista de item 's con una lista de entornos, como

\begin{myitem} 
... 
\end{myitem} 

\begin{myitem} 
... 
\end{myitem} 

con un \newcounter etc. si ayuda a lograr mi objetivo — ser capaz de imprimir sólo algunos elementos con números dados sin cortar y pegar. Puedo tener los elementos en un archivo y el comando \printitems en otro, si es necesario.

No puedo poner los números en el archivo — el archivo está en constante cambio, y necesito la enumeración automática.

Respuesta

1

La parte difícil (o más bien, no trivial) de hacer esto es analizar la entrada separada por comas. Varios paquetes han implementado esto; quizás la implementación de lipsum es lo suficientemente simple como para extraerlo para sus propósitos.

Después de eso, solo es cuestión de pasar un contador cada vez que toca un elemento y mostrar el contenido o no dependiendo de cómo se analiza la lista de comandos.

+0

La parte difícil consiguió recientemente discutió aquí: http://stackoverflow.com/questions/2402354/split-comma-separated-parameters-in-latex –

+0

El bucle en sí es fácil; ver mi última respuesta para un ejemplo del análisis de rango que es un poco difícil escribir desde cero. –

1

primer lugar el uso de la función foreach para dividir una lista separada por comas dada en

Split comma-separated parameters in LaTeX

Se puede simplificar mediante la eliminación del parámetro constante # 2 usado.

después definir los elementos de la siguiente manera (esta es la manera de construir un hash en TeX):

\@namedef{item_1}{This is item 1} 
\@namedef{item_2}{This is item 2} 
\@namedef{item_3}{This is item 3} 

definir una función que se utilizará en foreach:

\def\printSingleItem#1{% 
    \@ifundefined{item_#1}{% 
     \PackageWarning{MyPackage}{Undefined Item #1}% 
    }{% 
     \@nameuse{item_#1}% This can be more fancy here, using formatting etc. 
    }% 
} 

Última definir printitems

\def\printitems#1{\foreach{\printSingleItem}{#1}} 
+1

Ah, no vi que necesita números dinámicos. Supongo que esta respuesta no te está ayudando realmente. Lo siento. –

+0

Casi allí. Dos cosas: 1) ¿puedo tener algunos cientos de estos nombres? Sé que algunos recursos en TeX son bastante limitados. 2) ¿Puedo construirlos desde un contador, como \ def \ myitem # 1 {\ namedef {item_ \ themycounter} {# 1}}? (Porque debo tener una numeración automática.) – AVB

+0

No puedo responder la segunda pregunta (pero creo que debería funcionar), pero la primera definitivamente funciona (tengo 5500 para indexar correos electrónicos en una lista de correo) –

3

Bien, entonces, aquí vamos.

Como puede ver a continuación, la parte principal de la codificación es analizar la entrada de rango separado por comas. Después de eso, es fácil verificar qué número estás haciendo en el entorno de enumeración (o lo que sea) y mostrar el elemento de manera condicional.

Puede copiar y pegar a partir de ahora en una .tex documento vacío y que sólo se debe trabajar:


%% En primer lugar, estoy usando el paquete expl3 hacer la mayor parte de esta codificación. Hace algunas cosas más fáciles.

 
\documentclass{article} 
\usepackage{expl3} 
\ExplSyntaxOn 

%% Aquí está la función de bucle sobre comas lista de entrada gama como -2,4-6,8,10-:

 
\prg_new_conditional:Nnn \i_in_range:nn {TF,T,F} { 
    \bool_set_false:N \l_tmpa_bool 
    \clist_map_inline:nn {#2} { 
    \parse_range:w ##1 - \q_marker - \q_nil #1 \q_nil 
    } 
    \bool_if:NTF \l_tmpa_bool \prg_return_true: \prg_return_false: 
} 

%% Y la función auxiliar para volver si el argumento de entrada se encuentra dentro de la gama:

\cs_set:Npn \parse_range:w #1 - #2 - #3 \q_nil #4 \q_nil { 
    \tl_if_eq:nnTF {\q_marker}{#2}{ 
    \intexpr_compare:nT {#4=#1} {\bool_set_true:N \l_tmpa_bool} 
    }{ 
    \tl_if_empty:nTF {#2}{ 
     \intexpr_compare:nT {#4>=#1} {\bool_set_true:N \l_tmpa_bool} 
    }{ 
     \tl_if_empty:nTF {#1}{ 
     \intexpr_compare:nT {#4<=#2} {\bool_set_true:N \l_tmpa_bool} 
     }{ 
     \intexpr_compare:nT {#4>=#1} { 
      \intexpr_compare:nT {#4<=#2} 
      {\bool_set_true:N \l_tmpa_bool} 
     } 
     } 
    } 
    } 
} 
\cs_generate_variant:Nn \i_in_range:nnTF {nV} 

%% Este es el comando a la entrada de cada elemento de la lista:

 
\newcommand\numitem[1]{ 
    \i_in_range:nVTF {\value{enumi}+1}{\l_item_range_tl}{ 
    \item #1 
    }{ 
    \stepcounter{enumi} 
    } 
} 

%% Y entornos enumerados con un argumento de rango:

 
\newenvironment{someitems}[1]{ 
    \tl_set:Nn \l_item_range_tl {#1} 
    \begin{enumerate} 
}{ 
    \end{enumerate} 
} 
\ExplSyntaxOff 

%% Por último, un ejemplo:

 
\begin{document} 
\begin{someitems}{-2,4-6,8,10-} 
\numitem{one}\numitem{two}\numitem{three} 
\numitem{four}\numitem{five}\numitem{six} 
\numitem{seven}\numitem{eight}\numitem{nine} 
\numitem{ten}\numitem{eleven} 
\end{someitems} 
\end{document} 
+0

Después de instalar la paquete expl3 - ¡funciona! – AVB

+0

Me alegra oírlo :) –

Cuestiones relacionadas