0

I want to write a document with a couple tables, where the entries of the tables are sorted alphabetically. I found a solution here:

Order table by row alphabeticaly

But when I want more than one table in my document, the entries of previous tables are also used in the new table. How can I alter the code, such that I can have more than one table in the document?

Here a minimal working example:

\documentclass[]{scrbook} 
\usepackage{geometry}
\usepackage{longtable}
\usepackage{xparse}     

\begin{document}
\ExplSyntaxOn
\NewDocumentCommand{\name}{mmm}
 {
  \seq_gput_right:Nn \g_alex_name_seq { \__alex_name_entry:nn {#1}{#2}{#3} }
 }
\seq_new:N \g_alex_name_seq
\tl_new:N  \g__alex_name_tablebody_tl

\NewDocumentCommand{\sortnames}{}
 {
  \cs_gset_eq:NN \__alex_name_entry:nn \use_i:nn
  \seq_gsort:Nn \g_alex_name_seq
   {
    \alex_name_if_before:ffTF { ##1 } { ##2 }
     { \sort_return_same: }
     { \sort_return_swapped: }
   }
  \cs_gset_eq:NN \__alex_name_entry:nn \alex_name_print:nn
  \tl_gset:Nx \g__alex_name_tablebody_tl
   {
    \seq_use:Nn \g_alex_name_seq { \\ \hline }
   }
 }
\NewExpandableDocumentCommand{\printnames}{}
 {
  \tl_use:N \g__alex_name_tablebody_tl
 }

\prg_new_conditional:Nnn \alex_name_if_before:nn { p,T,F,TF }
 {% I hope the LaTeX3 police won't catch me
  \int_compare:nTF { \pdftex_strcmp:D { #1 } { #2 } < 0 }
   {
    \prg_return_true:
   }
   {
    \prg_return_false:
   }
 }
\cs_generate_variant:Nn \alex_name_if_before:nnTF { ff }

\cs_new:Nn \alex_name_print:nn { #1 & #2 &  }
\ExplSyntaxOff

%First Table
\name{Jerimir}{Some Project}{B}
\name{Emma}{Second Project }{A}
\sortnames
\begin{longtable}{
 |
 p{\dimexpr.2\textwidth-2\tabcolsep-1.5\arrayrulewidth}
 |
 p{\dimexpr.6\textwidth-2\tabcolsep-1.5\arrayrulewidth}
 |
 p{\dimexpr.1\textwidth-2\tabcolsep-1.5\arrayrulewidth}
 |
} 
\hline
\textbf{Name} & \textbf{Project} & Grade\\ \hline
\printnames \\ \hline
\end{longtable}

% Second Table
\name{Aaro}{New Project}{A}
\name{Zion}{Other Project}{C}
\sortnames
\begin{longtable}{
 |
 p{\dimexpr.2\textwidth-2\tabcolsep-1.5\arrayrulewidth}
 |
 p{\dimexpr.6\textwidth-2\tabcolsep-1.5\arrayrulewidth}
 |
 p{\dimexpr.1\textwidth-2\tabcolsep-1.5\arrayrulewidth}
 |
} 
\hline
\textbf{Name} & \textbf{Project} & Grade  \\ \hline
\printnames \\ \hline
\end{longtable}

\end{document}

The names of the first table are also in the second table: enter image description here

2
  • 2
    Welcome to TeX.SE! Unfortunately, it's impossible for us to tell you how to alter the code where we don't have the code you're using. Please post a minimal working example. Commented Feb 13, 2020 at 18:59
  • The question now includes a minimal working example
    – Niels Wer
    Commented Feb 15, 2020 at 20:03

1 Answer 1

1

If you use LuaLaTeX, the following could work. As you can see, \sortnames is no longer necessary. Moreover, the name list cleans itself with each print and you only need the first \hline (although you can include it into the Lua macro if you want)

%!TEX program = lualatex
\documentclass[]{scrbook}
\usepackage{luacode} 
\usepackage{geometry}
\usepackage{longtable}
\usepackage{xparse}     
\begin{luacode*}
    nametable = nametable or {}
    function addnames(A, B, C)
        table.insert(nametable, A..[[ & ]]..B..[[ & ]]..C..[[\\ \hline ]])
    end

    function clearnames(table)
        for k in pairs (table) do
            table [k] = nil
        end
    end
\end{luacode*}
\def\name#1#2#3{\directlua{addnames("#1", "#2", "#3")}}
\def\printnames{%
    \directlua{
    table.sort(nametable) 
    tex.sprint(table.concat(nametable," "))
    clearnames(nametable)
    }
}
\begin{document}
%First Table
\name{Jerimir}{Some Project}{B}
\name{Emma}{Second Project }{A}

\begin{longtable}{
 |
 p{\dimexpr.2\textwidth-2\tabcolsep-1.5\arrayrulewidth}
 |
 p{\dimexpr.6\textwidth-2\tabcolsep-1.5\arrayrulewidth}
 |
 p{\dimexpr.1\textwidth-2\tabcolsep-1.5\arrayrulewidth}
 |
} 
\hline
\textbf{Name} & \textbf{Project} & Grade\\ \hline
\printnames 
\end{longtable}

% Second Table
\name{Aaro}{New Project}{A}
\name{Zion}{Other Project}{C}

\begin{longtable}{
 |
 p{\dimexpr.2\textwidth-2\tabcolsep-1.5\arrayrulewidth}
 |
 p{\dimexpr.6\textwidth-2\tabcolsep-1.5\arrayrulewidth}
 |
 p{\dimexpr.1\textwidth-2\tabcolsep-1.5\arrayrulewidth}
 |
} 
\hline
\textbf{Name} & \textbf{Project} & Grade  \\ \hline
\printnames
\end{longtable}

\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .