对自定义命令创建的元素列表进行排序

对自定义命令创建的元素列表进行排序

为了得到这个结果

在此处输入图片描述

我写了这个命令:

\newlength{\boldAcrwidth}
\setlength{\boldAcrwidth}{2cm}

\NewDocumentCommand{\boldAcr}{m >{\SplitList{ }}m}{%
    \makebox[\boldAcrwidth][l]{\bfseries\textit{\MakeUppercase{#1}}}%
    \ProcessList{#2}{\boldAcrFirst}%
    \unskip
}
\NewDocumentCommand{\boldAcrFirst}{m}{%
    \boldAcrFirstAux#1 % we want a space
}
\NewDocumentCommand{\boldAcrFirstAux}{m}{%
    \textbf{\MakeUppercase{#1}}%
}

\begin{flushleft}
        \boldAcr{owasp}{open web application security project} \\
        \boldAcr{asvs}{application security verification standard}\\
        \boldAcr{dbms}{database management system}\\
        \boldAcr{sqlia}{structured query language injection attack}\\
        \boldAcr{ldap}{lightweight directory access protocol}\\
\end{flushleft}

有没有办法修改它以便根据首字母缩略词按字母顺序对元素进行排序?

答案1

这是实现此目的的方法。每次调用都会将\boldAcr一个项目添加到seq包含首字母缩略词和含义的变量中。在\end定义环境的 中,对seqvar 进行排序(使用来自这个答案-- 同样的注意事项适用)然后使用 打印\boldAcroPut,这与您之前定义的相同。

在此处输入图片描述

\documentclass{article}

\usepackage{xparse}

\newlength{\boldAcrwidth}
\setlength{\boldAcrwidth}{2cm}

\ExplSyntaxOn
\cs_if_exist:NTF \__str_if_eq:nn
  { \cs_new_eq:NN \sctale_str_if_eq:nn \__str_if_eq:nn } % TexLive 2018 onwards
  { \cs_new_eq:NN \sctale_str_if_eq:nn \__str_if_eq_x:nn } % Previous versions (TeXLive 2017 at least)
\cs_generate_variant:Nn \sctale_str_if_eq:nn { oo }
\cs_new:Npn \__sctale_acro:w #1 \q_mark #2 \q_stop {#1}
\seq_new:N \l__sctale_acro_seq
\NewDocumentEnvironment { acroenv } { }
  { \seq_clear:N \l__sctale_acro_seq }
  {
    \seq_sort:Nn \l__sctale_acro_seq
      {
        \int_compare:nNnTF
          {
            \sctale_str_if_eq:oo
              { \__sctale_acro:w ##1 \q_stop }
              { \__sctale_acro:w ##2 \q_stop }
          }
            < 0
          { \sort_return_same: }
          { \sort_return_swapped: }
      }
    \seq_map_function:NN \l__sctale_acro_seq \__sctale_put_acro:n
  }
\cs_new:Npn \__sctale_put_acro:n #1 { \__sctale_put_acro:w #1 \q_stop }
\cs_new:Npn \__sctale_put_acro:w #1 \q_mark #2 \q_stop
  { \boldAcroPut{#1}{#2} }
\NewDocumentCommand { \boldAcr }{ m >{\SplitList{~}} m }
  { \seq_put_right:Nn \l__sctale_acro_seq { #1 \q_mark {#2} } }
\ExplSyntaxOff

\NewDocumentCommand{\boldAcroPut}{mm}{%
  \noindent
  \makebox[\boldAcrwidth][l]{\bfseries\textit{\MakeUppercase{#1}}}%
  \ProcessList{#2}{\boldAcrFirst}%
  \unskip\par%
}
\NewDocumentCommand{\boldAcrFirst}{m}{%
  \boldAcrFirstAux#1 % we want a space
}
\NewDocumentCommand{\boldAcrFirstAux}{m}{%
  \textbf{\MakeUppercase{#1}}%
}

\begin{document}

\begin{acroenv}
  \boldAcr{owasp}{open web application security project}
  \boldAcr{asvs}{application security verification standard}
  \boldAcr{dbms}{database management system}
  \boldAcr{sqlia}{structured query language injection attack}
  \boldAcr{ldap}{lightweight directory access protocol}
\end{acroenv}

\end{document}

将的定义替换\boldAcr为:

% \NewDocumentCommand { \boldAcr }{ m >{\SplitList{~}} m }
%   { \seq_put_right:Nn \l__sctale_acro_seq { #1 \q_mark {#2} } }
\cs_new_eq:NN \dont \prg_do_nothing:
\NewDocumentCommand { \boldAcr }{ >{\SplitList{~}} m }
  {
    \tl_set:Nx \l__sctale_tmpa_tl { \tl_map_function:nN {#1} \__sctale_make_acro:n }
    \seq_put_right:No \l__sctale_acro_seq { \l__sctale_tmpa_tl \q_mark {#1} }
  }
\cs_new:Npn \__sctale_make_acro:n #1 { \__sctale_make_acro:w #1 \q_nil }
\cs_new:Npn \__sctale_make_acro:w #1 #2 \q_nil
  { \token_if_eq_meaning:NNF #1 \dont { #1 } }

您省去了编写首字母缩略词的麻烦。要避免在首字母缩略词中使用某个单词,您只需告诉它\dont使用它:

\begin{acroenv}
  \boldAcr{open web application security project}
  \boldAcr{application security verification standard}
  \boldAcr{database management system}
  \boldAcr{structured query language injection attack}
  \boldAcr{lightweight directory access protocol}
  \boldAcr{national oceanic \dont{and} atmospheric administration}
\end{acroenv}

在此处输入图片描述

答案2

我刚刚从这里

\usepackage{xparse}

\ExplSyntaxOn

\seq_new:N \g_sctale_acr_seq
\prop_new:N \g_sctale_acr_prop

\NewDocumentCommand \addacr { m m }
 {
  \seq_put_right:Nn \g_sctale_acr_seq { #1 }
  \prop_put:Nnn \g_sctale_acr_prop { #1 } { #2 }
 }

\NewDocumentCommand \printacrlist { }
 {
  \seq_sort:Nn \g_sctale_acr_seq
   {
    \sctale_string_if_before_case_insensitive:nnTF { ##1 } { ##2 }
     { \sort_return_same:    }
     { \sort_return_swapped: }
   }
  \begin{flushleft}
   \seq_map_inline:Nn \g_sctale_acr_seq
    { \boldAcr{##1}{ \prop_item:Nn \g_sctale_acr_prop {##1} } \\ }
  \end{flushleft}
 }

\prg_new_conditional:Nnn \sctale_string_if_before_case_insensitive:nn { p, T, F, TF }
 {
  \int_compare:nNnTF { \pdftex_strcmp:D { \str_lowercase:n {#1} } { \str_lowercase:n {#2} } } < 0
   { \prg_return_true:  }
   { \prg_return_false: }
 }

\ExplSyntaxOff

这只是使用\addacr{sql}{structured query language}之前,然后\printacrlist,依次使用你的\boldAcr来打印每一个。

相关内容