按字母顺序对表格进行排序

按字母顺序对表格进行排序

我想编写一个包含几个表格的文档,其中表格的条目按字母顺序排序。我在这里找到了一个解决方案:

按行的字母顺序排列表格

但是当我想在文档中放置多个表格时,新表格中也会使用先前表格的条目。我该如何修改代码,以便文档中可以放置多个表格?

这是一个最小的工作示例:

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

第一个表的名称也出现在第二个表中: 在此处输入图片描述

答案1

如果您使用 LuaLaTeX,则以下内容可以工作。如您所见,\sortnames不再需要。此外,每次打印时名称列表都会自行清理,您只需要第一个\hline(尽管您可以根据需要将其包含在 Lua 宏中)

%!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}

在此处输入图片描述

相关内容