diff options
author | Karl Berry <karl@freefriends.org> | 2020-04-29 21:22:29 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2020-04-29 21:22:29 +0000 |
commit | 9dc098550a08a0a6535d68c59ce28ce13fad7593 (patch) | |
tree | 87154c9583e8bd0b5335f78aec2f2c9f7803bff3 /Master/texmf-dist/tex/latex | |
parent | 88363fa054edfe4dafa9a338ec24f3e062c1f26a (diff) |
acro (29apr20)
git-svn-id: svn://tug.org/texlive/trunk@54937 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex')
-rw-r--r-- | Master/texmf-dist/tex/latex/acro/acro-manual.cls | 391 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/acro/acro.definitions.tex | 581 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/acro/acro.sty | 7599 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/acro/acro2.sty | 4640 |
4 files changed, 9103 insertions, 4108 deletions
diff --git a/Master/texmf-dist/tex/latex/acro/acro-manual.cls b/Master/texmf-dist/tex/latex/acro/acro-manual.cls deleted file mode 100644 index e0a35f47810..00000000000 --- a/Master/texmf-dist/tex/latex/acro/acro-manual.cls +++ /dev/null @@ -1,391 +0,0 @@ -% -------------------------------------------------------------------------- -% the ACRO package -% -% Typeset Acronyms -% -% -------------------------------------------------------------------------- -% Clemens Niederberger -% Web: https://bitbucket.org/cgnieder/acro/ -% E-Mail: contact@mychemistry.eu -% -------------------------------------------------------------------------- -% Copyright 2011--2020 Clemens Niederberger -% -% This work may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3 -% of this license or (at your option) any later version. -% The latest version of this license is in -% http://www.latex-project.org/lppl.txt -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. -% -% This work has the LPPL maintenance status `maintained'. -% -% The Current Maintainer of this work is Clemens Niederberger. -% -------------------------------------------------------------------------- -% The acro package consists of the files -% - acro.sty, acro.definitions.tex, acro.cfg -% - acro-manual.tex, acro-manual.pdf, acro-manual.cls -% - acro.history, README -% -------------------------------------------------------------------------- -% If you have any ideas, questions, suggestions or bugs to report, please -% feel free to contact me. -% -------------------------------------------------------------------------- -\ProvidesClass{acro-manual}[2020/01/24] - -\LoadClass[load-preamble,add-index]{cnltx-doc} -\RequirePackage{imakeidx} -\RequirePackage[utf8]{inputenc} - -\usepackage{acro} -\acsetup{ - single = true , - accsupp = true , - index = true , - use-barriers = true , - hyperref = true , - log = true -} - -\setcnltx{ - package = {acro} , - info = {Typeset Acronyms and other Abbreviations} , - authors = Clemens Niederberger , - email = contact@mychemistry.eu , - url = https://bitbucket.org/cgnieder/acro/ , - abstract = {% - \acro\ allows you to define and use abbreviations in a simple way. - Abbreviations can be divided into different classes of abbreviations. - Lists of abbreviations can be created (also of separate classes of - abbreviations) and printed wherever you want the lists to appear.\par - \acro\ provides an option \option{single} which ignores abbreviations that - are used only once in the whole document.\par - As an experimental feature \acro\ also offers the option \option{sort} which - automatically sorts the list created by \cs{printacronyms}.\par - \acro\ also has the feature of creating \emph{local} lists - } , - add-cmds = { - ac, Ac, aca, Aca, acap, Acap, acbarrier, acdot, acf, Acf, acflike, acg, - acfp, Acfp, acfplike, aciftrailing, acl, Acl, aclp, Aclp, acp, Acp, - acpsingle, Acpsingle, AcroRegisterTrailing, acs, Acs, acsingle, - Acsingle, acsp, Acsp, acspace, acreset, acresetall, acsetup, - DeclareAcroCommand, DeclareAcronym, DeclareAcroExtraStyle, - DeclareAcroFirstStyle, DeclareAcroListHeading, - DeclareAcroListStyle, DeclareAcroPageStyle, DeclarePseudoAcroCommand, - iac, Iac, iaca, Iaca, iacs, Iacs, iacl, Iacl, iacf, Iacf, iacflike, - Iacflike, - NewAcroCommand, NewPseudoAcroCommand, - printacronyms, - ProvideAcroCommand, ProvideAcroEnding, ProvidePseudoAcroCommand, - RenewAcroCommand, RenewPseudoAcroCommand - } , - add-silent-cmds = { - addcolon, DeclareInstance, babelhyphen, ExplSyntaxOff, ExplSyntaxOn, nato, - NewDocumentCommand, newlist, ny, setlist - } , - index-setup = { level = \section , headers={\indexname}{\indexname} } -} - -\colorlet{property}{blue} -\newidxcmd\property{\code{\textcolor{property}{#1}}}[ (property)] -\newrobustcmd*\prop{\@ifstar{\cnltx@prop@star}{\cnltx@prop@nostar}} - -\newrobustcmd*\cnltx@prop@star{% - \cnltx@ifdash - {\cnltx@prop@aux*\meta} - {\cnltx@prop@aux*\marg}% -} -\newrobustcmd*\cnltx@prop@nostar{% - \cnltx@ifdash - {\cnltx@prop@aux{}\meta} - {\cnltx@prop@aux{}\marg}% -} -\newcommand*\cnltx@prop@aux[4]{% - \code{\property#1{#3}\cnltx@isvalue#2{#4}}% -} - -\newrobustcmd*\propis{% - \@ifstar - {\cnltx@propis*} - {\cnltx@propis{}}% -} -\newrobustcmd*\cnltx@propis[1]{% - \cnltx@ifdash - {\cnltx@prop@aux{#1}\@firstofone} - {\cnltx@prop@aux{#1}\Marg}% -} -\newrobustcmd*\choiceprop{% - \@ifstar - {\cnltx@choiceprop@star} - {\cnltx@choiceprop@nostar}% -} -\def\cnltx@choiceprop@star#1#2{% - \code{\property*{#1}\cnltx@isvalue\choices{#2}}} -\def\cnltx@choiceprop@nostar#1#2{% - \code{\property{#1}\cnltx@isvalue\choices{#2}}} -\newcommand*\boolprop{% - \@ifstar - {\cnltx@boolprop@star} - {\cnltx@boolprop@nostar}% -} -\def\cnltx@boolprop@star#1{\choiceprop*{#1}{\default{true},false}} -\def\cnltx@boolprop@nostar#1{\choiceprop{#1}{\default{true},false}} - -\newenvironment{properties} - {% - \def\propert{\@cnltx@option@item\property}% - \def\propval{\@cnltx@option@item\prop}% - \def\proplit{\@cnltx@option@item\propis}% - \def\propchoice{\@cnltx@option@item\choiceprop}% - \def\propbool{\@cnltx@option@item\boolprop}% - \cnltxlist - } - {\endcnltxlist} - -\protected\def\@versionstar{\raisebox{-.25em}{*}} -\newcommand\versionstar{\texorpdfstring{\@versionstar}{*}} - -\newcommand*\TF{\textcolor{red}{\uline{\code{\textcolor{cs}{\textit{TF}}}}}} - -\RequirePackage{fontawesome} -\RequirePackage{datetime2} -\DTMsetup{useregional=numeric,datesep=/} -\newrobustcmd*\acro@add@version[2]{% - \csdef{ac@ver@#2}{% - \DTMdate{#1}% - \csgdef{ac@ver@#2used}{}% - \csdef{ac@ver@#2}{\DTMdate{#1}}% - }% -} - -\newrobustcmd*\ac@date[1]{\ifcsdef{ac@ver@#1used}{}{ (\csuse{ac@ver@#1})}} -\newrobustcmd*\ac@ifnew[1]{\ifcsstring{c_acro_version_tl}{#1}} -\newrobustcmd*\ac@NEW{\faStarO\ New} - -\renewrobustcmd*\sinceversion[1]{% - \ac@ifnew{#1}% - {\cnltx@version@note{\textcolor{red}{\ac@NEW}}}% - {\cnltx@version@note{\GetTranslation{cnltx-introduced}~#1\ac@date{#1}}}% -} -\renewrobustcmd*\changedversion[1]{% - \cnltx@version@note{\GetTranslation{cnltx-changed}~#1\ac@date{#1}}% -} - -\newnote*\sincechanged[2]{% - \GetTranslation{cnltx-introduced}~#1\ac@date{#1}, - changed with version~#2\ac@date{#2}\ac@ifnew{#2}{ \ac@NEW}{}% -} - -\RenewDocumentEnvironment{commands}{} - {% - \cnltx@set@catcode_{12}% - \let\command\cnltx@command - \cnltxlist - } - {\endcnltxlist} - -\RequirePackage{tcolorbox,xsimverb} -\tcbuselibrary{skins,breakable} -\tcbset{enhanced,enhanced jigsaw} - -\newtcolorbox{bewareofthedog}{ - colback = white , - colframe = red , - underlay={% - \path[draw=none] - (interior.south west) - rectangle node[red]{\Huge\bfseries !} - ([xshift=-4mm]interior.north west); - }% -} - -\newtcolorbox{cnltxcode}[1][]{ - boxrule = 1pt , - colback = cnltxbg , - colframe = cnltx , - arc = 5pt , - beforeafter skip = .5\baselineskip ,% - #1% -} - -\newcommand*\acroman@readoptions[1]{% - \catcode`\^^M=13 - \acroman@read@options{#1}% -} - -\begingroup -\catcode`\^^M=13 -\gdef\acroman@read@options#1#2^^M{% - \endgroup - \ifblank{#2}{}{\acroman@read@options@#2}% - #1% - \XSIMfilewritestart*{\jobname.tmp}% -}% -\endgroup -\def\acroman@read@options@[#1]{\pgfqkeys{/cnltx}{#1}} - -\RenewDocumentEnvironment{sourcecode}{} - {% - \begingroup - \acroman@readoptions{% - \setlength\cnltx@sidebysidewidth - {\dimexpr .45\columnwidth -\lst@xleftmargin -\lst@xrightmargin\relax}% - \expanded{% - \noexpand\lstset{ - style=cnltx, - \ifboolexpe{ bool {cnltx@sidebyside} and not bool {cnltx@codeonly} } - {linewidth=\cnltx@sidebysidewidth,}{}% - \expandonce\cnltx@local@listings@options - }% - }% - \XSIMgobblechars{2}% - }% - } - {% - \XSIMfilewritestop - \cnltxcode[breakable]% - \lstinputlisting[style=cnltx]{\jobname.tmp}% - \endcnltxcode - } - -\RenewDocumentEnvironment{example}{} - {% - \begingroup - \acroman@readoptions{% - \setlength\cnltx@sidebysidewidth - {\dimexpr .45\columnwidth -\lst@xleftmargin -\lst@xrightmargin\relax}% - \expanded{% - \noexpand\lstset{ - style=cnltx, - \ifboolexpe{ bool {cnltx@sidebyside} and not bool {cnltx@codeonly} } - {linewidth=\cnltx@sidebysidewidth,}{}% - \expandonce\cnltx@local@listings@options - }% - }% - \XSIMgobblechars{2}% - }% - } - {% - \XSIMfilewritestop - \ifbool{cnltx@sidebyside} - {% - \cnltxcode - \noindent - \minipage[c]{\cnltx@sidebysidewidth}% - \cnltx@pre@source@hook - \lstinputlisting[style=cnltx] {\jobname.tmp}% - \cnltx@after@source@hook - \endminipage\hfill - \minipage[c]{\cnltx@sidebysidewidth}% - \cnltx@pre@example@hook - \input {\jobname.tmp}% - \cnltx@after@example@hook - \endminipage - } - {% - \cnltxcode[breakable]% - \cnltx@pre@source@hook - \lstinputlisting{\jobname.tmp}% - \cnltx@after@source@hook - \tcblower - \cnltx@pre@example@hook - \input {\jobname.tmp}% - \cnltx@after@example@hook - }% - \endcnltxcode - } - -\RequirePackage[ - backend=biber, - style=cnltx, - sortlocale=en_US, - indexing=cite]{biblatex} -\RequirePackage{csquotes,varioref} -\defbibheading{bibliography}{\section{References}} - -\RequirePackage[biblatex]{embrac}[2012/06/29] -\ChangeEmph{[}[,.02em]{]}[.055em,-.08em] -\ChangeEmph{(}[-.01em,.04em]{)}[.04em,-.05em] - -% additional packages: -\RequirePackage{longtable,array,booktabs,enumitem,amssymb} - -\newcommand*\h[1]{\textcolor{cnltx}{\textbf{#1}}} -\newcommand*\mailto[1]{\texttt{\href{mailto:#1}{#1}}} - -\ProvideAcroEnding {possessive} {'s} {'s} - -\acro@add@version{2012-06-22}{0.1} -\acro@add@version{2012-06-23}{0.1a} -\acro@add@version{2012-06-24}{0.1b} -\acro@add@version{2012-06-24}{0.1c} -\acro@add@version{2012-06-24}{0.2} -\acro@add@version{2012-06-25}{0.2a} -\acro@add@version{2012-06-25}{0.3} -\acro@add@version{2012-06-27}{0.3a} -\acro@add@version{2012-06-29}{0.3b} -\acro@add@version{2012-07-16}{0.3c} -\acro@add@version{2012-07-23}{0.3d} -\acro@add@version{2012-07-24}{0.3e} -\acro@add@version{2012-09-28}{0.4} -\acro@add@version{2012-10-07}{0.4a} -\acro@add@version{2012-11-30}{0.5} -\acro@add@version{2012-12-14}{0.6} -\acro@add@version{2013-01-02}{0.6a} -\acro@add@version{2013-01-16}{1.0} -\acro@add@version{2013-01-26}{1.1} -\acro@add@version{2013-01-29}{1.1a} -\acro@add@version{2013-02-09}{1.2} -\acro@add@version{2013-04-04}{1.2a} -\acro@add@version{2013-05-06}{1.3} -\acro@add@version{2013-05-09}{1.3a} -\acro@add@version{2013-05-30}{1.3b} -\acro@add@version{2013-06-16}{1.3c} -\acro@add@version{2013-07-08}{1.3d} -\acro@add@version{2013-08-07}{1.3e} -\acro@add@version{2013-08-27}{1.4} -\acro@add@version{2013-09-02}{1.4a} -\acro@add@version{2013-09-24}{1.4b} -\acro@add@version{2013-11-04}{1.4c} -\acro@add@version{2013-11-22}{1.4d} -\acro@add@version{2013-12-18}{1.5} -\acro@add@version{2015-02-26}{1.6} -\acro@add@version{2015-04-08}{1.6a} -\acro@add@version{2015-05-10}{1.6b} -\acro@add@version{2015-08-16}{2.0} -\acro@add@version{2015-08-25}{2.0a} -\acro@add@version{2015-08-29}{2.0b} -\acro@add@version{2015-09-05}{2.1} -\acro@add@version{2015-10-03}{2.2} -\acro@add@version{2016-01-07}{2.2a} -\acro@add@version{2016-01-21}{2.2b} -\acro@add@version{2016-02-02}{2.2c} -\acro@add@version{2016-03-14}{2.3} -\acro@add@version{2016-03-25}{2.4} -\acro@add@version{2016-04-14}{2.4a} -\acro@add@version{2016-05-03}{2.4b} -\acro@add@version{2016-05-25}{2.5} -\acro@add@version{2016-05-26}{2.5a} -\acro@add@version{2016-05-30}{2.5b} -\acro@add@version{2016-07-20}{2.6} -\acro@add@version{2016-08-13}{2.6a} -\acro@add@version{2016-08-13}{2.6b} -\acro@add@version{2016-08-16}{2.6c} -\acro@add@version{2016-08-30}{2.6d} -\acro@add@version{2016-09-04}{2.6e} -\acro@add@version{2017-01-22}{2.7} -\acro@add@version{2017-02-09}{2.7a} -\acro@add@version{2017-06-21}{2.7b} -\acro@add@version{2017-08-28}{2.7c} -\acro@add@version{2018-01-30}{2.8} -\acro@add@version{2019-02-17}{2.9} -\acro@add@version{2019-09-23}{2.10} -\acro@add@version{2019-10-02}{2.10a} -\acro@add@version{2019-10-06}{2.10b} -\acro@add@version{2019-10-12}{2.10c} -\acro@add@version{2019-12-30}{2.10d} -\acro@add@version{2020-01-11}{2.11} -\acro@add@version{2020-01-16}{2.11a} -\acro@add@version{2020-01-24}{2.11b} -\acro@add@version{2020-02-03}{2.11c} - -\endinput diff --git a/Master/texmf-dist/tex/latex/acro/acro.definitions.tex b/Master/texmf-dist/tex/latex/acro/acro.definitions.tex deleted file mode 100644 index a150faf6d81..00000000000 --- a/Master/texmf-dist/tex/latex/acro/acro.definitions.tex +++ /dev/null @@ -1,581 +0,0 @@ -% -------------------------------------------------------------------------- -% the ACRO package -% -% Typeset Acronyms -% -% -------------------------------------------------------------------------- -% Clemens Niederberger -% Web: https://bitbucket.org/cgnieder/acro/ -% E-Mail: contact@mychemistry.eu -% -------------------------------------------------------------------------- -% Copyright 2011--2020 Clemens Niederberger -% -% This work may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3 -% of this license or (at your option) any later version. -% The latest version of this license is in -% http://www.latex-project.org/lppl.txt -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. -% -% This work has the LPPL maintenance status `maintained'. -% -% The Current Maintainer of this work is Clemens Niederberger. -% -------------------------------------------------------------------------- -% The acro package consists of the files -% - acro.sty, acro.definitions.tex, acro.cfg -% - acro-manual.tex, acro-manual.pdf, acro-manual.cls -% - acro.history, README -% -------------------------------------------------------------------------- -% If you have any ideas, questions, suggestions or bugs to report, please -% feel free to contact me. -% -------------------------------------------------------------------------- -\ExplSyntaxOn - -% document commands: -\NewDocumentCommand \DeclareAcronym {mm} - { \acro_declare_acronym:nn {#1} {#2} } - -\NewDocumentCommand \acsetup { m } - { - \tl_if_blank:nF {#1} - { \keys_set:nn {acro} {#1} } - \ignorespaces - } - -\NewDocumentCommand \ProvideAcroEnding {mmm} - { \acro_provide_ending:nnn {#1} {#2} {#3} } - -\NewDocumentCommand \AcroRegisterTrailing {mm} - { \acro_register_trailing_token:Nn #1 {#2} } - -\NewDocumentCommand \DeclareAcroTranslation {mm} - { \acro_declare_translation:nn {#1} {#2} } - -\DeclareExpandableDocumentCommand \acifused { m } - { \acro_if_acronym_used:nTF {#1} } - -\NewDocumentCommand \acresetall {} - { \acro_reset_all: } - -\NewDocumentCommand \acuseall {} - { \acro_mark_all_as_used: } - -\NewDocumentCommand \acreset { > { \SplitList {,} } m } - { \ProcessList {#1} { \acro_reset:n } \ignorespaces } - -\NewDocumentCommand \acuse { > { \SplitList {,} } m } - { \ProcessList {#1} { \acro_mark_as_used:n } \ignorespaces } - -\NewDocumentCommand \acfirstupper {m} - { \acro_first_upper_case:n {#1} } - -\NewExpandableDocumentCommand \aciffirst {+m+m} - { \bool_if:NTF \l__acro_first_instance_bool {#1} {#2} } - -\NewDocumentCommand \acdot {} { \acro_dot: } -\NewDocumentCommand \acspace {} { \acro_space: } - -\NewDocumentCommand \acbarrier {} - { \acro_barrier: } - -\NewDocumentCommand \acswitchoff {} - { \acro_switch_off: } - -\NewDocumentCommand \acswitchon {} - { \acro_switch_on: } - -\NewDocumentCommand \printacronyms { O{} } - { \acro_print_acronyms:n {#1} } - -% -------------------------------------------------------------------------- -% styles -% #1: name -% #2: template -% #3: settings -\NewDocumentCommand \DeclareAcroFirstStyle {mmm} - { \acro_declare_first_style:nnn {#1} {#2} {#3} } - -\NewDocumentCommand \DeclareAcroExtraStyle {mmm} - { \acro_declare_extra_style:nnn {#1} {#2} {#3} } - -\NewDocumentCommand \DeclareAcroPageStyle {mmm} - { \acro_declare_page_style:nnn {#1} {#2} {#3} } - -\NewDocumentCommand \DeclareAcroListHeading {mm} - { \acro_declare_list_heading:nn {#1} {#2} } - -\NewDocumentCommand \DeclareAcroListStyle {mmm} - { \acro_declare_list_style:nnn {#1} {#2} {#3} } - -% -------------------------------------------------------------------------- -% endings: -\ProvideAcroEnding {plural} {s} {s} - -% -------------------------------------------------------------------------- -% use acronyms: -% automatic: -\NewAcroCommand \ac - { \acro_use:n {#1} } - -\NewAcroCommand \Ac - { - \acro_first_upper: - \acro_use:n {#1} - } - -\NewAcroCommand \iac - { - \acro_indefinite: - \acro_use:n {#1} - } - -\NewAcroCommand \Iac - { - \acro_first_upper: - \acro_indefinite: - \acro_use:n {#1} - } - -\NewAcroCommand \acp - { - \acro_plural: - \acro_use:n {#1} - } - -\NewAcroCommand \Acp - { - \acro_plural: - \acro_first_upper: - \acro_use:n {#1} - } - -\NewAcroCommand \acsingle - { - \acro_get:n {#1} - \acro_single:n {#1} - } - -\NewAcroCommand \acpsingle - { - \acro_get:n {#1} - \acro_plural: - \acro_single:n {#1} - } - -\NewAcroCommand \Acsingle - { - \acro_get:n {#1} - \acro_first_upper: - \acro_single:n {#1} - } - -\NewAcroCommand \Acpsingle - { - \acro_get:n {#1} - \acro_first_upper: - \acro_plural: - \acro_single:n {#1} - } - -% short: -\NewAcroCommand \acs - { \acro_short:n {#1} } - -\NewAcroCommand \Acs - { - \acro_first_upper: - \acro_short:n {#1} - } - -\NewAcroCommand \iacs - { - \acro_indefinite: - \acro_short:n {#1} - } - -\NewAcroCommand \Iacs - { - \acro_first_upper: - \acro_indefinite: - \acro_short:n {#1} - } - -\NewAcroCommand \acsp - { - \acro_plural: - \acro_short:n {#1} - } - -\NewAcroCommand \Acsp - { - \acro_first_upper: - \acro_plural: - \acro_short:n {#1} - } - -% alt: -\NewAcroCommand \aca - { \acro_alt:n {#1} } - -\NewAcroCommand \Aca - { - \acro_first_upper: - \acro_alt:n {#1} - } - -\NewAcroCommand \iaca - { - \acro_indefinite: - \acro_alt:n {#1} - } - -\NewAcroCommand \Iaca - { - \acro_first_upper: - \acro_indefinite: - \acro_alt:n {#1} - } - -\NewAcroCommand \acap - { - \acro_plural: - \acro_alt:n {#1} - } - -\NewAcroCommand \Acap - { - \acro_first_upper: - \acro_plural: - \acro_alt:n {#1} - } - -% long: -\NewAcroCommand \acl - { \acro_long:n {#1} } - -\NewAcroCommand \Acl - { - \acro_first_upper: - \acro_long:n {#1} - } - -\NewAcroCommand \iacl - { - \acro_indefinite: - \acro_long:n {#1} - } - -\NewAcroCommand \Iacl - { - \acro_first_upper: - \acro_indefinite: - \acro_long:n {#1} - } - -\NewAcroCommand \aclp - { - \acro_plural: - \acro_long:n {#1} - } - -\NewAcroCommand \Aclp - { - \acro_plural: - \acro_first_upper: - \acro_long:n {#1} - } - -% first: -\NewAcroCommand \acf - { \acro_first:n {#1} } - -\NewAcroCommand \Acf - { - \acro_first_upper: - \acro_first:n {#1} - } - -\NewAcroCommand \iacf - { - \acro_indefinite: - \acro_first:n {#1} - } - -\NewAcroCommand \Iacf - { - \acro_first_upper: - \acro_indefinite: - \acro_first:n {#1} - } - -\NewAcroCommand \acfp - { - \acro_plural: - \acro_first:n {#1} - } - -\NewAcroCommand \Acfp - { - \acro_plural: - \acro_first_upper: - \acro_first:n {#1} - } - -% first-like: -\NewPseudoAcroCommand \acflike - { \acro_first_like:nn {#1} {#2} } - -\NewPseudoAcroCommand \iacflike - { - \acro_indefinite: - \acro_first_like:nn {#1} {#2} - } - -\NewPseudoAcroCommand \Iacflike - { - \acro_first_upper: - \acro_indefinite: - \acro_first_like:nn {#1} {#2} - } - -\NewPseudoAcroCommand \acfplike - { - \acro_plural: - \acro_first_like:nn {#1} {#2} - } - -% -------------------------------------------------------------------------- -% first appearance styles: -\DeclareAcroFirstStyle {default} {inline} - { } - -\DeclareAcroFirstStyle {reversed} {inline} - { reversed = true } - -\DeclareAcroFirstStyle {short} {inline} - { - only-short = true , - brackets = false - } - -\DeclareAcroFirstStyle {long} {inline} - { - only-long = true , - brackets = false - } - -\DeclareAcroFirstStyle {square} {inline} - { brackets-type = [] } - -\DeclareAcroFirstStyle {plain} {inline} - { - brackets = false , - between = -- - } - -\DeclareAcroFirstStyle {plain-reversed} {inline} - { - brackets = false , - between = -- , - reversed = true - } - -\DeclareAcroFirstStyle {footnote} {note} - { } - -\DeclareAcroFirstStyle {footnote-reversed} {note} - { reversed = true } - -\DeclareAcroFirstStyle {sidenote} {note} - { note-command = \sidenote {#1} } - -\DeclareAcroFirstStyle {sidenote-reversed} {note} - { - note-command = \sidenote {#1} , - reversed = true - } - -\DeclareAcroFirstStyle {empty} {note} - { use-note = false } - -% -------------------------------------------------------------------------- -% extra info appearance styles: -\DeclareAcroExtraStyle {default} {inline} - { - brackets = false , - punct = true , - punct-symbol = . - } - -\DeclareAcroExtraStyle {plain} {inline} - { - brackets = false , - punct = true , - punct-symbol = - } - -\DeclareAcroExtraStyle {paren} {inline} - { - brackets = true , - punct = true , - punct-symbol = - } - -\DeclareAcroExtraStyle {bracket} {inline} - { - brackets = true , - punct = true , - punct-symbol = , - brackets-type = [] - } - -\DeclareAcroExtraStyle {comma} {inline} - { - punct = true, - punct-symbol = {,} , - brackets = false - } - -% -------------------------------------------------------------------------- -% page number appearance styles: -\DeclareAcroPageStyle {default} {inline} - { - punct = true , - punct-symbol = . - } - -\DeclareAcroPageStyle {plain} {inline} - { punct = false } - -\DeclareAcroPageStyle {comma} {inline} - { punct = true } - -\DeclareAcroPageStyle {paren} {inline} - { - brackets=true , - punct-symbol = ~ - } - -\DeclareAcroPageStyle {none} {inline} - { display = false } - -% -------------------------------------------------------------------------- -% list heading styles: -\DeclareAcroListHeading {part} {\part} -\DeclareAcroListHeading {part*} {\part*} -\DeclareAcroListHeading {chapter} {\chapter} -\DeclareAcroListHeading {chapter*} {\chapter*} -\DeclareAcroListHeading {addchap} {\addchap} -\DeclareAcroListHeading {section} {\section} -\DeclareAcroListHeading {section*} {\section*} -\DeclareAcroListHeading {addsec} {\addsec} -\DeclareAcroListHeading {subsection} {\subsection} -\DeclareAcroListHeading {subsection*} {\subsection*} -\DeclareAcroListHeading {subsubsection} {\subsubsection} -\DeclareAcroListHeading {subsubsection*} {\subsubsection*} -\DeclareAcroListHeading {none} {\use_none:n} - -% -------------------------------------------------------------------------- -% list styles: -\DeclareAcroListStyle {description} {list} - { } - -\DeclareAcroListStyle {toc} {list-of} - { } - -\DeclareAcroListStyle {lof} {list-of} - { style = lof } - -\DeclareAcroListStyle {tabular} {table} - { table = tabular } - -\DeclareAcroListStyle {longtable} {table} - { table = longtable } - -\DeclareAcroListStyle {extra-tabular} {extra-table} - { table = tabular } - -\DeclareAcroListStyle {extra-longtable} {extra-table} - { table = longtable } - -\DeclareAcroListStyle {extra-tabular-rev} {extra-table} - { - table = tabular , - reverse = true - } - -\DeclareAcroListStyle {extra-longtable-rev} {extra-table} - { - table = longtable , - reverse = true - } - -% -------------------------------------------------------------------------- -% register some tokens to be checked for: -\AcroRegisterTrailing . {dot} -\AcroRegisterTrailing - {dash} -\AcroRegisterTrailing \babelhyphen {babel-hyphen} - -\acsetup { activate-trailing-tokens = dot } - -% some user macros: -\cs_new_protected:Npn \acro_dot: - { \acro_if_trailing_tokens:nF {dot} {.\@} } - -\cs_new_protected:Npn \acro_space: - { \acro_if_trailing_tokens:nF {dash,babel-hyphen} { \c_space_tl } } - -% -------------------------------------------------------------------------- -% translations: -% list name -\DeclareAcroTranslation {acronym-list-name} - { - Fallback = Acronyms , - English = Acronyms , - French = Acronymes , - German = Abk\"urzungen , - Italian = Acronimi , - Portuguese = Acr\'onimos , - Spanish = Siglas , - Catalan = Sigles , - Turkish = K\i saltmalar - } - -% page name -\DeclareAcroTranslation {acronym-page-name} - { - Fallback = p. , - English = p. , - German = S. , - Portuguese = p. - } - -% pages name -\DeclareAcroTranslation {acronym-pages-name} - { - Fallback = pp. , - English = pp. , - German = S. , - Portuguese = pp. - } - -% following page -\DeclareAcroTranslation {acronym-next-page} - { - Fallback = f. , - English = f. , - German = f. , - Portuguese = s. - } - -% following pages -\DeclareAcroTranslation {acronym-next-pages} - { - Fallback = ff. , - English = ff. , - German = ff. , - Portuguese = ss. - } - -\file_input_stop: diff --git a/Master/texmf-dist/tex/latex/acro/acro.sty b/Master/texmf-dist/tex/latex/acro/acro.sty index 5209dda3ca9..d1761cf0052 100644 --- a/Master/texmf-dist/tex/latex/acro/acro.sty +++ b/Master/texmf-dist/tex/latex/acro/acro.sty @@ -5,7 +5,7 @@ % % -------------------------------------------------------------------------- % Clemens Niederberger -% Web: https://bitbucket.org/cgnieder/acro/ +% Web: https://github.com/cgnieder/acro/ % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- % Copyright 2011--2020 Clemens Niederberger @@ -30,15 +30,15 @@ % If you have any ideas, questions, suggestions or bugs to report, please % feel free to contact me. % -------------------------------------------------------------------------- -\RequirePackage{expl3,xparse,xtemplate,l3keys2e} -\RequirePackage{etoolbox} % for the document hooks - +\RequirePackage{expl3,xparse,l3keys2e} \ExplSyntaxOn -\tl_const:Nn \c_acro_date_tl {2020/03/07} -\tl_const:Nn \c_acro_version_major_number_tl {2} -\tl_const:Nn \c_acro_version_minor_number_tl {11} -\tl_const:Nn \c_acro_version_subrelease_tl {d} +% setup package: +\tl_const:Nn \c_acro_package_name_tl {acro} +\tl_const:Nn \c_acro_date_tl {2020/04/29} +\tl_const:Nn \c_acro_version_major_number_tl {3} +\tl_const:Nn \c_acro_version_minor_number_tl {0} +\tl_const:Nn \c_acro_version_subrelease_tl {} \tl_const:Nx \c_acro_version_number_tl { \c_acro_version_major_number_tl . @@ -49,3448 +49,4199 @@ \c_acro_version_number_tl \c_acro_version_subrelease_tl } -\tl_const:Nn \c_acro_info_tl {Typeset~ Acronyms} +\tl_const:Nn \c_acro_info_tl {typeset~ acronyms~ and~ other~ abbreviations} \ProvidesExplPackage - {acro} + {\c_acro_package_name_tl} {\c_acro_date_tl} {\c_acro_version_tl} {\c_acro_info_tl} % -------------------------------------------------------------------------- -% warning and error messages: -\msg_new:nnn {acro} {undefined} - { - You've~ requested~ acronym~ `#1'~ \msg_line_context: \ but~ you~ - apparently~ haven't~ defined~ it,~ yet! \\ - Maybe~ you've~ misspelled~ `#1'? - } +% document hooks: +\tl_new:N \g_acro_end_document_hook_tl +\tl_new:N \g_acro_begin_document_hook_tl -\msg_new:nnn {acro} {macro} - { - A~ macro~ with~ the~ csname~ `#1'~ already~ exists! \\ - Unless~ you~ set~ acro's~ option~ `strict'~ I~ won't~ redefine~ it~ - \msg_line_context: . - } +\AtBeginDocument { \tl_use:N \g_acro_begin_document_hook_tl } +\AtEndDocument { \tl_use:N \g_acro_end_document_hook_tl } + +\cs_new_protected:Npn \acro_at_begin_document:n #1 + { \tl_gput_right:Nn \g_acro_begin_document_hook_tl {#1} } -\msg_new:nnn {acro} {replaced} +\cs_new_protected:Npn \acro_at_end_document:n #1 + { \tl_gput_right:Nn \g_acro_end_document_hook_tl {#1} } + +% -------------------------------------------------------------------------- +% load-time messages: +\msg_new:nnn {acro} {load-time-option} { - The~ #1~ `#2' ~you ~used~ \msg_line_context: \ is~ deprecated~ and~ has~ - been~ replaced~ by~ `#3'. ~Since~ I~ will~ not~ guarantee~ that~ #1~ `#2'~ - will~ be~ kept~ forever~ I~ strongly~ encourage~ you~ to~ switch! + `#1'~ is~ a~ load-time~ option! \\ + You~ cannot~ set~ it~ with~ \token_to_str:N \acsetup ! \\ + You~ need~ to~ use~ \token_to_str:N \usepackage [#1] {acro} . } -\msg_new:nnn {acro} {deprecated} +\msg_new:nnn {acro} {unknown-option} { - The~ #1~ `#2'~ you~ used~ \msg_line_context: \ is~ deprecated~and~ there~ - is~ no~ replacement.~ Since~ I~ will~ not~ guarantee~ that~ #1~ `#2'~ - will~ be~ kept~ forever~ I~ strongly~ encourage~ you~ to~ remove~ it~ - from~ your~ document. + Unknown~ option~ `#1' \\ + I~ dont'~ know~ the~ option~ `#1'.~ Please~ make~ sure~ there~ is~ no~ + typo.~ Check~ the~ manual~ for~ help. } -\msg_new:nnn {acro} {substitute-short} +% -------------------------------------------------------------------------- +% re-compile mechanism: +\bool_new:N \g__acro_rerun_bool +\tl_new:N \g__acro_rerun_message_tl + +\tl_const:Nn \l__acro_rerun_general_tl + { Rerun~ to~ get~ `acro'~ synchronized. } + +\tl_const:Nn \l__acro_rerun_property_tl { - There~ is~ no~ short~ form~ set~ for~ acronym~ `#1'! \\ - I~ am~ setting~ the~ short~ form~ equal~ to~ the~ ID~ `#1'. \\ - If~ that~ is~ not~ what~ you~ want~ make~ sure~ to~ add~ an~ explicit~ - short~ form. + Acronym~ properties~ may~ have~ changed.~ Rerun~ to~ get~ them~ + synchronized. } -\msg_new:nnn {acro} {ending-exists} + +\tl_const:Nn \l__acro_rerun_list_tl { - An~ ending~ with~ the~ name~ `#1'~ already~ exists! \\ \\ - I~ am~ overwriting~ the~ defaults. + Empty~ acronym~ list.~ If~ you~ have~ used~ acronyms~ then~ re-compile~ + to~ get~ the~ list~ filled.~ Otherwise~ remove~ \token_to_str:N + \printacronyms } -\msg_new:nnn {acro} {ending-before-acronyms} +\msg_new:nnn {acro} {rerun} { \use:c {l__acro_rerun_#1_tl} } + +\prg_new_conditional:Npnn \acro_if_rerun: {p,T,F,TF} { - You~ are~ using~ \token_to_str:N \ProvideAcroEnding \ after~ you've~ - declared~ at~ least~ one~ acronym.~ This~ will~ lead~ to~ trouble! \\ - Make~ sure~ to~ define~ endings~ before~ *any*~ acronym~ declarations! + \bool_if:NTF \g__acro_rerun_bool + { \prg_return_true: } + { \prg_return_false: } } -\msg_new:nnn {acro} {no-alternative} +\cs_new_protected:Npn \acro_rerun:n #1 { - There~ is~ no~ alternative~ form~ for~ acronym~ `#1'! \\ \\ - I~ am~ using~ the~ short~ form~ instead. + \bool_gset_true:N \g__acro_rerun_bool + \tl_map_inline:Nn \g__acro_rerun_message_tl + { + \tl_if_eq:nnT {##1} {#1} + { \tl_map_break:n { \use_none:nn } } + } + \use:n { \tl_gput_right:Nn \g__acro_rerun_message_tl {{#1}} } } -\msg_new:nnn {acro} {unknown} +\cs_new_protected:Npn \acro_do_rerun: { - You're~ trying~ to~ use~ the~ #1~ `#2'~ \msg_line_context: . \\ - However,~ I~ do~ not~ know~ #1~ `#2'! \\ - If~ this~ is~ no~ typo~ please~ contact~ the~ package~ author. \\ \\ - I~ am~ going~ to~ use~ the~ #1~ `#3'~ instead. + \acro_if_rerun:T + { + \tl_map_inline:Nn \g__acro_rerun_message_tl + { + \str_case:nnTF {##1} + { + {property} { \msg_warning:nnn {acro} {rerun} {property} } + {list} { \msg_warning:nnn {acro} {rerun} {list} } + {general} { \msg_warning:nnn {acro} {rerun} {general} } + } + { \tl_map_break: } + { \msg_warning:nnn {acro} {rerun} {general} } + } + } } -\msg_new:nnn {acro} {definitions-missing} + +% -------------------------------------------------------------------------- +% debugging mechanism: +\bool_new:N \g__acro_debug_bool + +\prg_new_conditional:Npnn \acro_if_debug: {p,T,F,TF} { - I~ cannot~ find~ the~ file~ \c_acro_definition_file_name_tl - .\c_acro_definition_file_extension_tl !~ This~ file~ contains~ all~ - essential~ user~ commands~ of~ acro~ and~ is~ a~ crucial~ part~ of~ the~ - package!~ Please~ check~ your~ installation. + \bool_if:NTF \g__acro_debug_bool + { \prg_return_true: } + { \prg_return_false: } } % -------------------------------------------------------------------------- -% temporary variables -\tl_new:N \l__acro_tmpa_tl -\tl_new:N \l__acro_tmpb_tl -\tl_new:N \l__acro_tmpc_tl -\prop_new:N \l__acro_tmpa_prop -\prop_new:N \l__acro_tmpb_prop -\seq_new:N \l__acro_tmpa_seq -\seq_new:N \l__acro_tmpb_seq -\int_new:N \l__acro_tmpa_int -\int_new:N \l__acro_tmpb_int -\int_new:N \l__acro_tmpc_int -\int_new:N \l__acro_tmpd_int +% check for stuff changed in the new version: +\bool_new:N \g__acro_upgrade_bool -% -------------------------------------------------------------------------- -% variants of kernel commands -\cs_generate_variant:Nn \quark_if_no_value:nTF {V} -\cs_generate_variant:Nn \tl_put_right:Nn {NV,Nv} -\cs_generate_variant:Nn \tl_if_eq:nnT {V} -\cs_generate_variant:Nn \tl_if_eq:nnF {V} -\cs_generate_variant:Nn \seq_use:Nnnn {c} -\cs_generate_variant:Nn \seq_gset_split:Nnn {c} -\cs_generate_variant:Nn \seq_set_split:Nnn {NnV} -\cs_generate_variant:Nn \seq_if_in:NnT {NV} -\cs_generate_variant:Nn \seq_if_in:NnTF {Ne} -\cs_generate_variant:Nn \prop_put:Nnn {NnV,cnx,cnv} -\cs_generate_variant:Nn \prop_get:NnNTF {cnc} -\cs_generate_variant:Nn \prop_get:NnNF {cn,cnc} -\cs_generate_variant:Nn \prop_get:NnN {cnc} -\cs_generate_variant:Nn \cs_generate_variant:Nn {c} -\cs_generate_variant:Nn \str_case:nn {V} +\prg_new_conditional:Npnn \acro_if_upgrade: {p,T,F,TF} + { + \bool_if:NTF \g__acro_upgrade_bool + { \prg_return_true: } + { \prg_return_false: } + } % -------------------------------------------------------------------------- -% variables: -\bool_new:N \l__acro_acc_supp_bool -\bool_new:N \l__acro_addto_index_bool -\bool_new:N \l__acro_capitalize_list_bool -\bool_new:N \g__acro_case_sensitive_bool -\bool_new:N \l__acro_citation_all_bool -\bool_new:N \l__acro_citation_first_bool -\bool_set_true:N \l__acro_citation_first_bool -\bool_new:N \l__acro_create_macros_bool -\bool_new:N \l__acro_custom_alt_format_bool -\bool_new:N \l__acro_custom_long_format_bool -\bool_new:N \l__acro_custom_short_format_bool -\bool_new:N \l__acro_custom_foreign_format_bool -\bool_new:N \l__acro_extra_punct_bool -\bool_new:N \l__acro_extra_use_brackets_bool -\bool_new:N \g__acro_first_acronym_declared_bool -\bool_new:N \l__acro_first_instance_bool -\bool_new:N \l__acro_first_only_short_bool -\bool_new:N \l__acro_first_only_long_bool -\bool_new:N \l__acro_first_reversed_bool -\bool_new:N \l__acro_first_switched_bool -\bool_new:N \l__acro_first_use_brackets_bool -\bool_new:N \l__acro_first_upper_bool -\bool_new:N \l__acro_following_page_bool -\bool_new:N \l__acro_following_pages_bool -\bool_new:N \l__acro_foreign_bool -\bool_set_true:N \l__acro_foreign_bool -\bool_new:N \l__acro_group_citation_bool -\bool_new:N \l__acro_hyperref_loaded_bool -\bool_new:N \l__acro_hyperref_use_bool -\bool_new:N \l__acro_include_endings_format_bool -\bool_new:N \l__acro_indefinite_bool -\bool_new:N \l__acro_in_list_bool -\bool_new:N \l__acro_is_included_bool -\bool_new:N \l__acro_is_excluded_bool -\bool_new:N \l__acro_list_all_pages_bool -\bool_set_true:N \l__acro_list_all_pages_bool -\bool_new:N \l__acro_list_reverse_long_extra_bool -\bool_new:N \l__acro_log_acronyms_bool -\bool_new:N \l__acro_log_acronyms_verbose_bool -\bool_new:N \l__acro_mark_as_used_bool -\bool_new:N \g__acro_mark_first_as_used_bool -\bool_new:N \l__acro_override_list_format_bool -\bool_new:N \l__acro_page_brackets_bool -\bool_new:N \l__acro_page_display_bool -\bool_new:N \l__acro_page_punct_bool -\bool_new:N \l__acro_place_label_bool -\bool_new:N \l__acro_print_only_used_bool -\bool_set_true:N \l__acro_print_only_used_bool -\bool_new:N \g__acro_rerun_bool -\bool_new:N \g__acro_reset_at_barrier_bool -\bool_new:N \l__acro_silence_bool -\bool_new:N \l__acro_single_use_bool -\bool_new:N \l__acro_sort_bool -\bool_set_true:N \l__acro_sort_bool -\bool_new:N \l__acro_strict_bool -\bool_new:N \l__acro_trailing_tokens_bool -\bool_new:N \l__acro_tooltip_bool -\bool_new:N \l__acro_tooltip_inside_bool -\bool_new:N \l__acro_upper_indefinite_bool -\bool_new:N \l__acro_upper_short_bool -\bool_new:N \l__acro_use_acronyms_bool -\bool_set_true:N \l__acro_use_acronyms_bool -\bool_new:N \l__acro_use_barrier_bool -\bool_new:N \g__acro_use_barriers_bool -\bool_new:N \l__acro_use_ending_form_bool -\bool_new:N \l__acro_use_note_bool -\bool_new:N \l__acro_xspace_bool - -\str_new:N \l__acro_current_id_str - -\tl_new:N \l__acro_list_entries_tl -\tl_new:N \l__acro_endings_tl -\tl_new:N \l__acro_trailing_tokens_tl -\tl_new:N \l__acro_included_classes_tl -\tl_new:N \l__acro_excluded_classes_tl -\tl_new:N \l__acro_ignore_tl -\tl_new:N \l__acro_default_indefinite_tl -\tl_set:Nn \l__acro_default_indefinite_tl {a} -\tl_new:N \l__acro_foreign_sep_tl -\tl_new:N \l__acro_extra_instance_tl -\tl_set:Nn \l__acro_extra_instance_tl {default} -\tl_new:N \l__acro_page_instance_tl -\tl_set:Nn \l__acro_page_instance_tl {none} -\tl_new:N \l__acro_page_name_tl -\tl_new:N \l__acro_pages_name_tl -\tl_new:N \l__acro_next_page_tl -\tl_new:N \l__acro_next_pages_tl -\tl_new:N \l__acro_list_instance_tl -\tl_set:Nn \l__acro_list_instance_tl {description} -\tl_new:N \l__acro_list_type_tl -\tl_new:N \l__acro_list_heading_cmd_tl -\tl_set:Nn \l__acro_list_heading_cmd_tl {section*} -\tl_new:N \l__acro_list_name_tl -\tl_new:N \l__acro_list_before_tl -\tl_new:N \l__acro_list_after_tl -\tl_new:N \l__acro_custom_short_format_tl -\tl_new:N \l__acro_first_between_tl -\tl_new:N \l__acro_citation_connect_tl -\tl_new:N \l__acro_between_group_connect_citation_tl -\tl_new:N \l__acro_extra_brackets_tl -\tl_new:N \l__acro_extra_punct_tl -\tl_new:N \l__acro_first_brackets_tl -\tl_new:N \l__acro_page_punct_tl -\tl_new:N \l__acro_page_brackets_tl -\tl_new:N \l__acro_last_page_tl -\tl_new:N \l__acro_current_page_tl -\tl_new:N \l__acro_list_table_tl -\tl_new:N \l__acro_list_table_spec_tl -\tl_new:N \l__acro_acc_supp_tl -\tl_new:N \l__acro_acc_supp_options_tl -\tl_new:N \l__acro_label_prefix_tl -\tl_set:Nn \l__acro_label_prefix_tl {ac:} -\tl_new:N \l__acro_index_short_tl -\tl_new:N \l__acro_first_instance_tl -\tl_set:Nn \l__acro_first_instance_tl {default} -\tl_new:N \l__acro_short_tl -\tl_new:N \l__acro_short_format_tl -\tl_new:N \l__acro_list_short_format_tl -\tl_new:N \l__acro_alt_tl -\tl_new:N \l__acro_alt_format_tl -\tl_new:N \l__acro_long_tl -\tl_new:N \l__acro_long_format_tl -\tl_new:N \l__acro_list_long_format_tl -\tl_new:N \l__acro_single_form_tl -\tl_set:Nn \l__acro_single_form_tl {long} -\tl_new:N \l__acro_extra_format_tl -\tl_new:N \l__acro_foreign_format_tl -\tl_new:N \l__acro_foreign_list_format_tl -\tl_set:Nn \l__acro_foreign_list_format_tl { \acroenparen } -\tl_new:N \l__acro_index_format_tl - -\skip_new:N \l__acro_page_space_skip - -\dim_new:N \l__acro_short_width_dim -\dim_set:Nn \l__acro_short_width_dim {3em} - -\int_new:N \g__acro_barrier_int - -\seq_new:N \l__acro_endings_seq -\seq_new:N \l__acro_actions_seq -\seq_new:N \g__acro_declared_acronyms_seq - -\prop_new:N \l__acro_citation_prop -\prop_new:N \l__acro_citation_pre_prop -\prop_new:N \l__acro_citation_post_prop -\prop_new:N \l__acro_pdfstring_alt_prop -\prop_new:N \l__acro_pdfstring_short_prop -\prop_new:N \g__acro_properties_prop -\prop_new:N \l__acro_trailing_tokens_prop -\prop_new:N \l__acro_trailing_actions_prop -\prop_new:N \l__acro_list_styles_prop -\prop_new:N \l__acro_list_headings_prop -\prop_new:N \l__acro_first_styles_prop -\prop_new:N \l__acro_extra_styles_prop -\prop_new:N \l__acro_page_styles_prop +% +\bool_new:N \g__acro_final_bool -% -------------------------------------------------------------------------- -% logging: -\prg_new_conditional:Npnn \acro_if_log: {p,T,F,TF} +\prg_new_conditional:Npnn \acro_if_final: {p,T,F,TF} { - \bool_if:NTF \l__acro_log_acronyms_bool + \bool_if:NTF \g__acro_final_bool { \prg_return_true: } { \prg_return_false: } } -\keys_define:nn {acro} +% -------------------------------------------------------------------------- +% load-time options: +% #1: message name +\cs_new_protected:Npn \__acro_loadtime_error:n #1 + { \msg_error:nnV {acro} {#1} \l_keys_key_str } + +\cs_new_protected:Npn \__acro_loadtime_warning:n #1 + { \msg_warning:nnV {acro} {#1} \l_keys_key_str } + +\cs_generate_variant:Nn \msg_error:nnn {nnV} +\cs_generate_variant:Nn \msg_warning:nnn {nnV} + +\int_new:N \g__acro_version_int + +\keys_define:nn {acro/package} { - log .choice: , - log / true .code:n = - \bool_set_true:N \l__acro_log_acronyms_bool - \bool_set_false:N \l__acro_log_acronyms_verbose_bool , - log / silent .meta:n = { log = true } , - log / verbose .code:n = - \bool_set_true:N \l__acro_log_acronyms_bool - \bool_set_true:N \l__acro_log_acronyms_verbose_bool , - log / false .code:n = - \bool_set_false:N \l__acro_log_acronyms_bool - \bool_set_false:N \l__acro_log_acronyms_verbose_bool , - log .default:n = true , - log .initial:n = false - } - -\cs_new:Npn \__acro_write_log:nn #1#2 { \ \ \ #1 ~ = ~ {#2} } -\cs_new:Npn \__acro_write_log_property:nnn #1#2#3 - { \__acro_write_log:nn {#2} { \__acro_property_get:nn {#3} {#1} } } - -\cs_new:Npn \__acro_ending_log_entry:nn #1#2 - { - | \\ - | \__acro_write_log_property:nnn {#1} {short-#2} {short_#2} \\ - | \__acro_write_log_property:nnn {#1} {short-#2-form} {short_#2_form} \\ - | \__acro_write_log_property:nnn {#1} {long-#2} {long_#2} \\ - | \__acro_write_log_property:nnn {#1} {long-#2-form} {long_#2_form} \\ - | \__acro_write_log_property:nnn {#1} {alt-#2} {alt_#2} \\ - | \__acro_write_log_property:nnn {#1} {alt-#2-form} {alt_#2_form} \\ - | \__acro_write_log_property:nnn {#1} {foreign-#2} {foreign_#2} \\ - | \__acro_write_log_property:nnn {#1} {foreign-#2-form} {foreign_#2_form} \\ + debug .bool_gset:N = \g__acro_debug_bool , + debug .initial:n = false , + upgrade .bool_gset:N = \g__acro_upgrade_bool , + upgrade .initial:n = true , + final .bool_set:N = \g__acro_final_bool , + final .initial:n = false , + version .choice: , + version / 2 .code:n = \int_set:Nn \g__acro_version_int {2} , + version / 3 .code:n = \int_set:Nn \g__acro_version_int {3} , + version .initial:n = 3 , + unknown .code:n = \__acro_loadtime_warning:n {unknown-option} } - -\msg_new:nnn {acro} {log-acronym-verbose} - { - ================================================= \\ - | ~ \msg_info_text:n {acro}~ --~ defining~ new~ acronym: \\ - | \__acro_write_log:nn {ID} {#1} \\ - | \__acro_write_log_property:nnn {#1} {short} {short} \\ - | \__acro_write_log_property:nnn {#1} {long} {long} \\ - | \__acro_write_log_property:nnn {#1} {alt} {alt} \\ - | \__acro_write_log_property:nnn {#1} {sort} {sort} \\ - | \__acro_write_log_property:nnn {#1} {class} {class} \\ - | \__acro_write_log_property:nnn {#1} {list} {list} \\ - | \__acro_write_log_property:nnn {#1} {extra} {extra} \\ - | \__acro_write_log_property:nnn {#1} {foreign} {foreign} \\ - | \__acro_write_log_property:nnn {#1} {single} {single} \\ - | \__acro_write_log_property:nnn {#1} {pdfstring} {pdfstring} \\ - | \__acro_write_log_property:nnn {#1} {accsupp} {accsupp} \\ - | \__acro_write_log_property:nnn {#1} {tooltip} {tooltip} \\ - | \\ - | \__acro_write_log_property:nnn {#1} {short-indefinite} {short_indefinite} \\ - | \__acro_write_log_property:nnn {#1} {long-indefinite} {long_indefinite} \\ - | \__acro_write_log_property:nnn {#1} {alt-indefinite} {alt_indefinite} \\ - \seq_map_function:NN \l__acro_endings_seq \__acro_ending_log_entry:n - | \\ - | \__acro_write_log_property:nnn {#1} {short-format} {short_format} \\ - | \__acro_write_log_property:nnn {#1} {long-format} {long_format} \\ - | \__acro_write_log_property:nnn {#1} {first-long-format} {first_long_format} \\ - | \__acro_write_log_property:nnn {#1} {single-format} {single_format} \\ - | \__acro_write_log_property:nnn {#1} {foreign-lang} {foreign_lang} \\ - | \\ - | \__acro_write_log_property:nnn {#1} {cite} {citation} \\ - | \__acro_write_log_property:nnn {#1} {before-citation} {before_citation} \\ - | \__acro_write_log_property:nnn {#1} {after-citation} {after_citation} \\ - | \__acro_write_log_property:nnn {#1} {index} {index} \\ - | \__acro_write_log_property:nnn {#1} {index-sort} {index_sort} \\ - | \\ - | \__acro_write_log_property:nnn {#1} {long-pre} {long_pre} \\ - | \__acro_write_log_property:nnn {#1} {long-post} {long_post} \\ - | \__acro_write_log_property:nnn {#1} {post} {post} \\ - | \__acro_write_log_property:nnn {#1} {index-cmd} {index_cmd} \\ - | \__acro_write_log_property:nnn {#1} {first-style} {first_style} \\ - ================================================= - } - -\msg_new:nnn {acro} {log-acronym-silent} - { - ================================================= \\ - | ~ \msg_info_text:n {acro}~ --~ defining~ new~ acronym: \\ - | \__acro_write_log:nn {ID} {#1} \\ - | \__acro_write_log_property:nnn {#1} {short} {short} \\ - | \__acro_write_log_property:nnn {#1} {long} {long} \\ - | \__acro_write_log_property:nnn {#1} {alt} {alt} \\ - | \__acro_write_log_property:nnn {#1} {sort} {sort} \\ - | \__acro_write_log_property:nnn {#1} {class} {class} \\ - | \__acro_write_log_property:nnn {#1} {list} {list} \\ - | \__acro_write_log_property:nnn {#1} {extra} {extra} \\ - | \__acro_write_log_property:nnn {#1} {foreign} {foreign} \\ - | \__acro_write_log_property:nnn {#1} {cite} {citation} \\ - ================================================= + +\ProcessKeysPackageOptions {acro/package} + +\int_compare:nNnT \g__acro_version_int = 2 + { + \RequirePackage {acro2} + \file_input_stop: } - -\cs_new_protected:Npn \__acro_log_acronym:n #1 + +\keys_define:nn {acro/package} { - \bool_if:NT \l__acro_log_acronyms_bool - { - \cs_set:Npn \__acro_ending_log_entry:n ##1 - { \__acro_ending_log_entry:nn {#1} {##1} } - \bool_if:NTF \l__acro_log_acronyms_verbose_bool - { \msg_log:nnn {acro} {log-acronym-verbose} {#1} } - { \msg_log:nnn {acro} {log-acronym-silent} {#1} } - } - } + debug .code:n = \__acro_loadtime_error:n {load-time-option} , + upgrade .code:n = \__acro_loadtime_error:n {load-time-option} , + final .code:n = \__acro_loadtime_error:n {load-time-option} + } -% -------------------------------------------------------------------------- -% message macros: -\cs_new:Npn \__acro_remove_backslash:N #1 - { \exp_after:wN \use_none:n \token_to_str:N #1 } +% ---------------------------------------------------------------------------- +% temporary variables: +\tl_new:N \l__acro_tmpa_tl +\tl_new:N \l__acro_tmpb_tl +\tl_new:N \l__acro_tmpc_tl + +\str_new:N \l__acro_tmpa_str +\str_new:N \l__acro_tmpb_str +\str_new:N \l__acro_tmpc_str + +\bool_new:N \l__acro_tmpa_bool +\bool_new:N \l__acro_tmpb_bool +\bool_new:N \l__acro_tmpc_bool + +\seq_new:N \l__acro_tmpa_seq +\seq_new:N \l__acro_tmpb_seq +\seq_new:N \l__acro_tmpc_seq + +\int_new:N \l__acro_tmpa_int +\int_new:N \l__acro_tmpb_int +\int_new:N \l__acro_tmpc_int +\int_new:N \l__acro_tmpd_int + +\clist_new:N \l__acro_tmpa_clist +\clist_new:N \l__acro_tmpb_clist +\clist_new:N \l__acro_tmpc_clist -\cs_new_protected:Npn \acro_new_message_commands:Nnnn #1#2#3#4 +% ---------------------------------------------------------------------------- +% module mechanism: +\msg_new:nnn {acro} {module-missing} { - \clist_map_inline:nn {#2} + You've~ requested~ the~ acro~ module~ `#1'~ but~ it~ appears~ to~ + be~ missing~ on~ your~ system.~ Maybe~ you've~ misspelled~ the~ name?~ + Loading~ the~ module~ will~ abort~ \msg_line_context: + } + +\msg_new:nnn {acro} {loading-module} + { Loading~ module~ `#1'~ ... } + +\msg_new:nnn {acro} {wrong-module-name} + { The~ module~ file~ name~ is~ `#2'~ but~ it~ provides~ module~ `#1'. } + +\msg_new:nnn {acro} {forbidden-module} + { + You've~ requested~ the~ acro~ module~ `modules'~ \msg_line_context: .~ + This~ module~ is~ a~ pseudo~ module~ which~ may~ not~ be~ loaded~ through~ + the~ module~ loading~ mechansim. + } + +% ---------------------------------------------------------------------------- +\cs_generate_variant:Nn \str_if_eq:nnF {xx} +\cs_generate_variant:Nn \msg_error:nnnn {nnnx} + +\prg_new_conditional:Npnn \acro_package_if_loaded:n #1 {p,T,F,TF} + { + \cs_if_exist:cTF {ver@#1.sty} + { \prg_return_true: } + { \prg_return_false: } + } + +% ---------------------------------------------------------------------------- +% this is for external file modules called "styles": +\tl_const:Nn \c__acro_module_extension_tl {code.tex} +\tl_const:Nn \c__acro_module_prefix_tl {acro} + +\tl_new:N \g__acro_modules_loaded_tl + +\cs_new_protected:Npn \acro_modules_load:n #1 + { \clist_map_inline:nn {#1} { \acro_module_load:n {##1} } } + +\cs_new_protected:Npn \acro_module_load:n #1 + { + \tl_set:Nx \l_tmpa_tl { \tl_trim_spaces:n {#1} } + \str_if_eq:VnTF \l_tmpa_tl {modules} + { \msg_error:nn {acro} {forbidden-module} } + { \__acro_module_load:V \l_tmpa_tl } + } + +\cs_new_protected:Npn \__acro_module_load:n #1 + { + \acro_if_module_loaded:nF {#1} { - \cs_new_protected:cpn { \__acro_remove_backslash:N #1 ##1 } + \acro_module_if_exist:nTF {#1} { - \bool_if:NTF \l__acro_silence_bool - { \use:c { \__acro_remove_backslash:N #3 n##1 } {acro} } - { \use:c { \__acro_remove_backslash:N #4 n##1 } {acro} } + \__acro_module_hook_use:nn {#1} {before} + \msg_info:nnn {acro} {loading-module} {#1} + \@onefilewithoptions + {\c__acro_module_prefix_tl.#1}[][] + \c__acro_module_extension_tl + \__acro_module_hook_use:nn {#1} {after} } + { \msg_error:nnn {acro} {module-missing} {#1} } } } +\cs_generate_variant:Nn \__acro_module_load:n {V} -\acro_new_message_commands:Nnnn \acro_serious_message: {n,nn,nnn} - { \msg_warning: } - { \msg_error: } +\prg_new_conditional:Npnn \acro_if_module_loaded:n #1 {p,T,F,TF} + { + \tl_if_in:NnTF \g__acro_modules_loaded_tl {#1} + { \prg_return_true: } + { \prg_return_false: } + } -\acro_new_message_commands:Nnnn \acro_harmless_message: {n,nn,nnn,nnnn} - { \msg_info: } - { \msg_warning: } +\prg_new_conditional:Npnn \acro_module_if_exist:n #1 {p,T,F,TF} + { + \file_if_exist:nTF + {\c__acro_module_prefix_tl.#1.\c__acro_module_extension_tl} + { \prg_return_true: } + { \prg_return_false: } + } -\cs_new_protected:Npn \acro_option_deprecated:nn #1#2 +% -------------------------------------------------------------------------- +% module hooks: +% #1: module +% #2: code +\cs_new_protected:Npn \acro_module_after:nn #1#2 { - \tl_if_blank:nTF {#2} - { \acro_harmless_message:nnn {deprecated} {option} {#1} } - { \acro_harmless_message:nnnn {replaced} {option} {#1} {#2} } + \acro_if_module_loaded:nTF {#1} + {#2} + { \__acro_add_to_module_hook:nnn {#1} {after} {#2} } } -\cs_new_protected:Npn \acro_option_deprecated:n #1 - { \acro_option_deprecated:nn {#1} {} } -\cs_new_protected:Npn \acro_command_deprecated:NN #1#2 +% #1: module +% #2: code +\cs_new_protected:Npn \acro_module_before:nn #1#2 { - \tl_if_blank:nTF {#2} + % TODO: error in T case? + \acro_if_module_loaded:nF {#1} + { \__acro_add_to_module_hook:nnn {#1} {before} {#2} } + } + +% #1: module +% #2: hook name +% #3: code +\cs_new_protected:Npn \__acro_add_to_module_hook:nnn #1#2#3 + { + \acro_if_module_loaded:nF {#1} { - \acro_harmless_message:nnn {deprecated} {command} - { \token_to_str:N #1 } + \tl_if_exist:cF {g__acro_module_hook_#1_#2_tl} + { \tl_new:c {g__acro_module_hook_#1_#2_tl} } + \tl_gput_right:cn {g__acro_module_hook_#1_#2_tl} {#3} } + } + +% #1: module +% #2: hook name +\cs_new_protected:Npn \__acro_module_hook_use:nn #1#2 + { + \tl_if_exist:cT {g__acro_module_hook_#1_#2_tl} { - \acro_harmless_message:nnnn {replaced} {command} - { \token_to_str:N #1 } - { \token_to_str:N #2 } + \tl_use:c {g__acro_module_hook_#1_#2_tl} + \tl_gclear:c {g__acro_module_hook_#1_#2_tl} } } +\cs_generate_variant:Nn \__acro_module_hook_use:nn {V} % -------------------------------------------------------------------------- -% small commands for use at various places -\cs_new:Npn \acro_no_break: { \tex_penalty:D 10000 \scan_stop: } +\tl_new:N \l__acro_module_date_tl +\tl_new:N \l__acro_module_version_tl -\cs_new_protected:Npn \__acro_first_upper_case:n #1 - { \text_titlecase_first:n {#1} } -\cs_generate_variant:Nn \__acro_first_upper_case:n {x} +\tl_set_eq:NN \l__acro_module_date_tl \c_acro_date_tl +\tl_set_eq:NN \l__acro_module_version_tl \c_acro_version_tl -\cs_new_eq:NN \acro_first_upper_case:n \__acro_first_upper_case:n +\cs_new_protected:Npn \__acro_module:nn #1#2 + { + \tl_gput_right:Nn \g__acro_modules_loaded_tl {{#1}} + \str_if_eq:xxF + {\c__acro_module_prefix_tl.#1.\c__acro_module_extension_tl} + {\@currname.\@currext} + { + \msg_error:nnnxx {acro} {wrong-module-name} + {#1} + {\@currname.\@currext} + } + \ProvidesFile + {\c__acro_module_prefix_tl.#1.\c__acro_module_extension_tl} + [ + \l__acro_module_date_tl + \c_space_tl + v \l__acro_module_version_tl + \c_space_tl + acro~ style~ file~ `#1'~ (#2) + ] + } % -------------------------------------------------------------------------- -\tl_new:N \l_acro_config_file_name_tl -\tl_new:N \l_acro_config_file_extension_tl +% define internal acro modules: +\tl_new:N \g_acro_module_tl +\tl_new:N \g__acro_module_stop_tl -\tl_set:Nn \l_acro_config_file_name_tl {acro} -\tl_set:Nn \l_acro_config_file_extension_tl {cfg} +\cs_new_protected:Npn \acro_stop_module:n #1 + { \tl_gput_right:Nn \g__acro_module_stop_tl {{#1}} } + +% #1: name +% #2: description +\cs_new_protected:Npn \AcroModule #1#2 + { + \msg_log:nnnn {acro} {loading-module} {#1} {#2} + \tl_gput_right:Nn \g__acro_modules_loaded_tl {{#1}} + \tl_gset:Nn \g_acro_module_tl {#1} + \__acro_module_hook_use:nn {#1} {before} + \tl_map_inline:Nn \g__acro_module_stop_tl + { + \str_if_eq:nnT {##1} {#1} + { \tl_map_break:n { \__acro_gobble_module:w } } + } + } + +\cs_new_protected:Npn \AcroModuleEnd + { \__acro_module_hook_use:Vn \g_acro_module_tl {after} } + +\cs_new_protected:Npn \__acro_gobble_module:w #1 \AcroModuleEnd {} + +\bool_lazy_or:nnT + { \acro_if_final_p: } + { !\acro_if_upgrade_p: } + { \acro_stop_module:n {upgrade} } + +% -------------------------------------------------------------------------- +% style files +\NewDocumentCommand \AcroStyle {smO{}} + { + \__acro_module:nn {style.#2} {#3} + \IfBooleanT {#1} { \ExplSyntaxOn } + } + +\cs_new_protected:Npn \acro_style_load:n #1 + { \clist_map_inline:nn {#1} { \acro_module_load:n {style.##1} } } -% options: \keys_define:nn {acro} + { load-style .code:n = \acro_style_load:n {#1} } + +% -------------------------------------------------------------------------- +\acro_if_debug:TF + { + \cs_new_protected:Npn \__acro_debug_start:n #1 + { + \iow_term:n {} + \iow_term:n {#1} + \acro_package_if_loaded:nT {l3benchmark} { \benchmark_tic: } + } + \cs_new_protected:Npn \__acro_debug_stop: + { \acro_package_if_loaded:nT {l3benchmark} { \benchmark_toc: } } + } { - messages .choice: , - messages / silent .code:n = - \bool_set_true:N \l__acro_silence_bool , - messages / loud .code:n = - \bool_set_false:N \l__acro_silence_bool , - messages .value_required:n = true , - config-file-name .tl_set:N = \l_acro_config_file_name_tl , - config-file-name .initial:n = acro , - config-file-extension .tl_set:N = \l_acro_config_file_extension_tl , - config-file-extension .initial:n = cfg , - accsupp .bool_set:N = \l__acro_acc_supp_bool , - accsupp-options .tl_set:N = \l__acro_acc_supp_options_tl , - tooltip .bool_set:N = \l__acro_tooltip_bool , - tooltip-cmd .code:n = \cs_set:Npn \__acro_tooltip_cmd:nn {#1} , - tooltip-cmd .value_required:n = true , - macros .bool_set:N = \l__acro_create_macros_bool , - xspace .bool_set:N = \l__acro_xspace_bool , - % xspace .code:n = \acro_option_deprecated:nn {xspace} {} , - strict .bool_set:N = \l__acro_strict_bool , - case-sensitive .bool_set:N = \g__acro_case_sensitive_bool , - case-sensitive .initial:n = true , - sort .bool_set:N = \l__acro_sort_bool , - short-format .code:n = - \tl_set:Nn \l__acro_short_format_tl {#1} - \tl_set_eq:NN \l__acro_alt_format_tl \l__acro_short_format_tl - \tl_set:Nn \l__acro_list_short_format_tl {#1} , - short-format .value_required:n = true , - alt-format .tl_set:N = \l__acro_alt_format_tl , - alt-format .value_required:n = true , - long-format .code:n = - \tl_set:Nn \l__acro_long_format_tl {#1} - \tl_set:Nn \l__acro_first_long_format_tl {#1} - \tl_set:Nn \l__acro_list_long_format_tl {#1} , - long-format .value_required:n = true , - first-long-format .code:n = - \tl_set:Nn \l__acro_first_long_format_tl {#1} , - first-long-format .value_required:n = true , - single-format .tl_set:N = \l__acro_single_format_tl , - single-format .value_required:n = true , - format-include-endings .bool_set:N = \l__acro_include_endings_format_bool , - display-foreign .bool_set:N = \l__acro_foreign_bool , - foreign-format .tl_set:N = \l__acro_foreign_format_tl , - foreign-format .value_required:n = true , - list-short-format .tl_set:N = \l__acro_list_short_format_tl , - list-short-format .value_required:n = true , - list-short-width .dim_set:N = \l__acro_short_width_dim , - list-short-width .value_required:n = true , - list-long-format .tl_set:N = \l__acro_list_long_format_tl , - list-long-format .value_required:n = true , - list-foreign-format .tl_set:N = \l__acro_foreign_list_format_tl , - list-foreign-format .value_required:n = true , - override-list-format .bool_set:N = \l__acro_override_list_format_bool , - override-list-format .initial:n = true , - extra-format .tl_set:N = \l__acro_extra_format_tl , - extra-format .value_required:n = true , - single .bool_set:N = \l__acro_single_use_bool , - single-form .tl_set:N = \l__acro_single_form_tl , - single-form .value_required:n = true , - first-style .code:n = \acro_set_first_style:n {#1} , - first-style .value_required:n = true , - extra-style .code:n = \acro_set_extra_style:n {#1} , - extra-style .value_required:n = true , - label .bool_set:N = \l__acro_place_label_bool , - label-prefix .tl_set:N = \l__acro_label_prefix_tl , - label-prefix .value_required:n = true , - pages .choice: , - pages / all .code:n = - \bool_set_true:N \l__acro_list_all_pages_bool , - pages / first .code:n = - \bool_set_true:N \l__acro_place_label_bool - \bool_set_false:N \l__acro_list_all_pages_bool , - pages .value_required:n = true , - page-ref .code:n = - \acro_option_deprecated:nn {page-ref} {page-style} - \acro_set_page_style:n {#1} , - page-style .code:n = \acro_set_page_style:n {#1} , - page-style .value_required:n = true , - page-name .tl_set:N = \l__acro_page_name_tl , - page-name .value_required:n = true , - pages-name .tl_set:N = \l__acro_pages_name_tl , - pages-name .value_required:n = true , - following-page .bool_set:N = \l__acro_following_page_bool , - following-pages .bool_set:N = \l__acro_following_pages_bool , - following-pages* .meta:n = - { following-page = #1 , following-pages = #1 } , - following-pages* .default:n = true , - next-page .tl_set:N = \l__acro_next_page_tl , - next-page .value_required:n = true , - next-pages .tl_set:N = \l__acro_next_pages_tl , - next-pages .value_required:n = true , - list-style .code:n = \acro_set_list_style:n {#1} , - list-style .value_required:n = true , - list-heading .code:n = \acro_set_list_heading:n {#1} , - list-heading .value_required:n = true , - list-name .tl_set:N = \l__acro_list_name_tl , - list-name .value_required:n = true , - hyperref .bool_set:N = \l__acro_hyperref_use_bool , - only-used .bool_set:N = \l__acro_print_only_used_bool , - mark-as-used .choice: , - mark-as-used / first .code:n = - \bool_gset_true:N \g__acro_mark_first_as_used_bool , - mark-as-used / any .code:n = - \bool_gset_false:N \g__acro_mark_first_as_used_bool , - mark-as-used .default:n = any , - list-caps .bool_set:N = \l__acro_capitalize_list_bool , - cite .choice: , - cite / all .code:n = - \bool_set_true:N \l__acro_citation_all_bool - \bool_set_true:N \l__acro_citation_first_bool , - cite / none .code:n = - \bool_set_false:N \l__acro_citation_all_bool - \bool_set_false:N \l__acro_citation_first_bool , - cite / first .code:n = - \bool_set_false:N \l__acro_citation_all_bool - \bool_set_true:N \l__acro_citation_first_bool , - cite .default:n = all , - cite-cmd .code:n = - \cs_set:Npn \__acro_citation_cmd:w {#1} , - cite-cmd .value_required:n = true , - group-cite-cmd .code:n = - \cs_set:Npn \__acro_group_citation_cmd:w {#1} , - group-cite-cmd .value_required:n = true , - group-citation .bool_set:N = \l__acro_group_citation_bool , - cite-connect .tl_set:N = \l__acro_citation_connect_tl , - cite-connect .initial:n = \nobreakspace , - cite-connect .value_required:n = true , - group-cite-connect .tl_set:N = \l__acro_between_group_connect_citation_tl , - group-cite-connect .initial:n = {,\nobreakspace} , - group-cite-connect .value_required:n = true , - index .bool_set:N = \l__acro_addto_index_bool , - index-cmd .code:n = - \cs_set:Npn \__acro_index_cmd:n {#1} , - index-cmd .value_required:n = true , - uc-cmd .code:n = - \cs_set_eq:NN \__acro_first_upper_case:n #1 , - uc-cmd .value_required:n = true , - uppercase-short .bool_set:N = \l__acro_upper_short_bool , - uppercase-short .initial:n = true - } - -\AtBeginDocument - { - \bool_if:NTF \l__acro_xspace_bool - { - \@ifpackageloaded {xspace} - { } - { \RequirePackage {xspace} } - \cs_new_eq:NN \acro_xspace: \xspace - } - { \cs_new:Npn \acro_xspace: {} } + \cs_new_protected:Npn \__acro_debug_start:n #1 {} + \cs_new_protected:Npn \__acro_debug_stop: {} } +% -------------------------------------------------------------------------- +\AcroModule{base}{basic functionality of the package} % -------------------------------------------------------------------------- -% we use xtemplate for different object types and with a different number of -% arguments; let's declare functions for usage later so we don't have to -% bother +% variants of kernel functions: +\cs_generate_variant:Nn \bool_lazy_any:nTF {e} +\cs_generate_variant:Nn \bool_lazy_all:nTF {e} +\cs_generate_variant:Nn \seq_gset_split:Nnn {cVx} +\cs_generate_variant:Nn \seq_use:Nn {cV} +\cs_generate_variant:Nn \seq_set_split:Nnn {Nnx} +\cs_generate_variant:Nn \seq_if_in:NnTF {Ne} +\cs_generate_variant:Nn \seq_if_in:NnF {ceF} +\cs_generate_variant:Nn \seq_gremove_all:Nn {cV} +\cs_generate_variant:Nn \seq_put_right:Nn {Ne} +\cs_generate_variant:Nn \seq_gput_right:Nn {Ne,ce} +\cs_generate_variant:Nn \seq_set_split:Nnn {Nne} +\cs_generate_variant:Nn \clist_if_empty:nTF {e} +\cs_generate_variant:Nn \clist_item:nn {e} +\cs_generate_variant:Nn \int_set:Nn {Nx} +\cs_generate_variant:Nn \tl_set:Nn {Ne} +\cs_generate_variant:Nn \tl_remove_all:Nn {NV} +\cs_generate_variant:Nn \tl_remove_once:Nn {NV} +\cs_generate_variant:Nn \tl_if_in:NnF {NV} +\cs_generate_variant:Nn \tl_put_right:Nn {Ne} +\cs_generate_variant:Nn \clist_set:Nn {Ne} +\cs_generate_variant:Nn \str_if_eq:nnT {x} +\cs_generate_variant:Nn \str_fold_case:n {e} +\cs_generate_variant:Nn \str_lowercase:n {e} +\cs_generate_variant:Nn \msg_error:nnnnn {nnnxx} +\cs_generate_variant:Nn \msg_warning:nn {nV} +\cs_generate_variant:Nn \msg_error:nnnn {nne} +\cs_generate_variant:Nn \prg_new_conditional:Npnn {c} +\cs_generate_variant:Nn \file_get_mdfive_hash:nN {V} +\cs_generate_variant:Nn \iow_open:Nn {NV} +\cs_generate_variant:Nn \use_ii:nn {ne} +\cs_generate_variant:Nn \keys_set:nn {nV} + +% -------------------------------------------------------------------------- +\prg_new_conditional:Npnn \acro_class_if_loaded:n #1 {p,T,F,TF} + { + \cs_if_exist:cTF {ver@#1.cls} + { \prg_return_true: } + { \prg_return_false: } + } -% objects with one argument: -\cs_new_protected:Npn \acro_page_number_instance:nn #1#2 - { \UseInstance {acro-page-number} {#1} {#2} } -\cs_generate_variant:Nn \acro_page_number_instance:nn {V} +\prg_new_conditional:Npnn \acro_if_komascript: {p,T,F,TF} + { + \cs_if_exist:NTF \KOMAClassName + { \prg_return_true: } + { \prg_return_false: } + } -\cs_new_protected:Npn \acro_extra_instance:nn #1#2 - { \UseInstance {acro-extra} {#1} {#2} } -\cs_generate_variant:Nn \acro_extra_instance:nn {VV} +% -------------------------------------------------------------------------- +% attributes instead of property lists: +\msg_new:nnn {acro} {attribute-not-set} + { The~ attribute~ `#1'~ is~ not~ set~ \msg_line_context: } -\cs_new_protected:Npn \acro_title_instance:nn #1#2 - { \UseInstance {acro-title} {#1} {#2} } -\cs_generate_variant:Nn \acro_title_instance:nn {VV} +\msg_new:nnn {acro} {attribute-defined} + { The~ attribute~ `#1'~ is~ already~ defined~ \msg_line_context: } -% objects with two arguments: -\cs_new_protected:Npn \acro_list_instance:nnn #1#2#3 - { \UseInstance {acro-list} {#1} {#2} {#3} } -\cs_generate_variant:Nn \acro_list_instance:nnn {VVV} +\msg_new:nnn {acro} {attribute-undefined} + { The~ attribute~ `#1'~ is~ not~ yet~ defined~ \msg_line_context: } -\cs_new_protected:Npn \acro_first_instance:nn #1#2 +\prg_new_conditional:Npnn \acro_attribute_if_exist:n #1 {p,T,F,TF} { - \acro_property_if_set:nnTF {#1} {first-style} + \cs_if_exist:cTF {____acro_attribute_main_ \tl_to_str:n {#1} :} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: attribute +\cs_new_protected:Npn \acro_attribute_new:n #1 + { + \acro_attribute_if_exist:nTF {#1} + { \msg_error:nnn {acro} {attribute-defined} {#1} } + { \cs_gset:cpx {____acro_attribute_main_ \tl_to_str:n {#1} :} {} } + } + +% #1: attribute +% #2: item +% #3: value +\cs_new_protected:Npn \acro_attribute_set:nnn #1#2#3 + { + \acro_attribute_if_exist:nTF {#1} { - \tl_set_eq:NN - \l__acro_tmpa_tl - \l__acro_first_style_tl + \cs_gset:cpx + {____acro_attribute_ \tl_to_str:n {#1::#2} :} + { \exp_not:n { \exp_not:n {#3} } } } + { \msg_error:nnn {acro} {attribute-undefined} {#1} } + } +\cs_generate_variant:Nn \acro_attribute_set:nnn {nnx,nne} + +% #1: attribute +% #2: item +\cs_new_protected:Npn \acro_attribute_unset:nn #1#2 + { \cs_undefine:c {____acro_attribute_ \tl_to_str:n {#1::#2} :} } + +% #1: attribute +% #2: item +\cs_new:Npn \acro_attribute_get:nn #1#2 + { + \acro_attribute_if_exist:nTF {#1} { - \tl_set_eq:NN - \l__acro_tmpa_tl - \l__acro_first_instance_tl + \cs_if_exist:cTF {____acro_attribute_ \tl_to_str:n {#1::#2} :} + { \use:c {____acro_attribute_ \tl_to_str:n {#1::#2} :} } + { + \acro_if_debug:T + { \msg_expandable_error:nnn {acro} {attribute-not-set} {#1::#2} } + } } - \acro_if_defined:nT {#1} + { \msg_expandable_error:nnn {acro} {attribute-undefined} {#1} } + } +\cs_generate_variant:Nn \acro_attribute_get:nn {ne} + +% #1: attribute +% #2: item +\prg_new_conditional:Npnn \acro_attribute_if_set:nn #1#2 {p,T,F,TF} + { + \acro_attribute_if_exist:nTF {#1} { - \use:x { - \UseInstance {acro-first} - { \exp_not:V \l__acro_tmpa_tl } - { \exp_not:n {#1} } - { \exp_not:n {#2} } - } + \cs_if_exist:cTF {____acro_attribute_ \tl_to_str:n {#1::#2} :} + { \prg_return_true: } + { \prg_return_false: } } + { \prg_return_false: } } -\cs_generate_variant:Nn \acro_first_instance:nn {nV} +\prg_generate_conditional_variant:Nnn \acro_attribute_if_set:nn {ne} {p,T,F,TF} -% -------------------------------------------------------------------------- -% hyperref support -\cs_new_eq:NN \acro_hyper_target:nn \use_ii:nn -\cs_new_eq:NN \acro_hyper_link:nn \use_ii:nn +% #1: attribute +% #2: item +\prg_new_conditional:Npnn \__acro_if_attribute_eq:nnn #1#2#3 {p,T,F,TF} + { + \tl_if_eq:enTF + { \use:c {____acro_attribute_ \tl_to_str:n {#1::#2} :} } + {#3} + { \prg_return_true: } + { \prg_return_false: } + } -\cs_new_protected:Npn \acro_activate_hyperref_support: +% #1: attribute +% #2: item +\cs_new_protected:Npn \acro_attribute_show:nn #1#2 { - \bool_lazy_and:nnT - { \l__acro_hyperref_loaded_bool } - { \l__acro_hyperref_use_bool } + \acro_attribute_if_exist:nTF {#1} { - \sys_if_engine_xetex:TF + \iow_term:n {} + \iow_term:x { - \cs_set:Npn \acro_hyper_link:nn ##1##2 - { \hyperlink {##1} { \XeTeXLinkBox {##2} } } + \c_space_tl \c_space_tl + \tl_to_str:n {#1::#2} + \c_space_tl \c_space_tl == \c_space_tl \c_space_tl + {\use:c {____acro_attribute_ \tl_to_str:n {#1::#2} :}} } - { \cs_set_eq:NN \acro_hyper_link:nn \hyperlink } - \cs_set:Npn \acro_hyper_target:nn ##1##2 - { \raisebox {3ex} [0pt] { \hypertarget {##1} { } } ##2 } + \iow_term:n {} } + { \msg_error:nnn {acro} {attribute-undefined} {#1} } } -% #1: id -% #2: text -\cs_new_protected:Npn \__acro_make_link:nn #1#2 +% ---------------------------------------------------------------------------- +% option setup: +\cs_new_protected:Npn \acro_setup:n #1 + { \keys_set:nn {acro} {#1} } + +% ---------------------------------------------------------------------------- +\AcroModuleEnd +\AcroModule{interface}{definitions of user commands} + +% -------------------------------------------------------------------------- +% helper commands +\NewDocumentCommand \AcroAddRow {+m} { - \bool_lazy_and:nnTF - { \l__acro_hyperref_use_bool } - { \l__acro_hyperref_loaded_bool } + \tl_put_right:Ne \AcronymTable { - \acro_hyper_link:nn {#1} { \phantom {#2} } - \acro_if_is_single:nTF {#1} - { \hbox_overlap_left:n {#2} } - { \acro_color_link:n { \hbox_overlap_left:n {#2} } } - } - {#2} + \exp_not:n { \tl_gset:Nn \AcronymID } { \AcronymID } + \exp_not:n {#1} + } } -\cs_new:Npn \acro_color_link:n #1 +\NewDocumentCommand \AcroRerun {} + { \acro_rerun:n {list} } + +\NewDocumentCommand \AcroPropertiesMap {+m} + { \acro_properties_map:n {#1} } + +\NewDocumentCommand \AcroMap {m+m} + { \acro_list_map:nn {#1} {#2} } + +\NewDocumentCommand \AcroNeedPackage {m} { - \cs_if_exist:NTF \hypersetup - { - \ifHy@colorlinks - \exp_after:wN \use_i:nn - \else - \ifHy@ocgcolorlinks - \exp_after:wN \use_i:nn - \else - \exp_after:wN \exp_after:wN \exp_after:wN \use_ii:nn - \fi - \fi - { \textcolor { \@linkcolor } {#1} } - {#1} - } - {#1} + \acro_package_if_loaded:nF {m} + { \msg_error:nnen {acro} {package-needed} { \TemplateName } {#1} } } -\AtBeginDocument{ - \cs_if_exist:NF \textcolor { \cs_new_eq:NN \textcolor \use_ii:nn } -} +% -------------------------------------------------------------------------- +% general commands: +\NewDocumentCommand \acsetup {+m} + { \acro_setup:n {#1} } + +\NewDocumentCommand \acroloadstyle {m} + { \acro_style_load:n {#1} } + +\NewExpandableDocumentCommand \acroifusedTF {m} + { \acro_boolean_property_if:nnTF {#1} {used} } + +\NewDocumentCommand \acuse {m} + { \acro_use:n {#1} } + +\NewDocumentCommand \acuseall {} + { \acro_use_all: } + +\NewDocumentCommand \acreset {m} + { \acro_reset:n {#1} } + +\NewDocumentCommand \acresetall {} + { \acro_reset_all: } + +\NewExpandableDocumentCommand \acsimple {mm} + { \acro_pdfstring_template:nn {#1} {#2} } + +\NewDocumentCommand \acbarrier {} + { \acro_barrier: } + +\NewDocumentCommand \acswitchoff {} + { \acro_switch_off: } + +\NewDocumentCommand \acswitchon {} + { \acro_switch_on: } % -------------------------------------------------------------------------- -% output style of the first time an acronym is used +\NewDocumentCommand \DeclareAcroProperty {st?t!t|m} + { \acro_property_declare:nnnnn {#1} {#2} {#3} {#4} {#5} } -% helper macros for the styles -% #1: short|long -% #2: id -% #3: long -\cs_new_protected:Npn \__acro_print_form_and_indefinite:nnn #1#2#3 +\NewDocumentCommand \DeclareAcroPropertyAlias {st?t!t|mm} { - \group_begin: - \acro_for_all_trailing_tokens_do:n - { \acro_deactivate_trailing_action:n {##1} } - \str_case:nn {#1} - { - {long} { - \bool_lazy_or:nnT - { \l__acro_first_only_long_bool } - { !\l__acro_first_only_short_bool } - { - \acro_write_indefinite:nn {#2} {long} - \acro_write_expanded:nnn {#2} {first-long} {#3} - } - } - {short} { - \bool_lazy_or:nnT - { !\l__acro_first_only_long_bool } - { \l__acro_first_only_short_bool } - { - \acro_soft_upper: - \acro_write_indefinite:nn {#2} {short} - \acro_write_compact:nn {#2} {short} - } - } - } - \group_end: + \acro_property_declare:nnnnn {#1} {#2} {#3} {#4} {#5} + \acro_property_make_alias:nn {#5} {#6} } -\cs_new_protected:Npn \__acro_open_bracket: +\NewDocumentCommand \MakeAcroPropertyAlias {mm} + { \acro_property_make_alias:nn {#1} {#2} } + +\NewDocumentCommand \UseAcroTemplate {O{acronym}mO{1}} + { \acro_template_use:nnn {#3} {#1} {#2} } + +\NewDocumentCommand \NewAcroTemplate {O{acronym}m+m} + { \use:c {acro_#1_template_new:nn} {#2} {#3} } + +\NewDocumentCommand \RenewAcroTemplate {O{acronym}m+m} + { \use:c {acro_#1_template_renew:nn} {#2} {#3} } + +\NewDocumentCommand \DeclareAcronym {m+m} + { \acro_declare_acronym:nn {#1} {#2} } + +\NewDocumentCommand \DeclareAcroEnding {mmm} + { \acro_declare_ending:nnn {#1} {#2} {#3} } + +\NewDocumentCommand \DeclareAcroArticle {mm} + { \acro_article_declare:nn {#1} {#2} } + +\NewDocumentCommand \DeclareAcroTranslation {m+m} + { \acro_declare_translations:nn {#1} {#2} } + +\NewDocumentCommand \AddAcroTranslations {m+m} + { \acro_add_translations:nn {#1} {#2} } + +\NewExpandableDocumentCommand \acrotranslate {m} + { \acro_translate:n {#1} } + +\NewExpandableDocumentCommand \aciftrailing {} + { \acro_trailing_if_tokens:nTF } + +\NewDocumentCommand \acfootnote {m} + { \acro_footnote:n {#1} } + +\NewDocumentCommand \acgobbletrail {} + { \bool_gset_true:N \g__acro_gobble_trail_bool } + +\NewExpandableDocumentCommand \acdot {} { \acro_dot: } +\NewExpandableDocumentCommand \acspace {} { \acro_space: } +\NewExpandableDocumentCommand \abbrdot {} { .\@ } + +\NewDocumentCommand \acroupper {} { \acro_upper: } +\NewDocumentCommand \acrofull {} { \acro_first: } + +\NewDocumentCommand \printacronyms {o} { - \bool_lazy_and:nnT - { !\l__acro_first_only_long_bool } - { !\l__acro_first_only_short_bool } - { - \acro_space: - \tl_if_blank:VF \l__acro_first_between_tl - { - \tl_use:N \l__acro_first_between_tl - \acro_space: - } - \bool_if:NT \l__acro_first_use_brackets_bool - { \tl_head:N \l__acro_first_brackets_tl } - } + \group_begin: + \IfNoValueF {#1} + { \keys_set:nn {acro/list} {#1} } + \acro_list: + \group_end: } -\cs_new_protected:Npn \__acro_close_bracket: +% -------------------------------------------------------------------------- +% commands for list templates +\NewDocumentCommand \acroheading {} { \acro_heading: } +\NewDocumentCommand \acropreamble {} { \acro_preamble: } + +\NewExpandableDocumentCommand \acrolistname {} + { \tl_use:N \l__acro_list_name_tl } + +% -------------------------------------------------------------------------- +% cmmands for use in templates: +\NewDocumentCommand \acronymsmapTF {+m+m+m} { - \bool_lazy_all:nT + \acro_acronyms_map:nTF { - { \l__acro_first_use_brackets_bool } - { !\l__acro_first_only_short_bool } - { !\l__acro_first_only_long_bool } + \tl_set:Nn \AcronymID {##1} + #1 } - { \tl_tail:N \l__acro_first_brackets_tl } + {#2} + {#3} } - -% #1: short|long -% #2: id -% #3: long -\cs_new_protected:Npn \__acro_print_form:nnn #1#2#3 + +\NewDocumentCommand \acronymsmapT {+m+m} + { \acronymsmapTF {#1} {#2} {} } + +\NewDocumentCommand \acronymsmapF {+m+m} + { \acronymsmapTF {#1} {} {#2} } + +\NewDocumentCommand \acronymsmap {+m} + { \acronymsmapTF {#1} {} {} } + +\NewExpandableDocumentCommand \acrofield {mm} + { \acro_property_get:nn {#1} {#2} } + +\NewDocumentCommand \acroprintfield {mm} { - \str_case:nn {#1} + \acro_property_if_eq:nnTF {#2} {list} { - {long} { - \bool_lazy_or:nnT - { \l__acro_first_only_long_bool } - { !\l__acro_first_only_short_bool } - { - \group_begin: - \bool_set_false:N \l__acro_first_upper_bool - \acro_write_expanded:nnn {#2} {first-long} {#3} - \group_end: - } - } - {short} { - \bool_lazy_or:nnT - { !\l__acro_first_only_long_bool } - { \l__acro_first_only_short_bool } - { - \group_begin: - \acro_soft_upper: - \acro_write_compact:nn {#2} {short} - \group_end: - } - } + \bool_if:NT \l__acro_upper_list_bool { \acro_upper: } + \acro_write:en {#1} {#2} } + { \acro_write:en {#1} {#2} } } -% #1: id -\cs_new_protected:Npn \__acro_foreign_sep:n #1 +\NewExpandableDocumentCommand \acrofieldifTF {+m+m+m+m} + { \acro_property_if_set:nnTF {#1} {#2} {#3} {#4} } + +\NewDocumentCommand \acroifanyfieldTF {mm+m+m} + { \acro_property_if_any:nnTF {#1} {#2} {#3} {#4} } + +\NewDocumentCommand \acroifallfieldsTF {mm+m+m} + { \acro_property_if_all:nnTF {#1} {#2} {#3} {#4} } + +\NewExpandableDocumentCommand \acroifpagefieldTF {m} + { \acro_if_pages:nTF {#1} } + +\NewDocumentCommand \acrowrite {m} + { \acroprintfield { \AcronymID } {#1} } + +\NewDocumentCommand \acroshow {m} + { \acro_property_show:en { \AcronymID } {#1} } + +\NewDocumentCommand \acrodonotuse {} + { \acro_use_false: } + +\NewDocumentCommand \acroformat {mm} + { \acro_format:enn { \AcronymID } {#1} {#2} } + +\NewDocumentCommand \acrogroupcite {} { - \bool_lazy_all:nT + \bool_if:NT \l__acro_cite_group_bool { - { \l__acro_foreign_bool } - { !\l__acro_first_only_short_bool } - { !\l__acro_first_only_long_bool } + \tl_set_eq:NN \l__acro_cite_pre_tl \l__acro_cite_between_tl + \cs_set_eq:NN \__acro_cite_cmd:w \__acro_cite_group_cmd:w + \acro_cite_if:neT { \l__acro_star_bool } { \AcronymID } + { \acro_cite:e { \AcronymID } } } - { \acro_if_foreign:nT {#1} { \tl_use:N \l__acro_foreign_sep_tl } } } - -% #1: id -\cs_new_protected:Npn \__acro_print_foreign:n #1 + +\NewDocumentCommand \acrocite {} + { \bool_set_true:N \l__acro_cite_always_bool } + +\NewDocumentCommand \acroifTF {m+m+m} + { \acro_property_if_set:enTF { \AcronymID } {#1} {#2} {#3} } +\NewDocumentCommand \acroifT {m+m} + { \acro_property_if_set:enTF { \AcronymID } {#1} {#2} {} } +\NewDocumentCommand \acroifF {m+m} + { \acro_property_if_set:enTF { \AcronymID } {#1} {} {#2} } + +\NewDocumentCommand \acroifanyTF {m+m+m} + { \acro_property_if_any:enTF { \AcronymID } {#1} {#2} {#3} } +\NewDocumentCommand \acroifanyT {m+m} + { \acro_property_if_any:enTF { \AcronymID } {#1} {#2} {} } +\NewDocumentCommand \acroifanyF {m+m} + { \acro_property_if_any:enTF { \AcronymID } {#1} {} {#2} } + +\NewDocumentCommand \acroifallTF {m+m+m} + { \acro_property_if_all:enTF { \AcronymID } {#1} {#2} {#3} } +\NewDocumentCommand \acroifallT {m+m} + { \acro_property_if_all:enTF { \AcronymID } {#1} {#2} {} } +\NewDocumentCommand \acroifallF {m+m} + { \acro_property_if_all:enTF { \AcronymID } {#1} {} {#2} } + +\NewDocumentCommand \acroifsingleTF {+m+m} + { \acro_if_single:eTF { \AcronymID } {#1} {#2} } +\NewDocumentCommand \acroifsingleT {+m} + { \acro_if_single:eTF { \AcronymID } {#1} {} } +\NewDocumentCommand \acroifsingleF {+m} + { \acro_if_single:eTF { \AcronymID } {} {#1} } + +\NewDocumentCommand \acroiffirstTF {+m+m} + { \acro_if_first:eTF { \AcronymID } {#1} {#2} } +\NewDocumentCommand \acroiffirstT {+m} + { \acro_if_first:eTF { \AcronymID } {#1} {} } +\NewDocumentCommand \acroiffirstF {+m} + { \acro_if_first:eTF { \AcronymID } {} {#1} } + +\NewDocumentCommand \acroiftagTF {m+m+m} + { \acro_if_tag:enTF { \AcronymID } {#1} {#2} {#3} } +\NewDocumentCommand \acroiftagT {m+m} + { \acro_if_tag:enT { \AcronymID } {#1} {#2} } +\NewDocumentCommand \acroiftagF {m+m} + { \acro_if_tag:enF { \AcronymID } {#1} {#2} } + +\NewDocumentCommand \acropages {mm} + { \acro_print_pages:enn { \AcronymID } {#1} {#2} } + +\NewDocumentCommand \acronopagerange {} + { \acro_no_page_ranges:e { \TemplateName } } + +\NewDocumentCommand \acropagefill {} + { \acro_if_pages:eT { \AcronymID } { \tl_use:N \l__acro_pages_fill_tl } } + +\NewExpandableDocumentCommand \acroifpagesTF {} + { \acro_if_pages:eTF { \AcronymID } } + +\NewExpandableDocumentCommand \acroifpagesT {} + { \acro_if_pages:eT { \AcronymID } } + +\NewExpandableDocumentCommand \acroifpagesF {} + { \acro_if_pages:eF { \AcronymID } } + +\NewExpandableDocumentCommand \acroifchapterTF {} + { \cs_if_exist:NTF \chapter } + +\NewExpandableDocumentCommand \acroifchapterT {} + { \cs_if_exist:NT \chapter } + +\NewExpandableDocumentCommand \acroifchapterF {} + { \cs_if_exist:NF \chapter } + +% -------------------------------------------------------------------------- +\AcroModuleEnd +\AcroModule{aux}{usage of auxiliary files} + +\cs_new_protected:Npn \ACRO #1 { \use:c {__acro_aux_#1:} } + +\cs_new_protected:Npn \__acro_auxlist_field_new:cpn #1 + { \cs_new_protected:cpn {__acro_aux_#1:} } + +\cs_new_protected:Npn \acro_auxlist_to_aux:nn #1#2 + { \acro_write_to_aux:x { \token_to_str:N \ACRO {#1} #2 } } + +\tl_const:Nx \c_acro_auxfile_tl { \c_sys_jobname_str .acr } + +\iow_new:N \l__acro_aux_file_iow +\tl_new:N \g__acro_mdfive_hash_tl + +\acro_at_begin_document:n { - \acro_if_foreign:nT {#1} + \legacy_if:nT {@filesw} { - \bool_lazy_all:nT - { - { \l__acro_foreign_bool } - { !\l__acro_first_only_short_bool } - { !\l__acro_first_only_long_bool } - } - { - \acro_write_foreign:n {#1} - \acro_endings:nn {#1} {foreign} - } + \iow_now:Nx \@auxout + { \token_to_str:N \providecommand \token_to_str:N \ACRO [1] {} } } + \file_get_mdfive_hash:VN + \c_acro_auxfile_tl + \g__acro_mdfive_hash_tl + \iow_open:NV \l__acro_aux_file_iow \c_acro_auxfile_tl } -\cs_new_protected:Npn \__acro_print_citation:n #1 +\cs_new_protected:Npn \acro_close_aux: { - \bool_if:NT \l__acro_group_citation_bool - { \acro_group_cite:n {#1} } + \iow_close:N \l__acro_aux_file_iow + \file_get_mdfive_hash:VN + \c_acro_auxfile_tl + \l__acro_tmpa_tl + \tl_if_eq:NNF \g__acro_mdfive_hash_tl \l__acro_tmpa_tl + { \acro_rerun:n {general} } + \legacy_if:nT {@filesw} + { \iow_now:Nx \@auxout { \token_to_str:N \ACRO {readaux} } } } -\cs_new_protected:Npn \__acro_finalize_first:n #1 +\cs_new_protected:Npn \acro_write_to_aux:n #1 { - \bool_if:NF \l__acro_group_citation_bool - { \acro_cite_if:Nn \l__acro_citation_first_bool {#1} } - \acro_index_if:Nn \l__acro_addto_index_bool {#1} - \acro_property_get:nnT {#1} {post} - { \tl_use:N \l__acro_post_tl } + \legacy_if:nT {@filesw} + { \iow_now:Nn \l__acro_aux_file_iow {#1} } } +\cs_generate_variant:Nn \acro_write_to_aux:n {x} -% -------------------------------------------------------------------------- -% the `acro-first' object, templates, instances: -% #1: id -% #2: long -\DeclareObjectType {acro-first} {2} - -% template for inline appearance: -\DeclareTemplateInterface {acro-first} {inline} {2} - { - brackets : boolean = true , - brackets-type : tokenlist = () , - only-short : boolean = false , - only-long : boolean = false , - reversed : boolean = false , - between : tokenlist , - foreign-sep : tokenlist = {,~} - } -\DeclareTemplateCode {acro-first} {inline} {2} - { - brackets = \l__acro_first_use_brackets_bool , - brackets-type = \l__acro_first_brackets_tl , - only-short = \l__acro_first_only_short_bool , - only-long = \l__acro_first_only_long_bool , - reversed = \l__acro_first_reversed_bool , - between = \l__acro_first_between_tl , - foreign-sep = \l__acro_foreign_sep_tl - } - { - \AssignTemplateKeys - \bool_set_true:N \l__acro_first_instance_bool - \bool_if:NTF \l__acro_first_reversed_bool - { % zuerst kurze Form, dann lange Form: - \__acro_print_form_and_indefinite:nnn {short} {#1} {#2} - \__acro_open_bracket: - \__acro_print_foreign:n {#1} - \__acro_foreign_sep:n {#1} - \__acro_print_form:nnn {long} {#1} {#2} - \__acro_print_citation:n {#1} - \__acro_close_bracket: - \__acro_finalize_first:n {#1} - } - { % zuerst lange Form, dann kurze Form: - \__acro_print_form_and_indefinite:nnn {long} {#1} {#2} - \__acro_open_bracket: - \__acro_print_foreign:n {#1} - \__acro_foreign_sep:n {#1} - \__acro_print_form:nnn {short} {#1} {#2} - \__acro_print_citation:n {#1} - \__acro_close_bracket: - \__acro_finalize_first:n {#1} - } - } - -% template for footnotes, sidenotes, ... -\cs_new:Npn \__acro_note_command:n #1 {#1} -\DeclareTemplateInterface {acro-first} {note} {2} +\__acro_auxlist_field_new:cpn {readaux} { - use-note : boolean = true , - note-command : function 1 = \footnote {#1} , - foreign-sep : tokenlist = {,~} , - reversed : boolean = false , + \file_if_exist:nT { \c_sys_jobname_str .acr } + { \file_input:n { \c_sys_jobname_str .acr } } } -\DeclareTemplateCode {acro-first} {note} {2} +% ---------------------------------------------------------------------------- +% list for recording values that need to be written to the aux file and +% updated at begin document + +\str_new:N \l__acro_auxlist_split_str +\keys_define:nn {acro} { - use-note = \l__acro_use_note_bool , - note-command = \__acro_note_command:n , - foreign-sep = \l__acro_foreign_sep_tl , - reversed = \l__acro_first_reversed_bool + auxlist-split .code:n = \str_set:Nn \l__acro_auxlist_split_str {#1} , + auxlist-split .initial:n = || } - { - \AssignTemplateKeys - \bool_if:NTF \l__acro_first_reversed_bool - { % long in text and short in note - \__acro_print_form_and_indefinite:nnn {long} {#1} {#2} - \bool_if:NT \l__acro_use_note_bool + +% define list: +% #1: name +\cs_new_protected:Npn \__acro_auxlist_new:n #1 + { + % entries collected during the run: + \seq_new:c {g__acro_auxlist_#1_seq} + % entries read from the auxfile: + \seq_new:c {g__acro_auxlist_recorded_#1_seq} + \acro_attribute_new:n {#1} + \__acro_auxlist_field_new:cpn {#1} ##1 + { + \tl_if_blank:nF {##1} { - \__acro_note_command:n - { - \__acro_print_foreign:n {#1} - \__acro_foreign_sep:n {#1} - \__acro_print_form:nnn {short} {#1} {#2} - \__acro_print_citation:n {#1} - \__acro_finalize_first:n {#1} - } + \seq_gset_split:cVx {g__acro_auxlist_#1_seq} + \l__acro_auxlist_split_str + { \tl_to_str:n {##1} } + \seq_map_inline:cn {g__acro_auxlist_#1_seq} + { \acro_attribute_set:nnn {#1} {####1} {} } } } - { % short in text and long in note - \__acro_print_form_and_indefinite:nnn {short} {#1} {#2} - \bool_if:NT \l__acro_use_note_bool + \acro_at_begin_document:n + { + \seq_gclear:c {g__acro_auxlist_recorded_#1_seq} + \seq_set_eq:Nc \l__acro_tmpa_seq {g__acro_auxlist_#1_seq} + \seq_map_inline:Nn \l__acro_tmpa_seq { - \__acro_note_command:n - { - \__acro_print_foreign:n {#1} - \__acro_foreign_sep:n {#1} - \__acro_print_form:nnn {long} {#1} {#2} - \__acro_print_citation:n {#1} - \__acro_finalize_first:n {#1} - } + \str_set:Nn \l__acro_tmpa_str {##1} + \seq_gput_right:cV {g__acro_auxlist_recorded_#1_seq} \l__acro_tmpa_str } + \seq_gremove_duplicates:c {g__acro_auxlist_recorded_#1_seq} } } -% -------------------------------------------------------------------------- -% declare new first styles: -\cs_new_protected:Npn \acro_declare_first_style:nnn #1#2#3 +% add to or remove from list: +% #1: name +% #2: entry +\cs_new_protected:Npn \__acro_auxlist_add:nn #1#2 { - \DeclareInstance {acro-first} {#1} {#2} {#3} - \prop_put:Nnn \l__acro_first_styles_prop {#1} {#2} + \str_set:Nn \l__acro_tmpa_str {#2} + \acro_attribute_set:nnn {#1} {#2} {} + \seq_if_in:cVT {g__acro_auxlist_#1_seq} \l__acro_tmpa_str + { \seq_gremove_all:cV {g__acro_auxlist_#1_seq} \l__acro_tmpa_str } + \seq_gput_right:cV {g__acro_auxlist_#1_seq} \l__acro_tmpa_str } +\cs_generate_variant:Nn \__acro_auxlist_add:nn {nx} -% set a list style -\cs_new_protected:Npn \acro_set_first_style:n #1 +% #1: name +% #2: entry +\cs_new_protected:Npn \__acro_auxlist_remove:nn #1#2 { - \prop_if_in:NnTF \l__acro_first_styles_prop {#1} - { \__acro_set_first_style:n {#1} } - { - \msg_warning:nnnnn {acro} {unknown} - {first~ style} - {#1} - {default} - \__acro_set_first_style:n {default} - } + \str_set:Nn \l__acro_tmpa_str {#2} + \acro_attribute_if_set:nnT {#1} {#2} + { \acro_attribute_unset:nn {#1} {#2} } + \seq_if_in:cVT {g__acro_auxlist_#1_seq} \l__acro_tmpa_str + { \seq_gremove_all:cV {g__acro_auxlist_#1_seq} \l__acro_tmpa_str } + \seq_if_in:cVT {g__acro_auxlist_recorded#1_seq} \l__acro_tmpa_str + { \seq_gremove_all:cV {g__acro_auxlist_recorded_#1_seq} \l__acro_tmpa_str } } +\cs_generate_variant:Nn \__acro_auxlist_remove:nn {nx} -\cs_new_protected:Npn \__acro_set_first_style:n #1 +% check if in list: +% #1: name +% #2: entry +\prg_new_conditional:Npnn \__acro_auxlist_if_in:nn #1#2 {p,T,F,TF} { - \tl_set:Nn \l__acro_first_instance_tl {#1} - \prop_get:NnN \l__acro_first_styles_prop {#1} \l__acro_tmpa_tl + \acro_attribute_if_set:nnTF {#1} {#2} + { \prg_return_true: } + { \prg_return_false: } } +\prg_generate_conditional_variant:Nnn \__acro_auxlist_if_in:nn {nx} {T,TF} -% -------------------------------------------------------------------------- -% formatting the extras information: -\DeclareObjectType {acro-extra} {1} +\bool_new:N \l__acro_auxlists_clear_bool +\cs_new_protected:Npn \acro_auxlists_clear: + { \bool_set_true:N \l__acro_auxlists_clear_bool } -\DeclareTemplateInterface {acro-extra} {inline} {1} - { - punct : boolean = false , - punct-symbol : tokenlist = {,} , - brackets : boolean = true , - brackets-type : tokenlist = () +% update list (should be used inside \acro_at_end_document:n): +% #1: name +\cs_new_protected:Npn \__acro_auxlist_update:n #1 + { + \seq_remove_duplicates:c {g__acro_auxlist_#1_seq} + \seq_remove_duplicates:c {g__acro_auxlist_recorded_#1_seq} + \str_set:Nx \l__acro_tmpa_str + { \seq_use:cn {g__acro_auxlist_#1_seq} {} } + \str_set:Nx \l__acro_tmpb_str + { \seq_use:cn {g__acro_auxlist_recorded_#1_seq} {} } + \str_if_eq:NNF \l__acro_tmpa_str \l__acro_tmpb_str + { \acro_rerun:n {property} } + \bool_if:NF \l__acro_auxlists_clear_bool + { + \acro_auxlist_to_aux:nn {#1} + { { \seq_use:cV {g__acro_auxlist_#1_seq} \l__acro_auxlist_split_str } } + } } -\DeclareTemplateCode {acro-extra} {inline} {1} - { - punct = \l__acro_extra_punct_bool , - punct-symbol = \l__acro_extra_punct_tl , - brackets = \l__acro_extra_use_brackets_bool , - brackets-type = \l__acro_extra_brackets_tl - } - { - \AssignTemplateKeys - \bool_if:NT \l__acro_extra_punct_bool - { \tl_use:N \l__acro_extra_punct_tl \tl_use:N \c_space_tl } - \bool_if:NT \l__acro_extra_use_brackets_bool - { \tl_head:N \l__acro_extra_brackets_tl } - \acro_write_long:Vn \l__acro_extra_format_tl {#1} - \bool_if:NT \l__acro_extra_use_brackets_bool - { \tl_tail:N \l__acro_extra_brackets_tl } - } +% loop over list: +% #1: name +% #2: code +\cs_new_protected:Npn \__acro_auxlist_foreach_entry:nn #1#2 + { \seq_map_inline:cn {g__acro_auxlist_recorded_#1_seq} {#2} } + +\cs_new_protected:Npn \__acro_auxlist_foreach_new_entry:nn #1#2 + { \seq_map_inline:cn {g__acro_auxlist_#1_seq} {#2} } + +% length of a list: +% #1: name +\cs_new:Npn \__acro_auxlist_count:n #1 + { \seq_count:c {g__acro_auxlist_recorded_#1_seq} } + +% item of a list: +% #1: name +% #2: integer +\cs_new:Npn \__acro_auxlist_item:nn #1#2 + { \seq_item:cn {g__acro_auxlist_recorded_#1_seq} {#2} } -% declare new extra styles: -\cs_new_protected:Npn \acro_declare_etxra_style:nnn #1#2#3 +% ---------------------------------------------------------------------------- +\AcroModuleEnd +\AcroModule{properties}{properties of acronyms} + +% ---------------------------------------------------------------------------- +% messages: +\msg_new:nnn {acro} {unknown-property} { - \DeclareInstance {acro-etxra} {#1} {#2} {#3} - \prop_put:Nnn \l__acro_etxra_styles_prop {#1} {#2} + You~ tried~ to~ set~ the~ property~ `#1'~ \msg_line_context: . \\ + This~ property~ does~ not~ exist.~ Check~ for~ a~ typo~ or~ \\ + define~ the~ property~ yourself. } -% set an extra style -\cs_new_protected:Npn \acro_set_extra_style:n #1 +\msg_new:nnn {acro} {property-unique} { - \prop_if_in:NnTF \l__acro_extra_styles_prop {#1} - { \__acro_set_extra_style:n {#1} } - { - \msg_warning:nnnnn {acro} {unknown} - {extra~ style} - {#1} - {default} - \__acro_set_extra_style:n {default} - } + You~ tried~ to~ set~ the~ property~ `#1'~ \msg_line_context: . \\ + This~ property~ has~ to~ have~ a~ unique~ value~ and~ thus~ \\ + cannot~ be~ set~ to~ `#2'~ since~ this~ value~ is~ already~ talen. } -\cs_new_protected:Npn \__acro_set_extra_style:n #1 +\msg_new:nnn {acro} {no-boolean-property} { - \tl_set:Nn \l__acro_extra_instance_tl {#1} - \prop_get:NnN \l__acro_extra_styles_prop {#1} \l__acro_tmpa_tl + You~ tried~ to~ check~ the~ boolean~ value~ of~ property~ `#1'~ + \msg_line_context: . \\ + However,~ property~ `#1'~ is~ not~ a~ boolean~ property! } -\cs_new_protected:Npn \acro_declare_extra_style:nnn #1#2#3 +\msg_new:nnn {acro} {unbalanced-property-list} { - \DeclareInstance {acro-extra} {#1} {#2} {#3} - \prop_put:Nnn \l__acro_extra_styles_prop {#1} {#2} + There~ is~ a~ mis-match~ in~ the~ property~ list: \\ + `#1' \\ + \msg_line_context: } -% -------------------------------------------------------------------------- -% outputting the page numbers: -\RequirePackage {zref-abspage} - -\cs_new_protected:Npn \__acro_create_page_records:n #1 +\msg_new:nnn {acro} {value-required} { - \seq_new:c { g__acro_#1_pages_seq } - \tl_new:c { g__acro_#1_recorded_pages_tl } + The~ property~ `#2'~ for~ acroynm~ `#1'~ \msg_line_context: \ + needs~ a~ (possibly~ empty)~ value! } + -\cs_new_protected:Npn \acro_hyper_page:n #1 { \use:n {#1} } - -\cs_new:Npn \acro_get_thepage:nnn #1#2#3 { \acro_hyper_page:n {#1} } -\cs_new:Npn \acro_get_thepage_from:N #1 - { \exp_after:wN \acro_get_thepage:nnn #1 } +% ---------------------------------------------------------------------------- +% declare properties: +\seq_new:N \l__acro_properties_seq -\cs_new:Npn \acro_get_page_number:nnn #1#2#3 {#2} -\cs_new:Npn \acro_get_page_number_from:N #1 - { \exp_after:wN \acro_get_page_number:nnn #1 } +\cs_new_protected:Npn \acro_properties_map:n #1 + { \seq_map_inline:Nn \l__acro_properties_seq {#1} } -\cs_new:Npn \acro_get_abspage:nnn #1#2#3 {#3} -\cs_new:Npn \acro_get_abspage_from:N #1 - { \exp_after:wN \acro_get_abspage:nnn #1 } +\acro_attribute_new:n {boolean} +\acro_attribute_new:n {unique} +\acro_attribute_new:n {mandatory} +\acro_attribute_new:n {dynamic} -\cs_new:Npn \acro_page_range_comma: {} +% \seq_new:N \l__acro_mandatory_properties_seq +\tl_new:N \l__acro_mandatory_properties_tl -\cs_new_protected:Npn \acro_print_page_numbers:n #1 +% new property: +% #1: boolean (true = unique) +% #2: boolean (true = boolean) +% #3: boolean (true = mandatory) +% #4: boolean (true = static != dynamic) +% #5: property name +\cs_new_protected:Npn \acro_property_declare:nnnnn #1#2#3#4#5 { - \seq_if_empty:cF {g__acro_#1_pages_seq} + \acro_property_if_exist:nF {#5} { - \bool_if:NTF \l__acro_list_all_pages_bool + \seq_put_right:Ne \l__acro_properties_seq { \tl_to_str:n {#5} } + \acro_attribute_new:n {property::#5} + \bool_if:nF {#4} + { \acro_attribute_set:nnn {dynamic} {#5} {true} } + \__acro_auxlist_new:n {#5} + \bool_if:nT {#3} { - % have the numbers changed? - \tl_set:Nx \l__acro_tmpa_tl - { \seq_use:cn {g__acro_#1_pages_seq} {|} } - \tl_if_eq:cNF {g__acro_#1_recorded_pages_tl} \l__acro_tmpa_tl - { - \@latex@warning@no@line - {Rerun~to~get~page~numbers~of~acronym~#1~in~acronym~list~right} - } - \tl_clear:N \l__acro_write_pages_tl - \tl_clear:N \l__acro_last_page_tl - \tl_clear:N \l__acro_current_page_tl - \seq_set_eq:Nc \l__acro_tmpb_seq { g__acro_#1_pages_seq } - \seq_remove_duplicates:N \l__acro_tmpb_seq - \seq_clear:N \l__acro_tmpa_seq - \cs_set_protected:Npn \acro_page_range_comma: - { \cs_set:Npn \acro_page_range_comma: { ,~ } } - % get the numbers: - \int_compare:nNnTF { \seq_count:N \l__acro_tmpb_seq } = { 1 } - { - \tl_use:N \l__acro_page_name_tl - \seq_get_right:cN { g__acro_#1_pages_seq } \l__acro_tmpa_tl - \acro_get_thepage_from:N \l__acro_tmpa_tl - } - { - \tl_use:N \l__acro_pages_name_tl - \seq_map_inline:cn { g__acro_#1_pages_seq } - { - \tl_if_blank:VTF \l__acro_last_page_tl - {% we're at the beginning - \seq_put_right:Nn \l__acro_tmpa_seq {##1} - \tl_set:Nn \l__acro_last_page_tl {##1} - } - {% we'at least at the second page - % current page: - \tl_set:Nn \l__acro_current_page_tl {##1} - % last page: - \seq_get_right:NN \l__acro_tmpa_seq \l__acro_last_page_tl - \tl_if_eq:NNTF \l__acro_current_page_tl \l__acro_last_page_tl - {% there were more than one appearance on the current page - \seq_put_right:Nn \l__acro_tmpa_seq {##1} - } - {% new page - \acro_determine_page_ranges:NNn - \l__acro_tmpa_seq - \l__acro_write_pages_tl - {##1} - } - } - } - \seq_if_empty:NF \l__acro_tmpa_seq - { - \acro_determine_page_ranges:NNV - \l__acro_tmpa_seq - \l__acro_write_pages_tl - \l__acro_current_page_tl - } - \tl_use:N \l__acro_write_pages_tl - \tl_clear:N \l__acro_write_pages_tl - } + \acro_attribute_set:nnn {mandatory} {#5} {true} + % \seq_put_right:Nn \l__acro_mandatory_properties_seq {#5} + \tl_put_right:Nn \l__acro_mandatory_properties_tl {{#5}} } + \bool_if:nT {#2} + { \acro_attribute_set:nnn {boolean} {#5} {true} } + \bool_if:nT {#1} { - \tl_use:N \l__acro_page_name_tl - \pageref{\l__acro_label_prefix_tl #1} - } - } - \seq_clear:N \l__acro_tmpa_seq - \seq_clear:N \l__acro_tmpb_seq - } - -\cs_new:Npn \acro_determine_page_ranges:NNn #1#2#3 - { - \seq_remove_duplicates:N #1 - % current page: - \int_set:Nn \l__acro_tmpa_int { \acro_get_abspage:nnn #3 } - \int_set:Nn \l__acro_tmpb_int { \acro_get_page_number:nnn #3 } - % last page: - \seq_get_right:NN #1 \l__acro_last_page_tl - \int_set:Nn \l__acro_tmpc_int - { \acro_get_abspage_from:N \l__acro_last_page_tl } - \int_set:Nn \l__acro_tmpd_int - { \acro_get_page_number_from:N \l__acro_last_page_tl } - \bool_lazy_and:nnTF - { - \int_compare_p:nNn - { \l__acro_tmpa_int - \l__acro_tmpc_int } - = - { \l__acro_tmpb_int - \l__acro_tmpd_int } - } - { - \int_compare_p:nNn - { \l__acro_tmpb_int - \l__acro_tmpd_int } = {1} - } - {% same kind of page numbering, one page ahead - % => possible range - \seq_put_right:Nn #1 {#3} - } - {% any possible range ended - \tl_put_right:Nn #2 { \acro_page_range_comma: } - \int_compare:nNnTF - { \seq_count:N #1 } > {2} - {% real range - \seq_get_left:NN #1 \l__acro_tmpa_tl - \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } - \bool_if:NTF \l__acro_following_pages_bool - { \tl_put_right:Nn #2 { \l__acro_next_pages_tl } } - { - \tl_put_right:Nn #2 { -- } - \seq_get_right:NN #1 \l__acro_tmpa_tl - \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } - } + \acro_attribute_set:nnn {unique} {#5} {true} + \seq_new:c {l__acro_unique_#5_seq} } + \bool_if:nT {#4} { - \int_compare:nNnTF - { \seq_count:N #1 } = {2} - {% range of two pages - \seq_get_left:NN #1 \l__acro_tmpa_tl - \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } - \bool_if:NTF \l__acro_following_page_bool - { \tl_put_right:Nn #2 { \l__acro_next_page_tl } } - { - \tl_put_right:Nn #2 { ,~ } - \seq_get_right:NN #1 \l__acro_tmpa_tl - \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } - } - } - {% no range at all - \seq_get_right:NN #1 \l__acro_tmpa_tl - \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } - } + \AtEndDocument { \__acro_auxlist_update:n {#5} } + \acro_at_begin_document:n { \__acro_property_set_from_auxlist:n {#5} } } - \seq_clear:N #1 - \seq_put_right:Nn #1 {#3} } } -\cs_generate_variant:Nn \acro_determine_page_ranges:NNn {NNV} - -% -------------------------------------------------------------------------- -\DeclareObjectType {acro-page-number} {1} -\DeclareTemplateInterface {acro-page-number} {inline} {1} +% ---------------------------------------------------------------------------- +% property conditionals: +\prg_new_conditional:Npnn \acro_property_if_exist:n #1 {T,F,TF} { - display : boolean = true , - punct : boolean = false , - punct-symbol : tokenlist = {,} , - brackets : boolean = false , - brackets-type : tokenlist = () , - space : skip = .333333em plus .166666em minus .111111em + \acro_attribute_if_exist:nTF {property::#1} + { \prg_return_true: } + { \prg_return_false: } } +\cs_generate_variant:Nn \acro_property_if_exist:nTF {x} -\DeclareTemplateCode {acro-page-number} {inline} {1} +% #1: id +% #2: property +\prg_new_conditional:Npnn \acro_property_if_set:nn #1#2 {p,T,F,TF} { - display = \l__acro_page_display_bool , - punct = \l__acro_page_punct_bool , - punct-symbol = \l__acro_page_punct_tl , - brackets = \l__acro_page_brackets_bool , - brackets-type = \l__acro_page_brackets_tl , - space = \l__acro_page_space_skip + \acro_attribute_if_set:neTF {#2} { \acro_case_insensitive:n {#1} } + { \prg_return_true: } + { \prg_return_false: } } - { - \AssignTemplateKeys - \bool_if:NT \l__acro_page_display_bool - { - \bool_if:NT \l__acro_page_punct_bool - { \tl_use:N \l__acro_page_punct_tl } - % \tl_use:N \c_space_tl - \dim_compare:nNnF { \l__acro_page_space_skip } = { 0pt } - { \skip_horizontal:N \l__acro_page_space_skip } - \bool_if:NT \l__acro_page_brackets_bool - { \tl_head:N \l__acro_page_brackets_tl } - \acro_print_page_numbers:n {#1} - \bool_if:NT \l__acro_page_brackets_bool - { \tl_tail:N \l__acro_page_brackets_tl } - } +\prg_generate_conditional_variant:Nnn \acro_property_if_set:nn + {nx,xx,nV,e,ne} + {p,T,F,TF} + + +% #1: id +% #2: properties +\prg_new_protected_conditional:Npnn \acro_property_if_any:nn #1#2 {T,F,TF} + { + \seq_set_from_clist:Nn \l__acro_tmpa_seq {#2} + \seq_set_map:NNn \l__acro_tmpa_seq \l__acro_tmpa_seq + { { \exp_not:N \acro_property_if_set_p:nn {#1} {##1} } } + \bool_lazy_any:eTF + { \seq_use:Nn \l__acro_tmpa_seq {} } + { \prg_return_true: } + { \prg_return_false: } } +\prg_generate_conditional_variant:Nnn \acro_property_if_any:nn {e} {TF} -% declare new page styles: -\cs_new_protected:Npn \acro_declare_page_style:nnn #1#2#3 - { - \DeclareInstance {acro-page-number} {#1} {#2} {#3} - \prop_put:Nnn \l__acro_page_styles_prop {#1} {#2} +% #1: id +% #2: properties +\prg_new_protected_conditional:Npnn \acro_property_if_all:nn #1#2 {T,F,TF} + { + \seq_set_from_clist:Nn \l__acro_tmpa_seq {#2} + \seq_set_map:NNn \l__acro_tmpa_seq \l__acro_tmpa_seq + { { \exp_not:N \acro_property_if_set_p:nn {#1} {##1} } } + \bool_lazy_all:eTF + { \seq_use:Nn \l__acro_tmpa_seq {} } + { \prg_return_true: } + { \prg_return_false: } } +\prg_generate_conditional_variant:Nnn \acro_property_if_all:nn {e} {TF} -% set a page style -\cs_new_protected:Npn \acro_set_page_style:n #1 +\prg_new_conditional:Npnn \acro_property_if_eq:nn #1#2 {p,T,F,TF} { - \prop_if_in:NnTF \l__acro_page_styles_prop {#1} - { \__acro_set_page_style:n {#1} } - { - \msg_warning:nnnnn {acro} {unknown} - {page~ style} - {#1} - {none} - \__acro_set_page_style:n {none} - } + \str_if_eq:nnTF {#1} {#2} + { \prg_return_true: } + { \prg_return_false: } } -\cs_new_protected:Npn \__acro_set_page_style:n #1 +\prg_new_conditional:Npnn \acro_property_if_mandatory:n #1 {p,T,F,TF} { - \tl_set:Nn \l__acro_page_instance_tl {#1} - \prop_get:NnN \l__acro_page_styles_prop {#1} \l__acro_tmpa_tl + \acro_attribute_if_set:nnTF {mandatory} {#1} + { \prg_return_true: } + { \prg_return_false: } } +\cs_generate_variant:Nn \acro_property_if_mandatory:nF {V} -% -------------------------------------------------------------------------- -% the title of the list: -\cs_new:Npn \acro_list_title_format:n #1 {#1} - -\DeclareObjectType {acro-title} {1} +\cs_new_protected:Npn \acro_property_foreach_mandatory:n #1 + { \tl_map_inline:Nn \l__acro_mandatory_properties_tl {#1} } -\DeclareTemplateInterface {acro-title} {sectioning} {1} - { name-format : function 1 = #1 } +\prg_new_conditional:Npnn \acro_property_if_boolean:n #1 {p,T,F,TF} + { + \acro_attribute_if_set:nnTF {boolean} {#1} + { \prg_return_true: } + { \prg_return_false: } + } -\DeclareTemplateCode {acro-title} {sectioning} {1} - { name-format = \acro_list_title_format:n } +\prg_new_conditional:Npnn \acro_property_if_unique:n #1 {p,T,F,TF} { - \AssignTemplateKeys - \acro_list_title_format:n {#1} + \acro_attribute_if_set:nnTF {unique} {#1} + { \prg_return_true: } + { \prg_return_false: } } -% set a list heading: -\cs_new_protected:Npn \acro_set_list_heading:n #1 +% #1: property +% #2: value +\prg_new_protected_conditional:Npnn \acro_property_if_unique_value:nn #1#2 {T,F,TF} { - \prop_if_in:NnTF \l__acro_list_headings_prop {#1} - { \__acro_set_list_heading:n {#1} } + \acro_property_if_unique:nTF {#1} { - \msg_warning:nnnnn {acro} {unknown} - {list~ heading} - {#1} - {section*} - \__acro_set_list_heading:n {section*} + \seq_if_in:cnTF {l__acro_unique_#1_seq} {#2} + { \prg_return_true: } + { \prg_return_false: } } + { \prg_return_false: } } -\cs_new_protected:Npn \__acro_set_list_heading:n #1 - { \tl_set:Nn \l__acro_list_heading_cmd_tl {#1} } - -\cs_new_protected:Npn \acro_declare_list_heading:nn #1#2 +% #1: id +% #2: property +\prg_new_conditional:Npnn \acro_property_get_if_set:nn #1#2 {T,F,TF} { - \prop_put:Nnn \l__acro_list_headings_prop {#1} {#2} - \DeclareInstance {acro-title} {#1} {sectioning} - { name-format = #2 {##1} } + \acro_property_if_set:nnTF {#1} {#2} + { + \acro_property_get:nn {#1} {#2} + \prg_return_true: + } + { \prg_return_false: } } - -% -------------------------------------------------------------------------- -% typesetting the acronym list -\DeclareObjectType {acro-list} {2} +\prg_generate_conditional_variant:Nnn \acro_property_if_set:nn {V} {TF} % #1: id -% #2: excluded classes -\prg_new_protected_conditional:Npnn \acro_if_is_excluded:nn #1#2 {T,F,TF} +% #2: property +\prg_new_conditional:Npnn \acro_boolean_property_if:nn #1#2 {p,T,F,TF} { - \bool_set_false:N \l__acro_is_excluded_bool - \tl_if_blank:nF {#2} + \acro_property_if_exist:nTF {#2} { - \acro_property_get:nnT {#1} {class} + \acro_property_if_boolean:nTF {#2} { - \seq_set_split:NnV \l__acro_tmpa_seq {,} \l__acro_class_tl - \clist_map_inline:nn {#2} + \acro_property_if_set:nnTF {#1} {#2} { - \seq_if_in:NnT \l__acro_tmpa_seq {##1} - { \bool_set_true:N \l__acro_is_excluded_bool } + \bool_if:cTF + {c_ \acro_property_get:nn {#1} {#2} _bool} + { \prg_return_true: } + { \prg_return_false: } } + { \prg_return_false: } } + { \prg_return_false: } } - \bool_if:NTF \l__acro_is_excluded_bool - { \prg_return_true: } { \prg_return_false: } } +\cs_generate_variant:Nn \acro_boolean_property_if:nnTF {oo} +\cs_generate_variant:Nn \acro_boolean_property_if:nnF {nV} +% ---------------------------------------------------------------------------- +% set properties: % #1: id -% #2: included classes -\prg_new_protected_conditional:Npnn \acro_if_is_included:nn #1#2 {T,F,TF} +% #2: property +% #3: value +\cs_new_protected:Npn \acro_property_set:nnn #1#2#3 { - \bool_set_false:N \l__acro_is_included_bool - \tl_if_blank:nTF {#2} - { \bool_set_true:N \l__acro_is_included_bool } + \acro_property_if_exist:nTF {#2} { - \acro_property_get:nnT {#1} {class} + \acro_property_if_set:nnTF {#1} {#2} + { + \acro_property_if_unique:nTF {#2} + { + \acro_property_if_unique_value:nnTF {#2} {#3} + { \__acro_unique_property_set:nnn {#1} {#2} {#3} } + { \msg_warning:nnnn {acro} {property-unique} {#2} {#3} } + } + { + \acro_property_if_boolean:nTF {#2} + { \__acro_boolean_property_set:nnn {#1} {#2} {#3} } + { \__acro_property_set:nnn {#1} {#2} {#3} } + } + } { - \seq_set_split:NnV \l__acro_tmpa_seq {,} \l__acro_class_tl - \clist_map_inline:nn {#2} + \acro_property_if_boolean:nTF {#2} + { \__acro_boolean_property_set:nnn {#1} {#2} {#3} } { - \seq_if_in:NnT \l__acro_tmpa_seq {##1} - { \bool_set_true:N \l__acro_is_included_bool } + \acro_property_if_unique:nTF {#2} + { \__acro_unique_property_set:nnn {#1} {#2} {#3} } + { \__acro_property_set:nnn {#1} {#2} {#3} } } } } - \bool_if:NTF \l__acro_is_included_bool - { \prg_return_true: } - { \prg_return_false: } + { \msg_error:nnn {acro} {unknown-property} {#2} } } +\cs_generate_variant:Nn \acro_property_set:nnn {nnV,nxx,nnx,e,nne,nnv} % #1: id -\cs_new_protected:Npn \__acro_list_entry_short:n #1 +% #2: property +% #3: value +\cs_new_protected:Npn \__acro_boolean_property_set:nnn #1#2#3 { - \group_begin: - \acro_get:n {#1} - \acro_hyper_target:nn - {#1} - { - \acro_acc_supp:nn - {#1} - { - \bool_lazy_and:nnTF - { \l__acro_custom_short_format_bool } - { \l__acro_override_list_format_bool } - { \l__acro_custom_short_format_tl } - { \l__acro_list_short_format_tl } - { \__acro_property_get:nn {short} {#1} } - } - } - \group_end: + \str_case_e:nnTF { \str_lowercase:n {#3} } + { + {} {} + {true} {} + } + { \__acro_property_set:nnn {#1} {#2} {true} } + { \__acro_property_set:nnn {#1} {#2} {false} } } % #1: id -\cs_new_protected:Npn \__acro_list_entry_long:n #1 +% #2: property +% #3: value +\cs_new_protected:Npn \__acro_unique_property_set:nnn #1#2#3 + { \__acro_property_set:nnn {#1} {#2} {#3} } + +% #1: id +% #2: property +\cs_new_protected:Npn \__acro_property_unset:nn #1#2 { - \group_begin: - \bool_if:NT \l__acro_capitalize_list_bool - { \bool_set_true:N \l__acro_first_upper_bool } - \acro_write_long:Vf \l__acro_list_long_format_tl - { - \prop_if_in:NnTF \l__acro_list_prop {#1} - { \__acro_property_get:nn {list} {#1} } - { \__acro_property_get:nn {long} {#1} } - } - \group_end: - \bool_if:NT \l__acro_foreign_bool - { \acro_get_foreign:n {#1} } - \acro_cite_if:Nn \l__acro_citation_all_bool {#1} + \__acro_property_remove_from_auxlist:nn {#1} {#2} + \acro_attribute_unset:nn {#2} {#1} } % #1: id -\cs_new_protected:Npn \__acro_list_entry_extra:n #1 +% #2: property +\cs_new_protected:Npn \acro_property_unset:nn #1#2 { - \acro_property_get:nnT {#1} {extra} - { - \acro_extra_instance:VV - \l__acro_extra_instance_tl - \l__acro_extra_tl - } + \acro_property_if_exist:nTF {#2} + { \__acro_property_unset:nn {#1} {#2} } + { \msg_error:nnn {acro} {unknown-property} {#2} } } +\cs_generate_variant:Nn \acro_property_unset:nn {nx,nV} % #1: id -\cs_new_protected:Npn \__acro_list_entry_page:n #1 +% #2: property +% #3: value +\cs_new_protected:Npn \__acro_property_set:nnn #1#2#3 { - \cs_if_exist:cT {acro@#1@once} - { - \acro_page_number_instance:Vn - \l__acro_page_instance_tl - {#1} - } + \__acro_property_remove_from_auxlist:nn {#1} {#2} + % now we can safely add the property to the list: + \__acro_auxlist_add:nn {#2} {#1=={#3}} + \acro_attribute_set:nnn {#2} {#1} {#3} } - -% macro for retrieval of items in the list: -% #1: property -% #2: id -\cs_new_protected:Npn \acro_list_entry:nn #1#2 +\cs_generate_variant:Nn \__acro_property_set:nnn {VnV,nne} + +\tl_set:Nx \l__acro_tmpa_tl { \cs_to_str:N \{ } +\tl_set:Nx \l__acro_tmpb_tl { \cs_to_str:N \} } +\use:x { - \str_case:nnF {#1} - { - {short} { \__acro_list_entry_short:n {#2} } - {long} { \__acro_list_entry_long:n {#2} } - {extra} { \__acro_list_entry_extra:n {#2} } - {page} { \__acro_list_entry_page:n {#2} } - } - { \__acro_property_get:nn {#1} {#2} } + \cs_new_protected:Npn + \exp_not:N \__acro_property_extract_auxlist_entry:NNww + ##1##2##3 == \l__acro_tmpa_tl ##4 \l__acro_tmpb_tl + \exp_not:N \q_stop + } + { + \str_set:Nn #1 {#3} + \str_set:Nn #2 {#4} } -% this macro may/should be redefined in templates: -% #1: short -% #2: long -% #3: extra -% #4: page number(s) -\cs_new_protected:Npn \acro_print_list_entry:nnnn #1#2#3#4 - { #1 #2 #3 #4 } - -\cs_new_protected:Npn \acro_for_all_acronyms_do:n #1 - { \prop_map_inline:Nn \l__acro_short_prop {#1} } - -% test, if acronyms should be printed or not; needs testing for in/excluded -% classes and options `only-used' and `single' -- this macro should be used in -% the template code for retrieving the list - % #1: id -% #2: included classes -% #3: excluded classes -\prg_new_protected_conditional:Npnn \acro_if_entry:nnn #1#2#3 {T,F,TF} +% #2: property +\cs_new_protected:Npn \__acro_property_remove_from_auxlist:nn #1#2 { - \bool_lazy_or:nnTF - { - \bool_lazy_and_p:nn - { !\l__acro_single_use_bool } - { !\l__acro_print_only_used_bool } - } + % make sure we change the entry if it has been recorded previously: + \__acro_auxlist_foreach_entry:nn {#2} { - \bool_lazy_and_p:nn - { \bool_if_p:c {g__acro_#1_in_list_bool} } + \__acro_property_extract_auxlist_entry:NNww + \l__acro_tmpa_str \l__acro_tmpb_str ##1 \q_stop + \str_if_eq:xnT { \l__acro_tmpa_str } {#1} { - \bool_lazy_or_p:nn - { - \bool_lazy_and_p:nn - { \l__acro_single_use_bool } - { \cs_if_exist_p:c {acro@#1@twice} } - } - { - \bool_lazy_all_p:n - { - { !\l__acro_single_use_bool } - { \cs_if_exist_p:c {acro@#1@once} } - { \l__acro_print_only_used_bool } - } - } + \__acro_auxlist_remove:nx {#2} + { #1 == {\l__acro_tmpb_str} } } } + % make sure we change the entry if it has been set during the current run: + \__acro_auxlist_foreach_new_entry:nn {#2} { - \acro_if_is_excluded:nnTF {#1} {#3} - { \prg_return_false: } + \__acro_property_extract_auxlist_entry:NNww + \l__acro_tmpa_str \l__acro_tmpb_str ##1 \q_stop + \str_if_eq:xnT { \l__acro_tmpa_str } {#1} { - \acro_if_is_included:nnTF {#1} {#2} - { - \bool_lazy_and:nnTF - { \g__acro_use_barriers_bool } - { \l__acro_use_barrier_bool } - { - \acro_if_in_barrier:nxTF {#1} - { \int_use:N \g__acro_barrier_int } - { \prg_return_true: } - { \prg_return_false: } - } - { \prg_return_true: } - } - { \prg_return_false: } + \__acro_auxlist_remove:nx {#2} + { #1 == {\l__acro_tmpb_str} } } } - { \prg_return_false: } } -% this macro is used in templates for fetching all items to be printed; it -% collects all entries in a tl which then is used where needed -% -% #1: tl containing the entries -% #2: included classes -% #3: excluded classes -\cs_new_protected:Npn \acro_build_list_entries:Nnn #1#2#3 +% #1: property +\cs_new_protected:Npn \__acro_property_set_from_auxlist:n #1 { - \tl_clear:N #1 - \acro_for_all_acronyms_do:n - {% ##1: id; ##2: short form - \group_begin: - \acro_get:n {##1} - \acro_if_entry:nnnT {##1} {#2} {#3} - { - \tl_gput_right:Nn #1 - { - \acro_print_list_entry:nnnn - { \acro_list_entry:nn {short} {##1} } - { \acro_list_entry:nn {long} {##1} } - { \acro_list_entry:nn {extra} {##1} } - { \acro_list_entry:nn {page} {##1} } - } - } - \group_end: + \__acro_auxlist_foreach_entry:nn {#1} + { + \__acro_property_extract_auxlist_entry:NNww + \l__acro_tmpa_str \l__acro_tmpb_str ##1 \q_stop + \tl_set_rescan:Nnx \l__acro_tmpa_tl {} { \l__acro_tmpb_str } + \__acro_property_set:VnV \l__acro_tmpa_str {#1} \l__acro_tmpa_tl } } -% this macro is used in templates for fetching all items to be printed: -\cs_new_protected:Npn \acro_list_items:nn #1#2 - { - \acro_build_list_entries:Nnn \l__acro_list_entries_tl {#1} {#2} - \tl_use:N \l__acro_list_entries_tl - } - -% -------------------------------------------------------------------------- -% declare templates for the list: -% `list' template: -\DeclareTemplateInterface {acro-list} {list} {2} +% set properties: +% #1: id +% #2: csv list of properties +\cs_new_protected:Npn \acro_properties_set:nn #1#2 { - foreign-sep : tokenlist = {~} , - list : tokenlist = {description} , - reverse : boolean = false , - before : tokenlist = , - after : tokenlist = + \cs_set_protected:Npn \__acro_parse_property:nn ##1##2 + { \acro_property_set:nnn {#1} {##1} {##2} } + \cs_set_protected:Npn \__acro_parse_property:n ##1 + { + \acro_property_if_boolean:nTF {##1} + { \acro_property_set:nnn {#1} {##1} {true} } + { \msg_error:nnnn {acro} {value-required} {#1} {##1} } + } + \keyval_parse:NNn + \__acro_parse_property:n + \__acro_parse_property:nn + {#2} } +\cs_generate_variant:Nn \acro_properties_set:nnn {nnx,nxx,nV,nVx} -\DeclareTemplateCode {acro-list} {list} {2} - { - foreign-sep = \l__acro_foreign_sep_tl , - list = \l__acro_list_tl , - reverse = \l__acro_list_reverse_long_extra_bool , - before = \l__acro_list_before_tl , - after = \l__acro_list_after_tl - } +% ---------------------------------------------------------------------------- +% inspect properties: +\cs_new_protected:Npn \acro_property_show:nn #1#2 { - \AssignTemplateKeys - \bool_set_true:N \l__acro_in_list_bool - \acro_activate_hyperref_support: - \bool_if:NTF \l__acro_list_reverse_long_extra_bool + \acro_property_if_set:nnT {#1} {#2} { - \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 - { \item [##1] ##3 ##2 ##4 } - } - { - \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 - { \item [##1] ##2 ##3 ##4 } - } - \use:x - { - \exp_not:V \l__acro_list_before_tl - \exp_not:N \begin { \exp_not:V \l__acro_list_tl } - \exp_not:n { \acro_list_items:nn {#1} {#2} } - \exp_not:N \end { \exp_not:V \l__acro_list_tl } - \exp_not:V \l__acro_list_after_tl + \iow_term:x + { + \c_space_tl \c_space_tl + \tl_to_str:n {#2} + \c_space_tl \c_space_tl => \c_space_tl \c_space_tl + { \acro_property_get:nn {#1} {#2} } + } } } +\cs_generate_variant:Nn \acro_property_show:nn {e} -% `list-of' template: -\DeclareTemplateInterface {acro-list} {list-of} {2} +% ---------------------------------------------------------------------------- +% alias properties: +\tl_new:N \g__acro_property_aliases_tl + +% #1: property +\prg_new_conditional:Npnn \acro_property_if_alias:n #1 {p,T,F,TF} { - foreign-sep : tokenlist = {~} , - style : tokenlist = {toc} , - reverse : boolean = false , - before : tokenlist = , - after : tokenlist = + \tl_map_tokens:Nn \g__acro_property_aliases_tl + { \__acro_property_if_alias:nn {#1} } + \use_ii:nn + { \prg_return_true: } + { \prg_return_false: } } -\DeclareTemplateCode {acro-list} {list-of} {2} +% #1: tl +% #2: tl +\cs_new:Npn \__acro_property_if_alias:nn #1#2 { - foreign-sep = \l__acro_foreign_sep_tl , - style = \l__acro_list_of_style , - reverse = \l__acro_list_reverse_long_extra_bool , - before = \l__acro_list_before_tl , - after = \l__acro_list_after_tl + \str_if_eq:nnT {#1} {#2} + { \tl_map_break:n { \use_ii:nnn } } } + +% #1: property +\cs_new:Npn \acro_property_alias:n #1 + { \acro_attribute_get:nn {#1} {alias} } +\cs_generate_variant:Nn \acro_property_alias:n {e} + +% #1: property +% #2: alias of +\cs_new_protected:Npn \acro_property_make_alias:nn #1#2 { - \AssignTemplateKeys - \bool_set_true:N \l__acro_in_list_bool - \tl_if_eq:VnT \l__acro_page_instance_tl {none} - { \tl_set:Nn \l__acro_page_instance_tl {plain} } - \tl_set:Nn \l__acro_page_name_tl {} - \tl_set:Nn \l__acro_pages_name_tl {} - \acro_activate_hyperref_support: - \str_case:Vn \l__acro_list_of_style + \acro_property_if_alias:nF {#1} { - {toc} - { % similar to the table of contents - \bool_if:NTF \l__acro_list_reverse_long_extra_bool - { - \cs_if_exist:NTF \chapter - { - \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 - { - \contentsline{chapter}{##1}{}{} - \contentsline{section}{##3##2}{##4}{} - } - } - { - \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 - { - \contentsline{section}{##1}{}{} - \contentsline{subsection}{##3##2}{##4}{} - } - } - } - { - \cs_if_exist:NTF \chapter - { - \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 - { - \contentsline{chapter}{##1}{}{} - \contentsline{section}{##2##3}{##4}{} - } - } - { - \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 - { - \contentsline{section}{##1}{}{} - \contentsline{subsection}{##2##3}{##4}{} - } - } - } - } - {lof} - { % similar to the list of figures - \cs_set_protected:Npn \l@acro - { \@dottedtocline {1} {1.5em} {\l__acro_short_width_dim} } - \bool_if:NTF \l__acro_list_reverse_long_extra_bool - { - \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 - { \contentsline{acro}{\numberline{##1}{##3##2}}{##4}{} } - } - { - \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 - { \contentsline{acro}{\numberline{##1}{##2##3}}{##4}{} } - } - } + \acro_attribute_set:nnn {#1} {alias} {#2} + \tl_gput_right:Nn \g__acro_property_aliases_tl {{#1}} } - \use:x - { - \exp_not:V \l__acro_list_before_tl - \exp_not:n { \acro_list_items:nn {#1} {#2} } - \exp_not:V \l__acro_list_before_tl - } - } - -% `table' template: -\DeclareTemplateInterface {acro-list} {table} {2} - { - table : tokenlist = tabular , - table-spec : tokenlist = lp{.7\linewidth} , - foreign-sep : tokenlist = {~} , - reverse : boolean = false , - before : tokenlist = , - after : tokenlist = } -\DeclareTemplateCode {acro-list} {table} {2} - { - table = \l__acro_list_table_tl , - table-spec = \l__acro_list_table_spec_tl , - foreign-sep = \l__acro_foreign_sep_tl , - reverse = \l__acro_list_reverse_long_extra_bool , - before = \l__acro_list_before_tl , - after = \l__acro_list_after_tl - } +% #1: id +% #2: alias property +\cs_new_protected:Npn \acro_property_set_alias:nn #1#2 { - \AssignTemplateKeys - \acro_activate_hyperref_support: - \bool_if:NTF \l__acro_list_reverse_long_extra_bool - { - \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 - { ##1 & ##3 ##2 ##4 \tabularnewline } - } + \acro_property_if_set:nnF {#1} {#2} { - \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 - { ##1 & ##2 ##3 ##4 \tabularnewline } - } - \acro_build_list_entries:Nnn \l__acro_list_entries_tl {#1} {#2} - \use:x - { - \exp_not:V \l__acro_list_before_tl - \exp_not:N \begin { \exp_not:V \l__acro_list_table_tl } - { \exp_not:V \l__acro_list_table_spec_tl } - \exp_not:V \l__acro_list_entries_tl - \exp_not:N \end { \exp_not:V \l__acro_list_table_tl } - \exp_not:V \l__acro_list_after_tl + \acro_property_if_set:neT {#1} { \acro_property_alias:n {#2} } + { + \__acro_property_set:nne {#1} {#2} + { \acro_property_get:ne {#1} { \acro_property_alias:n {#2} } } + } } } -% `extra-table' template: -\DeclareTemplateInterface {acro-list} {extra-table} {2} +% #1: id +\cs_new_protected:Npn \acro_property_set_aliases:n #1 { - table : tokenlist = tabular , - table-spec : tokenlist = llll , - foreign-sep : tokenlist = {~} , - reverse : boolean = false , - before : tokenlist = , - after : tokenlist = + \tl_map_inline:Nn \g__acro_property_aliases_tl + { \acro_property_set_alias:nn {#1} {##1} } } -\DeclareTemplateCode {acro-list} {extra-table} {2} +% ---------------------------------------------------------------------------- +% retrieve properties: +% #1: id +% #2: property +\cs_new:Npn \acro_property_get:nn #1#2 + { \acro_attribute_get:ne {#2} { \acro_case_insensitive:n {#1} } } +\cs_generate_variant:Nn \acro_property_get:nn {nx,ne,V} + +% ---------------------------------------------------------------------------- +\AcroModuleEnd +% ---------------------------------------------------------------------------- +% the ACRO package - acronyms module +% +% Typeset Acronyms +% +% -------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/acro/ +% E-Mail: contact@mychemistry.eu +% -------------------------------------------------------------------------- +% Copyright 2011--2020 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% -------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% -------------------------------------------------------------------------- +\AcroModule{acronyms}{define acronyms} + +% -------------------------------------------------------------------------- +\msg_new:nnn {acro} {undefined} { - table = \l__acro_list_table_tl , - table-spec = \l__acro_list_table_spec_tl , - foreign-sep = \l__acro_foreign_sep_tl , - reverse = \l__acro_list_reverse_long_extra_bool , - before = \l__acro_list_before_tl , - after = \l__acro_list_after_tl + You've~ requested~ acronym~ `#1'~ \msg_line_context: \ but~ you~ + apparently~ haven't~ defined~ it,~ yet! \\ + Maybe~ you've~ misspelled~ `#1'? } + +\msg_new:nnn {acro} {mandatory} { - \AssignTemplateKeys - \acro_activate_hyperref_support: - \bool_if:NTF \l__acro_list_reverse_long_extra_bool - { - \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 - { ##1 & ##3 & ##2 & ##4 \tabularnewline } - } - { - \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 - { ##1 & ##2 & ##3 & ##4 \tabularnewline } - } - \acro_build_list_entries:Nnn \l__acro_list_entries_tl {#1} {#2} - \use:x - { - \exp_not:V \l__acro_list_before_tl - \exp_not:N \begin { \exp_not:V \l__acro_list_table_tl } - { \exp_not:V \l__acro_list_table_spec_tl } - \exp_not:V \l__acro_list_entries_tl - \exp_not:N \end { \exp_not:V \l__acro_list_table_tl } - \exp_not:V \l__acro_list_after_tl - } + You~ forgot~ to~ set~ the~ mandatory~ property~ `#2'~ for~ acronym~ + `#1'~ \msg_line_context: } % -------------------------------------------------------------------------- -% declare new list styles: -\cs_new_protected:Npn \acro_declare_list_style:nnn #1#2#3 - { - \DeclareInstance {acro-list} {#1} {#2} {#3} - \prop_put:Nnn \l__acro_list_styles_prop {#1} {#2} - } +% short and long list: +\tl_new:N \l__acro_short_tl +\tl_new:N \l__acro_long_tl -% set a list style -\cs_new_protected:Npn \acro_set_list_style:n #1 +\cs_new_protected:Npn \acro_list_add:nn #1#2 { - \prop_if_in:NnTF \l__acro_list_styles_prop {#1} - { \__acro_set_list_style:n {#1} } + \clist_map_inline:nn {#2} { - \msg_warning:nnnnn {acro} {unknown} - {list~ style} - {#1} - {description} - \__acro_set_list_style:n {description} + \tl_put_right:cn {l__acro_#1_tl} {{##1}} + \cs_set:cpn {____acro_#1::##1____:} {} } } -\cs_new_protected:Npn \__acro_set_list_style:n #1 +\cs_new_protected:Npn \acro_list_map:nn #1#2 + { \tl_map_inline:cn {l__acro_#1_tl} {#2} } + +\prg_new_conditional:Npnn \acro_if_short:n #1 {p,T,F,TF} { - \tl_set:Nn \l__acro_list_instance_tl {#1} - \prop_get:NnN \l__acro_list_styles_prop {#1} \l__acro_list_type_tl + \cs_if_exist:cTF {____acro_short::#1____:} + { \prg_return_true: } + { \prg_return_false: } } -% -------------------------------------------------------------------------- -% case insensitivity of the ID: -\cs_new:Npn \acro_case_insensitive:n #1 +\prg_new_conditional:Npnn \acro_if_long:n #1 {p,T,F,TF} { - \bool_if:NTF \g__acro_case_sensitive_bool - { \tl_to_str:n {#1} } - { \str_lowercase:n {#1} } + \cs_if_exist:cTF {____acro_long::#1____:} + { \prg_return_true: } + { \prg_return_false: } } -\cs_new_protected:Npn \acro_protected_case_insensitive:n #1 - { \acro_case_insensitive:n {#1} } - -\cs_new:Npn \acro_case_insensitive:Nn #1#2 - { \exp_args:Ne #1 { \acro_case_insensitive:n {#2} } } +% -------------------------------------------------------------------------- +% define necessary properties: +% short and long properties: +\acro_list_add:nn {short} {short,alt} +\acro_list_add:nn {long} {long,foreign,single,extra,list} + +% meta information: +\DeclareAcroProperty*!{id} +\DeclareAcroProperty ?{used} +\DeclareAcroProperty |{usage} +\DeclareAcroProperty |{pages} +\DeclareAcroProperty |{barriers} +\DeclareAcroProperty* {label} + +% main properties: +\DeclareAcroProperty !{short} +\DeclareAcroProperty {alt} +\DeclareAcroProperty !{long} + +% sorting, indexing, ... : +\DeclareAcroPropertyAlias {sort} {short} +\DeclareAcroProperty {index} +\DeclareAcroProperty?{no-index} +\DeclareAcroPropertyAlias {index-sort} {sort} +\DeclareAcroProperty {index-cmd} +\DeclareAcroProperty {tag} +\DeclareAcroProperty {cite} +\DeclareAcroProperty {before-citation} +\DeclareAcroPropertyAlias {pdfstring} {short} +\DeclareAcroProperty {pdfcomment} + +% locale: +\DeclareAcroProperty {foreign} +\DeclareAcroProperty {foreign-babel} +\DeclareAcroProperty {foreign-locale} + +% additional properties: +\DeclareAcroPropertyAlias {single} {long} +\DeclareAcroPropertyAlias {list} {long} +\DeclareAcroPropertyAlias {first-long} {long} +\DeclareAcroProperty {extra} +\DeclareAcroProperty {post} +\DeclareAcroProperty {long-post} +\DeclareAcroProperty {first-style} +\DeclareAcroProperty {single-style} + +% formatting: +\DeclareAcroProperty {format} +\DeclareAcroPropertyAlias {short-format} {format} +\DeclareAcroProperty {alt-format} +\DeclareAcroPropertyAlias {long-format} {format} +\DeclareAcroPropertyAlias {first-long-format} {long-format} +\DeclareAcroProperty {foreign-format} +\DeclareAcroProperty {single-format} +\DeclareAcroProperty {list-format} +\DeclareAcroProperty {extra-format} + +% Accessibility: +\acro_list_map:nn {short} + { + \DeclareAcroPropertyAlias {#1-acc} {#1} + \acro_list_add:nn {short} {#1-acc} + } + +\DeclareAcroPropertyAlias {single-acc} {long-acc} +\acro_list_map:nn {long} + { + \DeclareAcroPropertyAlias {#1-acc} {#1} + \acro_list_add:nn {long} {#1-acc} + } -\cs_new:Npn \acro_case_insensitive:Nnn #1#2#3 - { \exp_args:Ne #1 { \acro_case_insensitive:n {#2} } {#3} } +% -------------------------------------------------------------------------- +% use id as short entry: +\bool_new:N \g__acro_use_id_bool -\cs_new_protected:Npn \acro_case_insensitive_command:Nnnn #1#2#3#4 - { \exp_args:Nnnx #1 {#2} {#3} { \acro_case_insensitive:n {#4} } } -\cs_generate_variant:Nn \acro_case_insensitive_command:Nnnn {c} +\keys_define:nn {acro} + { + use-id-as-short .choice: , + use-id-as-short / true .code:n = + \bool_gset_true:N \g__acro_use_id_bool , + use-id-as-short / false .code:n = + \bool_gset_false:N \g__acro_use_id_bool , + use-id-as-short .default:n = true + } % -------------------------------------------------------------------------- -% automatic typesetting, the internals of \ac: -% #1: id +% declaration of acronyms: +\seq_new:N \g__acro_acronyms_seq -\cs_new_protected:Npn \acro_soft_upper: +\tl_new:N \l__acro_first_style_tl + +\acro_attribute_new:n {acronyms} + +\keys_define:nn {acro} { - \bool_if:NF \l__acro_upper_short_bool - { \bool_set_false:N \l__acro_first_upper_bool } + first-style .tl_set:N = \l__acro_first_style_tl , + first-style .initial:n = long-short } -\cs_new_protected:Npn \acro_use:n #1 +\cs_new_protected:Npn \acro_declare_acronym:nn #1#2 + { \acro_case_insensitive:Nn \__acro_declare_acronym:nn {#1} {#2} } + +% #1: id +% #2: properties +\cs_new_protected:Npn \__acro_declare_acronym:nn #1#2 { - % get the acronym and the plural settings: - \acro_get:n {#1} - \acro_is_used:nTF {#1} + \int_new:c {g__acro_#1_int} + \seq_new:c {g__acro_#1_pages_seq} + \seq_new:c {g__acro_#1_barriers_seq} + \acro_at_begin_document:n { - \acro_soft_upper: - % this is not the first time - \acro_write_indefinite:nn {#1} {short} - \acro_write_compact:nn {#1} {short} - \acro_after:n {#1} + \intarray_new:cn + {g__acro_#1_barriers_intarray} + { \g_acro_barrier_total_int } } + \seq_gput_right:Nn \g__acro_acronyms_seq {#1} + \acro_attribute_set:nnn {acronyms} {#1} {} + % set defaults: + \__acro_set_article_defaults:n {#1} + % set user input: + \acro_properties_set:nn {#1} {#2} + % set defaults which must not be overwritten: + \acro_property_set:nnn {#1} {usage} {0} + \bool_lazy_and:nnT + { \g__acro_use_id_bool } + { !\acro_property_if_set_p:nn {#1} {short} } + { \acro_property_set:nnn {#1} {short} {#1} } + \acro_property_set:nnn {#1} {id} {#1} + \acro_property_set_aliases:n {#1} + % check mandatory properties: + \acro_property_foreach_mandatory:n { - % this is the first time - \bool_gset_true:c { g__acro_#1_first_use_bool } - \acro_if_is_single:nTF {#1} - { \acro_single:n {#1} } - { \acro_first_instance:nV {#1} \l__acro_long_tl } + \acro_property_if_set:nnF {#1} {##1} + { \msg_error:nnnn {acro} {mandatory} {#1} {##1} } } + % set endings: + \acro_set_endings:n {#1} + \acro_at_end_document:n + { + \acro_property_set:nnx {#1} {usage} { \int_use:c {g__acro_#1_int} } + \acro_set_barriers:n {#1} + } + } + +\prg_new_conditional:Npnn \acro_if_defined:n #1 {p,T,F,TF} + { + \acro_attribute_if_set:neTF {acronyms} + { \acro_case_insensitive:n {#1} } + { \prg_return_true: } + { \prg_return_false: } } -% single appearances: -\cs_new_protected:Npn \acro_single:n #1 +\cs_new_protected:Npn \acro_check_definition:n #1 { - \acro_cite: - \acro_single_form:nV {#1} \l__acro_single_form_tl - \acro_after:n {#1} + \acro_if_defined:nF {#1} + { \msg_error:nnn {acro} {undefined} {#1} } } -% #1: ID -% #2: long|first|<other> -\cs_new_protected:Npn \acro_single_form:nn #1#2 +% -------------------------------------------------------------------------- +% use and reset: +\bool_new:N \l__acro_use_bool +\bool_set_true:N \l__acro_use_bool + +\cs_new_protected:Npn \acro_use_false: + { \bool_set_false:N \l__acro_use_bool } + +\cs_new_protected:Npn \__acro_use:n #1 { - \acro_write_indefinite:nn {#1} {#2} - \str_case:nnF {#2} + \bool_if:NT \l__acro_use_bool { - {long} { - \tl_if_blank:VT \l__acro_single_format_tl - { - \bool_if:NTF \l__acro_custom_long_format_bool - { - \tl_set_eq:NN - \l__acro_single_format_tl - \l__acro_custom_long_format_tl - } - { - \tl_set_eq:NN - \l__acro_single_format_tl - \l__acro_long_format_tl - } - } - \tl_if_blank:VT \l__acro_single_tl - { \tl_set_eq:NN \l__acro_single_tl \l__acro_long_tl } - % BUG: should that be \acro_write_expanded:nn ? - % \acro_write_expanded:nnn {#1} {#2} {\l__acro_single_tl} - \acro_write_long:VV \l__acro_single_format_tl \l__acro_single_tl - \acro_endings:nn {#1} {single} - \l__acro_long_post_tl - } - {first} { - \tl_if_blank:VF \l__acro_single_format_tl - { - \tl_set_eq:NN - \l__acro_first_long_format_tl - \l__acro_single_format_tl - } - \tl_if_blank:VT \l__acro_single_tl - { \tl_set_eq:NN \l__acro_single_tl \l__acro_long_tl } - \acro_first_instance:nV {#1} \l__acro_single_tl - } - } - { % other (e.g. short) - \acro_soft_upper: - \tl_if_blank:VF \l__acro_single_tl - { \tl_set_eq:cN {l__acro_#2_tl} \l__acro_single_tl } - \tl_if_blank:VF \l__acro_single_format_tl - { \tl_set_eq:cN {l__acro_#2_format_tl} \l__acro_single_format_tl } - \acro_write_compact:nn {#1} {#2} + \acro_property_set:nnn {#1} {used} {true} + \acro_step:n {#1} } } -\cs_generate_variant:Nn \acro_single_form:nn {nV} -\prg_new_conditional:Npnn \acro_if_is_single:n #1 { p,T,TF } +\cs_new_protected:Npn \acro_use:n #1 + { \clist_map_inline:nn {#1} { \__acro_use:n {#1} } } +\cs_generate_variant:Nn \acro_use:n {e} + +\cs_new_protected:Npn \acro_use_all: + { \seq_map_inline:Nn \g__acro_acronyms_seq { \__acro_use:n {##1} } } + +\cs_new_protected:Npn \__acro_reset:n #1 { - \bool_lazy_or:nnTF - { !\l__acro_single_use_bool } - { \cs_if_exist_p:c {acro@#1@twice} } - { \prg_return_false: } - { \prg_return_true: } + \acro_property_set:nnn {#1} {used} {false} + \int_gzero:c {g__acro_ \acro_case_insensitive:n {#1} _int} + \int_compare:nNnF + { \acro_property_get:nn {#1} {usage} } > 0 + { \acro_property_set:nnn {#1} {usage} {0} } } -\cs_new_protected:Npn \acro_use_acronym:n #1 - { \use:c {bool_set_#1:N} \l__acro_mark_as_used_bool } +\cs_new_protected:Npn \acro_reset:n #1 + { \clist_map_inline:nn {#1} { \__acro_reset:n {##1} } } + +\cs_new_protected:Npn \acro_reset_all: + { \seq_map_inline:Nn \g__acro_acronyms_seq { \__acro_reset:n {##1} } } + +\cs_new_protected:Npn \acro_switch_off: + { \bool_set_false:N \l__acro_use_bool } + +\cs_new_protected:Npn \acro_switch_on: + { \bool_set_true:N \l__acro_use_bool } % -------------------------------------------------------------------------- -% some helpers we'll need more often: -\prg_new_conditional:Npnn \acro_if_defined:n #1 {p,T,F,TF} +% check for tags: +% #1: id +% #2: tag +\prg_new_protected_conditional:Npnn \acro_tag_if:nn #1#2 {T,F,TF} { - \seq_if_in:NeTF \g__acro_declared_acronyms_seq - { \acro_case_insensitive:n {#1} } + \clist_set:Ne \l__acro_tmpa_clist { \acro_property_get:nn {#1} {tag} } + \clist_if_in:NnTF \l__acro_tmpa_clist {#2} { \prg_return_true: } { \prg_return_false: } } +\prg_generate_conditional_variant:Nnn \acro_tag_if:nn {en} {T,F,TF} -\cs_new_protected:Npn \acro_defined:n #1 +% -------------------------------------------------------------------------- +\AcroModuleEnd +\AcroModule{formatting}{formatting of acronyms} +% -------------------------------------------------------------------------- +% formatting: +\bool_new:N \l__acro_format_replace_bool + +% sets the format from the global option: +% #1: property +\cs_new:Npn \__acro_global_format:n #1 { - \acro_if_defined:nF {#1} - { \acro_serious_message:nn {undefined} {#1} } + \acro_property_if_alias:nTF {#1} + { + \tl_if_empty:cTF {l__acro_format_ #1 _tl} + { \__acro_use_global_format:n { \acro_property_alias:n {#1} } } + { \__acro_use_global_format:n {#1} } + } + { \__acro_use_global_format:n {#1} } } -% expandably gets property but doesn't transform property name -- internal -% name is needed % #1: property -% #2: id -\cs_new:Npn \__acro_property_get:nn #1#2 - { \prop_item:cn {l__acro_#1_prop} {#2} } +\cs_new:Npn \__acro_use_global_format:n #1 + { + \tl_if_exist:cT {l__acro_format_ #1 _tl} + { \tl_use:c {l__acro_format_ #1 _tl} } + } % #1: id % #2: property -% #3: set case -% #4: not set case -\prg_new_protected_conditional:Npnn \acro_property_get:nn #1#2 {T,F,TF} - { - \tl_set:Nn \l__acro_tmpa_tl {#2} - \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} - \prop_get:cncTF - {l__acro_ \l__acro_tmpa_tl _prop} - {#1} - {l__acro_ \l__acro_tmpa_tl _tl} - { \prg_return_true: } +% #3: insert if false +\cs_new:Npn \__acro_property_format:nnF #1#2#3 + { + \acro_property_if_set:nnTF {#1} {#2-format} + { \acro_property_get:nn {#1} {#2-format} } + { + \acro_if_format_alias:nnTF {#1} {#2} + { + \acro_property_get:nn {#1} + { \acro_property_alias:n {#2} -format } + } + {#3} + } + } + +% #1: id +% #1: property +\prg_new_conditional:Npnn \acro_if_format_alias:nn #1#2 {TF} + { + \acro_property_if_alias:nTF {#2} + { + \acro_property_if_set:nnTF {#1} + { \acro_property_alias:n {#2} -format } + { \prg_return_true: } + { \prg_return_false: } + } { \prg_return_false: } } -\cs_new_protected:Npn \acro_property_get:nn #1#2 - { \acro_property_get:nnTF {#1} {#2} {} {} } -\cs_generate_variant:Nn \acro_property_get:nn {V} +% #1: id +% #1: property +\cs_new:Npn \__acro_property_format:nn #1#2 + { \__acro_property_format:nnF {#1} {#2} {} } -% within this command one can refer to the current id with `#1' -\cs_new_protected:Npn \acro_add_action:n #1 - { \seq_put_right:Nn \l__acro_actions_seq {#1} } +% sets the individual format: +% #1: id +% #2: property +% #3: text +\cs_new:Npn \acro_format:nnn #1#2#3 + { + { + \bool_if:NTF \l__acro_format_replace_bool + { + \__acro_property_format:nnF {#1} {#2} + { \__acro_global_format:n {#2} } + {#3} + } + { + \__acro_global_format:n {#2} + { + \__acro_property_format:nn {#1} {#2} + {#3} + } + } + } + } +\cs_generate_variant:Nn \acro_format:nnn {e} -\cs_new_protected:Npn \__acro_get_actions:n #1 +% #1: property: +\cs_new_protected:Npn \acro_new_format:n #1 { - \seq_map_inline:Nn \l__acro_actions_seq + \tl_new:c {l__acro_format_#1_tl} + \keys_define:nn {acro/format} { - \cs_set:Npn \__acro_action:n ####1 {##1} - \__acro_action:n {#1} + #1 .tl_set:c = l__acro_format_#1_tl , + #1 .initial:n = } } -\cs_new_protected:Npn \acro_get:n #1 +\acro_new_format:n {short} +\acro_new_format:n {long} +\acro_new_format:n {alt} +\acro_new_format:n {extra} +\acro_new_format:n {foreign} +\acro_new_format:n {list} +\acro_new_format:n {first-long} + +\keys_define:nn {acro} + { + format .meta:n = { format/short = #1 , format/long = #1 } , + format / replace .bool_set:N = \l__acro_format_replace_bool , + format / replace .initial:n = false + } + +% ---------------------------------------------------------------------------- +\AcroModuleEnd +\AcroModule{ppfixes}{pre- and postfixes to acronyms} +% -------------------------------------------------------------------------- +% articles +\bool_new:N \l__acro_article_bool +\tl_new:N \g__acro_articles_tl + +% #1: name +% #2: default +\cs_new_protected:Npn \acro_article_declare:nn #1#2 { - \bool_if:NF \l__acro_in_list_bool { \leavevmode } - \acro_activate_hyperref_support: - % short: - \acro_property_get:nn {#1} {short} - % alt: - \acro_property_get:nnF {#1} {alt} - { \tl_set_eq:NN \l__acro_alt_tl \l__acro_short_tl } - % long: - \acro_property_get:nn {#1} {long} - % foreign: - \acro_property_get:nn {#1} {foreign} - % foreign-lang: - \acro_property_get:nn {#1} {foreign-lang} - % extra: - \acro_property_get:nn {#1} {extra} - % single: - \acro_property_get:nn {#1} {single} - % first-style: - \acro_property_get:nn {#1} {first-style} - % formatting - \acro_property_get:nnTF {#1} {long-format} - { - \tl_set_eq:NN \l__acro_custom_long_format_tl \l__acro_long_format_tl - \bool_set_true:N \l__acro_custom_long_format_bool - } - { \bool_set_false:N \l__acro_custom_long_format_bool } - \acro_property_get:nn {#1} {first-long-format} - \acro_property_get:nnTF {#1} {format} + \tl_gput_right:Nn \g__acro_articles_tl {{#1}} + \acro_property_declare:nnnnn + { \c_false_bool } { \c_false_bool } { \c_false_bool } { \c_false_bool } + {#1} + \acro_list_map:nn {short} { - \tl_set_eq:NN \l__acro_custom_short_format_tl \l__acro_format_tl - \bool_set_true:N \l__acro_custom_short_format_bool + \DeclareAcroPropertyAlias {##1-#1} {#1} + \str_if_in:nnF {##1} {-acc} + { \DeclareAcroPropertyAlias {##1-acc-#1} {##1-#1} } } - { \bool_set_false:N \l__acro_custom_short_format_bool } - \acro_property_get:nnTF {#1} {alt-format} + \acro_list_map:nn {long} { - \tl_set_eq:NN \l__acro_custom_alt_format_tl \l__acro_alt_format_tl - \bool_set_true:N \l__acro_custom_alt_format_bool + \DeclareAcroPropertyAlias {##1-#1} {#1} + \str_if_in:nnF {##1} {acc} + { \DeclareAcroPropertyAlias {##1-acc-#1} {##1-#1} } } - { \bool_set_false:N \l__acro_custom_alt_format_bool } - \acro_property_get:nnTF {#1} {foreign-format} + \bool_new:c {l__acro_article_#1_bool} + \tl_new:c {l__acro_article_#1_tl} + \exp_args:Nc \NewDocumentCommand {acro#1} {} { \use:c {acro_#1:} } + \cs_new_protected:cpn {acro_#1:} { - \tl_set_eq:NN \l__acro_custom_foreign_format_tl \l__acro_foreign_format_tl - \bool_set_true:N \l__acro_custom_foreign_format_bool + \bool_if:NF \l__acro_article_bool + { + \bool_set_true:c {l__acro_article_#1_bool} + \bool_set_true:N \l__acro_article_bool + } } - { \bool_set_false:N \l__acro_custom_foreign_format_bool } - \acro_property_get:nn {#1} {single-format} - \acro_for_endings_do:n + \keys_define:nn {acro} { - \bool_if:cT {l__acro_##1_bool} - { \__acro_set_ending_for:nnn {##1} {#1} {long} } + #1 .tl_set:c = {l__acro_article_#1_tl} , + #1 .initial:n = #2 } - \acro_property_get:nnF {#1} {long-post} - { \tl_clear:N \l__acro_long_post_tl } - \acro_property_get:nnT {#1} {long-pre} - { \tl_put_left:NV \l__acro_long_tl \l__acro_long_pre_tl } - \__acro_get_actions:n {#1} } +% #1: id +\cs_new_protected:Npn \__acro_set_article_defaults:n #1 + { + \tl_map_tokens:Nn \g__acro_articles_tl + { \__acro_default_article:nn {#1} } + } + +% #1: id +% #2: article +\cs_new_protected:Npn \__acro_default_article:nn #1#2 + { \acro_property_set:nnv {#1} {#2} {l__acro_article_#2_tl} } + % -------------------------------------------------------------------------- -% plural endings and similar concepts: +% mechanism for endings: +\tl_new:N \l__acro_endings_tl -\cs_new_protected:Npn \acro_for_endings_do:n #1 - { \seq_map_inline:Nn \l__acro_endings_seq {#1} } +\bool_new:N \l__acro_ending_bool -% #1: ending -% #2: ID -\cs_new_protected:Npn \__acro_set_ending:nn #1#2 +\acro_attribute_new:n {short:endings} +\acro_attribute_new:n {long:endings} + +\cs_new_protected:Npn \__acro_declare_ending_properties:n #1 { - \bool_if:cT {l__acro_#1_bool} - { - \__acro_set_ending_for:nnn {#1} {#2} {short} - \__acro_set_ending_for:nnn {#1} {#2} {alt} - \__acro_set_ending_for:nnn {#1} {#2} {long} - \__acro_set_ending_for:nnn {#1} {#2} {foreign} % XXX - } + \acro_property_declare:nnnnn + { \c_false_bool } { \c_false_bool } { \c_false_bool } { \c_false_bool } + {#1} + \acro_property_declare:nnnnn + { \c_false_bool } { \c_false_bool } { \c_false_bool } { \c_false_bool } + {#1-form} } -% this does nothing if a non-existent ending (#1) or non-existent form (#3) is -% input % #1: ending -% #2: id -% #3: short|alt|long|foreign -\cs_new_protected:Npn \__acro_set_ending_for:nnn #1#2#3 +% #2: short default +% #3: long default +\cs_new_protected:Npn \acro_declare_ending:nnn #1#2#3 { - \acro_if_ending_form_exist:nnT {#1} {#3} + \bool_new:c {l__acro_ending_#1_bool} + \exp_args:Nc \NewDocumentCommand {acro#1} {} { \use:c {acro_#1:} } + \cs_new_protected:cpn {acro_#1:} + { + \bool_if:NF \l__acro_ending_bool + { + \bool_set_true:c {l__acro_ending_#1_bool} + \bool_set_true:N \l__acro_ending_bool + } + } + \prg_new_conditional:cpnn {acro_if_#1:} {p,T,F,TF} + { + \bool_if:cTF {l__acro_ending_#1_bool} + { \prg_return_true: } + { \prg_return_false: } + } + \tl_put_right:Nn \l__acro_endings_tl {{#1}} + \keys_define:nn {acro} + { + short-#1-ending .code:n = + \acro_attribute_set:nnn {short:endings} {#1} {##1} , + short-#1-ending .initial:n = #2 , + long-#1-ending .code:n = + \acro_attribute_set:nnn {long:endings} {#1} {##1} , + long-#1-ending .initial:n = #3 + } + \__acro_declare_ending_properties:n {#1}% plural + plural-form + \acro_list_map:nn {short} { - \bool_if:cTF - { c_ \prop_item:cn {l__acro_#3_#1_form_prop} {#2} _bool } - { \prop_get:cnc {l__acro_#3_#1_prop} {#2} {l__acro_#3_tl} } - { \prop_get:cnc {l__acro_#3_#1_prop} {#2} {l__acro_#3_#1_tl} } + % short-plural + short-plural-form + \__acro_declare_ending_properties:n {##1-#1} + % short-plural = plural + \acro_property_make_alias:nn {##1-#1} {#1} + } + \acro_list_map:nn {long} + { + % long-plural + long-plural-form + \__acro_declare_ending_properties:n {##1-#1} + % long-plural = plural + \acro_property_make_alias:nn {##1-#1} {#1} + % long-plural-form = plural-form + \acro_property_make_alias:nn {##1-#1-form} {#1-form} } } -\cs_new_protected:Npn \__acro_set_endings:n #1 +% #1: id +% #2: short|long +\cs_new_protected:Npn \__acro_set_endings:nn #1#2 { - \acro_for_endings_do:n - { \__acro_set_ending:nn {##1} {#1} } + \acro_list_map:nn {#2} + { + \tl_map_inline:Nn \l__acro_endings_tl + { \__acro_set_ending:nnnn {#1} {#2} {##1} {####1} } + } } % #1: id -% #2: short|alt|… -\cs_new_protected:Npn \acro_get_ending_form:nn #1#2 +% #2: short|long +% #3: property +% #4: ending +\cs_new_protected:Npn \__acro_set_ending:nnnn #1#2#3#4 { - \acro_for_endings_do:n + \acro_property_if_set:nnF {#1} {#3-#4-form} { - \acro_if_ending_form_exist:nnT {##1} {#2} + \acro_property_if_set:nnF {#1} {#3-#4} { - \bool_lazy_and:nnT - { \use:c {l__acro_##1_bool} } - { \use:c { c_ \prop_item:cn {l__acro_#2_##1_form_prop} {#1} _bool } } - { \prop_get:cncF {l__acro_#2_##1_prop} {#1} {l__acro_#2_tl} {} } + \__acro_property_set:nne {#1} {#3-#4} + { \acro_attribute_get:nn {#2:endings} {#4} } } } } % #1: id -% #2: short|alt|… -\cs_new_protected:Npn \acro_endings:nn #1#2 +\cs_new_protected:Npn \acro_set_endings:n #1 { - \group_begin: - \str_if_eq:nnTF {#2} {single} - { - \keys_set:nn {acro} - { long-format= \l__acro_single_format_tl } - \__acro_endings:nn {#1} {long} - } - { \__acro_endings:nn {#1} {#2} } - \group_end: + \__acro_set_endings:nn {#1} {short} + \__acro_set_endings:nn {#1} {long} + } + +% ---------------------------------------------------------------------------- +\AcroModuleEnd +\AcroModule{tools}{tools for treating different aspects} + +% ---------------------------------------------------------------------------- +\bool_new:N \l__acro_label_bool +\tl_new:N \l_acro_label_prefix_tl + +\keys_define:nn {acro} + { + labels .bool_set:N = \l__acro_label_bool , + labels .initial:n = false , + label-prefix .tl_set:N = \l_acro_label_prefix_tl , + label-prefix .initial:n = ac: } -\cs_new_protected:Npn \__acro_endings:nn #1#2 +% -------------------------------------------------------------------------- +% check for first usage: +\bool_new:N \l__acro_first_bool + +\cs_new_protected:Npn \acro_first: + { \bool_set_true:N \l__acro_first_bool } + +\prg_new_conditional:Npnn \acro_if_first:n #1 {p,T,F,TF} { - \acro_for_endings_do:n + \bool_if:NTF \l__acro_first_bool + { \prg_return_true: } { - \__acro_set_ending_for:nnn {##1} {#1} {#2} - \bool_if:cT {l__acro_##1_bool} - { \__acro_ending_format:nn {#2} { \tl_use:c {l__acro_#2_##1_tl} } } + \acro_boolean_property_if:nnTF {#1} {used} + { \prg_return_false: } + { \prg_return_true: } } } +\prg_generate_conditional_variant:Nnn \acro_if_first:n {e,V} {T,F,TF} + +% -------------------------------------------------------------------------- +% check for single usage: +\int_new:N \l__acro_minimal_usage_int -% #1: long|short|alt -% #2: string -\cs_new_protected:Npn \__acro_ending_format:nn #1#2 +% #1: id +\cs_new_protected:Npn \acro_step:n #1 + { \int_gincr:c {g__acro_ \acro_case_insensitive:n {#1} _int} } +\cs_generate_variant:Nn \acro_step:n {e} + +% #1: id +\prg_new_conditional:Npnn \acro_if_single:n #1 {p,T,F,TF} { - \bool_if:NTF \l__acro_include_endings_format_bool + \int_compare:nNnTF { - \str_case:nn {#1} - { - {long} - { - \bool_if:NTF \l__acro_custom_long_format_bool - { \l__acro_custom_long_format_tl } - { - \bool_if:NTF \l__acro_first_instance_bool - { \l__acro_first_long_format_tl } - { \l__acro_long_format_tl } - } - } - {short} - { - \bool_if:NTF \l__acro_custom_short_format_bool - { \l__acro_custom_short_format_tl } - { \l__acro_short_format_tl } - } - {alt} - { - \bool_if:NTF \l__acro_custom_alt_format_bool - { \l__acro_custom_alt_format_tl } - { \l__acro_alt_format_tl } - } - {foreign} - { - \bool_if:NTF \l__acro_custom_foreign_format_bool - { \l__acro_custom_foreign_format_tl } - { \l__acro_foreign_format_tl } - } - } + \bool_if:NTF \l__acro_usage_local_bool + { \acro_barrier_usage:n {#1} } + { \acro_property_get:nn {#1} {usage} } } - { \use:n } - {#2} + > \l__acro_minimal_usage_int + { \prg_return_false: } + { \prg_return_true: } } - -\prg_new_conditional:Npnn \acro_if_ending_exist:n #1 {p,T,F,TF} +\prg_generate_conditional_variant:Nnn \acro_if_single:n {e,V} {p,TF} + +\bool_new:N \l__acro_use_only_first_bool +\tl_new:N \l__acro_single_tl + +\keys_define:nn {acro} { - \seq_if_in:NnTF \l__acro_endings_seq {#1} - { \prg_return_true: } - { \prg_return_false: } + single .code:n = + \str_case:nnF {#1} + { + {} { \int_set:Nn \l__acro_minimal_usage_int {1} } + {true} { \int_set:Nn \l__acro_minimal_usage_int {1} } + {false} { \int_set:Nn \l__acro_minimal_usage_int {0} } + } + { \int_set:Nn \l__acro_minimal_usage_int {#1} } , + minimal-usage .meta:n = { single = #1 } , + single .initial:n = 0 , + single-style .tl_set:N = \l__acro_single_tl , + single-style .initial:n = long , + use-only-first .bool_set:N = \l__acro_use_only_first_bool , + use-only-first .initial:n = false } -% #1: ending -% #2: short|alt|… -\prg_new_conditional:Npnn \acro_if_ending_form_exist:nn #1#2 {p,T,F,TF} +% -------------------------------------------------------------------------- +% uppercasing the first letter: +\bool_new:N \l__acro_upper_bool +\bool_new:N \l__acro_upper_short_bool +\bool_new:N \l__acro_upper_list_bool + +\cs_new:Npn \__acro_upper_case:n #1 {} +\cs_new:Npn \__acro_list_upper_case:n #1 {} + +\cs_new_protected:Npn \acro_soft_upper: { - \cs_if_exist:cTF {l__acro_#2_#1_prop} - { \prg_return_true: } - { \prg_return_false: } + \bool_if:NF \l__acro_upper_short_bool + { \bool_set_false:N \l__acro_upper_bool } } - -% #1: name -% #2: default short -% #3: default long -\cs_new_protected:Npn \acro_provide_ending:nnn #1#2#3 - { - \acro_if_ending_exist:nTF {#1} - { - \acro_harmless_message:nn {ending-exists} {#1} - % short variables - \acro_set_ending_variables:nnn {short} {#1} {#2} - % alt variables - \acro_set_ending_variables:nnn {alt} {#1} {#2} - % long variables - \acro_set_ending_variables:nnn {long} {#1} {#3} - % foreign variables % XXX - \acro_set_ending_variables:nnn {foreign} {#1} {#3} - } - { - % registering: - \bool_if:NT \g__acro_first_acronym_declared_bool - { \acro_serious_message:n {ending-before-acronyms} } - \seq_put_right:Nn \l__acro_endings_seq {#1} - \bool_new:c {l__acro_#1_bool} - % short variables - \acro_define_and_set_ending_variables:nnn {short} {#1} {#2} - % alt variables - \acro_define_and_set_ending_variables:nnn {alt} {#1} {#2} - % long variables - \acro_define_and_set_ending_variables:nnn {long} {#1} {#3} - % foreign variables % XXX - \acro_define_and_set_ending_variables:nnn {foreign} {#1} {#3} - % define setup command: - \tl_set:Nn \l__acro_tmpa_tl {#1} - \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} - \cs_new_protected:cpn {acro_ \l__acro_tmpa_tl :} - { \bool_set_true:c {l__acro_#1_bool} } - % acronym properties: - % short-<ending>: - \acro_declare_property:nnn {short_#1} {short-#1} - { - \prop_put:cnn {l__acro_short_#1_form_prop} {##1} {false} - \prop_put:cnx {l__acro_pdfstring_short_#1_prop} - {##1} { \prop_item:Nn \l__acro_short_prop {##1} \exp_not:n {##2} } - } - % short-<ending>-form: - \acro_declare_property_generic:nnn {short_#1_form} {short-#1-form} - { - \__acro_property_check:nn {##1} {short-#1-form} - \prop_put:cnn {l__acro_short_#1_form_prop} {##1} {true} - \prop_put:cnn {l__acro_short_#1_prop} {##1} {##2} - \prop_put:cnn {l__acro_pdfstring_short_#1_prop} {##1} {##2} - } - % alt-<ending>: - \acro_declare_property:nnn {alt_#1} {alt-#1} - { - \prop_put:cnn {l__acro_alt_#1_form_prop} {##1} {false} - \prop_put:cnx {l__acro_pdfstring_alt_#1_prop} - {##1} { \prop_item:Nn \l__acro_alt_prop {##1} \exp_not:n {##2} } - } - % alt-<ending>-form: - \acro_declare_property_generic:nnn {alt_#1_form} {alt-#1-form} - { - \__acro_property_check:nn {##1} {alt-#1-form} - \prop_put:cnn {l__acro_alt_#1_form_prop} {##1} {true} - \prop_put:cnn {l__acro_alt_#1_prop} {##1} {##2} - \prop_put:cnn {l__acro_pdfstring_alt_#1_prop} {##1} {##2} - } - % long-<ending>: - \acro_declare_property:nnn {long_#1} {long-#1} - { \prop_put:cnn {l__acro_long_#1_form_prop} {##1} {false} } - % long-<ending>-form: - \acro_declare_property_generic:nnn {long_#1_form} {long-#1-form} - { - \__acro_property_check:nn {##1} {long-#1-form} - \prop_put:cnn {l__acro_long_#1_form_prop} {##1} {true} - \prop_put:cnn {l__acro_long_#1_prop} {##1} {##2} - } - % foreign-<ending>: % XXX - \acro_declare_property:nnn {foreign_#1} {foreign-#1} - { \prop_put:cnn {l__acro_foreign_#1_form_prop} {##1} {false} } - % foreign-<ending>-form: % XXX - \acro_declare_property_generic:nnn {foreign_#1_form} {foreign-#1-form} - { - \__acro_property_check:nn {##1} {foreign-#1-form} - \prop_put:cnn {l__acro_foreign_#1_form_prop} {##1} {true} - \prop_put:cnn {l__acro_foreign_#1_prop} {##1} {##2} - } - % options: - % short-<ending>-ending - % alt-<ending>-ending - % long-<ending>-ending - % foreign-<ending>-ending % XXX - % <ending>-ending - \keys_define:nn {acro} - { - short-#1-ending .code:n = - \bool_if:NT \g__acro_first_acronym_declared_bool - { \acro_serious_message:n {ending-before-acronyms} } - \tl_set:cn {l__acro_default_short_#1_tl} {##1} , - alt-#1-ending .code:n = - \bool_if:NT \g__acro_first_acronym_declared_bool - { \acro_serious_message:n {ending-before-acronyms} } - \tl_set:cn {l__acro_default_alt_#1_tl} {##1} , - long-#1-ending .code:n = - \bool_if:NT \g__acro_first_acronym_declared_bool - { \acro_serious_message:n {ending-before-acronyms} } - \tl_set:cn {l__acro_default_long_#1_tl} {##1} , - foreign-#1-ending .code:n = - \bool_if:NT \g__acro_first_acronym_declared_bool - { \acro_serious_message:n {ending-before-acronyms} } - \tl_set:cn {l__acro_default_foreign_#1_tl} {##1} , - #1-ending .code:n = - \bool_if:NT \g__acro_first_acronym_declared_bool - { \acro_serious_message:n {ending-before-acronyms} } - \__acro_read_ending_settings:nww {#1} ##1// \acro_stop: - } - % pdfstrings: - % TODO: add long forms: - \prop_new:c {l__acro_pdfstring_short_#1_prop} - \cs_new:cpn {acro_pdf_string_short_#1:n} ##1 - { - \acro_if_star_gobble:nTF {##1} - { \use:e { \prop_item:cn {l__acro_pdfstring_short_#1_prop} } } - { \use:e {\prop_item:cn {l__acro_pdfstring_short_#1_prop} {##1} } } - } - \cs_new:cpn {acpdfstring#1} { \use:c {acro_pdf_string_short_#1:n} } - \prop_new:c {l__acro_pdfstring_alt_#1_prop} - \cs_new:cpn {acro_pdf_string_alt_#1:n} ##1 - { - \acro_if_star_gobble:nTF {##1} - { \prop_item:cn {l__acro_pdfstring_alt_#1_prop} } - { \prop_item:cn {l__acro_pdfstring_alt_#1_prop} {##1} } - } - \cs_new:cpn {acpdfstringalt#1} { \use:c {acro_pdf_string_alt_#1:n} } - } + +\cs_new_protected:Npn \acro_upper: + { + \bool_if:NT \l__acro_article_bool + { \bool_set_false:N \l__acro_article_bool } + \bool_set_true:N \l__acro_upper_bool + } + +\cs_new:Npn \__acro_upper:n #1 + { + \bool_if:NTF \l__acro_upper_bool + { \__acro_upper_case:n {#1} } + {#1} } +\cs_generate_variant:Nn \__acro_upper:n {e} -% #1: short|alt|long -% #2: ending name -% #3: default ending -\cs_new_protected:Npn \acro_define_and_set_ending_variables:nnn #1#2#3 +\keys_define:nn {acro/uppercase} { - \acro_define_ending_variables:nn {#1} {#2} - \acro_set_ending_variables:nnn {#1} {#2} {#3} + cmd .cs_set:Np = \__acro_upper_case:n , + cmd .value_required:n = true , + first .meta:n = { cmd = \text_titlecase_first:n } , + first .value_forbidden:n = true , + all .meta:n = { cmd = \text_uppercase:n } , + all .value_forbidden:n = true , + none .meta:n = { cmd = \text_lowercase:n } , + none .value_forbidden:n = true , + title .meta:n = { first } , + title .value_forbidden:n = true , + short .bool_set:N = \l__acro_upper_short_bool , + short .initial:n = true , + list .bool_set:N = \l__acro_upper_list_bool , + list .initial:n = false } -% #1: short|alt|long -% #2: ending name -\cs_new_protected:Npn \acro_define_ending_variables:nn #1#2 +\keys_define:nn {acro/list/uppercase} { - \prop_new:c {l__acro_#1_#2_prop} - \prop_new:c {l__acro_#1_#2_form_prop} - \tl_new:c {l__acro_#1_#2_tl} - \tl_new:c {l__acro_default_#1_#2_tl} + cmd .cs_set:Np = \__acro_list_upper_case:n , + cmd .value_required:n = true , + first .meta:n = { cmd = \text_titlecase_first:n } , + first .value_forbidden:n = true , + all .meta:n = { cmd = \text_uppercase:n } , + all .value_forbidden:n = true , + none .meta:n = { cmd = \text_lowercase:n } , + none .value_forbidden:n = true , + title .meta:n = { first } , + title .value_forbidden:n = true , } -% #1: short|alt|long -% #2: ending name -% #3: default ending -\cs_new_protected:Npn \acro_set_ending_variables:nnn #1#2#3 - { \tl_set:cn {l__acro_default_#1_#2_tl} {#3} } +\keys_set:nn {acro} { list/uppercase/first , uppercase/first } -% #1: ending name -% #2: short (and long if #4 is blank) -% #3: long -\cs_new_protected:Npn \__acro_read_ending_settings:nww #1#2/#3/#4 \acro_stop: +% -------------------------------------------------------------------------- +% citing: +\bool_new:N \l__acro_cite_bool +\bool_new:N \l__acro_cite_always_bool +\bool_new:N \l__acro_cite_group_bool +\bool_new:N \g__acro_cited_bool + +\tl_new:N \l__acro_cite_pre_tl +\tl_new:N \l__acro_cite_between_tl + +% #1: id +\cs_new_protected:Npn \__acro_cite:n #1 { - \acro_set_ending_variables:nnn {short} {#1} {#2} - \acro_set_ending_variables:nnn {alt} {#1} {#2} - \tl_if_blank:nTF {#4} + \use:e { - \acro_set_ending_variables:nnn {long} {#1} {#3} - \acro_set_ending_variables:nnn {foreign} {#1} {#3} - } - { - \acro_set_ending_variables:nnn {long} {#1} {#2} - \acro_set_ending_variables:nnn {foreign} {#1} {#2} + \__acro_cite:w + \acro_property_get:nn {#1} {cite} } + [\q_no_value] + [\q_no_value] + \scan_stop: + \acro_stop: } +\cs_generate_variant:Nn \__acro_cite:n {e} -% -------------------------------------------------------------------------- -% enable us to know if the acronym is used only once and provide a different -% style for that: -\prg_new_protected_conditional:Npnn \acro_is_used:n #1 { T,F,TF } +% #1: boolean, true if starred +% #2: id +\prg_new_conditional:Npnn \acro_cite_if:nn #1#2 {T,F,TF} { - \acro_record_barrier:n {#1} - \bool_lazy_and:nnTF - { \bool_if_p:c {g__acro_#1_used_bool} } + \bool_lazy_all:nTF { - \bool_lazy_or_p:nn - { - \bool_lazy_and_p:nn - { \bool_if_p:c {g__acro_#1_first_use_bool} } - { \g__acro_mark_first_as_used_bool } - } - { !\g__acro_mark_first_as_used_bool } + { \l__acro_cite_bool } + { \l__acro_use_bool } + { !#1 } } { - \bool_if:NTF \l__acro_mark_as_used_bool - { - \__acro_aux_file:Nxxxx \acro@used@twice - {#1} - { \thepage } - { \arabic {page} } - { \arabic {abspage} } - } - { \__acro_aux_file:Nxxxx \acro@used@twice {#1} {} {} {} } - \prg_return_true: + \bool_lazy_or:nnTF + { \l__acro_cite_always_bool } + { \acro_if_first_p:n {#2} } + { \prg_return_true: } + { \prg_return_false: } } + { \prg_return_false: } + } +\prg_generate_conditional_variant:Nnn \acro_cite_if:nn {ne} {T} + +% #1: cite key +\cs_new_protected:Npn \acro_cite:n #1 + { + \acro_property_if_set:nnT {#1} {cite} { - \bool_if:NTF \l__acro_mark_as_used_bool - { - \__acro_aux_file:Nxxxx \acro@used@once - {#1} - { \thepage } - { \arabic {page} } - { \arabic {abspage} } - \bool_lazy_and:nnT - { !\bool_if_p:c {g__acro_#1_label_bool} } - { \l__acro_place_label_bool } - { - \bool_gset_true:c { g__acro_#1_label_bool } - \label{\l__acro_label_prefix_tl #1} - } - \bool_gset_true:c { g__acro_#1_used_bool } - } - {} - % I can't remember why I want an empty first use case for starred - % acronyms… - % { \__acro_aux_file:Nxxxx \acro@used@once {#1} {} {} {} } - \prg_return_false: + \acro_property_get:nn {#1} {before-citation} + \l__acro_cite_pre_tl + \__acro_cite:n {#1} + \bool_gset_true:N \g__acro_cited_bool } } +\cs_generate_variant:Nn \acro_cite:n {e} -\cs_new:Npn \acro_is_used:n #1 - { \acro_is_used:nTF {#1} { } { } } +\cs_new_protected:Npn \__acro_cite:w #1[#2]#3[#4]#5#6 \acro_stop: + { + % no options: #1: key, #6 is blank + % 1 option: #3: key, #2: option, #4: \q_no_value + % 2 options: #5: property, #2: first option, #4: second option + \tl_if_blank:nTF {#6} + { \__acro_cite_cmd:w {#1} } + { + \quark_if_no_value:nTF {#4} + { \__acro_cite_cmd:w [{#2}] {#3}} + { \__acro_cite_cmd:w [{#2}] [{#4}] {#5} } + } + } -\cs_new_protected:Npn \__acro_aux_file:Nnnnn #1#2#3#4#5 - { \iow_shipout:Nn \@auxout { #1 {#2} {#3} {#4} {#5} } } -\cs_generate_variant:Nn \__acro_aux_file:Nnnnn {Nxxxx} - -\cs_new_protected:Npn \__acro_aux_file_now:n #1 - { \iow_now:Nn \@auxout {#1} } -\cs_generate_variant:Nn \__acro_aux_file_now:n {x} +\cs_new_protected:Npn \__acro_cite_cmd:w {} +\cs_new_protected:Npn \__acro_cite_group_cmd:w {} + +\keys_define:nn {acro/cite} + { + cmd .cs_set:Np = \__acro_cite_cmd:w , + cmd .initial:n = \cite , + cmd .value_required:n = true , + group .code:n = + \str_case:nnTF {#1} + { {true} {} {false} {} } + { \use:c {bool_set_#1:N} \l__acro_cite_group_bool } + { \msg_error:nnn {kernel} {boolean-values-only} {group} } , + group .initial:n = false , + display .choice: , + display/all .code:n = + \bool_set_true:N \l__acro_cite_bool + \bool_set_true:N \l__acro_cite_always_bool , + display/first .code:n = + \bool_set_true:N \l__acro_cite_bool + \bool_set_false:N \l__acro_cite_always_bool , + display/none .code:n = \bool_set_false:N \l__acro_cite_bool , + display .initial:n = first , + pre .tl_set:N = \l__acro_cite_pre_tl , + pre .initial:n = \nobreakspace , + group / pre .tl_set:N = \l__acro_cite_between_tl , + group / pre .initial:n = {,~} , + group / cmd .cs_set:Np = \__acro_cite_group_cmd:w , + group / cmd .initial:n = \cite + } % -------------------------------------------------------------------------- -% the commands for the auxiliary file: -\cs_new_protected:Npn \acro@used@once #1#2#3#4 +% indexing +\bool_new:N \l__acro_index_bool +\tl_new:N \l_acro_index_disable_tl + +\cs_new_protected:Npn \__acro_index:n {} +\cs_generate_variant:Nn \__acro_index:n {e} + +% #1: id +\cs_new_protected:Npn \acro_index:n #1 { - \cs_gset_nopar:cpn {acro@#1@once} {#1} - \bool_gset_true:c {g__acro_#1_in_list_bool} - \tl_if_empty:nF {#2#3#4} + \bool_lazy_and:nnT + { \l__acro_index_bool } + { !\acro_boolean_property_if_p:nn {#1} {no-index} } { - % \bool_gset_true:c { g__acro_#1_used_bool } - \seq_gput_right:cn {g__acro_#1_pages_seq} { {#2}{#3}{#4} } + \group_begin: + \acro_trailing_map:n + { \bool_set_false:c {l__acro_trailing_##1_bool} } + \l_acro_index_disable_tl + \acro_property_if_set:nnT {#1} {index-cmd} + { + \exp_args:NNe + \cs_set:Npn \__acro_index:n + { \acro_property_get:nn {#1} {index-cmd} } + } + \acro_property_if_set:nnTF {#1} {index} + { \__acro_index:e { \acro_property_get:nn {#1} {index} } } + { + \__acro_index:e + { + \acro_property_get:nn {#1} {index-sort} @ + \acro_format:nnn + {#1} + {short} + { \acro_property_get:nn {#1} {short} } + } + } + \group_end: } } -\cs_new_protected:Npn \acro@used@twice #1#2#3#4 + +\keys_define:nn {acro/index} { - \cs_gset_nopar:cpn {acro@#1@twice} {#1} - \tl_if_empty:nF {#2#3#4} - { \seq_gput_right:cn {g__acro_#1_pages_seq} { {#2}{#3}{#4} } } + use .bool_set:N = \l__acro_index_bool , + use .initial:n = false , + cmd .cs_set:Np = \__acro_index:n , + cmd .initial:n = \index , + cmd .value_required:n = true , + disable .code:n = \tl_put_right:Nn \l_acro_index_disable_tl {#1} , + disable .value_required:n = true , + clear .code:n = \tl_clear:N \l_acro_index_disable_tl , + clear .value_forbidden:n = true } -\cs_new_protected:Npn \acro@pages #1#2 - { \tl_gset:cn {g__acro_#1_recorded_pages_tl} {#2} } +\keys_set:nn {acro/index} { disable = \def\@{} } -\cs_new_protected:Npn \acro@rerun@check +% -------------------------------------------------------------------------- +% looking for trailing tokens and define action +\bool_new:N \l__acro_trailing_tokens_bool +\tl_new:N \l__acro_trailing_tokens_tl +\tl_new:N \g__acro_trailing_tokens_tl +\acro_attribute_new:n {trailing:token} +\acro_attribute_new:n {trailing:action} + +\cs_new_protected:Npn \acro_trailing_action_new:n #1 + { \bool_new:c {l__acro_trailing_#1_bool} } + +\cs_new_protected:Npn \acro_trailing_action_activate:n #1 + { \bool_set_true:c {l__acro_trailing_#1_bool} } + +\cs_new_protected:Npn \acro_trailing_action_deactivate:n #1 + { \bool_set_false:c {l__acro_trailing_#1_bool} } + +% register a new token but don't activate its action: +% #1: token +% #2: action +\cs_new_protected:Npn \acro_trailing_token_register:Nn #1#2 { - \bool_if:NT \g__acro_rerun_bool - { - \@latex@warning@no@line - {Acronyms~ may~ have~ changed.~ Please~ rerun~ LaTeX} - } + \tl_gput_right:Nn \g__acro_trailing_tokens_tl {{#2}} + \acro_attribute_set:nnn {trailing:token} {#2} {#1} + \acro_attribute_set:nnn {trailing:action} {#1} + { \acro_trailing_action_activate:n {#2} } + \acro_trailing_action_new:n {#2} } -\AtEndDocument +% maps over actions +\cs_new_protected:Npn \acro_trailing_map:n #1 + { \tl_map_inline:Nn \g__acro_trailing_tokens_tl {#1} } + +% activate a token: +% #1: action +\cs_new_protected:Npn \acro_trailing_token_activate:n #1 { - \bool_gset_false:N \g__acro_rerun_bool - \cs_gset_protected:Npn \acro@used@once #1#2#3#4 + \tl_set:Ne \l__acro_tmpa_tl { \acro_attribute_get:nn {trailing:token} {#1} } + \tl_if_blank:VF \l__acro_tmpa_tl { - \tl_set:Nn \l__acro_tmpa_tl {#1} - \tl_if_eq:cNF {acro@#1@once} \l__acro_tmpa_tl - { \bool_gset_true:N \g__acro_rerun_bool } + \tl_remove_all:NV \l__acro_trailing_tokens_tl \l__acro_tmpa_tl + \tl_put_right:NV \l__acro_trailing_tokens_tl \l__acro_tmpa_tl } - \cs_gset_protected:Npn \acro@used@twice #1#2#3#4 + } + +% deactivate a token: +% #1: action +\cs_new_protected:Npn \acro_trailing_token_deactivate:n #1 + { + \tl_set:Ne \l__acro_tmpa_tl { \acro_attribute_get:nn {trailing:token} {#1} } + \tl_if_blank:VF \l__acro_tmpa_tl + { \tl_remove_once:NV \l__acro_trailing_tokens_tl \l__acro_tmpa_tl } + } + +% #1: action +\prg_new_conditional:Npnn \acro_trailing_if_token:n #1 {p,T,F,TF} + { + \bool_if:cTF {l__acro_trailing_#1_bool} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: csv list of actions +\prg_new_conditional:Npnn \acro_trailing_if_tokens:n #1 {T,F,TF} + { + \clist_map_function:nN {#1} \__acro_trailing_if_tokens:n + \use_ii:nn + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: action +\cs_new:Npn \__acro_trailing_if_tokens:n #1 + { + \bool_if:cT {l__acro_trailing_#1_bool} + { \clist_map_break:n { \use_ii:nnn } } + } + +\cs_new_protected:Npn \__acro_trailing_check:N #1 + { + \tl_map_inline:Nn \l__acro_trailing_tokens_tl { - \tl_set:Nn \l__acro_tmpa_tl {#1} - \tl_if_eq:cNF {acro@#1@twice} \l__acro_tmpa_tl - { \bool_gset_true:N \g__acro_rerun_bool } + \token_if_eq_meaning:NNT #1 ##1 + { \acro_attribute_get:nn {trailing:action} {##1} } } - \acro_for_all_acronyms_do:n + } + +\cs_new_protected:Npn \acro_begin: + { + \group_begin: + \__acro_check_after_end:w + } + +\cs_new_protected:Npn \__acro_check_after_end:w #1 \acro_end: + { + \cs_set:Npn \__acro_execute: { - \seq_if_empty:cF {g__acro_#1_pages_seq} - { - \__acro_aux_file_now:x - { - \acro@pages {#1} - { \seq_use:cn {g__acro_#1_pages_seq} {|} } ^^J - \acro@barriers {#1} - { \seq_use:cn {g__acro_#1_barriers_seq} {,} } - } - } - \acro_check_barriers:n {#1} + \__acro_trailing_check:N \l_peek_token + #1 + \acro_end: % this will end the group opened by \acro_begin: } - \__acro_aux_file_now:n { \acro@rerun@check } + \peek_after:Nw \__acro_execute: } -% if `acro' is deactivated prevent unnecessary errors from aux file: -\if@filesw -\AtBeginDocument +\bool_new:N \g__acro_gobble_trail_bool + +\cs_new_protected:Npn \acro_end: { - \__acro_aux_file_now:n + \bool_if:NT \g__acro_gobble_trail_bool { - \providecommand \acro@used@once [4] {} ^^J - \providecommand \acro@used@twice [4] {} ^^J - \providecommand \acro@pages [2] {} ^^J - \providecommand \acro@rerun@check {} ^^J - \providecommand \acro@print@list {} ^^J - \providecommand \acro@barriers [2] {} + \bool_gset_false:N \g__acro_gobble_trail_bool + \use_i:nn } + \group_end: } -\fi -% -------------------------------------------------------------------------- -% #1: short|alt|long -% #2: string to be typeset -\cs_new_protected:Npn \__acro_typeset:nn #1#2 +% register some tokens to be checked for: +\acro_trailing_token_register:Nn . {dot} +\acro_trailing_token_register:Nn , {comma} +\acro_trailing_token_register:Nn - {dash} +\acro_trailing_token_register:Nn \babelhyphen {babel-hyphen} + +\tl_new:N \l__acro_fnpct_check_tl + +\cs_new_protected:Npn \acro_footnote:n #1 { - \mode_if_horizontal:F { \leavevmode } - \group_begin: - \use:x - { - \bool_if:cTF {l__acro_custom_#1_format_bool} - { \exp_not:v {l__acro_custom_#1_format_tl} } - { \exp_not:v {l__acro_#1_format_tl} } - {#2} - } - \group_end: + \tl_set:Ne \l__acro_fnpct_check_tl { \l__acro_fnpct_check_tl } + \exp_last_unbraced:Nno + \footnote {#1} + \l__acro_fnpct_check_tl } -% typeset the short form: -% #1: ID -% #2: short form -\cs_new_protected:Npn \acro_write_short:nn #1#2 +% options for activating actions: +\keys_define:nn {acro/trailing} { - \__acro_make_link:nn {#1} + activate .code:n = + \clist_map_inline:nn {#1} { \acro_trailing_token_activate:n {##1} } , + activate .initial:n = {dot,comma} , + deactivate .code:n = + \clist_map_inline:nn {#1} { \acro_trailing_token_deactivate:n {##1} } , + register .code:n = \acro_trailing_token_register:Nn #1 , + fnpct-check .tl_set:N = \l__acro_fnpct_check_tl , + fnpct-check .initial:n = + \aciftrailing {dot} { . \acgobbletrail } {} + \aciftrailing {comma} { , \acgobbletrail } {} + } + +% some user macros: +\cs_new:Npn \acro_dot: + { \acro_trailing_if_token:nF {dot} {.\@} } + +\cs_new:Npn \acro_space: + { \acro_trailing_if_tokens:nF {dash,babel-hyphen} { \c_space_tl } } + +% ---------------------------------------------------------------------------- +% sorting the list: +% the following code is an adaption of expl3 code used for \str_if_eq:NN(TF) +\sys_if_engine_luatex:TF + { + \cs_new_protected:Npn \__acro_strcmp:nn #1#2 { - \__acro_typeset:nn {short} + \lua_now:e { - \bool_if:NTF \l__acro_first_upper_bool - { \exp_not:N \__acro_first_upper_case:n { \exp_not:n {#2} } } - { \exp_not:n {#2} } + l3kernel.strcmp + ( + " \__acro_escape_x:n {#1} " , + " \__acro_escape_x:n {#2} " + ) } } + \cs_new:Npn \__acro_escape_x:n #1 + { + \lua_escape:e + { \tex_detokenize:D \use:e { {#1} } } + } } -\cs_generate_variant:Nn \acro_write_short:nn {nV,nv} + { \cs_new_eq:NN \__acro_strcmp:nn \tex_strcmp:D } -% typeset the alternative form: -% #1: ID -% #2: alt form -\cs_new_protected:Npn \acro_write_alt:nn #1#2 +\cs_new_protected:Npn \acro_list_sort: { - \__acro_make_link:nn {#1} + \seq_sort:Nn \g__acro_list_seq { - \__acro_typeset:nn {alt} + \int_compare:nNnTF { - \bool_lazy_and:nnTF - { \l__acro_first_upper_bool } - { \l__acro_upper_short_bool } - { \exp_not:N \__acro_first_upper_case:n { \exp_not:n {#2} } } - { \exp_not:n {#2} } - } + \__acro_strcmp:nn + { \str_fold_case:e { \acro_property_get:nn {##1} {sort} } } + { \str_fold_case:e { \acro_property_get:nn {##2} {sort} } } + } = {-1} + { \sort_return_same: } + { \sort_return_swapped: } } } -\cs_generate_variant:Nn \acro_write_alt:nn {nV,nv} -% typeset a long form: -% TODO: rethink the formatting mechanism -% right now a custom format gets applied additionally to the global one -% although before it -% #1: format -% #2: long form -\cs_new_protected:Npn \acro_write_long:nn #1#2 +% -------------------------------------------------------------------------- +% barriers: +\int_new:N \g_acro_barrier_int +\int_new:N \g_acro_barrier_total_int +\bool_new:N \l__acro_barriers_bool +\bool_new:N \l__acro_barriers_reset_bool +\bool_new:N \l__acro_usage_local_bool + +\msg_new:nnn {acro} {barriers} { - \__acro_typeset:nn {long} - { - \exp_not:n {#1} - { - \bool_if:NTF \l__acro_first_upper_bool - { \exp_not:N \__acro_first_upper_case:n { \exp_not:n {#2} } } - { \exp_not:n {#2} } - } - } + You~ seem~ to~ be~ using~ barriers~ but~ haven't~ set~ `barriers/use~ =~ + true',~ yet! } -\cs_generate_variant:Nn \acro_write_long:nn {VV,Vo,Vf,V,v,vv} -\prg_new_conditional:Npnn \acro_if_foreign:n #1 {T,F,TF} +\__acro_auxlist_field_new:cpn {total-barriers} #1 + { \int_gset:Nn \g_acro_barrier_total_int {#1} } + +\acro_at_begin_document:n + { \int_gset:Nn \g_acro_barrier_int {1} } + +\acro_at_end_document:n { - \bool_lazy_and:nnTF - { \l__acro_foreign_bool } - { \prop_if_in_p:Nn \l__acro_foreign_prop {#1} } - { \prg_return_true: } - { \prg_return_false: } + \acro_auxlist_to_aux:nn + {total-barriers} + { { \int_use:N \g_acro_barrier_int } } } -\cs_new_protected:Npn \acro_foreign_language:nn #1#2 {} -\AtBeginDocument{ - \cs_if_exist:NTF \foreignlanguage - { - \cs_set_protected:Npn \acro_foreign_language:nn #1#2 - { - \tl_if_blank:nTF {#1} - {#2} - { \foreignlanguage {#1} {#2} } - } - } - { - \cs_set_protected:Npn \acro_foreign_language:nn #1#2 - { \use_ii:nn {#1} {#2} } - } -} -\cs_generate_variant:Nn \acro_foreign_language:nn {VV} +\cs_new_protected:Npn \acro_barrier: + { + \int_gincr:N \g_acro_barrier_int + \bool_if:NT \l__acro_barriers_reset_bool + { \acro_reset_all: } + \bool_if:NF \l__acro_barriers_bool + { \msg_warning:nnn {acro} {barriers} } + } -\cs_new_protected:Npn \acro_write_foreign:n #1 +% #1: id +\cs_new_protected:Npn \acro_record_barrier:n #1 { - \acro_if_foreign:nT {#1} + \bool_if:NT \l__acro_barriers_bool { - \acro_property_get:nnT {#1} {foreign} + \int_compare:nNnTF + { \intarray_count:c {g__acro_#1_barriers_intarray} } > 0 { - \group_begin: - \__acro_endings:nn {#1} {foreign} - \tl_use:N \l__acro_foreign_format_tl + \intarray_gset:cnn {g__acro_#1_barriers_intarray} + { \int_use:N \g_acro_barrier_int } { - \acro_foreign_language:VV - \l__acro_foreign_lang_tl - \l__acro_foreign_tl + \intarray_item:cn {g__acro_#1_barriers_intarray} + { \int_use:N \g_acro_barrier_int } + +1 } - \group_end: } + { \acro_rerun:n {barriers} } } } -\cs_new:Npn \acroenparen #1 { (#1) } - -\cs_new_protected:Npn \acro_get_foreign:n #1 +% #1: id +\cs_new:Npn \acro_barrier_usage:n #1 { - \acro_property_get:nnT {#1} {foreign} + \clist_if_empty:eTF { \acro_property_get:nn {#1} {barriers} } + {0} { - \tl_use:N \l__acro_foreign_sep_tl - \group_begin: - \tl_use:N \l__acro_foreign_list_format_tl - { - \acro_foreign_language:VV - \l__acro_foreign_lang_tl - \l__acro_foreign_tl - } - \group_end: + \clist_item:en + { \acro_property_get:nn {#1} {barriers} } + { \g_acro_barrier_int } } } -% -------------------------------------------------------------------------- % #1: id -% #2: short|alt -\cs_set_protected:Npn \acro_write_compact:nn #1#2 +\cs_new_protected:Npn \acro_set_barriers:n #1 { - \acro_get_ending_form:nn {#1} {#2} - \acro_acc_supp:nn - {#1} + \bool_if:NT \l__acro_barriers_bool { - \acro_write_tooltip:nnV - {#1} + \int_compare:nNnTF + { \intarray_count:c {g__acro_#1_barriers_intarray} } = 0 + { \acro_rerun:n {barriers} } { - \use:c {acro_write_#2:nv} {#1} {l__acro_#2_tl} - \acro_endings:nn {#1} {#2} + \int_zero:N \l__acro_tmpa_int + \int_do_while:nNnn + \l__acro_tmpa_int < { \intarray_count:c {g__acro_#1_barriers_intarray} } + { + \int_incr:N \l__acro_tmpa_int + \seq_gput_right:ce {g__acro_#1_barriers_seq} + { + \intarray_item:cn {g__acro_#1_barriers_intarray} + { \l__acro_tmpa_int } + } + } + \acro_property_set:nnx {#1} {barriers} + { \seq_use:cn {g__acro_#1_barriers_seq} {,} } } - \l__acro_long_tl } } -% TODO: get rid of argument #3? -% #1: ID -% #2: long|first-long|list-long|extra -% #3: long form -\cs_new_protected:Npn \acro_write_expanded:nnn #1#2#3 +\keys_define:nn {acro/barriers} { - \tl_set:Nn \l__acro_tmpa_tl {#2} - \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} - \acro_write_long:vn {l__acro_ \l__acro_tmpa_tl _format_tl} {#3} - \acro_endings:nn {#1} {long} - \tl_if_in:nnT {#2} {long} - { \l__acro_long_post_tl } + use .bool_set:N = \l__acro_barriers_bool , + use .initial:n = false , + reset .bool_set:N = \l__acro_barriers_reset_bool , + reset .initial:n = false , + single .bool_set:N = \l__acro_usage_local_bool , + single .initial:n = false } -\cs_generate_variant:Nn \acro_write_expanded:nnn {nnV} -% #1: ID -% #2: long|first-long|list-long|extra -\cs_new_protected:Npn \acro_write_expanded:nn #1#2 +% ---------------------------------------------------------------------------- +\AcroModuleEnd +\AcroModule{commands}{frameworks for user commands} + +% -------------------------------------------------------------------------- +% case insensitivity of the ID: +\bool_new:N \g__acro_case_sensitive_bool + +\cs_new:Npn \acro_case_insensitive:n #1 { - \tl_set:Nn \l__acro_tmpa_tl {#2} - \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} - \acro_write_long:vv - {l__acro_ \l__acro_tmpa_tl _format_tl} - {l__acro_ \l__acro_tmpa_tl _tl} - \acro_endings:nn {#1} {long} - \tl_if_in:nnT {#2} {long} - { \l__acro_long_post_tl } + \bool_if:NTF \g__acro_case_sensitive_bool + { \tl_to_str:n {#1} } + { \str_lowercase:n {#1} } } +\cs_new_protected:Npn \acro_protected_case_insensitive:n #1 + { \acro_case_insensitive:n {#1} } + +\cs_new:Npn \acro_case_insensitive:Nn #1#2 + { \exp_args:Ne #1 { \acro_case_insensitive:n {#2} } } + +\keys_define:nn {acro} + { + case-sensitive .bool_set:N = \g__acro_case_sensitive_bool , + case-sensitive .initial:n = true , + } + +% ---------------------------------------------------------------------------- +% typeset endings and ending forms: +\bool_new:N \l__acro_include_endings_bool + % #1: id -\cs_new_protected:Npn \acro_after:n #1 +% #2: property +% #3: ending +\cs_new:Npn \__acro_get_ending:nnn #1#2#3 { - \acro_cite_if:Nn \l__acro_citation_all_bool {#1} - \acro_index_if:Nn \l__acro_addto_index_bool {#1} - \acro_property_get:nnT {#1} {post} - { \tl_use:N \l__acro_post_tl } + \use:c {acro_if_#3:T} + { \acro_property_get:nn {#1} {#2-#3} } } -\cs_new_protected:Npn \acro_check_single:n #1 +% #1: id +% #2: property +\cs_new:Npn \__acro_ending:nn #1#2 { - \acro_if_is_single:nT {#1} - { \cs_set_eq:NN \acro_hyper_link:nn \use_ii:nn } + \tl_map_tokens:Nn \l__acro_endings_tl + { \__acro_get_ending:nnn {#1} {#2} } } -% -------------------------------------------------------------------------- % #1: id -\cs_new_protected:Npn \acro_before:n #1 +% #2: property +% #3: ending +\cs_new:Npn \__acro_get_ending_form:nnn #1#2#3 { - \acro_get:n {#1} - \acro_is_used:n {#1} - \acro_check_single:n {#1} + \acro_property_if_set:nnT {#1} {#2-#3-form} + { + \use:c {acro_if_#3:T} + { + \acro_property_get:nn {#1} {#2-#3-form} + \tl_map_break:n { \use_ii:nnn } + } + } } -% the standard internals: % #1: id -\cs_new_protected:Npn \acro_short:n #1 +% #2: property +\cs_new:Npn \acro_ending_form:nnTF #1#2#3#4 { - \acro_before:n {#1} - \acro_write_indefinite:nn {#1} {short} - \acro_write_compact:nn {#1} {short} - \acro_after:n {#1} + \tl_map_tokens:Nn \l__acro_endings_tl + { \__acro_get_ending_form:nnn {#1} {#2} } + \use_ii:nn {#3} {#4} } -% get alternative entry: % #1: id -\cs_new_protected:Npn \acro_alt:n #1 +% #2: property +\cs_new:Npn \acro_ending_form:nnT #1#2#3 + { \acro_ending_form:nnTF {#1} {#2} {#3} {} } + +% #1: id +% #2: property +\cs_new:Npn \acro_ending_form:nnF #1#2#3 + { \acro_ending_form:nnTF {#1} {#2} {} {#3} } + +% #1: id +% #2: property +\cs_new:Npn \acro_ending_form:nn #1#2 + { \acro_ending_form:nnTF {#1} {#2} {} {} } + +% #1: id +% #2: property +% #3: ending +\cs_new:Npn \__acro_check_ending_form:nnn #1#2#3 { - \acro_before:n {#1} - \acro_alt_error:n {#1} - \acro_write_indefinite:nn {#1} {alt} - \acro_write_compact:nn {#1} {alt} - \acro_after:n {#1} + \acro_property_if_set:nnT {#1} {#2-#3-form} + { \use:c {acro_if_#3:T} { \tl_map_break:n { \use_ii:nnn } } } } -% get long entry: % #1: id -\cs_new_protected:Npn \acro_long:n #1 +% #2: property +\cs_new:Npn \acro_if_ending_form:nnTF #1#2#3#4 { - \acro_before:n {#1} - \acro_write_indefinite:nn {#1} {long} - \acro_write_expanded:nn {#1} {long} - \acro_after:n {#1} + \tl_map_tokens:Nn \l__acro_endings_tl + { \__acro_check_ending_form:nnn {#1} {#2} } + \use_ii:nn {#3} {#4} } -% get foreign entry: % #1: id -\cs_new_protected:Npn \acro_foreign:n #1 +% #2: property +\cs_new:Npn \acro_if_ending_form:nnT #1#2#3 + { \acro_if_ending_form:nnTF {#1} {#2} {#3} {} } + +% #1: id +% #2: property +\cs_new:Npn \acro_if_ending_form:nnF #1#2#3 + { \acro_if_ending_form:nnTF {#1} {#2} {} {#3} } + +% -------------------------------------------------------------------------- +% typeset acronyms: +% #1: id +% #2: property +\cs_new:Npn \__acro_article:nn #1#2 { - \acro_get:n {#1} - \tl_if_blank:VF \l__acro_foreign_tl + \bool_if:NT \l__acro_article_bool { - \acro_is_used:n {#1} - \acro_check_single:n {#1} - \acro_write_long:VV \l__acro_foreign_format_tl \l__acro_foreign_tl - \acro_after:n {#1} + \tl_map_tokens:Nn \g__acro_articles_tl + { \__acro_article:nnn {#1} {#2} } } } -% get extra entry: % #1: id -\cs_new_protected:Npn \acro_extra:n #1 +% #2: property +% #3: article +\cs_new:Npn \__acro_article:nnn #1#2#3 { - \acro_get:n {#1} - \tl_if_blank:VF \l__acro_extra_tl + \bool_if:cT {l__acro_article_#3_bool} { - \acro_is_used:n {#1} - \acro_check_single:n {#1} - \acro_write_long:VV \l__acro_extra_format_tl \l__acro_extra_tl - \acro_after:n {#1} + \tl_map_break:n + { \acro_property_get:nn {#1} {#2-#3} \exp_stop_f: } } } -% output like the first time: % #1: id -\cs_new_protected:Npn \acro_first:n #1 +% #2: property +\cs_new_protected:Npn \__acro_write:nn #1#2 { - \bool_gset_true:c {g__acro_#1_first_use_bool} - \acro_before:n {#1} - \acro_first_instance:nV {#1} \l__acro_long_tl + \acro_property_if_exist:nTF {#2-acc} + { + \__acro_accsupp:ee + { \__acro_write_acronym:nn {#1} {#2-acc} } + { \__acro_write_acronym:nn {#1} {#2} } + } + { \__acro_write_acronym:nn {#1} {#2} } } -% output like the first time with own long version: % #1: id -% #2: instead of long entry -\cs_new_protected:Npn \acro_first_like:nn #1#2 +% #2: property +\cs_new:Npn \__acro_write_acronym:nn #1#2 { - \bool_gset_true:c {g__acro_#1_first_use_bool} - \acro_before:n {#1} - \acro_first_instance:nn {#1} {#2} + \bool_lazy_and:nnTF + { \acro_property_if_eq_p:nn {#2} {long} } + { \acro_if_first_p:n {#1} } + { \acro_format:nnn {#1} {first-#2} } + { \acro_format:nnn {#1} {#2} } + { + \__acro_upper:n + { + \__acro_article:nn {#1} {#2} + \acro_if_ending_form:nnTF {#1} {#2} + { \acro_ending_form:nn {#1} {#2} } + { \acro_property_get:nn {#1} {#2} } + } + } + } + +% #1: id +% #2: property +\cs_new_protected:Npn \acro_write:nn #1#2 + { + \group_begin: + \acro_if_short:nT {#2} { \acro_soft_upper: } + \__acro_make_link:nnn {#1} {#2} + { + \acro_locale:nnn {#1} {#2} + { + \__acro_write:nn {#1} {#2} + \bool_if:NT \l__acro_include_endings_bool + { + \acro_if_ending_form:nnF {#1} {#2} + { \__acro_ending:nn {#1} {#2} } + } + } + } + \group_end: + \acro_if_ending_form:nnF {#1} {#2} + { + \bool_if:NF \l__acro_include_endings_bool + { \__acro_ending:nn {#1} {#2} } + } + \acro_property_if_eq:nnT {#2} {long} + { \acro_property_get:nn {#1} {long-post} } + \bool_set_false:N \l__acro_upper_bool + \bool_set_false:N \l__acro_article_bool + } +\cs_generate_variant:Nn \acro_write:nn {e} + +\keys_define:nn {acro} + { + include-endings .bool_set:N = \l__acro_include_endings_bool , + include-endings .initial:n = true } -% ---------------------------------------------------------------------------- -% citations: -\cs_new:Npn \__acro_citation_cmd:w { \cite } -\cs_new:Npn \__acro_group_citation_cmd:w { \cite } -% #1 pre -% #2 post -% #3 key -\cs_new:Npn \__acro_cite:nnn #1#2#3 +% -------------------------------------------------------------------------- +% #1: boolean +% #2: id +\cs_new_protected:Npn \acro_finalize:nn #1#2 { - \quark_if_no_value:nTF {#1} - { \__acro_citation_cmd:w {#3} } + \bool_if:NF \g__acro_cited_bool + { \acro_cite_if:nnT {#1} {#2} { \acro_cite:n {#2} } } + \bool_gset_false:N \g__acro_cited_bool + \acro_property_if_set:nnT {#1} {post} + { \acro_property_get:nn {#2} {post} } + \bool_lazy_all:nT + { + { \l__acro_label_bool } + { \l__acro_use_bool } + { !#1 } + } + { + \acro_if_first:nT {#2} + { + \acro_property_if_set:nnF {#2} {label} + { + \acro_property_set:nnn {#2} {label} {#2} + \label { \l_acro_label_prefix_tl #2 } + } + } + } + \bool_lazy_and:nnT + { \l__acro_use_bool } + { !#1 } { - \quark_if_no_value:nTF {#2} - { \__acro_citation_cmd:w [#1] {#3} } - { \__acro_citation_cmd:w [#1] [#2] {#3} } + \acro_use:n {#2} + \acro_record_page:n {#2} + \acro_record_barrier:n {#2} + \acro_index:n {#2} } } -\cs_generate_variant:Nn \__acro_cite:nnn {VVV} +\cs_generate_variant:Nn \acro_finalize:nn {ne} -\cs_new_protected:Npn \acro_cite:n #1 +% -------------------------------------------------------------------------- +% define acronym typesetting commands: +\bool_new:N \l__acro_star_bool +\tl_new:N \l__acro_options_tl + +\cs_new:Npn \__acro_remove_bs:N #1 + { \exp_after:wN \use_none:n \token_to_str:N #1 } + +\tl_new:N \l__acro_begin_command_hook_tl +\tl_new:N \l__acro_end_command_hook_tl + +% #1: csname +% #2: xparse csname +% #3: action +\cs_set_protected:Npn \acro_new_definition_command:NNn #1#2#3 { - \acro_property_get:nnT {#1} {before-citation} - { \acro_no_break: \l__acro_before_citation_tl } - \prop_get:NnNT \l__acro_citation_prop {#1} \l__acro_tmpa_tl + % internal command for \NewAcroCommand + % ##1: csname + % ##2: arg spec + % ##3: code with arg numbers n=n+2 + \cs_new_protected:cpn {acro_command_#3:Nnn} ##1##2##3 { - \prop_get:NnN \l__acro_citation_pre_prop {#1} \l__acro_tmpb_tl - \prop_get:NnN \l__acro_citation_post_prop {#1} \l__acro_tmpc_tl - \acro_no_break: - \tl_use:N \l__acro_citation_connect_tl - \__acro_cite:VVV - \l__acro_tmpb_tl - \l__acro_tmpc_tl - \l__acro_tmpa_tl + \exp_args:Nc \DeclareDocumentCommand + { base \__acro_remove_bs:N ##1 } {##2} + { + \acro_begin: + \l__acro_begin_command_hook_tl + \cs_set:Npn \nospace { \exp:w \exp_end_continue_f:w } + \acro_check_definition:n {####1} + \bool_set_true:N \l__acro_use_bool + \keys_set:nV {acro} \l__acro_options_tl + \tl_set:Ne \AcronymID { \acro_case_insensitive:n {####1} } + \tl_set:Ne \l_acro_id_tl { \acro_case_insensitive:n {####1} } + ##3 + \acro_finalize:ne + { \l__acro_star_bool } + { \acro_case_insensitive:n {####1} } + \l__acro_end_command_hook_tl + \acro_end: + } + \use:x + { + \exp_not:n { #2 ##1 {so} } + { + \exp_not:n + { + \mode_leave_vertical: + \bool_set_false:N \l__acro_star_bool + \tl_clear:N \l__acro_options_tl + \IfBooleanT {####1} { \bool_set_true:N \l__acro_star_bool } + \IfNoValueF {####2} { \tl_set:Nn \l__acro_options_tl {####2} } + } + \exp_not:c { base \__acro_remove_bs:N ##1 } + } + } } - \acro_property_get:nnT {#1} {after-citation} - { \acro_no_break: \l__acro_after_citation_tl } + % define \NewAcroCommand + \NewDocumentCommand #1 {mm+m} + { \use:c {acro_command_#3:Nnn} ##1 {##2} {##3} } + } + +\acro_new_definition_command:NNn + \NewAcroCommand + \NewDocumentCommand + {new} + +\acro_new_definition_command:NNn + \RenewAcroCommand + \RenewDocumentCommand + {renew} + +\acro_new_definition_command:NNn + \DeclareAcroCommand + \DeclareDocumentCommand + {declare} + +\acro_new_definition_command:NNn + \ProvideAcroCommand + \ProvideDocumentCommand + {provide} + +\keys_define:nn {acro/commands} + { + begin .code:n = + \tl_put_right:Nn \l__acro_begin_command_hook_tl {#1} , + end .code:n = + \tl_put_right:Nn \l__acro_end_command_hook_tl {#1} , + clear .choice: , + clear / begin .code:n = + \tl_clear:N \l__acro_begin_command_hook_tl , + clear / end .code:n = + \tl_clear:N \l__acro_end_command_hook_tl , + clear / all .code:n = + \tl_clear:N \l__acro_begin_command_hook_tl + \tl_clear:N \l__acro_end_command_hook_tl } -\cs_new_protected:Npn \acro_group_cite:n #1 +% -------------------------------------------------------------------------- +\AcroModuleEnd +\AcroModule{templates}{templates for typesetting exercises} + +\msg_new:nnn {acro} {unknown-template} { - \group_begin: - \cs_set_eq:NN \__acro_citation_cmd:w \__acro_group_citation_cmd:w - \tl_set_eq:NN - \l__acro_citation_connect_tl - \l__acro_between_group_connect_citation_tl - \acro_cite_if:Nn \l__acro_citation_first_bool {#1} - \group_end: + The~ template~ `#1'~ (template~ type~ `#2')~ \msg_line_context: \ + does~ not~ seem~ to~ be~ defined. } -\cs_new_protected:Npn \acro_cite_if:Nn #1#2 - { \bool_if:NT #1 { \acro_cite:n {#2} } } +\msg_new:nnn {acro} {template-type-exists} + { The~ template~ type~ `#1'~ already~ exists~ \msg_line_context: } + +\msg_new:nnn {acro} {package-needed} + { + The~ template~ `#1'~ needs~ the~ package~ `#2'~ loaded~ + \msg_line_context: + } % ---------------------------------------------------------------------------- -% indexing: -\cs_new_protected:Npn \acro_index_if:Nn #1#2 +\seq_new:N \l__acro_template_types_seq + +% #1: template type +\cs_new_protected:Npn \acro_template_type_new:n #1 { - \bool_lazy_and:nnT {#1} { \l__acro_mark_as_used_bool } + \seq_if_in:NnTF \l__acro_template_types_seq {#1} + { \msg_error:nnn {acro} {template-type-exists} {#1} } { - \prop_get:NnN \l__acro_index_cmd_prop {#2} \l__acro_tmpa_tl - \prop_get:NnN \l__acro_index_sort_prop {#2} \l__acro_tmpb_tl - \prop_get:NnN \l__acro_index_prop {#2} \l__acro_tmpc_tl - \__acro_index:VnVV - \l__acro_tmpa_tl - {#2} - \l__acro_tmpb_tl - \l__acro_tmpc_tl + \seq_put_right:Nn \l__acro_template_types_seq {#1} + \acro_attribute_new:n {template::#1} } } -\cs_new:Npn \__acro_index_cmd:n { \index } +% #1: template type +% #2: template name +% #3: code +\cs_new_protected:Npn \__acro_template_add:nnn #1#2#3 + { + \tl_new:c {l__acro_template_#1_#2_setup_tl} + \acro_attribute_set:nnn {template::#1} {#2} {#3} + } + +% #1: template type +% #2: template name +% #3: code +\cs_new_protected:Npn \__acro_template_change:nnn #1#2#3 + { + \acro_template_if_exist:nnTF {#1} {#2} + { \acro_attribute_set:nnn {template::#1} {#2} {#3} } + { \msg_error:nnnn {acro} {unknown-template} {#2} {#1} } + } -% #1: cmd -% #2: key -% #3: sort -% #4: replace -\cs_new_protected:Npn \__acro_index:nnnn #1#2#3#4 +% #1: template type +% #2: template name +\prg_new_conditional:Npnn \acro_template_if_exist:nn #1#2 {T,F,TF} { - \prop_get:NnNF \l__acro_short_prop {#2} \l__acro_index_short_tl {} - \prop_get:NnNF \l__acro_format_prop {#2} \l__acro_index_format_tl {} - \quark_if_no_value:VTF \l__acro_index_format_tl - { \tl_set:Nn \l__acro_tmpa_tl { \l__acro_short_format_tl \l__acro_index_short_tl } } - { \tl_set:Nn \l__acro_tmpa_tl { \l__acro_index_format_tl \l__acro_index_short_tl } } - \quark_if_no_value:nF {#1} - { \cs_set:Npn \__acro_index_cmd:n {#1} } - \quark_if_no_value:nTF {#4} + \acro_attribute_if_set:nnTF {template::#1} {#2} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: parameter number +% #2: template type +% #3: template name +\cs_new_protected:Npn \__acro_template_get:nnn #1#2#3 + { + \use:x { - \quark_if_no_value:nTF {#3} - { \__acro_index_cmd:n { #2 @ { \l__acro_tmpa_tl } } } - { \__acro_index_cmd:n { #3 @ { \l__acro_tmpa_tl } } } + \cs_set:cn { __acro_tmp: \prg_replicate:nn {#1} {n} } + { \acro_attribute_get:nn {template::#2} {#3} } } - { \__acro_index_cmd:n {#4} } + \use:c { __acro_tmp: \prg_replicate:nn {#1} {n} } } -\cs_generate_variant:Nn \__acro_index:nnnn {VnVV} -% ---------------------------------------------------------------------------- -% accessability support -\cs_new_eq:NN \acro_acc_supp:nn \use_ii:nn +% using templates: +% setup up the next usage of `template name': +% #1: template type +% #2: template name +% #3: setup code +\cs_new_protected:Npn \acro_template_setup:nnn #1#2#3 + { \tl_set:cn {l__acro_template_#1_#2_setup_tl} {#3} } +\cs_generate_variant:Nn \acro_template_setup:nnn {nnV,nVn} + +% #1: template type +% #2: template name +\cs_new_protected:Npn \__acro_template_setup:nn #1#2 + { \tl_use:c {l__acro_template_#1_#2_setup_tl} } + +% #1: template type +% #2: template name +\cs_new_protected:Npn \__acro_clear_template_setup:nn #1#2 + { \tl_clear:c {l__acro_template_#1_#2_setup_tl} } + +% #1: template type +% #2: template name +\cs_new_protected:Npn \__acro_template_start:nn #1#2 + { + \group_begin: + \__acro_template_setup:nn {#1} {#2} + \tl_clear_new:N \TemplateType + \tl_set:Nn \TemplateType {#1} + \tl_clear_new:N \TemplateName + \tl_set:Nn \TemplateName {#2} + } + +% #1: template type +% #2: template name +\cs_new_protected:Npn \__acro_template_stop:nn #1#2 + { \group_end: \__acro_clear_template_setup:nn {#1} {#2} } + +% typesetting the first appearance of acronym: pseude template `first' -\cs_new_protected:Npn \acro_get_acc_supp:nn #1#2 +% #1: parameter number +% #2: template type +% #3: template name +\cs_new_protected:Npn \acro_template_use:nnn #1#2#3 { - \prop_get:NnNF \l__acro_acc_supp_prop {#1} \l__acro_acc_supp_tl - { \prop_get:NnNF \l__acro_short_prop {#1} \l__acro_acc_supp_tl {} } - \acro_for_endings_do:n + \bool_set_false:N \l__acro_tmpa_bool + \bool_if:NT \l__acro_use_only_first_bool { - \bool_if:cT {l__acro_##1_bool} + \bool_if:NT \l__acro_use_bool { - \tl_put_right:Nv - \l__acro_acc_supp_tl - {l__acro_short_##1_tl} + \bool_set_true:N \l__acro_tmpa_bool + \bool_set_false:N \l__acro_use_bool } } - \acro_do_acc_supp:VVn - \l__acro_acc_supp_tl - \l__acro_acc_supp_options_tl - {#2} + \str_case:nnF {#3} + { + {first} { + \bool_if:NT \l__acro_tmpa_bool + { \bool_set_true:N \l__acro_use_bool } + \bool_lazy_and:nnTF + { !\l__acro_first_bool } + { \acro_if_single_p:V \l_acro_id_tl } + { + \acro_property_if_set:VnTF \l_acro_id_tl {single-style} + { + \tl_set:Ne \l__acro_tmpa_tl + { \acro_property_get:Vn \l_acro_id_tl {single-style} } + } + { \tl_set_eq:NN \l__acro_tmpa_tl \l__acro_single_tl } + } + { + \acro_if_first:VTF \l_acro_id_tl + { + \acro_property_if_set:VnTF \l_acro_id_tl {first-style} + { + \tl_set:Ne \l__acro_tmpa_tl + { \acro_property_get:Vn \l_acro_id_tl {first-style} } + } + { \tl_set_eq:NN \l__acro_tmpa_tl \l__acro_first_style_tl } + } + { \tl_set:Nn \l__acro_tmpa_tl {short} } + } + } + {single} { + \acro_property_if_set:VnTF \l_acro_id_tl {single-style} + { + \tl_set:Ne \l__acro_tmpa_tl + { \acro_property_get:Vn \l_acro_id_tl {single-style} } + } + { \tl_set_eq:NN \l__acro_tmpa_tl \l__acro_single_tl } + } + } + { \tl_set:Nn \l__acro_tmpa_tl {#3} } + \str_if_eq:VnT \l__acro_tmpa_tl {first} + { + \acro_property_if_set:VnTF \l_acro_id_tl {first-style} + { + \tl_set:Ne \l__acro_tmpa_tl + { \acro_property_get:Vn \l_acro_id_tl {first-style} } + } + { \tl_set_eq:NN \l__acro_tmpa_tl \l__acro_first_style_tl } + } + \__acro_template_use:nnV {#1} {#2} \l__acro_tmpa_tl } +\cs_generate_variant:Nn \acro_template_use:nnn {nnV} -\cs_new:Npn \acro_do_acc_supp:nnn #1#2#3 +\cs_new_protected:Npn \__acro_template_use:nnn #1#2#3 { - \BeginAccSupp { ActualText = #1 , #2 } - #3 - \EndAccSupp { } + \acro_template_if_exist:nnTF {#2} {#3} + { \__acro_template_get:nnn {#1} {#2} {#3} } + { + \msg_warning:nnnn {acro} {unknown-template} {#3} {#2} + \__acro_template_get:nnn {#1} {#2} {first} + } } -\cs_generate_variant:Nn \acro_do_acc_supp:nnn {VV} +\cs_generate_variant:Nn \__acro_template_use:nnn {nnx,nnV} -\AtEndPreamble +% ---------------------------------------------------------------------------- +% acronym templates: +\acro_template_type_new:n {acronym} + +% #1: template name +% #2: code +\cs_new_protected:Npn \acro_acronym_template_new:nn #1#2 { - \bool_if:NT \l__acro_acc_supp_bool + \__acro_template_add:nnn {acronym} {#1} { - \RequirePackage {accsupp} - \cs_set_eq:NN \acro_acc_supp:nn \acro_get_acc_supp:nn + \__acro_template_start:nn {acronym} {#1} + #2 + \__acro_template_stop:nn {acronym} {#1} } - \bool_if:NT \l__acro_tooltip_bool + } + +% #1: template name +% #2: code +\cs_new_protected:Npn \acro_acronym_template_renew:nn #1#2 + { + \__acro_template_change:nnn {acronym} {#1} { - \RequirePackage {pdfcomment} - \cs_if_eq:NNT \__acro_tooltip_cmd:nn \use_i:nn - { \cs_set:Npn \__acro_tooltip_cmd:nn { \pdftooltip } } + \__acro_template_start:nn {acronym} {#1} + #2 + \__acro_template_stop:nn {acronym} {#1} } } -% -------------------------------------------------------------------------- -% tooltips for acronyms +% ---------------------------------------------------------------------------- +% heading templates: +\acro_template_type_new:n {heading} -% #1: id -% #2: printed text -% #3: tool tip text -\cs_new_protected:Npn \acro_write_tooltip:nnn #1#2#3 +% #1: template name +% #2: code +\cs_new_protected:Npn \acro_heading_template_new:nn #1#2 { - \acro_property_get:nnTF {#1} {tooltip} - { \__acro_check_tooltip:nV {#2} \l__acro_tooltip_tl } - { \__acro_check_tooltip:nn {#2} {#3} } + \__acro_template_add:nnn {heading} {#1} + { + \__acro_template_start:nn {heading} {#1} + #2 + \__acro_template_stop:nn {heading} {#1} + } } -\cs_generate_variant:Nn \acro_write_tooltip:nnn {nnV} -% #1: printed text -% #2: tool tip text -\cs_new_protected:Npn \__acro_check_tooltip:nn #1#2 +% #1: template name +% #2: code +\cs_new_protected:Npn \acro_heading_template_renew:nn #1#2 { - \bool_if:NTF \l__acro_tooltip_inside_bool - {#1} + \__acro_template_change:nnn {heading} {#1} { - \bool_set_true:N \l__acro_tooltip_inside_bool - \__acro_tooltip_cmd:nn {#1} {#2} + \__acro_template_start:nn {heading} {#1} + #2 + \__acro_template_stop:nn {heading} {#1} } } -\cs_generate_variant:Nn \__acro_check_tooltip:nn { nV } -% use whatever command you like for creating tooltips here: -% #1: printed text -% #2: tool tip text -\cs_new_eq:NN \__acro_tooltip_cmd:nn \use_i:nn - -% -------------------------------------------------------------------------- -% indefinite articles: +% ---------------------------------------------------------------------------- +% list templates: +\acro_template_type_new:n {list} -% #1: ID -% #2: short|long|alt -\cs_new_protected:Npn \acro_write_indefinite:nn #1#2 +% #1: template name +% #2: code +\cs_new_protected:Npn \acro_list_template_new:nn #1#2 { - \bool_if:NT \l__acro_indefinite_bool - { \prop_item:cn {l__acro_#2_indefinite_prop} {#1} ~ } - \bool_if:NT \l__acro_upper_indefinite_bool - { % \bool_set_true:N \l__acro_first_upper_bool - \__acro_first_upper_case:x - { \prop_item:cn {l__acro_#2_indefinite_prop} {#1} } ~ + \__acro_template_add:nnn {list} {#1} + { + \__acro_template_start:nn {list} {#1} + \tl_clear_new:N \AcronymTable + #2 + \__acro_template_stop:nn {list} {#1} } } -% -------------------------------------------------------------------------- -% experimental sorting feature: - -% the following code is an adaption of expl3 code used for \str_if_eq:NN(TF) -\sys_if_engine_luatex:TF +% #1: template name +% #2: code +\cs_new_protected:Npn \acro_list_template_renew:nn #1#2 { - \tl_set:Nn \l__acro_tmpa_tl + \__acro_template_change:nnn {list} {#1} { - acro ~ = ~ acro ~ or ~ { ~ } ~ - function ~ acro.strcmp ~ (A, B) ~ - if ~ A ~ == ~ B ~ then ~ - tex.write ("0") ~ - elseif ~ A ~ < ~ B ~ then ~ - tex.write ("-1") ~ - else ~ - tex.write ("1") ~ - end ~ - end + \__acro_template_start:nn {list} {#1} + \tl_clear_new:N \AcronymTable + #2 + \__acro_template_stop:nn {list} {#1} } - \lua_now:e { \l__acro_tmpa_tl } - \cs_new_protected:Npn \acro_strcmp:nn #1#2 + } + +% ---------------------------------------------------------------------------- +\AcroModuleEnd +\AcroModule{list}{the list of acronyms} +% -------------------------------------------------------------------------- +% list of acronyms: +\bool_new:N \l__acro_list_display_all_bool +\bool_new:N \l__acro_list_bool +\bool_new:N \l__acro_list_local_bool + +\seq_new:N \g__acro_list_seq + +\tl_new:N \l__acro_list_tl + +\clist_new:N \l__acro_tag_include_clist +\clist_new:N \l__acro_tag_exclude_clist + +\cs_new_protected:Npn \acro_list_choose_set: + { + \bool_if:NTF \l__acro_list_display_all_bool + { \seq_gset_eq:NN \g__acro_list_seq \g__acro_acronyms_seq } { - \lua_now:e + \seq_gclear:N \g__acro_list_seq + \seq_map_inline:Nn \g__acro_acronyms_seq { - acro.strcmp - ( - " \__acro_escape_x:n {#1} " , - " \__acro_escape_x:n {#2} " - ) + \acro_if_single:nF {##1} + { \seq_gput_right:Nn \g__acro_list_seq {##1} } } } - \cs_new:Npn \__acro_escape_x:n #1 + } + +% -------------------------------------------------------------------------- +% #1: filtered sequence +% #2: sequence +\cs_new_protected:Npn \__acro_list_filter:NN #1#2 + { + \seq_clear:N #2 + \seq_clear:N \l__acro_tmpc_seq + \bool_if:NF \l__acro_list_local_bool + { \bool_set_true:N \l__acro_tmpb_bool } + \seq_map_inline:Nn #1 { - \lua_escape:e - { \__kernel_tl_to_str:w \use:e { {#1} } } + \__acro_check_tags:Nn \l__acro_tmpa_bool {##1} + \bool_lazy_and:nnT + { \l__acro_list_local_bool } + { + \int_compare_p:nNn + { \intarray_count:c {g__acro_##1_barriers_intarray} } > 0 + } + { + \bool_set_false:N \l__acro_tmpb_bool + \int_compare:nNnT + { \acro_barrier_usage:n {##1} } > 0 + { \bool_set_true:N \l__acro_tmpb_bool } + } + \bool_lazy_and:nnT { \l__acro_tmpa_bool } { \l__acro_tmpb_bool } + { \seq_put_right:Nn #2 {##1} } } } - { \cs_new_eq:NN \acro_strcmp:nn \tex_strcmp:D } -\AtBeginDocument - { - \bool_if:NT \l__acro_sort_bool - { - \cs_new_protected:Npn \acro_sort_prop:NN #1#2 +% #1: boolean +% #2: id +\cs_new_protected:Npn \__acro_check_tags:Nn #1#2 + { + \bool_set_false:N #1 + % get tags for acronym: + \clist_set:Ne \l__acro_tmpa_clist + { \acro_property_get:nn {#2} {tag} } + \clist_if_empty:NTF \l__acro_tmpa_clist + {% acronym does not have (a) tag(s) + \clist_if_empty:NT \l__acro_tag_include_clist + { \bool_set_true:N #1 } + } + {% acronym has (a) tag(s) + \clist_if_empty:NTF \l__acro_tag_include_clist + { \bool_set_true:N #1 } { - \seq_clear:N \l__acro_tmpa_seq - \prop_clear:N \l__acro_tmpa_prop - \prop_clear:N \l__acro_tmpb_prop - \prop_map_inline:Nn #2 - { - \seq_put_right:Nn \l__acro_tmpa_seq {##2} - \prop_put:Nnn \l__acro_tmpa_prop {##1} {##2} - } - \seq_sort:Nn \l__acro_tmpa_seq + \clist_map_inline:Nn \l__acro_tmpa_clist { - \int_compare:nTF - { - \acro_strcmp:nn - { \str_fold_case:n {##1} } - { \str_fold_case:n {##2} } - = -1 + \clist_if_in:NnT \l__acro_tag_include_clist {##1} + {% acronym is included + \bool_set_true:N #1 + \clist_map_break: } - { \sort_return_same: } - { \sort_return_swapped: } } - \seq_map_inline:Nn \l__acro_tmpa_seq + } + \bool_if:NT #1 + {% we only need to check if acronym is included: + \clist_if_empty:NF \l__acro_tag_exclude_clist { - \prop_map_inline:Nn \l__acro_tmpa_prop + \clist_map_inline:Nn \l__acro_tmpa_clist { - \str_if_eq:nnT {##1} {####2} - { - \prop_get:NnN #1 {####1} \l__acro_tmpa_tl - \prop_put:NnV \l__acro_tmpb_prop {####1} - \l__acro_tmpa_tl + \clist_if_in:NnT \l__acro_tag_exclude_clist {##1} + {% acronym is excluded + \bool_set_false:N #1 + \clist_map_break: } } } - \prop_set_eq:NN #1 \l__acro_tmpb_prop } } } % -------------------------------------------------------------------------- -% regarding list printing: -% this command ensures that a rerun warning is given when \printacronyms -% is set the first time. This mechanism doesn't make very much sense, -% should be replaced by a different and more efficient one -% -\cs_new_protected:Npn \acro@print@list - { \cs_if_exist:NF \acro@printed@list { \cs_new:Npn \acro@printed@list { printed } } } +\prg_new_protected_conditional:Npnn \acro_acronyms_map:n #1 {T,F,TF} + { + \__acro_list_filter:NN \g__acro_list_seq \l__acro_tmpa_seq + \seq_if_empty:NTF \l__acro_tmpa_seq + { \prg_return_false: } + { + \seq_map_inline:Nn \l__acro_tmpa_seq {#1} + \prg_return_true: + } + } + +\cs_new_protected:Npn \acro_list: + { + \group_begin: + \bool_set_true:N \l__acro_list_bool + \acro_list_choose_set: + \cs_set_eq:NN \__acro_upper_case:n \__acro_list_upper_case:n + \bool_if:NT \l__acro_sort_bool { \acro_list_sort: } + \acro_template_use:nnV {0} {list} \l__acro_list_tl + \group_end: + } % -------------------------------------------------------------------------- -% trailing tokens and what to do when present +\tl_new:N \l__acro_heading_tl +\tl_new:N \l__acro_preamble_tl -\cs_new_protected:Npn \acro_new_trailing_token:n #1 - { \bool_new:c {l__acro_trailing_#1_bool} } -\cs_new_protected:Npn \acro_activate_trailing_action:n #1 - { \bool_set_true:c {l__acro_trailing_#1_bool} } -\cs_new_protected:Npn \acro_deactivate_trailing_action:n #1 - { \bool_set_false:c {l__acro_trailing_#1_bool} } +\cs_new_protected:Npn \acro_heading: + { \acro_template_use:nnV {0} {heading} \l__acro_heading_tl } -% register a new token but don't activate its action: -% #1: token -% #2: name -\cs_new_protected:Npn \acro_register_trailing_token:Nn #1#2 - { - \prop_put:Nnn \l__acro_trailing_tokens_prop {#2} {#1} - \prop_put:Nnn \l__acro_trailing_actions_prop {#1} - { \acro_activate_trailing_action:n {#2} } - \acro_new_trailing_token:n {#2} - } +\cs_new_protected:Npn \acro_preamble: + { \tl_use:N \l__acro_preamble_tl } -\cs_new_protected:Npn \acro_for_all_trailing_tokens_do:n #1 - { \prop_map_inline:Nn \l__acro_trailing_tokens_prop {#1} } +\tl_new:N \l__acro_list_name_tl -% activate a token: -\cs_new_protected:Npn \acro_activate_trailing_token:n #1 +% -------------------------------------------------------------------------- +\keys_define:nn {acro/list} { - \prop_get:NnN \l__acro_trailing_tokens_prop {#1} \l__acro_tmpa_tl - \tl_put_right:NV \l__acro_trailing_tokens_tl \l__acro_tmpa_tl + template .tl_set:N = \l__acro_list_tl , + template .initial:n = description , + sort .bool_set:N = \l__acro_sort_bool , + sort .initial:n = true , + display .choice: , + display/all .code:n = \bool_set_true:N \l__acro_list_display_all_bool , + display/used .code:n = \bool_set_false:N \l__acro_list_display_all_bool , + display .initial:n = used , + include .clist_set:N = \l__acro_tag_include_clist , + exclude .clist_set:N = \l__acro_tag_exclude_clist , + local .bool_set:N = \l__acro_list_local_bool , + heading .tl_set:N = \l__acro_heading_tl , + preamble .tl_set:N = \l__acro_preamble_tl , + preamble .initial:n = , + name .tl_set:N = \l__acro_list_name_tl , + name .initial:n = \acro_translate:n {list-name} } -% deactivate a token: -\cs_new_protected:Npn \acro_deactivate_trailing_token:n #1 +\acro_if_komascript:TF { - \prop_get:NnN \l__acro_trailing_tokens_prop {#1} \l__acro_tmpa_tl - \tl_remove_all:NV \l__acro_trailing_tokens_tl \l__acro_tmpa_tl + \cs_if_exist:NTF \chapter + { \keys_set:nn {acro/list}{ heading = addchap } } + { \keys_set:nn {acro/list}{ heading = addsec } } } - -% #1: name -\prg_new_conditional:Npnn \acro_if_trailing_token:n #1 {p,T,F,TF} { - \bool_if:cTF {l__acro_trailing_#1_bool} - { \prg_return_true: } - { \prg_return_false: } + \cs_if_exist:NTF \chapter + { \keys_set:nn {acro/list}{ heading = chapter* } } + { \keys_set:nn {acro/list}{ heading = section* } } } -% #1: csv list of names -\prg_new_protected_conditional:Npnn \acro_if_trailing_tokens:n #1 {T,F,TF} +% -------------------------------------------------------------------------- +\AcroModuleEnd +\AcroModule{pages}{recording and printing of pages} +% ---------------------------------------------------------------------------- +% record page numbers: +\RequirePackage {zref-abspage} + +\msg_new:nnn {acro} {label} + { The~ list~ template~ `#1'~ needs~ the~ option~ `labels'~ activated. } + +\msg_new:nnn {acro} {threshold} + { The~ sequentes~ threshold~ needs~ to~ be~ at~ least~ 3. } + +\group_begin: +\char_set_catcode_other:N \@ + +% #1: id +\cs_new_protected:Npn \acro_record_page:n #1 { - \bool_set_false:N \l__acro_trailing_tokens_bool - \clist_map_inline:nn {#1} + \seq_if_in:ceF {g__acro_#1_pages_seq} + { \arabic{abspage} @ \int_use:N \g_acro_barrier_int @ \thepage } { - \bool_if:cT {l__acro_trailing_##1_bool} - { - \bool_set_true:N \l__acro_trailing_tokens_bool - \clist_map_break: - } + \seq_gput_right:ce {g__acro_#1_pages_seq} + { \arabic{abspage} @ \int_use:N \g_acro_barrier_int @ \thepage } } - \bool_if:NTF \l__acro_trailing_tokens_bool - { \prg_return_true: } - { \prg_return_false: } + \seq_gremove_duplicates:c {g__acro_#1_pages_seq} + \acro_at_end_document:n + { + \acro_property_set:nnx {#1} {pages} + { \seq_use:cn {g__acro_#1_pages_seq} {|} } + } + } + +\cs_new:Npn \__acro_page_name:w #1@#2@#3 \q_stop + { + \acro_package_if_loaded:nTF {hyperref} + { \exp_not:N \hyperpage { \exp_not:n {#3} } } + { \exp_not:n {#3} } } -\cs_new_protected:Npn \aciftrailing { \acro_if_trailing_tokens:nTF } +\cs_new:Npn \__acro_absolute_page:w #1@#2@#3 \q_stop {#1} -\cs_new_protected:Npn \__acro_check_trail:N #1 +\cs_new:Npn \__acro_barrier:w #1@#2@#3 \q_stop {#2} + +\group_end: + +\RequirePackage {zref-totpages} + +\acro_at_begin_document:n + { \intarray_new:Nn \g__acro_pages_intarray { \ztotpages } } + +% #1: id +% #2: one page +% #3: more than one page +\cs_new_protected:Npn \acro_print_pages:nnn #1#2#3 { - \tl_map_inline:Nn \l__acro_trailing_tokens_tl + \acro_if_pages:nT {#1} { - \token_if_eq_meaning:NNT #1 ##1 - { \prop_item:Nn \l__acro_trailing_actions_prop {##1} } + \bool_if:NTF \l__acro_pages_all_bool + { + \bool_if:NTF \l__acro_pages_name_display_bool + { \acro_print_page_ranges:nnn {#1} {#2} {#3} } + { \acro_print_page_ranges:nnn {#1} {} {} } + } + { + \bool_if:NT \l__acro_pages_name_display_bool {#2} + \pageref { \l_acro_label_prefix_tl #1 } + } } } +\cs_generate_variant:Nn \acro_print_pages:nnn {e} -% options for activating actions: -\keys_define:nn {acro} - { - activate-trailing-tokens .code:n = - \clist_map_inline:nn {#1} { \acro_activate_trailing_token:n {##1} } , - deactivate-trailing-tokens .code:n = - \clist_map_inline:nn {#1} { \acro_deactivate_trailing_token:n {##1} } - } - -% --------------------------------------------------------------------------- -% reset outputs, they'll behave like the first time again (!not like the _only_ -% time!): -\cs_new_protected:Npn \acro_reset:n #1 - { - \bool_gset_false:c { g__acro_#1_used_bool } - \bool_gset_false:c { g__acro_#1_first_use_bool } +% #1: id +% #2: one page +% #3: more than one page +\cs_set_protected:Npn \acro_print_page_ranges:nnn #1#2#3 + { + \seq_set_split:Nnx \l__acro_tmpa_seq {|} + { \acro_property_get:nn {#1} {pages} } + \intarray_gzero:N \g__acro_pages_intarray + \seq_map_inline:Nn \l__acro_tmpa_seq + { + \intarray_gset:Nnn \g__acro_pages_intarray + { \__acro_absolute_page:w ##1 \q_stop + 1 } + { + \bool_if:NTF \l__acro_list_local_bool + { + \int_compare:nNnTF + { \__acro_barrier:w ##1 \q_stop } + = + \g_acro_barrier_int + {1} + {0} + } + {1} + } + } + \bool_if:NT \l__acro_list_local_bool + { + \seq_clear:N \l__acro_tmpb_seq + \seq_map_inline:Nn \l__acro_tmpa_seq + { + \int_compare:nNnT + { \__acro_barrier:w ##1 \q_stop } + = + \g_acro_barrier_int + { \seq_put_right:Nn \l__acro_tmpb_seq {##1} } + } + \seq_set_eq:NN \l__acro_tmpa_seq \l__acro_tmpb_seq + } + \seq_clear:N \l__acro_tmpb_seq + \int_zero:N \l__acro_tmpb_int + \seq_map_inline:Nn \l__acro_tmpa_seq + { + % the current page + \int_set:Nn \l__acro_tmpa_int + { \__acro_absolute_page:w ##1 \q_stop + 1 } + \int_compare:nNnTF \l__acro_tmpa_int = 1 + { % first page, start range + \seq_put_right:Ne \l__acro_tmpb_seq + { \__acro_page_name:w ##1 \q_stop } + \int_incr:N \l__acro_tmpb_int + } + { % not first page + \int_compare:nNnTF + { + \intarray_item:Nn \g__acro_pages_intarray + { \l__acro_tmpa_int - 1 } + } + = 0 + { % start range + \int_zero:N \l__acro_tmpb_int + \seq_put_right:Ne \l__acro_tmpb_seq + { \__acro_page_name:w ##1 \q_stop } + \int_incr:N \l__acro_tmpb_int + } + { % continue range + \int_compare:nNnTF + \l__acro_tmpa_int = { \intarray_count:N \g__acro_pages_intarray } + { % last page, range ended + \__acro_finish_range:Nnn \l__acro_tmpb_seq + { \l__acro_tmpb_int } + {##1} + \int_zero:N \l__acro_tmpb_int + } + { % not last page + \int_compare:nNnTF + { + \intarray_item:Nn \g__acro_pages_intarray + { \l__acro_tmpa_int + 1 } + } + = 0 + { % range ended + \__acro_finish_range:Nnn \l__acro_tmpb_seq + { \l__acro_tmpb_int } + {##1} + \int_zero:N \l__acro_tmpb_int + } + {% continue range + \int_incr:N \l__acro_tmpb_int + } + } + } + } + } + \seq_use:Nn \l__acro_tmpb_seq { \l__acro_pages_sep_tl } } -\cs_new_protected:Npn \acro_mark_as_used:n #1 +% #1: sequence +% #2: range length +% #3: page property entry +\cs_new_protected:Npn \__acro_finish_range:Nnn #1#2#3 { - \bool_gset_true:c { g__acro_#1_used_bool } - \bool_gset_true:c { g__acro_#1_first_use_bool } - \bool_gset_true:c { g__acro_#1_in_list_bool } - \if@filesw - \__acro_aux_file_now:n { \acro@used@once {#1} {} {} {} } - \__acro_aux_file_now:n { \acro@used@twice {#1} {} {} {} } - \fi + \seq_pop_right:NN #1 \l__acro_tmpa_tl + \int_compare:nNnTF {#2} > 1 + { + \bool_lazy_and:nnTF + { \l__acro_seq_use_bool } + { \int_compare_p:nNn {#2} < \l__acro_pages_seq_threshold_int } + { + \seq_put_right:Ne \l__acro_tmpb_seq + { + \exp_not:V \l__acro_tmpa_tl + \exp_not:V \l__acro_pages_seq_pre_tl + \acro_translate:n {sequentes} + } + } + { + \seq_put_right:Ne \l__acro_tmpb_seq + { + \exp_not:V \l__acro_tmpa_tl + -- + \__acro_page_name:w #3 \q_stop + } + } + } + { + \bool_if:NTF \l__acro_seq_use_bool + { + \seq_put_right:Ne \l__acro_tmpb_seq + { + \exp_not:V \l__acro_tmpa_tl + \exp_not:V \l__acro_pages_seq_pre_tl + \acro_translate:n {sequens} + } + } + { + \seq_put_right:Ne \l__acro_tmpb_seq + { \exp_not:V \l__acro_tmpa_tl } + \seq_put_right:Ne \l__acro_tmpb_seq + { \__acro_page_name:w #3 \q_stop } + } + } } -\cs_new_protected:Npn \acro_reset_all: - { \acro_for_all_acronyms_do:n { \acro_reset:n {##1} } } +\bool_new:N \l__acro_pages_all_bool +\bool_new:N \l__acro_pages_display_bool +\bool_new:N \l__acro_seq_use_bool -% make sure that no acronym is used at the beginning of the document, see -% issue #81 for reasons why this may be necessary: -\AfterEndPreamble { \acro_reset_all: } - -\cs_new_protected:Npn \acro_mark_all_as_used: - { \acro_for_all_acronyms_do:n { \acro_mark_as_used:n {##1} } } - -\prg_new_conditional:Npnn \acro_if_acronym_used:n #1 { p,T,F,TF } +% #1: id +\prg_new_conditional:Npnn \acro_if_pages:n #1 {p,T,F,TF} { \bool_lazy_and:nnTF - { \bool_if_p:c {g__acro_#1_used_bool} } - { !\acro_if_is_single_p:n {#1} } + { \l__acro_pages_display_bool } + { + \bool_lazy_and_p:nn + { \acro_attribute_if_set_p:nn {pages} {#1} } + { !\acro_if_single_p:n {#1} } + } { \prg_return_true: } { \prg_return_false: } } +\prg_generate_conditional_variant:Nnn \acro_if_pages:n {e} {p,T,F,TF} -% -------------------------------------------------------------------------- -% acronym barriers: allow local lists of only those acronyms used between two -% barriers - -\keys_define:nn {acro} +\acro_at_begin_document:n { - use-barriers .bool_gset:N = \g__acro_use_barriers_bool , - use-barriers .initial:n = false , - reset-at-barriers .bool_gset:N = \g__acro_reset_at_barrier_bool , - reset-at-barriers .initial:n = false + \bool_lazy_and:nnT + { \l__acro_pages_display_bool } + { !\l__acro_pages_all_bool } + { \bool_set_true:N \l__acro_label_bool } + } + +% #1: style name +\cs_new_protected:Npn \acro_no_page_ranges:n #1 + { + \bool_if:NF \l__acro_label_bool + { \msg_warning:nnn {acro} {label} {#1} } + \bool_set_false:N \l__acro_pages_all_bool + } +\cs_generate_variant:Nn \acro_no_page_ranges:n {e} + +\tl_new:N \l__acro_pages_fill_tl +\tl_new:N \l__acro_pages_sep_tl +\tl_new:N \l__acro_pages_seq_pre_tl + +\int_new:N \l__acro_pages_seq_threshold_int + +\keys_define:nn {acro/pages} + { + display .choice: , + display / all .code:n = + \bool_set_true:N \l__acro_pages_display_bool + \bool_set_true:N \l__acro_pages_all_bool , + display / first .code:n = + \bool_set_true:N \l__acro_pages_display_bool + \bool_set_false:N \l__acro_pages_all_bool , + display / none .code:n = + \bool_set_false:N \l__acro_pages_display_bool , + seq / use .bool_set:N = \l__acro_seq_use_bool , + seq / use .initial:n = true , + seq / pre .tl_set:N = \l__acro_pages_seq_pre_tl , + seq / pre .initial:n = \, , + seq / threshold .code:n = + \int_compare:nNnTF {#1} < 3 + { \msg_error:nn {acro} {threshold} } + { \int_set:Nn \l__acro_pages_seq_threshold_int {#1} } , + seq / threshold .initial:n = 3 , + fill .tl_set:N = \l__acro_pages_fill_tl , + fill .initial:n = \dotfill , + sep .tl_set:N = \l__acro_pages_sep_tl , + sep .initial:n = {,~} , + name .bool_set:N = \l__acro_pages_name_display_bool , + name .initial:n = false } -\cs_new_protected:Npn \acro_barrier: +% ---------------------------------------------------------------------------- +\AcroModuleEnd +\AcroModule{locale}{language support} + +\RequirePackage{translations} + +% -------------------------------------------------------------------------- +\msg_new:nnn {acro} {language-not-defined} { - \int_gincr:N \g__acro_barrier_int - \bool_if:NT \g__acro_reset_at_barrier_bool - { \acro_reset_all: } + You~ chose~ the~ language~ `#1'~ which~ is~ not~ defined~ by~ acro.~ + `english'~ is~ used~ instead.~ If~ you~ just~ mistyped~ try~ again!~ + Otherwise~ contact~ the~ author~ and~ he'll~ probably~ add~ your~ language. } -\cs_new_protected:Npn \acro_check_barriers:n #1 +\msg_new:nnn {acro} {translation-value} + { You~ need~ to~ give~ a~ value~ to~ `#1'~ \msg_line_context: } + +% -------------------------------------------------------------------------- +\bool_new:N \l__acro_show_locale_bool +\bool_new:N \l__acro_list_show_locale_bool +\tl_new:N \l__acro_locale_format_tl + +% #1: id +% #2: property +\prg_new_conditional:Npnn \acro_if_locale:nn #1#2 {p,T,F,TF} { - \bool_if:NT \g__acro_use_barriers_bool + \str_if_eq:nnTF {#2} {foreign} { - \tl_set:Nx \l__acro_tmpa_tl - { \seq_use:cn {g__acro_#1_barriers_seq} {} } - \tl_set:Nx \l__acro_tmpb_tl - { \seq_use:cn {g__acro_#1_recorded_barriers_seq} {} } - \tl_if_eq:NNF \l__acro_tmpa_tl \l__acro_tmpb_tl - { - \@latex@warning@no@line - {Rerun~to~get~barriers~of~acronym~#1~right} - } + \bool_lazy_or:nnTF + { \acro_property_if_set_p:nn {#1} {foreign-babel} } + { \acro_property_if_set_p:nn {#1} {foreign-locale} } + { \prg_return_true: } + { \prg_return_false: } } + { \prg_return_false: } } -\cs_new_protected:Npn \acro_record_barrier:n #1 +% #1: id +% #2: property +% #3: text +\cs_new_protected:Npn \acro_locale:nnn #1#2#3 { - \bool_if:NT \g__acro_use_barriers_bool + \acro_if_locale:nnTF {#1} {#2} { - \seq_if_in:cxF {g__acro_#1_barriers_seq} - { \int_use:N \g__acro_barrier_int } + \__acro_foreign_language:en + { \str_lowercase:e { \acro_property_get:nn {#1} {foreign-babel} } } { - \seq_gput_right:cx {g__acro_#1_barriers_seq} - { \int_use:N \g__acro_barrier_int } + \bool_lazy_or:nnT + { \l__acro_show_locale_bool } + { + \bool_lazy_and_p:nn + { \l__acro_list_bool } + { \l__acro_list_show_locale_bool } + } + { + { + \l__acro_locale_format_tl + { + \acro_property_if_set:nnTF {#1} {foreign-locale} + { \acro_property_get:nn {#1} {foreign-locale} } + { + \baselanguage + { \acro_property_get:nn {#1} {foreign-babel} } + } + } + } + :~ + } + #3 } } + {#3} } -% #1: id -% #2: barrier number -\prg_new_protected_conditional:Npnn \acro_if_in_barrier:nn #1#2 {T,F,TF} +\cs_new_protected:Npn \__acro_foreign_language:nn #1#2 { - \seq_if_in:cnTF {g__acro_#1_recorded_barriers_seq} {#2} - { \prg_return_true: } - { \prg_return_false: } + \bool_lazy_or:nnTF + { \acro_package_if_loaded_p:n {babel} } + { \acro_package_if_loaded_p:n {polyglossia} } + { \foreignlanguage {#1} {#2} } + {#2} + } +\cs_generate_variant:Nn \__acro_foreign_language:nn {e} + +\keys_define:nn {acro/locale} + { + display .bool_set:N = \l__acro_show_locale_bool , + display .initial:n = false , + format .tl_set:N = \l__acro_locale_format_tl , + format .initial:n = \em \text_titlecase_first:n } -\cs_generate_variant:Nn \acro_if_in_barrier:nnTF {nx} -\cs_new_protected:Npn \acro@barriers #1#2 - { \seq_gset_split:cnn {g__acro_#1_recorded_barriers_seq} {,} {#2} } +\keys_define:nn {acro/list/locale} + { + display .bool_set:N = \l__acro_list_show_locale_bool , + display .initial:n = false + } % -------------------------------------------------------------------------- -% the user commands -- preparation: -\cs_new_protected:Npn \acro_begin: + +\bool_new:N \l__acro_language_auto_bool +\bool_set_true:N \l__acro_language_auto_bool +% this token list will hold the chosen language for acro; since the +% language is either chosen automatically or by option it is only available at +% begin document +\tl_new:N \l_acro_language_tl +\tl_set:Nn \l_acro_language_tl {english} +\tl_new:N \l__acro_current_language_tl + +% ---------------------------------------------------------------------------- +\tl_const:Nn \c__acro_keyword_prefix_tl {acro-keyword-} +\prop_new:N \g_acro_translations_prop + +% translate the key #1 +\cs_new:Npn \acro_translate:n #1 { - \group_begin: - \__acro_check_after_end:w + \bool_if:NTF \l__acro_language_auto_bool + { \GetTranslation { \c__acro_keyword_prefix_tl #1 } } + { + \GetTranslationFor + { \l_acro_language_tl } + { \c__acro_keyword_prefix_tl #1 } + } } -\cs_new_protected:Npn \__acro_check_after_end:w #1 \acro_end: +\acro_at_begin_document:n { - \cs_set:Npn \__acro_execute: + \bool_if:NTF \l__acro_language_auto_bool { - \__acro_check_trail:N \l_peek_token - #1 - \acro_end: % this will end the group opened by \acro_begin: + \tl_set:Nx \l_acro_language_tl + { \@trnslt@language{\@trnslt@current@language} } } - \peek_after:Nw \__acro_execute: + { + \tl_set_eq:NN + \l_acro_language_tl + \l__acro_current_language_tl + } + } + +% ---------------------------------------------------------------------------- +% #1: language +% #2: keyword +% #3: translation +\cs_new_protected:Npn \acro_declare_translation:nnn #1#2#3 + { + \declaretranslation + {#1} + { \c__acro_keyword_prefix_tl #2 } + {#3} + \prop_gput:Nnn \g_acro_translations_prop {#2(#1)} {#3} } +\cs_generate_variant:Nn \acro_declare_translation:nnn {V,VnV} -\cs_new_protected:Npn \acro_end: { \group_end: } +% #1: key +% #2: csv list: { <lang1> = <translation1> , <lang2> = <translation2> } +\cs_new_protected:Npn \acro_declare_translations:nn #1#2 + { + \cs_set:Npn \__acro_declare_translation_aux:n ##1 + { \msg_error:nnn {acro} {translation-value} {##1} } + \cs_set:Npn \__acro_declare_translation_aux:nn ##1##2 + { \acro_declare_translation:nnn {##1} {#1} {##2} } + \keyval_parse:NNn + \__acro_declare_translation_aux:n + \__acro_declare_translation_aux:nn + {#2} + } -\cs_new_protected:Npn \acro_reset_specials: +% #1: language +% #2: csv list: { <key1> = <translation1> , <key2> = <translation2> } +\cs_new_protected:Npn \acro_add_translations:nn #1#2 { - \bool_set_false:N \l__acro_indefinite_bool - \bool_set_false:N \l__acro_first_upper_bool - \bool_set_false:N \l__acro_upper_indefinite_bool - \acro_for_endings_do:n { \bool_set_false:c {l__acro_##1_bool} } + \cs_set:Npn \__acro_declare_translation_aux:n ##1 + { \msg_error:nnn {acro} {translation-value} {##1} } + \cs_set:Npn \__acro_declare_translation_aux:nn ##1##2 + { \acro_declare_translation:nnn {#1} {##1} {##2} } + \keyval_parse:NNn + \__acro_declare_translation_aux:n + \__acro_declare_translation_aux:nn + {#2} } -% #1: ID -% #2: true|false -\cs_new_protected:Npn \acro_check_acronym:nn #1#2 +% within the loop: +% #1: keyword +% #2: language +% #3: translation +\cs_new_protected:Npn \__acro_for_all_translations_do:n #1 { - \acro_defined:n {#1} - \acro_use_acronym:n {#2} + \cs_set:Npn \__acro_parse_translate_list_entry:nnn ##1##2##3 {#1} + \prop_map_inline:Nn \g_acro_translations_prop + { \__acro_parse_translate_list_entry:www ##1 \q_mark ##2 \q_stop } } -% #1: boolean -% #2: ID -\cs_new_protected:Npn \acro_check_and_mark_if:nn #1#2 +% the purpose of the following is to easy documentation: +\cs_new:Npn \__acro_parse_translate_list_entry:nnn #1#2#3 {} + +\cs_new_protected:Npn \__acro_parse_translate_list_entry:www #1(#2)\q_mark#3\q_stop + { \__acro_parse_translate_list_entry:nnn {#1} {#2} {#3} } + +% ---------------------------------------------------------------------------- + +\keys_define:nn {acro} { - \bool_lazy_or:nnTF {#1} { !\l__acro_use_acronyms_bool } - { \acro_check_acronym:nn {#2} {false} } - { \acro_check_acronym:nn {#2} {true} } + language .value_required:n = true , + language .code:n = + \str_case:nnF {#1} + { {auto} { \bool_set_true:N \l__acro_language_auto_bool } } + { + \bool_set_false:N \l__acro_language_auto_bool + \tl_set:Nn \l__acro_current_language_tl {#1} + } , + language .initial:n = auto } -\cs_new_protected:Npn \acro_switch_off: - { \bool_set_false:N \l__acro_use_acronyms_bool } +% -------------------------------------------------------------------------- +\AcroModuleEnd +\AcroModule{pdfsupport}{support for bookmarks and accessibility} -\cs_new_protected:Npn \acro_switch_on: - { \bool_set_true:N \l__acro_use_acronyms_bool } +\msg_new:nnn {acro} {pdf-template-exists} + { The~ pdfstring~ template~ `#1'~ already~ exists~ \msg_line_context: } + +\msg_new:nnn {acro} {pdf-template-undefined} + { The~ pdfstring~ template~ `#1'~ is~ not~ defined~ \msg_line_context: } + +\msg_new:nnn {acro} {local-links} + { + You~ are~ using~ the~ option~ `make-links'~ in~ combination~ with~ local~ + acronym~ lists.~ Please~ make~ sure~ to~ also~ set \\ + \ \ \ \ barriers/single~ =~ true \\ + for~ referencing~ only~ existing~ and~ unique~ links. + } + +% -------------------------------------------------------------------------- +% hyper linking +\bool_new:N \l__acro_hyperref_use_bool + +\cs_new_eq:NN \__acro_hyper_target:nn \use_ii:nn +\cs_new_eq:NN \__acro_hyper_link:nn \use_ii:nn + +\cs_generate_variant:Nn \__acro_hyper_target:nn {e} +\cs_generate_variant:Nn \__acro_hyper_link:nn {e} + +% \acro_property_declare:nnnnn +% { \c_false_bool } % not unique +% { \c_true_bool } % boolean +% { \c_false_bool } % not mandatory +% { \c_false_bool } % dynamic +% {target-set} -% commands for (re)defining \ac-like macros: -\cs_new_protected:Npn \acro_define_new_acro_command:NN #1#2 +\cs_new_protected:Npn \__acro_activate_hyperref_support: { - % #1: csname - % #2: definition where `#1' refers to the ID - \cs_new_protected:Npn #1 ##1##2 + \bool_lazy_and:nnT + { \acro_package_if_loaded_p:n {hyperref} } + { \l__acro_hyperref_use_bool } { - \cs_set:Npn \__acro_tmp:n ####1 {##2} - \cs_new_protected:cpx - {acro_ \__acro_remove_backslash:N ##1 :nnn} ####1####2####3 - { - \acro_begin: - \acro_reset_specials: - \exp_not:N \tl_if_blank:nF {####2} { \keys_set:nn {acro} {####2} } - \acro_check_and_mark_if:nn {####1} {####3} - \__acro_tmp:n {####3} - \acro_end: - } - #2 ##1 {sO{}m} + \sys_if_engine_xetex:TF { - \acro_case_insensitive_command:cnnn - {acro_ \__acro_remove_backslash:N ##1 :nnn} - {####1} - {####2} - {####3} + \cs_set:Npn \__acro_hyper_link:nn ##1##2 + { \hyperlink {##1} { \XeTeXLinkBox {##2} } } } + { \cs_set_eq:NN \__acro_hyper_link:nn \hyperlink } + \cs_set:Npn \__acro_hyper_target:nn ##1##2 + { \raisebox {3ex} [0pt] { \hypertarget {##1} { } } ##2 } } } -\cs_generate_variant:Nn \acro_define_new_acro_command:NN {cc} -\cs_generate_variant:Nn \acro_check_and_mark_if:nn {nx} -% commands for (re)defining \acflike-like macros: -\cs_new_protected:Npn \acro_define_new_acro_pseudo_command:NN #1#2 +% #1: id +% #2: property +% #3: text +\cs_new_protected:Npn \__acro_make_link:nnn #1#2#3 { - % #1: csname - % #2: definition where `#1' refers to the ID and `#2' to the pseudo long form - \cs_new_protected:Npn #1 ##1##2 + \acro_if_short:nTF {#2} { - \cs_set:Npn \__acro_tmp:nn ####1####2 {##2} - \cs_new_protected:cpx - {acro_ \__acro_remove_backslash:N ##1 :nnn} ####1####2####3 + \bool_lazy_all:nTF { - \acro_begin: - \acro_reset_specials: - \acro_check_and_mark_if:nn {####1} {####3} - \__acro_tmp:nn {####3} {####2} - \acro_end: + { \acro_package_if_loaded_p:n {hyperref} } + { \l__acro_hyperref_use_bool } + { !\acro_if_single_p:n {#1} } } - #2 ##1 {smm} { - \acro_case_insensitive_command:cnnn - {acro_ \__acro_remove_backslash:N ##1 :nnn} - {####1} - {####3} - {####2} + \bool_if:NTF \l__acro_list_bool + { + \__acro_hyper_target:en + { + acro : #1 + \bool_lazy_and:nnT + { \l__acro_list_local_bool } + { \l__acro_usage_local_bool } + { : \int_use:N \g_acro_barrier_int } + } + {#3} + } + { + \__acro_hyper_link:en + { + acro : #1 + \bool_if:NT \l__acro_usage_local_bool + { : \int_use:N \g_acro_barrier_int } + } + { \phantom {#3} } + \__acro_color_link:n { \hbox_overlap_left:n {#3} } + } } + {#3} } + {#3} } -\cs_generate_variant:Nn \acro_define_new_acro_pseudo_command:NN {cc} -\clist_map_inline:nn {New,Renew,Declare,Provide} +\acro_at_begin_document:n { - \acro_define_new_acro_command:cc - {#1AcroCommand} - {#1DocumentCommand} - \acro_define_new_acro_pseudo_command:cc - {#1PseudoAcroCommand} - {#1DocumentCommand} - } - -% -------------------------------------------------------------------------- -% user commands -- facilities -\cs_new_protected:Npn \acro_first_upper: - { - \bool_if:NTF \l__acro_indefinite_bool + \bool_if:nT { - \bool_set_false:N \l__acro_indefinite_bool - \bool_set_true:N \l__acro_upper_indefinite_bool + \l__acro_hyperref_use_bool && + \l__acro_barriers_bool && + ! \l__acro_usage_local_bool } - { \bool_set_true:N \l__acro_first_upper_bool } + { \msg_warning:nn {acro} {local-links} } } -\cs_new_protected:Npn \acro_indefinite: +% #1: text +\cs_new:Npn \__acro_color_link:n #1 { - \bool_if:NTF \l__acro_first_upper_bool + \bool_lazy_and:nnTF + { \cs_if_exist_p:N \hypersetup } { - \bool_set_true:N \l__acro_upper_indefinite_bool - \bool_set_false:N \l__acro_first_upper_bool + \bool_lazy_or_p:nn + { \legacy_if_p:n {Hy@colorlinks} } + { \legacy_if_p:n {Hy@ocgcolorlinks} } } - { \bool_set_true:N \l__acro_indefinite_bool } + { \textcolor { \@linkcolor } {#1} } + {#1} } -\cs_new_protected:Npn \acro_cite: +\acro_at_begin_document:n { - \bool_set_true:N \l__acro_citation_all_bool - \bool_set_true:N \l__acro_citation_first_bool + \__acro_activate_hyperref_support: + \cs_if_exist:NF \textcolor { \cs_new_eq:NN \textcolor \use_ii:nn } } -\cs_new_protected:Npn \acro_no_cite: +\keys_define:nn {acro} { - \bool_set_false:N \l__acro_citation_all_bool - \bool_set_false:N \l__acro_citation_first_bool + make-links .bool_set:N = \l__acro_hyperref_use_bool , + make-links .initial:n = false } -\cs_new_protected:Npn \acro_index: - { \bool_set_true:N \l__acro_addto_index_bool } +% -------------------------------------------------------------------------- +% accessibility support +\bool_new:N \l__acro_accsupp_bool +\tl_new:N \l__acro_accsupp_options_tl +\tl_new:N \l__acro_accsupp_method_tl -% similar macros \acro_<ending>: are defined by \acro_provide_ending:nnn +% #1: copied text +% #2: printed text +\cs_new_protected:Npn \__acro_accsupp:nn #1#2 + { + \bool_if:NTF \l__acro_accsupp_bool + { + \__acro_do_accsupp:Vnn + \l__acro_acc_supp_options_tl + {#1} + {#2} + } + {#2} + } +\cs_generate_variant:Nn \__acro_accsupp:nn {ee} -% --------------------------------------------------------------------------- -% process options: -\ProcessKeysPackageOptions {acro} +% #1: options +% #2: copied text +% #3: printed text +\cs_new_protected:Npn \__acro_do_accsupp:nnn #1#2#3 + { + \BeginAccSupp { method = \l__acro_accsupp_method_tl , ActualText = {#2} , #1 } + #3 + \EndAccSupp { } + } +\cs_generate_variant:Nn \__acro_do_accsupp:nnn {V} -% --------------------------------------------------------------------------- -% PDF bookmark support -\cs_new:Npn \acpdfstring - { \acro_pdf_string_short:n } +\acro_at_begin_document:n + { + \bool_lazy_all:nT + { + { \acro_package_if_loaded_p:n {accsupp} } + { \acro_package_if_loaded_p:n {hyperref} } + { \l__acro_use_accsupp_bool } + } + { \bool_set_true:N \l__acro_accsupp_bool } + } -\cs_new:Npn \acpdfstringalt - { \acro_pdf_string_alt:n } +\keys_define:nn {acro/accsupp} + { + use .code:n = + \str_case:nnTF {#1} + { {true} {} {false} {} } + { \use:c {bool_set_#1:N} \l__acro_use_accsupp_bool } + { \msg_error:nnn {kernel} {boolean-values-only} {group} } , + use .initial:n = true , + options .tl_set:N = \l__acro_acc_supp_options_tl , + options .initial:n = , + method .tl_set:N = \l__acro_accsupp_method_tl , + method .initial:n = pdfstringdef + } -\cs_new:Npn \acpdfstringlong - { \acro_pdf_string_long:n } +% -------------------------------------------------------------------------- +% pdf comments a.k.a. tooltips +\bool_new:N \l__acro_pdfcomment_use_bool -\cs_new:Npn \acpdfstringfirst #1 - { \acpdfstringlong {#1} ~ ( \acpdfstring {#1} ) } +% #1: id +% #2: property +% #3: text +\cs_new_protected:Npn \__acro_pdf_comment:nnn #1#2#3 + { + \bool_lazy_all:nTF + { + { \l__acro_pdfcomment_use_bool } + { \acro_property_if_set_p:nn {#1} {pdfcomment} } + { \acro_if_short_p:n {#2} } + } + { + \__acro_pdf_comment_cmd:nn + {#3} + { \acro_property_get:nn {#1} {pdfcomment} } + } + {#3} + } -% TODO: place this somewhere where endings are defined: -\cs_new:Npn \acpdfstringlongplural - { \acro_pdf_string_long_plural:n } +\keys_define:nn {acro/pdfcomments} + { + use .bool_set:N = \l__acro_pdfcomment_use_bool , + use .initial:n = false , + cmd .cs_set:Np = \__acro_pdf_comment_cmd:nn #1#2 , + cmd .initial:n = \pdftooltip {#1} {#2} + } +% -------------------------------------------------------------------------- +% expandable templates for use in pdfstrings \prg_new_conditional:Npnn \acro_if_star_gobble:n #1 {TF} { \if_meaning:w *#1 @@ -3500,625 +4251,1201 @@ \fi: } -\cs_new:Npn \acro_expandable_short:n #1 - { \use:e { \prop_item:Nn \l__acro_short_prop {#1} } } - -\cs_new:Npn \acro_expandable_alt:n #1 - { \use:e { \prop_item:Nn \l__acro_alt_prop {#1} } } +% #1: name +% #2: code +\cs_new_protected:Npn \acro_pdfstring_template_new:nn #1#2 + { + \cs_if_exist:cTF {____acro:pdfstring:template:#1} + { \msg_error:nnn {acro} {pdf-template-exists} {#1} } + { \cs_new:cpn {____acro:pdfstring:template:#1} ##1 {#2} } + } -\cs_new:Npn \acro_expandable_long:n #1 - { \use:e { \prop_item:Nn \l__acro_long_prop {#1} } } +% #1: name +% #2: code +\cs_new_protected:Npn \acro_pdfstring_template_set:nn #1#2 + { + \cs_if_exist:cTF {____acro:pdfstring:template:#1} + { \cs_set:cpn {____acro:pdfstring:template:#1} ##1 {#2} } + { \cs_new:cpn {____acro:pdfstring:template:#1} ##1 {#2} } + } -\cs_new:Npn \acro_expandable_long_plural:n #1 +% #1: name +% #2: name to be let to +\cs_new_protected:Npn \acro_pdfstring_template_let:nn #1#2 { - \bool_if:cTF - { c_ \prop_item:Nn \l__acro_long_plural_form_prop {#1} _bool } - { \use:e { \prop_item:Nn \l__acro_long_plural_prop {#1} } } + \cs_if_exist:cTF {____acro:pdfstring:template:#2} { - \use:e { - \prop_item:Nn \l__acro_long_prop {#1} - \prop_item:Nn \l__acro_long_plural_prop {#1} - } + \cs_set_eq:cc + {____acro:pdfstring:template:#1} + {____acro:pdfstring:template:#2} + } + { \msg_error:nnn {acro} {pdf-template-undefined} {#2} } + } + +% #1: name +% #2: id +\cs_new:Npn \acro_pdfstring_template:nn #1#2 + { + \cs_if_exist:cTF {____acro:pdfstring:template:#1} + { \use:c {____acro:pdfstring:template:#1} {#2} } + { \msg_expandable_error:nnn {acro} {pdf-template-undefined} {#1} } + } + +% #1: cs +% #2: template +\cs_new_protected:Npn \acro_set_pdf_cs:Nn #1#2 + { + \cs_set:Npn #1 ##1 + { + \acro_if_star_gobble:nTF {##1} + { \acro_pdfstring_template:nn {#2} } + { \acro_pdfstring_template:nn {#2} {##1} } + } + } + +% #1: id +% #2: property +\cs_new:Npn \__acro_pdfstring_plural:nn #1#2 + { + \acro_property_get_if_set:nnF {#1} {#2-plural-form} + { + \str_if_eq:nnTF {#2} {short} + { \acro_property_get:nn {#1} {pdfstring} } + { \acro_property_get:nn {#1} {#2} } + \acro_property_get:nn {#1} {#2-plural} } } -\cs_new:Npn \acro_pdf_string_short:n #1 +% #1: id +% #2: property +\cs_new:Npn \__acro_pdfstring_indefinite:nn #1#2 { - \acro_if_star_gobble:nTF {#1} - { \acro_expandable_short:n } - { \acro_expandable_short:n {#1} } + \acro_property_get_if_set:nnT {#1} {#2-indefinite} + { \c_space_tl } } -\cs_new:Npn \acro_pdf_string_alt:n #1 +% #1: text +\cs_new:Npn \__acro_pdfstring_upper:n #1 + { \text_titlecase_first:e {#1} } + +\cs_generate_variant:Nn \text_titlecase_first:n {e} + +% -------------------------------------------------------------------------- +% long-short +\acro_pdfstring_template_new:nn {long-short} { - \acro_if_star_gobble:nTF {#1} - { \acro_expandable_alt:n } - { \acro_expandable_alt:n {#1} } + \acro_property_get:nn {#1} {long} + \acro_space: + ( \acro_property_get:nn {#1} {pdfstring} ) } -\cs_new:Npn \acro_pdf_string_long:n #1 +% indef-long-short +\acro_pdfstring_template_new:nn {indef-long-short} { - \acro_if_star_gobble:nTF {#1} - { \acro_expandable_long:n } - { \acro_expandable_long:n {#1} } + \__acro_pdfstring_indefinite:nn {#1} {long} + \acro_property_get:nn {#1} {long} + \acro_space: + ( \acro_property_get:nn {#1} {pdfstring} ) } -% TODO: place this somewhere where endings are defined: -\cs_new:Npn \acro_pdf_string_long_plural:n #1 +% Long-short +\acro_pdfstring_template_new:nn {Long-short} { - \acro_if_star_gobble:nTF {#1} - { \acro_expandable_long_plural:n } - { \acro_expandable_long_plural:n {#1} } + \__acro_pdfstring_upper:n + { \acro_property_get:nn {#1} {long} } + \acro_space: + ( \acro_property_get:nn {#1} {pdfstring} ) } -\AtBeginDocument +% Indef-long-short +\acro_pdfstring_template_new:nn {Indef-long-short} { - \@ifpackageloaded {hyperref} + \__acro_pdfstring_upper:n { - \bool_set_true:N \l__acro_hyperref_loaded_bool - \pdfstringdefDisableCommands - { - \cs_set_eq:NN \ac \acpdfstring - \cs_set_eq:NN \Ac \acpdfstring - \cs_set_eq:NN \acs \acpdfstring - \cs_set_eq:NN \acl \acpdfstringlong - \cs_set_eq:NN \Acl \acpdfstringlong - \cs_set_eq:NN \acf \acpdfstringfirst - \cs_set_eq:NN \Acf \acpdfstringfirst - \cs_set_eq:NN \aca \acpdfstringalt - \cs_set_eq:NN \acp \acpdfstringplural - \cs_set_eq:NN \Acp \acpdfstringplural - \cs_set_eq:NN \acsp \acpdfstringplural - \cs_set_eq:NN \aclp \acpdfstringlongplural - \cs_set_eq:NN \Aclp \acpdfstringlongplural - \cs_set_eq:NN \acfp \acpdfstringplural - \cs_set_eq:NN \Acfp \acpdfstringplural - \cs_set_eq:NN \acap \acpdfstringaltplural - } - \cs_set_protected:Npn \acro_hyper_page:n #1 { \hyperpage {#1} } - } {} + \__acro_pdfstring_indefinite:nn {#1} {long} + \acro_property_get:nn {#1} {long} + } + \acro_space: + ( \acro_property_get:nn {#1} {pdfstring} ) } -% -------------------------------------------------------------------------- -% key and order checking -\msg_new:nnn {acro} {no-id} +% long-short-plural +\acro_pdfstring_template_new:nn {long-short-plural} { - Something~ has~ gone~ wrong,~ you've~ probably~ forgotten~ to~ set~ the~ - acronym~ ID. + \__acro_pdfstring_plural:nn {#1} {long} + \acro_space: + ( \__acro_pdfstring_plural:nn {#1} {short} ) } -\msg_new:nnn {acro} {before-short} +% Long-short-plural +\acro_pdfstring_template_new:nn {Long-short-plural} { - You've~ set~ the~ property~ `#2'~ before~ the~ `short'~ property~ for~ - acronym~ `#1'~ but~ it~ needs~ to~ be~ set~ after~ it. + \__acro_pdfstring_upper:n + { \__acro_pdfstring_plural:nn {#1} {long} } + \acro_space: + ( \__acro_pdfstring_plural:nn {#1} {short} ) } -\msg_new:nnn {acro} {missing} - { The~ `#2'~ property~ for~ acronym~ `#1'~ is~ missing. } +% -------------------------------------------------------------------------- +% short-long +\acro_pdfstring_template_new:nn {short-long} + { + \acro_property_get:nn {#1} {pdfstring} + \acro_space: + ( \acro_property_get:nn {#1} {long} ) + } -\msg_new:nnn {acro} {doubled-property} +% indef-short-long +\acro_pdfstring_template_new:nn {indef-short-long} { - It~ seems~ to~ me~ you~ have~ used~ the~ `#2'~ property~ twice~ in~ the~ - declaration~ of~ acronym~ `#1'.~ If~ you~ haven't~ there's~ - something~ different~ wrong~ and~ I'm~ lost.~ You~'re~ on~ your~ own~ - then. + \__acro_pdfstring_indefinite:nn {#1} {short} + \acro_property_get:nn {#1} {pdfstring} + \acro_space: + ( \acro_property_get:nn {#1} {long} ) } -% #1: acronym -% #2: property -\cs_new_protected:Npn \__acro_property_check:nn #1#2 +% Short-long +\acro_pdfstring_template_new:nn {Short-long} { - \str_if_empty:NT \l__acro_current_id_str - { \acro_serious_message:n {no-id} } - \str_if_eq:nnF {#2} {short} - { - \acro_property_if_set:nnF {#1} {short} - { - \keys_set:nn {acro/declare-acronym} { short = {#1} } - \acro_harmless_message:nn {substitute-short} {#1} - } - } - \acro_property_mark_set:nn {#1} {#2} + \__acro_pdfstring_upper:n + { \acro_property_get:nn {#1} {pdfstring} } + \acro_space: + ( \acro_property_get:nn {#1} {long} ) } -\cs_new_protected:Npn \__acro_first_property_check:nn #1#2 +% Indef-short-long +\acro_pdfstring_template_new:nn {Indef-short-long} { - \cs_if_exist:cTF {l__acro_#1_short_set_bool} + \__acro_pdfstring_upper:n { - \acro_property_if_set:nnT {#1} {short} - { \acro_serious_message:nnn {doubled-property} {#1} {#2} } + \__acro_pdfstring_indefinite:nn {#1} {short} + \acro_property_get:nn {#1} {pdfstring} } - { \bool_new:c {l__acro_#1_short_set_bool} } - \acro_property_mark_set:nn {#1} {short} + \acro_space: + ( \acro_property_get:nn {#1} {long} ) } -% #1: ID -% #2: property -\prg_new_conditional:Npnn \acro_property_if_set:nn #1#2 {T,F,TF} +% short-long-plural +\acro_pdfstring_template_new:nn {short-long-plural} { - \bool_if:cTF {l__acro_#1_#2_set_bool} - { \prg_return_true: } - { \prg_return_false: } + \__acro_pdfstring_plural:nn {#1} {short} + \acro_space: + ( \__acro_pdfstring_plural:nn {#1} {long} ) } -% #1: ID -% #2: property -\cs_new_protected:Npn \acro_property_mark_set:nn #1#2 - { \bool_set_true:c { l__acro_#1_#2_set_bool } } -\cs_generate_variant:Nn \acro_property_mark_set:nn {V} +% Short-long-plural +\acro_pdfstring_template_new:nn {Short-long-plural} + { + \__acro_pdfstring_upper:n + { \__acro_pdfstring_plural:nn {#1} {short} } + \acro_space: + ( \__acro_pdfstring_plural:nn {#1} {long} ) + } % -------------------------------------------------------------------------- -% the internal property selection functions for \DeclareAcronym: +% short +\acro_pdfstring_template_new:nn {short} + { \acro_property_get:nn {#1} {pdfstring} } -\cs_new_protected:Npn \acro_for_properties_do:n - { \prop_map_inline:Nn \g__acro_properties_prop } +% indef-short +\acro_pdfstring_template_new:nn {indef-short} + { + \__acro_pdfstring_indefinite:nn {#1} {short} + \acro_property_get:nn {#1} {pdfstring} + } -% #1: name in associated cs -% #2: property name -% #3: action -\cs_new_protected:Npn \acro_declare_property_generic:nnn #1#2#3 +% Short +\acro_pdfstring_template_new:nn {Short} { - \prop_clear_new:c {l__acro_#1_prop} - \tl_clear_new:c {l__acro_#1_tl} - \cs_new_protected:cpn {__acro_declare_#1:nn} ##1##2 {#3} - \cs_generate_variant:cn {__acro_declare_#1:nn} {V} - \keys_define:nn {acro/declare-acronym} - { - #2 .code:n = - \use:c {__acro_declare_#1:Vn} \l__acro_current_id_str {##1} - \acro_property_mark_set:Vn \l__acro_current_id_str {#2} - } - \prop_gput:Nnn \g__acro_properties_prop {#2} {#1} + \__acro_pdfstring_upper:n + { \acro_property_get:nn {#1} {pdfstring} } } -% #1: name in associated cs -% #2: property name -% #3: action -\cs_new_protected:Npn \acro_declare_property:nnn #1#2#3 +% Indef-short +\acro_pdfstring_template_new:nn {Indef-short} { - \acro_declare_property_generic:nnn {#1} {#2} + \__acro_pdfstring_upper:n { - \__acro_property_check:nn {##1} {#2} - \prop_put:cnn {l__acro_#1_prop} {##1} {##2} - #3 + \__acro_pdfstring_indefinite:nn {#1} {short} + \acro_property_get:nn {#1} {pdfstring} } } -% #1: name in associated cs -% #2: property name -\cs_new_protected:Npn \acro_declare_property:nn #1#2 - { \acro_declare_property:nnn {#1} {#2} {} } -\cs_generate_variant:Nn \acro_declare_property:nn {V} +% short-plural +\acro_pdfstring_template_new:nn {short-plural} + { \__acro_pdfstring_plural:nn {#1} {short} } -\cs_new_protected:Npn \acro_declare_property_simple:n #1 +% Short-plural +\acro_pdfstring_template_new:nn {Short-plural} { - \tl_set:Nn \l__acro_tmpa_tl {#1} - \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} - \acro_declare_property:Vn \l__acro_tmpa_tl {#1} + \__acro_pdfstring_upper:n + { \__acro_pdfstring_plural:nn {#1} {short} } } -% #1: new alias property -% #2: old property -\cs_new_protected:Npn \acro_declare_property_alias:nn #1#2 +% -------------------------------------------------------------------------- +% alt +\acro_pdfstring_template_new:nn {alt} { - \keys_define:nn {acro/declare-acronym} - { #1 .meta:n = { #2 = {##1} } } + \acro_property_get_if_set:nnF {#1} {alt} + { \acro_pdfstring_template:nn {#1} {short} } } -% -------------------------------------------------------------------------- -% declare the properties for \DeclareAcronym: -% short: -\acro_declare_property_generic:nnn {short} {short} - { - \__acro_first_property_check:nn {#1} {short} - \prop_put:Nnn \l__acro_short_prop {#1} {#2} - \prop_put:Nnn \l__acro_sort_prop {#1} {#1} - \prop_put:Nnn \l__acro_index_sort_prop {#1} {#1} - \prop_put:Nnn \l__acro_alt_prop {#1} {#2} - \prop_put:Nnn \l__acro_pdfstring_short_prop {#1} {#2} - \prop_put:Nnn \l__acro_pdfstring_alt_prop {#1} {#2} - \acro_for_endings_do:n - { - \prop_put:cnv {l__acro_short_##1_prop} - {#1} {l__acro_default_short_##1_tl} - \prop_put:cnx {l__acro_pdfstring_short_##1_prop} - {#1} { \exp_not:n {#2} \exp_not:v {l__acro_default_short_##1_tl} } - \prop_put:cnn {l__acro_short_##1_form_prop} {#1} {false} - \prop_put:cnv {l__acro_alt_##1_prop} - {#1} {l__acro_default_alt_##1_tl} - \prop_put:cnx {l__acro_pdfstring_alt_##1_prop} - {#1} { \exp_not:n {#2} \exp_not:v {l__acro_default_short_##1_tl} } - \prop_put:cnn {l__acro_alt_##1_form_prop} {#1} {false} - } - \prop_put:NnV \l__acro_short_indefinite_prop - {#1} \l__acro_default_indefinite_tl - \prop_put:NnV \l__acro_alt_indefinite_prop - {#1} \l__acro_default_indefinite_tl - } - -% long: -\acro_declare_property:nnn {long} {long} - { - \prop_put:NnV \l__acro_long_indefinite_prop - {#1} - \l__acro_default_indefinite_tl - \acro_for_endings_do:n +% indef-alt +\acro_pdfstring_template_new:nn {indef-alt} + { + \acro_property_if_set:nnTF {#1} {alt} { - \prop_put:cnn {l__acro_long_##1_form_prop} {#1} {false} - \acro_property_if_set:nnF {#1} {long-##1} - { \prop_put:cnv {l__acro_long_##1_prop} {#1} {l__acro_default_long_##1_tl} } - \prop_put:cnn {l__acro_foreign_##1_form_prop} {#1} {false} - \acro_property_if_set:nnF {#1} {foreign-##1} - { \prop_put:cnv {l__acro_foreign_##1_prop} {#1} {l__acro_default_foreign_##1_tl} } + \__acro_pdfstring_indefinite:nn {#1} {alt} + \acro_property_get:nn {#1} {alt} } + { \acro_pdfstring_template:nn {#1} {indef-short} } } -\acro_declare_property_simple:n {first-style} - -% list: -\acro_declare_property_simple:n {list} - -% defines `short-plural', `long-plural' and `long-plural-form' as well as the -% options `plural-ending', `short-plural-ending' and `long-plural-ending': -% \ProvideAcroEnding {plural} {s} {s} - -% short indefinite article: -\acro_declare_property_simple:n {short-indefinite} +% Alt +\acro_pdfstring_template_new:nn {Alt} + { + \acro_property_if_set:nnTF {#1} {alt} + { + \__acro_pdfstring_upper:n + { \acro_property_get:nn {#1} {alt} } + } + { \acro_pdfstring_template:nn {#1} {Short} } + } -% long indefinite article: -\acro_declare_property_simple:n {long-indefinite} +% Indef-alt +\acro_pdfstring_template_new:nn {Indef-alt} + { + \acro_property_if_set:nnTF {#1} {alt} + { + \__acro_pdfstring_upper:n + { \__acro_pdfstring_indefinite:nn {#1} {alt} } + \acro_property_get:nn {#1} {alt} + } + { \acro_pdfstring_template:nn {#1} {Indef-short} } + } -% pre long: -\acro_declare_property_simple:n {long-pre} +% alt-plural +\acro_pdfstring_template_new:nn {alt-plural} + { + \acro_property_if_set:nnTF {#1} {alt} + { \__acro_pdfstring_plural:nn {#1} {alt} } + { \acro_pdfstring_template:nn {#1} {short-plural} } + } -% post long: -\acro_declare_property_simple:n {long-post} +% Alt-plural +\acro_pdfstring_template_new:nn {Alt-plural} + { + \acro_property_if_set:nnTF {#1} {alt} + { + \__acro_pdfstring_upper:n + { \__acro_pdfstring_plural:nn {#1} {alt} } + } + { \acro_pdfstring_template:nn {#1} {Short-plural} } + } -% post: -\acro_declare_property_simple:n {post} +% -------------------------------------------------------------------------- +% long +\acro_pdfstring_template_new:nn {long} + { \acro_property_get:nn {#1} {long} } -% sort: -\acro_declare_property:nnn {sort} {sort} +% indef-long +\acro_pdfstring_template_new:nn {indef-long} { - \acro_property_if_set:nnF {#1} {index-sort} - { \prop_put:Nnn \l__acro_index_sort_prop {#1} {#2} } + \__acro_pdfstring_indefinite:nn {#1} {long} + \acro_property_get:nn {#1} {long} } -% alternative: -\acro_declare_property:nnn {alt} {alt} +% Long +\acro_pdfstring_template_new:nn {Long} { - \prop_put:Nnn \l__acro_pdfstring_alt_prop {#1} {#2} - \prop_put:NnV \l__acro_alt_indefinite_prop - {#1} \l__acro_default_indefinite_tl + \__acro_pdfstring_upper:n + { \acro_property_get:nn {#1} {long} } } -\cs_set_protected:Npn \acro_alt_error:n #1 +% Indef-long +\acro_pdfstring_template_new:nn {Indef-long} { - \acro_property_if_set:nnF {#1} {alt} - { \acro_harmless_message:nn {no-alternative} {#1} } + \__acro_pdfstring_upper:n + { + \__acro_pdfstring_indefinite:nn {#1} {long} + \acro_property_get:nn {#1} {long} + } } -% alt. indefinite article: -\acro_declare_property_simple:n {alt-indefinite} +% long-plural +\acro_pdfstring_template_new:nn {long-plural} + { \__acro_pdfstring_plural:nn {#1} {long} } -% foreign: -\acro_declare_property_simple:n {foreign} +% Long-plural +\acro_pdfstring_template_new:nn {Long-plural} + { + \__acro_pdfstring_upper:n + { \__acro_pdfstring_plural:nn {#1} {long} } + } -% foreign-lang: -\acro_declare_property_simple:n {foreign-lang} +% -------------------------------------------------------------------------- +% first +\acro_pdfstring_template_let:nn {first} {short} -% format: -\acro_declare_property_simple:n {format} +% indef-first +\acro_pdfstring_template_let:nn {indef-first} {indef-short} -% short format: -\acro_declare_property_alias:nn {short-format} {format} +% First +\acro_pdfstring_template_let:nn {First} {Short} -% alt format: -\acro_declare_property_simple:n {alt-format} +% indef-first +\acro_pdfstring_template_let:nn {Indef-first} {Indef-short} -% long format: -\acro_declare_property_simple:n {long-format} +% first-plural +\acro_pdfstring_template_let:nn {first-plural} {short-plural} -% first long format: -\acro_declare_property_simple:n {first-long-format} +% First-plural +\acro_pdfstring_template_let:nn {First-plural} {Short-plural} -% pdfstring -- currently needs to be done `by hand': -\cs_new_protected:Npn \__acro_declare_pdfstring:nw #1#2/#3/#4 \acro_stop: +% -------------------------------------------------------------------------- + +\acro_at_begin_document:n { - \__acro_property_check:nn {#1} {pdfstring} - \prop_put:Nnx \l__acro_pdfstring_short_prop {#1} {#2} - \acro_for_endings_do:n + \acro_package_if_loaded:nT {hyperref} { - \tl_if_blank:nTF {#4} - { - \prop_put:cnx {l__acro_pdfstring_short_##1_prop} - {#1} { \exp_not:n {#2} \exp_not:v {l__acro_default_short_##1_tl} } - } + \pdfstringdefDisableCommands { - \prop_put:cnn {l__acro_pdfstring_short_##1_prop} - {#1} {#2#3} + \acro_set_pdf_cs:Nn \ac {first} + \acro_set_pdf_cs:Nn \iac {indef-first} + \acro_set_pdf_cs:Nn \Ac {First} + \acro_set_pdf_cs:Nn \Iac {Indef-first} + \acro_set_pdf_cs:Nn \acs {short} + \acro_set_pdf_cs:Nn \iacs {indef-short} + \acro_set_pdf_cs:Nn \Acs {Short} + \acro_set_pdf_cs:Nn \Iacs {Indef-short} + \acro_set_pdf_cs:Nn \acl {long} + \acro_set_pdf_cs:Nn \iacl {indef-long} + \acro_set_pdf_cs:Nn \Acl {Long} + \acro_set_pdf_cs:Nn \Iacl {Indef-long} + \acro_set_pdf_cs:Nn \aca {alt} + \acro_set_pdf_cs:Nn \iaca {indef-alt} + \acro_set_pdf_cs:Nn \Aca {Alt} + \acro_set_pdf_cs:Nn \Iaca {Indef-alt} + + \acro_set_pdf_cs:Nn \acp {first-plural} + \acro_set_pdf_cs:Nn \Acp {First-plural} + \acro_set_pdf_cs:Nn \acsp {short-plural} + \acro_set_pdf_cs:Nn \Acsp {Short-plural} + \acro_set_pdf_cs:Nn \aclp {long-plural} + \acro_set_pdf_cs:Nn \Aclp {Long-plural} + \acro_set_pdf_cs:Nn \acap {alt-plural} + \acro_set_pdf_cs:Nn \Acap {Alt-plural} + \cs_set_eq:NN \acro_format:nnn \use_iii:nnn + \cs_set:Npn \@ {} } - } + \cs_set_protected:Npn \acro_hyper_page:n #1 { \hyperpage {#1} } + } {} } -\cs_generate_variant:Nn \__acro_declare_pdfstring:nw {V} + +% ---------------------------------------------------------------------------- +\AcroModuleEnd +\AcroModule{definitions}{definitions of user commands} + +% -------------------------------------------------------------------------- +% commands for typesetting acronyms: +\NewAcroCommand \ac {m} + { \UseAcroTemplate {first} {#1} } +\NewAcroCommand \acp {m} + { \acroplural \UseAcroTemplate {first} {#1} } +\NewAcroCommand \iac {m} + { \acroindefinite \UseAcroTemplate {first} {#1} } +\NewAcroCommand \Ac {m} + { \acroupper \UseAcroTemplate {first} {#1} } +\NewAcroCommand \Acp {m} + { \acroplural \acroupper \UseAcroTemplate {first} {#1} } +\NewAcroCommand \Iac {m} + { \acroupper \acroindefinite \UseAcroTemplate {first} {#1} } + +\NewAcroCommand \acs {m} + { \UseAcroTemplate {short} {#1} } +\NewAcroCommand \acsp {m} + { \acroplural \UseAcroTemplate {short} {#1} } +\NewAcroCommand \iacs {m} + { \acroindefinite \UseAcroTemplate {short} {#1} } +\NewAcroCommand \Acs {m} + { \acroupper \UseAcroTemplate {short} {#1} } +\NewAcroCommand \Acsp {m} + { \acroplural \acroupper \UseAcroTemplate {short} {#1} } +\NewAcroCommand \Iacs {m} + { \acroupper \acroindefinite \UseAcroTemplate {short} {#1} } -\keys_define:nn {acro/declare-acronym} +\NewAcroCommand \acl {m} + { \UseAcroTemplate {long} {#1} } +\NewAcroCommand \aclp {m} + { \acroplural \UseAcroTemplate {long} {#1} } +\NewAcroCommand \iacl {m} + { \acroindefinite \UseAcroTemplate {long} {#1} } +\NewAcroCommand \Acl {m} + { \acroupper \UseAcroTemplate {long} {#1} } +\NewAcroCommand \Aclp {m} + { \acroplural \acroupper \UseAcroTemplate {long} {#1} } +\NewAcroCommand \Iacl {m} + { \acroupper \acroindefinite \UseAcroTemplate {long} {#1} } + +\NewAcroCommand \aca {m} + { \UseAcroTemplate {alt} {#1} } +\NewAcroCommand \acap {m} + { \acroplural \UseAcroTemplate {alt} {#1} } +\NewAcroCommand \iaca {m} + { \acroindefinite \UseAcroTemplate {alt} {#1} } +\NewAcroCommand \Aca {m} + { \acroupper \UseAcroTemplate {alt} {#1} } +\NewAcroCommand \Acap {m} + { \acroplural \acroupper \UseAcroTemplate {alt} {#1} } +\NewAcroCommand \Iaca {m} + { \acroupper \acroindefinite \UseAcroTemplate {alt} {#1} } + +\NewAcroCommand \acf {m} + { \acrofull \UseAcroTemplate {first} {#1} } +\NewAcroCommand \acfp {m} + { \acrofull \acroplural \UseAcroTemplate {first} {#1} } +\NewAcroCommand \iacf {m} + { \acrofull \acroindefinite \UseAcroTemplate {first} {#1} } +\NewAcroCommand \Acf {m} + { \acrofull \acroupper \UseAcroTemplate {first} {#1} } +\NewAcroCommand \Acfp {m} + { \acrofull \acroplural \acroupper \UseAcroTemplate {first} {#1} } +\NewAcroCommand \Iacf {m} + { \acrofull \acroupper \acroindefinite \UseAcroTemplate {first} {#1} } + +\NewAcroCommand \acshow {m} + { \acrodonotuse \UseAcroTemplate {show} {#1} } + +% -------------------------------------------------------------------------- +\DeclareAcroEnding {plural} {s} {s} + +\DeclareAcroArticle {indefinite} {a} + +\ProvideExpandableDocumentCommand \nospace {} {} + +% -------------------------------------------------------------------------- +% acronym templates: +\NewAcroTemplate {long-short} { - pdfstring .code:n = - \__acro_declare_pdfstring:Vw \l__acro_current_id_str #1 // \acro_stop: + \acroiffirstTF + { + \acrowrite {long} + \acspace + ( + \acroifT {foreign} { \acrowrite {foreign} ,~ } + \acrowrite {short} + \acroifT {alt} { ~ \acrotranslate {or} ~ \acrowrite {alt} } + \acrogroupcite + ) + } + { \acrowrite {short} } } -\cs_new_protected:Npn \__acro_declare_pdfstring_alt:nw #1#2/#3/#4 \acro_stop: +\NewAcroTemplate {short-long} { - \__acro_property_check:nn {#1} {pdfstring-alt} - \prop_put:Nnn \l__acro_pdfstring_alt_prop {#1} {#2} - \acro_for_endings_do:n + \acrowrite {short} + \acroiffirstT { - \tl_if_empty:nTF {#3} - { - \prop_put:cnx {l__acro_pdfstring_alt_##1_prop} - {#1} { \exp_not:n {#2} \exp_not:v {l__acro_default_alt_##1_tl} } - } - { \prop_put:cnn {l__acro_pdfstring_alt_##1_prop} {#1} {#2#3} } + \space + ( + \acroifT {alt} { \acrotranslate {or} ~ \acrowrite {alt} ~ } + \acroifT {foreign} { \acrowrite {foreign} :~ } + \acrowrite {long} + \acrogroupcite + ) } } -\cs_generate_variant:Nn \__acro_declare_pdfstring_alt:nw {V} -\keys_define:nn {acro/declare-acronym} +\NewAcroTemplate {footnote} { - pdfstring-alt .code:n = - \__acro_declare_pdfstring_alt:Vw \l__acro_current_id_str #1 // \acro_stop: + \acrowrite {short} + \acroiffirstT + { + \acfootnote + { + \acroifT {alt} { \acrotranslate {or} ~ \acrowrite {alt} :~ } + \acroifT {foreign} { \acrowrite {foreign} ,~ } + \acrowrite {long} + \acrogroupcite + } + } } - -% class: -\acro_declare_property_simple:n {class} -% extra information: -\acro_declare_property_simple:n {extra} +\NewAcroTemplate {long} + { \acrowrite {long} } -% single appearances: -\acro_declare_property_simple:n {single} +\NewAcroTemplate {short} + { \acrowrite {short} } -% single format: -\acro_declare_property_simple:n {single-format} +\NewAcroTemplate {alt} + { + \acroifTF {alt} + { \acrowrite {alt} } + { \acrowrite {short} } + } -% acc supp: -\acro_declare_property:nn {acc_supp} {accsupp} +\NewAcroTemplate {show} + { + \iow_term:n {} + \iow_term:x + { + The~ acronym~ `\AcronymID'~ has~ the~ properties~ (without~ outer~ + braces): + } + \iow_term:n {} + \AcroPropertiesMap { \acroshow {##1} } + \iow_term:n {} + } -% tooltip: -\acro_declare_property_simple:n {tooltip} +% -------------------------------------------------------------------------- +% heading templates: +\NewAcroTemplate[heading] {none} { } -% before-citation: -\acro_declare_property_simple:n {before-citation} +\NewAcroTemplate[heading] {section} + { \section { \acrolistname } } -% after-citation: -\acro_declare_property_simple:n {after-citation} +\NewAcroTemplate[heading] {section*} + { \section* { \acrolistname } } -% citation -- this needs a bit more work: -\cs_new_protected:Npn \__acro_declare_citation:nw #1#2[#3]#4[#5]#6#7 \acro_stop: +\acro_if_komascript:T { - % no options: #1: ID, #2: property, #7 is blank - % 1 option: #1: ID, #4: property, #3: option, #5: \q_no_value - % 2 options: #1: ID: #6: property, #3: first option, #5: second option - \tl_if_blank:nTF {#7} + \NewAcroTemplate[heading] {addsec} + { \addsec { \acrolistname } } + } + +\cs_if_exist:NT \chapter + { + \NewAcroTemplate[heading] {chapter} + { \chapter { \acrolistname } } + \NewAcroTemplate[heading] {chapter*} + { \chapter* { \acrolistname } } + \acro_if_komascript:T { - \__acro_declare_citation_aux:nnnn {#1} - { \q_no_value } - { \q_no_value } - {#2} + \NewAcroTemplate[heading] {addchap} + { \addchap { \acrolistname } } } + } + +% -------------------------------------------------------------------------- +% list templates: +\NewAcroTemplate[list] {description} + { + \acroheading + \acropreamble + \begin {description} + \acronymsmapF + { + \item [ \acrowrite {short} \acroifT {alt} { / \acrowrite {alt} } ] + \acrowrite {list} + \acroifanyT {foreign,extra} {~(} + \acroifT {foreign} + { + \acrowrite {foreign} + \acroifT {extra} {,~} + } + \acroifT {extra} + { \acrowrite {extra} } + \acroifanyT {foreign,extra} {)} + \acropagefill + \acropages + { \acrotranslate {page} \nobreakspace } + { \acrotranslate {pages} \nobreakspace } + } + { \item \AcroRerun } + \end {description} + } + +\NewAcroTemplate[list] {tabular} + { + \AcroNeedPackage {array} + \acronymsmapF { - \quark_if_no_value:nTF {#5} + \AcroAddRow { - \__acro_declare_citation_aux:nnnx {#1} - { \q_no_value } - {#3} - { \tl_head:n {#4} } + \acrowrite {short} + \acroifT {alt} { / \acrowrite {alt} } + & + \acrowrite {list} + \acroifanyT {foreign,extra} {~(} + \acroifT {foreign} + { + \acrowrite {foreign} + \acroifT {extra} {,~} + } + \acroifT {extra} + { \acrowrite {extra} } + \acroifanyT {foreign,extra} {)} + \acropagefill + \acropages + { \acrotranslate {page} \nobreakspace } + { \acrotranslate {pages} \nobreakspace } + \tabularnewline } - { \__acro_declare_citation_aux:nnnn {#1} {#3} {#5} {#6} } } + { \AcroRerun } + \acroheading + \acropreamble + \par \noindent + \begin {tabular} {>{\bfseries}lp{.7\linewidth}} + \AcronymTable + \end {tabular} } -\cs_generate_variant:Nn \__acro_declare_citation:nw {V} -\keys_define:nn {acro/declare-acronym} +\NewAcroTemplate[list] {longtable} { - cite .code:n = - \__acro_declare_citation:Vw - \l__acro_current_id_str #1 [\q_no_value][\q_no_value] \scan_stop: \acro_stop: + \AcroNeedPackage {array} + \AcroNeedPackage {longtable} + \acronymsmapF + { + \AcroAddRow + { + \acrowrite {short} + \acroifT {alt} { / \acrowrite {alt} } + & + \acrowrite {list} + \acroifanyT {foreign,extra} {~(} + \acroifT {foreign} + { + \acrowrite {foreign} + \acroifT {extra} {,~} + } + \acroifT {extra} + { \acrowrite {extra} } + \acroifanyT {foreign,extra} {)} + \acropagefill + \acropages + { \acrotranslate {page} \nobreakspace } + { \acrotranslate {pages} \nobreakspace } + \tabularnewline + } + } + { \AcroRerun } + \acroheading + \acropreamble + \par \noindent + \begin {longtabu} {>{\bfseries}lp{.7\linewidth}} + \AcronymTable + \end {longtabu} } -\prop_gput:Nnn \g__acro_properties_prop {cite} {cite} - -% #1: ID -% #2: pre -% #3: post -% #4: citation key -\cs_new_protected:Npn \__acro_declare_citation_aux:nnnn #1#2#3#4 - { - \__acro_property_check:nn {#1} {cite} - \prop_put:Nnn \l__acro_citation_prop {#1} {#4} - \quark_if_no_value:nF {#2} - { \prop_put:Nnn \l__acro_citation_pre_prop {#1} {#2} } - \quark_if_no_value:nF {#3} - { \prop_put:Nnn \l__acro_citation_post_prop {#1} {#3} } - } -\cs_generate_variant:Nn \__acro_declare_citation_aux:nnnn {nnnx} -% TODO: -% add index entries, by default \index{<sort>@<short>} -% index: overwrite default <sort>@<short> entry completely -% index-sort: overwrite the <sort> part of <sort>@<short> entry - -% need to take care of custom index cmd, at least -% - \index{} -% - \index[]{} -% question is, though, if it should be the same one for all acronyms? -% I go for yes but would also add a `post' property that allows to add arbitrary -% TeX code after an acronym is typeset - -% index: -\acro_declare_property_simple:n {index} - -% index-sort: -\acro_declare_property_simple:n {index-sort} - -% index-cmd: -\acro_declare_property_simple:n {index-cmd} +\NewAcroTemplate[list] {longtabu} + { + \AcroNeedPackage {array} + \AcroNeedPackage {longtable} + \AcroNeedPackage {tabu} + \acronymsmapF + { + \AcroAddRow + { + \acrowrite {short} + \acroifT {alt} { / \acrowrite {alt} } + & + \acrowrite {list} + \acroifanyT {foreign,extra} {~(} + \acroifT {foreign} + { + \acrowrite {foreign} + \acroifT {extra} {,~} + } + \acroifT {extra} + { \acrowrite {extra} } + \acroifanyT {foreign,extra} {)} + \acropagefill + \acropages + { \acrotranslate {page} \nobreakspace } + { \acrotranslate {pages} \nobreakspace } + \tabularnewline + } + } + { \AcroRerun } + \acroheading + \acropreamble + \par \noindent + \begin {longtabu} {>{\bfseries}lX[l]} + \AcronymTable + \end {longtabu} + } + +\NewAcroTemplate [list] {lof} + { + \acroheading + \acropreamble + \acronopagerange + \let\l@acro\l@figure + \acronymsmapF + { + \contentsline {acro} + { + \numberline + { \acrowrite {short} \acroifT {alt} { / \acrowrite {alt} } } + { + \acrowrite {list} + \acroifT {foreign} + { \acrowrite {foreign} \acroifT {extra} {,~} } + \acroifT {extra} { \acrowrite {extra} } + \acroifanyT {foreign,extra} {)} + } + } + { \acropages {} {} } + {} + } + { \AcroRerun } + } -% -------------------------------------------------------------------------- -% acronym macros: -\cs_new_protected:Npn \__acro_define_acronym_macro:n #1 +\NewAcroTemplate [list] {toc} { - \bool_if:NT \l__acro_create_macros_bool + \acroheading + \acropreamble + \acronopagerange + \acronymsmapF { - \cs_if_exist:cTF {#1} + \contentsline { \acroifchapterTF {chapter} {section} } + { \acrowrite {short} \acroifT {alt} { / \acrowrite {alt} } } + {}{} + \contentsline { \acroifchapterF {sub} section } { - \bool_if:NTF \l__acro_strict_bool - { \cs_set:cpn {#1} { \ac {#1} \acro_xspace: } } - { \acro_serious_message:nn {macro} {#1} } + \acrowrite {list} + \acroifT {foreign} + { \acrowrite {foreign} \acroifT {extra} {,~} } + \acroifT {extra} { \acrowrite {extra} } + \acroifanyT {foreign,extra} {) } } - { \cs_new:cpn {#1} { \ac {#1} \acro_xspace: } } + { \acropages {} {} } + {} } + { \AcroRerun } } % -------------------------------------------------------------------------- -% internal acronym declaring function: -\cs_new_protected:Npn \acro_declare_acronym:nn #1#2 - { \acro_case_insensitive:Nnn \__acro_declare_acronym:nn {#1} {#2} } +% translations: +% list name +\DeclareAcroTranslation {list-name} + { + Fallback = Acronyms , + English = Acronyms , + French = Acronymes , + German = Abk\"urzungen , + Italian = Acronimi , + Portuguese = Acr\'onimos , + Spanish = Siglas , + Catalan = Sigles + } + +% page name +\DeclareAcroTranslation {page} + { + Fallback = p\abbrdot , + English = p\abbrdot , + French = p\abbrdot , + German = S\abbrdot , + Italian = p\abbrdot , + Portuguese = p\abbrdot , + Spanish = p\'ag\abbrdot , + Catalan = p\`ag\abbrdot + } + +% pages name +\DeclareAcroTranslation {pages} + { + Fallback = pp\abbrdot , + English = pp\abbrdot , + French = pp\abbrdot , + German = S\abbrdot , + Italian = pp\abbrdot , + Portuguese = pp\abbrdot , + Spanish = p\'ags\abbrdot , + Catalan = p\`ag\abbrdot + } + +% following page +\DeclareAcroTranslation {sequens} + { + Fallback = f\abbrdot , + English = f\abbrdot , + French = sq\abbrdot , + German = f\abbrdot , + Italian = s\abbrdot , + Portuguese = s\abbrdot , + Spanish = s\abbrdot , + Catalan = seq\abbrdot + } + +% following pages +\DeclareAcroTranslation {sequentes} + { + Fallback = ff\abbrdot , + English = ff\abbrdot , + French = sqq\abbrdot , + German = ff\abbrdot , + Italian = ss\abbrdot , + Portuguese = ss\abbrdot , + Spanish = ss\abbrdot , + Catalan = et seq\abbrdot + } + +% also +\DeclareAcroTranslation {also} + { + Fallback = also , + English = also , + French = aussi , + German = auch , + Italian = anche , + Portuguese = tamb\'{e}m , + Spanish = tambien , + Catalan = tamb\'{e} + } + +% or +\DeclareAcroTranslation {or} + { + Fallback = or , + English = or , + French = ou , + German = oder , + Italian = o , + Portuguese = ou , + Spanish = o , + Catalan = o + } + +% and +\DeclareAcroTranslation {and} + { + Fallback = and , + English = and , + French = et , + German = und , + Italian = e , + Portuguese = e , + Spanish = y , + Catalan = i + } + +% -------------------------------------------------------------------------- +\AcroModuleEnd +\AcroModule{upgrade}{ease upgrading from version 2} -\cs_new_protected:Npn \__acro_declare_acronym:nn #1#2 +% ---------------------------------------------------------------------------- +\msg_new:nnn {acro} {deprecated} { - \seq_gput_right:Nn \g__acro_declared_acronyms_seq {#1} - \bool_gset_true:N \g__acro_first_acronym_declared_bool - \str_set:Nn \l__acro_current_id_str {#1} - \acro_for_properties_do:n - { \bool_new:c {l__acro_ \l__acro_current_id_str _##1_set_bool} } - \keys_set:nn {acro/declare-acronym} {#2} - \bool_new:c {g__acro_#1_first_use_bool} - \bool_new:c {g__acro_#1_used_bool} - \bool_new:c {g__acro_#1_label_bool} - \bool_new:c {g__acro_#1_in_list_bool} - \seq_new:c {g__acro_#1_barriers_seq} - \seq_new:c {g__acro_#1_recorded_barriers_seq} - \bool_if:NF \l__acro_print_only_used_bool - { \bool_gset_true:c {g__acro_#1_in_list_bool} } - \__acro_create_page_records:n {#1} - \__acro_define_acronym_macro:n {#1} - \str_clear:N \l__acro_current_id_str - \acro_property_if_set:nnF {#1} {short} - { \acro_serious_message:nnn {missing} {#1} {short} } - \acro_property_if_set:nnF {#1} {long} - { \acro_serious_message:nnn {missing} {#1} {long} } - \__acro_log_acronym:n {#1} + On~ line~ \msg_line_number: : \\ + The~ #1~ `#2'~ is~ deprecated.~ Use~ #1~ `#3'~ instead . } - -% -------------------------------------------------------------------------- -% print the list: -% #1: list of classes -% #2: list of excluded classes -\keys_define:nn {acro/print-acronyms} +\msg_new:nnn {acro} {deprecated-function} + { The~ command~ #1~ is~ deprecated.~ Use~ #2 instead . } + +\msg_new:nnn {acro} {removed-function} + { The~ command~ #1~ has~ been~ removed. } + +\msg_new:nnn {acro} {removed} { - include-classes .tl_set:N = \l__acro_included_classes_tl , - exclude-classes .tl_set:N = \l__acro_excluded_classes_tl , - name .tl_set:N = \l__acro_list_name_tl , - heading .code:n = \__acro_set_list_heading:n {#1} , - sort .bool_set:N = \l__acro_sort_bool , - local-to-barriers .bool_set:N = \l__acro_use_barrier_bool + On~ line~ \msg_line_number: : \\ + The~ #1~ `#2'~ has~ been~ removed~ from~ acro. \\ + If~ you~ need~ it~ back~ please~ open~ an~ issue~ on~ \\ + https://github.com/cgnieder/acro/issues + \tl_if_blank:nF {#3} { \\ #3 } } -\cs_new_protected:Npn \acro_print_acronyms:n #1 +% ---------------------------------------------------------------------------- +% #1: type +% #2: old +% #3: new +\cs_new_protected:Npn \__acro_deprecation_warning:nnn #1#2#3 + { \msg_warning:nnnnn {acro} {deprecated} {#1} {#2} {#3} } +\cs_generate_variant:Nn \__acro_deprecation_warning:nnn {nne,nV} + +\acro_attribute_new:n {deprecated} +\acro_attribute_new:n {removed} + +\prg_new_conditional:Npnn \acro_if_deprecated:n #1 {p,T,F,TF} { - \group_begin: - % this is a cheap trick to prevent the \@noitemerr - % if one forgot to delete either the aux file or - % remove \printacronyms -- but it's local: - \cs_set:Npn \@noitemerr {} - \tl_clear:N \l__acro_included_classes_tl - \tl_clear:N \l__acro_excluded_classes_tl - \tl_if_blank:nF {#1} - { \keys_set:nn {acro/print-acronyms} {#1} } - \__acro_aux_file_now:n { \acro@print@list } - \bool_if:NT \l__acro_sort_bool - { \acro_sort_prop:NN \l__acro_short_prop \l__acro_sort_prop } - \acro_title_instance:VV - \l__acro_list_heading_cmd_tl - \l__acro_list_name_tl - \cs_if_exist:NTF \acro@printed@list - { - \acro_list_instance:VVV - \l__acro_list_instance_tl - \l__acro_included_classes_tl - \l__acro_excluded_classes_tl - } - { \@latex@warning@no@line {Rerun~to~get~acronym~list~right} } - \group_end: + \acro_attribute_if_set:nnTF {deprecated} {#1} + { \prg_return_true: } + { \prg_return_false: } } -% -------------------------------------------------------------------------- -% language support -\RequirePackage {translations} - -\cs_new_protected:Npn \__acro_declare_translation:www #1 \q_mark #2=#3 \q_stop - { - \tl_set:Nx \l__acro_tmpa_tl { \tl_trim_spaces:n {#1} } - \tl_set:Nx \l__acro_tmpb_tl { \tl_trim_spaces:n {#2} } - \tl_if_in:nnT {#3} {=} - {} % TODO: misplaced equal sign - \tl_set:Nx \l__acro_tmpc_tl { \tl_trim_spaces:n {#3} } - \__acro_declare_translation:VVV - \l__acro_tmpb_tl - \l__acro_tmpa_tl - \l__acro_tmpc_tl +\prg_new_conditional:Npnn \acro_if_removed:n #1 {p,T,F,TF} + { + \acro_attribute_if_set:nnTF {removed} {#1} + { \prg_return_true: } + { \prg_return_false: } } -% #1: key -% #2: lang -% #3: translation -\cs_new_protected:Npn \__acro_declare_translation:nnn #1#2#3 - { \DeclareTranslation {#1} {#2} {#3} } -\cs_generate_variant:Nn \__acro_declare_translation:nnn {VVV} +% #1: old +% #2: new +\cs_new_protected:Npn \acro_deprecate:nn #1#2 + { \acro_attribute_set:nnn {deprecated} {#1} {#2} } -% #1: key -% #2: csv list: { <lang1> = <translation1> , <lang2> = <translation2> } -\cs_new_protected:Npn \acro_declare_translation:nn #1#2 +% #1: old +\cs_new_protected:Npn \acro_remove:n #1 + { \acro_attribute_set:nnn {removed} {#1} {} } + +% #1: type +% #2: old +\cs_new_protected:Npn \acro_deprecation_warning:nn #1#2 { - \clist_map_inline:nn {#2} + \__acro_deprecation_warning:nne + {#1} + {#2} + { \acro_attribute_get:nn {deprecated} {#2} } + } + +% #1: type +% #2: old +% #3: additional text +\cs_new_protected:Npn \acro_removal_warning:nnn #1#2#3 + { \msg_warning:nnnnn {acro} {removed} {#1} {#2} {#3} } +\cs_generate_variant:Nn \acro_removal_warning:nnn {nV} + +% #1: type +% #2: old +\cs_new_protected:Npn \acro_removal_warning:nn #1#2 + { \msg_warning:nnnn {acro} {removed} {#1} {#2} } +\cs_generate_variant:Nn \acro_removal_warning:nn {nV} + +% ---------------------------------------------------------------------------- +% #1: id +% #2: property +% #3: value +\cs_set_protected:Npn \__acro_property_set:nnn #1#2#3 + { + \acro_if_deprecated:nT {#2} { - \tl_if_blank:nF {##1} - { \__acro_declare_translation:www #1 \q_mark ##1 \q_stop } + \acro_deprecation_warning:nn {property} {#2} + \__acro_property_remove_from_auxlist:ne {#1} + { \acro_attribute_get:nn {deprecated} {#2} } + \__acro_auxlist_add:en + { \acro_attribute_get:nn {deprecated} {#2} } + {#1=={#3}} + \acro_attribute_set:enn + { \acro_attribute_get:nn {deprecated} {#2} } + {#1} {#3} + } + \acro_if_removed:nT {#2} + { \acro_removal_warning:nn {property} {#2} } + \bool_lazy_and:nnT + { ! \acro_if_deprecated_p:n {#2} } + { ! \acro_if_removed_p:n {#2} } + { + \__acro_property_remove_from_auxlist:nn {#1} {#2} + \__acro_auxlist_add:nn {#2} {#1=={#3}} + \acro_attribute_set:nnn {#2} {#1} {#3} } } -% tokenlists using the translations: -\tl_set:Nn \l__acro_list_name_tl { \GetTranslation {acronym-list-name} } -\tl_set:Nn \l__acro_page_name_tl { \GetTranslation {acronym-page-name}\@\, } -\tl_set:Nn \l__acro_pages_name_tl { \GetTranslation {acronym-pages-name}\@\, } -\tl_set:Nn \l__acro_next_page_tl { \,\GetTranslation {acronym-next-page}\@ } -\tl_set:Nn \l__acro_next_pages_tl { \,\GetTranslation {acronym-next-pages}\@ } +\cs_generate_variant:Nn \acro_attribute_set:nnn {e} +\cs_generate_variant:Nn \__acro_auxlist_add:nn {e} +\cs_generate_variant:Nn \__acro_property_remove_from_auxlist:nn {ne} -% -------------------------------------------------------------------------- -% definition file: -\tl_const:Nn \c_acro_definition_file_name_tl {acro.definitions} -\tl_const:Nn \c_acro_definition_file_extension_tl {tex} +% #1: old +% #2: new +\cs_new_protected:Npn \acro_deprecated_property:nn #1#2 + { + \acro_deprecate:nn {#1} {#2} + \acro_property_declare:nnnnn + { \c_false_bool } + { \c_false_bool } + { \c_false_bool } + { \c_false_bool } + {#1} + } -\file_if_exist:nTF - { \c_acro_definition_file_name_tl .\c_acro_definition_file_extension_tl } +% #1: old +\cs_new_protected:Npn \acro_removed_property:n #1 { - \@onefilewithoptions - {\c_acro_definition_file_name_tl} [] [] - \c_acro_definition_file_extension_tl + \acro_remove:n {#1} + \acro_property_declare:nnnnn + { \c_false_bool } + { \c_false_bool } + { \c_false_bool } + { \c_false_bool } + {#1} } - { \acro_serious_message:n {definitions-missing} } -% -------------------------------------------------------------------------- -% allow for a configuration file: +% ---------------------------------------------------------------------------- +% #1: old +% #2: new +\cs_new_protected:Npn \acro_deprecate_function:NN #1#2 + { + \cs_set_protected:Npn #1 + { + \msg_error:nnnn {acro} {deprecated-function} {#1} {#2} + #2 + } + } -\file_if_exist:nT - { \l_acro_config_file_name_tl . \l_acro_config_file_extension_tl } +% #1: old +\cs_new_protected:Npn \acro_remove_function:N #1 { - \@onefilewithoptions - {\l_acro_config_file_name_tl} [] [] - \l_acro_config_file_extension_tl + \cs_set_protected:Npn #1 + { \msg_error:nnn {acro} {removed-function} {#1} } } +% ---------------------------------------------------------------------------- +% #1: new +% #2: value +\cs_new_protected:Npn \acro_deprecate_option:nn #1#2 + { + \__acro_deprecation_warning:nVn {option} \l_keys_key_str {#1} + \keys_set:nn {acro} { #1 = #2 } + } + +% #1: additional text +\cs_new_protected:Npn \acro_remove_option:n #1 + { \acro_removal_warning:nVn {option} \l_keys_key_str {#1} } + +\cs_new_protected:Npn \acro_remove_option: + { \acro_removal_warning:nV {option} \l_keys_key_str } + +% ---------------------------------------------------------------------------- +% old properties: +\acro_deprecated_property:nn {accsupp} {short-acc} +\acro_deprecated_property:nn {tooltip} {pdfcomment} +\acro_deprecated_property:nn {class} {tag} +\acro_deprecated_property:nn {foreign-lang} {foreign-babel} + +\acro_removed_property:n {long-pre} +\acro_removed_property:n {after-citation} +\acro_removed_property:n {index-cmd} + +% ---------------------------------------------------------------------------- +% old functions +\acro_remove_function:N \acflike +\acro_remove_function:N \acfplike +\acro_remove_function:N \acsingle +\acro_remove_function:N \Acsingle +\acro_remove_function:N \acpsingle +\acro_remove_function:N \Acpsingle + +\acro_remove_function:N \acpdfstring +\acro_remove_function:N \acpdfstringplural +\acro_remove_function:N \AcroRegisterTrailing + +\acro_deprecate_function:NN \acifused \acroifusedTF +\acro_deprecate_function:NN \aciffirst \acroiffirstTF +\acro_deprecate_function:NN \ProvideAcroEnding \DeclareAcroEnding + +\acro_remove_function:N \DeclareAcroListStyle +\acro_remove_function:N \DeclareAcroListHeading +\acro_remove_function:N \DeclareAcroFirstStyle +\acro_remove_function:N \DeclareAcroExtraStyle +\acro_remove_function:N \DeclareAcroPageStyle +\acro_remove_function:N \AcroRegisterTrailing + +% ---------------------------------------------------------------------------- +% old options: +\keys_define:nn {acro} + { + %%% package: + log .code:n = + \acro_remove_option:n + { You~ can~ use~ \acshow ~ to~ inspect~ an~ acronym~ instead . } , + messages .code:n = \acro_remove_option: , + macros .code:n = \acro_remove_option: , + xspace .code:n = \acro_remove_option: , + strict .code:n = \acro_remove_option: , + %%% behaviour: + hyperref .code:n = + \acro_deprecate_option:nn {make-links} {true} , + label .code:n = + \acro_deprecate_option:nn {labels} {true} , + only-used .code:n = + \acro_deprecate_option:nn {list/display} {used} , + mark-as-used .code:n = + \acro_deprecate_option:nn {use-only-first} {true} , + sort .code:n = + \acro_deprecate_option:nn {list/sort} {true} , + display-foreign .code:n = \acro_remove_option: , + cite .code:n = + \acro_deprecate_option:nn {cite/display} {#1} , + cite-cmd .code:n = + \acro_deprecate_option:nn {cite/cmd} {#1} , + group-citation .code:n = + \acro_deprecate_option:nn {cite/group} {true} , + cite-connect .code:n = + \acro_deprecate_option:nn {cite/pre} {#1} , + group-cite-connect .code:n = + \acro_deprecate_option:nn {cite/group/pre} {#1} , + group-cite-cmd .code:n = + \acro_remove_option:n {Maybe~ the~ option~ `cite/cmd'~ helps.} , + index .code:n = + \acro_deprecate_option:nn {index/use} {true} , + index-cmd .code:n = + \acro_deprecate_option:nn {index/cmd} {#1} , + short-format .code:n = + \acro_deprecate_option:nn {format/short} {#1} , + long-format .code:n = + \acro_deprecate_option:nn {format/long} {#1} , + foreign-format .code:n = + \acro_deprecate_option:nn {format/foreign} {#1} , + extra-format .code:n = + \acro_deprecate_option:nn {format/extra} {#1} , + single-format .code:n = \acro_remove_option: , + single-form .code:n = + \acro_deprecate_option:nn {single-style} {#1} , + first-long-format .code:n = + \acro_deprecate_option:nn {format/first-long} {#1} , + list-short-format .code:n = \acro_remove_option: , + list-long-format .code:n = + \acro_deprecate_option:nn {format/list} {#1} , + list-foreign-format .code:n = \acro_remove_option: , + override-list-format .code:n = \acro_remove_option: , + format-include-endings .code:n = + \acro_deprecate_option:nn {include-endings} {true} , + extra-style .code:n = \acro_remove_option: , + page-style.code:n = \acro_remove_option: , + pages .code:n = + \acro_deprecate_option:nn {pages/display} {#1} , + page-name .code:n = \acro_remove_option: , + pages-name .code:n = \acro_remove_option: , + following-page .code:n = + \acro_deprecate_option:nn {pages/seq} {true} , + following-pages .code:n = + \acro_deprecate_option:nn {pages/seq} {true} , + next-page .code:n = \acro_remove_option: , + next-pages .code:n = \acro_remove_option: , + uc-cmd .code:n = + \acro_deprecate_option:nn {uppercase/cmd} {#1} , + uppercase-short .code:n = + \acro_deprecate_option:nn {uppercase/short} {#1} , + tooltip .code:n = + \acro_deprecate_option:nn {pdfcomments/use} {#1} , + tooltip-cmd .code:n = + \acro_deprecate_option:nn {pdfcomments/cmd} {#1} , + use-barriers .code:n = \acro_remove_option: , + reset-at-barriers .code:n = + \acro_deprecate_option:nn {barriers/reset} {#1} , + activate-trailing-tokens .code:n = + \acro_deprecate_option:nn {trailing/activate} {#1} , + deactivate-trailing-tokens .code:n = + \acro_deprecate_option:nn {trailing/deactivate} {#1} , + %%% list options: + list-style .code:n = + \acro_deprecate_option:nn {list/template} {#1} , + list-heading .code:n = + \acro_deprecate_option:nn {list/heading} {#1} , + list-name .code:n = + \acro_deprecate_option:nn {list/name} {#1} , + list-caps .code:n = \acro_remove_option: , + print-acronyms/include-classes .code:n = + \acro_deprecate_option:nn {list/include} {#1} , + print-acronyms/exclude-classes .code:n = + \acro_deprecate_option:nn {list/exclude} {#1} , + print-acronyms/name .code:n = + \acro_deprecate_option:nn {list/name} {#1} , + print-acronyms/heading .code:n = + \acro_deprecate_option:nn {list/heading} {#1} , + print-acronyms/sort .code:n = + \acro_deprecate_option:nn {list/sort} {true} , + print-acronyms/local-to-barriers .code:n = + \acro_deprecate_option:nn {list/local} {true} + } + +% ---------------------------------------------------------------------------- +\AcroModuleEnd +% finish package: +\AtEndDocument { \acro_close_aux: \acro_do_rerun: } +%---------------------------------------------------------------------------- \file_input_stop: diff --git a/Master/texmf-dist/tex/latex/acro/acro2.sty b/Master/texmf-dist/tex/latex/acro/acro2.sty new file mode 100644 index 00000000000..c8eb1d6b996 --- /dev/null +++ b/Master/texmf-dist/tex/latex/acro/acro2.sty @@ -0,0 +1,4640 @@ +% -------------------------------------------------------------------------- +% the ACRO package +% +% Typeset Acronyms +% +% -------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/acro/ +% E-Mail: contact@mychemistry.eu +% -------------------------------------------------------------------------- +% Copyright 2011--2020 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% -------------------------------------------------------------------------- +% The acro package consists of the files +% - acro.sty, acro.definitions.tex, acro.cfg +% - acro-manual.tex, acro-manual.pdf, acro-manual.cls +% - acro.history, README +% -------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% -------------------------------------------------------------------------- +\RequirePackage{expl3,xparse,xtemplate,l3keys2e} +\RequirePackage{etoolbox} % for the document hooks + +\ProvidesExplPackage + {acro2} + {2020/03/07} + {2.11d} + {\csname c_acro_info_tl\endcsname} + +% -------------------------------------------------------------------------- +% warning and error messages: +\msg_new:nnn {acro} {undefined} + { + You've~ requested~ acronym~ `#1'~ \msg_line_context: \ but~ you~ + apparently~ haven't~ defined~ it,~ yet! \\ + Maybe~ you've~ misspelled~ `#1'? + } + +\msg_new:nnn {acro} {macro} + { + A~ macro~ with~ the~ csname~ `#1'~ already~ exists! \\ + Unless~ you~ set~ acro's~ option~ `strict'~ I~ won't~ redefine~ it~ + \msg_line_context: . + } + +\msg_new:nnn {acro} {replaced} + { + The~ #1~ `#2' ~you ~used~ \msg_line_context: \ is~ deprecated~ and~ has~ + been~ replaced~ by~ `#3'. ~Since~ I~ will~ not~ guarantee~ that~ #1~ `#2'~ + will~ be~ kept~ forever~ I~ strongly~ encourage~ you~ to~ switch! + } + +\msg_new:nnn {acro} {deprecated} + { + The~ #1~ `#2'~ you~ used~ \msg_line_context: \ is~ deprecated~and~ there~ + is~ no~ replacement.~ Since~ I~ will~ not~ guarantee~ that~ #1~ `#2'~ + will~ be~ kept~ forever~ I~ strongly~ encourage~ you~ to~ remove~ it~ + from~ your~ document. + } + +\msg_new:nnn {acro} {substitute-short} + { + There~ is~ no~ short~ form~ set~ for~ acronym~ `#1'! \\ + I~ am~ setting~ the~ short~ form~ equal~ to~ the~ ID~ `#1'. \\ + If~ that~ is~ not~ what~ you~ want~ make~ sure~ to~ add~ an~ explicit~ + short~ form. + } +\msg_new:nnn {acro} {ending-exists} + { + An~ ending~ with~ the~ name~ `#1'~ already~ exists! \\ \\ + I~ am~ overwriting~ the~ defaults. + } + +\msg_new:nnn {acro} {ending-before-acronyms} + { + You~ are~ using~ \token_to_str:N \ProvideAcroEnding \ after~ you've~ + declared~ at~ least~ one~ acronym.~ This~ will~ lead~ to~ trouble! \\ + Make~ sure~ to~ define~ endings~ before~ *any*~ acronym~ declarations! + } + +\msg_new:nnn {acro} {no-alternative} + { + There~ is~ no~ alternative~ form~ for~ acronym~ `#1'! \\ \\ + I~ am~ using~ the~ short~ form~ instead. + } + +\msg_new:nnn {acro} {unknown} + { + You're~ trying~ to~ use~ the~ #1~ `#2'~ \msg_line_context: . \\ + However,~ I~ do~ not~ know~ #1~ `#2'! \\ + If~ this~ is~ no~ typo~ please~ contact~ the~ package~ author. \\ \\ + I~ am~ going~ to~ use~ the~ #1~ `#3'~ instead. + } +\msg_new:nnn {acro} {definitions-missing} + { + I~ cannot~ find~ the~ file~ \c_acro_definition_file_name_tl + .\c_acro_definition_file_extension_tl !~ This~ file~ contains~ all~ + essential~ user~ commands~ of~ acro~ and~ is~ a~ crucial~ part~ of~ the~ + package!~ Please~ check~ your~ installation. + } + +% -------------------------------------------------------------------------- +% temporary variables +\tl_new:N \l__acro_tmpa_tl +\tl_new:N \l__acro_tmpb_tl +\tl_new:N \l__acro_tmpc_tl +\prop_new:N \l__acro_tmpa_prop +\prop_new:N \l__acro_tmpb_prop +\seq_new:N \l__acro_tmpa_seq +\seq_new:N \l__acro_tmpb_seq +\int_new:N \l__acro_tmpa_int +\int_new:N \l__acro_tmpb_int +\int_new:N \l__acro_tmpc_int +\int_new:N \l__acro_tmpd_int + +% -------------------------------------------------------------------------- +% variants of kernel commands +\cs_generate_variant:Nn \quark_if_no_value:nTF {V} +\cs_generate_variant:Nn \tl_put_right:Nn {NV,Nv} +\cs_generate_variant:Nn \tl_if_eq:nnT {V} +\cs_generate_variant:Nn \tl_if_eq:nnF {V} +\cs_generate_variant:Nn \seq_use:Nnnn {c} +\cs_generate_variant:Nn \seq_gset_split:Nnn {c} +\cs_generate_variant:Nn \seq_set_split:Nnn {NnV} +\cs_generate_variant:Nn \seq_if_in:NnT {NV} +\cs_generate_variant:Nn \seq_if_in:NnTF {Ne} +\cs_generate_variant:Nn \prop_put:Nnn {NnV,cnx,cnv} +\cs_generate_variant:Nn \prop_get:NnNTF {cnc} +\cs_generate_variant:Nn \prop_get:NnNF {cn,cnc} +\cs_generate_variant:Nn \prop_get:NnN {cnc} +\cs_generate_variant:Nn \cs_generate_variant:Nn {c} +\cs_generate_variant:Nn \str_case:nn {V} + +% -------------------------------------------------------------------------- +% variables: +\bool_new:N \l__acro_acc_supp_bool +\bool_new:N \l__acro_addto_index_bool +\bool_new:N \l__acro_capitalize_list_bool +\bool_new:N \g__acro_case_sensitive_bool +\bool_new:N \l__acro_citation_all_bool +\bool_new:N \l__acro_citation_first_bool +\bool_set_true:N \l__acro_citation_first_bool +\bool_new:N \l__acro_create_macros_bool +\bool_new:N \l__acro_custom_alt_format_bool +\bool_new:N \l__acro_custom_long_format_bool +\bool_new:N \l__acro_custom_short_format_bool +\bool_new:N \l__acro_custom_foreign_format_bool +\bool_new:N \l__acro_extra_punct_bool +\bool_new:N \l__acro_extra_use_brackets_bool +\bool_new:N \g__acro_first_acronym_declared_bool +\bool_new:N \l__acro_first_instance_bool +\bool_new:N \l__acro_first_only_short_bool +\bool_new:N \l__acro_first_only_long_bool +\bool_new:N \l__acro_first_reversed_bool +\bool_new:N \l__acro_first_switched_bool +\bool_new:N \l__acro_first_use_brackets_bool +\bool_new:N \l__acro_first_upper_bool +\bool_new:N \l__acro_following_page_bool +\bool_new:N \l__acro_following_pages_bool +\bool_new:N \l__acro_foreign_bool +\bool_set_true:N \l__acro_foreign_bool +\bool_new:N \l__acro_group_citation_bool +\bool_new:N \l__acro_hyperref_loaded_bool +\bool_new:N \l__acro_hyperref_use_bool +\bool_new:N \l__acro_include_endings_format_bool +\bool_new:N \l__acro_indefinite_bool +\bool_new:N \l__acro_in_list_bool +\bool_new:N \l__acro_is_included_bool +\bool_new:N \l__acro_is_excluded_bool +\bool_new:N \l__acro_list_all_pages_bool +\bool_set_true:N \l__acro_list_all_pages_bool +\bool_new:N \l__acro_list_reverse_long_extra_bool +\bool_new:N \l__acro_log_acronyms_bool +\bool_new:N \l__acro_log_acronyms_verbose_bool +\bool_new:N \l__acro_mark_as_used_bool +\bool_new:N \g__acro_mark_first_as_used_bool +\bool_new:N \l__acro_override_list_format_bool +\bool_new:N \l__acro_page_brackets_bool +\bool_new:N \l__acro_page_display_bool +\bool_new:N \l__acro_page_punct_bool +\bool_new:N \l__acro_place_label_bool +\bool_new:N \l__acro_print_only_used_bool +\bool_set_true:N \l__acro_print_only_used_bool +\bool_new:N \g__acro_reset_at_barrier_bool +\bool_new:N \l__acro_silence_bool +\bool_new:N \l__acro_single_use_bool +\bool_new:N \l__acro_sort_bool +\bool_set_true:N \l__acro_sort_bool +\bool_new:N \l__acro_strict_bool +\bool_new:N \l__acro_trailing_tokens_bool +\bool_new:N \l__acro_tooltip_bool +\bool_new:N \l__acro_tooltip_inside_bool +\bool_new:N \l__acro_upper_indefinite_bool +\bool_new:N \l__acro_upper_short_bool +\bool_new:N \l__acro_use_acronyms_bool +\bool_set_true:N \l__acro_use_acronyms_bool +\bool_new:N \l__acro_use_barrier_bool +\bool_new:N \g__acro_use_barriers_bool +\bool_new:N \l__acro_use_ending_form_bool +\bool_new:N \l__acro_use_note_bool +\bool_new:N \l__acro_xspace_bool + +\str_new:N \l__acro_current_id_str + +\tl_new:N \l__acro_list_entries_tl +\tl_new:N \l__acro_endings_tl +\tl_new:N \l__acro_trailing_tokens_tl +\tl_new:N \l__acro_included_classes_tl +\tl_new:N \l__acro_excluded_classes_tl +\tl_new:N \l__acro_ignore_tl +\tl_new:N \l__acro_default_indefinite_tl +\tl_set:Nn \l__acro_default_indefinite_tl {a} +\tl_new:N \l__acro_foreign_sep_tl +\tl_new:N \l__acro_extra_instance_tl +\tl_set:Nn \l__acro_extra_instance_tl {default} +\tl_new:N \l__acro_page_instance_tl +\tl_set:Nn \l__acro_page_instance_tl {none} +\tl_new:N \l__acro_page_name_tl +\tl_new:N \l__acro_pages_name_tl +\tl_new:N \l__acro_next_page_tl +\tl_new:N \l__acro_next_pages_tl +\tl_new:N \l__acro_list_instance_tl +\tl_set:Nn \l__acro_list_instance_tl {description} +\tl_new:N \l__acro_list_type_tl +\tl_new:N \l__acro_list_heading_cmd_tl +\tl_set:Nn \l__acro_list_heading_cmd_tl {section*} +\tl_new:N \l__acro_list_name_tl +\tl_new:N \l__acro_list_before_tl +\tl_new:N \l__acro_list_after_tl +\tl_new:N \l__acro_custom_short_format_tl +\tl_new:N \l__acro_first_between_tl +\tl_new:N \l__acro_citation_connect_tl +\tl_new:N \l__acro_between_group_connect_citation_tl +\tl_new:N \l__acro_extra_brackets_tl +\tl_new:N \l__acro_extra_punct_tl +\tl_new:N \l__acro_first_brackets_tl +\tl_new:N \l__acro_page_punct_tl +\tl_new:N \l__acro_page_brackets_tl +\tl_new:N \l__acro_last_page_tl +\tl_new:N \l__acro_current_page_tl +\tl_new:N \l__acro_list_table_tl +\tl_new:N \l__acro_list_table_spec_tl +\tl_new:N \l__acro_acc_supp_tl +\tl_new:N \l__acro_acc_supp_options_tl +\tl_new:N \l__acro_label_prefix_tl +\tl_set:Nn \l__acro_label_prefix_tl {ac:} +\tl_new:N \l__acro_index_short_tl +\tl_new:N \l__acro_first_instance_tl +\tl_set:Nn \l__acro_first_instance_tl {default} +\tl_new:N \l__acro_short_tl +\tl_new:N \l__acro_short_format_tl +\tl_new:N \l__acro_list_short_format_tl +\tl_new:N \l__acro_alt_tl +\tl_new:N \l__acro_alt_format_tl +\tl_new:N \l__acro_long_tl +\tl_new:N \l__acro_long_format_tl +\tl_new:N \l__acro_list_long_format_tl +\tl_new:N \l__acro_single_form_tl +\tl_set:Nn \l__acro_single_form_tl {long} +\tl_new:N \l__acro_extra_format_tl +\tl_new:N \l__acro_foreign_format_tl +\tl_new:N \l__acro_foreign_list_format_tl +\tl_set:Nn \l__acro_foreign_list_format_tl { \acroenparen } +\tl_new:N \l__acro_index_format_tl + +\skip_new:N \l__acro_page_space_skip + +\dim_new:N \l__acro_short_width_dim +\dim_set:Nn \l__acro_short_width_dim {3em} + +\int_new:N \g__acro_barrier_int + +\seq_new:N \l__acro_endings_seq +\seq_new:N \l__acro_actions_seq +\seq_new:N \g__acro_declared_acronyms_seq + +\prop_new:N \l__acro_citation_prop +\prop_new:N \l__acro_citation_pre_prop +\prop_new:N \l__acro_citation_post_prop +\prop_new:N \l__acro_pdfstring_alt_prop +\prop_new:N \l__acro_pdfstring_short_prop +\prop_new:N \g__acro_properties_prop +\prop_new:N \l__acro_trailing_tokens_prop +\prop_new:N \l__acro_trailing_actions_prop +\prop_new:N \l__acro_list_styles_prop +\prop_new:N \l__acro_list_headings_prop +\prop_new:N \l__acro_first_styles_prop +\prop_new:N \l__acro_extra_styles_prop +\prop_new:N \l__acro_page_styles_prop + +% -------------------------------------------------------------------------- +% logging: +\prg_new_conditional:Npnn \acro_if_log: {p,T,F,TF} + { + \bool_if:NTF \l__acro_log_acronyms_bool + { \prg_return_true: } + { \prg_return_false: } + } + +\keys_define:nn {acro} + { + log .choice: , + log / true .code:n = + \bool_set_true:N \l__acro_log_acronyms_bool + \bool_set_false:N \l__acro_log_acronyms_verbose_bool , + log / silent .meta:n = { log = true } , + log / verbose .code:n = + \bool_set_true:N \l__acro_log_acronyms_bool + \bool_set_true:N \l__acro_log_acronyms_verbose_bool , + log / false .code:n = + \bool_set_false:N \l__acro_log_acronyms_bool + \bool_set_false:N \l__acro_log_acronyms_verbose_bool , + log .default:n = true , + log .initial:n = false + } + +\cs_new:Npn \__acro_write_log:nn #1#2 { \ \ \ #1 ~ = ~ {#2} } +\cs_new:Npn \__acro_write_log_property:nnn #1#2#3 + { \__acro_write_log:nn {#2} { \__acro_property_get:nn {#3} {#1} } } + +\cs_new:Npn \__acro_ending_log_entry:nn #1#2 + { + | \\ + | \__acro_write_log_property:nnn {#1} {short-#2} {short_#2} \\ + | \__acro_write_log_property:nnn {#1} {short-#2-form} {short_#2_form} \\ + | \__acro_write_log_property:nnn {#1} {long-#2} {long_#2} \\ + | \__acro_write_log_property:nnn {#1} {long-#2-form} {long_#2_form} \\ + | \__acro_write_log_property:nnn {#1} {alt-#2} {alt_#2} \\ + | \__acro_write_log_property:nnn {#1} {alt-#2-form} {alt_#2_form} \\ + | \__acro_write_log_property:nnn {#1} {foreign-#2} {foreign_#2} \\ + | \__acro_write_log_property:nnn {#1} {foreign-#2-form} {foreign_#2_form} \\ + } + +\msg_new:nnn {acro} {log-acronym-verbose} + { + ================================================= \\ + | ~ \msg_info_text:n {acro}~ --~ defining~ new~ acronym: \\ + | \__acro_write_log:nn {ID} {#1} \\ + | \__acro_write_log_property:nnn {#1} {short} {short} \\ + | \__acro_write_log_property:nnn {#1} {long} {long} \\ + | \__acro_write_log_property:nnn {#1} {alt} {alt} \\ + | \__acro_write_log_property:nnn {#1} {sort} {sort} \\ + | \__acro_write_log_property:nnn {#1} {class} {class} \\ + | \__acro_write_log_property:nnn {#1} {list} {list} \\ + | \__acro_write_log_property:nnn {#1} {extra} {extra} \\ + | \__acro_write_log_property:nnn {#1} {foreign} {foreign} \\ + | \__acro_write_log_property:nnn {#1} {single} {single} \\ + | \__acro_write_log_property:nnn {#1} {pdfstring} {pdfstring} \\ + | \__acro_write_log_property:nnn {#1} {accsupp} {accsupp} \\ + | \__acro_write_log_property:nnn {#1} {tooltip} {tooltip} \\ + | \\ + | \__acro_write_log_property:nnn {#1} {short-indefinite} {short_indefinite} \\ + | \__acro_write_log_property:nnn {#1} {long-indefinite} {long_indefinite} \\ + | \__acro_write_log_property:nnn {#1} {alt-indefinite} {alt_indefinite} \\ + \seq_map_function:NN \l__acro_endings_seq \__acro_ending_log_entry:n + | \\ + | \__acro_write_log_property:nnn {#1} {short-format} {short_format} \\ + | \__acro_write_log_property:nnn {#1} {long-format} {long_format} \\ + | \__acro_write_log_property:nnn {#1} {first-long-format} {first_long_format} \\ + | \__acro_write_log_property:nnn {#1} {single-format} {single_format} \\ + | \__acro_write_log_property:nnn {#1} {foreign-lang} {foreign_lang} \\ + | \\ + | \__acro_write_log_property:nnn {#1} {cite} {citation} \\ + | \__acro_write_log_property:nnn {#1} {before-citation} {before_citation} \\ + | \__acro_write_log_property:nnn {#1} {after-citation} {after_citation} \\ + | \__acro_write_log_property:nnn {#1} {index} {index} \\ + | \__acro_write_log_property:nnn {#1} {index-sort} {index_sort} \\ + | \\ + | \__acro_write_log_property:nnn {#1} {long-pre} {long_pre} \\ + | \__acro_write_log_property:nnn {#1} {long-post} {long_post} \\ + | \__acro_write_log_property:nnn {#1} {post} {post} \\ + | \__acro_write_log_property:nnn {#1} {index-cmd} {index_cmd} \\ + | \__acro_write_log_property:nnn {#1} {first-style} {first_style} \\ + ================================================= + } + +\msg_new:nnn {acro} {log-acronym-silent} + { + ================================================= \\ + | ~ \msg_info_text:n {acro}~ --~ defining~ new~ acronym: \\ + | \__acro_write_log:nn {ID} {#1} \\ + | \__acro_write_log_property:nnn {#1} {short} {short} \\ + | \__acro_write_log_property:nnn {#1} {long} {long} \\ + | \__acro_write_log_property:nnn {#1} {alt} {alt} \\ + | \__acro_write_log_property:nnn {#1} {sort} {sort} \\ + | \__acro_write_log_property:nnn {#1} {class} {class} \\ + | \__acro_write_log_property:nnn {#1} {list} {list} \\ + | \__acro_write_log_property:nnn {#1} {extra} {extra} \\ + | \__acro_write_log_property:nnn {#1} {foreign} {foreign} \\ + | \__acro_write_log_property:nnn {#1} {cite} {citation} \\ + ================================================= + } + +\cs_new_protected:Npn \__acro_log_acronym:n #1 + { + \bool_if:NT \l__acro_log_acronyms_bool + { + \cs_set:Npn \__acro_ending_log_entry:n ##1 + { \__acro_ending_log_entry:nn {#1} {##1} } + \bool_if:NTF \l__acro_log_acronyms_verbose_bool + { \msg_log:nnn {acro} {log-acronym-verbose} {#1} } + { \msg_log:nnn {acro} {log-acronym-silent} {#1} } + } + } + +% -------------------------------------------------------------------------- +% message macros: +\cs_new:Npn \__acro_remove_backslash:N #1 + { \exp_after:wN \use_none:n \token_to_str:N #1 } + +\cs_new_protected:Npn \acro_new_message_commands:Nnnn #1#2#3#4 + { + \clist_map_inline:nn {#2} + { + \cs_new_protected:cpn { \__acro_remove_backslash:N #1 ##1 } + { + \bool_if:NTF \l__acro_silence_bool + { \use:c { \__acro_remove_backslash:N #3 n##1 } {acro} } + { \use:c { \__acro_remove_backslash:N #4 n##1 } {acro} } + } + } + } + +\acro_new_message_commands:Nnnn \acro_serious_message: {n,nn,nnn} + { \msg_warning: } + { \msg_error: } + +\acro_new_message_commands:Nnnn \acro_harmless_message: {n,nn,nnn,nnnn} + { \msg_info: } + { \msg_warning: } + +\cs_new_protected:Npn \acro_option_deprecated:nn #1#2 + { + \tl_if_blank:nTF {#2} + { \acro_harmless_message:nnn {deprecated} {option} {#1} } + { \acro_harmless_message:nnnn {replaced} {option} {#1} {#2} } + } +\cs_new_protected:Npn \acro_option_deprecated:n #1 + { \acro_option_deprecated:nn {#1} {} } + +\cs_new_protected:Npn \acro_command_deprecated:NN #1#2 + { + \tl_if_blank:nTF {#2} + { + \acro_harmless_message:nnn {deprecated} {command} + { \token_to_str:N #1 } + } + { + \acro_harmless_message:nnnn {replaced} {command} + { \token_to_str:N #1 } + { \token_to_str:N #2 } + } + } + +% -------------------------------------------------------------------------- +% small commands for use at various places +\cs_new:Npn \acro_no_break: { \tex_penalty:D 10000 \scan_stop: } + +\cs_new_protected:Npn \__acro_first_upper_case:n #1 + { \text_titlecase_first:n {#1} } +\cs_generate_variant:Nn \__acro_first_upper_case:n {x} + +\cs_new_eq:NN \acro_first_upper_case:n \__acro_first_upper_case:n + +% -------------------------------------------------------------------------- +\tl_new:N \l_acro_config_file_name_tl +\tl_new:N \l_acro_config_file_extension_tl + +\tl_set:Nn \l_acro_config_file_name_tl {acro} +\tl_set:Nn \l_acro_config_file_extension_tl {cfg} + +% options: +\keys_define:nn {acro} + { + messages .choice: , + messages / silent .code:n = + \bool_set_true:N \l__acro_silence_bool , + messages / loud .code:n = + \bool_set_false:N \l__acro_silence_bool , + messages .value_required:n = true , + config-file-name .tl_set:N = \l_acro_config_file_name_tl , + config-file-name .initial:n = acro , + config-file-extension .tl_set:N = \l_acro_config_file_extension_tl , + config-file-extension .initial:n = cfg , + accsupp .bool_set:N = \l__acro_acc_supp_bool , + accsupp-options .tl_set:N = \l__acro_acc_supp_options_tl , + tooltip .bool_set:N = \l__acro_tooltip_bool , + tooltip-cmd .code:n = \cs_set:Npn \__acro_tooltip_cmd:nn {#1} , + tooltip-cmd .value_required:n = true , + macros .bool_set:N = \l__acro_create_macros_bool , + xspace .bool_set:N = \l__acro_xspace_bool , + % xspace .code:n = \acro_option_deprecated:nn {xspace} {} , + strict .bool_set:N = \l__acro_strict_bool , + case-sensitive .bool_set:N = \g__acro_case_sensitive_bool , + case-sensitive .initial:n = true , + sort .bool_set:N = \l__acro_sort_bool , + short-format .code:n = + \tl_set:Nn \l__acro_short_format_tl {#1} + \tl_set_eq:NN \l__acro_alt_format_tl \l__acro_short_format_tl + \tl_set:Nn \l__acro_list_short_format_tl {#1} , + short-format .value_required:n = true , + alt-format .tl_set:N = \l__acro_alt_format_tl , + alt-format .value_required:n = true , + long-format .code:n = + \tl_set:Nn \l__acro_long_format_tl {#1} + \tl_set:Nn \l__acro_first_long_format_tl {#1} + \tl_set:Nn \l__acro_list_long_format_tl {#1} , + long-format .value_required:n = true , + first-long-format .code:n = + \tl_set:Nn \l__acro_first_long_format_tl {#1} , + first-long-format .value_required:n = true , + single-format .tl_set:N = \l__acro_single_format_tl , + single-format .value_required:n = true , + format-include-endings .bool_set:N = \l__acro_include_endings_format_bool , + display-foreign .bool_set:N = \l__acro_foreign_bool , + foreign-format .tl_set:N = \l__acro_foreign_format_tl , + foreign-format .value_required:n = true , + list-short-format .tl_set:N = \l__acro_list_short_format_tl , + list-short-format .value_required:n = true , + list-short-width .dim_set:N = \l__acro_short_width_dim , + list-short-width .value_required:n = true , + list-long-format .tl_set:N = \l__acro_list_long_format_tl , + list-long-format .value_required:n = true , + list-foreign-format .tl_set:N = \l__acro_foreign_list_format_tl , + list-foreign-format .value_required:n = true , + override-list-format .bool_set:N = \l__acro_override_list_format_bool , + override-list-format .initial:n = true , + extra-format .tl_set:N = \l__acro_extra_format_tl , + extra-format .value_required:n = true , + single .bool_set:N = \l__acro_single_use_bool , + single-form .tl_set:N = \l__acro_single_form_tl , + single-form .value_required:n = true , + first-style .code:n = \acro_set_first_style:n {#1} , + first-style .value_required:n = true , + extra-style .code:n = \acro_set_extra_style:n {#1} , + extra-style .value_required:n = true , + label .bool_set:N = \l__acro_place_label_bool , + label-prefix .tl_set:N = \l__acro_label_prefix_tl , + label-prefix .value_required:n = true , + pages .choice: , + pages / all .code:n = + \bool_set_true:N \l__acro_list_all_pages_bool , + pages / first .code:n = + \bool_set_true:N \l__acro_place_label_bool + \bool_set_false:N \l__acro_list_all_pages_bool , + pages .value_required:n = true , + page-ref .code:n = + \acro_option_deprecated:nn {page-ref} {page-style} + \acro_set_page_style:n {#1} , + page-style .code:n = \acro_set_page_style:n {#1} , + page-style .value_required:n = true , + page-name .tl_set:N = \l__acro_page_name_tl , + page-name .value_required:n = true , + pages-name .tl_set:N = \l__acro_pages_name_tl , + pages-name .value_required:n = true , + following-page .bool_set:N = \l__acro_following_page_bool , + following-pages .bool_set:N = \l__acro_following_pages_bool , + following-pages* .meta:n = + { following-page = #1 , following-pages = #1 } , + following-pages* .default:n = true , + next-page .tl_set:N = \l__acro_next_page_tl , + next-page .value_required:n = true , + next-pages .tl_set:N = \l__acro_next_pages_tl , + next-pages .value_required:n = true , + list-style .code:n = \acro_set_list_style:n {#1} , + list-style .value_required:n = true , + list-heading .code:n = \acro_set_list_heading:n {#1} , + list-heading .value_required:n = true , + list-name .tl_set:N = \l__acro_list_name_tl , + list-name .value_required:n = true , + hyperref .bool_set:N = \l__acro_hyperref_use_bool , + only-used .bool_set:N = \l__acro_print_only_used_bool , + mark-as-used .choice: , + mark-as-used / first .code:n = + \bool_gset_true:N \g__acro_mark_first_as_used_bool , + mark-as-used / any .code:n = + \bool_gset_false:N \g__acro_mark_first_as_used_bool , + mark-as-used .default:n = any , + list-caps .bool_set:N = \l__acro_capitalize_list_bool , + cite .choice: , + cite / all .code:n = + \bool_set_true:N \l__acro_citation_all_bool + \bool_set_true:N \l__acro_citation_first_bool , + cite / none .code:n = + \bool_set_false:N \l__acro_citation_all_bool + \bool_set_false:N \l__acro_citation_first_bool , + cite / first .code:n = + \bool_set_false:N \l__acro_citation_all_bool + \bool_set_true:N \l__acro_citation_first_bool , + cite .default:n = all , + cite-cmd .code:n = + \cs_set:Npn \__acro_citation_cmd:w {#1} , + cite-cmd .value_required:n = true , + group-cite-cmd .code:n = + \cs_set:Npn \__acro_group_citation_cmd:w {#1} , + group-cite-cmd .value_required:n = true , + group-citation .bool_set:N = \l__acro_group_citation_bool , + cite-connect .tl_set:N = \l__acro_citation_connect_tl , + cite-connect .initial:n = \nobreakspace , + cite-connect .value_required:n = true , + group-cite-connect .tl_set:N = \l__acro_between_group_connect_citation_tl , + group-cite-connect .initial:n = {,\nobreakspace} , + group-cite-connect .value_required:n = true , + index .bool_set:N = \l__acro_addto_index_bool , + index-cmd .code:n = + \cs_set:Npn \__acro_index_cmd:n {#1} , + index-cmd .value_required:n = true , + uc-cmd .code:n = + \cs_set_eq:NN \__acro_first_upper_case:n #1 , + uc-cmd .value_required:n = true , + uppercase-short .bool_set:N = \l__acro_upper_short_bool , + uppercase-short .initial:n = true + } + +\AtBeginDocument + { + \bool_if:NTF \l__acro_xspace_bool + { + \@ifpackageloaded {xspace} + { } + { \RequirePackage {xspace} } + \cs_new_eq:NN \acro_xspace: \xspace + } + { \cs_new:Npn \acro_xspace: {} } + } + +% -------------------------------------------------------------------------- +% we use xtemplate for different object types and with a different number of +% arguments; let's declare functions for usage later so we don't have to +% bother + +% objects with one argument: +\cs_new_protected:Npn \acro_page_number_instance:nn #1#2 + { \UseInstance {acro-page-number} {#1} {#2} } +\cs_generate_variant:Nn \acro_page_number_instance:nn {V} + +\cs_new_protected:Npn \acro_extra_instance:nn #1#2 + { \UseInstance {acro-extra} {#1} {#2} } +\cs_generate_variant:Nn \acro_extra_instance:nn {VV} + +\cs_new_protected:Npn \acro_title_instance:nn #1#2 + { \UseInstance {acro-title} {#1} {#2} } +\cs_generate_variant:Nn \acro_title_instance:nn {VV} + +% objects with two arguments: +\cs_new_protected:Npn \acro_list_instance:nnn #1#2#3 + { \UseInstance {acro-list} {#1} {#2} {#3} } +\cs_generate_variant:Nn \acro_list_instance:nnn {VVV} + +\cs_new_protected:Npn \acro_first_instance:nn #1#2 + { + \acro_property_if_set:nnTF {#1} {first-style} + { + \tl_set_eq:NN + \l__acro_tmpa_tl + \l__acro_first_style_tl + } + { + \tl_set_eq:NN + \l__acro_tmpa_tl + \l__acro_first_instance_tl + } + \acro_if_defined:nT {#1} + { + \use:x { + \UseInstance {acro-first} + { \exp_not:V \l__acro_tmpa_tl } + { \exp_not:n {#1} } + { \exp_not:n {#2} } + } + } + } +\cs_generate_variant:Nn \acro_first_instance:nn {nV} + +% -------------------------------------------------------------------------- +% hyperref support +\cs_new_eq:NN \acro_hyper_target:nn \use_ii:nn +\cs_new_eq:NN \acro_hyper_link:nn \use_ii:nn + +\cs_new_protected:Npn \acro_activate_hyperref_support: + { + \bool_lazy_and:nnT + { \l__acro_hyperref_loaded_bool } + { \l__acro_hyperref_use_bool } + { + \sys_if_engine_xetex:TF + { + \cs_set:Npn \acro_hyper_link:nn ##1##2 + { \hyperlink {##1} { \XeTeXLinkBox {##2} } } + } + { \cs_set_eq:NN \acro_hyper_link:nn \hyperlink } + \cs_set:Npn \acro_hyper_target:nn ##1##2 + { \raisebox {3ex} [0pt] { \hypertarget {##1} { } } ##2 } + } + } + +% #1: id +% #2: text +\cs_new_protected:Npn \__acro_make_link:nn #1#2 + { + \bool_lazy_and:nnTF + { \l__acro_hyperref_use_bool } + { \l__acro_hyperref_loaded_bool } + { + \acro_hyper_link:nn {#1} { \phantom {#2} } + \acro_if_is_single:nTF {#1} + { \hbox_overlap_left:n {#2} } + { \acro_color_link:n { \hbox_overlap_left:n {#2} } } + } + {#2} + } + +\cs_new:Npn \acro_color_link:n #1 + { + \cs_if_exist:NTF \hypersetup + { + \ifHy@colorlinks + \exp_after:wN \use_i:nn + \else + \ifHy@ocgcolorlinks + \exp_after:wN \use_i:nn + \else + \exp_after:wN \exp_after:wN \exp_after:wN \use_ii:nn + \fi + \fi + { \textcolor { \@linkcolor } {#1} } + {#1} + } + {#1} + } + +\AtBeginDocument{ + \cs_if_exist:NF \textcolor { \cs_new_eq:NN \textcolor \use_ii:nn } +} + +% -------------------------------------------------------------------------- +% output style of the first time an acronym is used + +% helper macros for the styles +% #1: short|long +% #2: id +% #3: long +\cs_new_protected:Npn \__acro_print_form_and_indefinite:nnn #1#2#3 + { + \group_begin: + \acro_for_all_trailing_tokens_do:n + { \acro_deactivate_trailing_action:n {##1} } + \str_case:nn {#1} + { + {long} { + \bool_lazy_or:nnT + { \l__acro_first_only_long_bool } + { !\l__acro_first_only_short_bool } + { + \acro_write_indefinite:nn {#2} {long} + \acro_write_expanded:nnn {#2} {first-long} {#3} + } + } + {short} { + \bool_lazy_or:nnT + { !\l__acro_first_only_long_bool } + { \l__acro_first_only_short_bool } + { + \acro_soft_upper: + \acro_write_indefinite:nn {#2} {short} + \acro_write_compact:nn {#2} {short} + } + } + } + \group_end: + } + +\cs_new_protected:Npn \__acro_open_bracket: + { + \bool_lazy_and:nnT + { !\l__acro_first_only_long_bool } + { !\l__acro_first_only_short_bool } + { + \acro_space: + \tl_if_blank:VF \l__acro_first_between_tl + { + \tl_use:N \l__acro_first_between_tl + \acro_space: + } + \bool_if:NT \l__acro_first_use_brackets_bool + { \tl_head:N \l__acro_first_brackets_tl } + } + } + +\cs_new_protected:Npn \__acro_close_bracket: + { + \bool_lazy_all:nT + { + { \l__acro_first_use_brackets_bool } + { !\l__acro_first_only_short_bool } + { !\l__acro_first_only_long_bool } + } + { \tl_tail:N \l__acro_first_brackets_tl } + } + +% #1: short|long +% #2: id +% #3: long +\cs_new_protected:Npn \__acro_print_form:nnn #1#2#3 + { + \str_case:nn {#1} + { + {long} { + \bool_lazy_or:nnT + { \l__acro_first_only_long_bool } + { !\l__acro_first_only_short_bool } + { + \group_begin: + \bool_set_false:N \l__acro_first_upper_bool + \acro_write_expanded:nnn {#2} {first-long} {#3} + \group_end: + } + } + {short} { + \bool_lazy_or:nnT + { !\l__acro_first_only_long_bool } + { \l__acro_first_only_short_bool } + { + \group_begin: + \acro_soft_upper: + \acro_write_compact:nn {#2} {short} + \group_end: + } + } + } + } + +% #1: id +\cs_new_protected:Npn \__acro_foreign_sep:n #1 + { + \bool_lazy_all:nT + { + { \l__acro_foreign_bool } + { !\l__acro_first_only_short_bool } + { !\l__acro_first_only_long_bool } + } + { \acro_if_foreign:nT {#1} { \tl_use:N \l__acro_foreign_sep_tl } } + } + +% #1: id +\cs_new_protected:Npn \__acro_print_foreign:n #1 + { + \acro_if_foreign:nT {#1} + { + \bool_lazy_all:nT + { + { \l__acro_foreign_bool } + { !\l__acro_first_only_short_bool } + { !\l__acro_first_only_long_bool } + } + { + \acro_write_foreign:n {#1} + \acro_endings:nn {#1} {foreign} + } + } + } + +\cs_new_protected:Npn \__acro_print_citation:n #1 + { + \bool_if:NT \l__acro_group_citation_bool + { \acro_group_cite:n {#1} } + } + +\cs_new_protected:Npn \__acro_finalize_first:n #1 + { + \bool_if:NF \l__acro_group_citation_bool + { \acro_cite_if:Nn \l__acro_citation_first_bool {#1} } + \acro_index_if:Nn \l__acro_addto_index_bool {#1} + \acro_property_get:nnT {#1} {post} + { \tl_use:N \l__acro_post_tl } + } + +% -------------------------------------------------------------------------- +% the `acro-first' object, templates, instances: +% #1: id +% #2: long +\DeclareObjectType {acro-first} {2} + +% template for inline appearance: +\DeclareTemplateInterface {acro-first} {inline} {2} + { + brackets : boolean = true , + brackets-type : tokenlist = () , + only-short : boolean = false , + only-long : boolean = false , + reversed : boolean = false , + between : tokenlist , + foreign-sep : tokenlist = {,~} + } +\DeclareTemplateCode {acro-first} {inline} {2} + { + brackets = \l__acro_first_use_brackets_bool , + brackets-type = \l__acro_first_brackets_tl , + only-short = \l__acro_first_only_short_bool , + only-long = \l__acro_first_only_long_bool , + reversed = \l__acro_first_reversed_bool , + between = \l__acro_first_between_tl , + foreign-sep = \l__acro_foreign_sep_tl + } + { + \AssignTemplateKeys + \bool_set_true:N \l__acro_first_instance_bool + \bool_if:NTF \l__acro_first_reversed_bool + { % zuerst kurze Form, dann lange Form: + \__acro_print_form_and_indefinite:nnn {short} {#1} {#2} + \__acro_open_bracket: + \__acro_print_foreign:n {#1} + \__acro_foreign_sep:n {#1} + \__acro_print_form:nnn {long} {#1} {#2} + \__acro_print_citation:n {#1} + \__acro_close_bracket: + \__acro_finalize_first:n {#1} + } + { % zuerst lange Form, dann kurze Form: + \__acro_print_form_and_indefinite:nnn {long} {#1} {#2} + \__acro_open_bracket: + \__acro_print_foreign:n {#1} + \__acro_foreign_sep:n {#1} + \__acro_print_form:nnn {short} {#1} {#2} + \__acro_print_citation:n {#1} + \__acro_close_bracket: + \__acro_finalize_first:n {#1} + } + } + +% template for footnotes, sidenotes, ... +\cs_new:Npn \__acro_note_command:n #1 {#1} +\DeclareTemplateInterface {acro-first} {note} {2} + { + use-note : boolean = true , + note-command : function 1 = \footnote {#1} , + foreign-sep : tokenlist = {,~} , + reversed : boolean = false , + } + +\DeclareTemplateCode {acro-first} {note} {2} + { + use-note = \l__acro_use_note_bool , + note-command = \__acro_note_command:n , + foreign-sep = \l__acro_foreign_sep_tl , + reversed = \l__acro_first_reversed_bool + } + { + \AssignTemplateKeys + \bool_if:NTF \l__acro_first_reversed_bool + { % long in text and short in note + \__acro_print_form_and_indefinite:nnn {long} {#1} {#2} + \bool_if:NT \l__acro_use_note_bool + { + \__acro_note_command:n + { + \__acro_print_foreign:n {#1} + \__acro_foreign_sep:n {#1} + \__acro_print_form:nnn {short} {#1} {#2} + \__acro_print_citation:n {#1} + \__acro_finalize_first:n {#1} + } + } + } + { % short in text and long in note + \__acro_print_form_and_indefinite:nnn {short} {#1} {#2} + \bool_if:NT \l__acro_use_note_bool + { + \__acro_note_command:n + { + \__acro_print_foreign:n {#1} + \__acro_foreign_sep:n {#1} + \__acro_print_form:nnn {long} {#1} {#2} + \__acro_print_citation:n {#1} + \__acro_finalize_first:n {#1} + } + } + } + } + +% -------------------------------------------------------------------------- +% declare new first styles: +\cs_new_protected:Npn \acro_declare_first_style:nnn #1#2#3 + { + \DeclareInstance {acro-first} {#1} {#2} {#3} + \prop_put:Nnn \l__acro_first_styles_prop {#1} {#2} + } + +% set a list style +\cs_new_protected:Npn \acro_set_first_style:n #1 + { + \prop_if_in:NnTF \l__acro_first_styles_prop {#1} + { \__acro_set_first_style:n {#1} } + { + \msg_warning:nnnnn {acro} {unknown} + {first~ style} + {#1} + {default} + \__acro_set_first_style:n {default} + } + } + +\cs_new_protected:Npn \__acro_set_first_style:n #1 + { + \tl_set:Nn \l__acro_first_instance_tl {#1} + \prop_get:NnN \l__acro_first_styles_prop {#1} \l__acro_tmpa_tl + } + +% -------------------------------------------------------------------------- +% formatting the extras information: +\DeclareObjectType {acro-extra} {1} + +\DeclareTemplateInterface {acro-extra} {inline} {1} + { + punct : boolean = false , + punct-symbol : tokenlist = {,} , + brackets : boolean = true , + brackets-type : tokenlist = () + } + +\DeclareTemplateCode {acro-extra} {inline} {1} + { + punct = \l__acro_extra_punct_bool , + punct-symbol = \l__acro_extra_punct_tl , + brackets = \l__acro_extra_use_brackets_bool , + brackets-type = \l__acro_extra_brackets_tl + } + { + \AssignTemplateKeys + \bool_if:NT \l__acro_extra_punct_bool + { \tl_use:N \l__acro_extra_punct_tl \tl_use:N \c_space_tl } + \bool_if:NT \l__acro_extra_use_brackets_bool + { \tl_head:N \l__acro_extra_brackets_tl } + \acro_write_long:Vn \l__acro_extra_format_tl {#1} + \bool_if:NT \l__acro_extra_use_brackets_bool + { \tl_tail:N \l__acro_extra_brackets_tl } + } + +% declare new extra styles: +\cs_new_protected:Npn \acro_declare_etxra_style:nnn #1#2#3 + { + \DeclareInstance {acro-etxra} {#1} {#2} {#3} + \prop_put:Nnn \l__acro_etxra_styles_prop {#1} {#2} + } + +% set an extra style +\cs_new_protected:Npn \acro_set_extra_style:n #1 + { + \prop_if_in:NnTF \l__acro_extra_styles_prop {#1} + { \__acro_set_extra_style:n {#1} } + { + \msg_warning:nnnnn {acro} {unknown} + {extra~ style} + {#1} + {default} + \__acro_set_extra_style:n {default} + } + } + +\cs_new_protected:Npn \__acro_set_extra_style:n #1 + { + \tl_set:Nn \l__acro_extra_instance_tl {#1} + \prop_get:NnN \l__acro_extra_styles_prop {#1} \l__acro_tmpa_tl + } + +\cs_new_protected:Npn \acro_declare_extra_style:nnn #1#2#3 + { + \DeclareInstance {acro-extra} {#1} {#2} {#3} + \prop_put:Nnn \l__acro_extra_styles_prop {#1} {#2} + } + +% -------------------------------------------------------------------------- +% outputting the page numbers: +\RequirePackage {zref-abspage} + +\cs_new_protected:Npn \__acro_create_page_records:n #1 + { + \seq_new:c { g__acro_#1_pages_seq } + \tl_new:c { g__acro_#1_recorded_pages_tl } + } + +\cs_new_protected:Npn \acro_hyper_page:n #1 { \use:n {#1} } + +\cs_new:Npn \acro_get_thepage:nnn #1#2#3 { \acro_hyper_page:n {#1} } +\cs_new:Npn \acro_get_thepage_from:N #1 + { \exp_after:wN \acro_get_thepage:nnn #1 } + +\cs_new:Npn \acro_get_page_number:nnn #1#2#3 {#2} +\cs_new:Npn \acro_get_page_number_from:N #1 + { \exp_after:wN \acro_get_page_number:nnn #1 } + +\cs_new:Npn \acro_get_abspage:nnn #1#2#3 {#3} +\cs_new:Npn \acro_get_abspage_from:N #1 + { \exp_after:wN \acro_get_abspage:nnn #1 } + +\cs_new:Npn \acro_page_range_comma: {} + +\cs_new_protected:Npn \acro_print_page_numbers:n #1 + { + \seq_if_empty:cF {g__acro_#1_pages_seq} + { + \bool_if:NTF \l__acro_list_all_pages_bool + { + % have the numbers changed? + \tl_set:Nx \l__acro_tmpa_tl + { \seq_use:cn {g__acro_#1_pages_seq} {|} } + \tl_if_eq:cNF {g__acro_#1_recorded_pages_tl} \l__acro_tmpa_tl + { + \@latex@warning@no@line + {Rerun~to~get~page~numbers~of~acronym~#1~in~acronym~list~right} + } + \tl_clear:N \l__acro_write_pages_tl + \tl_clear:N \l__acro_last_page_tl + \tl_clear:N \l__acro_current_page_tl + \seq_set_eq:Nc \l__acro_tmpb_seq { g__acro_#1_pages_seq } + \seq_remove_duplicates:N \l__acro_tmpb_seq + \seq_clear:N \l__acro_tmpa_seq + \cs_set_protected:Npn \acro_page_range_comma: + { \cs_set:Npn \acro_page_range_comma: { ,~ } } + % get the numbers: + \int_compare:nNnTF { \seq_count:N \l__acro_tmpb_seq } = { 1 } + { + \tl_use:N \l__acro_page_name_tl + \seq_get_right:cN { g__acro_#1_pages_seq } \l__acro_tmpa_tl + \acro_get_thepage_from:N \l__acro_tmpa_tl + } + { + \tl_use:N \l__acro_pages_name_tl + \seq_map_inline:cn { g__acro_#1_pages_seq } + { + \tl_if_blank:VTF \l__acro_last_page_tl + {% we're at the beginning + \seq_put_right:Nn \l__acro_tmpa_seq {##1} + \tl_set:Nn \l__acro_last_page_tl {##1} + } + {% we'at least at the second page + % current page: + \tl_set:Nn \l__acro_current_page_tl {##1} + % last page: + \seq_get_right:NN \l__acro_tmpa_seq \l__acro_last_page_tl + \tl_if_eq:NNTF \l__acro_current_page_tl \l__acro_last_page_tl + {% there were more than one appearance on the current page + \seq_put_right:Nn \l__acro_tmpa_seq {##1} + } + {% new page + \acro_determine_page_ranges:NNn + \l__acro_tmpa_seq + \l__acro_write_pages_tl + {##1} + } + } + } + \seq_if_empty:NF \l__acro_tmpa_seq + { + \acro_determine_page_ranges:NNV + \l__acro_tmpa_seq + \l__acro_write_pages_tl + \l__acro_current_page_tl + } + \tl_use:N \l__acro_write_pages_tl + \tl_clear:N \l__acro_write_pages_tl + } + } + { + \tl_use:N \l__acro_page_name_tl + \pageref{\l__acro_label_prefix_tl #1} + } + } + \seq_clear:N \l__acro_tmpa_seq + \seq_clear:N \l__acro_tmpb_seq + } + +\cs_new:Npn \acro_determine_page_ranges:NNn #1#2#3 + { + \seq_remove_duplicates:N #1 + % current page: + \int_set:Nn \l__acro_tmpa_int { \acro_get_abspage:nnn #3 } + \int_set:Nn \l__acro_tmpb_int { \acro_get_page_number:nnn #3 } + % last page: + \seq_get_right:NN #1 \l__acro_last_page_tl + \int_set:Nn \l__acro_tmpc_int + { \acro_get_abspage_from:N \l__acro_last_page_tl } + \int_set:Nn \l__acro_tmpd_int + { \acro_get_page_number_from:N \l__acro_last_page_tl } + \bool_lazy_and:nnTF + { + \int_compare_p:nNn + { \l__acro_tmpa_int - \l__acro_tmpc_int } + = + { \l__acro_tmpb_int - \l__acro_tmpd_int } + } + { + \int_compare_p:nNn + { \l__acro_tmpb_int - \l__acro_tmpd_int } = {1} + } + {% same kind of page numbering, one page ahead + % => possible range + \seq_put_right:Nn #1 {#3} + } + {% any possible range ended + \tl_put_right:Nn #2 { \acro_page_range_comma: } + \int_compare:nNnTF + { \seq_count:N #1 } > {2} + {% real range + \seq_get_left:NN #1 \l__acro_tmpa_tl + \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } + \bool_if:NTF \l__acro_following_pages_bool + { \tl_put_right:Nn #2 { \l__acro_next_pages_tl } } + { + \tl_put_right:Nn #2 { -- } + \seq_get_right:NN #1 \l__acro_tmpa_tl + \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } + } + } + { + \int_compare:nNnTF + { \seq_count:N #1 } = {2} + {% range of two pages + \seq_get_left:NN #1 \l__acro_tmpa_tl + \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } + \bool_if:NTF \l__acro_following_page_bool + { \tl_put_right:Nn #2 { \l__acro_next_page_tl } } + { + \tl_put_right:Nn #2 { ,~ } + \seq_get_right:NN #1 \l__acro_tmpa_tl + \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } + } + } + {% no range at all + \seq_get_right:NN #1 \l__acro_tmpa_tl + \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } + } + } + \seq_clear:N #1 + \seq_put_right:Nn #1 {#3} + } + } +\cs_generate_variant:Nn \acro_determine_page_ranges:NNn {NNV} + +% -------------------------------------------------------------------------- +\DeclareObjectType {acro-page-number} {1} + +\DeclareTemplateInterface {acro-page-number} {inline} {1} + { + display : boolean = true , + punct : boolean = false , + punct-symbol : tokenlist = {,} , + brackets : boolean = false , + brackets-type : tokenlist = () , + space : skip = .333333em plus .166666em minus .111111em + } + +\DeclareTemplateCode {acro-page-number} {inline} {1} + { + display = \l__acro_page_display_bool , + punct = \l__acro_page_punct_bool , + punct-symbol = \l__acro_page_punct_tl , + brackets = \l__acro_page_brackets_bool , + brackets-type = \l__acro_page_brackets_tl , + space = \l__acro_page_space_skip + } + { + \AssignTemplateKeys + \bool_if:NT \l__acro_page_display_bool + { + \bool_if:NT \l__acro_page_punct_bool + { \tl_use:N \l__acro_page_punct_tl } + % \tl_use:N \c_space_tl + \dim_compare:nNnF { \l__acro_page_space_skip } = { 0pt } + { \skip_horizontal:N \l__acro_page_space_skip } + \bool_if:NT \l__acro_page_brackets_bool + { \tl_head:N \l__acro_page_brackets_tl } + \acro_print_page_numbers:n {#1} + \bool_if:NT \l__acro_page_brackets_bool + { \tl_tail:N \l__acro_page_brackets_tl } + } + } + +% declare new page styles: +\cs_new_protected:Npn \acro_declare_page_style:nnn #1#2#3 + { + \DeclareInstance {acro-page-number} {#1} {#2} {#3} + \prop_put:Nnn \l__acro_page_styles_prop {#1} {#2} + } + +% set a page style +\cs_new_protected:Npn \acro_set_page_style:n #1 + { + \prop_if_in:NnTF \l__acro_page_styles_prop {#1} + { \__acro_set_page_style:n {#1} } + { + \msg_warning:nnnnn {acro} {unknown} + {page~ style} + {#1} + {none} + \__acro_set_page_style:n {none} + } + } + +\cs_new_protected:Npn \__acro_set_page_style:n #1 + { + \tl_set:Nn \l__acro_page_instance_tl {#1} + \prop_get:NnN \l__acro_page_styles_prop {#1} \l__acro_tmpa_tl + } + +% -------------------------------------------------------------------------- +% the title of the list: +\cs_new:Npn \acro_list_title_format:n #1 {#1} + +\DeclareObjectType {acro-title} {1} + +\DeclareTemplateInterface {acro-title} {sectioning} {1} + { name-format : function 1 = #1 } + +\DeclareTemplateCode {acro-title} {sectioning} {1} + { name-format = \acro_list_title_format:n } + { + \AssignTemplateKeys + \acro_list_title_format:n {#1} + } + +% set a list heading: +\cs_new_protected:Npn \acro_set_list_heading:n #1 + { + \prop_if_in:NnTF \l__acro_list_headings_prop {#1} + { \__acro_set_list_heading:n {#1} } + { + \msg_warning:nnnnn {acro} {unknown} + {list~ heading} + {#1} + {section*} + \__acro_set_list_heading:n {section*} + } + } + +\cs_new_protected:Npn \__acro_set_list_heading:n #1 + { \tl_set:Nn \l__acro_list_heading_cmd_tl {#1} } + +\cs_new_protected:Npn \acro_declare_list_heading:nn #1#2 + { + \prop_put:Nnn \l__acro_list_headings_prop {#1} {#2} + \DeclareInstance {acro-title} {#1} {sectioning} + { name-format = #2 {##1} } + } + +% -------------------------------------------------------------------------- +% typesetting the acronym list +\DeclareObjectType {acro-list} {2} + +% #1: id +% #2: excluded classes +\prg_new_protected_conditional:Npnn \acro_if_is_excluded:nn #1#2 {T,F,TF} + { + \bool_set_false:N \l__acro_is_excluded_bool + \tl_if_blank:nF {#2} + { + \acro_property_get:nnT {#1} {class} + { + \seq_set_split:NnV \l__acro_tmpa_seq {,} \l__acro_class_tl + \clist_map_inline:nn {#2} + { + \seq_if_in:NnT \l__acro_tmpa_seq {##1} + { \bool_set_true:N \l__acro_is_excluded_bool } + } + } + } + \bool_if:NTF \l__acro_is_excluded_bool + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: id +% #2: included classes +\prg_new_protected_conditional:Npnn \acro_if_is_included:nn #1#2 {T,F,TF} + { + \bool_set_false:N \l__acro_is_included_bool + \tl_if_blank:nTF {#2} + { \bool_set_true:N \l__acro_is_included_bool } + { + \acro_property_get:nnT {#1} {class} + { + \seq_set_split:NnV \l__acro_tmpa_seq {,} \l__acro_class_tl + \clist_map_inline:nn {#2} + { + \seq_if_in:NnT \l__acro_tmpa_seq {##1} + { \bool_set_true:N \l__acro_is_included_bool } + } + } + } + \bool_if:NTF \l__acro_is_included_bool + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: id +\cs_new_protected:Npn \__acro_list_entry_short:n #1 + { + \group_begin: + \acro_get:n {#1} + \acro_hyper_target:nn + {#1} + { + \acro_acc_supp:nn + {#1} + { + \bool_lazy_and:nnTF + { \l__acro_custom_short_format_bool } + { \l__acro_override_list_format_bool } + { \l__acro_custom_short_format_tl } + { \l__acro_list_short_format_tl } + { \__acro_property_get:nn {short} {#1} } + } + } + \group_end: + } + +% #1: id +\cs_new_protected:Npn \__acro_list_entry_long:n #1 + { + \group_begin: + \bool_if:NT \l__acro_capitalize_list_bool + { \bool_set_true:N \l__acro_first_upper_bool } + \acro_write_long:Vf \l__acro_list_long_format_tl + { + \prop_if_in:NnTF \l__acro_list_prop {#1} + { \__acro_property_get:nn {list} {#1} } + { \__acro_property_get:nn {long} {#1} } + } + \group_end: + \bool_if:NT \l__acro_foreign_bool + { \acro_get_foreign:n {#1} } + \acro_cite_if:Nn \l__acro_citation_all_bool {#1} + } + +% #1: id +\cs_new_protected:Npn \__acro_list_entry_extra:n #1 + { + \acro_property_get:nnT {#1} {extra} + { + \acro_extra_instance:VV + \l__acro_extra_instance_tl + \l__acro_extra_tl + } + } + +% #1: id +\cs_new_protected:Npn \__acro_list_entry_page:n #1 + { + \cs_if_exist:cT {acro@#1@once} + { + \acro_page_number_instance:Vn + \l__acro_page_instance_tl + {#1} + } + } + +% macro for retrieval of items in the list: +% #1: property +% #2: id +\cs_new_protected:Npn \acro_list_entry:nn #1#2 + { + \str_case:nnF {#1} + { + {short} { \__acro_list_entry_short:n {#2} } + {long} { \__acro_list_entry_long:n {#2} } + {extra} { \__acro_list_entry_extra:n {#2} } + {page} { \__acro_list_entry_page:n {#2} } + } + { \__acro_property_get:nn {#1} {#2} } + } + +% this macro may/should be redefined in templates: +% #1: short +% #2: long +% #3: extra +% #4: page number(s) +\cs_new_protected:Npn \acro_print_list_entry:nnnn #1#2#3#4 + { #1 #2 #3 #4 } + +\cs_new_protected:Npn \acro_for_all_acronyms_do:n #1 + { \prop_map_inline:Nn \l__acro_short_prop {#1} } + +% test, if acronyms should be printed or not; needs testing for in/excluded +% classes and options `only-used' and `single' -- this macro should be used in +% the template code for retrieving the list + +% #1: id +% #2: included classes +% #3: excluded classes +\prg_new_protected_conditional:Npnn \acro_if_entry:nnn #1#2#3 {T,F,TF} + { + \bool_lazy_or:nnTF + { + \bool_lazy_and_p:nn + { !\l__acro_single_use_bool } + { !\l__acro_print_only_used_bool } + } + { + \bool_lazy_and_p:nn + { \bool_if_p:c {g__acro_#1_in_list_bool} } + { + \bool_lazy_or_p:nn + { + \bool_lazy_and_p:nn + { \l__acro_single_use_bool } + { \cs_if_exist_p:c {acro@#1@twice} } + } + { + \bool_lazy_all_p:n + { + { !\l__acro_single_use_bool } + { \cs_if_exist_p:c {acro@#1@once} } + { \l__acro_print_only_used_bool } + } + } + } + } + { + \acro_if_is_excluded:nnTF {#1} {#3} + { \prg_return_false: } + { + \acro_if_is_included:nnTF {#1} {#2} + { + \bool_lazy_and:nnTF + { \g__acro_use_barriers_bool } + { \l__acro_use_barrier_bool } + { + \acro_if_in_barrier:nxTF {#1} + { \int_use:N \g__acro_barrier_int } + { \prg_return_true: } + { \prg_return_false: } + } + { \prg_return_true: } + } + { \prg_return_false: } + } + } + { \prg_return_false: } + } + +% this macro is used in templates for fetching all items to be printed; it +% collects all entries in a tl which then is used where needed +% +% #1: tl containing the entries +% #2: included classes +% #3: excluded classes +\cs_new_protected:Npn \acro_build_list_entries:Nnn #1#2#3 + { + \tl_clear:N #1 + \acro_for_all_acronyms_do:n + {% ##1: id; ##2: short form + \group_begin: + \acro_get:n {##1} + \acro_if_entry:nnnT {##1} {#2} {#3} + { + \tl_gput_right:Nn #1 + { + \acro_print_list_entry:nnnn + { \acro_list_entry:nn {short} {##1} } + { \acro_list_entry:nn {long} {##1} } + { \acro_list_entry:nn {extra} {##1} } + { \acro_list_entry:nn {page} {##1} } + } + } + \group_end: + } + } + +% this macro is used in templates for fetching all items to be printed: +\cs_new_protected:Npn \acro_list_items:nn #1#2 + { + \acro_build_list_entries:Nnn \l__acro_list_entries_tl {#1} {#2} + \tl_use:N \l__acro_list_entries_tl + } + +% -------------------------------------------------------------------------- +% declare templates for the list: +% `list' template: +\DeclareTemplateInterface {acro-list} {list} {2} + { + foreign-sep : tokenlist = {~} , + list : tokenlist = {description} , + reverse : boolean = false , + before : tokenlist = , + after : tokenlist = + } + +\DeclareTemplateCode {acro-list} {list} {2} + { + foreign-sep = \l__acro_foreign_sep_tl , + list = \l__acro_list_tl , + reverse = \l__acro_list_reverse_long_extra_bool , + before = \l__acro_list_before_tl , + after = \l__acro_list_after_tl + } + { + \AssignTemplateKeys + \bool_set_true:N \l__acro_in_list_bool + \acro_activate_hyperref_support: + \bool_if:NTF \l__acro_list_reverse_long_extra_bool + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { \item [##1] ##3 ##2 ##4 } + } + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { \item [##1] ##2 ##3 ##4 } + } + \use:x + { + \exp_not:V \l__acro_list_before_tl + \exp_not:N \begin { \exp_not:V \l__acro_list_tl } + \exp_not:n { \acro_list_items:nn {#1} {#2} } + \exp_not:N \end { \exp_not:V \l__acro_list_tl } + \exp_not:V \l__acro_list_after_tl + } + } + +% `list-of' template: +\DeclareTemplateInterface {acro-list} {list-of} {2} + { + foreign-sep : tokenlist = {~} , + style : tokenlist = {toc} , + reverse : boolean = false , + before : tokenlist = , + after : tokenlist = + } + +\DeclareTemplateCode {acro-list} {list-of} {2} + { + foreign-sep = \l__acro_foreign_sep_tl , + style = \l__acro_list_of_style , + reverse = \l__acro_list_reverse_long_extra_bool , + before = \l__acro_list_before_tl , + after = \l__acro_list_after_tl + } + { + \AssignTemplateKeys + \bool_set_true:N \l__acro_in_list_bool + \tl_if_eq:VnT \l__acro_page_instance_tl {none} + { \tl_set:Nn \l__acro_page_instance_tl {plain} } + \tl_set:Nn \l__acro_page_name_tl {} + \tl_set:Nn \l__acro_pages_name_tl {} + \acro_activate_hyperref_support: + \str_case:Vn \l__acro_list_of_style + { + {toc} + { % similar to the table of contents + \bool_if:NTF \l__acro_list_reverse_long_extra_bool + { + \cs_if_exist:NTF \chapter + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { + \contentsline{chapter}{##1}{}{} + \contentsline{section}{##3##2}{##4}{} + } + } + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { + \contentsline{section}{##1}{}{} + \contentsline{subsection}{##3##2}{##4}{} + } + } + } + { + \cs_if_exist:NTF \chapter + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { + \contentsline{chapter}{##1}{}{} + \contentsline{section}{##2##3}{##4}{} + } + } + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { + \contentsline{section}{##1}{}{} + \contentsline{subsection}{##2##3}{##4}{} + } + } + } + } + {lof} + { % similar to the list of figures + \cs_set_protected:Npn \l@acro + { \@dottedtocline {1} {1.5em} {\l__acro_short_width_dim} } + \bool_if:NTF \l__acro_list_reverse_long_extra_bool + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { \contentsline{acro}{\numberline{##1}{##3##2}}{##4}{} } + } + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { \contentsline{acro}{\numberline{##1}{##2##3}}{##4}{} } + } + } + } + \use:x + { + \exp_not:V \l__acro_list_before_tl + \exp_not:n { \acro_list_items:nn {#1} {#2} } + \exp_not:V \l__acro_list_before_tl + } + } + +% `table' template: +\DeclareTemplateInterface {acro-list} {table} {2} + { + table : tokenlist = tabular , + table-spec : tokenlist = lp{.7\linewidth} , + foreign-sep : tokenlist = {~} , + reverse : boolean = false , + before : tokenlist = , + after : tokenlist = + } + +\DeclareTemplateCode {acro-list} {table} {2} + { + table = \l__acro_list_table_tl , + table-spec = \l__acro_list_table_spec_tl , + foreign-sep = \l__acro_foreign_sep_tl , + reverse = \l__acro_list_reverse_long_extra_bool , + before = \l__acro_list_before_tl , + after = \l__acro_list_after_tl + } + { + \AssignTemplateKeys + \acro_activate_hyperref_support: + \bool_if:NTF \l__acro_list_reverse_long_extra_bool + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { ##1 & ##3 ##2 ##4 \tabularnewline } + } + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { ##1 & ##2 ##3 ##4 \tabularnewline } + } + \acro_build_list_entries:Nnn \l__acro_list_entries_tl {#1} {#2} + \use:x + { + \exp_not:V \l__acro_list_before_tl + \exp_not:N \begin { \exp_not:V \l__acro_list_table_tl } + { \exp_not:V \l__acro_list_table_spec_tl } + \exp_not:V \l__acro_list_entries_tl + \exp_not:N \end { \exp_not:V \l__acro_list_table_tl } + \exp_not:V \l__acro_list_after_tl + } + } + +% `extra-table' template: +\DeclareTemplateInterface {acro-list} {extra-table} {2} + { + table : tokenlist = tabular , + table-spec : tokenlist = llll , + foreign-sep : tokenlist = {~} , + reverse : boolean = false , + before : tokenlist = , + after : tokenlist = + } + +\DeclareTemplateCode {acro-list} {extra-table} {2} + { + table = \l__acro_list_table_tl , + table-spec = \l__acro_list_table_spec_tl , + foreign-sep = \l__acro_foreign_sep_tl , + reverse = \l__acro_list_reverse_long_extra_bool , + before = \l__acro_list_before_tl , + after = \l__acro_list_after_tl + } + { + \AssignTemplateKeys + \acro_activate_hyperref_support: + \bool_if:NTF \l__acro_list_reverse_long_extra_bool + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { ##1 & ##3 & ##2 & ##4 \tabularnewline } + } + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { ##1 & ##2 & ##3 & ##4 \tabularnewline } + } + \acro_build_list_entries:Nnn \l__acro_list_entries_tl {#1} {#2} + \use:x + { + \exp_not:V \l__acro_list_before_tl + \exp_not:N \begin { \exp_not:V \l__acro_list_table_tl } + { \exp_not:V \l__acro_list_table_spec_tl } + \exp_not:V \l__acro_list_entries_tl + \exp_not:N \end { \exp_not:V \l__acro_list_table_tl } + \exp_not:V \l__acro_list_after_tl + } + } + +% -------------------------------------------------------------------------- +% declare new list styles: +\cs_new_protected:Npn \acro_declare_list_style:nnn #1#2#3 + { + \DeclareInstance {acro-list} {#1} {#2} {#3} + \prop_put:Nnn \l__acro_list_styles_prop {#1} {#2} + } + +% set a list style +\cs_new_protected:Npn \acro_set_list_style:n #1 + { + \prop_if_in:NnTF \l__acro_list_styles_prop {#1} + { \__acro_set_list_style:n {#1} } + { + \msg_warning:nnnnn {acro} {unknown} + {list~ style} + {#1} + {description} + \__acro_set_list_style:n {description} + } + } + +\cs_new_protected:Npn \__acro_set_list_style:n #1 + { + \tl_set:Nn \l__acro_list_instance_tl {#1} + \prop_get:NnN \l__acro_list_styles_prop {#1} \l__acro_list_type_tl + } + +% -------------------------------------------------------------------------- +% case insensitivity of the ID: +\cs_new:Npn \acro_case_insensitive:n #1 + { + \bool_if:NTF \g__acro_case_sensitive_bool + { \tl_to_str:n {#1} } + { \str_lowercase:n {#1} } + } + +\cs_new_protected:Npn \acro_protected_case_insensitive:n #1 + { \acro_case_insensitive:n {#1} } + +\cs_new:Npn \acro_case_insensitive:Nn #1#2 + { \exp_args:Ne #1 { \acro_case_insensitive:n {#2} } } + +\cs_new:Npn \acro_case_insensitive:Nnn #1#2#3 + { \exp_args:Ne #1 { \acro_case_insensitive:n {#2} } {#3} } + +\cs_new_protected:Npn \acro_case_insensitive_command:Nnnn #1#2#3#4 + { \exp_args:Nnnx #1 {#2} {#3} { \acro_case_insensitive:n {#4} } } +\cs_generate_variant:Nn \acro_case_insensitive_command:Nnnn {c} + +% -------------------------------------------------------------------------- +% automatic typesetting, the internals of \ac: +% #1: id + +\cs_new_protected:Npn \acro_soft_upper: + { + \bool_if:NF \l__acro_upper_short_bool + { \bool_set_false:N \l__acro_first_upper_bool } + } + +\cs_new_protected:Npn \acro_use:n #1 + { + % get the acronym and the plural settings: + \acro_get:n {#1} + \acro_is_used:nTF {#1} + { + \acro_soft_upper: + % this is not the first time + \acro_write_indefinite:nn {#1} {short} + \acro_write_compact:nn {#1} {short} + \acro_after:n {#1} + } + { + % this is the first time + \bool_gset_true:c { g__acro_#1_first_use_bool } + \acro_if_is_single:nTF {#1} + { \acro_single:n {#1} } + { \acro_first_instance:nV {#1} \l__acro_long_tl } + } + } + +% single appearances: +\cs_new_protected:Npn \acro_single:n #1 + { + \acro_cite: + \acro_single_form:nV {#1} \l__acro_single_form_tl + \acro_after:n {#1} + } + +% #1: ID +% #2: long|first|<other> +\cs_new_protected:Npn \acro_single_form:nn #1#2 + { + \acro_write_indefinite:nn {#1} {#2} + \str_case:nnF {#2} + { + {long} { + \tl_if_blank:VT \l__acro_single_format_tl + { + \bool_if:NTF \l__acro_custom_long_format_bool + { + \tl_set_eq:NN + \l__acro_single_format_tl + \l__acro_custom_long_format_tl + } + { + \tl_set_eq:NN + \l__acro_single_format_tl + \l__acro_long_format_tl + } + } + \tl_if_blank:VT \l__acro_single_tl + { \tl_set_eq:NN \l__acro_single_tl \l__acro_long_tl } + % BUG: should that be \acro_write_expanded:nn ? + % \acro_write_expanded:nnn {#1} {#2} {\l__acro_single_tl} + \acro_write_long:VV \l__acro_single_format_tl \l__acro_single_tl + \acro_endings:nn {#1} {single} + \l__acro_long_post_tl + } + {first} { + \tl_if_blank:VF \l__acro_single_format_tl + { + \tl_set_eq:NN + \l__acro_first_long_format_tl + \l__acro_single_format_tl + } + \tl_if_blank:VT \l__acro_single_tl + { \tl_set_eq:NN \l__acro_single_tl \l__acro_long_tl } + \acro_first_instance:nV {#1} \l__acro_single_tl + } + } + { % other (e.g. short) + \acro_soft_upper: + \tl_if_blank:VF \l__acro_single_tl + { \tl_set_eq:cN {l__acro_#2_tl} \l__acro_single_tl } + \tl_if_blank:VF \l__acro_single_format_tl + { \tl_set_eq:cN {l__acro_#2_format_tl} \l__acro_single_format_tl } + \acro_write_compact:nn {#1} {#2} + } + } +\cs_generate_variant:Nn \acro_single_form:nn {nV} + +\prg_new_conditional:Npnn \acro_if_is_single:n #1 { p,T,TF } + { + \bool_lazy_or:nnTF + { !\l__acro_single_use_bool } + { \cs_if_exist_p:c {acro@#1@twice} } + { \prg_return_false: } + { \prg_return_true: } + } + +\cs_new_protected:Npn \acro_use_acronym:n #1 + { \use:c {bool_set_#1:N} \l__acro_mark_as_used_bool } + +% -------------------------------------------------------------------------- +% some helpers we'll need more often: +\prg_new_conditional:Npnn \acro_if_defined:n #1 {p,T,F,TF} + { + \seq_if_in:NeTF \g__acro_declared_acronyms_seq + { \acro_case_insensitive:n {#1} } + { \prg_return_true: } + { \prg_return_false: } + } + +\cs_new_protected:Npn \acro_defined:n #1 + { + \acro_if_defined:nF {#1} + { \acro_serious_message:nn {undefined} {#1} } + } + +% expandably gets property but doesn't transform property name -- internal +% name is needed +% #1: property +% #2: id +\cs_new:Npn \__acro_property_get:nn #1#2 + { \prop_item:cn {l__acro_#1_prop} {#2} } + +% #1: id +% #2: property +% #3: set case +% #4: not set case +\prg_new_protected_conditional:Npnn \acro_property_get:nn #1#2 {T,F,TF} + { + \tl_set:Nn \l__acro_tmpa_tl {#2} + \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} + \prop_get:cncTF + {l__acro_ \l__acro_tmpa_tl _prop} + {#1} + {l__acro_ \l__acro_tmpa_tl _tl} + { \prg_return_true: } + { \prg_return_false: } + } + +\cs_new_protected:Npn \acro_property_get:nn #1#2 + { \acro_property_get:nnTF {#1} {#2} {} {} } +\cs_generate_variant:Nn \acro_property_get:nn {V} + +% within this command one can refer to the current id with `#1' +\cs_new_protected:Npn \acro_add_action:n #1 + { \seq_put_right:Nn \l__acro_actions_seq {#1} } + +\cs_new_protected:Npn \__acro_get_actions:n #1 + { + \seq_map_inline:Nn \l__acro_actions_seq + { + \cs_set:Npn \__acro_action:n ####1 {##1} + \__acro_action:n {#1} + } + } + +\cs_new_protected:Npn \acro_get:n #1 + { + \bool_if:NF \l__acro_in_list_bool { \leavevmode } + \acro_activate_hyperref_support: + % short: + \acro_property_get:nn {#1} {short} + % alt: + \acro_property_get:nnF {#1} {alt} + { \tl_set_eq:NN \l__acro_alt_tl \l__acro_short_tl } + % long: + \acro_property_get:nn {#1} {long} + % foreign: + \acro_property_get:nn {#1} {foreign} + % foreign-lang: + \acro_property_get:nn {#1} {foreign-lang} + % extra: + \acro_property_get:nn {#1} {extra} + % single: + \acro_property_get:nn {#1} {single} + % first-style: + \acro_property_get:nn {#1} {first-style} + % formatting + \acro_property_get:nnTF {#1} {long-format} + { + \tl_set_eq:NN \l__acro_custom_long_format_tl \l__acro_long_format_tl + \bool_set_true:N \l__acro_custom_long_format_bool + } + { \bool_set_false:N \l__acro_custom_long_format_bool } + \acro_property_get:nn {#1} {first-long-format} + \acro_property_get:nnTF {#1} {format} + { + \tl_set_eq:NN \l__acro_custom_short_format_tl \l__acro_format_tl + \bool_set_true:N \l__acro_custom_short_format_bool + } + { \bool_set_false:N \l__acro_custom_short_format_bool } + \acro_property_get:nnTF {#1} {alt-format} + { + \tl_set_eq:NN \l__acro_custom_alt_format_tl \l__acro_alt_format_tl + \bool_set_true:N \l__acro_custom_alt_format_bool + } + { \bool_set_false:N \l__acro_custom_alt_format_bool } + \acro_property_get:nnTF {#1} {foreign-format} + { + \tl_set_eq:NN \l__acro_custom_foreign_format_tl \l__acro_foreign_format_tl + \bool_set_true:N \l__acro_custom_foreign_format_bool + } + { \bool_set_false:N \l__acro_custom_foreign_format_bool } + \acro_property_get:nn {#1} {single-format} + \acro_for_endings_do:n + { + \bool_if:cT {l__acro_##1_bool} + { \__acro_set_ending_for:nnn {##1} {#1} {long} } + } + \acro_property_get:nnF {#1} {long-post} + { \tl_clear:N \l__acro_long_post_tl } + \acro_property_get:nnT {#1} {long-pre} + { \tl_put_left:NV \l__acro_long_tl \l__acro_long_pre_tl } + \__acro_get_actions:n {#1} + } + +% -------------------------------------------------------------------------- +% plural endings and similar concepts: + +\cs_new_protected:Npn \acro_for_endings_do:n #1 + { \seq_map_inline:Nn \l__acro_endings_seq {#1} } + +% #1: ending +% #2: ID +\cs_new_protected:Npn \__acro_set_ending:nn #1#2 + { + \bool_if:cT {l__acro_#1_bool} + { + \__acro_set_ending_for:nnn {#1} {#2} {short} + \__acro_set_ending_for:nnn {#1} {#2} {alt} + \__acro_set_ending_for:nnn {#1} {#2} {long} + \__acro_set_ending_for:nnn {#1} {#2} {foreign} % XXX + } + } + +% this does nothing if a non-existent ending (#1) or non-existent form (#3) is +% input +% #1: ending +% #2: id +% #3: short|alt|long|foreign +\cs_new_protected:Npn \__acro_set_ending_for:nnn #1#2#3 + { + \acro_if_ending_form_exist:nnT {#1} {#3} + { + \bool_if:cTF + { c_ \prop_item:cn {l__acro_#3_#1_form_prop} {#2} _bool } + { \prop_get:cnc {l__acro_#3_#1_prop} {#2} {l__acro_#3_tl} } + { \prop_get:cnc {l__acro_#3_#1_prop} {#2} {l__acro_#3_#1_tl} } + } + } + +\cs_new_protected:Npn \__acro_set_endings:n #1 + { + \acro_for_endings_do:n + { \__acro_set_ending:nn {##1} {#1} } + } + +% #1: id +% #2: short|alt|… +\cs_new_protected:Npn \acro_get_ending_form:nn #1#2 + { + \acro_for_endings_do:n + { + \acro_if_ending_form_exist:nnT {##1} {#2} + { + \bool_lazy_and:nnT + { \use:c {l__acro_##1_bool} } + { \use:c { c_ \prop_item:cn {l__acro_#2_##1_form_prop} {#1} _bool } } + { \prop_get:cncF {l__acro_#2_##1_prop} {#1} {l__acro_#2_tl} {} } + } + } + } + +% #1: id +% #2: short|alt|… +\cs_new_protected:Npn \acro_endings:nn #1#2 + { + \group_begin: + \str_if_eq:nnTF {#2} {single} + { + \keys_set:nn {acro} + { long-format= \l__acro_single_format_tl } + \__acro_endings:nn {#1} {long} + } + { \__acro_endings:nn {#1} {#2} } + \group_end: + } + +\cs_new_protected:Npn \__acro_endings:nn #1#2 + { + \acro_for_endings_do:n + { + \__acro_set_ending_for:nnn {##1} {#1} {#2} + \bool_if:cT {l__acro_##1_bool} + { \__acro_ending_format:nn {#2} { \tl_use:c {l__acro_#2_##1_tl} } } + } + } + +% #1: long|short|alt +% #2: string +\cs_new_protected:Npn \__acro_ending_format:nn #1#2 + { + \bool_if:NTF \l__acro_include_endings_format_bool + { + \str_case:nn {#1} + { + {long} + { + \bool_if:NTF \l__acro_custom_long_format_bool + { \l__acro_custom_long_format_tl } + { + \bool_if:NTF \l__acro_first_instance_bool + { \l__acro_first_long_format_tl } + { \l__acro_long_format_tl } + } + } + {short} + { + \bool_if:NTF \l__acro_custom_short_format_bool + { \l__acro_custom_short_format_tl } + { \l__acro_short_format_tl } + } + {alt} + { + \bool_if:NTF \l__acro_custom_alt_format_bool + { \l__acro_custom_alt_format_tl } + { \l__acro_alt_format_tl } + } + {foreign} + { + \bool_if:NTF \l__acro_custom_foreign_format_bool + { \l__acro_custom_foreign_format_tl } + { \l__acro_foreign_format_tl } + } + } + } + { \use:n } + {#2} + } + +\prg_new_conditional:Npnn \acro_if_ending_exist:n #1 {p,T,F,TF} + { + \seq_if_in:NnTF \l__acro_endings_seq {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: ending +% #2: short|alt|… +\prg_new_conditional:Npnn \acro_if_ending_form_exist:nn #1#2 {p,T,F,TF} + { + \cs_if_exist:cTF {l__acro_#2_#1_prop} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: name +% #2: default short +% #3: default long +\cs_new_protected:Npn \acro_provide_ending:nnn #1#2#3 + { + \acro_if_ending_exist:nTF {#1} + { + \acro_harmless_message:nn {ending-exists} {#1} + % short variables + \acro_set_ending_variables:nnn {short} {#1} {#2} + % alt variables + \acro_set_ending_variables:nnn {alt} {#1} {#2} + % long variables + \acro_set_ending_variables:nnn {long} {#1} {#3} + % foreign variables % XXX + \acro_set_ending_variables:nnn {foreign} {#1} {#3} + } + { + % registering: + \bool_if:NT \g__acro_first_acronym_declared_bool + { \acro_serious_message:n {ending-before-acronyms} } + \seq_put_right:Nn \l__acro_endings_seq {#1} + \bool_new:c {l__acro_#1_bool} + % short variables + \acro_define_and_set_ending_variables:nnn {short} {#1} {#2} + % alt variables + \acro_define_and_set_ending_variables:nnn {alt} {#1} {#2} + % long variables + \acro_define_and_set_ending_variables:nnn {long} {#1} {#3} + % foreign variables % XXX + \acro_define_and_set_ending_variables:nnn {foreign} {#1} {#3} + % define setup command: + \tl_set:Nn \l__acro_tmpa_tl {#1} + \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} + \cs_new_protected:cpn {acro_ \l__acro_tmpa_tl :} + { \bool_set_true:c {l__acro_#1_bool} } + % acronym properties: + % short-<ending>: + \acro_declare_property:nnn {short_#1} {short-#1} + { + \prop_put:cnn {l__acro_short_#1_form_prop} {##1} {false} + \prop_put:cnx {l__acro_pdfstring_short_#1_prop} + {##1} { \prop_item:Nn \l__acro_short_prop {##1} \exp_not:n {##2} } + } + % short-<ending>-form: + \acro_declare_property_generic:nnn {short_#1_form} {short-#1-form} + { + \__acro_property_check:nn {##1} {short-#1-form} + \prop_put:cnn {l__acro_short_#1_form_prop} {##1} {true} + \prop_put:cnn {l__acro_short_#1_prop} {##1} {##2} + \prop_put:cnn {l__acro_pdfstring_short_#1_prop} {##1} {##2} + } + % alt-<ending>: + \acro_declare_property:nnn {alt_#1} {alt-#1} + { + \prop_put:cnn {l__acro_alt_#1_form_prop} {##1} {false} + \prop_put:cnx {l__acro_pdfstring_alt_#1_prop} + {##1} { \prop_item:Nn \l__acro_alt_prop {##1} \exp_not:n {##2} } + } + % alt-<ending>-form: + \acro_declare_property_generic:nnn {alt_#1_form} {alt-#1-form} + { + \__acro_property_check:nn {##1} {alt-#1-form} + \prop_put:cnn {l__acro_alt_#1_form_prop} {##1} {true} + \prop_put:cnn {l__acro_alt_#1_prop} {##1} {##2} + \prop_put:cnn {l__acro_pdfstring_alt_#1_prop} {##1} {##2} + } + % long-<ending>: + \acro_declare_property:nnn {long_#1} {long-#1} + { \prop_put:cnn {l__acro_long_#1_form_prop} {##1} {false} } + % long-<ending>-form: + \acro_declare_property_generic:nnn {long_#1_form} {long-#1-form} + { + \__acro_property_check:nn {##1} {long-#1-form} + \prop_put:cnn {l__acro_long_#1_form_prop} {##1} {true} + \prop_put:cnn {l__acro_long_#1_prop} {##1} {##2} + } + % foreign-<ending>: % XXX + \acro_declare_property:nnn {foreign_#1} {foreign-#1} + { \prop_put:cnn {l__acro_foreign_#1_form_prop} {##1} {false} } + % foreign-<ending>-form: % XXX + \acro_declare_property_generic:nnn {foreign_#1_form} {foreign-#1-form} + { + \__acro_property_check:nn {##1} {foreign-#1-form} + \prop_put:cnn {l__acro_foreign_#1_form_prop} {##1} {true} + \prop_put:cnn {l__acro_foreign_#1_prop} {##1} {##2} + } + % options: + % short-<ending>-ending + % alt-<ending>-ending + % long-<ending>-ending + % foreign-<ending>-ending % XXX + % <ending>-ending + \keys_define:nn {acro} + { + short-#1-ending .code:n = + \bool_if:NT \g__acro_first_acronym_declared_bool + { \acro_serious_message:n {ending-before-acronyms} } + \tl_set:cn {l__acro_default_short_#1_tl} {##1} , + alt-#1-ending .code:n = + \bool_if:NT \g__acro_first_acronym_declared_bool + { \acro_serious_message:n {ending-before-acronyms} } + \tl_set:cn {l__acro_default_alt_#1_tl} {##1} , + long-#1-ending .code:n = + \bool_if:NT \g__acro_first_acronym_declared_bool + { \acro_serious_message:n {ending-before-acronyms} } + \tl_set:cn {l__acro_default_long_#1_tl} {##1} , + foreign-#1-ending .code:n = + \bool_if:NT \g__acro_first_acronym_declared_bool + { \acro_serious_message:n {ending-before-acronyms} } + \tl_set:cn {l__acro_default_foreign_#1_tl} {##1} , + #1-ending .code:n = + \bool_if:NT \g__acro_first_acronym_declared_bool + { \acro_serious_message:n {ending-before-acronyms} } + \__acro_read_ending_settings:nww {#1} ##1// \acro_stop: + } + % pdfstrings: + % TODO: add long forms: + \prop_new:c {l__acro_pdfstring_short_#1_prop} + \cs_new:cpn {acro_pdf_string_short_#1:n} ##1 + { + \acro_if_star_gobble:nTF {##1} + { \use:e { \prop_item:cn {l__acro_pdfstring_short_#1_prop} } } + { \use:e {\prop_item:cn {l__acro_pdfstring_short_#1_prop} {##1} } } + } + \cs_new:cpn {acpdfstring#1} { \use:c {acro_pdf_string_short_#1:n} } + \prop_new:c {l__acro_pdfstring_alt_#1_prop} + \cs_new:cpn {acro_pdf_string_alt_#1:n} ##1 + { + \acro_if_star_gobble:nTF {##1} + { \prop_item:cn {l__acro_pdfstring_alt_#1_prop} } + { \prop_item:cn {l__acro_pdfstring_alt_#1_prop} {##1} } + } + \cs_new:cpn {acpdfstringalt#1} { \use:c {acro_pdf_string_alt_#1:n} } + } + } + +% #1: short|alt|long +% #2: ending name +% #3: default ending +\cs_new_protected:Npn \acro_define_and_set_ending_variables:nnn #1#2#3 + { + \acro_define_ending_variables:nn {#1} {#2} + \acro_set_ending_variables:nnn {#1} {#2} {#3} + } + +% #1: short|alt|long +% #2: ending name +\cs_new_protected:Npn \acro_define_ending_variables:nn #1#2 + { + \prop_new:c {l__acro_#1_#2_prop} + \prop_new:c {l__acro_#1_#2_form_prop} + \tl_new:c {l__acro_#1_#2_tl} + \tl_new:c {l__acro_default_#1_#2_tl} + } + +% #1: short|alt|long +% #2: ending name +% #3: default ending +\cs_new_protected:Npn \acro_set_ending_variables:nnn #1#2#3 + { \tl_set:cn {l__acro_default_#1_#2_tl} {#3} } + +% #1: ending name +% #2: short (and long if #4 is blank) +% #3: long +\cs_new_protected:Npn \__acro_read_ending_settings:nww #1#2/#3/#4 \acro_stop: + { + \acro_set_ending_variables:nnn {short} {#1} {#2} + \acro_set_ending_variables:nnn {alt} {#1} {#2} + \tl_if_blank:nTF {#4} + { + \acro_set_ending_variables:nnn {long} {#1} {#3} + \acro_set_ending_variables:nnn {foreign} {#1} {#3} + } + { + \acro_set_ending_variables:nnn {long} {#1} {#2} + \acro_set_ending_variables:nnn {foreign} {#1} {#2} + } + } + +% -------------------------------------------------------------------------- +% enable us to know if the acronym is used only once and provide a different +% style for that: +\prg_new_protected_conditional:Npnn \acro_is_used:n #1 { T,F,TF } + { + \acro_record_barrier:n {#1} + \bool_lazy_and:nnTF + { \bool_if_p:c {g__acro_#1_used_bool} } + { + \bool_lazy_or_p:nn + { + \bool_lazy_and_p:nn + { \bool_if_p:c {g__acro_#1_first_use_bool} } + { \g__acro_mark_first_as_used_bool } + } + { !\g__acro_mark_first_as_used_bool } + } + { + \bool_if:NTF \l__acro_mark_as_used_bool + { + \__acro_aux_file:Nxxxx \acro@used@twice + {#1} + { \thepage } + { \arabic {page} } + { \arabic {abspage} } + } + { \__acro_aux_file:Nxxxx \acro@used@twice {#1} {} {} {} } + \prg_return_true: + } + { + \bool_if:NTF \l__acro_mark_as_used_bool + { + \__acro_aux_file:Nxxxx \acro@used@once + {#1} + { \thepage } + { \arabic {page} } + { \arabic {abspage} } + \bool_lazy_and:nnT + { !\bool_if_p:c {g__acro_#1_label_bool} } + { \l__acro_place_label_bool } + { + \bool_gset_true:c { g__acro_#1_label_bool } + \label{\l__acro_label_prefix_tl #1} + } + \bool_gset_true:c { g__acro_#1_used_bool } + } + {} + % I can't remember why I want an empty first use case for starred + % acronyms… + % { \__acro_aux_file:Nxxxx \acro@used@once {#1} {} {} {} } + \prg_return_false: + } + } + +\cs_new:Npn \acro_is_used:n #1 + { \acro_is_used:nTF {#1} { } { } } + +\cs_new_protected:Npn \__acro_aux_file:Nnnnn #1#2#3#4#5 + { \iow_shipout:Nn \@auxout { #1 {#2} {#3} {#4} {#5} } } +\cs_generate_variant:Nn \__acro_aux_file:Nnnnn {Nxxxx} + +\cs_new_protected:Npn \__acro_aux_file_now:n #1 + { \iow_now:Nn \@auxout {#1} } +\cs_generate_variant:Nn \__acro_aux_file_now:n {x} + +% -------------------------------------------------------------------------- +% the commands for the auxiliary file: +\cs_new_protected:Npn \acro@used@once #1#2#3#4 + { + \cs_gset_nopar:cpn {acro@#1@once} {#1} + \bool_gset_true:c {g__acro_#1_in_list_bool} + \tl_if_empty:nF {#2#3#4} + { + % \bool_gset_true:c { g__acro_#1_used_bool } + \seq_gput_right:cn {g__acro_#1_pages_seq} { {#2}{#3}{#4} } + } + } +\cs_new_protected:Npn \acro@used@twice #1#2#3#4 + { + \cs_gset_nopar:cpn {acro@#1@twice} {#1} + \tl_if_empty:nF {#2#3#4} + { \seq_gput_right:cn {g__acro_#1_pages_seq} { {#2}{#3}{#4} } } + } + +\cs_new_protected:Npn \acro@pages #1#2 + { \tl_gset:cn {g__acro_#1_recorded_pages_tl} {#2} } + +\cs_new_protected:Npn \acro@rerun@check + { + \bool_if:NT \g__acro_rerun_bool + { + \@latex@warning@no@line + {Acronyms~ may~ have~ changed.~ Please~ rerun~ LaTeX} + } + } + +\AtEndDocument + { + \bool_gset_false:N \g__acro_rerun_bool + \cs_gset_protected:Npn \acro@used@once #1#2#3#4 + { + \tl_set:Nn \l__acro_tmpa_tl {#1} + \tl_if_eq:cNF {acro@#1@once} \l__acro_tmpa_tl + { \bool_gset_true:N \g__acro_rerun_bool } + } + \cs_gset_protected:Npn \acro@used@twice #1#2#3#4 + { + \tl_set:Nn \l__acro_tmpa_tl {#1} + \tl_if_eq:cNF {acro@#1@twice} \l__acro_tmpa_tl + { \bool_gset_true:N \g__acro_rerun_bool } + } + \acro_for_all_acronyms_do:n + { + \seq_if_empty:cF {g__acro_#1_pages_seq} + { + \__acro_aux_file_now:x + { + \acro@pages {#1} + { \seq_use:cn {g__acro_#1_pages_seq} {|} } ^^J + \acro@barriers {#1} + { \seq_use:cn {g__acro_#1_barriers_seq} {,} } + } + } + \acro_check_barriers:n {#1} + } + \__acro_aux_file_now:n { \acro@rerun@check } + } + +% if `acro' is deactivated prevent unnecessary errors from aux file: +\if@filesw +\AtBeginDocument + { + \__acro_aux_file_now:n + { + \providecommand \acro@used@once [4] {} ^^J + \providecommand \acro@used@twice [4] {} ^^J + \providecommand \acro@pages [2] {} ^^J + \providecommand \acro@rerun@check {} ^^J + \providecommand \acro@print@list {} ^^J + \providecommand \acro@barriers [2] {} + } + } +\fi + +% -------------------------------------------------------------------------- +% #1: short|alt|long +% #2: string to be typeset +\cs_new_protected:Npn \__acro_typeset:nn #1#2 + { + \mode_if_horizontal:F { \leavevmode } + \group_begin: + \use:x + { + \bool_if:cTF {l__acro_custom_#1_format_bool} + { \exp_not:v {l__acro_custom_#1_format_tl} } + { \exp_not:v {l__acro_#1_format_tl} } + {#2} + } + \group_end: + } + +% typeset the short form: +% #1: ID +% #2: short form +\cs_new_protected:Npn \acro_write_short:nn #1#2 + { + \__acro_make_link:nn {#1} + { + \__acro_typeset:nn {short} + { + \bool_if:NTF \l__acro_first_upper_bool + { \exp_not:N \__acro_first_upper_case:n { \exp_not:n {#2} } } + { \exp_not:n {#2} } + } + } + } +\cs_generate_variant:Nn \acro_write_short:nn {nV,nv} + +% typeset the alternative form: +% #1: ID +% #2: alt form +\cs_new_protected:Npn \acro_write_alt:nn #1#2 + { + \__acro_make_link:nn {#1} + { + \__acro_typeset:nn {alt} + { + \bool_lazy_and:nnTF + { \l__acro_first_upper_bool } + { \l__acro_upper_short_bool } + { \exp_not:N \__acro_first_upper_case:n { \exp_not:n {#2} } } + { \exp_not:n {#2} } + } + } + } +\cs_generate_variant:Nn \acro_write_alt:nn {nV,nv} + +% typeset a long form: +% TODO: rethink the formatting mechanism +% right now a custom format gets applied additionally to the global one +% although before it +% #1: format +% #2: long form +\cs_new_protected:Npn \acro_write_long:nn #1#2 + { + \__acro_typeset:nn {long} + { + \exp_not:n {#1} + { + \bool_if:NTF \l__acro_first_upper_bool + { \exp_not:N \__acro_first_upper_case:n { \exp_not:n {#2} } } + { \exp_not:n {#2} } + } + } + } +\cs_generate_variant:Nn \acro_write_long:nn {VV,Vo,Vf,V,v,vv} + +\prg_new_conditional:Npnn \acro_if_foreign:n #1 {T,F,TF} + { + \bool_lazy_and:nnTF + { \l__acro_foreign_bool } + { \prop_if_in_p:Nn \l__acro_foreign_prop {#1} } + { \prg_return_true: } + { \prg_return_false: } + } + +\cs_new_protected:Npn \acro_foreign_language:nn #1#2 {} +\AtBeginDocument{ + \cs_if_exist:NTF \foreignlanguage + { + \cs_set_protected:Npn \acro_foreign_language:nn #1#2 + { + \tl_if_blank:nTF {#1} + {#2} + { \foreignlanguage {#1} {#2} } + } + } + { + \cs_set_protected:Npn \acro_foreign_language:nn #1#2 + { \use_ii:nn {#1} {#2} } + } +} +\cs_generate_variant:Nn \acro_foreign_language:nn {VV} + +\cs_new_protected:Npn \acro_write_foreign:n #1 + { + \acro_if_foreign:nT {#1} + { + \acro_property_get:nnT {#1} {foreign} + { + \group_begin: + \__acro_endings:nn {#1} {foreign} + \tl_use:N \l__acro_foreign_format_tl + { + \acro_foreign_language:VV + \l__acro_foreign_lang_tl + \l__acro_foreign_tl + } + \group_end: + } + } + } + +\cs_new:Npn \acroenparen #1 { (#1) } + +\cs_new_protected:Npn \acro_get_foreign:n #1 + { + \acro_property_get:nnT {#1} {foreign} + { + \tl_use:N \l__acro_foreign_sep_tl + \group_begin: + \tl_use:N \l__acro_foreign_list_format_tl + { + \acro_foreign_language:VV + \l__acro_foreign_lang_tl + \l__acro_foreign_tl + } + \group_end: + } + } + +% -------------------------------------------------------------------------- +% #1: id +% #2: short|alt +\cs_set_protected:Npn \acro_write_compact:nn #1#2 + { + \acro_get_ending_form:nn {#1} {#2} + \acro_acc_supp:nn + {#1} + { + \acro_write_tooltip:nnV + {#1} + { + \use:c {acro_write_#2:nv} {#1} {l__acro_#2_tl} + \acro_endings:nn {#1} {#2} + } + \l__acro_long_tl + } + } + +% TODO: get rid of argument #3? +% #1: ID +% #2: long|first-long|list-long|extra +% #3: long form +\cs_new_protected:Npn \acro_write_expanded:nnn #1#2#3 + { + \tl_set:Nn \l__acro_tmpa_tl {#2} + \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} + \acro_write_long:vn {l__acro_ \l__acro_tmpa_tl _format_tl} {#3} + \acro_endings:nn {#1} {long} + \tl_if_in:nnT {#2} {long} + { \l__acro_long_post_tl } + } +\cs_generate_variant:Nn \acro_write_expanded:nnn {nnV} + +% #1: ID +% #2: long|first-long|list-long|extra +\cs_new_protected:Npn \acro_write_expanded:nn #1#2 + { + \tl_set:Nn \l__acro_tmpa_tl {#2} + \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} + \acro_write_long:vv + {l__acro_ \l__acro_tmpa_tl _format_tl} + {l__acro_ \l__acro_tmpa_tl _tl} + \acro_endings:nn {#1} {long} + \tl_if_in:nnT {#2} {long} + { \l__acro_long_post_tl } + } + +% #1: id +\cs_new_protected:Npn \acro_after:n #1 + { + \acro_cite_if:Nn \l__acro_citation_all_bool {#1} + \acro_index_if:Nn \l__acro_addto_index_bool {#1} + \acro_property_get:nnT {#1} {post} + { \tl_use:N \l__acro_post_tl } + } + +\cs_new_protected:Npn \acro_check_single:n #1 + { + \acro_if_is_single:nT {#1} + { \cs_set_eq:NN \acro_hyper_link:nn \use_ii:nn } + } + +% -------------------------------------------------------------------------- +% #1: id +\cs_new_protected:Npn \acro_before:n #1 + { + \acro_get:n {#1} + \acro_is_used:n {#1} + \acro_check_single:n {#1} + } + +% the standard internals: +% #1: id +\cs_new_protected:Npn \acro_short:n #1 + { + \acro_before:n {#1} + \acro_write_indefinite:nn {#1} {short} + \acro_write_compact:nn {#1} {short} + \acro_after:n {#1} + } + +% get alternative entry: +% #1: id +\cs_new_protected:Npn \acro_alt:n #1 + { + \acro_before:n {#1} + \acro_alt_error:n {#1} + \acro_write_indefinite:nn {#1} {alt} + \acro_write_compact:nn {#1} {alt} + \acro_after:n {#1} + } + +% get long entry: +% #1: id +\cs_new_protected:Npn \acro_long:n #1 + { + \acro_before:n {#1} + \acro_write_indefinite:nn {#1} {long} + \acro_write_expanded:nn {#1} {long} + \acro_after:n {#1} + } + +% get foreign entry: +% #1: id +\cs_new_protected:Npn \acro_foreign:n #1 + { + \acro_get:n {#1} + \tl_if_blank:VF \l__acro_foreign_tl + { + \acro_is_used:n {#1} + \acro_check_single:n {#1} + \acro_write_long:VV \l__acro_foreign_format_tl \l__acro_foreign_tl + \acro_after:n {#1} + } + } + +% get extra entry: +% #1: id +\cs_new_protected:Npn \acro_extra:n #1 + { + \acro_get:n {#1} + \tl_if_blank:VF \l__acro_extra_tl + { + \acro_is_used:n {#1} + \acro_check_single:n {#1} + \acro_write_long:VV \l__acro_extra_format_tl \l__acro_extra_tl + \acro_after:n {#1} + } + } + +% output like the first time: +% #1: id +\cs_new_protected:Npn \acro_first:n #1 + { + \bool_gset_true:c {g__acro_#1_first_use_bool} + \acro_before:n {#1} + \acro_first_instance:nV {#1} \l__acro_long_tl + } + +% output like the first time with own long version: +% #1: id +% #2: instead of long entry +\cs_new_protected:Npn \acro_first_like:nn #1#2 + { + \bool_gset_true:c {g__acro_#1_first_use_bool} + \acro_before:n {#1} + \acro_first_instance:nn {#1} {#2} + } + +% ---------------------------------------------------------------------------- +% citations: +\cs_new:Npn \__acro_citation_cmd:w { \cite } +\cs_new:Npn \__acro_group_citation_cmd:w { \cite } + +% #1 pre +% #2 post +% #3 key +\cs_new:Npn \__acro_cite:nnn #1#2#3 + { + \quark_if_no_value:nTF {#1} + { \__acro_citation_cmd:w {#3} } + { + \quark_if_no_value:nTF {#2} + { \__acro_citation_cmd:w [#1] {#3} } + { \__acro_citation_cmd:w [#1] [#2] {#3} } + } + } +\cs_generate_variant:Nn \__acro_cite:nnn {VVV} + +\cs_new_protected:Npn \acro_cite:n #1 + { + \acro_property_get:nnT {#1} {before-citation} + { \acro_no_break: \l__acro_before_citation_tl } + \prop_get:NnNT \l__acro_citation_prop {#1} \l__acro_tmpa_tl + { + \prop_get:NnN \l__acro_citation_pre_prop {#1} \l__acro_tmpb_tl + \prop_get:NnN \l__acro_citation_post_prop {#1} \l__acro_tmpc_tl + \acro_no_break: + \tl_use:N \l__acro_citation_connect_tl + \__acro_cite:VVV + \l__acro_tmpb_tl + \l__acro_tmpc_tl + \l__acro_tmpa_tl + } + \acro_property_get:nnT {#1} {after-citation} + { \acro_no_break: \l__acro_after_citation_tl } + } + +\cs_new_protected:Npn \acro_group_cite:n #1 + { + \group_begin: + \cs_set_eq:NN \__acro_citation_cmd:w \__acro_group_citation_cmd:w + \tl_set_eq:NN + \l__acro_citation_connect_tl + \l__acro_between_group_connect_citation_tl + \acro_cite_if:Nn \l__acro_citation_first_bool {#1} + \group_end: + } + +\cs_new_protected:Npn \acro_cite_if:Nn #1#2 + { \bool_if:NT #1 { \acro_cite:n {#2} } } + +% ---------------------------------------------------------------------------- +% indexing: +\cs_new_protected:Npn \acro_index_if:Nn #1#2 + { + \bool_lazy_and:nnT {#1} { \l__acro_mark_as_used_bool } + { + \prop_get:NnN \l__acro_index_cmd_prop {#2} \l__acro_tmpa_tl + \prop_get:NnN \l__acro_index_sort_prop {#2} \l__acro_tmpb_tl + \prop_get:NnN \l__acro_index_prop {#2} \l__acro_tmpc_tl + \__acro_index:VnVV + \l__acro_tmpa_tl + {#2} + \l__acro_tmpb_tl + \l__acro_tmpc_tl + } + } + +\cs_new:Npn \__acro_index_cmd:n { \index } + +% #1: cmd +% #2: key +% #3: sort +% #4: replace +\cs_new_protected:Npn \__acro_index:nnnn #1#2#3#4 + { + \prop_get:NnNF \l__acro_short_prop {#2} \l__acro_index_short_tl {} + \prop_get:NnNF \l__acro_format_prop {#2} \l__acro_index_format_tl {} + \quark_if_no_value:VTF \l__acro_index_format_tl + { \tl_set:Nn \l__acro_tmpa_tl { \l__acro_short_format_tl \l__acro_index_short_tl } } + { \tl_set:Nn \l__acro_tmpa_tl { \l__acro_index_format_tl \l__acro_index_short_tl } } + \quark_if_no_value:nF {#1} + { \cs_set:Npn \__acro_index_cmd:n {#1} } + \quark_if_no_value:nTF {#4} + { + \quark_if_no_value:nTF {#3} + { \__acro_index_cmd:n { #2 @ { \l__acro_tmpa_tl } } } + { \__acro_index_cmd:n { #3 @ { \l__acro_tmpa_tl } } } + } + { \__acro_index_cmd:n {#4} } + } +\cs_generate_variant:Nn \__acro_index:nnnn {VnVV} + +% ---------------------------------------------------------------------------- +% accessability support +\cs_new_eq:NN \acro_acc_supp:nn \use_ii:nn + +\cs_new_protected:Npn \acro_get_acc_supp:nn #1#2 + { + \prop_get:NnNF \l__acro_acc_supp_prop {#1} \l__acro_acc_supp_tl + { \prop_get:NnNF \l__acro_short_prop {#1} \l__acro_acc_supp_tl {} } + \acro_for_endings_do:n + { + \bool_if:cT {l__acro_##1_bool} + { + \tl_put_right:Nv + \l__acro_acc_supp_tl + {l__acro_short_##1_tl} + } + } + \acro_do_acc_supp:VVn + \l__acro_acc_supp_tl + \l__acro_acc_supp_options_tl + {#2} + } + +\cs_new:Npn \acro_do_acc_supp:nnn #1#2#3 + { + \BeginAccSupp { ActualText = #1 , #2 } + #3 + \EndAccSupp { } + } +\cs_generate_variant:Nn \acro_do_acc_supp:nnn {VV} + +\AtEndPreamble + { + \bool_if:NT \l__acro_acc_supp_bool + { + \RequirePackage {accsupp} + \cs_set_eq:NN \acro_acc_supp:nn \acro_get_acc_supp:nn + } + \bool_if:NT \l__acro_tooltip_bool + { + \RequirePackage {pdfcomment} + \cs_if_eq:NNT \__acro_tooltip_cmd:nn \use_i:nn + { \cs_set:Npn \__acro_tooltip_cmd:nn { \pdftooltip } } + } + } + +% -------------------------------------------------------------------------- +% tooltips for acronyms + +% #1: id +% #2: printed text +% #3: tool tip text +\cs_new_protected:Npn \acro_write_tooltip:nnn #1#2#3 + { + \acro_property_get:nnTF {#1} {tooltip} + { \__acro_check_tooltip:nV {#2} \l__acro_tooltip_tl } + { \__acro_check_tooltip:nn {#2} {#3} } + } +\cs_generate_variant:Nn \acro_write_tooltip:nnn {nnV} + +% #1: printed text +% #2: tool tip text +\cs_new_protected:Npn \__acro_check_tooltip:nn #1#2 + { + \bool_if:NTF \l__acro_tooltip_inside_bool + {#1} + { + \bool_set_true:N \l__acro_tooltip_inside_bool + \__acro_tooltip_cmd:nn {#1} {#2} + } + } +\cs_generate_variant:Nn \__acro_check_tooltip:nn { nV } + +% use whatever command you like for creating tooltips here: +% #1: printed text +% #2: tool tip text +\cs_new_eq:NN \__acro_tooltip_cmd:nn \use_i:nn + +% -------------------------------------------------------------------------- +% indefinite articles: + +% #1: ID +% #2: short|long|alt +\cs_new_protected:Npn \acro_write_indefinite:nn #1#2 + { + \bool_if:NT \l__acro_indefinite_bool + { \prop_item:cn {l__acro_#2_indefinite_prop} {#1} ~ } + \bool_if:NT \l__acro_upper_indefinite_bool + { + \__acro_first_upper_case:x + { \prop_item:cn {l__acro_#2_indefinite_prop} {#1} } ~ + } + } + +% -------------------------------------------------------------------------- +% experimental sorting feature: + +% the following code is an adaption of expl3 code used for \str_if_eq:NN(TF) +\sys_if_engine_luatex:TF + { + \tl_set:Nn \l__acro_tmpa_tl + { + acro ~ = ~ acro ~ or ~ { ~ } ~ + function ~ acro.strcmp ~ (A, B) ~ + if ~ A ~ == ~ B ~ then ~ + tex.write ("0") ~ + elseif ~ A ~ < ~ B ~ then ~ + tex.write ("-1") ~ + else ~ + tex.write ("1") ~ + end ~ + end + } + \lua_now:e { \l__acro_tmpa_tl } + \cs_new_protected:Npn \acro_strcmp:nn #1#2 + { + \lua_now:e + { + acro.strcmp + ( + " \__acro_escape_x:n {#1} " , + " \__acro_escape_x:n {#2} " + ) + } + } + \cs_new:Npn \__acro_escape_x:n #1 + { + \lua_escape:e + { \__kernel_tl_to_str:w \use:e { {#1} } } + } + } + { \cs_new_eq:NN \acro_strcmp:nn \tex_strcmp:D } + +\AtBeginDocument + { + \bool_if:NT \l__acro_sort_bool + { + \cs_new_protected:Npn \acro_sort_prop:NN #1#2 + { + \seq_clear:N \l__acro_tmpa_seq + \prop_clear:N \l__acro_tmpa_prop + \prop_clear:N \l__acro_tmpb_prop + \prop_map_inline:Nn #2 + { + \seq_put_right:Nn \l__acro_tmpa_seq {##2} + \prop_put:Nnn \l__acro_tmpa_prop {##1} {##2} + } + \seq_sort:Nn \l__acro_tmpa_seq + { + \int_compare:nTF + { + \acro_strcmp:nn + { \str_fold_case:n {##1} } + { \str_fold_case:n {##2} } + = -1 + } + { \sort_return_same: } + { \sort_return_swapped: } + } + \seq_map_inline:Nn \l__acro_tmpa_seq + { + \prop_map_inline:Nn \l__acro_tmpa_prop + { + \str_if_eq:nnT {##1} {####2} + { + \prop_get:NnN #1 {####1} \l__acro_tmpa_tl + \prop_put:NnV \l__acro_tmpb_prop {####1} + \l__acro_tmpa_tl + } + } + } + \prop_set_eq:NN #1 \l__acro_tmpb_prop + } + } + } + +% -------------------------------------------------------------------------- +% regarding list printing: +% this command ensures that a rerun warning is given when \printacronyms +% is set the first time. This mechanism doesn't make very much sense, +% should be replaced by a different and more efficient one +% +\cs_new_protected:Npn \acro@print@list + { \cs_if_exist:NF \acro@printed@list { \cs_new:Npn \acro@printed@list { printed } } } + +% -------------------------------------------------------------------------- +% trailing tokens and what to do when present + +\cs_new_protected:Npn \acro_new_trailing_token:n #1 + { \bool_new:c {l__acro_trailing_#1_bool} } +\cs_new_protected:Npn \acro_activate_trailing_action:n #1 + { \bool_set_true:c {l__acro_trailing_#1_bool} } +\cs_new_protected:Npn \acro_deactivate_trailing_action:n #1 + { \bool_set_false:c {l__acro_trailing_#1_bool} } + +% register a new token but don't activate its action: +% #1: token +% #2: name +\cs_new_protected:Npn \acro_register_trailing_token:Nn #1#2 + { + \prop_put:Nnn \l__acro_trailing_tokens_prop {#2} {#1} + \prop_put:Nnn \l__acro_trailing_actions_prop {#1} + { \acro_activate_trailing_action:n {#2} } + \acro_new_trailing_token:n {#2} + } + +\cs_new_protected:Npn \acro_for_all_trailing_tokens_do:n #1 + { \prop_map_inline:Nn \l__acro_trailing_tokens_prop {#1} } + +% activate a token: +\cs_new_protected:Npn \acro_activate_trailing_token:n #1 + { + \prop_get:NnN \l__acro_trailing_tokens_prop {#1} \l__acro_tmpa_tl + \tl_put_right:NV \l__acro_trailing_tokens_tl \l__acro_tmpa_tl + } + +% deactivate a token: +\cs_new_protected:Npn \acro_deactivate_trailing_token:n #1 + { + \prop_get:NnN \l__acro_trailing_tokens_prop {#1} \l__acro_tmpa_tl + \tl_remove_all:NV \l__acro_trailing_tokens_tl \l__acro_tmpa_tl + } + +% #1: name +\prg_new_conditional:Npnn \acro_if_trailing_token:n #1 {p,T,F,TF} + { + \bool_if:cTF {l__acro_trailing_#1_bool} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: csv list of names +\prg_new_protected_conditional:Npnn \acro_if_trailing_tokens:n #1 {T,F,TF} + { + \bool_set_false:N \l__acro_trailing_tokens_bool + \clist_map_inline:nn {#1} + { + \bool_if:cT {l__acro_trailing_##1_bool} + { + \bool_set_true:N \l__acro_trailing_tokens_bool + \clist_map_break: + } + } + \bool_if:NTF \l__acro_trailing_tokens_bool + { \prg_return_true: } + { \prg_return_false: } + } + +\cs_new_protected:Npn \aciftrailing { \acro_if_trailing_tokens:nTF } + +\cs_new_protected:Npn \__acro_check_trail:N #1 + { + \tl_map_inline:Nn \l__acro_trailing_tokens_tl + { + \token_if_eq_meaning:NNT #1 ##1 + { \prop_item:Nn \l__acro_trailing_actions_prop {##1} } + } + } + +% options for activating actions: +\keys_define:nn {acro} + { + activate-trailing-tokens .code:n = + \clist_map_inline:nn {#1} { \acro_activate_trailing_token:n {##1} } , + deactivate-trailing-tokens .code:n = + \clist_map_inline:nn {#1} { \acro_deactivate_trailing_token:n {##1} } + } + +% --------------------------------------------------------------------------- +% reset outputs, they'll behave like the first time again (!not like the _only_ +% time!): +\cs_new_protected:Npn \acro_reset:n #1 + { + \bool_gset_false:c { g__acro_#1_used_bool } + \bool_gset_false:c { g__acro_#1_first_use_bool } + } + +\cs_new_protected:Npn \acro_mark_as_used:n #1 + { + \bool_gset_true:c { g__acro_#1_used_bool } + \bool_gset_true:c { g__acro_#1_first_use_bool } + \bool_gset_true:c { g__acro_#1_in_list_bool } + \if@filesw + \__acro_aux_file_now:n { \acro@used@once {#1} {} {} {} } + \__acro_aux_file_now:n { \acro@used@twice {#1} {} {} {} } + \fi + } + +\cs_new_protected:Npn \acro_reset_all: + { \acro_for_all_acronyms_do:n { \acro_reset:n {##1} } } + +% make sure that no acronym is used at the beginning of the document, see +% issue #81 for reasons why this may be necessary: +\AfterEndPreamble { \acro_reset_all: } + +\cs_new_protected:Npn \acro_mark_all_as_used: + { \acro_for_all_acronyms_do:n { \acro_mark_as_used:n {##1} } } + +\prg_new_conditional:Npnn \acro_if_acronym_used:n #1 { p,T,F,TF } + { + \bool_lazy_and:nnTF + { \bool_if_p:c {g__acro_#1_used_bool} } + { !\acro_if_is_single_p:n {#1} } + { \prg_return_true: } + { \prg_return_false: } + } + +% -------------------------------------------------------------------------- +% acronym barriers: allow local lists of only those acronyms used between two +% barriers + +\keys_define:nn {acro} + { + use-barriers .bool_gset:N = \g__acro_use_barriers_bool , + use-barriers .initial:n = false , + reset-at-barriers .bool_gset:N = \g__acro_reset_at_barrier_bool , + reset-at-barriers .initial:n = false + } + +\cs_new_protected:Npn \acro_barrier: + { + \int_gincr:N \g__acro_barrier_int + \bool_if:NT \g__acro_reset_at_barrier_bool + { \acro_reset_all: } + } + +\cs_new_protected:Npn \acro_check_barriers:n #1 + { + \bool_if:NT \g__acro_use_barriers_bool + { + \tl_set:Nx \l__acro_tmpa_tl + { \seq_use:cn {g__acro_#1_barriers_seq} {} } + \tl_set:Nx \l__acro_tmpb_tl + { \seq_use:cn {g__acro_#1_recorded_barriers_seq} {} } + \tl_if_eq:NNF \l__acro_tmpa_tl \l__acro_tmpb_tl + { + \@latex@warning@no@line + {Rerun~to~get~barriers~of~acronym~#1~right} + } + } + } + +\cs_new_protected:Npn \acro_record_barrier:n #1 + { + \bool_if:NT \g__acro_use_barriers_bool + { + \seq_if_in:cxF {g__acro_#1_barriers_seq} + { \int_use:N \g__acro_barrier_int } + { + \seq_gput_right:cx {g__acro_#1_barriers_seq} + { \int_use:N \g__acro_barrier_int } + } + } + } + +% #1: id +% #2: barrier number +\prg_new_protected_conditional:Npnn \acro_if_in_barrier:nn #1#2 {T,F,TF} + { + \seq_if_in:cnTF {g__acro_#1_recorded_barriers_seq} {#2} + { \prg_return_true: } + { \prg_return_false: } + } +\cs_generate_variant:Nn \acro_if_in_barrier:nnTF {nx} + +\cs_new_protected:Npn \acro@barriers #1#2 + { \seq_gset_split:cnn {g__acro_#1_recorded_barriers_seq} {,} {#2} } + +% -------------------------------------------------------------------------- +% the user commands -- preparation: +\cs_new_protected:Npn \acro_begin: + { + \group_begin: + \__acro_check_after_end:w + } + +\cs_new_protected:Npn \__acro_check_after_end:w #1 \acro_end: + { + \cs_set:Npn \__acro_execute: + { + \__acro_check_trail:N \l_peek_token + #1 + \acro_end: % this will end the group opened by \acro_begin: + } + \peek_after:Nw \__acro_execute: + } + +\cs_new_protected:Npn \acro_end: { \group_end: } + +\cs_new_protected:Npn \acro_reset_specials: + { + \bool_set_false:N \l__acro_indefinite_bool + \bool_set_false:N \l__acro_first_upper_bool + \bool_set_false:N \l__acro_upper_indefinite_bool + \acro_for_endings_do:n { \bool_set_false:c {l__acro_##1_bool} } + } + +% #1: ID +% #2: true|false +\cs_new_protected:Npn \acro_check_acronym:nn #1#2 + { + \acro_defined:n {#1} + \acro_use_acronym:n {#2} + } + +% #1: boolean +% #2: ID +\cs_new_protected:Npn \acro_check_and_mark_if:nn #1#2 + { + \bool_lazy_or:nnTF {#1} { !\l__acro_use_acronyms_bool } + { \acro_check_acronym:nn {#2} {false} } + { \acro_check_acronym:nn {#2} {true} } + } + +\cs_new_protected:Npn \acro_switch_off: + { \bool_set_false:N \l__acro_use_acronyms_bool } + +\cs_new_protected:Npn \acro_switch_on: + { \bool_set_true:N \l__acro_use_acronyms_bool } + +% commands for (re)defining \ac-like macros: +\cs_new_protected:Npn \acro_define_new_acro_command:NN #1#2 + { + % #1: csname + % #2: definition where `#1' refers to the ID + \cs_new_protected:Npn #1 ##1##2 + { + \cs_set:Npn \__acro_tmp:n ####1 {##2} + \cs_new_protected:cpx + {acro_ \__acro_remove_backslash:N ##1 :nnn} ####1####2####3 + { + \acro_begin: + \acro_reset_specials: + \exp_not:N \tl_if_blank:nF {####2} { \keys_set:nn {acro} {####2} } + \acro_check_and_mark_if:nn {####1} {####3} + \__acro_tmp:n {####3} + \acro_end: + } + #2 ##1 {sO{}m} + { + \acro_case_insensitive_command:cnnn + {acro_ \__acro_remove_backslash:N ##1 :nnn} + {####1} + {####2} + {####3} + } + } + } +\cs_generate_variant:Nn \acro_define_new_acro_command:NN {cc} +\cs_generate_variant:Nn \acro_check_and_mark_if:nn {nx} + +% commands for (re)defining \acflike-like macros: +\cs_new_protected:Npn \acro_define_new_acro_pseudo_command:NN #1#2 + { + % #1: csname + % #2: definition where `#1' refers to the ID and `#2' to the pseudo long form + \cs_new_protected:Npn #1 ##1##2 + { + \cs_set:Npn \__acro_tmp:nn ####1####2 {##2} + \cs_new_protected:cpx + {acro_ \__acro_remove_backslash:N ##1 :nnn} ####1####2####3 + { + \acro_begin: + \acro_reset_specials: + \acro_check_and_mark_if:nn {####1} {####3} + \__acro_tmp:nn {####3} {####2} + \acro_end: + } + #2 ##1 {smm} + { + \acro_case_insensitive_command:cnnn + {acro_ \__acro_remove_backslash:N ##1 :nnn} + {####1} + {####3} + {####2} + } + } + } +\cs_generate_variant:Nn \acro_define_new_acro_pseudo_command:NN {cc} + +\clist_map_inline:nn {New,Renew,Declare,Provide} + { + \acro_define_new_acro_command:cc + {#1AcroCommand} + {#1DocumentCommand} + \acro_define_new_acro_pseudo_command:cc + {#1PseudoAcroCommand} + {#1DocumentCommand} + } + +% -------------------------------------------------------------------------- +% user commands -- facilities +\cs_new_protected:Npn \acro_first_upper: + { + \bool_if:NTF \l__acro_indefinite_bool + { + \bool_set_false:N \l__acro_indefinite_bool + \bool_set_true:N \l__acro_upper_indefinite_bool + } + { \bool_set_true:N \l__acro_first_upper_bool } + } + +\cs_new_protected:Npn \acro_indefinite: + { + \bool_if:NTF \l__acro_first_upper_bool + { + \bool_set_true:N \l__acro_upper_indefinite_bool + \bool_set_false:N \l__acro_first_upper_bool + } + { \bool_set_true:N \l__acro_indefinite_bool } + } + +\cs_new_protected:Npn \acro_cite: + { + \bool_set_true:N \l__acro_citation_all_bool + \bool_set_true:N \l__acro_citation_first_bool + } + +\cs_new_protected:Npn \acro_no_cite: + { + \bool_set_false:N \l__acro_citation_all_bool + \bool_set_false:N \l__acro_citation_first_bool + } + +\cs_new_protected:Npn \acro_index: + { \bool_set_true:N \l__acro_addto_index_bool } + +% similar macros \acro_<ending>: are defined by \acro_provide_ending:nnn + +% --------------------------------------------------------------------------- +% process options: +\ProcessKeysPackageOptions {acro} + +% --------------------------------------------------------------------------- +% PDF bookmark support +\cs_new:Npn \acpdfstring + { \acro_pdf_string_short:n } + +\cs_new:Npn \acpdfstringalt + { \acro_pdf_string_alt:n } + +\cs_new:Npn \acpdfstringlong + { \acro_pdf_string_long:n } + +\cs_new:Npn \acpdfstringfirst #1 + { \acpdfstringlong {#1} ~ ( \acpdfstring {#1} ) } + +% TODO: place this somewhere where endings are defined: +\cs_new:Npn \acpdfstringlongplural + { \acro_pdf_string_long_plural:n } + +\prg_new_conditional:Npnn \acro_if_star_gobble:n #1 {TF} + { + \if_meaning:w *#1 + \prg_return_true: + \else: + \prg_return_false: + \fi: + } + +\cs_new:Npn \acro_expandable_short:n #1 + { \use:e { \prop_item:Nn \l__acro_short_prop {#1} } } + +\cs_new:Npn \acro_expandable_alt:n #1 + { \use:e { \prop_item:Nn \l__acro_alt_prop {#1} } } + +\cs_new:Npn \acro_expandable_long:n #1 + { \use:e { \prop_item:Nn \l__acro_long_prop {#1} } } + +\cs_new:Npn \acro_expandable_long_plural:n #1 + { + \bool_if:cTF + { c_ \prop_item:Nn \l__acro_long_plural_form_prop {#1} _bool } + { \use:e { \prop_item:Nn \l__acro_long_plural_prop {#1} } } + { + \use:e { + \prop_item:Nn \l__acro_long_prop {#1} + \prop_item:Nn \l__acro_long_plural_prop {#1} + } + } + } + +\cs_new:Npn \acro_pdf_string_short:n #1 + { + \acro_if_star_gobble:nTF {#1} + { \acro_expandable_short:n } + { \acro_expandable_short:n {#1} } + } + +\cs_new:Npn \acro_pdf_string_alt:n #1 + { + \acro_if_star_gobble:nTF {#1} + { \acro_expandable_alt:n } + { \acro_expandable_alt:n {#1} } + } + +\cs_new:Npn \acro_pdf_string_long:n #1 + { + \acro_if_star_gobble:nTF {#1} + { \acro_expandable_long:n } + { \acro_expandable_long:n {#1} } + } + +% TODO: place this somewhere where endings are defined: +\cs_new:Npn \acro_pdf_string_long_plural:n #1 + { + \acro_if_star_gobble:nTF {#1} + { \acro_expandable_long_plural:n } + { \acro_expandable_long_plural:n {#1} } + } + +\AtBeginDocument + { + \@ifpackageloaded {hyperref} + { + \bool_set_true:N \l__acro_hyperref_loaded_bool + \pdfstringdefDisableCommands + { + \cs_set_eq:NN \ac \acpdfstring + \cs_set_eq:NN \Ac \acpdfstring + \cs_set_eq:NN \acs \acpdfstring + \cs_set_eq:NN \acl \acpdfstringlong + \cs_set_eq:NN \Acl \acpdfstringlong + \cs_set_eq:NN \acf \acpdfstringfirst + \cs_set_eq:NN \Acf \acpdfstringfirst + \cs_set_eq:NN \aca \acpdfstringalt + \cs_set_eq:NN \acp \acpdfstringplural + \cs_set_eq:NN \Acp \acpdfstringplural + \cs_set_eq:NN \acsp \acpdfstringplural + \cs_set_eq:NN \aclp \acpdfstringlongplural + \cs_set_eq:NN \Aclp \acpdfstringlongplural + \cs_set_eq:NN \acfp \acpdfstringplural + \cs_set_eq:NN \Acfp \acpdfstringplural + \cs_set_eq:NN \acap \acpdfstringaltplural + } + \cs_set_protected:Npn \acro_hyper_page:n #1 { \hyperpage {#1} } + } {} + } + +% -------------------------------------------------------------------------- +% key and order checking +\msg_new:nnn {acro} {no-id} + { + Something~ has~ gone~ wrong,~ you've~ probably~ forgotten~ to~ set~ the~ + acronym~ ID. + } + +\msg_new:nnn {acro} {before-short} + { + You've~ set~ the~ property~ `#2'~ before~ the~ `short'~ property~ for~ + acronym~ `#1'~ but~ it~ needs~ to~ be~ set~ after~ it. + } + +\msg_new:nnn {acro} {missing} + { The~ `#2'~ property~ for~ acronym~ `#1'~ is~ missing. } + +\msg_new:nnn {acro} {doubled-property} + { + It~ seems~ to~ me~ you~ have~ used~ the~ `#2'~ property~ twice~ in~ the~ + declaration~ of~ acronym~ `#1'.~ If~ you~ haven't~ there's~ + something~ different~ wrong~ and~ I'm~ lost.~ You~'re~ on~ your~ own~ + then. + } + +% #1: acronym +% #2: property +\cs_new_protected:Npn \__acro_property_check:nn #1#2 + { + \str_if_empty:NT \l__acro_current_id_str + { \acro_serious_message:n {no-id} } + \str_if_eq:nnF {#2} {short} + { + \acro_property_if_set:nnF {#1} {short} + { + \keys_set:nn {acro/declare-acronym} { short = {#1} } + \acro_harmless_message:nn {substitute-short} {#1} + } + } + \acro_property_mark_set:nn {#1} {#2} + } + +\cs_new_protected:Npn \__acro_first_property_check:nn #1#2 + { + \cs_if_exist:cTF {l__acro_#1_short_set_bool} + { + \acro_property_if_set:nnT {#1} {short} + { \acro_serious_message:nnn {doubled-property} {#1} {#2} } + } + { \bool_new:c {l__acro_#1_short_set_bool} } + \acro_property_mark_set:nn {#1} {short} + } + +% #1: ID +% #2: property +\prg_new_conditional:Npnn \acro_property_if_set:nn #1#2 {T,F,TF} + { + \bool_if:cTF {l__acro_#1_#2_set_bool} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: ID +% #2: property +\cs_new_protected:Npn \acro_property_mark_set:nn #1#2 + { \bool_set_true:c { l__acro_#1_#2_set_bool } } +\cs_generate_variant:Nn \acro_property_mark_set:nn {V} + +% -------------------------------------------------------------------------- +% the internal property selection functions for \DeclareAcronym: + +\cs_new_protected:Npn \acro_for_properties_do:n + { \prop_map_inline:Nn \g__acro_properties_prop } + +% #1: name in associated cs +% #2: property name +% #3: action +\cs_new_protected:Npn \acro_declare_property_generic:nnn #1#2#3 + { + \prop_clear_new:c {l__acro_#1_prop} + \tl_clear_new:c {l__acro_#1_tl} + \cs_new_protected:cpn {__acro_declare_#1:nn} ##1##2 {#3} + \cs_generate_variant:cn {__acro_declare_#1:nn} {V} + \keys_define:nn {acro/declare-acronym} + { + #2 .code:n = + \use:c {__acro_declare_#1:Vn} \l__acro_current_id_str {##1} + \acro_property_mark_set:Vn \l__acro_current_id_str {#2} + } + \prop_gput:Nnn \g__acro_properties_prop {#2} {#1} + } + +% #1: name in associated cs +% #2: property name +% #3: action +\cs_new_protected:Npn \acro_declare_property:nnn #1#2#3 + { + \acro_declare_property_generic:nnn {#1} {#2} + { + \__acro_property_check:nn {##1} {#2} + \prop_put:cnn {l__acro_#1_prop} {##1} {##2} + #3 + } + } + +% #1: name in associated cs +% #2: property name +\cs_new_protected:Npn \acro_declare_property:nn #1#2 + { \acro_declare_property:nnn {#1} {#2} {} } +\cs_generate_variant:Nn \acro_declare_property:nn {V} + +\cs_new_protected:Npn \acro_declare_property_simple:n #1 + { + \tl_set:Nn \l__acro_tmpa_tl {#1} + \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} + \acro_declare_property:Vn \l__acro_tmpa_tl {#1} + } + +% #1: new alias property +% #2: old property +\cs_new_protected:Npn \acro_declare_property_alias:nn #1#2 + { + \keys_define:nn {acro/declare-acronym} + { #1 .meta:n = { #2 = {##1} } } + } + +% -------------------------------------------------------------------------- +% declare the properties for \DeclareAcronym: +% short: +\acro_declare_property_generic:nnn {short} {short} + { + \__acro_first_property_check:nn {#1} {short} + \prop_put:Nnn \l__acro_short_prop {#1} {#2} + \prop_put:Nnn \l__acro_sort_prop {#1} {#1} + \prop_put:Nnn \l__acro_index_sort_prop {#1} {#1} + \prop_put:Nnn \l__acro_alt_prop {#1} {#2} + \prop_put:Nnn \l__acro_pdfstring_short_prop {#1} {#2} + \prop_put:Nnn \l__acro_pdfstring_alt_prop {#1} {#2} + \acro_for_endings_do:n + { + \prop_put:cnv {l__acro_short_##1_prop} + {#1} {l__acro_default_short_##1_tl} + \prop_put:cnx {l__acro_pdfstring_short_##1_prop} + {#1} { \exp_not:n {#2} \exp_not:v {l__acro_default_short_##1_tl} } + \prop_put:cnn {l__acro_short_##1_form_prop} {#1} {false} + \prop_put:cnv {l__acro_alt_##1_prop} + {#1} {l__acro_default_alt_##1_tl} + \prop_put:cnx {l__acro_pdfstring_alt_##1_prop} + {#1} { \exp_not:n {#2} \exp_not:v {l__acro_default_short_##1_tl} } + \prop_put:cnn {l__acro_alt_##1_form_prop} {#1} {false} + } + \prop_put:NnV \l__acro_short_indefinite_prop + {#1} \l__acro_default_indefinite_tl + \prop_put:NnV \l__acro_alt_indefinite_prop + {#1} \l__acro_default_indefinite_tl + } + +% long: +\acro_declare_property:nnn {long} {long} + { + \prop_put:NnV \l__acro_long_indefinite_prop + {#1} + \l__acro_default_indefinite_tl + \acro_for_endings_do:n + { + \prop_put:cnn {l__acro_long_##1_form_prop} {#1} {false} + \acro_property_if_set:nnF {#1} {long-##1} + { \prop_put:cnv {l__acro_long_##1_prop} {#1} {l__acro_default_long_##1_tl} } + \prop_put:cnn {l__acro_foreign_##1_form_prop} {#1} {false} + \acro_property_if_set:nnF {#1} {foreign-##1} + { \prop_put:cnv {l__acro_foreign_##1_prop} {#1} {l__acro_default_foreign_##1_tl} } + } + } + +\acro_declare_property_simple:n {first-style} + +% list: +\acro_declare_property_simple:n {list} + +% defines `short-plural', `long-plural' and `long-plural-form' as well as the +% options `plural-ending', `short-plural-ending' and `long-plural-ending': +% \ProvideAcroEnding {plural} {s} {s} + +% short indefinite article: +\acro_declare_property_simple:n {short-indefinite} + +% long indefinite article: +\acro_declare_property_simple:n {long-indefinite} + +% pre long: +\acro_declare_property_simple:n {long-pre} + +% post long: +\acro_declare_property_simple:n {long-post} + +% post: +\acro_declare_property_simple:n {post} + +% sort: +\acro_declare_property:nnn {sort} {sort} + { + \acro_property_if_set:nnF {#1} {index-sort} + { \prop_put:Nnn \l__acro_index_sort_prop {#1} {#2} } + } + +% alternative: +\acro_declare_property:nnn {alt} {alt} + { + \prop_put:Nnn \l__acro_pdfstring_alt_prop {#1} {#2} + \prop_put:NnV \l__acro_alt_indefinite_prop + {#1} \l__acro_default_indefinite_tl + } + +\cs_set_protected:Npn \acro_alt_error:n #1 + { + \acro_property_if_set:nnF {#1} {alt} + { \acro_harmless_message:nn {no-alternative} {#1} } + } + +% alt. indefinite article: +\acro_declare_property_simple:n {alt-indefinite} + +% foreign: +\acro_declare_property_simple:n {foreign} + +% foreign-lang: +\acro_declare_property_simple:n {foreign-lang} + +% format: +\acro_declare_property_simple:n {format} + +% short format: +\acro_declare_property_alias:nn {short-format} {format} + +% alt format: +\acro_declare_property_simple:n {alt-format} + +% long format: +\acro_declare_property_simple:n {long-format} + +% first long format: +\acro_declare_property_simple:n {first-long-format} + +% pdfstring -- currently needs to be done `by hand': +\cs_new_protected:Npn \__acro_declare_pdfstring:nw #1#2/#3/#4 \acro_stop: + { + \__acro_property_check:nn {#1} {pdfstring} + \prop_put:Nnx \l__acro_pdfstring_short_prop {#1} {#2} + \acro_for_endings_do:n + { + \tl_if_blank:nTF {#4} + { + \prop_put:cnx {l__acro_pdfstring_short_##1_prop} + {#1} { \exp_not:n {#2} \exp_not:v {l__acro_default_short_##1_tl} } + } + { + \prop_put:cnn {l__acro_pdfstring_short_##1_prop} + {#1} {#2#3} + } + } + } +\cs_generate_variant:Nn \__acro_declare_pdfstring:nw {V} + +\keys_define:nn {acro/declare-acronym} + { + pdfstring .code:n = + \__acro_declare_pdfstring:Vw \l__acro_current_id_str #1 // \acro_stop: + } + +\cs_new_protected:Npn \__acro_declare_pdfstring_alt:nw #1#2/#3/#4 \acro_stop: + { + \__acro_property_check:nn {#1} {pdfstring-alt} + \prop_put:Nnn \l__acro_pdfstring_alt_prop {#1} {#2} + \acro_for_endings_do:n + { + \tl_if_empty:nTF {#3} + { + \prop_put:cnx {l__acro_pdfstring_alt_##1_prop} + {#1} { \exp_not:n {#2} \exp_not:v {l__acro_default_alt_##1_tl} } + } + { \prop_put:cnn {l__acro_pdfstring_alt_##1_prop} {#1} {#2#3} } + } + } +\cs_generate_variant:Nn \__acro_declare_pdfstring_alt:nw {V} + +\keys_define:nn {acro/declare-acronym} + { + pdfstring-alt .code:n = + \__acro_declare_pdfstring_alt:Vw \l__acro_current_id_str #1 // \acro_stop: + } + +% class: +\acro_declare_property_simple:n {class} + +% extra information: +\acro_declare_property_simple:n {extra} + +% single appearances: +\acro_declare_property_simple:n {single} + +% single format: +\acro_declare_property_simple:n {single-format} + +% acc supp: +\acro_declare_property:nn {acc_supp} {accsupp} + +% tooltip: +\acro_declare_property_simple:n {tooltip} + +% before-citation: +\acro_declare_property_simple:n {before-citation} + +% after-citation: +\acro_declare_property_simple:n {after-citation} + +% citation -- this needs a bit more work: +\cs_new_protected:Npn \__acro_declare_citation:nw #1#2[#3]#4[#5]#6#7 \acro_stop: + { + % no options: #1: ID, #2: property, #7 is blank + % 1 option: #1: ID, #4: property, #3: option, #5: \q_no_value + % 2 options: #1: ID: #6: property, #3: first option, #5: second option + \tl_if_blank:nTF {#7} + { + \__acro_declare_citation_aux:nnnn {#1} + { \q_no_value } + { \q_no_value } + {#2} + } + { + \quark_if_no_value:nTF {#5} + { + \__acro_declare_citation_aux:nnnx {#1} + { \q_no_value } + {#3} + { \tl_head:n {#4} } + } + { \__acro_declare_citation_aux:nnnn {#1} {#3} {#5} {#6} } + } + } +\cs_generate_variant:Nn \__acro_declare_citation:nw {V} + +\keys_define:nn {acro/declare-acronym} + { + cite .code:n = + \__acro_declare_citation:Vw + \l__acro_current_id_str #1 [\q_no_value][\q_no_value] \scan_stop: \acro_stop: + } +\prop_gput:Nnn \g__acro_properties_prop {cite} {cite} + +% #1: ID +% #2: pre +% #3: post +% #4: citation key +\cs_new_protected:Npn \__acro_declare_citation_aux:nnnn #1#2#3#4 + { + \__acro_property_check:nn {#1} {cite} + \prop_put:Nnn \l__acro_citation_prop {#1} {#4} + \quark_if_no_value:nF {#2} + { \prop_put:Nnn \l__acro_citation_pre_prop {#1} {#2} } + \quark_if_no_value:nF {#3} + { \prop_put:Nnn \l__acro_citation_post_prop {#1} {#3} } + } +\cs_generate_variant:Nn \__acro_declare_citation_aux:nnnn {nnnx} + +% TODO: +% add index entries, by default \index{<sort>@<short>} +% index: overwrite default <sort>@<short> entry completely +% index-sort: overwrite the <sort> part of <sort>@<short> entry + +% need to take care of custom index cmd, at least +% - \index{} +% - \index[]{} +% question is, though, if it should be the same one for all acronyms? +% I go for yes but would also add a `post' property that allows to add arbitrary +% TeX code after an acronym is typeset + +% index: +\acro_declare_property_simple:n {index} + +% index-sort: +\acro_declare_property_simple:n {index-sort} + +% index-cmd: +\acro_declare_property_simple:n {index-cmd} + +% -------------------------------------------------------------------------- +% acronym macros: +\cs_new_protected:Npn \__acro_define_acronym_macro:n #1 + { + \bool_if:NT \l__acro_create_macros_bool + { + \cs_if_exist:cTF {#1} + { + \bool_if:NTF \l__acro_strict_bool + { \cs_set:cpn {#1} { \ac {#1} \acro_xspace: } } + { \acro_serious_message:nn {macro} {#1} } + } + { \cs_new:cpn {#1} { \ac {#1} \acro_xspace: } } + } + } + +% -------------------------------------------------------------------------- +% internal acronym declaring function: +\cs_new_protected:Npn \acro_declare_acronym:nn #1#2 + { \acro_case_insensitive:Nnn \__acro_declare_acronym:nn {#1} {#2} } + +\cs_new_protected:Npn \__acro_declare_acronym:nn #1#2 + { + \seq_gput_right:Nn \g__acro_declared_acronyms_seq {#1} + \bool_gset_true:N \g__acro_first_acronym_declared_bool + \str_set:Nn \l__acro_current_id_str {#1} + \acro_for_properties_do:n + { \bool_new:c {l__acro_ \l__acro_current_id_str _##1_set_bool} } + \keys_set:nn {acro/declare-acronym} {#2} + \bool_new:c {g__acro_#1_first_use_bool} + \bool_new:c {g__acro_#1_used_bool} + \bool_new:c {g__acro_#1_label_bool} + \bool_new:c {g__acro_#1_in_list_bool} + \seq_new:c {g__acro_#1_barriers_seq} + \seq_new:c {g__acro_#1_recorded_barriers_seq} + \bool_if:NF \l__acro_print_only_used_bool + { \bool_gset_true:c {g__acro_#1_in_list_bool} } + \__acro_create_page_records:n {#1} + \__acro_define_acronym_macro:n {#1} + \str_clear:N \l__acro_current_id_str + \acro_property_if_set:nnF {#1} {short} + { \acro_serious_message:nnn {missing} {#1} {short} } + \acro_property_if_set:nnF {#1} {long} + { \acro_serious_message:nnn {missing} {#1} {long} } + \__acro_log_acronym:n {#1} + } + + +% -------------------------------------------------------------------------- +% print the list: +% #1: list of classes +% #2: list of excluded classes +\keys_define:nn {acro/print-acronyms} + { + include-classes .tl_set:N = \l__acro_included_classes_tl , + exclude-classes .tl_set:N = \l__acro_excluded_classes_tl , + name .tl_set:N = \l__acro_list_name_tl , + heading .code:n = \__acro_set_list_heading:n {#1} , + sort .bool_set:N = \l__acro_sort_bool , + local-to-barriers .bool_set:N = \l__acro_use_barrier_bool + } + +\cs_new_protected:Npn \acro_print_acronyms:n #1 + { + \group_begin: + % this is a cheap trick to prevent the \@noitemerr + % if one forgot to delete either the aux file or + % remove \printacronyms -- but it's local: + \cs_set:Npn \@noitemerr {} + \tl_clear:N \l__acro_included_classes_tl + \tl_clear:N \l__acro_excluded_classes_tl + \tl_if_blank:nF {#1} + { \keys_set:nn {acro/print-acronyms} {#1} } + \__acro_aux_file_now:n { \acro@print@list } + \bool_if:NT \l__acro_sort_bool + { \acro_sort_prop:NN \l__acro_short_prop \l__acro_sort_prop } + \acro_title_instance:VV + \l__acro_list_heading_cmd_tl + \l__acro_list_name_tl + \cs_if_exist:NTF \acro@printed@list + { + \acro_list_instance:VVV + \l__acro_list_instance_tl + \l__acro_included_classes_tl + \l__acro_excluded_classes_tl + } + { \@latex@warning@no@line {Rerun~to~get~acronym~list~right} } + \group_end: + } + +% -------------------------------------------------------------------------- +% language support +\RequirePackage {translations} + +\cs_new_protected:Npn \__acro_declare_translation:www #1 \q_mark #2=#3 \q_stop + { + \tl_set:Nx \l__acro_tmpa_tl { \tl_trim_spaces:n {#1} } + \tl_set:Nx \l__acro_tmpb_tl { \tl_trim_spaces:n {#2} } + \tl_if_in:nnT {#3} {=} + {} % TODO: misplaced equal sign + \tl_set:Nx \l__acro_tmpc_tl { \tl_trim_spaces:n {#3} } + \__acro_declare_translation:VVV + \l__acro_tmpb_tl + \l__acro_tmpa_tl + \l__acro_tmpc_tl + } + +% #1: key +% #2: lang +% #3: translation +\cs_new_protected:Npn \__acro_declare_translation:nnn #1#2#3 + { \DeclareTranslation {#1} {#2} {#3} } +\cs_generate_variant:Nn \__acro_declare_translation:nnn {VVV} + +% #1: key +% #2: csv list: { <lang1> = <translation1> , <lang2> = <translation2> } +\cs_new_protected:Npn \acro_declare_translation:nn #1#2 + { + \clist_map_inline:nn {#2} + { + \tl_if_blank:nF {##1} + { \__acro_declare_translation:www #1 \q_mark ##1 \q_stop } + } + } + +% tokenlists using the translations: +\tl_set:Nn \l__acro_list_name_tl { \GetTranslation {acronym-list-name} } +\tl_set:Nn \l__acro_page_name_tl { \GetTranslation {acronym-page-name}\@\, } +\tl_set:Nn \l__acro_pages_name_tl { \GetTranslation {acronym-pages-name}\@\, } +\tl_set:Nn \l__acro_next_page_tl { \,\GetTranslation {acronym-next-page}\@ } +\tl_set:Nn \l__acro_next_pages_tl { \,\GetTranslation {acronym-next-pages}\@ } + +% -------------------------------------------------------------------------- +% allow for a configuration file: + +\file_if_exist:nT + { \l_acro_config_file_name_tl . \l_acro_config_file_extension_tl } + { + \@onefilewithoptions + {\l_acro_config_file_name_tl} [] [] + \l_acro_config_file_extension_tl + } + +% -------------------------------------------------------------------------- +% define user functions: +% document commands: +\NewDocumentCommand \DeclareAcronym {mm} + { \acro_declare_acronym:nn {#1} {#2} } + +\NewDocumentCommand \acsetup { m } + { + \tl_if_blank:nF {#1} + { \keys_set:nn {acro} {#1} } + \ignorespaces + } + +\NewDocumentCommand \ProvideAcroEnding {mmm} + { \acro_provide_ending:nnn {#1} {#2} {#3} } + +\NewDocumentCommand \AcroRegisterTrailing {mm} + { \acro_register_trailing_token:Nn #1 {#2} } + +\NewDocumentCommand \DeclareAcroTranslation {mm} + { \acro_declare_translation:nn {#1} {#2} } + +\DeclareExpandableDocumentCommand \acifused { m } + { \acro_if_acronym_used:nTF {#1} } + +\NewDocumentCommand \acresetall {} + { \acro_reset_all: } + +\NewDocumentCommand \acuseall {} + { \acro_mark_all_as_used: } + +\NewDocumentCommand \acreset { > { \SplitList {,} } m } + { \ProcessList {#1} { \acro_reset:n } \ignorespaces } + +\NewDocumentCommand \acuse { > { \SplitList {,} } m } + { \ProcessList {#1} { \acro_mark_as_used:n } \ignorespaces } + +\NewDocumentCommand \acfirstupper {m} + { \acro_first_upper_case:n {#1} } + +\NewExpandableDocumentCommand \aciffirst {+m+m} + { \bool_if:NTF \l__acro_first_instance_bool {#1} {#2} } + +\NewDocumentCommand \acdot {} { \acro_dot: } +\NewDocumentCommand \acspace {} { \acro_space: } + +\NewDocumentCommand \acbarrier {} + { \acro_barrier: } + +\NewDocumentCommand \acswitchoff {} + { \acro_switch_off: } + +\NewDocumentCommand \acswitchon {} + { \acro_switch_on: } + +\NewDocumentCommand \printacronyms { O{} } + { \acro_print_acronyms:n {#1} } + +% -------------------------------------------------------------------------- +% styles +% #1: name +% #2: template +% #3: settings +\NewDocumentCommand \DeclareAcroFirstStyle {mmm} + { \acro_declare_first_style:nnn {#1} {#2} {#3} } + +\NewDocumentCommand \DeclareAcroExtraStyle {mmm} + { \acro_declare_extra_style:nnn {#1} {#2} {#3} } + +\NewDocumentCommand \DeclareAcroPageStyle {mmm} + { \acro_declare_page_style:nnn {#1} {#2} {#3} } + +\NewDocumentCommand \DeclareAcroListHeading {mm} + { \acro_declare_list_heading:nn {#1} {#2} } + +\NewDocumentCommand \DeclareAcroListStyle {mmm} + { \acro_declare_list_style:nnn {#1} {#2} {#3} } + +% -------------------------------------------------------------------------- +% endings: +\ProvideAcroEnding {plural} {s} {s} + +% -------------------------------------------------------------------------- +% use acronyms: +% automatic: +\NewAcroCommand \ac + { \acro_use:n {#1} } + +\NewAcroCommand \Ac + { + \acro_first_upper: + \acro_use:n {#1} + } + +\NewAcroCommand \iac + { + \acro_indefinite: + \acro_use:n {#1} + } + +\NewAcroCommand \Iac + { + \acro_first_upper: + \acro_indefinite: + \acro_use:n {#1} + } + +\NewAcroCommand \acp + { + \acro_plural: + \acro_use:n {#1} + } + +\NewAcroCommand \Acp + { + \acro_plural: + \acro_first_upper: + \acro_use:n {#1} + } + +\NewAcroCommand \acsingle + { + \acro_get:n {#1} + \acro_single:n {#1} + } + +\NewAcroCommand \acpsingle + { + \acro_get:n {#1} + \acro_plural: + \acro_single:n {#1} + } + +\NewAcroCommand \Acsingle + { + \acro_get:n {#1} + \acro_first_upper: + \acro_single:n {#1} + } + +\NewAcroCommand \Acpsingle + { + \acro_get:n {#1} + \acro_first_upper: + \acro_plural: + \acro_single:n {#1} + } + +% short: +\NewAcroCommand \acs + { \acro_short:n {#1} } + +\NewAcroCommand \Acs + { + \acro_first_upper: + \acro_short:n {#1} + } + +\NewAcroCommand \iacs + { + \acro_indefinite: + \acro_short:n {#1} + } + +\NewAcroCommand \Iacs + { + \acro_first_upper: + \acro_indefinite: + \acro_short:n {#1} + } + +\NewAcroCommand \acsp + { + \acro_plural: + \acro_short:n {#1} + } + +\NewAcroCommand \Acsp + { + \acro_first_upper: + \acro_plural: + \acro_short:n {#1} + } + +% alt: +\NewAcroCommand \aca + { \acro_alt:n {#1} } + +\NewAcroCommand \Aca + { + \acro_first_upper: + \acro_alt:n {#1} + } + +\NewAcroCommand \iaca + { + \acro_indefinite: + \acro_alt:n {#1} + } + +\NewAcroCommand \Iaca + { + \acro_first_upper: + \acro_indefinite: + \acro_alt:n {#1} + } + +\NewAcroCommand \acap + { + \acro_plural: + \acro_alt:n {#1} + } + +\NewAcroCommand \Acap + { + \acro_first_upper: + \acro_plural: + \acro_alt:n {#1} + } + +% long: +\NewAcroCommand \acl + { \acro_long:n {#1} } + +\NewAcroCommand \Acl + { + \acro_first_upper: + \acro_long:n {#1} + } + +\NewAcroCommand \iacl + { + \acro_indefinite: + \acro_long:n {#1} + } + +\NewAcroCommand \Iacl + { + \acro_first_upper: + \acro_indefinite: + \acro_long:n {#1} + } + +\NewAcroCommand \aclp + { + \acro_plural: + \acro_long:n {#1} + } + +\NewAcroCommand \Aclp + { + \acro_plural: + \acro_first_upper: + \acro_long:n {#1} + } + +% first: +\NewAcroCommand \acf + { \acro_first:n {#1} } + +\NewAcroCommand \Acf + { + \acro_first_upper: + \acro_first:n {#1} + } + +\NewAcroCommand \iacf + { + \acro_indefinite: + \acro_first:n {#1} + } + +\NewAcroCommand \Iacf + { + \acro_first_upper: + \acro_indefinite: + \acro_first:n {#1} + } + +\NewAcroCommand \acfp + { + \acro_plural: + \acro_first:n {#1} + } + +\NewAcroCommand \Acfp + { + \acro_plural: + \acro_first_upper: + \acro_first:n {#1} + } + +% first-like: +\NewPseudoAcroCommand \acflike + { \acro_first_like:nn {#1} {#2} } + +\NewPseudoAcroCommand \iacflike + { + \acro_indefinite: + \acro_first_like:nn {#1} {#2} + } + +\NewPseudoAcroCommand \Iacflike + { + \acro_first_upper: + \acro_indefinite: + \acro_first_like:nn {#1} {#2} + } + +\NewPseudoAcroCommand \acfplike + { + \acro_plural: + \acro_first_like:nn {#1} {#2} + } + +% -------------------------------------------------------------------------- +% first appearance styles: +\DeclareAcroFirstStyle {default} {inline} + { } + +\DeclareAcroFirstStyle {reversed} {inline} + { reversed = true } + +\DeclareAcroFirstStyle {short} {inline} + { + only-short = true , + brackets = false + } + +\DeclareAcroFirstStyle {long} {inline} + { + only-long = true , + brackets = false + } + +\DeclareAcroFirstStyle {square} {inline} + { brackets-type = [] } + +\DeclareAcroFirstStyle {plain} {inline} + { + brackets = false , + between = -- + } + +\DeclareAcroFirstStyle {plain-reversed} {inline} + { + brackets = false , + between = -- , + reversed = true + } + +\DeclareAcroFirstStyle {footnote} {note} + { } + +\DeclareAcroFirstStyle {footnote-reversed} {note} + { reversed = true } + +\DeclareAcroFirstStyle {sidenote} {note} + { note-command = \sidenote {#1} } + +\DeclareAcroFirstStyle {sidenote-reversed} {note} + { + note-command = \sidenote {#1} , + reversed = true + } + +\DeclareAcroFirstStyle {empty} {note} + { use-note = false } + +% -------------------------------------------------------------------------- +% extra info appearance styles: +\DeclareAcroExtraStyle {default} {inline} + { + brackets = false , + punct = true , + punct-symbol = . + } + +\DeclareAcroExtraStyle {plain} {inline} + { + brackets = false , + punct = true , + punct-symbol = + } + +\DeclareAcroExtraStyle {paren} {inline} + { + brackets = true , + punct = true , + punct-symbol = + } + +\DeclareAcroExtraStyle {bracket} {inline} + { + brackets = true , + punct = true , + punct-symbol = , + brackets-type = [] + } + +\DeclareAcroExtraStyle {comma} {inline} + { + punct = true, + punct-symbol = {,} , + brackets = false + } + +% -------------------------------------------------------------------------- +% page number appearance styles: +\DeclareAcroPageStyle {default} {inline} + { + punct = true , + punct-symbol = . + } + +\DeclareAcroPageStyle {plain} {inline} + { punct = false } + +\DeclareAcroPageStyle {comma} {inline} + { punct = true } + +\DeclareAcroPageStyle {paren} {inline} + { + brackets=true , + punct-symbol = ~ + } + +\DeclareAcroPageStyle {none} {inline} + { display = false } + +% -------------------------------------------------------------------------- +% list heading styles: +\DeclareAcroListHeading {part} {\part} +\DeclareAcroListHeading {part*} {\part*} +\DeclareAcroListHeading {chapter} {\chapter} +\DeclareAcroListHeading {chapter*} {\chapter*} +\DeclareAcroListHeading {addchap} {\addchap} +\DeclareAcroListHeading {section} {\section} +\DeclareAcroListHeading {section*} {\section*} +\DeclareAcroListHeading {addsec} {\addsec} +\DeclareAcroListHeading {subsection} {\subsection} +\DeclareAcroListHeading {subsection*} {\subsection*} +\DeclareAcroListHeading {subsubsection} {\subsubsection} +\DeclareAcroListHeading {subsubsection*} {\subsubsection*} +\DeclareAcroListHeading {none} {\use_none:n} + +% -------------------------------------------------------------------------- +% list styles: +\DeclareAcroListStyle {description} {list} + { } + +\DeclareAcroListStyle {toc} {list-of} + { } + +\DeclareAcroListStyle {lof} {list-of} + { style = lof } + +\DeclareAcroListStyle {tabular} {table} + { table = tabular } + +\DeclareAcroListStyle {longtable} {table} + { table = longtable } + +\DeclareAcroListStyle {extra-tabular} {extra-table} + { table = tabular } + +\DeclareAcroListStyle {extra-longtable} {extra-table} + { table = longtable } + +\DeclareAcroListStyle {extra-tabular-rev} {extra-table} + { + table = tabular , + reverse = true + } + +\DeclareAcroListStyle {extra-longtable-rev} {extra-table} + { + table = longtable , + reverse = true + } + +% -------------------------------------------------------------------------- +% register some tokens to be checked for: +\AcroRegisterTrailing . {dot} +\AcroRegisterTrailing - {dash} +\AcroRegisterTrailing \babelhyphen {babel-hyphen} + +\acsetup { activate-trailing-tokens = dot } + +% some user macros: +\cs_new_protected:Npn \acro_dot: + { \acro_if_trailing_tokens:nF {dot} {.\@} } + +\cs_new_protected:Npn \acro_space: + { \acro_if_trailing_tokens:nF {dash,babel-hyphen} { \c_space_tl } } + +% -------------------------------------------------------------------------- +% translations: +% list name +\DeclareAcroTranslation {acronym-list-name} + { + Fallback = Acronyms , + English = Acronyms , + French = Acronymes , + German = Abk\"urzungen , + Italian = Acronimi , + Portuguese = Acr\'onimos , + Spanish = Siglas , + Catalan = Sigles , + Turkish = K\i saltmalar + } + +% page name +\DeclareAcroTranslation {acronym-page-name} + { + Fallback = p. , + English = p. , + German = S. , + Portuguese = p. + } + +% pages name +\DeclareAcroTranslation {acronym-pages-name} + { + Fallback = pp. , + English = pp. , + German = S. , + Portuguese = pp. + } + +% following page +\DeclareAcroTranslation {acronym-next-page} + { + Fallback = f. , + English = f. , + German = f. , + Portuguese = s. + } + +% following pages +\DeclareAcroTranslation {acronym-next-pages} + { + Fallback = ff. , + English = ff. , + German = ff. , + Portuguese = ss. + } + +% -------------------------------------------------------------------------- +\file_input_stop: |