Select only some items from a list in LaTeX

给你一囗甜甜゛ 提交于 2019-12-23 08:40:09

问题


I have a LaTeX document which is basically one big enumerate environment, with a few hundreds of items. I want to be able to issue a command like

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

which will output only the requested items.

A similar command \onlyslides is a part of slides.cls, but I cannot figure out what goes on there and adapt it to my needs.

I can replace the list of item's with a list of environments, like

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

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

with a \newcounter etc. if it helps to achieve my purpose — being able to print only some items with given numbers without cut-and-pasting. I can have the items in one file, and the \printitems command in another, if needed.

I can not put the numbers in the file — the file is constantly changing, and I need the automatic enumeration.


回答1:


Alright, then, here we go.

As you can see below, the main part of the coding is parsing the comma separated range input. After that, it's easy to check what number you're up to in the enumerate environment (or whatever) and conditionally display the item.

You can copy and paste from here on into an empty .tex document and it should just work:


%% First of all, I'm using the expl3 package to do most of this coding. Makes some things easier.

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

%% Here's the function to loop over comma-list range input like -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:
}

%% And the auxiliary function to return whether the input argument is contained within the range:

\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}

%% This is the command to input each item of your list:

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

%% And the enumerate environment with a range argument:

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

%% Finally, an example:

\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}



回答2:


The difficult (or rather, non-trivial) part of doing this is parsing the comma-separated input. Several packages have implemented this; perhaps lipsum's implementation is simple enough to extract for your purposes.

After that, it's just a matter of stepping a counter every time you hit an item and either display the contents or not depending on how the comma-list is parsed.




回答3:


First use the foreach function to split a comma separated list given in

Split comma-separated parameters in LaTeX

You can simplify it by removing the constant parameter #2 used.

Then define your items as following (this is the way to build a hash in TeX):

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

Define a function to be used in foreach:

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

Last define printitems

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


来源:https://stackoverflow.com/questions/2389081/select-only-some-items-from-a-list-in-latex

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!