3

In order to have this result

enter image description here

I wrote this command:

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

and

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

Is there a way to modify it in order to sort the elements alphabetically, based on the acronym?

  • An option would be to have \addacr{owasp}{open web application security project} and add any acronym and then have a \printacrlist that automatically sorts them. But may be there's a package already made for acronyms? – Manuel Feb 13 '19 at 12:15
  • @Manuel There is the Acronym package, but it doesn't do (as I tried) the effect that i want – ScTALE Feb 13 '19 at 12:17
5

Here's a way to do it. Each call to \boldAcr adds an item to a seq variable that contains the acronym and the meaning. At the \end of the defined environment the seq var is sorted (using code from this answer -- same caveats apply) then printed using \boldAcroPut, which is the same as you defined previously.

enter image description here

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

Replacing the definition of \boldAcr with this:

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

you spare yourself the hassle of writing the acronym. To avoid a word being used in the acronym you just tell it to \dont use it:

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

enter image description here

| improve this answer | |
  • It works with only one acronym, with 2 I have errors (Undefined control sequence. \end{acroenv}) – ScTALE Feb 13 '19 at 12:59
  • @ScTALE Sorry, I don't understand what you mean by “two acronyms”. Can you give an example for me to reproduce the error? – Phelype Oleinik Feb 13 '19 at 13:08
  • pastebin.com/LaqPM4QX With only one element, the acroenv environment works, with 2 no – ScTALE Feb 13 '19 at 13:13
  • @ScTALE Weird... The code you showed works for me (screenshot and output log). What LaTeX distribution/version you have. Can you upload the log so I can see? Perhaps it's an issue with the version of expl3. – Phelype Oleinik Feb 13 '19 at 13:20
  • At the moment I am writing from a different computer than before and unfortunately I will be not able to answer your question until tomorrow morning. In any case, I am using TexLive for Ubuntu 18 – ScTALE Feb 13 '19 at 13:58
5

I just took the sorting algorithm from here.

\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

This just uses \addacr{sql}{structured query language} before, and then \printacrlist, which in turn uses your \boldAcr for printing each one.

| improve this answer | |

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.