% -------------------------------------------------------------------------- % the ACRO package % % Typeset Acronyms % % -------------------------------------------------------------------------- % Clemens Niederberger % Web: https://bitbucket.org/cgnieder/acro/ % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- % Copyright 2011-2013 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, acro0.def, acro1.def, acro_en.tex, acro_en.pdf, README % -------------------------------------------------------------------------- % If you have any ideas, questions, suggestions or bugs to report, please % feel free to contact me. % -------------------------------------------------------------------------- \ProvidesFile{acro1.def} % -------------------------------------------------------------------------- % additional variables: \tl_new:N \l__acro_current_key_tl % -------------------------------------------------------------------------- % key and order checking \msg_new:nnnn { acro } { no-id } { Something~has~gone~wrong,~you've~probably~forgotten~to~set~the~acronym~ID. } { Something~has~gone~wrong,~you've~probably~forgotten~to~set~the~acronym~ID. } \msg_new:nnnn { acro } { before-short } { The~key~`#2'~needs~to~be~set~after~`short'. } { You've~set~The~key~`#2'~before~the~`short'~key~for~acronym~`#1'~but~ needs~to~be~set~after~it. } \msg_new:nnnn { acro } { missing } { The~`#2'~key~for~acronym~`#1'~is~missing. } { The~`#2'~key~for~acronym~`#1'~is~missing. } \msg_new:nnnn { acro } { doubled-key } { It~seems~to~me~you~have~used~the~`#1'~key~before. } { It~seems~to~me~you~have~used~the~`#1'~key~before.~If~you~haven't~there's~ something~different~wrong~and~I'm~lost.~You~'re~on~your~own~now. } \cs_new_protected:Npn \__acro_key_check:nn #1#2 { \tl_if_blank:VT \l__acro_current_key_tl { \msg_error:nn { acro } { no-id } } \bool_if:cF { l__acro_#1_short_set_bool } { \msg_error:nnxx { acro } { before-short } { #1 } { #2 } } \bool_new:c { l__acro_#1_#2_set_bool } \bool_set_true:c { l__acro_#1_#2_set_bool } } \cs_new_protected:Npn \__acro_first_key_check:n #1 { \cs_if_exist:cTF { l__acro_#1_short_set_bool } { \bool_if:cT { l__acro_#1_short_set_bool } { \msg_error:nnx { acro } { doubled-key } { #1 } } } { \bool_new:c { l__acro_#1_short_set_bool } \bool_set_true:c { l__acro_#1_short_set_bool } } } % -------------------------------------------------------------------------- % the internal selection functions: % short: \cs_new_protected:Npn \__acro_declare_short:nn #1#2 { \__acro_first_key_check:n { #1 } \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:Nnx \l__acro_pdfstring_prop { #1 } { \exp_not:n { #2 } } \prop_put:Nnn \l__acro_short_plural_prop { #1 } { \l__acro_default_plural_tl } \prop_put:Nnx \l__acro_short_indefinite_prop { #1 } { \l__acro_default_indefinite_tl } \prop_put:Nnx \l__acro_alt_indefinite_prop { #1 } { \l__acro_default_indefinite_tl } \prop_put:Nnx \l__acro_pdfstring_plural_prop { #1 } { \exp_not:n { #2 } \exp_not:V \l__acro_default_plural_tl } } \cs_generate_variant:Nn \__acro_declare_short:nn { V } % short plural: \cs_new_protected:Npn \__acro_declare_short_plural:nn #1#2 { \__acro_key_check:nn { #1 } { short-plural } \prop_put:Nnn \l__acro_short_plural_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_short_plural:nn { V } % long: \cs_new_protected:Npn \__acro_declare_long:nn #1#2 { \__acro_key_check:nn { #1 } { long } \prop_put:Nnn \l__acro_replace_long_plural_prop { #1 } { \c_false_bool } \prop_put:Nnn \l__acro_long_prop { #1 } { #2 } \prop_put:Nnx \l__acro_long_indefinite_prop { #1 } { \l__acro_default_indefinite_tl } \bool_if:cF { l__acro_#1_long-plural_set_bool } { \prop_put:Nnn \l__acro_long_plural_prop { #1 } { \l__acro_default_plural_tl } } } \cs_generate_variant:Nn \__acro_declare_long:nn { V } % list: \cs_new_protected:Npn \__acro_declare_list:nn #1#2 { \__acro_key_check:nn { #1 } { list } \prop_put:Nnn \l__acro_list_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_list:nn { V } % long plural: \cs_new_protected:Npn \__acro_declare_long_plural:nn #1#2 { \__acro_key_check:nn { #1 } { long-plural } \prop_put:Nnn \l__acro_replace_long_plural_prop { #1 } { \c_false_bool } \prop_put:Nnn \l__acro_long_plural_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_long_plural:nn { V } % long plural form: \cs_new_protected:Npn \__acro_declare_long_plural_form:nn #1#2 { \__acro_key_check:nn { #1 } { long-plural-form } \prop_put:Nnn \l__acro_replace_long_plural_prop { #1 } { \c_true_bool } \prop_put:Nnn \l__acro_long_plural_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_long_plural_form:nn { V } % short indefinite article: \cs_new_protected:Npn \__acro_declare_short_indefinite:nn #1#2 { \__acro_key_check:nn { #1 } { short-indefinite } \prop_put:Nnn \l__acro_short_indefinite_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_short_indefinite:nn { V } % long indefinite article: \cs_new_protected:Npn \__acro_declare_long_indefinite:nn #1#2 { \__acro_key_check:nn { #1 } { long-indefinite } \prop_put:Nnn \l__acro_long_indefinite_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_long_indefinite:nn { V } % pre long: \cs_new_protected:Npn \__acro_declare_long_pre:nn #1#2 { \__acro_key_check:nn { #1 } { long-pre } \prop_put:Nnn \l__acro_long_pre_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_long_pre:nn { V } % post long: \cs_new_protected:Npn \__acro_declare_long_post:nn #1#2 { \__acro_key_check:nn { #1 } { long-post } \prop_put:Nnn \l__acro_long_post_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_long_post:nn { V } % sort: \cs_new_protected:Npn \__acro_declare_sort:nn #1#2 { \__acro_key_check:nn { #1 } { sort } \prop_put:Nnn \l__acro_sort_prop { #1 } { #2 } \bool_if:cF { l__acro_#1_index-sort_set_bool } { \prop_put:Nnn \l__acro_index_sort_prop { #1 } { #2 } } } \cs_generate_variant:Nn \__acro_declare_sort:nn { V } % alternative: \cs_new_protected:Npn \__acro_declare_alt:nn #1#2 { \__acro_key_check:nn { #1 } { alt } \prop_put:Nnn \l__acro_alt_prop { #1 } { #2 } \prop_put:Nnx \l__acro_alt_indefinite_prop { #1 } { \l__acro_default_indefinite_tl } } \cs_generate_variant:Nn \__acro_declare_alt:nn { V } % alt. indefinite article: \cs_new_protected:Npn \__acro_declare_alt_indefinite:nn #1#2 { \__acro_key_check:nn { #1 } { alt-indefinite } \prop_put:Nnn \l__acro_alt_indefinite_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_alt_indefinite:nn { V } % foreign: \cs_new_protected:Npn \__acro_declare_foreign:nn #1#2 { \__acro_key_check:nn { #1 } { alt } \prop_put:Nnn \l__acro_foreign_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_foreign:nn { V } % format: \cs_new_protected:Npn \__acro_declare_format:nn #1#2 { \__acro_key_check:nn { #1 } { format } \prop_put:Nnn \l__acro_format_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_format:nn { V } % long format: \cs_new_protected:Npn \__acro_declare_long_format:nn #1#2 { \__acro_key_check:nn { #1 } { long-format } \prop_put:Nnn \l__acro_long_format_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_long_format:nn { V } % first long format: \cs_new_protected:Npn \__acro_declare_first_long_format:nn #1#2 { \__acro_key_check:nn { #1 } { first-long-format } \prop_put:Nnn \l__acro_first_long_format_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_first_long_format:nn { V } % pdfstring: \cs_new_protected:Npn \__acro_declare_pdfstring:nw #1#2/#3/#4 \acro_stop: { \__acro_key_check:nn { #1 } { pdfstring } \prop_put:Nnx \l__acro_pdfstring_prop { #1 } { #2 } \tl_if_empty:nTF { #3 } { \prop_put:Nnx \l__acro_pdfstring_plural_prop { #1 } { \exp_not:n { #2 } \exp_not:V \l__acro_default_plural_tl } } { \prop_put:Nnx \l__acro_pdfstring_plural_prop { #1 } { \exp_not:n { #2#3 } } } } \cs_generate_variant:Nn \__acro_declare_pdfstring:nw { V } % class: \cs_new_protected:Npn \__acro_declare_class:nn #1#2 { \__acro_key_check:nn { #1 } { class } \prop_put:Nnn \l__acro_class_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_class:nn { V } % extra information: \cs_new_protected:Npn \__acro_declare_extra:nn #1#2 { \__acro_key_check:nn { #1 } { extra } \prop_put:Nnn \l__acro_extra_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_extra:nn { V } % acc supp: \cs_new_protected:Npn \__acro_declare_acc_supp:nn #1#2 { \__acro_key_check:nn { #1 } { accsupp } \prop_put:Nnn \l__acro_acc_supp_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_acc_supp:nn { V } % citation: \cs_new_protected:Npn \__acro_declare_citation:nw #1#2[#3]#4[#5]#6#7 \acro_stop: { % no options: #1: ID, #2: key, #3 is blank % 1 option: #1: ID, #4: key, #3: option, #5 is blank % 2 options: #1: ID: #6: key, #3: first option, #5: second option \tl_if_blank:nF { #2#4#6 } { \tl_if_empty:nTF { #3 } { \__acro_declare_citation_aux:nnnn { #1 } { } { } { #2 } } { \tl_if_empty:nTF { #5 } { \__acro_declare_citation_aux:nnnn { #1 } { #3 } { } { #4 } } { \__acro_declare_citation_aux:nnnn { #1 } { #3 } { #5 } { #6 } } } } } \cs_generate_variant:Nn \__acro_declare_citation:nw { V } \cs_new_protected:Npn \__acro_declare_citation_aux:nnnn #1#2#3#4 { \__acro_key_check:nn { #1 } { cite } \prop_put:Nnn \l__acro_citation_prop { #1 } { #4 } \tl_if_empty:nF { #2 } { \prop_put:Nnn \l__acro_citation_pre_prop { #1 } { #2 } } \tl_if_empty:nF { #3 } { \prop_put:Nnn \l__acro_citation_post_prop { #1 } { #3 } } } % TODO: % add index entries, by default \index{@} % index: overwrite default @ entry completely % index-sort: overwrite the part of @ 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' key that allows to add arbitrary % TeX code after an acronym is typeset % index: \cs_new_protected:Npn \__acro_declare_index:nn #1#2 { \__acro_key_check:nn { #1 } { index } \prop_put:Nnn \l__acro_index_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_index:nn { V } % index-sort: \cs_new_protected:Npn \__acro_declare_index_sort:nn #1#2 { \__acro_key_check:nn { #1 } { index-sort } \prop_put:Nnn \l__acro_index_sort_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_index_sort:nn { V } % index-cmd: \cs_new_protected:Npn \__acro_declare_index_cmd:nn #1#2 { \__acro_key_check:nn { #1 } { index-cmd } \prop_put:Nnn \l__acro_index_cmd_prop { #1 } { #2 } } \cs_generate_variant:Nn \__acro_declare_index_cmd:nn { V } % -------------------------------------------------------------------------- % the keys of \DeclareAcronym \keys_define:nn { acro / declare-acronym } { short .code:n = \__acro_declare_short:Vn \l__acro_current_key_tl { #1 } , short-plural .code:n = \__acro_declare_short_plural:Vn \l__acro_current_key_tl { #1 } , % short-plural-form .code:n = % \__acro_declare_short_plural_form:Vn \l__acro_current_key_tl { #1 } , alt .code:n = \__acro_declare_alt:Vn \l__acro_current_key_tl { #1 } , long .code:n = \__acro_declare_long:Vn \l__acro_current_key_tl { #1 } , long-plural .code:n = \__acro_declare_long_plural:Vn \l__acro_current_key_tl { #1 } , long-plural-form .code:n = \__acro_declare_long_plural_form:Vn \l__acro_current_key_tl { #1 } , list .code:n = \__acro_declare_list:Vn \l__acro_current_key_tl { #1 } , short-indefinite .code:n = \__acro_declare_short_indefinite:Vn \l__acro_current_key_tl { #1 } , alt-indefinite .code:n = \__acro_declare_alt_indefinite:Vn \l__acro_current_key_tl { #1 } , long-indefinite .code:n = \__acro_declare_long_indefinite:Vn \l__acro_current_key_tl { #1 } , long-pre .code:n = \__acro_declare_long_pre:Vn \l__acro_current_key_tl { #1 } , long-post .code:n = \__acro_declare_long_post:Vn \l__acro_current_key_tl { #1 } , sort .code:n = \__acro_declare_sort:Vn \l__acro_current_key_tl { #1 } , extra .code:n = \__acro_declare_extra:Vn \l__acro_current_key_tl { #1 } , foreign .code:n = \__acro_declare_foreign:Vn \l__acro_current_key_tl { #1 } , format .code:n = \__acro_declare_format:Vn \l__acro_current_key_tl { #1 } , short-format .code:n = \__acro_declare_format:Vn \l__acro_current_key_tl { #1 } , long-format .code:n = \__acro_declare_long_format:Vn \l__acro_current_key_tl { #1 } , first-long-format .code:n = \__acro_declare_first_long_format:Vn \l__acro_current_key_tl { #1 } , class .code:n = \__acro_declare_class:Vn \l__acro_current_key_tl { #1 } , cite .code:n = \__acro_declare_citation:Vw \l__acro_current_key_tl #1 [][] \scan_stop: \acro_stop: , pdfstring .code:n = \__acro_declare_pdfstring:Vw \l__acro_current_key_tl #1 // \acro_stop: , accsupp .code:n = \__acro_declare_acc_supp:Vn \l__acro_current_key_tl { #1 } , index .code:n = \__acro_declare_index:Vn \l__acro_current_key_tl { #1 } , index-sort .code:n = \__acro_declare_index_sort:Vn \l__acro_current_key_tl { #1 } , index-cmd .code:n = \__acro_declare_index_cmd:Vn \l__acro_current_key_tl { #1 } } \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:NT \l__acro_strict_bool { \cs_set:cpn { #1 } { \ac { #1 } \acro_xspace: } } } { \cs_new:cpn { #1 } { \ac { #1 } \acro_xspace: } } } } % -------------------------------------------------------------------------- % internal acronym declaring function: \cs_new_protected:Npn \acro_declare_acronym:nn #1#2 { \tl_set:Nn \l__acro_current_key_tl { #1 } \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 } \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 } \tl_clear:N \l__acro_current_key_tl \bool_if:cF { l__acro_#1_short_set_bool } { \msg_error:nnxx { acro } { missing } { #1 } { short } } \bool_if:cF { l__acro_#1_long_set_bool } { \msg_error:nnxx { acro } { missing } { #1 } { long } } } % -------------------------------------------------------------------------- % the user command: \NewDocumentCommand \DeclareAcronym { mm } { \acro_declare_acronym:nn { #1 } { #2 } } % \@onlypreamble\DeclareAcronym % -------------------------------------------------------------------------- % print the list: % #1: list of classes % #2: list of excluded classes \tl_new:N \l__acro_included_classes_tl \tl_new:N \l__acro_excluded_classes_tl \cs_new_protected:Npn \acro_use_list_instance:nn #1#2 { \UseInstance { acro-list } { \l__acro_list_instance_tl } { \l__acro_list_type_tl } { #1 } { #2 } } \cs_generate_variant:Nn \acro_use_list_instance:nn { VV } \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 , header .code:n = \acro_option_deprecated:nn { header } { heading } \tl_set:Nn \l__acro_list_title_tl { #1 } , heading .tl_set:N = \l__acro_list_title_tl , sort .bool_set:N = \l__acro_sort_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 \keys_set:nn { acro / print-acronyms } { #1 } \iow_now:Nx \@auxout { \string \acro@print@list } \bool_if:NT \l__acro_sort_bool { \acro_sort_prop:N \l__acro_short_prop } \UseInstance { acro-title } { \l__acro_list_title_tl } { \l__acro_list_name_tl } \cs_if_exist:NTF \acro@printed@list { \acro_use_list_instance:VV \l__acro_included_classes_tl \l__acro_excluded_classes_tl } { \@latex@warning@no@line {Rerun~to~get~acronym~list~right} } \group_end: } \NewDocumentCommand \printacronyms { O{} } { \acro_print_acronyms:n { #1 } } \tex_endinput:D