cgnieder / acro

acronyms for LaTeX
LaTeX Project Public License v1.3c
42 stars 9 forks source link

Version 3 propagates plural, capital properties #191

Closed dbosk closed 3 years ago

dbosk commented 3 years ago

The following example works in version 2 (if \acroifusedTF is replaced by \acifused), but not in version 3. The expected output is "zero-knowledge proofs of knowledge (ZKPKs)", but in version 3 we get "zero-knowledges proofs of knowledge (ZKsPKss)" (note all extra plurals that are propagated to the "subacros").

\documentclass{article}
\usepackage{acro}
\DeclareAcronym{ZK}{%
  short = {ZK},
  long = {zero-knowledge},
}
\DeclareAcronym{PK}{%
  short = {PK},
  long = {proof of knowledge},
  long-plural-form = {proofs of knowledge},
}
\DeclareAcronym{ZKPK}{%
  short = {\acs*{ZK}\acs*{PK}},
  long = {%
    \acroifusedTF{ZK}{%
        \acroifusedTF{PK}{\acs*{ZK}\acs*{PK}}{\acs*{ZK} \acl*{PK}}%
      }{%
        \acl*{ZK} \acroifusedTF{PK}{\acs*{PK}}{\acl*{PK}}%
    }%
  },
  long-plural-form = {%
    \acroifusedTF{ZK}{%
        \acroifusedTF{PK}{\acs*{ZK}\acsp*{PK}}{\acs*{ZK} \aclp*{PK}}%
      }{%
        \acl*{ZK} \acroifusedTF{PK}{\acsp*{PK}}{\aclp*{PK}}%
    }%
  },
}

\begin{document}
  \acp{ZKPK} \dots
\end{document}
dbosk commented 3 years ago

Well, a workaround is to hardcode the ZK acronyms (long and short), instead of using \acs* and \acl*.

\documentclass{article}
\usepackage{acro}
\DeclareAcronym{ZK}{%
  short = {ZK},
  long = {zero-knowledge},
}
\DeclareAcronym{PK}{%
  short = {PK},
  long = {proof of knowledge},
  long-plural-form = {proofs of knowledge},
}
\DeclareAcronym{ZKPK}{%
  short = {ZKPK},
  long = {%
    \acroifusedTF{ZK}{%
        \acroifusedTF{PK}{ZK\acs*{PK}}{ZK \acl*{PK}}%
      }{%
        zero-knowledge \acroifusedTF{PK}{\acs*{PK}}{\acl*{PK}}%
    }%
  },
  long-plural-form = {%
    \acroifusedTF{ZK}{%
        \acroifusedTF{PK}{ZK\acsp*{PK}}{ZK \aclp*{PK}}%
      }{%
        zero-knowledge \acroifusedTF{PK}{\acsp*{PK}}{\aclp*{PK}}%
    }%
  },
}

\begin{document}
  \acp{ZKPK} \dots
\end{document}
cgnieder commented 3 years ago

Thanks. This needs to be resolved. But it's not an easy one, I'm afraid…

cgnieder commented 3 years ago

This seems to work:

\documentclass{article}
\usepackage{acro,xcolor}

