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}
  • 2
    Trivial on the Linux command line: tac <list.txt >list-reverse.txt – Heiko Oberdiek Apr 21 '14 at 20:52
  • Welcome to TeX.SX! A tip: You can use backticks ` to mark your inline code as I did in my edit. – jub0bs Apr 21 '14 at 21:21
  • Thanks! I think I will just do tac in \immediate\write18. – rukh Apr 22 '14 at 21:03
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

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

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.