7

I wonder if there is a reverse version of input.

For instance, I maintenance a list of things.

list.txt
\myitem{20080103}{a}
\myitem{20090202}{b}

I could do \input{list.txt} and define \myitem in one file to generate an itemized list.

But now I want to list those in the reverse order in another file in table format. I can redefine \myitem, but is there an easy way to \input in the reverse order? i.e.

\myitem{20090202}{b}
\myitem{20080103}{a}
jub0bs
  • 58,916
rukh
  • 73

2 Answers2

8

The following example redefines macro \myitem to build the reversed list in \rlist, which is then used instead of \input:

\documentclass{article}
\usepackage{etoolbox}

\newcommand*{\myitem}[2]{#1&#2\\}

\begin{document}
\begin{tabular}{ll}
  \hline
  \input{list.txt}
  \hline
\end{tabular}

\begingroup
  \def\rlist{}%
  \renewcommand*{\myitem}[2]{%
    \pretocmd\rlist{\myitem{#1}{#2}}{}{}%
  }%
  \input{list.txt}
  \global\let\rlist=\rlist
\endgroup
\begin{tabular}{ll}
  \hline
  \rlist
  \hline
\end{tabular}
\end{document}

Result

Heiko Oberdiek
  • 271,626
3

An exercise in expl3 programming.

\begin{filecontents*}{\jobname.list}
\myitem{20080103}{a}
\myitem{20090202}{b}
\end{filecontents*}

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\inputlist}{sm}
 {
  \IfBooleanTF{#1}
   {
    \cs_set_eq:NN \__egreg_list_put:Nn \seq_put_left:Nn
    \egreg_print_list:n { #2 }
   }
   {
    \cs_set_eq:NN \__egreg_list_put:Nn \seq_put_right:Nn
    \egreg_print_list:n { #2 }
   }
 }

\seq_new:N \l__egreg_list_input_seq
\ior_new:N \l__egreg_list_read_stream

\cs_new_protected:Npn \egreg_print_list:n #1
 {
  \seq_clear:N \l__egreg_list_input_seq
  \ior_open:Nn \l__egreg_list_read_stream { #1 }
  \ior_map_inline:Nn \l__egreg_list_read_stream
   {
    \__egreg_list_put:Nn \l__egreg_list_input_seq { ##1 }
   }
  \seq_use:Nn \l__egreg_list_input_seq { }
 }
\ExplSyntaxOff
\newcommand{\myitem}[2]{\printdate#1&#2\\}
\newcommand{\printdate}[8]{#1#2#3#4-#5#6-#7#8}

\begin{document}

\begin{tabular}{ll}
\inputlist{\jobname.list}
\end{tabular}

\bigskip

\begin{tabular}{ll}
\inputlist*{\jobname.list}
\end{tabular}

\end{document}

The input file is read line by line and each line is stored in a sequence for subsequent use. The * variant reverses the order, because the sequence is built backwards.

Several refinements are possible.

enter image description here

egreg
  • 1,121,712