\newcommand\expect[1]{\textcolor{gray}{#1}}

\ExplSyntaxOn
\cs_new_protected:Npn \acro_unset_ending:n #1
  { \bool_set_false:c {l__acro_ending_#1_bool} }
\cs_new_protected:Npn \acro_reset_endings:
  {
    \tl_map_tokens:Nn \l__acro_endings_tl { \acro_unset_ending:n }
    \bool_set_false:N \l__acro_ending_bool
  }
\acsetup{
  commands/begin = \acro_reset_endings:
}
\ExplSyntaxOff

\DeclareAcronym{ZK}{
  short = ZK ,
  long  = zero-knowledge
}
\DeclareAcronym{PK}{
  short = PK ,
  long  = proof of knowledge ,
  long-plural-form = proofs of knowledge
}
\DeclareAcronym{ZKPK}{
  short = \acs*{ZK}\acs*{PK} ,
  long =
    \acroifusedTF{ZK}
      {\acroifusedTF{PK}{\acs*{ZK}\acs*{PK}}{\acs*{ZK} \acl*{PK}}}
      {\acl*{ZK} \acroifusedTF{PK}{\acs*{PK}}{\acl*{PK}}} ,
  short-plural-form = \acs*{ZK}\acsp*{PK} ,
  long-plural-form =
    \acroifusedTF{ZK}
      {\acroifusedTF{PK}{\acs*{ZK}\acsp*{PK}}{\acs*{ZK} \aclp*{PK}}}
      {\acl*{ZK} \acroifusedTF{PK}{\acsp*{PK}}{\aclp*{PK}}}
}

\begin{document}

\setlength\parindent{0pt}

\subsection*{ZK used}
\ac{ZK} \expect{zero-knowledge (ZK)}\par
\ac{ZKPK} \expect{ZK proof of knowledge (ZKPK)} \par
\bigskip
\acresetall
\acp{ZK} \expect{zero-knowledges (ZKs)}\par
\acp{ZKPK} \expect{ZK proofs of knowledge (ZKPKs)} \par

\subsection*{PK used}
\acresetall
\ac{PK} \expect{proof of knowledge (PK)} \par
\ac{ZKPK} \expect{zero-knowledge PK (ZKPK)} \par
\bigskip
\acresetall
\acp{PK} \expect{proofs of knowledge (PKs)} \par
\acp{ZKPK} \expect{zero-knowledge PKs (ZKPKs)} \par

\subsection*{Both used}
\acresetall
\ac{ZK} \expect{zero-knowledge (ZK)}\par
\ac{PK} \expect{proof of knowledge (PK)} \par
\ac{ZKPK} \expect{ZKPK (ZKPK)} (??)\par
\bigskip
\acresetall
\acp{ZK} \expect{zero-knowledges (ZKs)}\par
\acp{PK} \expect{proofs of knowledge (PKs)} \par
\acp{ZKPK} \expect{ZKPKs (ZKPKs)} (??)\par

\subsection*{None used}
\acresetall
\ac{ZKPK} \expect{zero-knowledge proof of knowledge (ZKPK)} \par
\bigskip
\acresetall
\acp{ZKPK} \expect{zero-knowledge proofs of knowledge (ZKPKs)} \par

\end{document}
cgnieder commented 3 years ago

I added the reset in f222e0fb252b511d7d05ac153df5e5e97cac5989 so this will become part of the next release.

The remaining questions is: what to do in the case when all nested acronyms have already been used when the combined acronym is called the first time?

I could imagine a property uselist or similar which determines other acronyms which when all already used marl the current acronym as used. I could also imagine that nested acronyms add themselves to such a uselist automatically. I'm not sure the latter always is a good idea, though.

dbosk commented 3 years ago

Nice, thanks!

That's a good question. But the uselist idea sounds like a good approach to me.

cgnieder commented 3 years ago

I added the uselist property; with it this code

\documentclass{article}
\usepackage{acro,xcolor}

\newcommand\expect[1]{\textcolor{gray}{#1}}

\DeclareAcronym{ZK}{
  short = ZK ,
  long  = zero-knowledge
}
\DeclareAcronym{PK}{
  short = PK ,
  long  = proof of knowledge ,
  long-plural-form = proofs of knowledge
}
\DeclareAcronym{ZKPK}{
  short = \acs*{ZK}\acs*{PK} ,
  long =
    \acroifusedTF{ZK}
      {\acroifusedTF{PK}{\acs*{ZK}\acs*{PK}}{\acs*{ZK} \acl*{PK}}}
      {\acl*{ZK} \acroifusedTF{PK}{\acs*{PK}}{\acl*{PK}}} ,
  short-plural-form = \acs*{ZK}\acsp*{PK} ,
  long-plural-form =
    \acroifusedTF{ZK}
      {\acroifusedTF{PK}{\acs*{ZK}\acsp*{PK}}{\acs*{ZK} \aclp*{PK}}}
      {\acl*{ZK} \acroifusedTF{PK}{\acsp*{PK}}{\aclp*{PK}}} ,
  uselist = {ZK,PK} ,
  sort = ZKPK
}

\begin{document}

\setlength\parindent{0pt}

\ac{ZK} \expect{zero-knowledge (ZK)}\par
\ac{PK} \expect{proof of knowledge (PK)} \par
\acresetall
\acp{ZK} \expect{zero-knowledges (ZKs)}\par
\acp{PK} \expect{proofs of knowledge (PKs)} \par

\subsection*{ZK used}
\acresetall\acuse{ZK}
\ac{ZKPK} \expect{ZK proof of knowledge (ZKPK)} \par
\acresetall\acuse{ZK}
\acp{ZKPK} \expect{ZK proofs of knowledge (ZKPKs)} \par

\subsection*{PK used}
\acresetall\acuse{PK}
\ac{ZKPK} \expect{zero-knowledge PK (ZKPK)} \par
\acresetall\acuse{PK}
\acp{ZKPK} \expect{zero-knowledge PKs (ZKPKs)} \par

\subsection*{Both used}
\acresetall\acuse{ZK,PK}
\ac{ZKPK} \expect{ZKPK} \par
\acresetall\acuse{ZK,PK}
\acp{ZKPK} \expect{ZKPKs} \par

\subsection*{None used}
\acresetall
\ac{ZKPK} \expect{zero-knowledge proof of knowledge (ZKPK)} \par
\acresetall
\acp{ZKPK} \expect{zero-knowledge proofs of knowledge (ZKPKs)} \par

\printacronyms

\end{document}

now gives

image

I consider this issue now resolved…