diff options
Diffstat (limited to 'macros/latex/contrib/acro/acro.sty')
-rw-r--r-- | macros/latex/contrib/acro/acro.sty | 4698 |
1 files changed, 4698 insertions, 0 deletions
diff --git a/macros/latex/contrib/acro/acro.sty b/macros/latex/contrib/acro/acro.sty new file mode 100644 index 0000000000..21f721615e --- /dev/null +++ b/macros/latex/contrib/acro/acro.sty @@ -0,0 +1,4698 @@ +% -------------------------------------------------------------------------- +% the ACRO package +% +% Typeset Acronyms +% +% -------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://bitbucket.org/cgnieder/acro/ +% E-Mail: contact@mychemistry.eu +% -------------------------------------------------------------------------- +% Copyright 2011--2019 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_en.tex, acro_en.pdf, README +% -------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% -------------------------------------------------------------------------- +\RequirePackage{expl3,xparse,l3keys2e,xtemplate,etoolbox} +\ProvidesExplPackage + {acro} + {2019/02/17} + {2.9} + {Typeset Acronyms} + +% -------------------------------------------------------------------------- +% 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. + } + +% -------------------------------------------------------------------------- +% logging: +\cs_new:Npn \acro_if_log:T #1 { \use:n {#1} } + +\bool_new:N \l__acro_log_acronyms_bool +\bool_new:N \l__acro_log_acronyms_verbose_bool + +\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_get_property: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} {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} {pdfstring} {pdfstring} \\ + | \__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 } + } + } + +% -------------------------------------------------------------------------- +% 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 \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_silence_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_use_single_bool +\bool_new:N \l__acro_print_only_used_bool +\bool_set_true:N \l__acro_print_only_used_bool +\bool_new:N \l__acro_hyperref_loaded_bool +\bool_new:N \l__acro_use_hyperref_bool +\bool_new:N \l__acro_xspace_bool +\bool_new:N \l__acro_custom_format_bool +\bool_new:N \l__acro_custom_long_format_bool +\bool_new:N \l__acro_strict_bool +\bool_new:N \l__acro_create_macros_bool +\bool_new:N \l__acro_first_upper_bool +\bool_new:N \l__acro_indefinite_bool +\bool_new:N \l__acro_upper_indefinite_bool +\bool_new:N \l__acro_foreign_bool +\bool_set_true:N \l__acro_foreign_bool +\bool_new:N \l__acro_sort_bool +\bool_set_true:N \l__acro_sort_bool +\bool_new:N \l__acro_capitalize_list_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_group_citation_bool +\bool_new:N \l__acro_acc_supp_bool +\bool_new:N \l__acro_tooltip_bool +\bool_new:N \l__acro_inside_tooltip_bool +\bool_new:N \l__acro_following_page_bool +\bool_new:N \l__acro_following_pages_bool +\bool_new:N \l__acro_addto_index_bool +\bool_new:N \l__acro_is_excluded_bool +\bool_new:N \l__acro_is_included_bool +\bool_new:N \l__acro_page_punct_bool +\bool_new:N \l__acro_page_brackets_bool +\bool_new:N \l__acro_page_display_bool +\bool_new:N \l__acro_new_page_numbering_bool +\bool_new:N \l__acro_first_use_brackets_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_use_note_bool +\bool_new:N \l__acro_extra_punct_bool +\bool_new:N \l__acro_extra_use_brackets_bool +\bool_new:N \l__acro_in_list_bool +\bool_new:N \l__acro_place_label_bool +\bool_new:N \l__acro_list_all_pages_bool +\bool_set_true:N \l__acro_list_all_pages_bool +\bool_new:N \g__acro_first_acronym_declared_bool +\bool_new:N \l__acro_include_endings_format_bool +\bool_new:N \l__acro_list_reverse_long_extra_bool +\bool_new:N \l__acro_use_acronyms_bool +\bool_set_true:N \l__acro_use_acronyms_bool + +\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_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_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_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} + +\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 + +% -------------------------------------------------------------------------- +% small commands for use at various places +\cs_new:Npn \acro_no_break: { \tex_penalty:D \c_ten_thousand } + +\cs_new_protected:Npn \__acro_first_upper_case:n #1 + { \tl_upper_case:n { \tl_head:n {#1} } \tl_tail:n {#1} } +\cs_generate_variant:Nn \__acro_first_upper_case:n { x } +\cs_generate_variant:Nn \tl_mixed_case:n { x } + +\cs_new_eq:NN \acro_first_upper_case:n \__acro_first_upper_case:n + +\NewDocumentCommand \acfirstupper { m } + { \acro_first_upper_case:n {#1} } + +% -------------------------------------------------------------------------- +% 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 , + 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 , + 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 , + 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 , + extra-format .tl_set:N = \l__acro_extra_format_tl , + extra-format .value_required:n = true , + single .bool_set:N = \l__acro_use_single_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_use_hyperref_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 + } + +\AtBeginDocument + { + \bool_if:NTF \l__acro_xspace_bool + { + \@ifpackageloaded {xspace} + { } + { \RequirePackage {xspace} } + \cs_new_eq:NN \acro_xspace: \xspace + } + { \cs_new:Npn \acro_xspace: {} } + } + +% -------------------------------------------------------------------------- +% setup command: +\NewDocumentCommand \acsetup { m } + { \keys_set:nn {acro} {#1} \ignorespaces } + +% -------------------------------------------------------------------------- +% 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_if_property: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_if:nT { \l__acro_hyperref_loaded_bool && \l__acro_use_hyperref_bool } + { + \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: tl var +% #2: id +% #3: text +\cs_new_protected:Npn \__acro_make_link:Nnn #1#2#3 + { + \bool_if:nTF + { \l__acro_use_hyperref_bool && \l__acro_hyperref_loaded_bool } + { + \tl_set:Nn #1 + { + \acro_hyper_link:nn {#2} { \phantom {#3} } + \acro_if_is_single:nTF {#2} + { \hbox_overlap_left:n {#3} } + { \acro_color_link:n { \hbox_overlap_left:n {#3} } } + } + } + { \tl_set:Nn #1 {#3} } + } +\cs_generate_variant:Nn \__acro_make_link:Nnn {NnV} + +\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_if:nT + { + \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_if:nT + { + !\l__acro_first_only_long_bool || + \l__acro_first_only_short_bool + } + { + \acro_write_indefinite:nn {#2} {short} + \acro_write_compact:nn {#2} {short} + } + } + } + \group_end: + } + +\cs_new_protected:Npn \__acro_open_bracket: + { + \bool_if:nT + { + !\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_if: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_if:nT + { + \l__acro_first_only_long_bool || + !\l__acro_first_only_short_bool + } + { \acro_write_expanded:nnn {#2} {first-long} {#3} } + } + {short} { + \bool_if:nT + { + !\l__acro_first_only_long_bool || + \l__acro_first_only_short_bool + } + { \acro_write_compact:nn {#2} {short} } + } + } + } + +% #1: id +\cs_new_protected:Npn \__acro_foreign_sep:n #1 + { + \bool_if: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 + { + \bool_if: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_get_property: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} + } + } + +\bool_new:N \l__acro_first_instance_bool + +\NewExpandableDocumentCommand \aciffirst {+m+m} + { \bool_if:NTF \l__acro_first_instance_bool {#1} {#2} } + +% 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} + } + +% #1: name +% #2: template +% #3: settings +\NewDocumentCommand \DeclareAcroFirstStyle {mmm} + { \acro_declare_first_style:nnn {#1} {#2} {#3} } + +% 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} + } + +% #1: name +% #2: template +% #3: settings +\NewDocumentCommand \DeclareAcroExtraStyle {mmm} + { \acro_declare_extra_style:nnn {#1} {#2} {#3} } + +% 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_if:nTF + { + \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} + } + +% #1: name +% #2: template +% #3: settings +\NewDocumentCommand \DeclareAcroPageStyle {mmm} + { \acro_declare_page_style:nnn {#1} {#2} {#3} } + +% 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} + % \prop_get:NnN \l__acro_list_headings_prop + % {#1} + % \l__acro_list_heading_cmd_tl + } + +\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} } + } + +\NewDocumentCommand \DeclareAcroListHeading {mm} + { \acro_declare_list_heading:nn {#1} {#2} } + +% -------------------------------------------------------------------------- +% 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} + { + \clist_map_inline:nn {#2} + { + \prop_get:NnNT \l__acro_class_prop {#1} \l__acro_tmpa_tl + { + \seq_set_split:NnV \l__acro_tmpa_seq {,} \l__acro_tmpa_tl + \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 } + { + \clist_map_inline:nn {#2} + { + \prop_get:NnNT \l__acro_class_prop {#1} \l__acro_tmpa_tl + { + \seq_set_split:NnV \l__acro_tmpa_seq {,} \l__acro_tmpa_tl + \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 + { + \acro_hyper_target:nn + {#1} + { + \acro_acc_supp:nn + {#1} + { + \acro_write_short:nn {#1} + { + \l__acro_list_short_format_tl + { \__acro_get_property:nn {short} {#1} } + } + } + } + } + +% #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_get_property:nn {list} {#1} } + { \__acro_get_property: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 + { + \prop_get:NnNT \l__acro_extra_prop {#1} \l__acro_tmpa_tl + { + \acro_extra_instance:VV + \l__acro_extra_instance_tl + \l__acro_tmpa_tl + } + } + +% #1: id +\cs_new_protected:Npn \__acro_list_entry_page:n #1 + { + \bool_if:nT { \cs_if_exist_p:c { 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_get_property: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_if:nTF + { + \bool_if_p:c { g__acro_#1_in_list_bool } && + ( + ( \l__acro_use_single_bool && \cs_if_exist_p:c { acro@#1@twice } ) + || + ( + !\l__acro_use_single_bool && + \cs_if_exist_p:c { acro@#1@once } && + \l__acro_print_only_used_bool + ) + ) + || + ( !\l__acro_use_single_bool && !\l__acro_print_only_used_bool ) + } + { + \acro_if_is_excluded:nnTF {#1} {#3} + { \prg_return_false: } + { + \acro_if_is_included:nnTF {#1} {#2} + { + \bool_if:nTF + { \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: } + } + +\tl_new:N \l__acro_list_entries_tl + +% 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 + \acro_get:n {##1} + \acro_if_entry:nnnT {##1} {#2} {#3} + { + \tl_put_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} } + } + } + } + } + +% 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} + } + +% #1: name +% #2: template +% #3: settings +\NewDocumentCommand \DeclareAcroListStyle {mmm} + { \acro_declare_list_style:nnn {#1} {#2} {#3} } + +% 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 + } + +% -------------------------------------------------------------------------- +% automatic typesetting, the internals of \ac: +% #1: id + +\cs_new_protected:Npn \acro_use:n #1 + { + % get the acronym and the plural settings: + \acro_get:n {#1} + \acro_is_used:nTF {#1} + { + % 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) + \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_if:nTF + { !\l__acro_use_single_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: +\seq_new:N \g__acro_declared_acronyms_seq + +\prg_new_conditional:Npnn \acro_if_defined:n #1 {p,T,F,TF} + { + \seq_if_in:NnTF \g__acro_declared_acronyms_seq {#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_get_property: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_get_property: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_get_property:nn #1#2 + { \acro_get_property:nnTF {#1} {#2} {} {} } +\cs_generate_variant:Nn \acro_get_property:nn {V} + +% #1: id +% #2: property +% #3: set case +% #4: not set case +\prg_new_protected_conditional:Npnn \acro_if_property:nn #1#2 {T,F,TF} + { + \tl_set:Nn \l__acro_tmpa_tl {#2} + \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} + \prop_if_in:cnTF + {l__acro_ \l__acro_tmpa_tl _prop} + {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +\seq_new:N \l__acro_actions_seq + +% 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} } + +\tl_new:N \l_acro_current_id_tl +\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: + \prop_get:NnNF \l__acro_short_prop {#1} \l__acro_tmpa_tl {} + \__acro_make_link:NnV \l__acro_short_tl {#1} \l__acro_tmpa_tl + % \acro_get_property:nn {#1} {short-format} + % alt: + \prop_get:NnNTF \l__acro_alt_prop {#1} \l__acro_tmpa_tl + { \__acro_make_link:NnV \l__acro_alt_tl {#1} \l__acro_tmpa_tl } + { \tl_set_eq:NN \l__acro_alt_tl \l__acro_short_tl } + % long: + \acro_get_property:nn {#1} {long} + % \acro_get_property:nn {#1} {long-format} + % foreign: + \acro_get_property:nn {#1} {foreign} + % foreign-lang: + \acro_get_property:nn {#1} {foreign-lang} + % extra: + \acro_get_property:nn {#1} {extra} + % \acro_get_property:nn {#1} {extra-format} + % single: + \acro_get_property:nn {#1} {single} + % \acro_get_property:nn {#1} {single-format} + % first-style: + \acro_get_property:nn {#1} {first-style} + % formatting + \prop_get:NnNTF \l__acro_long_format_prop {#1} + \l__acro_custom_long_format_tl + { \bool_set_true:N \l__acro_custom_long_format_bool } + { \bool_set_false:N \l__acro_custom_long_format_bool } + \acro_get_property:nn {#1} {first-long-format} + \prop_get:NnNTF \l__acro_format_prop {#1} \l__acro_custom_format_tl + { \bool_set_true:N \l__acro_custom_format_bool } + { \bool_set_false:N \l__acro_custom_format_bool } + \acro_get_property: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_get_property:nnF {#1} {long-post} + { \tl_clear:N \l__acro_long_post_tl } + \acro_get_property: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: +\seq_new:N \l__acro_endings_seq + +\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 + } + } + +\tl_new:N \l__acro_endings_tl + +\bool_new:N \l__acro_use_ending_form_bool + +% this does nothing if a non-existent ending (#1) or non-existent form (#3) is +% input +% #1: ending +% #2: id +% #3: short|alt|long +\cs_new_protected:Npn \__acro_set_ending_for:nnn #1#2#3 + { + \acro_if_ending_form_exist:nnT {#1} {#3} + { + \bool_if:nTF { \prop_item:cn {l__acro_#3_#1_form_prop} {#2} } + { \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_if:nT + { + \prop_item:cn {l__acro_#2_##1_form_prop} {#1} + && + \use:c {l__acro_##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 + { + \bool_if:NTF \l__acro_include_endings_format_bool + { + \str_if_eq:nnTF {long} {#2} + { + \bool_if:NTF \l__acro_custom_long_format_bool + { \l__acro_custom_long_format_tl } + { \tl_use:c {l__acro_#2_format_tl} } + } + { + \bool_if:NTF \l__acro_custom_format_bool + { \l__acro_custom_format_tl } + { \tl_use:c {l__acro_#2_format_tl} } + } + } + { \use:n } + { + \acro_for_endings_do:n + { + \__acro_set_ending_for:nnn {##1} {#1} {#2} + \bool_if:cT {l__acro_##1_bool} + { \tl_use:c {l__acro_#2_##1_tl} } + } + } + } + +\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} { \c_false_bool } + \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} { \c_true_bool } + \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} { \c_false_bool } + \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} { \c_true_bool } + \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} { \c_false_bool } } + % 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} { \c_true_bool } + \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} { \c_false_bool } } + % 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} { \c_true_bool } + \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} + { \prop_item:cn {l__acro_pdfstring_short_#1_prop} } + { \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} % XXX + } + { + \acro_set_ending_variables:nnn {long} {#1} {#2} + \acro_set_ending_variables:nnn {foreign} {#1} {#2} + } + } + +\NewDocumentCommand \ProvideAcroEnding {mmm} + { \acro_provide_ending:nnn {#1} {#2} {#3} } + +% -------------------------------------------------------------------------- +% 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_if:nTF + { + \bool_if_p:c { g__acro_#1_used_bool } && + ( + ( + \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_if:nT + { + !\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 } + } + { \__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} } + +\bool_new:N \g__acro_rerun_bool + +\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 + { + \token_to_str:N \acro@pages {#1} + { \seq_use:cn {g__acro_#1_pages_seq} {|} } ^^J + \token_to_str:N \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 + +% -------------------------------------------------------------------------- +% typeset the short form: +% #1: ID +% #2: short form +\cs_new_protected:Npn \acro_write_short:nn #1#2 + { + \mode_if_horizontal:F { \leavevmode } + \group_begin: + \bool_if:NTF \l__acro_custom_format_bool + { \l__acro_custom_format_tl } + { \l__acro_short_format_tl } + {#2} + \group_end: + } +\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 + { + \mode_if_horizontal:F { \leavevmode } + \group_begin: + \bool_if:NTF \l__acro_custom_format_bool + { \l__acro_custom_format_tl } + { \l__acro_alt_format_tl } + {#2} + \group_end: + } +\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 + { + \mode_if_horizontal:F { \leavevmode } + \group_begin: + \bool_if:NTF \l__acro_custom_long_format_bool + { \l__acro_custom_long_format_tl } + { \use:n } + { + \use:x + { + \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} } + } + } + } + \group_end: + } +\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_if:nTF + { + \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} + { + \prop_get:NnNT \l__acro_foreign_prop {#1} \l__acro_foreign_tl + { + \group_begin: + \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 + { + \prop_if_in:NnT \l__acro_foreign_prop {#1} + { + \tl_use:N \l__acro_foreign_sep_tl + \prop_get:NnN \l__acro_foreign_prop {#1} \l__acro_foreign_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_get_property: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 + { + \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 + } + } + +\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_if:nT { (#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 + { + \prop_get:NnNTF \l__acro_tooltip_prop {#1} \l__acro_tmpa_tl + { \__acro_check_tooltip:nV {#2} \l__acro_tmpa_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_inside_tooltip_bool + {#1} + { + \bool_set_true:N \l__acro_inside_tooltip_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 + { % \bool_set_true:N \l__acro_first_upper_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 + } + \luatex_directlua:D { \l__acro_tmpa_tl } + \cs_new_protected:Npn \acro_strcmp:nn #1#2 + { + \luatex_directlua:D + { + acro.strcmp + ( + " \__acro_escape_x:n {#1} " , + " \__acro_escape_x:n {#2} " + ) + } + } + \cs_new:Npn \__acro_escape_x:n #1 + { + \luatex_luaescapestring:D + { \etex_detokenize:D \exp_after:wN { \luatex_expanded:D {#1} } } + } + } + { \cs_new_eq:NN \acro_strcmp:nn \pdftex_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} } + = - \c_one + } + { \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 +\prop_new:N \l__acro_trailing_tokens_prop +\prop_new:N \l__acro_trailing_actions_prop +\bool_new:N \l__acro_trailing_tokens_bool +\tl_new:N \l__acro_trailing_tokens_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} } + +% 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} + } + +\NewDocumentCommand \AcroRegisterTrailing {mm} + { \acro_register_trailing_token:Nn #1 {#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} } , + activate-trailing-tokens .initial:n = dot , + deactivate-trailing-tokens .code:n = + \clist_map_inline:nn {#1} { \acro_deactivate_trailing_token:n {##1} } + } + +% 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 } } + +\NewDocumentCommand \acdot {} { \acro_dot: } +\NewDocumentCommand \acspace {} { \acro_space: } + +% --------------------------------------------------------------------------- +% 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} } } + +\DeclareExpandableDocumentCommand \acifused { m } + { \acro_if_acronym_used:nTF {#1} } + +\prg_new_conditional:Npnn \acro_if_acronym_used:n #1 { p,T,F,TF } + { + \bool_if:nTF + { + \bool_if_p:c { g__acro_#1_used_bool } && + ( !\acro_if_is_single_p:n {#1} ) + } + { \prg_return_true: } + { \prg_return_false: } + } + +\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 } + +% -------------------------------------------------------------------------- +% acronym barriers: allow local lists of only those acronyms used between two +% barriers + +\int_new:N \g__acro_barrier_int +\bool_new:N \g__acro_use_barriers_bool +\bool_new:N \g__acro_reset_at_barrier_bool +\bool_new:N \l__acro_use_barrier_bool + +\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: } + } + +\NewDocumentCommand \acbarrier {} + { \acro_barrier: } + +\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: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 + % \bool_set_false:N \l__acro_citation_all_bool + % \bool_set_false:N \l__acro_citation_first_bool + % \bool_set_false:N \l__acro_addto_index_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_if:nTF + { (#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 } + +\NewDocumentCommand \acswitchoff {} + { \acro_switch_off: } + +\NewDocumentCommand \acswitchon {} + { \acro_switch_on: } + +% 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_command:n ####1 {##2} + \exp_args:NNnx #2 ##1 {sO{}m} + { + \acro_begin: + \acro_reset_specials: + \keys_set:nn {acro} {########2} + \acro_check_and_mark_if:nn {########1} {########3} + \exp_not:o { \__acro_tmp_command:n {####3} } + \acro_end: + } + } + } +\cs_generate_variant:Nn \acro_define_new_acro_command:NN {cc} + +% 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_command:nn ####1####2 {##2} + \exp_args:NNnx #2 ##1 {smm} + { + \acro_begin: + \acro_reset_specials: + \acro_check_and_mark_if:nn {########1} {########2} + \exp_not:o { \__acro_tmp_command:nn {####2} {####3} } + \acro_end: + } + } + } +\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_long:n #1 + { \prop_item:Nn \l__acro_long_prop {#1} } + +\cs_new:Npn \acro_expandable_long_plural:n #1 + { + \bool_if:nTF + { \prop_item:Nn \l__acro_long_plural_form_prop {#1} } + { \prop_item:Nn \l__acro_long_plural_prop {#1} } + { + \prop_item:Nn \l__acro_long_prop {#1} + \prop_item:Nn \l__acro_long_plural_prop {#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} } + } + +\cs_new:Npn \acro_pdf_string_short:n #1 + { + \acro_if_star_gobble:nTF {#1} + { \prop_item:Nn \l__acro_pdfstring_short_prop } + { \prop_item:Nn \l__acro_pdfstring_short_prop {#1} } + } + +\cs_new:Npn \acro_pdf_string_alt:n #1 + { + \acro_if_star_gobble:nTF {#1} + { \prop_item:Nn \l__acro_pdfstring_alt_prop } + { \prop_item:Nn \l__acro_pdfstring_alt_prop {#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} } + } {} + } + +% -------------------------------------------------------------------------- +% additional variables: +\tl_new:N \l__acro_current_property_tl + +% -------------------------------------------------------------------------- +% 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 + { + \tl_if_blank:VT \l__acro_current_property_tl + { \acro_serious_message:n {no-id} } + \str_if_eq:nnF {#2} {short} + { + \bool_if:cF { l__acro_#1_short_set_bool } + { + \keys_set:nn { acro / declare-acronym } { short = {#1} } + \acro_harmless_message:nn {substitute-short} {#1} + } + } + % \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_property_check:nn #1#2 + { + \cs_if_exist:cTF { l__acro_#1_short_set_bool } + { + \bool_if:cT { l__acro_#1_short_set_bool } + { \acro_serious_message:nnn {doubled-property} {#1} {#2} } + } + { + \bool_new:c { l__acro_#1_short_set_bool } + \bool_set_true:c { l__acro_#1_short_set_bool } + } + } + +% -------------------------------------------------------------------------- +% the internal property selection functions for \DeclareAcronym: +\prop_new:N \g__acro_properties_prop + +\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} + \cs_new_protected:cpn {__acro_declare_#1:nn} ##1##2 {#3} + \cs_generate_variant:cn {__acro_declare_#1:nn} {V} + % \bool_new:c {l__acro_ \l__acro_current_property_tl _#1_set_bool} + \keys_define:nn {acro/declare-acronym} + { + #2 .code:n = + \use:c {__acro_declare_#1:Vn} \l__acro_current_property_tl {##1} + \bool_set_true:c {l__acro_ \l__acro_current_property_tl _#2_set_bool} + } + \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_simple_property:n #1 + { + \tl_set:Nn \l__acro_tmpa_tl {#1} + \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} + \tl_clear_new:c {l__acro_ \l__acro_tmpa_tl _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} { \c_false_bool } + \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} { \c_false_bool } + } + \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} { \c_false_bool } + \bool_if:cF {l__acro_#1_long-##1_set_bool} + { \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} { \c_false_bool } + \bool_if:cF {l__acro_#1_foreign-##1_set_bool} + { \prop_put:cnv {l__acro_foreign_##1_prop} {#1} {l__acro_default_foreign_##1_tl} } + } + } + +\acro_declare_simple_property:n {first-style} + +% list: +\acro_declare_simple_property: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_simple_property:n {short-indefinite} + +% long indefinite article: +\acro_declare_simple_property:n {long-indefinite} + +% pre long: +\acro_declare_simple_property:n {long-pre} + +% post long: +\acro_declare_simple_property:n {long-post} + +% post: +\acro_declare_simple_property:n {post} + +% sort: +\acro_declare_property:nnn {sort} {sort} + { + \bool_if:cF { l__acro_#1_index-sort_set_bool } + { \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 + { + \bool_if:cF {l__acro_#1_alt_set_bool} + { \acro_harmless_message:nn {no-alternative} {#1} } + } + +% alt. indefinite article: +\acro_declare_simple_property:n {alt-indefinite} + +% foreign: +\acro_declare_simple_property:n {foreign} + +% foreign-lang: +\acro_declare_simple_property:n {foreign-lang} + +% format: +\acro_declare_simple_property:n {format} + +% short format: +\acro_declare_property_alias:nn {short-format} {format} + +% long format: +\acro_declare_simple_property:n {long-format} + +% first long format: +\acro_declare_simple_property:n {first-long-format} + +% pdfstring -- currently needs to be done `by hand': +\prop_new:N \l__acro_pdfstring_short_prop +\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_property_tl #1 // \acro_stop: , + } + +\prop_new:N \l__acro_pdfstring_alt_prop +\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_property_tl #1 // \acro_stop: , + } + +% class: +\acro_declare_simple_property:n {class} + +% extra information: +\acro_declare_simple_property:n {extra} + +% single appearances: +\acro_declare_simple_property:n {single} + +% single format: +\acro_declare_simple_property:n {single-format} + +% acc supp: +\acro_declare_property:nn {acc_supp} {accsupp} + +% tooltip: +\acro_declare_simple_property:n {tooltip} + +% citation -- currently needs to be done `by hand': +\prop_new:N \l__acro_citation_prop +\prop_new:N \l__acro_citation_pre_prop +\prop_new:N \l__acro_citation_post_prop +\cs_new_protected:Npn \__acro_declare_citation:nw #1#2[#3]#4[#5]#6#7 \acro_stop: + { + % no options: #1: ID, #2: property, #3 is blank + % 1 option: #1: ID, #4: property, #3: option, #5 is blank + % 2 options: #1: ID: #6: property, #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 } + +\keys_define:nn { acro / declare-acronym } + { + cite .code:n = + \__acro_declare_citation:Vw + \l__acro_current_property_tl #1 [][] \scan_stop: \acro_stop: + } + +\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} + \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{<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_simple_property:n {index} + +% index-sort: +\acro_declare_simple_property:n {index-sort} + +% index-cmd: +\acro_declare_simple_property: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 + { + \seq_gput_right:Nn \g__acro_declared_acronyms_seq {#1} + \bool_gset_true:N \g__acro_first_acronym_declared_bool + \tl_set:Nn \l__acro_current_property_tl {#1} + \acro_for_properties_do:n + { \bool_new:c {l__acro_#1_##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} + \tl_clear:N \l__acro_current_property_tl + \bool_if:cF {l__acro_#1_short_set_bool} + { \acro_serious_message:nnn {missing} {#1} {short} } + \bool_if:cF {l__acro_#1_long_set_bool} + { \acro_serious_message:nnn {missing} {#1} {long} } + \__acro_log_acronym:n {#1} + } + +% -------------------------------------------------------------------------- +% the user command: +\NewDocumentCommand \DeclareAcronym {mm} + { \acro_declare_acronym:nn {#1} {#2} } + +% -------------------------------------------------------------------------- +% 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 + +\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 + \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: + } + +\NewDocumentCommand \printacronyms { O{} } + { \acro_print_acronyms:n {#1} } + +% -------------------------------------------------------------------------- +% 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 } + } + } + +\NewDocumentCommand \DeclareAcroTranslation {mm} + { \acro_declare_translation:nn {#1} {#2} } +\@onlypreamble \DeclareAcroTranslation + +% 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}\@ } + +% -------------------------------------------------------------------------- +% definition file: +% \tl_const:Nn \c_acro_definition_file_name_tl {acro} +% \tl_const:Nn \c_acro_definition_file_extension_tl {def} + +% \file_if_exist:nTF +% { \c_acro_definition_file_name_tl .\c_acro_definition_file_extension_tl } +% { +% \@onefilewithoptions +% {\c_acro_definition_file_name_tl} [] [] +% \c_acro_definition_file_extension_tl +% } +% { \acro_serious_message:n {definitions-missing} } + + +% -------------------------------------------------------------------------- +% 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} + +% -------------------------------------------------------------------------- +% the user commands +% automatic: +\NewAcroCommand \ac + { \acro_use:n {#1} } + +\NewAcroCommand \iac + { + \acro_indefinite: + \acro_use:n {#1} + } + +\NewAcroCommand \Iac + { + \acro_first_upper: + \acro_indefinite: + \acro_use:n {#1} + } + +\NewAcroCommand \Ac + { + \acro_first_upper: + \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 \Acsingle + { + \acro_get:n {#1} + \acro_first_upper: + \acro_single:n {#1} + } + +% short: +\NewAcroCommand \acs + { \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} + } + +% 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} + } + +% long: +\NewAcroCommand \acl + { \acro_long:n {#1} } + +\NewAcroCommand \iacl + { + \acro_indefinite: + \acro_long:n {#1} + } + +\NewAcroCommand \Iacl + { + \acro_first_upper: + \acro_indefinite: + \acro_long:n {#1} + } + +\NewAcroCommand \Acl + { + \acro_first_upper: + \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 \iacf + { + \acro_indefinite: + \acro_first:n {#1} + } + +\NewAcroCommand \Iacf + { + \acro_first_upper: + \acro_indefinite: + \acro_first:n {#1} + } + +\NewAcroCommand \Acf + { + \acro_first_upper: + \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} + } + +% -------------------------------------------------------------------------- +% endings: +\ProvideAcroEnding {plural} {s} {s} + +% -------------------------------------------------------------------------- +% 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. + } + +% -------------------------------------------------------------------------- +% allow for a configuration file: +\tl_const:Nn \c_acro_config_file_name_tl {acro} +\tl_const:Nn \c_acro_config_file_extension_tl {cfg} + +\file_if_exist:nT + { \c_acro_config_file_name_tl .\c_acro_config_file_extension_tl } + { + \@onefilewithoptions + {\c_acro_config_file_name_tl} [] [] + \c_acro_config_file_extension_tl + } + +\tex_endinput:D +% -------------------------------------------------------------------------- +% HISTORY: +2012/06/22 v0.1 - first public release +2012/06/23 v0.1a - bug fix, added `strict' and `macros' option and creation of + shortcut macros + - added capitalized version of long forms + - added `sort' option +2012/06/24 v0.1b - added \Acf and \Acfp, added option `plural-ending' +2012/06/24 v0.1c - added excluded argument to \printacronyms +2012/06/24 v0.2 - renamed \NewAcronym => \DeclareAcronym + \AcronymFormat => \DeclareAcronymFormat +2012/06/25 v0.2a - new first-style's: `short' and `reversed' +2012/06/25 v0.3 - new list formats: extra-tabular, extra-longtable, + extra-tabular-rev, extra-longtable-rev + - extra precaution when using \printacronyms to avoid errors. +2012/06/27 v0.3a - new option `list-caps', \Acp added +2012/06/29 v0.3b - extended the `text' template to the `acro-first' object + - added `acro-first' instances `plain' and `plain-reversed' +2012/07/16 v0.3c - small adjustments to the documentation +2012/07/23 v0.3d - first CTAN version +2012/07/24 v0.3e - adapted to updated l3kernel +2012/09/28 v0.4 - added means to add citations to acronyms +2012/10/07 v0.4a - new options: "uc-cmd", "list-long-format" + - preliminary language support, needs package `translations' +2012/11/30 v0.5 - added starred variants of the commands that won't mark an + acronym as used + - added \acreset{<id>} + - added preliminary support for pdf strings: in pdf strings + always the singular lowercase short version is inserted + (the equivalent of \acs) +2012/12/14 v0.6 - bug with not-colored links resolved + - bug introduced with the last update (full expansion of the + short entry) resolved + - option `xspace' added +2013/01/02 v0.6a - \acuseall +2013/01/16 v1.0 - new syntax of \DeclareAcronym + - new option `version' + - new `accsupp' acronym property + - new `sort' acronym property + - new syntax of \printacronyms + - new default: `sort=true' + - new options `page-ranges', `next-page', `next-pages', + `pages-name', `record-pages' + - no automatic label placement for page number referencing + any more +2013/01/26 v1.1 - bug fix in the plural detection + - new keys `long-pre' and `long-post' + - new keys `index', `index-sort' and `index-cmd' + - new options `index' and `index-cmd' +2013/01/29 v1.1a - added `long-format' key + - renamed `format' key into `short-format', kept `format' for + compatibility reasons +2013/02/09 v1.2 - error message instead of hanging when an undefined acronym + is used + - added `first-long-format' key and `first-long-format' option + - added \acflike and \acfplike + - improvements and bug fixes to the page recording mechanism + - new option `mark-as-used' + - new keys: `short-indefinite', `alt-indefinite' and + `long-indefinite' + - new commands: \iac, \Iac, \iacs, \Iacs, \iaca, \Iaca, \iacl, + \Iacl, \iacf, \Iacf, \iacflike and \Iacflike +2013/04/04 v1.2a - added Portuguese translations +2013/05/06 v1.3 - protected internal commands where appropriate + - new option `sort' to \printacronyms + - renamed options `print-acronyms/header' and `list-header' + into `print-acronyms/heading' and `list-heading' + - fix: added missing group to \printacronyms + - add key `foreign' + - rewritten page-recording: + * most importantly: record them at shipout; this is done + when \acro@used@once or \acro@used@twice are written to + the aux file + * no restrictions regarding \pagenumbering + * options `page-ranges' and `record-pages' are deprecated + * new options `following-page' and `following-pages' + - disable \@noitemerr in the list of acronyms: we don't need + it there but there are occasions when it is annoying + - cleaned the sty file, added a few more comments +2013/05/09 v1.3a - Bug fix: corrected wrong argument checking in \Ac, thanks + to Michel Voßkuhle +2013/05/30 v1.3b - obey \if@filesw +2013/06/16 v1.3c - added \leavevmode to \acro_get:n +2013/07/08 v1.3d - corrected wrong call of \leavevmode in the list + (list-type=list) +2013/08/07 v1.3e - bug fix in the list when testing for used acronyms + - new commands \acifused, \acfirstupper +2013/08/27 v1.4 - new property `list' +2013/09/02 v1.4a - bug fix: used acronyms are added to the list when the list + is printed before the use + - \DeclareAcronym may now be used after \begin{document} +2013/09/24 v1.4b - bug fix: only-used=false works again for only declared but + unused acronyms (only if option single is not used) +2013/11/04 v1.4c - remove \hbox from the written short form + - changed \__acro_make_link:nNN in a way that it doesn't box + its when links are deactivated +2013/11/22 v1.4d - require `l3sort' independently from the `sort' option + instead of at begin document in order to avoid conflicts + with `babel' and `french' +2013/12/18 v1.5 - new option `label=true|false' that + places \label{<prefix>:<id>} the first time an acronym is + used + - new option `pages=first|all' that determines if in the list + of acronyms all appearances are listed or only the first + time; implicitly sets `label=true' +2015/02/26 v1.6 - new `acro-title' instance `none' + - change of expl3's tl uppercasing function (adapt to updates + of l3kernel and friends + - new package option `messages=silent|loud' + - fix issue https://bitbucket.org/cgnieder/acro/issue/23/ + - fix issue https://bitbucket.org/cgnieder/acro/issue/24/ + - fix issue https://bitbucket.org/cgnieder/acro/issue/28/ + - drop support for version 0 +2015/04/08 v1.6a - more generalized user command definitions, see + http://tex.stackexchange.com/q/236362/ for an application +2015/05/10 v1.6b - \ProcessKeysPackageOptions , + - correct bug http://tex.stackexchange.com/q/236860/ : + option `pages = first' works again +2015/08/16 v2.0 - fix https://bitbucket.org/cgnieder/acro/issue/36 + - implement https://bitbucket.org/cgnieder/acro/issue/39 + - implement https://bitbucket.org/cgnieder/acro/issue/40 + (=> new option `group-cite-cmd') + - add ideas for https://bitbucket.org/cgnieder/acro/issue/41 + - implement https://bitbucket.org/cgnieder/acro/issue/18 + - implement https://bitbucket.org/cgnieder/acro/issue/43 + - further generalization for defining user commands: + \NewAcroCommand, \NewPseudoAcroCommand and siblings + - bug fix in indefinite versions with first-upper + - add `short-<ending>-form' equivalent to + `long-<ending>-form' + (https://bitbucket.org/cgnieder/acro/issue/44) + - implement https://bitbucket.org/cgnieder/acro/issue/35 + - new option `single-form' +2015/08/25 v2.0a - fix https://bitbucket.org/cgnieder/acro/issue/38 and + https://bitbucket.org/cgnieder/acro/issue/49 +2015/08/29 v2.0b - fix https://bitbucket.org/cgnieder/acro/issue/44 + - fix https://bitbucket.org/cgnieder/acro/issue/45 + - implement https://bitbucket.org/cgnieder/acro/issue/42 +2015/09/05 v2.1 - add list object type `list-of' that prints the list like a + toc or lof, new option `list-short-width', + - correct bug in the `plain' extra style + - implemented `tooltip' property + - remove \tl_to_lowercase:n +2015/10/03 v2.2 - fix https://bitbucket.org/cgnieder/acro/issue/52 + - fix typo in `list-of' object + - \DeclareAcroListStyle + - \DeclareAcroListHeading + - input `acro.cfg' if present + - all acro commands have an optional argument: \ac*[]{} +2016/01/07 v2.2a - \prop_get:Nn => \prop_item:Nn +2016/01/21 v2.2b - fix issue #59 +2016/02/02 v2.2c - fix issue #60 +2016/03/14 v2.3 - foreign-format may be a macro taking an argument + - \Aca, \Acsingle + - properties `single' and `single-format', option + `single-format' => issue #62 + - property `first-style' => issue #61 + - fix issue #64: long-post entry is now added *after* the + endings + - property `foreign-lang' + - fix issue #65 +2016/03/25 v2.4 - extend class mechanism: classes can be used like tags + - add idea of `barriers' and list local to those barriers + => new option `reset-at-barriers' + => new option `local-to-barriers' for \printacronyms + => new command \acbarrier +2016/04/14 v2.4a - if undefined acronym is used and `messages = silent' is + active don't through error +2016/05/03 v2.4b - expand `pdfstring' property before saving => issue #69 + - \ProvideAcroEnding can be used twice – it then just sets + the defaults + - the option <ending>-ending has a new syntax: + * <ending>-ending = <val> sets all endings to <val> + * <ending>-ending = <val1>/<val2> sets short endings to + <val1> and long endings to <val2> + - a single appearance should be treated like a first + appearance as far as citations are concerned +2016/05/25 v2.5 - some of the entries added to the aux file need to be + written \immediate in order to avoid this trap: + http://tex.stackexchange.com/q/116001/ + - cleaner interface for first-style template definitions + - new `acro-first' instances `footnote-reversed' and + `sidenote-reversed' + - new commands \DeclareAcroFirstStyle, \DeclareAcroExtraStyle + and \DeclareAcroPageStyle + - add warning `ending-before-acronyms' to options setting the + defaults of an ending; this should avoid confusion + - property declaration for acronyms should be handled by + internal functions + - improvements in the list template code + - logging info when an acronym is declared + - remove deprecated options + - new option `use-barriers' + - new option `following-pages*' + - option `page-ref' replaced by option `page-style' +2016/05/26 v2.5a - bug fix: remove erroneous group in `<ending>-ending' option +2016/05/30 v2.5b - fix issue #72 +2016/07/20 v2.6 - \l__acro_use_acronyms_bool can be used to disable \ac + e.g. in the trial phase of a table like `tabu'; interface: + \acro_switch_off: and \acswitchoff + - fix issue #79 + - fix issue #74 + - fix error: acronyms with same sort entry are not + overwritten any more in the list of acronyms +2016/08/13 v2.6a - fix issues #80 and #81 +2016/08/13 v2.6b - version stepped by accident +2016/08/16 v2.6c - really fixes issue #81 +2016/08/30 v2.6d - fix issue #82 +2016/09/04 v2.6e - fix issue in http://tex.stackexchange.com/q/270034/ +2017/01/22 v2.7 - rename \acro_get_property:nn into \__acro_get_property:nn + - \acro_get_property:nn, \acro_get_property:nnTF, + \acro_if_property:nnTF, retrieve property without error if + not set + - make \__acro_declare_property functions public + - \acro_add_action:n (adds code to \acro_get:n) +2017/02/09 v2.7a - adapt to integration of l3sort into l3kernel +2017/06/21 v2.7b - fix issue #93 +2017/08/28 v2.7c - fix issue #96 +2018/01/30 v2.8 - fix issue #94 + - document `format-include-endings', fix issue #99 + - new property `post' + - \aciffirst + - resolve issue #95 +2019/02/17 v2.9 - small redefinition of \acro_get_foreign:n which allows + `foreign-sep' to be a & + - fix issue #116 + - implemented issue #112 + +% -------------------------------------------------------------------------- +% TODO: +- extend option `macros' to also define uppercase macros, possibly as a choice +- add \ACF, \ACFP, \ACL and \ACLP that will print all words of the long form + capitalized |