6

I need a command which removes all following tokens which are digits, comma, spaces or newlines and stops if it encounters something else. I can do it by nesting a lot of \peek_charcode_remove_ignore_spaces:NTF, but is there a more elegant way to map e.g. over a clist?

\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\clist_const:Nn\c_uf_page_clist{1,2,3,4,5,6,7,8,9,0,{,}}
\cs_new:Nn\uf_eatline: {
   \peek_charcode_remove_ignore_spaces:NTF 0 { \uf_eatline: }
    {
     \peek_charcode_remove_ignore_spaces:NTF 1 { \uf_eatline: }
      {
       \peek_charcode_remove_ignore_spaces:NTF 6 { \uf_eatline: }
        {
         \peek_charcode_remove_ignore_spaces:NTF , { \uf_eatline: }
         { 
          %and more nesting ...          
         }
        }      
      } 
    }
}

\cs_set_eq:NN\eatline\uf_eatline:
\ExplSyntaxOff
\newcommand\see[2]{, \emph{see} #1}
\begin{document}

\begin{itemize}
\item Texta\eatline116, 
153
\item Textb\eatline\see{Texta}{162}
\end{itemize}

Wanted output:
\begin{itemize}
\item Texta

\item Textb\see{Texta}{162}
\end{itemize}


\end{document}
  • Do you expect something like {Whatever\eatline}? – egreg Jan 28 at 15:14
  • @egreg No. it is from an index, where I want to remove the page numbers (well probably I don't want it anymore, I think I simply misunderstood a request, but I would still be interested to see how to loop in such cases). – Ulrike Fischer Jan 28 at 15:23
6

If you don't expect \eatline to be called inside a group ending with } and you want to skip spaces, you can grab the next token(s) as an argument, examine it and decide.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\eatline}{m}
 {
  \uf_eatline:n { #1 }
 }

\cs_new_protected:Nn \uf_eatline:n
 {
  \regex_match:nnTF { [0-9,] } { #1 }
   {
    \uf_eatline:n
   }
   { #1 }
 }
\ExplSyntaxOff

\newcommand\see[2]{, \emph{see} #1}

\begin{document}

\begin{itemize}
\item Texta\eatline116, 
153
\item Textb\eatline\see{Texta}{162}
\end{itemize}

Wanted output:
\begin{itemize}
\item Texta

\item Textb\see{Texta}{162}
\end{itemize}

\end{document}

If the token is not a digit or a comma, it is reinserted back, otherwise another token is examined.

Something like {abc} would be reinserted without braces, but it doesn't seem a problem in this context.

The problem with } could be treated at the beginning with a single \peek_catcode:NTF check.

enter image description here

  • 1
    That's naturally a much saner way to solve the concrete problem - I wonder why I thought that I need to peek ahead. But I guess it also means that there is no (easy) way to use a \peek command in a loop over a clist or something like this? – Ulrike Fischer Jan 28 at 15:52
  • @UlrikeFischer No, but something about this has been discussed in the list. – egreg Jan 28 at 15:54
3

If you're not going to have page numbers larger than 2^31-1 then this might work.

The \uf_eatline: command starts a group, then sets the \catcode of ,, , and ^^M to 9, then uses a primitive integer assignment to consume the remaining numbers (expanding tokens in this process) until something that is not a number is found. Finally, the catcodes are put back to normal with \afterassignment\endgroup. This should work even if no numbers follow the \eatline function and in the {Whatever\eatline} case that egreg mentioned.

\documentclass{article}
\usepackage{expl3}

\ExplSyntaxOn

\cs_set_eq:NN \uf_after_assignment:N \tex_afterassignment:D
\int_new:N \l_uf_tmpa_int
\cs_new:Nn \uf_eatline:
  {
    \group_begin:
      \char_set_catcode_ignore:n { `\, }
      \char_set_catcode_ignore:n { `\  }
      \char_set_catcode_ignore:n { `\^^M }
      \tex_endlinechar:D = 32
      \uf_after_assignment:N
    \group_end:
      \l_uf_tmpa_int = 0
  }

\cs_set_eq:NN\eatline\uf_eatline:
\ExplSyntaxOff

\newcommand\see[2]{, \emph{see} #1}
\begin{document}

\begin{itemize}
\item Texta\eatline116, 
153
\item Textb\eatline\see{Texta}{162}
\end{itemize}

Wanted output:
\begin{itemize}
\item Texta

\item Textb\see{Texta}{162}
\end{itemize}

\end{document}

enter image description here

  • 1
    Nice trick but a bit too low-level to count as "elegant" ;-) – Ulrike Fischer Jan 28 at 21:13
  • @UlrikeFischer Elegance is relative :) But I agree, it's pretty low-level and it has the integer limitation :/ – Phelype Oleinik Jan 28 at 21:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.