diff options
author | Karl Berry <karl@freefriends.org> | 2020-04-29 21:22:29 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2020-04-29 21:22:29 +0000 |
commit | 9dc098550a08a0a6535d68c59ce28ce13fad7593 (patch) | |
tree | 87154c9583e8bd0b5335f78aec2f2c9f7803bff3 /Master/texmf-dist/tex/latex/acro/acro2.sty | |
parent | 88363fa054edfe4dafa9a338ec24f3e062c1f26a (diff) |
acro (29apr20)
git-svn-id: svn://tug.org/texlive/trunk@54937 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/acro/acro2.sty')
-rw-r--r-- | Master/texmf-dist/tex/latex/acro/acro2.sty | 4640 |
1 files changed, 4640 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/acro/acro2.sty b/Master/texmf-dist/tex/latex/acro/acro2.sty new file mode 100644 index 00000000000..c8eb1d6b996 --- /dev/null +++ b/Master/texmf-dist/tex/latex/acro/acro2.sty @@ -0,0 +1,4640 @@ +% -------------------------------------------------------------------------- +% the ACRO package +% +% Typeset Acronyms +% +% -------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/acro/ +% E-Mail: contact@mychemistry.eu +% -------------------------------------------------------------------------- +% Copyright 2011--2020 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% -------------------------------------------------------------------------- +% The acro package consists of the files +% - acro.sty, acro.definitions.tex, acro.cfg +% - acro-manual.tex, acro-manual.pdf, acro-manual.cls +% - acro.history, README +% -------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% -------------------------------------------------------------------------- +\RequirePackage{expl3,xparse,xtemplate,l3keys2e} +\RequirePackage{etoolbox} % for the document hooks + +\ProvidesExplPackage + {acro2} + {2020/03/07} + {2.11d} + {\csname c_acro_info_tl\endcsname} + +% -------------------------------------------------------------------------- +% warning and error messages: +\msg_new:nnn {acro} {undefined} + { + You've~ requested~ acronym~ `#1'~ \msg_line_context: \ but~ you~ + apparently~ haven't~ defined~ it,~ yet! \\ + Maybe~ you've~ misspelled~ `#1'? + } + +\msg_new:nnn {acro} {macro} + { + A~ macro~ with~ the~ csname~ `#1'~ already~ exists! \\ + Unless~ you~ set~ acro's~ option~ `strict'~ I~ won't~ redefine~ it~ + \msg_line_context: . + } + +\msg_new:nnn {acro} {replaced} + { + The~ #1~ `#2' ~you ~used~ \msg_line_context: \ is~ deprecated~ and~ has~ + been~ replaced~ by~ `#3'. ~Since~ I~ will~ not~ guarantee~ that~ #1~ `#2'~ + will~ be~ kept~ forever~ I~ strongly~ encourage~ you~ to~ switch! + } + +\msg_new:nnn {acro} {deprecated} + { + The~ #1~ `#2'~ you~ used~ \msg_line_context: \ is~ deprecated~and~ there~ + is~ no~ replacement.~ Since~ I~ will~ not~ guarantee~ that~ #1~ `#2'~ + will~ be~ kept~ forever~ I~ strongly~ encourage~ you~ to~ remove~ it~ + from~ your~ document. + } + +\msg_new:nnn {acro} {substitute-short} + { + There~ is~ no~ short~ form~ set~ for~ acronym~ `#1'! \\ + I~ am~ setting~ the~ short~ form~ equal~ to~ the~ ID~ `#1'. \\ + If~ that~ is~ not~ what~ you~ want~ make~ sure~ to~ add~ an~ explicit~ + short~ form. + } +\msg_new:nnn {acro} {ending-exists} + { + An~ ending~ with~ the~ name~ `#1'~ already~ exists! \\ \\ + I~ am~ overwriting~ the~ defaults. + } + +\msg_new:nnn {acro} {ending-before-acronyms} + { + You~ are~ using~ \token_to_str:N \ProvideAcroEnding \ after~ you've~ + declared~ at~ least~ one~ acronym.~ This~ will~ lead~ to~ trouble! \\ + Make~ sure~ to~ define~ endings~ before~ *any*~ acronym~ declarations! + } + +\msg_new:nnn {acro} {no-alternative} + { + There~ is~ no~ alternative~ form~ for~ acronym~ `#1'! \\ \\ + I~ am~ using~ the~ short~ form~ instead. + } + +\msg_new:nnn {acro} {unknown} + { + You're~ trying~ to~ use~ the~ #1~ `#2'~ \msg_line_context: . \\ + However,~ I~ do~ not~ know~ #1~ `#2'! \\ + If~ this~ is~ no~ typo~ please~ contact~ the~ package~ author. \\ \\ + I~ am~ going~ to~ use~ the~ #1~ `#3'~ instead. + } +\msg_new:nnn {acro} {definitions-missing} + { + I~ cannot~ find~ the~ file~ \c_acro_definition_file_name_tl + .\c_acro_definition_file_extension_tl !~ This~ file~ contains~ all~ + essential~ user~ commands~ of~ acro~ and~ is~ a~ crucial~ part~ of~ the~ + package!~ Please~ check~ your~ installation. + } + +% -------------------------------------------------------------------------- +% temporary variables +\tl_new:N \l__acro_tmpa_tl +\tl_new:N \l__acro_tmpb_tl +\tl_new:N \l__acro_tmpc_tl +\prop_new:N \l__acro_tmpa_prop +\prop_new:N \l__acro_tmpb_prop +\seq_new:N \l__acro_tmpa_seq +\seq_new:N \l__acro_tmpb_seq +\int_new:N \l__acro_tmpa_int +\int_new:N \l__acro_tmpb_int +\int_new:N \l__acro_tmpc_int +\int_new:N \l__acro_tmpd_int + +% -------------------------------------------------------------------------- +% variants of kernel commands +\cs_generate_variant:Nn \quark_if_no_value:nTF {V} +\cs_generate_variant:Nn \tl_put_right:Nn {NV,Nv} +\cs_generate_variant:Nn \tl_if_eq:nnT {V} +\cs_generate_variant:Nn \tl_if_eq:nnF {V} +\cs_generate_variant:Nn \seq_use:Nnnn {c} +\cs_generate_variant:Nn \seq_gset_split:Nnn {c} +\cs_generate_variant:Nn \seq_set_split:Nnn {NnV} +\cs_generate_variant:Nn \seq_if_in:NnT {NV} +\cs_generate_variant:Nn \seq_if_in:NnTF {Ne} +\cs_generate_variant:Nn \prop_put:Nnn {NnV,cnx,cnv} +\cs_generate_variant:Nn \prop_get:NnNTF {cnc} +\cs_generate_variant:Nn \prop_get:NnNF {cn,cnc} +\cs_generate_variant:Nn \prop_get:NnN {cnc} +\cs_generate_variant:Nn \cs_generate_variant:Nn {c} +\cs_generate_variant:Nn \str_case:nn {V} + +% -------------------------------------------------------------------------- +% variables: +\bool_new:N \l__acro_acc_supp_bool +\bool_new:N \l__acro_addto_index_bool +\bool_new:N \l__acro_capitalize_list_bool +\bool_new:N \g__acro_case_sensitive_bool +\bool_new:N \l__acro_citation_all_bool +\bool_new:N \l__acro_citation_first_bool +\bool_set_true:N \l__acro_citation_first_bool +\bool_new:N \l__acro_create_macros_bool +\bool_new:N \l__acro_custom_alt_format_bool +\bool_new:N \l__acro_custom_long_format_bool +\bool_new:N \l__acro_custom_short_format_bool +\bool_new:N \l__acro_custom_foreign_format_bool +\bool_new:N \l__acro_extra_punct_bool +\bool_new:N \l__acro_extra_use_brackets_bool +\bool_new:N \g__acro_first_acronym_declared_bool +\bool_new:N \l__acro_first_instance_bool +\bool_new:N \l__acro_first_only_short_bool +\bool_new:N \l__acro_first_only_long_bool +\bool_new:N \l__acro_first_reversed_bool +\bool_new:N \l__acro_first_switched_bool +\bool_new:N \l__acro_first_use_brackets_bool +\bool_new:N \l__acro_first_upper_bool +\bool_new:N \l__acro_following_page_bool +\bool_new:N \l__acro_following_pages_bool +\bool_new:N \l__acro_foreign_bool +\bool_set_true:N \l__acro_foreign_bool +\bool_new:N \l__acro_group_citation_bool +\bool_new:N \l__acro_hyperref_loaded_bool +\bool_new:N \l__acro_hyperref_use_bool +\bool_new:N \l__acro_include_endings_format_bool +\bool_new:N \l__acro_indefinite_bool +\bool_new:N \l__acro_in_list_bool +\bool_new:N \l__acro_is_included_bool +\bool_new:N \l__acro_is_excluded_bool +\bool_new:N \l__acro_list_all_pages_bool +\bool_set_true:N \l__acro_list_all_pages_bool +\bool_new:N \l__acro_list_reverse_long_extra_bool +\bool_new:N \l__acro_log_acronyms_bool +\bool_new:N \l__acro_log_acronyms_verbose_bool +\bool_new:N \l__acro_mark_as_used_bool +\bool_new:N \g__acro_mark_first_as_used_bool +\bool_new:N \l__acro_override_list_format_bool +\bool_new:N \l__acro_page_brackets_bool +\bool_new:N \l__acro_page_display_bool +\bool_new:N \l__acro_page_punct_bool +\bool_new:N \l__acro_place_label_bool +\bool_new:N \l__acro_print_only_used_bool +\bool_set_true:N \l__acro_print_only_used_bool +\bool_new:N \g__acro_reset_at_barrier_bool +\bool_new:N \l__acro_silence_bool +\bool_new:N \l__acro_single_use_bool +\bool_new:N \l__acro_sort_bool +\bool_set_true:N \l__acro_sort_bool +\bool_new:N \l__acro_strict_bool +\bool_new:N \l__acro_trailing_tokens_bool +\bool_new:N \l__acro_tooltip_bool +\bool_new:N \l__acro_tooltip_inside_bool +\bool_new:N \l__acro_upper_indefinite_bool +\bool_new:N \l__acro_upper_short_bool +\bool_new:N \l__acro_use_acronyms_bool +\bool_set_true:N \l__acro_use_acronyms_bool +\bool_new:N \l__acro_use_barrier_bool +\bool_new:N \g__acro_use_barriers_bool +\bool_new:N \l__acro_use_ending_form_bool +\bool_new:N \l__acro_use_note_bool +\bool_new:N \l__acro_xspace_bool + +\str_new:N \l__acro_current_id_str + +\tl_new:N \l__acro_list_entries_tl +\tl_new:N \l__acro_endings_tl +\tl_new:N \l__acro_trailing_tokens_tl +\tl_new:N \l__acro_included_classes_tl +\tl_new:N \l__acro_excluded_classes_tl +\tl_new:N \l__acro_ignore_tl +\tl_new:N \l__acro_default_indefinite_tl +\tl_set:Nn \l__acro_default_indefinite_tl {a} +\tl_new:N \l__acro_foreign_sep_tl +\tl_new:N \l__acro_extra_instance_tl +\tl_set:Nn \l__acro_extra_instance_tl {default} +\tl_new:N \l__acro_page_instance_tl +\tl_set:Nn \l__acro_page_instance_tl {none} +\tl_new:N \l__acro_page_name_tl +\tl_new:N \l__acro_pages_name_tl +\tl_new:N \l__acro_next_page_tl +\tl_new:N \l__acro_next_pages_tl +\tl_new:N \l__acro_list_instance_tl +\tl_set:Nn \l__acro_list_instance_tl {description} +\tl_new:N \l__acro_list_type_tl +\tl_new:N \l__acro_list_heading_cmd_tl +\tl_set:Nn \l__acro_list_heading_cmd_tl {section*} +\tl_new:N \l__acro_list_name_tl +\tl_new:N \l__acro_list_before_tl +\tl_new:N \l__acro_list_after_tl +\tl_new:N \l__acro_custom_short_format_tl +\tl_new:N \l__acro_first_between_tl +\tl_new:N \l__acro_citation_connect_tl +\tl_new:N \l__acro_between_group_connect_citation_tl +\tl_new:N \l__acro_extra_brackets_tl +\tl_new:N \l__acro_extra_punct_tl +\tl_new:N \l__acro_first_brackets_tl +\tl_new:N \l__acro_page_punct_tl +\tl_new:N \l__acro_page_brackets_tl +\tl_new:N \l__acro_last_page_tl +\tl_new:N \l__acro_current_page_tl +\tl_new:N \l__acro_list_table_tl +\tl_new:N \l__acro_list_table_spec_tl +\tl_new:N \l__acro_acc_supp_tl +\tl_new:N \l__acro_acc_supp_options_tl +\tl_new:N \l__acro_label_prefix_tl +\tl_set:Nn \l__acro_label_prefix_tl {ac:} +\tl_new:N \l__acro_index_short_tl +\tl_new:N \l__acro_first_instance_tl +\tl_set:Nn \l__acro_first_instance_tl {default} +\tl_new:N \l__acro_short_tl +\tl_new:N \l__acro_short_format_tl +\tl_new:N \l__acro_list_short_format_tl +\tl_new:N \l__acro_alt_tl +\tl_new:N \l__acro_alt_format_tl +\tl_new:N \l__acro_long_tl +\tl_new:N \l__acro_long_format_tl +\tl_new:N \l__acro_list_long_format_tl +\tl_new:N \l__acro_single_form_tl +\tl_set:Nn \l__acro_single_form_tl {long} +\tl_new:N \l__acro_extra_format_tl +\tl_new:N \l__acro_foreign_format_tl +\tl_new:N \l__acro_foreign_list_format_tl +\tl_set:Nn \l__acro_foreign_list_format_tl { \acroenparen } +\tl_new:N \l__acro_index_format_tl + +\skip_new:N \l__acro_page_space_skip + +\dim_new:N \l__acro_short_width_dim +\dim_set:Nn \l__acro_short_width_dim {3em} + +\int_new:N \g__acro_barrier_int + +\seq_new:N \l__acro_endings_seq +\seq_new:N \l__acro_actions_seq +\seq_new:N \g__acro_declared_acronyms_seq + +\prop_new:N \l__acro_citation_prop +\prop_new:N \l__acro_citation_pre_prop +\prop_new:N \l__acro_citation_post_prop +\prop_new:N \l__acro_pdfstring_alt_prop +\prop_new:N \l__acro_pdfstring_short_prop +\prop_new:N \g__acro_properties_prop +\prop_new:N \l__acro_trailing_tokens_prop +\prop_new:N \l__acro_trailing_actions_prop +\prop_new:N \l__acro_list_styles_prop +\prop_new:N \l__acro_list_headings_prop +\prop_new:N \l__acro_first_styles_prop +\prop_new:N \l__acro_extra_styles_prop +\prop_new:N \l__acro_page_styles_prop + +% -------------------------------------------------------------------------- +% logging: +\prg_new_conditional:Npnn \acro_if_log: {p,T,F,TF} + { + \bool_if:NTF \l__acro_log_acronyms_bool + { \prg_return_true: } + { \prg_return_false: } + } + +\keys_define:nn {acro} + { + log .choice: , + log / true .code:n = + \bool_set_true:N \l__acro_log_acronyms_bool + \bool_set_false:N \l__acro_log_acronyms_verbose_bool , + log / silent .meta:n = { log = true } , + log / verbose .code:n = + \bool_set_true:N \l__acro_log_acronyms_bool + \bool_set_true:N \l__acro_log_acronyms_verbose_bool , + log / false .code:n = + \bool_set_false:N \l__acro_log_acronyms_bool + \bool_set_false:N \l__acro_log_acronyms_verbose_bool , + log .default:n = true , + log .initial:n = false + } + +\cs_new:Npn \__acro_write_log:nn #1#2 { \ \ \ #1 ~ = ~ {#2} } +\cs_new:Npn \__acro_write_log_property:nnn #1#2#3 + { \__acro_write_log:nn {#2} { \__acro_property_get:nn {#3} {#1} } } + +\cs_new:Npn \__acro_ending_log_entry:nn #1#2 + { + | \\ + | \__acro_write_log_property:nnn {#1} {short-#2} {short_#2} \\ + | \__acro_write_log_property:nnn {#1} {short-#2-form} {short_#2_form} \\ + | \__acro_write_log_property:nnn {#1} {long-#2} {long_#2} \\ + | \__acro_write_log_property:nnn {#1} {long-#2-form} {long_#2_form} \\ + | \__acro_write_log_property:nnn {#1} {alt-#2} {alt_#2} \\ + | \__acro_write_log_property:nnn {#1} {alt-#2-form} {alt_#2_form} \\ + | \__acro_write_log_property:nnn {#1} {foreign-#2} {foreign_#2} \\ + | \__acro_write_log_property:nnn {#1} {foreign-#2-form} {foreign_#2_form} \\ + } + +\msg_new:nnn {acro} {log-acronym-verbose} + { + ================================================= \\ + | ~ \msg_info_text:n {acro}~ --~ defining~ new~ acronym: \\ + | \__acro_write_log:nn {ID} {#1} \\ + | \__acro_write_log_property:nnn {#1} {short} {short} \\ + | \__acro_write_log_property:nnn {#1} {long} {long} \\ + | \__acro_write_log_property:nnn {#1} {alt} {alt} \\ + | \__acro_write_log_property:nnn {#1} {sort} {sort} \\ + | \__acro_write_log_property:nnn {#1} {class} {class} \\ + | \__acro_write_log_property:nnn {#1} {list} {list} \\ + | \__acro_write_log_property:nnn {#1} {extra} {extra} \\ + | \__acro_write_log_property:nnn {#1} {foreign} {foreign} \\ + | \__acro_write_log_property:nnn {#1} {single} {single} \\ + | \__acro_write_log_property:nnn {#1} {pdfstring} {pdfstring} \\ + | \__acro_write_log_property:nnn {#1} {accsupp} {accsupp} \\ + | \__acro_write_log_property:nnn {#1} {tooltip} {tooltip} \\ + | \\ + | \__acro_write_log_property:nnn {#1} {short-indefinite} {short_indefinite} \\ + | \__acro_write_log_property:nnn {#1} {long-indefinite} {long_indefinite} \\ + | \__acro_write_log_property:nnn {#1} {alt-indefinite} {alt_indefinite} \\ + \seq_map_function:NN \l__acro_endings_seq \__acro_ending_log_entry:n + | \\ + | \__acro_write_log_property:nnn {#1} {short-format} {short_format} \\ + | \__acro_write_log_property:nnn {#1} {long-format} {long_format} \\ + | \__acro_write_log_property:nnn {#1} {first-long-format} {first_long_format} \\ + | \__acro_write_log_property:nnn {#1} {single-format} {single_format} \\ + | \__acro_write_log_property:nnn {#1} {foreign-lang} {foreign_lang} \\ + | \\ + | \__acro_write_log_property:nnn {#1} {cite} {citation} \\ + | \__acro_write_log_property:nnn {#1} {before-citation} {before_citation} \\ + | \__acro_write_log_property:nnn {#1} {after-citation} {after_citation} \\ + | \__acro_write_log_property:nnn {#1} {index} {index} \\ + | \__acro_write_log_property:nnn {#1} {index-sort} {index_sort} \\ + | \\ + | \__acro_write_log_property:nnn {#1} {long-pre} {long_pre} \\ + | \__acro_write_log_property:nnn {#1} {long-post} {long_post} \\ + | \__acro_write_log_property:nnn {#1} {post} {post} \\ + | \__acro_write_log_property:nnn {#1} {index-cmd} {index_cmd} \\ + | \__acro_write_log_property:nnn {#1} {first-style} {first_style} \\ + ================================================= + } + +\msg_new:nnn {acro} {log-acronym-silent} + { + ================================================= \\ + | ~ \msg_info_text:n {acro}~ --~ defining~ new~ acronym: \\ + | \__acro_write_log:nn {ID} {#1} \\ + | \__acro_write_log_property:nnn {#1} {short} {short} \\ + | \__acro_write_log_property:nnn {#1} {long} {long} \\ + | \__acro_write_log_property:nnn {#1} {alt} {alt} \\ + | \__acro_write_log_property:nnn {#1} {sort} {sort} \\ + | \__acro_write_log_property:nnn {#1} {class} {class} \\ + | \__acro_write_log_property:nnn {#1} {list} {list} \\ + | \__acro_write_log_property:nnn {#1} {extra} {extra} \\ + | \__acro_write_log_property:nnn {#1} {foreign} {foreign} \\ + | \__acro_write_log_property:nnn {#1} {cite} {citation} \\ + ================================================= + } + +\cs_new_protected:Npn \__acro_log_acronym:n #1 + { + \bool_if:NT \l__acro_log_acronyms_bool + { + \cs_set:Npn \__acro_ending_log_entry:n ##1 + { \__acro_ending_log_entry:nn {#1} {##1} } + \bool_if:NTF \l__acro_log_acronyms_verbose_bool + { \msg_log:nnn {acro} {log-acronym-verbose} {#1} } + { \msg_log:nnn {acro} {log-acronym-silent} {#1} } + } + } + +% -------------------------------------------------------------------------- +% message macros: +\cs_new:Npn \__acro_remove_backslash:N #1 + { \exp_after:wN \use_none:n \token_to_str:N #1 } + +\cs_new_protected:Npn \acro_new_message_commands:Nnnn #1#2#3#4 + { + \clist_map_inline:nn {#2} + { + \cs_new_protected:cpn { \__acro_remove_backslash:N #1 ##1 } + { + \bool_if:NTF \l__acro_silence_bool + { \use:c { \__acro_remove_backslash:N #3 n##1 } {acro} } + { \use:c { \__acro_remove_backslash:N #4 n##1 } {acro} } + } + } + } + +\acro_new_message_commands:Nnnn \acro_serious_message: {n,nn,nnn} + { \msg_warning: } + { \msg_error: } + +\acro_new_message_commands:Nnnn \acro_harmless_message: {n,nn,nnn,nnnn} + { \msg_info: } + { \msg_warning: } + +\cs_new_protected:Npn \acro_option_deprecated:nn #1#2 + { + \tl_if_blank:nTF {#2} + { \acro_harmless_message:nnn {deprecated} {option} {#1} } + { \acro_harmless_message:nnnn {replaced} {option} {#1} {#2} } + } +\cs_new_protected:Npn \acro_option_deprecated:n #1 + { \acro_option_deprecated:nn {#1} {} } + +\cs_new_protected:Npn \acro_command_deprecated:NN #1#2 + { + \tl_if_blank:nTF {#2} + { + \acro_harmless_message:nnn {deprecated} {command} + { \token_to_str:N #1 } + } + { + \acro_harmless_message:nnnn {replaced} {command} + { \token_to_str:N #1 } + { \token_to_str:N #2 } + } + } + +% -------------------------------------------------------------------------- +% small commands for use at various places +\cs_new:Npn \acro_no_break: { \tex_penalty:D 10000 \scan_stop: } + +\cs_new_protected:Npn \__acro_first_upper_case:n #1 + { \text_titlecase_first:n {#1} } +\cs_generate_variant:Nn \__acro_first_upper_case:n {x} + +\cs_new_eq:NN \acro_first_upper_case:n \__acro_first_upper_case:n + +% -------------------------------------------------------------------------- +\tl_new:N \l_acro_config_file_name_tl +\tl_new:N \l_acro_config_file_extension_tl + +\tl_set:Nn \l_acro_config_file_name_tl {acro} +\tl_set:Nn \l_acro_config_file_extension_tl {cfg} + +% options: +\keys_define:nn {acro} + { + messages .choice: , + messages / silent .code:n = + \bool_set_true:N \l__acro_silence_bool , + messages / loud .code:n = + \bool_set_false:N \l__acro_silence_bool , + messages .value_required:n = true , + config-file-name .tl_set:N = \l_acro_config_file_name_tl , + config-file-name .initial:n = acro , + config-file-extension .tl_set:N = \l_acro_config_file_extension_tl , + config-file-extension .initial:n = cfg , + accsupp .bool_set:N = \l__acro_acc_supp_bool , + accsupp-options .tl_set:N = \l__acro_acc_supp_options_tl , + tooltip .bool_set:N = \l__acro_tooltip_bool , + tooltip-cmd .code:n = \cs_set:Npn \__acro_tooltip_cmd:nn {#1} , + tooltip-cmd .value_required:n = true , + macros .bool_set:N = \l__acro_create_macros_bool , + xspace .bool_set:N = \l__acro_xspace_bool , + % xspace .code:n = \acro_option_deprecated:nn {xspace} {} , + strict .bool_set:N = \l__acro_strict_bool , + case-sensitive .bool_set:N = \g__acro_case_sensitive_bool , + case-sensitive .initial:n = true , + sort .bool_set:N = \l__acro_sort_bool , + short-format .code:n = + \tl_set:Nn \l__acro_short_format_tl {#1} + \tl_set_eq:NN \l__acro_alt_format_tl \l__acro_short_format_tl + \tl_set:Nn \l__acro_list_short_format_tl {#1} , + short-format .value_required:n = true , + alt-format .tl_set:N = \l__acro_alt_format_tl , + alt-format .value_required:n = true , + long-format .code:n = + \tl_set:Nn \l__acro_long_format_tl {#1} + \tl_set:Nn \l__acro_first_long_format_tl {#1} + \tl_set:Nn \l__acro_list_long_format_tl {#1} , + long-format .value_required:n = true , + first-long-format .code:n = + \tl_set:Nn \l__acro_first_long_format_tl {#1} , + first-long-format .value_required:n = true , + single-format .tl_set:N = \l__acro_single_format_tl , + single-format .value_required:n = true , + format-include-endings .bool_set:N = \l__acro_include_endings_format_bool , + display-foreign .bool_set:N = \l__acro_foreign_bool , + foreign-format .tl_set:N = \l__acro_foreign_format_tl , + foreign-format .value_required:n = true , + list-short-format .tl_set:N = \l__acro_list_short_format_tl , + list-short-format .value_required:n = true , + list-short-width .dim_set:N = \l__acro_short_width_dim , + list-short-width .value_required:n = true , + list-long-format .tl_set:N = \l__acro_list_long_format_tl , + list-long-format .value_required:n = true , + list-foreign-format .tl_set:N = \l__acro_foreign_list_format_tl , + list-foreign-format .value_required:n = true , + override-list-format .bool_set:N = \l__acro_override_list_format_bool , + override-list-format .initial:n = true , + extra-format .tl_set:N = \l__acro_extra_format_tl , + extra-format .value_required:n = true , + single .bool_set:N = \l__acro_single_use_bool , + single-form .tl_set:N = \l__acro_single_form_tl , + single-form .value_required:n = true , + first-style .code:n = \acro_set_first_style:n {#1} , + first-style .value_required:n = true , + extra-style .code:n = \acro_set_extra_style:n {#1} , + extra-style .value_required:n = true , + label .bool_set:N = \l__acro_place_label_bool , + label-prefix .tl_set:N = \l__acro_label_prefix_tl , + label-prefix .value_required:n = true , + pages .choice: , + pages / all .code:n = + \bool_set_true:N \l__acro_list_all_pages_bool , + pages / first .code:n = + \bool_set_true:N \l__acro_place_label_bool + \bool_set_false:N \l__acro_list_all_pages_bool , + pages .value_required:n = true , + page-ref .code:n = + \acro_option_deprecated:nn {page-ref} {page-style} + \acro_set_page_style:n {#1} , + page-style .code:n = \acro_set_page_style:n {#1} , + page-style .value_required:n = true , + page-name .tl_set:N = \l__acro_page_name_tl , + page-name .value_required:n = true , + pages-name .tl_set:N = \l__acro_pages_name_tl , + pages-name .value_required:n = true , + following-page .bool_set:N = \l__acro_following_page_bool , + following-pages .bool_set:N = \l__acro_following_pages_bool , + following-pages* .meta:n = + { following-page = #1 , following-pages = #1 } , + following-pages* .default:n = true , + next-page .tl_set:N = \l__acro_next_page_tl , + next-page .value_required:n = true , + next-pages .tl_set:N = \l__acro_next_pages_tl , + next-pages .value_required:n = true , + list-style .code:n = \acro_set_list_style:n {#1} , + list-style .value_required:n = true , + list-heading .code:n = \acro_set_list_heading:n {#1} , + list-heading .value_required:n = true , + list-name .tl_set:N = \l__acro_list_name_tl , + list-name .value_required:n = true , + hyperref .bool_set:N = \l__acro_hyperref_use_bool , + only-used .bool_set:N = \l__acro_print_only_used_bool , + mark-as-used .choice: , + mark-as-used / first .code:n = + \bool_gset_true:N \g__acro_mark_first_as_used_bool , + mark-as-used / any .code:n = + \bool_gset_false:N \g__acro_mark_first_as_used_bool , + mark-as-used .default:n = any , + list-caps .bool_set:N = \l__acro_capitalize_list_bool , + cite .choice: , + cite / all .code:n = + \bool_set_true:N \l__acro_citation_all_bool + \bool_set_true:N \l__acro_citation_first_bool , + cite / none .code:n = + \bool_set_false:N \l__acro_citation_all_bool + \bool_set_false:N \l__acro_citation_first_bool , + cite / first .code:n = + \bool_set_false:N \l__acro_citation_all_bool + \bool_set_true:N \l__acro_citation_first_bool , + cite .default:n = all , + cite-cmd .code:n = + \cs_set:Npn \__acro_citation_cmd:w {#1} , + cite-cmd .value_required:n = true , + group-cite-cmd .code:n = + \cs_set:Npn \__acro_group_citation_cmd:w {#1} , + group-cite-cmd .value_required:n = true , + group-citation .bool_set:N = \l__acro_group_citation_bool , + cite-connect .tl_set:N = \l__acro_citation_connect_tl , + cite-connect .initial:n = \nobreakspace , + cite-connect .value_required:n = true , + group-cite-connect .tl_set:N = \l__acro_between_group_connect_citation_tl , + group-cite-connect .initial:n = {,\nobreakspace} , + group-cite-connect .value_required:n = true , + index .bool_set:N = \l__acro_addto_index_bool , + index-cmd .code:n = + \cs_set:Npn \__acro_index_cmd:n {#1} , + index-cmd .value_required:n = true , + uc-cmd .code:n = + \cs_set_eq:NN \__acro_first_upper_case:n #1 , + uc-cmd .value_required:n = true , + uppercase-short .bool_set:N = \l__acro_upper_short_bool , + uppercase-short .initial:n = true + } + +\AtBeginDocument + { + \bool_if:NTF \l__acro_xspace_bool + { + \@ifpackageloaded {xspace} + { } + { \RequirePackage {xspace} } + \cs_new_eq:NN \acro_xspace: \xspace + } + { \cs_new:Npn \acro_xspace: {} } + } + +% -------------------------------------------------------------------------- +% we use xtemplate for different object types and with a different number of +% arguments; let's declare functions for usage later so we don't have to +% bother + +% objects with one argument: +\cs_new_protected:Npn \acro_page_number_instance:nn #1#2 + { \UseInstance {acro-page-number} {#1} {#2} } +\cs_generate_variant:Nn \acro_page_number_instance:nn {V} + +\cs_new_protected:Npn \acro_extra_instance:nn #1#2 + { \UseInstance {acro-extra} {#1} {#2} } +\cs_generate_variant:Nn \acro_extra_instance:nn {VV} + +\cs_new_protected:Npn \acro_title_instance:nn #1#2 + { \UseInstance {acro-title} {#1} {#2} } +\cs_generate_variant:Nn \acro_title_instance:nn {VV} + +% objects with two arguments: +\cs_new_protected:Npn \acro_list_instance:nnn #1#2#3 + { \UseInstance {acro-list} {#1} {#2} {#3} } +\cs_generate_variant:Nn \acro_list_instance:nnn {VVV} + +\cs_new_protected:Npn \acro_first_instance:nn #1#2 + { + \acro_property_if_set:nnTF {#1} {first-style} + { + \tl_set_eq:NN + \l__acro_tmpa_tl + \l__acro_first_style_tl + } + { + \tl_set_eq:NN + \l__acro_tmpa_tl + \l__acro_first_instance_tl + } + \acro_if_defined:nT {#1} + { + \use:x { + \UseInstance {acro-first} + { \exp_not:V \l__acro_tmpa_tl } + { \exp_not:n {#1} } + { \exp_not:n {#2} } + } + } + } +\cs_generate_variant:Nn \acro_first_instance:nn {nV} + +% -------------------------------------------------------------------------- +% hyperref support +\cs_new_eq:NN \acro_hyper_target:nn \use_ii:nn +\cs_new_eq:NN \acro_hyper_link:nn \use_ii:nn + +\cs_new_protected:Npn \acro_activate_hyperref_support: + { + \bool_lazy_and:nnT + { \l__acro_hyperref_loaded_bool } + { \l__acro_hyperref_use_bool } + { + \sys_if_engine_xetex:TF + { + \cs_set:Npn \acro_hyper_link:nn ##1##2 + { \hyperlink {##1} { \XeTeXLinkBox {##2} } } + } + { \cs_set_eq:NN \acro_hyper_link:nn \hyperlink } + \cs_set:Npn \acro_hyper_target:nn ##1##2 + { \raisebox {3ex} [0pt] { \hypertarget {##1} { } } ##2 } + } + } + +% #1: id +% #2: text +\cs_new_protected:Npn \__acro_make_link:nn #1#2 + { + \bool_lazy_and:nnTF + { \l__acro_hyperref_use_bool } + { \l__acro_hyperref_loaded_bool } + { + \acro_hyper_link:nn {#1} { \phantom {#2} } + \acro_if_is_single:nTF {#1} + { \hbox_overlap_left:n {#2} } + { \acro_color_link:n { \hbox_overlap_left:n {#2} } } + } + {#2} + } + +\cs_new:Npn \acro_color_link:n #1 + { + \cs_if_exist:NTF \hypersetup + { + \ifHy@colorlinks + \exp_after:wN \use_i:nn + \else + \ifHy@ocgcolorlinks + \exp_after:wN \use_i:nn + \else + \exp_after:wN \exp_after:wN \exp_after:wN \use_ii:nn + \fi + \fi + { \textcolor { \@linkcolor } {#1} } + {#1} + } + {#1} + } + +\AtBeginDocument{ + \cs_if_exist:NF \textcolor { \cs_new_eq:NN \textcolor \use_ii:nn } +} + +% -------------------------------------------------------------------------- +% output style of the first time an acronym is used + +% helper macros for the styles +% #1: short|long +% #2: id +% #3: long +\cs_new_protected:Npn \__acro_print_form_and_indefinite:nnn #1#2#3 + { + \group_begin: + \acro_for_all_trailing_tokens_do:n + { \acro_deactivate_trailing_action:n {##1} } + \str_case:nn {#1} + { + {long} { + \bool_lazy_or:nnT + { \l__acro_first_only_long_bool } + { !\l__acro_first_only_short_bool } + { + \acro_write_indefinite:nn {#2} {long} + \acro_write_expanded:nnn {#2} {first-long} {#3} + } + } + {short} { + \bool_lazy_or:nnT + { !\l__acro_first_only_long_bool } + { \l__acro_first_only_short_bool } + { + \acro_soft_upper: + \acro_write_indefinite:nn {#2} {short} + \acro_write_compact:nn {#2} {short} + } + } + } + \group_end: + } + +\cs_new_protected:Npn \__acro_open_bracket: + { + \bool_lazy_and:nnT + { !\l__acro_first_only_long_bool } + { !\l__acro_first_only_short_bool } + { + \acro_space: + \tl_if_blank:VF \l__acro_first_between_tl + { + \tl_use:N \l__acro_first_between_tl + \acro_space: + } + \bool_if:NT \l__acro_first_use_brackets_bool + { \tl_head:N \l__acro_first_brackets_tl } + } + } + +\cs_new_protected:Npn \__acro_close_bracket: + { + \bool_lazy_all:nT + { + { \l__acro_first_use_brackets_bool } + { !\l__acro_first_only_short_bool } + { !\l__acro_first_only_long_bool } + } + { \tl_tail:N \l__acro_first_brackets_tl } + } + +% #1: short|long +% #2: id +% #3: long +\cs_new_protected:Npn \__acro_print_form:nnn #1#2#3 + { + \str_case:nn {#1} + { + {long} { + \bool_lazy_or:nnT + { \l__acro_first_only_long_bool } + { !\l__acro_first_only_short_bool } + { + \group_begin: + \bool_set_false:N \l__acro_first_upper_bool + \acro_write_expanded:nnn {#2} {first-long} {#3} + \group_end: + } + } + {short} { + \bool_lazy_or:nnT + { !\l__acro_first_only_long_bool } + { \l__acro_first_only_short_bool } + { + \group_begin: + \acro_soft_upper: + \acro_write_compact:nn {#2} {short} + \group_end: + } + } + } + } + +% #1: id +\cs_new_protected:Npn \__acro_foreign_sep:n #1 + { + \bool_lazy_all:nT + { + { \l__acro_foreign_bool } + { !\l__acro_first_only_short_bool } + { !\l__acro_first_only_long_bool } + } + { \acro_if_foreign:nT {#1} { \tl_use:N \l__acro_foreign_sep_tl } } + } + +% #1: id +\cs_new_protected:Npn \__acro_print_foreign:n #1 + { + \acro_if_foreign:nT {#1} + { + \bool_lazy_all:nT + { + { \l__acro_foreign_bool } + { !\l__acro_first_only_short_bool } + { !\l__acro_first_only_long_bool } + } + { + \acro_write_foreign:n {#1} + \acro_endings:nn {#1} {foreign} + } + } + } + +\cs_new_protected:Npn \__acro_print_citation:n #1 + { + \bool_if:NT \l__acro_group_citation_bool + { \acro_group_cite:n {#1} } + } + +\cs_new_protected:Npn \__acro_finalize_first:n #1 + { + \bool_if:NF \l__acro_group_citation_bool + { \acro_cite_if:Nn \l__acro_citation_first_bool {#1} } + \acro_index_if:Nn \l__acro_addto_index_bool {#1} + \acro_property_get:nnT {#1} {post} + { \tl_use:N \l__acro_post_tl } + } + +% -------------------------------------------------------------------------- +% the `acro-first' object, templates, instances: +% #1: id +% #2: long +\DeclareObjectType {acro-first} {2} + +% template for inline appearance: +\DeclareTemplateInterface {acro-first} {inline} {2} + { + brackets : boolean = true , + brackets-type : tokenlist = () , + only-short : boolean = false , + only-long : boolean = false , + reversed : boolean = false , + between : tokenlist , + foreign-sep : tokenlist = {,~} + } +\DeclareTemplateCode {acro-first} {inline} {2} + { + brackets = \l__acro_first_use_brackets_bool , + brackets-type = \l__acro_first_brackets_tl , + only-short = \l__acro_first_only_short_bool , + only-long = \l__acro_first_only_long_bool , + reversed = \l__acro_first_reversed_bool , + between = \l__acro_first_between_tl , + foreign-sep = \l__acro_foreign_sep_tl + } + { + \AssignTemplateKeys + \bool_set_true:N \l__acro_first_instance_bool + \bool_if:NTF \l__acro_first_reversed_bool + { % zuerst kurze Form, dann lange Form: + \__acro_print_form_and_indefinite:nnn {short} {#1} {#2} + \__acro_open_bracket: + \__acro_print_foreign:n {#1} + \__acro_foreign_sep:n {#1} + \__acro_print_form:nnn {long} {#1} {#2} + \__acro_print_citation:n {#1} + \__acro_close_bracket: + \__acro_finalize_first:n {#1} + } + { % zuerst lange Form, dann kurze Form: + \__acro_print_form_and_indefinite:nnn {long} {#1} {#2} + \__acro_open_bracket: + \__acro_print_foreign:n {#1} + \__acro_foreign_sep:n {#1} + \__acro_print_form:nnn {short} {#1} {#2} + \__acro_print_citation:n {#1} + \__acro_close_bracket: + \__acro_finalize_first:n {#1} + } + } + +% template for footnotes, sidenotes, ... +\cs_new:Npn \__acro_note_command:n #1 {#1} +\DeclareTemplateInterface {acro-first} {note} {2} + { + use-note : boolean = true , + note-command : function 1 = \footnote {#1} , + foreign-sep : tokenlist = {,~} , + reversed : boolean = false , + } + +\DeclareTemplateCode {acro-first} {note} {2} + { + use-note = \l__acro_use_note_bool , + note-command = \__acro_note_command:n , + foreign-sep = \l__acro_foreign_sep_tl , + reversed = \l__acro_first_reversed_bool + } + { + \AssignTemplateKeys + \bool_if:NTF \l__acro_first_reversed_bool + { % long in text and short in note + \__acro_print_form_and_indefinite:nnn {long} {#1} {#2} + \bool_if:NT \l__acro_use_note_bool + { + \__acro_note_command:n + { + \__acro_print_foreign:n {#1} + \__acro_foreign_sep:n {#1} + \__acro_print_form:nnn {short} {#1} {#2} + \__acro_print_citation:n {#1} + \__acro_finalize_first:n {#1} + } + } + } + { % short in text and long in note + \__acro_print_form_and_indefinite:nnn {short} {#1} {#2} + \bool_if:NT \l__acro_use_note_bool + { + \__acro_note_command:n + { + \__acro_print_foreign:n {#1} + \__acro_foreign_sep:n {#1} + \__acro_print_form:nnn {long} {#1} {#2} + \__acro_print_citation:n {#1} + \__acro_finalize_first:n {#1} + } + } + } + } + +% -------------------------------------------------------------------------- +% declare new first styles: +\cs_new_protected:Npn \acro_declare_first_style:nnn #1#2#3 + { + \DeclareInstance {acro-first} {#1} {#2} {#3} + \prop_put:Nnn \l__acro_first_styles_prop {#1} {#2} + } + +% set a list style +\cs_new_protected:Npn \acro_set_first_style:n #1 + { + \prop_if_in:NnTF \l__acro_first_styles_prop {#1} + { \__acro_set_first_style:n {#1} } + { + \msg_warning:nnnnn {acro} {unknown} + {first~ style} + {#1} + {default} + \__acro_set_first_style:n {default} + } + } + +\cs_new_protected:Npn \__acro_set_first_style:n #1 + { + \tl_set:Nn \l__acro_first_instance_tl {#1} + \prop_get:NnN \l__acro_first_styles_prop {#1} \l__acro_tmpa_tl + } + +% -------------------------------------------------------------------------- +% formatting the extras information: +\DeclareObjectType {acro-extra} {1} + +\DeclareTemplateInterface {acro-extra} {inline} {1} + { + punct : boolean = false , + punct-symbol : tokenlist = {,} , + brackets : boolean = true , + brackets-type : tokenlist = () + } + +\DeclareTemplateCode {acro-extra} {inline} {1} + { + punct = \l__acro_extra_punct_bool , + punct-symbol = \l__acro_extra_punct_tl , + brackets = \l__acro_extra_use_brackets_bool , + brackets-type = \l__acro_extra_brackets_tl + } + { + \AssignTemplateKeys + \bool_if:NT \l__acro_extra_punct_bool + { \tl_use:N \l__acro_extra_punct_tl \tl_use:N \c_space_tl } + \bool_if:NT \l__acro_extra_use_brackets_bool + { \tl_head:N \l__acro_extra_brackets_tl } + \acro_write_long:Vn \l__acro_extra_format_tl {#1} + \bool_if:NT \l__acro_extra_use_brackets_bool + { \tl_tail:N \l__acro_extra_brackets_tl } + } + +% declare new extra styles: +\cs_new_protected:Npn \acro_declare_etxra_style:nnn #1#2#3 + { + \DeclareInstance {acro-etxra} {#1} {#2} {#3} + \prop_put:Nnn \l__acro_etxra_styles_prop {#1} {#2} + } + +% set an extra style +\cs_new_protected:Npn \acro_set_extra_style:n #1 + { + \prop_if_in:NnTF \l__acro_extra_styles_prop {#1} + { \__acro_set_extra_style:n {#1} } + { + \msg_warning:nnnnn {acro} {unknown} + {extra~ style} + {#1} + {default} + \__acro_set_extra_style:n {default} + } + } + +\cs_new_protected:Npn \__acro_set_extra_style:n #1 + { + \tl_set:Nn \l__acro_extra_instance_tl {#1} + \prop_get:NnN \l__acro_extra_styles_prop {#1} \l__acro_tmpa_tl + } + +\cs_new_protected:Npn \acro_declare_extra_style:nnn #1#2#3 + { + \DeclareInstance {acro-extra} {#1} {#2} {#3} + \prop_put:Nnn \l__acro_extra_styles_prop {#1} {#2} + } + +% -------------------------------------------------------------------------- +% outputting the page numbers: +\RequirePackage {zref-abspage} + +\cs_new_protected:Npn \__acro_create_page_records:n #1 + { + \seq_new:c { g__acro_#1_pages_seq } + \tl_new:c { g__acro_#1_recorded_pages_tl } + } + +\cs_new_protected:Npn \acro_hyper_page:n #1 { \use:n {#1} } + +\cs_new:Npn \acro_get_thepage:nnn #1#2#3 { \acro_hyper_page:n {#1} } +\cs_new:Npn \acro_get_thepage_from:N #1 + { \exp_after:wN \acro_get_thepage:nnn #1 } + +\cs_new:Npn \acro_get_page_number:nnn #1#2#3 {#2} +\cs_new:Npn \acro_get_page_number_from:N #1 + { \exp_after:wN \acro_get_page_number:nnn #1 } + +\cs_new:Npn \acro_get_abspage:nnn #1#2#3 {#3} +\cs_new:Npn \acro_get_abspage_from:N #1 + { \exp_after:wN \acro_get_abspage:nnn #1 } + +\cs_new:Npn \acro_page_range_comma: {} + +\cs_new_protected:Npn \acro_print_page_numbers:n #1 + { + \seq_if_empty:cF {g__acro_#1_pages_seq} + { + \bool_if:NTF \l__acro_list_all_pages_bool + { + % have the numbers changed? + \tl_set:Nx \l__acro_tmpa_tl + { \seq_use:cn {g__acro_#1_pages_seq} {|} } + \tl_if_eq:cNF {g__acro_#1_recorded_pages_tl} \l__acro_tmpa_tl + { + \@latex@warning@no@line + {Rerun~to~get~page~numbers~of~acronym~#1~in~acronym~list~right} + } + \tl_clear:N \l__acro_write_pages_tl + \tl_clear:N \l__acro_last_page_tl + \tl_clear:N \l__acro_current_page_tl + \seq_set_eq:Nc \l__acro_tmpb_seq { g__acro_#1_pages_seq } + \seq_remove_duplicates:N \l__acro_tmpb_seq + \seq_clear:N \l__acro_tmpa_seq + \cs_set_protected:Npn \acro_page_range_comma: + { \cs_set:Npn \acro_page_range_comma: { ,~ } } + % get the numbers: + \int_compare:nNnTF { \seq_count:N \l__acro_tmpb_seq } = { 1 } + { + \tl_use:N \l__acro_page_name_tl + \seq_get_right:cN { g__acro_#1_pages_seq } \l__acro_tmpa_tl + \acro_get_thepage_from:N \l__acro_tmpa_tl + } + { + \tl_use:N \l__acro_pages_name_tl + \seq_map_inline:cn { g__acro_#1_pages_seq } + { + \tl_if_blank:VTF \l__acro_last_page_tl + {% we're at the beginning + \seq_put_right:Nn \l__acro_tmpa_seq {##1} + \tl_set:Nn \l__acro_last_page_tl {##1} + } + {% we'at least at the second page + % current page: + \tl_set:Nn \l__acro_current_page_tl {##1} + % last page: + \seq_get_right:NN \l__acro_tmpa_seq \l__acro_last_page_tl + \tl_if_eq:NNTF \l__acro_current_page_tl \l__acro_last_page_tl + {% there were more than one appearance on the current page + \seq_put_right:Nn \l__acro_tmpa_seq {##1} + } + {% new page + \acro_determine_page_ranges:NNn + \l__acro_tmpa_seq + \l__acro_write_pages_tl + {##1} + } + } + } + \seq_if_empty:NF \l__acro_tmpa_seq + { + \acro_determine_page_ranges:NNV + \l__acro_tmpa_seq + \l__acro_write_pages_tl + \l__acro_current_page_tl + } + \tl_use:N \l__acro_write_pages_tl + \tl_clear:N \l__acro_write_pages_tl + } + } + { + \tl_use:N \l__acro_page_name_tl + \pageref{\l__acro_label_prefix_tl #1} + } + } + \seq_clear:N \l__acro_tmpa_seq + \seq_clear:N \l__acro_tmpb_seq + } + +\cs_new:Npn \acro_determine_page_ranges:NNn #1#2#3 + { + \seq_remove_duplicates:N #1 + % current page: + \int_set:Nn \l__acro_tmpa_int { \acro_get_abspage:nnn #3 } + \int_set:Nn \l__acro_tmpb_int { \acro_get_page_number:nnn #3 } + % last page: + \seq_get_right:NN #1 \l__acro_last_page_tl + \int_set:Nn \l__acro_tmpc_int + { \acro_get_abspage_from:N \l__acro_last_page_tl } + \int_set:Nn \l__acro_tmpd_int + { \acro_get_page_number_from:N \l__acro_last_page_tl } + \bool_lazy_and:nnTF + { + \int_compare_p:nNn + { \l__acro_tmpa_int - \l__acro_tmpc_int } + = + { \l__acro_tmpb_int - \l__acro_tmpd_int } + } + { + \int_compare_p:nNn + { \l__acro_tmpb_int - \l__acro_tmpd_int } = {1} + } + {% same kind of page numbering, one page ahead + % => possible range + \seq_put_right:Nn #1 {#3} + } + {% any possible range ended + \tl_put_right:Nn #2 { \acro_page_range_comma: } + \int_compare:nNnTF + { \seq_count:N #1 } > {2} + {% real range + \seq_get_left:NN #1 \l__acro_tmpa_tl + \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } + \bool_if:NTF \l__acro_following_pages_bool + { \tl_put_right:Nn #2 { \l__acro_next_pages_tl } } + { + \tl_put_right:Nn #2 { -- } + \seq_get_right:NN #1 \l__acro_tmpa_tl + \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } + } + } + { + \int_compare:nNnTF + { \seq_count:N #1 } = {2} + {% range of two pages + \seq_get_left:NN #1 \l__acro_tmpa_tl + \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } + \bool_if:NTF \l__acro_following_page_bool + { \tl_put_right:Nn #2 { \l__acro_next_page_tl } } + { + \tl_put_right:Nn #2 { ,~ } + \seq_get_right:NN #1 \l__acro_tmpa_tl + \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } + } + } + {% no range at all + \seq_get_right:NN #1 \l__acro_tmpa_tl + \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } + } + } + \seq_clear:N #1 + \seq_put_right:Nn #1 {#3} + } + } +\cs_generate_variant:Nn \acro_determine_page_ranges:NNn {NNV} + +% -------------------------------------------------------------------------- +\DeclareObjectType {acro-page-number} {1} + +\DeclareTemplateInterface {acro-page-number} {inline} {1} + { + display : boolean = true , + punct : boolean = false , + punct-symbol : tokenlist = {,} , + brackets : boolean = false , + brackets-type : tokenlist = () , + space : skip = .333333em plus .166666em minus .111111em + } + +\DeclareTemplateCode {acro-page-number} {inline} {1} + { + display = \l__acro_page_display_bool , + punct = \l__acro_page_punct_bool , + punct-symbol = \l__acro_page_punct_tl , + brackets = \l__acro_page_brackets_bool , + brackets-type = \l__acro_page_brackets_tl , + space = \l__acro_page_space_skip + } + { + \AssignTemplateKeys + \bool_if:NT \l__acro_page_display_bool + { + \bool_if:NT \l__acro_page_punct_bool + { \tl_use:N \l__acro_page_punct_tl } + % \tl_use:N \c_space_tl + \dim_compare:nNnF { \l__acro_page_space_skip } = { 0pt } + { \skip_horizontal:N \l__acro_page_space_skip } + \bool_if:NT \l__acro_page_brackets_bool + { \tl_head:N \l__acro_page_brackets_tl } + \acro_print_page_numbers:n {#1} + \bool_if:NT \l__acro_page_brackets_bool + { \tl_tail:N \l__acro_page_brackets_tl } + } + } + +% declare new page styles: +\cs_new_protected:Npn \acro_declare_page_style:nnn #1#2#3 + { + \DeclareInstance {acro-page-number} {#1} {#2} {#3} + \prop_put:Nnn \l__acro_page_styles_prop {#1} {#2} + } + +% set a page style +\cs_new_protected:Npn \acro_set_page_style:n #1 + { + \prop_if_in:NnTF \l__acro_page_styles_prop {#1} + { \__acro_set_page_style:n {#1} } + { + \msg_warning:nnnnn {acro} {unknown} + {page~ style} + {#1} + {none} + \__acro_set_page_style:n {none} + } + } + +\cs_new_protected:Npn \__acro_set_page_style:n #1 + { + \tl_set:Nn \l__acro_page_instance_tl {#1} + \prop_get:NnN \l__acro_page_styles_prop {#1} \l__acro_tmpa_tl + } + +% -------------------------------------------------------------------------- +% the title of the list: +\cs_new:Npn \acro_list_title_format:n #1 {#1} + +\DeclareObjectType {acro-title} {1} + +\DeclareTemplateInterface {acro-title} {sectioning} {1} + { name-format : function 1 = #1 } + +\DeclareTemplateCode {acro-title} {sectioning} {1} + { name-format = \acro_list_title_format:n } + { + \AssignTemplateKeys + \acro_list_title_format:n {#1} + } + +% set a list heading: +\cs_new_protected:Npn \acro_set_list_heading:n #1 + { + \prop_if_in:NnTF \l__acro_list_headings_prop {#1} + { \__acro_set_list_heading:n {#1} } + { + \msg_warning:nnnnn {acro} {unknown} + {list~ heading} + {#1} + {section*} + \__acro_set_list_heading:n {section*} + } + } + +\cs_new_protected:Npn \__acro_set_list_heading:n #1 + { \tl_set:Nn \l__acro_list_heading_cmd_tl {#1} } + +\cs_new_protected:Npn \acro_declare_list_heading:nn #1#2 + { + \prop_put:Nnn \l__acro_list_headings_prop {#1} {#2} + \DeclareInstance {acro-title} {#1} {sectioning} + { name-format = #2 {##1} } + } + +% -------------------------------------------------------------------------- +% typesetting the acronym list +\DeclareObjectType {acro-list} {2} + +% #1: id +% #2: excluded classes +\prg_new_protected_conditional:Npnn \acro_if_is_excluded:nn #1#2 {T,F,TF} + { + \bool_set_false:N \l__acro_is_excluded_bool + \tl_if_blank:nF {#2} + { + \acro_property_get:nnT {#1} {class} + { + \seq_set_split:NnV \l__acro_tmpa_seq {,} \l__acro_class_tl + \clist_map_inline:nn {#2} + { + \seq_if_in:NnT \l__acro_tmpa_seq {##1} + { \bool_set_true:N \l__acro_is_excluded_bool } + } + } + } + \bool_if:NTF \l__acro_is_excluded_bool + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: id +% #2: included classes +\prg_new_protected_conditional:Npnn \acro_if_is_included:nn #1#2 {T,F,TF} + { + \bool_set_false:N \l__acro_is_included_bool + \tl_if_blank:nTF {#2} + { \bool_set_true:N \l__acro_is_included_bool } + { + \acro_property_get:nnT {#1} {class} + { + \seq_set_split:NnV \l__acro_tmpa_seq {,} \l__acro_class_tl + \clist_map_inline:nn {#2} + { + \seq_if_in:NnT \l__acro_tmpa_seq {##1} + { \bool_set_true:N \l__acro_is_included_bool } + } + } + } + \bool_if:NTF \l__acro_is_included_bool + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: id +\cs_new_protected:Npn \__acro_list_entry_short:n #1 + { + \group_begin: + \acro_get:n {#1} + \acro_hyper_target:nn + {#1} + { + \acro_acc_supp:nn + {#1} + { + \bool_lazy_and:nnTF + { \l__acro_custom_short_format_bool } + { \l__acro_override_list_format_bool } + { \l__acro_custom_short_format_tl } + { \l__acro_list_short_format_tl } + { \__acro_property_get:nn {short} {#1} } + } + } + \group_end: + } + +% #1: id +\cs_new_protected:Npn \__acro_list_entry_long:n #1 + { + \group_begin: + \bool_if:NT \l__acro_capitalize_list_bool + { \bool_set_true:N \l__acro_first_upper_bool } + \acro_write_long:Vf \l__acro_list_long_format_tl + { + \prop_if_in:NnTF \l__acro_list_prop {#1} + { \__acro_property_get:nn {list} {#1} } + { \__acro_property_get:nn {long} {#1} } + } + \group_end: + \bool_if:NT \l__acro_foreign_bool + { \acro_get_foreign:n {#1} } + \acro_cite_if:Nn \l__acro_citation_all_bool {#1} + } + +% #1: id +\cs_new_protected:Npn \__acro_list_entry_extra:n #1 + { + \acro_property_get:nnT {#1} {extra} + { + \acro_extra_instance:VV + \l__acro_extra_instance_tl + \l__acro_extra_tl + } + } + +% #1: id +\cs_new_protected:Npn \__acro_list_entry_page:n #1 + { + \cs_if_exist:cT {acro@#1@once} + { + \acro_page_number_instance:Vn + \l__acro_page_instance_tl + {#1} + } + } + +% macro for retrieval of items in the list: +% #1: property +% #2: id +\cs_new_protected:Npn \acro_list_entry:nn #1#2 + { + \str_case:nnF {#1} + { + {short} { \__acro_list_entry_short:n {#2} } + {long} { \__acro_list_entry_long:n {#2} } + {extra} { \__acro_list_entry_extra:n {#2} } + {page} { \__acro_list_entry_page:n {#2} } + } + { \__acro_property_get:nn {#1} {#2} } + } + +% this macro may/should be redefined in templates: +% #1: short +% #2: long +% #3: extra +% #4: page number(s) +\cs_new_protected:Npn \acro_print_list_entry:nnnn #1#2#3#4 + { #1 #2 #3 #4 } + +\cs_new_protected:Npn \acro_for_all_acronyms_do:n #1 + { \prop_map_inline:Nn \l__acro_short_prop {#1} } + +% test, if acronyms should be printed or not; needs testing for in/excluded +% classes and options `only-used' and `single' -- this macro should be used in +% the template code for retrieving the list + +% #1: id +% #2: included classes +% #3: excluded classes +\prg_new_protected_conditional:Npnn \acro_if_entry:nnn #1#2#3 {T,F,TF} + { + \bool_lazy_or:nnTF + { + \bool_lazy_and_p:nn + { !\l__acro_single_use_bool } + { !\l__acro_print_only_used_bool } + } + { + \bool_lazy_and_p:nn + { \bool_if_p:c {g__acro_#1_in_list_bool} } + { + \bool_lazy_or_p:nn + { + \bool_lazy_and_p:nn + { \l__acro_single_use_bool } + { \cs_if_exist_p:c {acro@#1@twice} } + } + { + \bool_lazy_all_p:n + { + { !\l__acro_single_use_bool } + { \cs_if_exist_p:c {acro@#1@once} } + { \l__acro_print_only_used_bool } + } + } + } + } + { + \acro_if_is_excluded:nnTF {#1} {#3} + { \prg_return_false: } + { + \acro_if_is_included:nnTF {#1} {#2} + { + \bool_lazy_and:nnTF + { \g__acro_use_barriers_bool } + { \l__acro_use_barrier_bool } + { + \acro_if_in_barrier:nxTF {#1} + { \int_use:N \g__acro_barrier_int } + { \prg_return_true: } + { \prg_return_false: } + } + { \prg_return_true: } + } + { \prg_return_false: } + } + } + { \prg_return_false: } + } + +% this macro is used in templates for fetching all items to be printed; it +% collects all entries in a tl which then is used where needed +% +% #1: tl containing the entries +% #2: included classes +% #3: excluded classes +\cs_new_protected:Npn \acro_build_list_entries:Nnn #1#2#3 + { + \tl_clear:N #1 + \acro_for_all_acronyms_do:n + {% ##1: id; ##2: short form + \group_begin: + \acro_get:n {##1} + \acro_if_entry:nnnT {##1} {#2} {#3} + { + \tl_gput_right:Nn #1 + { + \acro_print_list_entry:nnnn + { \acro_list_entry:nn {short} {##1} } + { \acro_list_entry:nn {long} {##1} } + { \acro_list_entry:nn {extra} {##1} } + { \acro_list_entry:nn {page} {##1} } + } + } + \group_end: + } + } + +% this macro is used in templates for fetching all items to be printed: +\cs_new_protected:Npn \acro_list_items:nn #1#2 + { + \acro_build_list_entries:Nnn \l__acro_list_entries_tl {#1} {#2} + \tl_use:N \l__acro_list_entries_tl + } + +% -------------------------------------------------------------------------- +% declare templates for the list: +% `list' template: +\DeclareTemplateInterface {acro-list} {list} {2} + { + foreign-sep : tokenlist = {~} , + list : tokenlist = {description} , + reverse : boolean = false , + before : tokenlist = , + after : tokenlist = + } + +\DeclareTemplateCode {acro-list} {list} {2} + { + foreign-sep = \l__acro_foreign_sep_tl , + list = \l__acro_list_tl , + reverse = \l__acro_list_reverse_long_extra_bool , + before = \l__acro_list_before_tl , + after = \l__acro_list_after_tl + } + { + \AssignTemplateKeys + \bool_set_true:N \l__acro_in_list_bool + \acro_activate_hyperref_support: + \bool_if:NTF \l__acro_list_reverse_long_extra_bool + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { \item [##1] ##3 ##2 ##4 } + } + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { \item [##1] ##2 ##3 ##4 } + } + \use:x + { + \exp_not:V \l__acro_list_before_tl + \exp_not:N \begin { \exp_not:V \l__acro_list_tl } + \exp_not:n { \acro_list_items:nn {#1} {#2} } + \exp_not:N \end { \exp_not:V \l__acro_list_tl } + \exp_not:V \l__acro_list_after_tl + } + } + +% `list-of' template: +\DeclareTemplateInterface {acro-list} {list-of} {2} + { + foreign-sep : tokenlist = {~} , + style : tokenlist = {toc} , + reverse : boolean = false , + before : tokenlist = , + after : tokenlist = + } + +\DeclareTemplateCode {acro-list} {list-of} {2} + { + foreign-sep = \l__acro_foreign_sep_tl , + style = \l__acro_list_of_style , + reverse = \l__acro_list_reverse_long_extra_bool , + before = \l__acro_list_before_tl , + after = \l__acro_list_after_tl + } + { + \AssignTemplateKeys + \bool_set_true:N \l__acro_in_list_bool + \tl_if_eq:VnT \l__acro_page_instance_tl {none} + { \tl_set:Nn \l__acro_page_instance_tl {plain} } + \tl_set:Nn \l__acro_page_name_tl {} + \tl_set:Nn \l__acro_pages_name_tl {} + \acro_activate_hyperref_support: + \str_case:Vn \l__acro_list_of_style + { + {toc} + { % similar to the table of contents + \bool_if:NTF \l__acro_list_reverse_long_extra_bool + { + \cs_if_exist:NTF \chapter + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { + \contentsline{chapter}{##1}{}{} + \contentsline{section}{##3##2}{##4}{} + } + } + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { + \contentsline{section}{##1}{}{} + \contentsline{subsection}{##3##2}{##4}{} + } + } + } + { + \cs_if_exist:NTF \chapter + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { + \contentsline{chapter}{##1}{}{} + \contentsline{section}{##2##3}{##4}{} + } + } + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { + \contentsline{section}{##1}{}{} + \contentsline{subsection}{##2##3}{##4}{} + } + } + } + } + {lof} + { % similar to the list of figures + \cs_set_protected:Npn \l@acro + { \@dottedtocline {1} {1.5em} {\l__acro_short_width_dim} } + \bool_if:NTF \l__acro_list_reverse_long_extra_bool + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { \contentsline{acro}{\numberline{##1}{##3##2}}{##4}{} } + } + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { \contentsline{acro}{\numberline{##1}{##2##3}}{##4}{} } + } + } + } + \use:x + { + \exp_not:V \l__acro_list_before_tl + \exp_not:n { \acro_list_items:nn {#1} {#2} } + \exp_not:V \l__acro_list_before_tl + } + } + +% `table' template: +\DeclareTemplateInterface {acro-list} {table} {2} + { + table : tokenlist = tabular , + table-spec : tokenlist = lp{.7\linewidth} , + foreign-sep : tokenlist = {~} , + reverse : boolean = false , + before : tokenlist = , + after : tokenlist = + } + +\DeclareTemplateCode {acro-list} {table} {2} + { + table = \l__acro_list_table_tl , + table-spec = \l__acro_list_table_spec_tl , + foreign-sep = \l__acro_foreign_sep_tl , + reverse = \l__acro_list_reverse_long_extra_bool , + before = \l__acro_list_before_tl , + after = \l__acro_list_after_tl + } + { + \AssignTemplateKeys + \acro_activate_hyperref_support: + \bool_if:NTF \l__acro_list_reverse_long_extra_bool + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { ##1 & ##3 ##2 ##4 \tabularnewline } + } + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { ##1 & ##2 ##3 ##4 \tabularnewline } + } + \acro_build_list_entries:Nnn \l__acro_list_entries_tl {#1} {#2} + \use:x + { + \exp_not:V \l__acro_list_before_tl + \exp_not:N \begin { \exp_not:V \l__acro_list_table_tl } + { \exp_not:V \l__acro_list_table_spec_tl } + \exp_not:V \l__acro_list_entries_tl + \exp_not:N \end { \exp_not:V \l__acro_list_table_tl } + \exp_not:V \l__acro_list_after_tl + } + } + +% `extra-table' template: +\DeclareTemplateInterface {acro-list} {extra-table} {2} + { + table : tokenlist = tabular , + table-spec : tokenlist = llll , + foreign-sep : tokenlist = {~} , + reverse : boolean = false , + before : tokenlist = , + after : tokenlist = + } + +\DeclareTemplateCode {acro-list} {extra-table} {2} + { + table = \l__acro_list_table_tl , + table-spec = \l__acro_list_table_spec_tl , + foreign-sep = \l__acro_foreign_sep_tl , + reverse = \l__acro_list_reverse_long_extra_bool , + before = \l__acro_list_before_tl , + after = \l__acro_list_after_tl + } + { + \AssignTemplateKeys + \acro_activate_hyperref_support: + \bool_if:NTF \l__acro_list_reverse_long_extra_bool + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { ##1 & ##3 & ##2 & ##4 \tabularnewline } + } + { + \cs_set_protected:Npn \acro_print_list_entry:nnnn ##1##2##3##4 + { ##1 & ##2 & ##3 & ##4 \tabularnewline } + } + \acro_build_list_entries:Nnn \l__acro_list_entries_tl {#1} {#2} + \use:x + { + \exp_not:V \l__acro_list_before_tl + \exp_not:N \begin { \exp_not:V \l__acro_list_table_tl } + { \exp_not:V \l__acro_list_table_spec_tl } + \exp_not:V \l__acro_list_entries_tl + \exp_not:N \end { \exp_not:V \l__acro_list_table_tl } + \exp_not:V \l__acro_list_after_tl + } + } + +% -------------------------------------------------------------------------- +% declare new list styles: +\cs_new_protected:Npn \acro_declare_list_style:nnn #1#2#3 + { + \DeclareInstance {acro-list} {#1} {#2} {#3} + \prop_put:Nnn \l__acro_list_styles_prop {#1} {#2} + } + +% set a list style +\cs_new_protected:Npn \acro_set_list_style:n #1 + { + \prop_if_in:NnTF \l__acro_list_styles_prop {#1} + { \__acro_set_list_style:n {#1} } + { + \msg_warning:nnnnn {acro} {unknown} + {list~ style} + {#1} + {description} + \__acro_set_list_style:n {description} + } + } + +\cs_new_protected:Npn \__acro_set_list_style:n #1 + { + \tl_set:Nn \l__acro_list_instance_tl {#1} + \prop_get:NnN \l__acro_list_styles_prop {#1} \l__acro_list_type_tl + } + +% -------------------------------------------------------------------------- +% case insensitivity of the ID: +\cs_new:Npn \acro_case_insensitive:n #1 + { + \bool_if:NTF \g__acro_case_sensitive_bool + { \tl_to_str:n {#1} } + { \str_lowercase:n {#1} } + } + +\cs_new_protected:Npn \acro_protected_case_insensitive:n #1 + { \acro_case_insensitive:n {#1} } + +\cs_new:Npn \acro_case_insensitive:Nn #1#2 + { \exp_args:Ne #1 { \acro_case_insensitive:n {#2} } } + +\cs_new:Npn \acro_case_insensitive:Nnn #1#2#3 + { \exp_args:Ne #1 { \acro_case_insensitive:n {#2} } {#3} } + +\cs_new_protected:Npn \acro_case_insensitive_command:Nnnn #1#2#3#4 + { \exp_args:Nnnx #1 {#2} {#3} { \acro_case_insensitive:n {#4} } } +\cs_generate_variant:Nn \acro_case_insensitive_command:Nnnn {c} + +% -------------------------------------------------------------------------- +% automatic typesetting, the internals of \ac: +% #1: id + +\cs_new_protected:Npn \acro_soft_upper: + { + \bool_if:NF \l__acro_upper_short_bool + { \bool_set_false:N \l__acro_first_upper_bool } + } + +\cs_new_protected:Npn \acro_use:n #1 + { + % get the acronym and the plural settings: + \acro_get:n {#1} + \acro_is_used:nTF {#1} + { + \acro_soft_upper: + % this is not the first time + \acro_write_indefinite:nn {#1} {short} + \acro_write_compact:nn {#1} {short} + \acro_after:n {#1} + } + { + % this is the first time + \bool_gset_true:c { g__acro_#1_first_use_bool } + \acro_if_is_single:nTF {#1} + { \acro_single:n {#1} } + { \acro_first_instance:nV {#1} \l__acro_long_tl } + } + } + +% single appearances: +\cs_new_protected:Npn \acro_single:n #1 + { + \acro_cite: + \acro_single_form:nV {#1} \l__acro_single_form_tl + \acro_after:n {#1} + } + +% #1: ID +% #2: long|first|<other> +\cs_new_protected:Npn \acro_single_form:nn #1#2 + { + \acro_write_indefinite:nn {#1} {#2} + \str_case:nnF {#2} + { + {long} { + \tl_if_blank:VT \l__acro_single_format_tl + { + \bool_if:NTF \l__acro_custom_long_format_bool + { + \tl_set_eq:NN + \l__acro_single_format_tl + \l__acro_custom_long_format_tl + } + { + \tl_set_eq:NN + \l__acro_single_format_tl + \l__acro_long_format_tl + } + } + \tl_if_blank:VT \l__acro_single_tl + { \tl_set_eq:NN \l__acro_single_tl \l__acro_long_tl } + % BUG: should that be \acro_write_expanded:nn ? + % \acro_write_expanded:nnn {#1} {#2} {\l__acro_single_tl} + \acro_write_long:VV \l__acro_single_format_tl \l__acro_single_tl + \acro_endings:nn {#1} {single} + \l__acro_long_post_tl + } + {first} { + \tl_if_blank:VF \l__acro_single_format_tl + { + \tl_set_eq:NN + \l__acro_first_long_format_tl + \l__acro_single_format_tl + } + \tl_if_blank:VT \l__acro_single_tl + { \tl_set_eq:NN \l__acro_single_tl \l__acro_long_tl } + \acro_first_instance:nV {#1} \l__acro_single_tl + } + } + { % other (e.g. short) + \acro_soft_upper: + \tl_if_blank:VF \l__acro_single_tl + { \tl_set_eq:cN {l__acro_#2_tl} \l__acro_single_tl } + \tl_if_blank:VF \l__acro_single_format_tl + { \tl_set_eq:cN {l__acro_#2_format_tl} \l__acro_single_format_tl } + \acro_write_compact:nn {#1} {#2} + } + } +\cs_generate_variant:Nn \acro_single_form:nn {nV} + +\prg_new_conditional:Npnn \acro_if_is_single:n #1 { p,T,TF } + { + \bool_lazy_or:nnTF + { !\l__acro_single_use_bool } + { \cs_if_exist_p:c {acro@#1@twice} } + { \prg_return_false: } + { \prg_return_true: } + } + +\cs_new_protected:Npn \acro_use_acronym:n #1 + { \use:c {bool_set_#1:N} \l__acro_mark_as_used_bool } + +% -------------------------------------------------------------------------- +% some helpers we'll need more often: +\prg_new_conditional:Npnn \acro_if_defined:n #1 {p,T,F,TF} + { + \seq_if_in:NeTF \g__acro_declared_acronyms_seq + { \acro_case_insensitive:n {#1} } + { \prg_return_true: } + { \prg_return_false: } + } + +\cs_new_protected:Npn \acro_defined:n #1 + { + \acro_if_defined:nF {#1} + { \acro_serious_message:nn {undefined} {#1} } + } + +% expandably gets property but doesn't transform property name -- internal +% name is needed +% #1: property +% #2: id +\cs_new:Npn \__acro_property_get:nn #1#2 + { \prop_item:cn {l__acro_#1_prop} {#2} } + +% #1: id +% #2: property +% #3: set case +% #4: not set case +\prg_new_protected_conditional:Npnn \acro_property_get:nn #1#2 {T,F,TF} + { + \tl_set:Nn \l__acro_tmpa_tl {#2} + \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} + \prop_get:cncTF + {l__acro_ \l__acro_tmpa_tl _prop} + {#1} + {l__acro_ \l__acro_tmpa_tl _tl} + { \prg_return_true: } + { \prg_return_false: } + } + +\cs_new_protected:Npn \acro_property_get:nn #1#2 + { \acro_property_get:nnTF {#1} {#2} {} {} } +\cs_generate_variant:Nn \acro_property_get:nn {V} + +% within this command one can refer to the current id with `#1' +\cs_new_protected:Npn \acro_add_action:n #1 + { \seq_put_right:Nn \l__acro_actions_seq {#1} } + +\cs_new_protected:Npn \__acro_get_actions:n #1 + { + \seq_map_inline:Nn \l__acro_actions_seq + { + \cs_set:Npn \__acro_action:n ####1 {##1} + \__acro_action:n {#1} + } + } + +\cs_new_protected:Npn \acro_get:n #1 + { + \bool_if:NF \l__acro_in_list_bool { \leavevmode } + \acro_activate_hyperref_support: + % short: + \acro_property_get:nn {#1} {short} + % alt: + \acro_property_get:nnF {#1} {alt} + { \tl_set_eq:NN \l__acro_alt_tl \l__acro_short_tl } + % long: + \acro_property_get:nn {#1} {long} + % foreign: + \acro_property_get:nn {#1} {foreign} + % foreign-lang: + \acro_property_get:nn {#1} {foreign-lang} + % extra: + \acro_property_get:nn {#1} {extra} + % single: + \acro_property_get:nn {#1} {single} + % first-style: + \acro_property_get:nn {#1} {first-style} + % formatting + \acro_property_get:nnTF {#1} {long-format} + { + \tl_set_eq:NN \l__acro_custom_long_format_tl \l__acro_long_format_tl + \bool_set_true:N \l__acro_custom_long_format_bool + } + { \bool_set_false:N \l__acro_custom_long_format_bool } + \acro_property_get:nn {#1} {first-long-format} + \acro_property_get:nnTF {#1} {format} + { + \tl_set_eq:NN \l__acro_custom_short_format_tl \l__acro_format_tl + \bool_set_true:N \l__acro_custom_short_format_bool + } + { \bool_set_false:N \l__acro_custom_short_format_bool } + \acro_property_get:nnTF {#1} {alt-format} + { + \tl_set_eq:NN \l__acro_custom_alt_format_tl \l__acro_alt_format_tl + \bool_set_true:N \l__acro_custom_alt_format_bool + } + { \bool_set_false:N \l__acro_custom_alt_format_bool } + \acro_property_get:nnTF {#1} {foreign-format} + { + \tl_set_eq:NN \l__acro_custom_foreign_format_tl \l__acro_foreign_format_tl + \bool_set_true:N \l__acro_custom_foreign_format_bool + } + { \bool_set_false:N \l__acro_custom_foreign_format_bool } + \acro_property_get:nn {#1} {single-format} + \acro_for_endings_do:n + { + \bool_if:cT {l__acro_##1_bool} + { \__acro_set_ending_for:nnn {##1} {#1} {long} } + } + \acro_property_get:nnF {#1} {long-post} + { \tl_clear:N \l__acro_long_post_tl } + \acro_property_get:nnT {#1} {long-pre} + { \tl_put_left:NV \l__acro_long_tl \l__acro_long_pre_tl } + \__acro_get_actions:n {#1} + } + +% -------------------------------------------------------------------------- +% plural endings and similar concepts: + +\cs_new_protected:Npn \acro_for_endings_do:n #1 + { \seq_map_inline:Nn \l__acro_endings_seq {#1} } + +% #1: ending +% #2: ID +\cs_new_protected:Npn \__acro_set_ending:nn #1#2 + { + \bool_if:cT {l__acro_#1_bool} + { + \__acro_set_ending_for:nnn {#1} {#2} {short} + \__acro_set_ending_for:nnn {#1} {#2} {alt} + \__acro_set_ending_for:nnn {#1} {#2} {long} + \__acro_set_ending_for:nnn {#1} {#2} {foreign} % XXX + } + } + +% this does nothing if a non-existent ending (#1) or non-existent form (#3) is +% input +% #1: ending +% #2: id +% #3: short|alt|long|foreign +\cs_new_protected:Npn \__acro_set_ending_for:nnn #1#2#3 + { + \acro_if_ending_form_exist:nnT {#1} {#3} + { + \bool_if:cTF + { c_ \prop_item:cn {l__acro_#3_#1_form_prop} {#2} _bool } + { \prop_get:cnc {l__acro_#3_#1_prop} {#2} {l__acro_#3_tl} } + { \prop_get:cnc {l__acro_#3_#1_prop} {#2} {l__acro_#3_#1_tl} } + } + } + +\cs_new_protected:Npn \__acro_set_endings:n #1 + { + \acro_for_endings_do:n + { \__acro_set_ending:nn {##1} {#1} } + } + +% #1: id +% #2: short|alt|… +\cs_new_protected:Npn \acro_get_ending_form:nn #1#2 + { + \acro_for_endings_do:n + { + \acro_if_ending_form_exist:nnT {##1} {#2} + { + \bool_lazy_and:nnT + { \use:c {l__acro_##1_bool} } + { \use:c { c_ \prop_item:cn {l__acro_#2_##1_form_prop} {#1} _bool } } + { \prop_get:cncF {l__acro_#2_##1_prop} {#1} {l__acro_#2_tl} {} } + } + } + } + +% #1: id +% #2: short|alt|… +\cs_new_protected:Npn \acro_endings:nn #1#2 + { + \group_begin: + \str_if_eq:nnTF {#2} {single} + { + \keys_set:nn {acro} + { long-format= \l__acro_single_format_tl } + \__acro_endings:nn {#1} {long} + } + { \__acro_endings:nn {#1} {#2} } + \group_end: + } + +\cs_new_protected:Npn \__acro_endings:nn #1#2 + { + \acro_for_endings_do:n + { + \__acro_set_ending_for:nnn {##1} {#1} {#2} + \bool_if:cT {l__acro_##1_bool} + { \__acro_ending_format:nn {#2} { \tl_use:c {l__acro_#2_##1_tl} } } + } + } + +% #1: long|short|alt +% #2: string +\cs_new_protected:Npn \__acro_ending_format:nn #1#2 + { + \bool_if:NTF \l__acro_include_endings_format_bool + { + \str_case:nn {#1} + { + {long} + { + \bool_if:NTF \l__acro_custom_long_format_bool + { \l__acro_custom_long_format_tl } + { + \bool_if:NTF \l__acro_first_instance_bool + { \l__acro_first_long_format_tl } + { \l__acro_long_format_tl } + } + } + {short} + { + \bool_if:NTF \l__acro_custom_short_format_bool + { \l__acro_custom_short_format_tl } + { \l__acro_short_format_tl } + } + {alt} + { + \bool_if:NTF \l__acro_custom_alt_format_bool + { \l__acro_custom_alt_format_tl } + { \l__acro_alt_format_tl } + } + {foreign} + { + \bool_if:NTF \l__acro_custom_foreign_format_bool + { \l__acro_custom_foreign_format_tl } + { \l__acro_foreign_format_tl } + } + } + } + { \use:n } + {#2} + } + +\prg_new_conditional:Npnn \acro_if_ending_exist:n #1 {p,T,F,TF} + { + \seq_if_in:NnTF \l__acro_endings_seq {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: ending +% #2: short|alt|… +\prg_new_conditional:Npnn \acro_if_ending_form_exist:nn #1#2 {p,T,F,TF} + { + \cs_if_exist:cTF {l__acro_#2_#1_prop} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: name +% #2: default short +% #3: default long +\cs_new_protected:Npn \acro_provide_ending:nnn #1#2#3 + { + \acro_if_ending_exist:nTF {#1} + { + \acro_harmless_message:nn {ending-exists} {#1} + % short variables + \acro_set_ending_variables:nnn {short} {#1} {#2} + % alt variables + \acro_set_ending_variables:nnn {alt} {#1} {#2} + % long variables + \acro_set_ending_variables:nnn {long} {#1} {#3} + % foreign variables % XXX + \acro_set_ending_variables:nnn {foreign} {#1} {#3} + } + { + % registering: + \bool_if:NT \g__acro_first_acronym_declared_bool + { \acro_serious_message:n {ending-before-acronyms} } + \seq_put_right:Nn \l__acro_endings_seq {#1} + \bool_new:c {l__acro_#1_bool} + % short variables + \acro_define_and_set_ending_variables:nnn {short} {#1} {#2} + % alt variables + \acro_define_and_set_ending_variables:nnn {alt} {#1} {#2} + % long variables + \acro_define_and_set_ending_variables:nnn {long} {#1} {#3} + % foreign variables % XXX + \acro_define_and_set_ending_variables:nnn {foreign} {#1} {#3} + % define setup command: + \tl_set:Nn \l__acro_tmpa_tl {#1} + \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} + \cs_new_protected:cpn {acro_ \l__acro_tmpa_tl :} + { \bool_set_true:c {l__acro_#1_bool} } + % acronym properties: + % short-<ending>: + \acro_declare_property:nnn {short_#1} {short-#1} + { + \prop_put:cnn {l__acro_short_#1_form_prop} {##1} {false} + \prop_put:cnx {l__acro_pdfstring_short_#1_prop} + {##1} { \prop_item:Nn \l__acro_short_prop {##1} \exp_not:n {##2} } + } + % short-<ending>-form: + \acro_declare_property_generic:nnn {short_#1_form} {short-#1-form} + { + \__acro_property_check:nn {##1} {short-#1-form} + \prop_put:cnn {l__acro_short_#1_form_prop} {##1} {true} + \prop_put:cnn {l__acro_short_#1_prop} {##1} {##2} + \prop_put:cnn {l__acro_pdfstring_short_#1_prop} {##1} {##2} + } + % alt-<ending>: + \acro_declare_property:nnn {alt_#1} {alt-#1} + { + \prop_put:cnn {l__acro_alt_#1_form_prop} {##1} {false} + \prop_put:cnx {l__acro_pdfstring_alt_#1_prop} + {##1} { \prop_item:Nn \l__acro_alt_prop {##1} \exp_not:n {##2} } + } + % alt-<ending>-form: + \acro_declare_property_generic:nnn {alt_#1_form} {alt-#1-form} + { + \__acro_property_check:nn {##1} {alt-#1-form} + \prop_put:cnn {l__acro_alt_#1_form_prop} {##1} {true} + \prop_put:cnn {l__acro_alt_#1_prop} {##1} {##2} + \prop_put:cnn {l__acro_pdfstring_alt_#1_prop} {##1} {##2} + } + % long-<ending>: + \acro_declare_property:nnn {long_#1} {long-#1} + { \prop_put:cnn {l__acro_long_#1_form_prop} {##1} {false} } + % long-<ending>-form: + \acro_declare_property_generic:nnn {long_#1_form} {long-#1-form} + { + \__acro_property_check:nn {##1} {long-#1-form} + \prop_put:cnn {l__acro_long_#1_form_prop} {##1} {true} + \prop_put:cnn {l__acro_long_#1_prop} {##1} {##2} + } + % foreign-<ending>: % XXX + \acro_declare_property:nnn {foreign_#1} {foreign-#1} + { \prop_put:cnn {l__acro_foreign_#1_form_prop} {##1} {false} } + % foreign-<ending>-form: % XXX + \acro_declare_property_generic:nnn {foreign_#1_form} {foreign-#1-form} + { + \__acro_property_check:nn {##1} {foreign-#1-form} + \prop_put:cnn {l__acro_foreign_#1_form_prop} {##1} {true} + \prop_put:cnn {l__acro_foreign_#1_prop} {##1} {##2} + } + % options: + % short-<ending>-ending + % alt-<ending>-ending + % long-<ending>-ending + % foreign-<ending>-ending % XXX + % <ending>-ending + \keys_define:nn {acro} + { + short-#1-ending .code:n = + \bool_if:NT \g__acro_first_acronym_declared_bool + { \acro_serious_message:n {ending-before-acronyms} } + \tl_set:cn {l__acro_default_short_#1_tl} {##1} , + alt-#1-ending .code:n = + \bool_if:NT \g__acro_first_acronym_declared_bool + { \acro_serious_message:n {ending-before-acronyms} } + \tl_set:cn {l__acro_default_alt_#1_tl} {##1} , + long-#1-ending .code:n = + \bool_if:NT \g__acro_first_acronym_declared_bool + { \acro_serious_message:n {ending-before-acronyms} } + \tl_set:cn {l__acro_default_long_#1_tl} {##1} , + foreign-#1-ending .code:n = + \bool_if:NT \g__acro_first_acronym_declared_bool + { \acro_serious_message:n {ending-before-acronyms} } + \tl_set:cn {l__acro_default_foreign_#1_tl} {##1} , + #1-ending .code:n = + \bool_if:NT \g__acro_first_acronym_declared_bool + { \acro_serious_message:n {ending-before-acronyms} } + \__acro_read_ending_settings:nww {#1} ##1// \acro_stop: + } + % pdfstrings: + % TODO: add long forms: + \prop_new:c {l__acro_pdfstring_short_#1_prop} + \cs_new:cpn {acro_pdf_string_short_#1:n} ##1 + { + \acro_if_star_gobble:nTF {##1} + { \use:e { \prop_item:cn {l__acro_pdfstring_short_#1_prop} } } + { \use:e {\prop_item:cn {l__acro_pdfstring_short_#1_prop} {##1} } } + } + \cs_new:cpn {acpdfstring#1} { \use:c {acro_pdf_string_short_#1:n} } + \prop_new:c {l__acro_pdfstring_alt_#1_prop} + \cs_new:cpn {acro_pdf_string_alt_#1:n} ##1 + { + \acro_if_star_gobble:nTF {##1} + { \prop_item:cn {l__acro_pdfstring_alt_#1_prop} } + { \prop_item:cn {l__acro_pdfstring_alt_#1_prop} {##1} } + } + \cs_new:cpn {acpdfstringalt#1} { \use:c {acro_pdf_string_alt_#1:n} } + } + } + +% #1: short|alt|long +% #2: ending name +% #3: default ending +\cs_new_protected:Npn \acro_define_and_set_ending_variables:nnn #1#2#3 + { + \acro_define_ending_variables:nn {#1} {#2} + \acro_set_ending_variables:nnn {#1} {#2} {#3} + } + +% #1: short|alt|long +% #2: ending name +\cs_new_protected:Npn \acro_define_ending_variables:nn #1#2 + { + \prop_new:c {l__acro_#1_#2_prop} + \prop_new:c {l__acro_#1_#2_form_prop} + \tl_new:c {l__acro_#1_#2_tl} + \tl_new:c {l__acro_default_#1_#2_tl} + } + +% #1: short|alt|long +% #2: ending name +% #3: default ending +\cs_new_protected:Npn \acro_set_ending_variables:nnn #1#2#3 + { \tl_set:cn {l__acro_default_#1_#2_tl} {#3} } + +% #1: ending name +% #2: short (and long if #4 is blank) +% #3: long +\cs_new_protected:Npn \__acro_read_ending_settings:nww #1#2/#3/#4 \acro_stop: + { + \acro_set_ending_variables:nnn {short} {#1} {#2} + \acro_set_ending_variables:nnn {alt} {#1} {#2} + \tl_if_blank:nTF {#4} + { + \acro_set_ending_variables:nnn {long} {#1} {#3} + \acro_set_ending_variables:nnn {foreign} {#1} {#3} + } + { + \acro_set_ending_variables:nnn {long} {#1} {#2} + \acro_set_ending_variables:nnn {foreign} {#1} {#2} + } + } + +% -------------------------------------------------------------------------- +% enable us to know if the acronym is used only once and provide a different +% style for that: +\prg_new_protected_conditional:Npnn \acro_is_used:n #1 { T,F,TF } + { + \acro_record_barrier:n {#1} + \bool_lazy_and:nnTF + { \bool_if_p:c {g__acro_#1_used_bool} } + { + \bool_lazy_or_p:nn + { + \bool_lazy_and_p:nn + { \bool_if_p:c {g__acro_#1_first_use_bool} } + { \g__acro_mark_first_as_used_bool } + } + { !\g__acro_mark_first_as_used_bool } + } + { + \bool_if:NTF \l__acro_mark_as_used_bool + { + \__acro_aux_file:Nxxxx \acro@used@twice + {#1} + { \thepage } + { \arabic {page} } + { \arabic {abspage} } + } + { \__acro_aux_file:Nxxxx \acro@used@twice {#1} {} {} {} } + \prg_return_true: + } + { + \bool_if:NTF \l__acro_mark_as_used_bool + { + \__acro_aux_file:Nxxxx \acro@used@once + {#1} + { \thepage } + { \arabic {page} } + { \arabic {abspage} } + \bool_lazy_and:nnT + { !\bool_if_p:c {g__acro_#1_label_bool} } + { \l__acro_place_label_bool } + { + \bool_gset_true:c { g__acro_#1_label_bool } + \label{\l__acro_label_prefix_tl #1} + } + \bool_gset_true:c { g__acro_#1_used_bool } + } + {} + % I can't remember why I want an empty first use case for starred + % acronyms… + % { \__acro_aux_file:Nxxxx \acro@used@once {#1} {} {} {} } + \prg_return_false: + } + } + +\cs_new:Npn \acro_is_used:n #1 + { \acro_is_used:nTF {#1} { } { } } + +\cs_new_protected:Npn \__acro_aux_file:Nnnnn #1#2#3#4#5 + { \iow_shipout:Nn \@auxout { #1 {#2} {#3} {#4} {#5} } } +\cs_generate_variant:Nn \__acro_aux_file:Nnnnn {Nxxxx} + +\cs_new_protected:Npn \__acro_aux_file_now:n #1 + { \iow_now:Nn \@auxout {#1} } +\cs_generate_variant:Nn \__acro_aux_file_now:n {x} + +% -------------------------------------------------------------------------- +% the commands for the auxiliary file: +\cs_new_protected:Npn \acro@used@once #1#2#3#4 + { + \cs_gset_nopar:cpn {acro@#1@once} {#1} + \bool_gset_true:c {g__acro_#1_in_list_bool} + \tl_if_empty:nF {#2#3#4} + { + % \bool_gset_true:c { g__acro_#1_used_bool } + \seq_gput_right:cn {g__acro_#1_pages_seq} { {#2}{#3}{#4} } + } + } +\cs_new_protected:Npn \acro@used@twice #1#2#3#4 + { + \cs_gset_nopar:cpn {acro@#1@twice} {#1} + \tl_if_empty:nF {#2#3#4} + { \seq_gput_right:cn {g__acro_#1_pages_seq} { {#2}{#3}{#4} } } + } + +\cs_new_protected:Npn \acro@pages #1#2 + { \tl_gset:cn {g__acro_#1_recorded_pages_tl} {#2} } + +\cs_new_protected:Npn \acro@rerun@check + { + \bool_if:NT \g__acro_rerun_bool + { + \@latex@warning@no@line + {Acronyms~ may~ have~ changed.~ Please~ rerun~ LaTeX} + } + } + +\AtEndDocument + { + \bool_gset_false:N \g__acro_rerun_bool + \cs_gset_protected:Npn \acro@used@once #1#2#3#4 + { + \tl_set:Nn \l__acro_tmpa_tl {#1} + \tl_if_eq:cNF {acro@#1@once} \l__acro_tmpa_tl + { \bool_gset_true:N \g__acro_rerun_bool } + } + \cs_gset_protected:Npn \acro@used@twice #1#2#3#4 + { + \tl_set:Nn \l__acro_tmpa_tl {#1} + \tl_if_eq:cNF {acro@#1@twice} \l__acro_tmpa_tl + { \bool_gset_true:N \g__acro_rerun_bool } + } + \acro_for_all_acronyms_do:n + { + \seq_if_empty:cF {g__acro_#1_pages_seq} + { + \__acro_aux_file_now:x + { + \acro@pages {#1} + { \seq_use:cn {g__acro_#1_pages_seq} {|} } ^^J + \acro@barriers {#1} + { \seq_use:cn {g__acro_#1_barriers_seq} {,} } + } + } + \acro_check_barriers:n {#1} + } + \__acro_aux_file_now:n { \acro@rerun@check } + } + +% if `acro' is deactivated prevent unnecessary errors from aux file: +\if@filesw +\AtBeginDocument + { + \__acro_aux_file_now:n + { + \providecommand \acro@used@once [4] {} ^^J + \providecommand \acro@used@twice [4] {} ^^J + \providecommand \acro@pages [2] {} ^^J + \providecommand \acro@rerun@check {} ^^J + \providecommand \acro@print@list {} ^^J + \providecommand \acro@barriers [2] {} + } + } +\fi + +% -------------------------------------------------------------------------- +% #1: short|alt|long +% #2: string to be typeset +\cs_new_protected:Npn \__acro_typeset:nn #1#2 + { + \mode_if_horizontal:F { \leavevmode } + \group_begin: + \use:x + { + \bool_if:cTF {l__acro_custom_#1_format_bool} + { \exp_not:v {l__acro_custom_#1_format_tl} } + { \exp_not:v {l__acro_#1_format_tl} } + {#2} + } + \group_end: + } + +% typeset the short form: +% #1: ID +% #2: short form +\cs_new_protected:Npn \acro_write_short:nn #1#2 + { + \__acro_make_link:nn {#1} + { + \__acro_typeset:nn {short} + { + \bool_if:NTF \l__acro_first_upper_bool + { \exp_not:N \__acro_first_upper_case:n { \exp_not:n {#2} } } + { \exp_not:n {#2} } + } + } + } +\cs_generate_variant:Nn \acro_write_short:nn {nV,nv} + +% typeset the alternative form: +% #1: ID +% #2: alt form +\cs_new_protected:Npn \acro_write_alt:nn #1#2 + { + \__acro_make_link:nn {#1} + { + \__acro_typeset:nn {alt} + { + \bool_lazy_and:nnTF + { \l__acro_first_upper_bool } + { \l__acro_upper_short_bool } + { \exp_not:N \__acro_first_upper_case:n { \exp_not:n {#2} } } + { \exp_not:n {#2} } + } + } + } +\cs_generate_variant:Nn \acro_write_alt:nn {nV,nv} + +% typeset a long form: +% TODO: rethink the formatting mechanism +% right now a custom format gets applied additionally to the global one +% although before it +% #1: format +% #2: long form +\cs_new_protected:Npn \acro_write_long:nn #1#2 + { + \__acro_typeset:nn {long} + { + \exp_not:n {#1} + { + \bool_if:NTF \l__acro_first_upper_bool + { \exp_not:N \__acro_first_upper_case:n { \exp_not:n {#2} } } + { \exp_not:n {#2} } + } + } + } +\cs_generate_variant:Nn \acro_write_long:nn {VV,Vo,Vf,V,v,vv} + +\prg_new_conditional:Npnn \acro_if_foreign:n #1 {T,F,TF} + { + \bool_lazy_and:nnTF + { \l__acro_foreign_bool } + { \prop_if_in_p:Nn \l__acro_foreign_prop {#1} } + { \prg_return_true: } + { \prg_return_false: } + } + +\cs_new_protected:Npn \acro_foreign_language:nn #1#2 {} +\AtBeginDocument{ + \cs_if_exist:NTF \foreignlanguage + { + \cs_set_protected:Npn \acro_foreign_language:nn #1#2 + { + \tl_if_blank:nTF {#1} + {#2} + { \foreignlanguage {#1} {#2} } + } + } + { + \cs_set_protected:Npn \acro_foreign_language:nn #1#2 + { \use_ii:nn {#1} {#2} } + } +} +\cs_generate_variant:Nn \acro_foreign_language:nn {VV} + +\cs_new_protected:Npn \acro_write_foreign:n #1 + { + \acro_if_foreign:nT {#1} + { + \acro_property_get:nnT {#1} {foreign} + { + \group_begin: + \__acro_endings:nn {#1} {foreign} + \tl_use:N \l__acro_foreign_format_tl + { + \acro_foreign_language:VV + \l__acro_foreign_lang_tl + \l__acro_foreign_tl + } + \group_end: + } + } + } + +\cs_new:Npn \acroenparen #1 { (#1) } + +\cs_new_protected:Npn \acro_get_foreign:n #1 + { + \acro_property_get:nnT {#1} {foreign} + { + \tl_use:N \l__acro_foreign_sep_tl + \group_begin: + \tl_use:N \l__acro_foreign_list_format_tl + { + \acro_foreign_language:VV + \l__acro_foreign_lang_tl + \l__acro_foreign_tl + } + \group_end: + } + } + +% -------------------------------------------------------------------------- +% #1: id +% #2: short|alt +\cs_set_protected:Npn \acro_write_compact:nn #1#2 + { + \acro_get_ending_form:nn {#1} {#2} + \acro_acc_supp:nn + {#1} + { + \acro_write_tooltip:nnV + {#1} + { + \use:c {acro_write_#2:nv} {#1} {l__acro_#2_tl} + \acro_endings:nn {#1} {#2} + } + \l__acro_long_tl + } + } + +% TODO: get rid of argument #3? +% #1: ID +% #2: long|first-long|list-long|extra +% #3: long form +\cs_new_protected:Npn \acro_write_expanded:nnn #1#2#3 + { + \tl_set:Nn \l__acro_tmpa_tl {#2} + \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} + \acro_write_long:vn {l__acro_ \l__acro_tmpa_tl _format_tl} {#3} + \acro_endings:nn {#1} {long} + \tl_if_in:nnT {#2} {long} + { \l__acro_long_post_tl } + } +\cs_generate_variant:Nn \acro_write_expanded:nnn {nnV} + +% #1: ID +% #2: long|first-long|list-long|extra +\cs_new_protected:Npn \acro_write_expanded:nn #1#2 + { + \tl_set:Nn \l__acro_tmpa_tl {#2} + \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} + \acro_write_long:vv + {l__acro_ \l__acro_tmpa_tl _format_tl} + {l__acro_ \l__acro_tmpa_tl _tl} + \acro_endings:nn {#1} {long} + \tl_if_in:nnT {#2} {long} + { \l__acro_long_post_tl } + } + +% #1: id +\cs_new_protected:Npn \acro_after:n #1 + { + \acro_cite_if:Nn \l__acro_citation_all_bool {#1} + \acro_index_if:Nn \l__acro_addto_index_bool {#1} + \acro_property_get:nnT {#1} {post} + { \tl_use:N \l__acro_post_tl } + } + +\cs_new_protected:Npn \acro_check_single:n #1 + { + \acro_if_is_single:nT {#1} + { \cs_set_eq:NN \acro_hyper_link:nn \use_ii:nn } + } + +% -------------------------------------------------------------------------- +% #1: id +\cs_new_protected:Npn \acro_before:n #1 + { + \acro_get:n {#1} + \acro_is_used:n {#1} + \acro_check_single:n {#1} + } + +% the standard internals: +% #1: id +\cs_new_protected:Npn \acro_short:n #1 + { + \acro_before:n {#1} + \acro_write_indefinite:nn {#1} {short} + \acro_write_compact:nn {#1} {short} + \acro_after:n {#1} + } + +% get alternative entry: +% #1: id +\cs_new_protected:Npn \acro_alt:n #1 + { + \acro_before:n {#1} + \acro_alt_error:n {#1} + \acro_write_indefinite:nn {#1} {alt} + \acro_write_compact:nn {#1} {alt} + \acro_after:n {#1} + } + +% get long entry: +% #1: id +\cs_new_protected:Npn \acro_long:n #1 + { + \acro_before:n {#1} + \acro_write_indefinite:nn {#1} {long} + \acro_write_expanded:nn {#1} {long} + \acro_after:n {#1} + } + +% get foreign entry: +% #1: id +\cs_new_protected:Npn \acro_foreign:n #1 + { + \acro_get:n {#1} + \tl_if_blank:VF \l__acro_foreign_tl + { + \acro_is_used:n {#1} + \acro_check_single:n {#1} + \acro_write_long:VV \l__acro_foreign_format_tl \l__acro_foreign_tl + \acro_after:n {#1} + } + } + +% get extra entry: +% #1: id +\cs_new_protected:Npn \acro_extra:n #1 + { + \acro_get:n {#1} + \tl_if_blank:VF \l__acro_extra_tl + { + \acro_is_used:n {#1} + \acro_check_single:n {#1} + \acro_write_long:VV \l__acro_extra_format_tl \l__acro_extra_tl + \acro_after:n {#1} + } + } + +% output like the first time: +% #1: id +\cs_new_protected:Npn \acro_first:n #1 + { + \bool_gset_true:c {g__acro_#1_first_use_bool} + \acro_before:n {#1} + \acro_first_instance:nV {#1} \l__acro_long_tl + } + +% output like the first time with own long version: +% #1: id +% #2: instead of long entry +\cs_new_protected:Npn \acro_first_like:nn #1#2 + { + \bool_gset_true:c {g__acro_#1_first_use_bool} + \acro_before:n {#1} + \acro_first_instance:nn {#1} {#2} + } + +% ---------------------------------------------------------------------------- +% citations: +\cs_new:Npn \__acro_citation_cmd:w { \cite } +\cs_new:Npn \__acro_group_citation_cmd:w { \cite } + +% #1 pre +% #2 post +% #3 key +\cs_new:Npn \__acro_cite:nnn #1#2#3 + { + \quark_if_no_value:nTF {#1} + { \__acro_citation_cmd:w {#3} } + { + \quark_if_no_value:nTF {#2} + { \__acro_citation_cmd:w [#1] {#3} } + { \__acro_citation_cmd:w [#1] [#2] {#3} } + } + } +\cs_generate_variant:Nn \__acro_cite:nnn {VVV} + +\cs_new_protected:Npn \acro_cite:n #1 + { + \acro_property_get:nnT {#1} {before-citation} + { \acro_no_break: \l__acro_before_citation_tl } + \prop_get:NnNT \l__acro_citation_prop {#1} \l__acro_tmpa_tl + { + \prop_get:NnN \l__acro_citation_pre_prop {#1} \l__acro_tmpb_tl + \prop_get:NnN \l__acro_citation_post_prop {#1} \l__acro_tmpc_tl + \acro_no_break: + \tl_use:N \l__acro_citation_connect_tl + \__acro_cite:VVV + \l__acro_tmpb_tl + \l__acro_tmpc_tl + \l__acro_tmpa_tl + } + \acro_property_get:nnT {#1} {after-citation} + { \acro_no_break: \l__acro_after_citation_tl } + } + +\cs_new_protected:Npn \acro_group_cite:n #1 + { + \group_begin: + \cs_set_eq:NN \__acro_citation_cmd:w \__acro_group_citation_cmd:w + \tl_set_eq:NN + \l__acro_citation_connect_tl + \l__acro_between_group_connect_citation_tl + \acro_cite_if:Nn \l__acro_citation_first_bool {#1} + \group_end: + } + +\cs_new_protected:Npn \acro_cite_if:Nn #1#2 + { \bool_if:NT #1 { \acro_cite:n {#2} } } + +% ---------------------------------------------------------------------------- +% indexing: +\cs_new_protected:Npn \acro_index_if:Nn #1#2 + { + \bool_lazy_and:nnT {#1} { \l__acro_mark_as_used_bool } + { + \prop_get:NnN \l__acro_index_cmd_prop {#2} \l__acro_tmpa_tl + \prop_get:NnN \l__acro_index_sort_prop {#2} \l__acro_tmpb_tl + \prop_get:NnN \l__acro_index_prop {#2} \l__acro_tmpc_tl + \__acro_index:VnVV + \l__acro_tmpa_tl + {#2} + \l__acro_tmpb_tl + \l__acro_tmpc_tl + } + } + +\cs_new:Npn \__acro_index_cmd:n { \index } + +% #1: cmd +% #2: key +% #3: sort +% #4: replace +\cs_new_protected:Npn \__acro_index:nnnn #1#2#3#4 + { + \prop_get:NnNF \l__acro_short_prop {#2} \l__acro_index_short_tl {} + \prop_get:NnNF \l__acro_format_prop {#2} \l__acro_index_format_tl {} + \quark_if_no_value:VTF \l__acro_index_format_tl + { \tl_set:Nn \l__acro_tmpa_tl { \l__acro_short_format_tl \l__acro_index_short_tl } } + { \tl_set:Nn \l__acro_tmpa_tl { \l__acro_index_format_tl \l__acro_index_short_tl } } + \quark_if_no_value:nF {#1} + { \cs_set:Npn \__acro_index_cmd:n {#1} } + \quark_if_no_value:nTF {#4} + { + \quark_if_no_value:nTF {#3} + { \__acro_index_cmd:n { #2 @ { \l__acro_tmpa_tl } } } + { \__acro_index_cmd:n { #3 @ { \l__acro_tmpa_tl } } } + } + { \__acro_index_cmd:n {#4} } + } +\cs_generate_variant:Nn \__acro_index:nnnn {VnVV} + +% ---------------------------------------------------------------------------- +% accessability support +\cs_new_eq:NN \acro_acc_supp:nn \use_ii:nn + +\cs_new_protected:Npn \acro_get_acc_supp:nn #1#2 + { + \prop_get:NnNF \l__acro_acc_supp_prop {#1} \l__acro_acc_supp_tl + { \prop_get:NnNF \l__acro_short_prop {#1} \l__acro_acc_supp_tl {} } + \acro_for_endings_do:n + { + \bool_if:cT {l__acro_##1_bool} + { + \tl_put_right:Nv + \l__acro_acc_supp_tl + {l__acro_short_##1_tl} + } + } + \acro_do_acc_supp:VVn + \l__acro_acc_supp_tl + \l__acro_acc_supp_options_tl + {#2} + } + +\cs_new:Npn \acro_do_acc_supp:nnn #1#2#3 + { + \BeginAccSupp { ActualText = #1 , #2 } + #3 + \EndAccSupp { } + } +\cs_generate_variant:Nn \acro_do_acc_supp:nnn {VV} + +\AtEndPreamble + { + \bool_if:NT \l__acro_acc_supp_bool + { + \RequirePackage {accsupp} + \cs_set_eq:NN \acro_acc_supp:nn \acro_get_acc_supp:nn + } + \bool_if:NT \l__acro_tooltip_bool + { + \RequirePackage {pdfcomment} + \cs_if_eq:NNT \__acro_tooltip_cmd:nn \use_i:nn + { \cs_set:Npn \__acro_tooltip_cmd:nn { \pdftooltip } } + } + } + +% -------------------------------------------------------------------------- +% tooltips for acronyms + +% #1: id +% #2: printed text +% #3: tool tip text +\cs_new_protected:Npn \acro_write_tooltip:nnn #1#2#3 + { + \acro_property_get:nnTF {#1} {tooltip} + { \__acro_check_tooltip:nV {#2} \l__acro_tooltip_tl } + { \__acro_check_tooltip:nn {#2} {#3} } + } +\cs_generate_variant:Nn \acro_write_tooltip:nnn {nnV} + +% #1: printed text +% #2: tool tip text +\cs_new_protected:Npn \__acro_check_tooltip:nn #1#2 + { + \bool_if:NTF \l__acro_tooltip_inside_bool + {#1} + { + \bool_set_true:N \l__acro_tooltip_inside_bool + \__acro_tooltip_cmd:nn {#1} {#2} + } + } +\cs_generate_variant:Nn \__acro_check_tooltip:nn { nV } + +% use whatever command you like for creating tooltips here: +% #1: printed text +% #2: tool tip text +\cs_new_eq:NN \__acro_tooltip_cmd:nn \use_i:nn + +% -------------------------------------------------------------------------- +% indefinite articles: + +% #1: ID +% #2: short|long|alt +\cs_new_protected:Npn \acro_write_indefinite:nn #1#2 + { + \bool_if:NT \l__acro_indefinite_bool + { \prop_item:cn {l__acro_#2_indefinite_prop} {#1} ~ } + \bool_if:NT \l__acro_upper_indefinite_bool + { + \__acro_first_upper_case:x + { \prop_item:cn {l__acro_#2_indefinite_prop} {#1} } ~ + } + } + +% -------------------------------------------------------------------------- +% experimental sorting feature: + +% the following code is an adaption of expl3 code used for \str_if_eq:NN(TF) +\sys_if_engine_luatex:TF + { + \tl_set:Nn \l__acro_tmpa_tl + { + acro ~ = ~ acro ~ or ~ { ~ } ~ + function ~ acro.strcmp ~ (A, B) ~ + if ~ A ~ == ~ B ~ then ~ + tex.write ("0") ~ + elseif ~ A ~ < ~ B ~ then ~ + tex.write ("-1") ~ + else ~ + tex.write ("1") ~ + end ~ + end + } + \lua_now:e { \l__acro_tmpa_tl } + \cs_new_protected:Npn \acro_strcmp:nn #1#2 + { + \lua_now:e + { + acro.strcmp + ( + " \__acro_escape_x:n {#1} " , + " \__acro_escape_x:n {#2} " + ) + } + } + \cs_new:Npn \__acro_escape_x:n #1 + { + \lua_escape:e + { \__kernel_tl_to_str:w \use:e { {#1} } } + } + } + { \cs_new_eq:NN \acro_strcmp:nn \tex_strcmp:D } + +\AtBeginDocument + { + \bool_if:NT \l__acro_sort_bool + { + \cs_new_protected:Npn \acro_sort_prop:NN #1#2 + { + \seq_clear:N \l__acro_tmpa_seq + \prop_clear:N \l__acro_tmpa_prop + \prop_clear:N \l__acro_tmpb_prop + \prop_map_inline:Nn #2 + { + \seq_put_right:Nn \l__acro_tmpa_seq {##2} + \prop_put:Nnn \l__acro_tmpa_prop {##1} {##2} + } + \seq_sort:Nn \l__acro_tmpa_seq + { + \int_compare:nTF + { + \acro_strcmp:nn + { \str_fold_case:n {##1} } + { \str_fold_case:n {##2} } + = -1 + } + { \sort_return_same: } + { \sort_return_swapped: } + } + \seq_map_inline:Nn \l__acro_tmpa_seq + { + \prop_map_inline:Nn \l__acro_tmpa_prop + { + \str_if_eq:nnT {##1} {####2} + { + \prop_get:NnN #1 {####1} \l__acro_tmpa_tl + \prop_put:NnV \l__acro_tmpb_prop {####1} + \l__acro_tmpa_tl + } + } + } + \prop_set_eq:NN #1 \l__acro_tmpb_prop + } + } + } + +% -------------------------------------------------------------------------- +% regarding list printing: +% this command ensures that a rerun warning is given when \printacronyms +% is set the first time. This mechanism doesn't make very much sense, +% should be replaced by a different and more efficient one +% +\cs_new_protected:Npn \acro@print@list + { \cs_if_exist:NF \acro@printed@list { \cs_new:Npn \acro@printed@list { printed } } } + +% -------------------------------------------------------------------------- +% trailing tokens and what to do when present + +\cs_new_protected:Npn \acro_new_trailing_token:n #1 + { \bool_new:c {l__acro_trailing_#1_bool} } +\cs_new_protected:Npn \acro_activate_trailing_action:n #1 + { \bool_set_true:c {l__acro_trailing_#1_bool} } +\cs_new_protected:Npn \acro_deactivate_trailing_action:n #1 + { \bool_set_false:c {l__acro_trailing_#1_bool} } + +% register a new token but don't activate its action: +% #1: token +% #2: name +\cs_new_protected:Npn \acro_register_trailing_token:Nn #1#2 + { + \prop_put:Nnn \l__acro_trailing_tokens_prop {#2} {#1} + \prop_put:Nnn \l__acro_trailing_actions_prop {#1} + { \acro_activate_trailing_action:n {#2} } + \acro_new_trailing_token:n {#2} + } + +\cs_new_protected:Npn \acro_for_all_trailing_tokens_do:n #1 + { \prop_map_inline:Nn \l__acro_trailing_tokens_prop {#1} } + +% activate a token: +\cs_new_protected:Npn \acro_activate_trailing_token:n #1 + { + \prop_get:NnN \l__acro_trailing_tokens_prop {#1} \l__acro_tmpa_tl + \tl_put_right:NV \l__acro_trailing_tokens_tl \l__acro_tmpa_tl + } + +% deactivate a token: +\cs_new_protected:Npn \acro_deactivate_trailing_token:n #1 + { + \prop_get:NnN \l__acro_trailing_tokens_prop {#1} \l__acro_tmpa_tl + \tl_remove_all:NV \l__acro_trailing_tokens_tl \l__acro_tmpa_tl + } + +% #1: name +\prg_new_conditional:Npnn \acro_if_trailing_token:n #1 {p,T,F,TF} + { + \bool_if:cTF {l__acro_trailing_#1_bool} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: csv list of names +\prg_new_protected_conditional:Npnn \acro_if_trailing_tokens:n #1 {T,F,TF} + { + \bool_set_false:N \l__acro_trailing_tokens_bool + \clist_map_inline:nn {#1} + { + \bool_if:cT {l__acro_trailing_##1_bool} + { + \bool_set_true:N \l__acro_trailing_tokens_bool + \clist_map_break: + } + } + \bool_if:NTF \l__acro_trailing_tokens_bool + { \prg_return_true: } + { \prg_return_false: } + } + +\cs_new_protected:Npn \aciftrailing { \acro_if_trailing_tokens:nTF } + +\cs_new_protected:Npn \__acro_check_trail:N #1 + { + \tl_map_inline:Nn \l__acro_trailing_tokens_tl + { + \token_if_eq_meaning:NNT #1 ##1 + { \prop_item:Nn \l__acro_trailing_actions_prop {##1} } + } + } + +% options for activating actions: +\keys_define:nn {acro} + { + activate-trailing-tokens .code:n = + \clist_map_inline:nn {#1} { \acro_activate_trailing_token:n {##1} } , + deactivate-trailing-tokens .code:n = + \clist_map_inline:nn {#1} { \acro_deactivate_trailing_token:n {##1} } + } + +% --------------------------------------------------------------------------- +% reset outputs, they'll behave like the first time again (!not like the _only_ +% time!): +\cs_new_protected:Npn \acro_reset:n #1 + { + \bool_gset_false:c { g__acro_#1_used_bool } + \bool_gset_false:c { g__acro_#1_first_use_bool } + } + +\cs_new_protected:Npn \acro_mark_as_used:n #1 + { + \bool_gset_true:c { g__acro_#1_used_bool } + \bool_gset_true:c { g__acro_#1_first_use_bool } + \bool_gset_true:c { g__acro_#1_in_list_bool } + \if@filesw + \__acro_aux_file_now:n { \acro@used@once {#1} {} {} {} } + \__acro_aux_file_now:n { \acro@used@twice {#1} {} {} {} } + \fi + } + +\cs_new_protected:Npn \acro_reset_all: + { \acro_for_all_acronyms_do:n { \acro_reset:n {##1} } } + +% make sure that no acronym is used at the beginning of the document, see +% issue #81 for reasons why this may be necessary: +\AfterEndPreamble { \acro_reset_all: } + +\cs_new_protected:Npn \acro_mark_all_as_used: + { \acro_for_all_acronyms_do:n { \acro_mark_as_used:n {##1} } } + +\prg_new_conditional:Npnn \acro_if_acronym_used:n #1 { p,T,F,TF } + { + \bool_lazy_and:nnTF + { \bool_if_p:c {g__acro_#1_used_bool} } + { !\acro_if_is_single_p:n {#1} } + { \prg_return_true: } + { \prg_return_false: } + } + +% -------------------------------------------------------------------------- +% acronym barriers: allow local lists of only those acronyms used between two +% barriers + +\keys_define:nn {acro} + { + use-barriers .bool_gset:N = \g__acro_use_barriers_bool , + use-barriers .initial:n = false , + reset-at-barriers .bool_gset:N = \g__acro_reset_at_barrier_bool , + reset-at-barriers .initial:n = false + } + +\cs_new_protected:Npn \acro_barrier: + { + \int_gincr:N \g__acro_barrier_int + \bool_if:NT \g__acro_reset_at_barrier_bool + { \acro_reset_all: } + } + +\cs_new_protected:Npn \acro_check_barriers:n #1 + { + \bool_if:NT \g__acro_use_barriers_bool + { + \tl_set:Nx \l__acro_tmpa_tl + { \seq_use:cn {g__acro_#1_barriers_seq} {} } + \tl_set:Nx \l__acro_tmpb_tl + { \seq_use:cn {g__acro_#1_recorded_barriers_seq} {} } + \tl_if_eq:NNF \l__acro_tmpa_tl \l__acro_tmpb_tl + { + \@latex@warning@no@line + {Rerun~to~get~barriers~of~acronym~#1~right} + } + } + } + +\cs_new_protected:Npn \acro_record_barrier:n #1 + { + \bool_if:NT \g__acro_use_barriers_bool + { + \seq_if_in:cxF {g__acro_#1_barriers_seq} + { \int_use:N \g__acro_barrier_int } + { + \seq_gput_right:cx {g__acro_#1_barriers_seq} + { \int_use:N \g__acro_barrier_int } + } + } + } + +% #1: id +% #2: barrier number +\prg_new_protected_conditional:Npnn \acro_if_in_barrier:nn #1#2 {T,F,TF} + { + \seq_if_in:cnTF {g__acro_#1_recorded_barriers_seq} {#2} + { \prg_return_true: } + { \prg_return_false: } + } +\cs_generate_variant:Nn \acro_if_in_barrier:nnTF {nx} + +\cs_new_protected:Npn \acro@barriers #1#2 + { \seq_gset_split:cnn {g__acro_#1_recorded_barriers_seq} {,} {#2} } + +% -------------------------------------------------------------------------- +% the user commands -- preparation: +\cs_new_protected:Npn \acro_begin: + { + \group_begin: + \__acro_check_after_end:w + } + +\cs_new_protected:Npn \__acro_check_after_end:w #1 \acro_end: + { + \cs_set:Npn \__acro_execute: + { + \__acro_check_trail:N \l_peek_token + #1 + \acro_end: % this will end the group opened by \acro_begin: + } + \peek_after:Nw \__acro_execute: + } + +\cs_new_protected:Npn \acro_end: { \group_end: } + +\cs_new_protected:Npn \acro_reset_specials: + { + \bool_set_false:N \l__acro_indefinite_bool + \bool_set_false:N \l__acro_first_upper_bool + \bool_set_false:N \l__acro_upper_indefinite_bool + \acro_for_endings_do:n { \bool_set_false:c {l__acro_##1_bool} } + } + +% #1: ID +% #2: true|false +\cs_new_protected:Npn \acro_check_acronym:nn #1#2 + { + \acro_defined:n {#1} + \acro_use_acronym:n {#2} + } + +% #1: boolean +% #2: ID +\cs_new_protected:Npn \acro_check_and_mark_if:nn #1#2 + { + \bool_lazy_or:nnTF {#1} { !\l__acro_use_acronyms_bool } + { \acro_check_acronym:nn {#2} {false} } + { \acro_check_acronym:nn {#2} {true} } + } + +\cs_new_protected:Npn \acro_switch_off: + { \bool_set_false:N \l__acro_use_acronyms_bool } + +\cs_new_protected:Npn \acro_switch_on: + { \bool_set_true:N \l__acro_use_acronyms_bool } + +% commands for (re)defining \ac-like macros: +\cs_new_protected:Npn \acro_define_new_acro_command:NN #1#2 + { + % #1: csname + % #2: definition where `#1' refers to the ID + \cs_new_protected:Npn #1 ##1##2 + { + \cs_set:Npn \__acro_tmp:n ####1 {##2} + \cs_new_protected:cpx + {acro_ \__acro_remove_backslash:N ##1 :nnn} ####1####2####3 + { + \acro_begin: + \acro_reset_specials: + \exp_not:N \tl_if_blank:nF {####2} { \keys_set:nn {acro} {####2} } + \acro_check_and_mark_if:nn {####1} {####3} + \__acro_tmp:n {####3} + \acro_end: + } + #2 ##1 {sO{}m} + { + \acro_case_insensitive_command:cnnn + {acro_ \__acro_remove_backslash:N ##1 :nnn} + {####1} + {####2} + {####3} + } + } + } +\cs_generate_variant:Nn \acro_define_new_acro_command:NN {cc} +\cs_generate_variant:Nn \acro_check_and_mark_if:nn {nx} + +% commands for (re)defining \acflike-like macros: +\cs_new_protected:Npn \acro_define_new_acro_pseudo_command:NN #1#2 + { + % #1: csname + % #2: definition where `#1' refers to the ID and `#2' to the pseudo long form + \cs_new_protected:Npn #1 ##1##2 + { + \cs_set:Npn \__acro_tmp:nn ####1####2 {##2} + \cs_new_protected:cpx + {acro_ \__acro_remove_backslash:N ##1 :nnn} ####1####2####3 + { + \acro_begin: + \acro_reset_specials: + \acro_check_and_mark_if:nn {####1} {####3} + \__acro_tmp:nn {####3} {####2} + \acro_end: + } + #2 ##1 {smm} + { + \acro_case_insensitive_command:cnnn + {acro_ \__acro_remove_backslash:N ##1 :nnn} + {####1} + {####3} + {####2} + } + } + } +\cs_generate_variant:Nn \acro_define_new_acro_pseudo_command:NN {cc} + +\clist_map_inline:nn {New,Renew,Declare,Provide} + { + \acro_define_new_acro_command:cc + {#1AcroCommand} + {#1DocumentCommand} + \acro_define_new_acro_pseudo_command:cc + {#1PseudoAcroCommand} + {#1DocumentCommand} + } + +% -------------------------------------------------------------------------- +% user commands -- facilities +\cs_new_protected:Npn \acro_first_upper: + { + \bool_if:NTF \l__acro_indefinite_bool + { + \bool_set_false:N \l__acro_indefinite_bool + \bool_set_true:N \l__acro_upper_indefinite_bool + } + { \bool_set_true:N \l__acro_first_upper_bool } + } + +\cs_new_protected:Npn \acro_indefinite: + { + \bool_if:NTF \l__acro_first_upper_bool + { + \bool_set_true:N \l__acro_upper_indefinite_bool + \bool_set_false:N \l__acro_first_upper_bool + } + { \bool_set_true:N \l__acro_indefinite_bool } + } + +\cs_new_protected:Npn \acro_cite: + { + \bool_set_true:N \l__acro_citation_all_bool + \bool_set_true:N \l__acro_citation_first_bool + } + +\cs_new_protected:Npn \acro_no_cite: + { + \bool_set_false:N \l__acro_citation_all_bool + \bool_set_false:N \l__acro_citation_first_bool + } + +\cs_new_protected:Npn \acro_index: + { \bool_set_true:N \l__acro_addto_index_bool } + +% similar macros \acro_<ending>: are defined by \acro_provide_ending:nnn + +% --------------------------------------------------------------------------- +% process options: +\ProcessKeysPackageOptions {acro} + +% --------------------------------------------------------------------------- +% PDF bookmark support +\cs_new:Npn \acpdfstring + { \acro_pdf_string_short:n } + +\cs_new:Npn \acpdfstringalt + { \acro_pdf_string_alt:n } + +\cs_new:Npn \acpdfstringlong + { \acro_pdf_string_long:n } + +\cs_new:Npn \acpdfstringfirst #1 + { \acpdfstringlong {#1} ~ ( \acpdfstring {#1} ) } + +% TODO: place this somewhere where endings are defined: +\cs_new:Npn \acpdfstringlongplural + { \acro_pdf_string_long_plural:n } + +\prg_new_conditional:Npnn \acro_if_star_gobble:n #1 {TF} + { + \if_meaning:w *#1 + \prg_return_true: + \else: + \prg_return_false: + \fi: + } + +\cs_new:Npn \acro_expandable_short:n #1 + { \use:e { \prop_item:Nn \l__acro_short_prop {#1} } } + +\cs_new:Npn \acro_expandable_alt:n #1 + { \use:e { \prop_item:Nn \l__acro_alt_prop {#1} } } + +\cs_new:Npn \acro_expandable_long:n #1 + { \use:e { \prop_item:Nn \l__acro_long_prop {#1} } } + +\cs_new:Npn \acro_expandable_long_plural:n #1 + { + \bool_if:cTF + { c_ \prop_item:Nn \l__acro_long_plural_form_prop {#1} _bool } + { \use:e { \prop_item:Nn \l__acro_long_plural_prop {#1} } } + { + \use:e { + \prop_item:Nn \l__acro_long_prop {#1} + \prop_item:Nn \l__acro_long_plural_prop {#1} + } + } + } + +\cs_new:Npn \acro_pdf_string_short:n #1 + { + \acro_if_star_gobble:nTF {#1} + { \acro_expandable_short:n } + { \acro_expandable_short:n {#1} } + } + +\cs_new:Npn \acro_pdf_string_alt:n #1 + { + \acro_if_star_gobble:nTF {#1} + { \acro_expandable_alt:n } + { \acro_expandable_alt:n {#1} } + } + +\cs_new:Npn \acro_pdf_string_long:n #1 + { + \acro_if_star_gobble:nTF {#1} + { \acro_expandable_long:n } + { \acro_expandable_long:n {#1} } + } + +% TODO: place this somewhere where endings are defined: +\cs_new:Npn \acro_pdf_string_long_plural:n #1 + { + \acro_if_star_gobble:nTF {#1} + { \acro_expandable_long_plural:n } + { \acro_expandable_long_plural:n {#1} } + } + +\AtBeginDocument + { + \@ifpackageloaded {hyperref} + { + \bool_set_true:N \l__acro_hyperref_loaded_bool + \pdfstringdefDisableCommands + { + \cs_set_eq:NN \ac \acpdfstring + \cs_set_eq:NN \Ac \acpdfstring + \cs_set_eq:NN \acs \acpdfstring + \cs_set_eq:NN \acl \acpdfstringlong + \cs_set_eq:NN \Acl \acpdfstringlong + \cs_set_eq:NN \acf \acpdfstringfirst + \cs_set_eq:NN \Acf \acpdfstringfirst + \cs_set_eq:NN \aca \acpdfstringalt + \cs_set_eq:NN \acp \acpdfstringplural + \cs_set_eq:NN \Acp \acpdfstringplural + \cs_set_eq:NN \acsp \acpdfstringplural + \cs_set_eq:NN \aclp \acpdfstringlongplural + \cs_set_eq:NN \Aclp \acpdfstringlongplural + \cs_set_eq:NN \acfp \acpdfstringplural + \cs_set_eq:NN \Acfp \acpdfstringplural + \cs_set_eq:NN \acap \acpdfstringaltplural + } + \cs_set_protected:Npn \acro_hyper_page:n #1 { \hyperpage {#1} } + } {} + } + +% -------------------------------------------------------------------------- +% key and order checking +\msg_new:nnn {acro} {no-id} + { + Something~ has~ gone~ wrong,~ you've~ probably~ forgotten~ to~ set~ the~ + acronym~ ID. + } + +\msg_new:nnn {acro} {before-short} + { + You've~ set~ the~ property~ `#2'~ before~ the~ `short'~ property~ for~ + acronym~ `#1'~ but~ it~ needs~ to~ be~ set~ after~ it. + } + +\msg_new:nnn {acro} {missing} + { The~ `#2'~ property~ for~ acronym~ `#1'~ is~ missing. } + +\msg_new:nnn {acro} {doubled-property} + { + It~ seems~ to~ me~ you~ have~ used~ the~ `#2'~ property~ twice~ in~ the~ + declaration~ of~ acronym~ `#1'.~ If~ you~ haven't~ there's~ + something~ different~ wrong~ and~ I'm~ lost.~ You~'re~ on~ your~ own~ + then. + } + +% #1: acronym +% #2: property +\cs_new_protected:Npn \__acro_property_check:nn #1#2 + { + \str_if_empty:NT \l__acro_current_id_str + { \acro_serious_message:n {no-id} } + \str_if_eq:nnF {#2} {short} + { + \acro_property_if_set:nnF {#1} {short} + { + \keys_set:nn {acro/declare-acronym} { short = {#1} } + \acro_harmless_message:nn {substitute-short} {#1} + } + } + \acro_property_mark_set:nn {#1} {#2} + } + +\cs_new_protected:Npn \__acro_first_property_check:nn #1#2 + { + \cs_if_exist:cTF {l__acro_#1_short_set_bool} + { + \acro_property_if_set:nnT {#1} {short} + { \acro_serious_message:nnn {doubled-property} {#1} {#2} } + } + { \bool_new:c {l__acro_#1_short_set_bool} } + \acro_property_mark_set:nn {#1} {short} + } + +% #1: ID +% #2: property +\prg_new_conditional:Npnn \acro_property_if_set:nn #1#2 {T,F,TF} + { + \bool_if:cTF {l__acro_#1_#2_set_bool} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: ID +% #2: property +\cs_new_protected:Npn \acro_property_mark_set:nn #1#2 + { \bool_set_true:c { l__acro_#1_#2_set_bool } } +\cs_generate_variant:Nn \acro_property_mark_set:nn {V} + +% -------------------------------------------------------------------------- +% the internal property selection functions for \DeclareAcronym: + +\cs_new_protected:Npn \acro_for_properties_do:n + { \prop_map_inline:Nn \g__acro_properties_prop } + +% #1: name in associated cs +% #2: property name +% #3: action +\cs_new_protected:Npn \acro_declare_property_generic:nnn #1#2#3 + { + \prop_clear_new:c {l__acro_#1_prop} + \tl_clear_new:c {l__acro_#1_tl} + \cs_new_protected:cpn {__acro_declare_#1:nn} ##1##2 {#3} + \cs_generate_variant:cn {__acro_declare_#1:nn} {V} + \keys_define:nn {acro/declare-acronym} + { + #2 .code:n = + \use:c {__acro_declare_#1:Vn} \l__acro_current_id_str {##1} + \acro_property_mark_set:Vn \l__acro_current_id_str {#2} + } + \prop_gput:Nnn \g__acro_properties_prop {#2} {#1} + } + +% #1: name in associated cs +% #2: property name +% #3: action +\cs_new_protected:Npn \acro_declare_property:nnn #1#2#3 + { + \acro_declare_property_generic:nnn {#1} {#2} + { + \__acro_property_check:nn {##1} {#2} + \prop_put:cnn {l__acro_#1_prop} {##1} {##2} + #3 + } + } + +% #1: name in associated cs +% #2: property name +\cs_new_protected:Npn \acro_declare_property:nn #1#2 + { \acro_declare_property:nnn {#1} {#2} {} } +\cs_generate_variant:Nn \acro_declare_property:nn {V} + +\cs_new_protected:Npn \acro_declare_property_simple:n #1 + { + \tl_set:Nn \l__acro_tmpa_tl {#1} + \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} + \acro_declare_property:Vn \l__acro_tmpa_tl {#1} + } + +% #1: new alias property +% #2: old property +\cs_new_protected:Npn \acro_declare_property_alias:nn #1#2 + { + \keys_define:nn {acro/declare-acronym} + { #1 .meta:n = { #2 = {##1} } } + } + +% -------------------------------------------------------------------------- +% declare the properties for \DeclareAcronym: +% short: +\acro_declare_property_generic:nnn {short} {short} + { + \__acro_first_property_check:nn {#1} {short} + \prop_put:Nnn \l__acro_short_prop {#1} {#2} + \prop_put:Nnn \l__acro_sort_prop {#1} {#1} + \prop_put:Nnn \l__acro_index_sort_prop {#1} {#1} + \prop_put:Nnn \l__acro_alt_prop {#1} {#2} + \prop_put:Nnn \l__acro_pdfstring_short_prop {#1} {#2} + \prop_put:Nnn \l__acro_pdfstring_alt_prop {#1} {#2} + \acro_for_endings_do:n + { + \prop_put:cnv {l__acro_short_##1_prop} + {#1} {l__acro_default_short_##1_tl} + \prop_put:cnx {l__acro_pdfstring_short_##1_prop} + {#1} { \exp_not:n {#2} \exp_not:v {l__acro_default_short_##1_tl} } + \prop_put:cnn {l__acro_short_##1_form_prop} {#1} {false} + \prop_put:cnv {l__acro_alt_##1_prop} + {#1} {l__acro_default_alt_##1_tl} + \prop_put:cnx {l__acro_pdfstring_alt_##1_prop} + {#1} { \exp_not:n {#2} \exp_not:v {l__acro_default_short_##1_tl} } + \prop_put:cnn {l__acro_alt_##1_form_prop} {#1} {false} + } + \prop_put:NnV \l__acro_short_indefinite_prop + {#1} \l__acro_default_indefinite_tl + \prop_put:NnV \l__acro_alt_indefinite_prop + {#1} \l__acro_default_indefinite_tl + } + +% long: +\acro_declare_property:nnn {long} {long} + { + \prop_put:NnV \l__acro_long_indefinite_prop + {#1} + \l__acro_default_indefinite_tl + \acro_for_endings_do:n + { + \prop_put:cnn {l__acro_long_##1_form_prop} {#1} {false} + \acro_property_if_set:nnF {#1} {long-##1} + { \prop_put:cnv {l__acro_long_##1_prop} {#1} {l__acro_default_long_##1_tl} } + \prop_put:cnn {l__acro_foreign_##1_form_prop} {#1} {false} + \acro_property_if_set:nnF {#1} {foreign-##1} + { \prop_put:cnv {l__acro_foreign_##1_prop} {#1} {l__acro_default_foreign_##1_tl} } + } + } + +\acro_declare_property_simple:n {first-style} + +% list: +\acro_declare_property_simple:n {list} + +% defines `short-plural', `long-plural' and `long-plural-form' as well as the +% options `plural-ending', `short-plural-ending' and `long-plural-ending': +% \ProvideAcroEnding {plural} {s} {s} + +% short indefinite article: +\acro_declare_property_simple:n {short-indefinite} + +% long indefinite article: +\acro_declare_property_simple:n {long-indefinite} + +% pre long: +\acro_declare_property_simple:n {long-pre} + +% post long: +\acro_declare_property_simple:n {long-post} + +% post: +\acro_declare_property_simple:n {post} + +% sort: +\acro_declare_property:nnn {sort} {sort} + { + \acro_property_if_set:nnF {#1} {index-sort} + { \prop_put:Nnn \l__acro_index_sort_prop {#1} {#2} } + } + +% alternative: +\acro_declare_property:nnn {alt} {alt} + { + \prop_put:Nnn \l__acro_pdfstring_alt_prop {#1} {#2} + \prop_put:NnV \l__acro_alt_indefinite_prop + {#1} \l__acro_default_indefinite_tl + } + +\cs_set_protected:Npn \acro_alt_error:n #1 + { + \acro_property_if_set:nnF {#1} {alt} + { \acro_harmless_message:nn {no-alternative} {#1} } + } + +% alt. indefinite article: +\acro_declare_property_simple:n {alt-indefinite} + +% foreign: +\acro_declare_property_simple:n {foreign} + +% foreign-lang: +\acro_declare_property_simple:n {foreign-lang} + +% format: +\acro_declare_property_simple:n {format} + +% short format: +\acro_declare_property_alias:nn {short-format} {format} + +% alt format: +\acro_declare_property_simple:n {alt-format} + +% long format: +\acro_declare_property_simple:n {long-format} + +% first long format: +\acro_declare_property_simple:n {first-long-format} + +% pdfstring -- currently needs to be done `by hand': +\cs_new_protected:Npn \__acro_declare_pdfstring:nw #1#2/#3/#4 \acro_stop: + { + \__acro_property_check:nn {#1} {pdfstring} + \prop_put:Nnx \l__acro_pdfstring_short_prop {#1} {#2} + \acro_for_endings_do:n + { + \tl_if_blank:nTF {#4} + { + \prop_put:cnx {l__acro_pdfstring_short_##1_prop} + {#1} { \exp_not:n {#2} \exp_not:v {l__acro_default_short_##1_tl} } + } + { + \prop_put:cnn {l__acro_pdfstring_short_##1_prop} + {#1} {#2#3} + } + } + } +\cs_generate_variant:Nn \__acro_declare_pdfstring:nw {V} + +\keys_define:nn {acro/declare-acronym} + { + pdfstring .code:n = + \__acro_declare_pdfstring:Vw \l__acro_current_id_str #1 // \acro_stop: + } + +\cs_new_protected:Npn \__acro_declare_pdfstring_alt:nw #1#2/#3/#4 \acro_stop: + { + \__acro_property_check:nn {#1} {pdfstring-alt} + \prop_put:Nnn \l__acro_pdfstring_alt_prop {#1} {#2} + \acro_for_endings_do:n + { + \tl_if_empty:nTF {#3} + { + \prop_put:cnx {l__acro_pdfstring_alt_##1_prop} + {#1} { \exp_not:n {#2} \exp_not:v {l__acro_default_alt_##1_tl} } + } + { \prop_put:cnn {l__acro_pdfstring_alt_##1_prop} {#1} {#2#3} } + } + } +\cs_generate_variant:Nn \__acro_declare_pdfstring_alt:nw {V} + +\keys_define:nn {acro/declare-acronym} + { + pdfstring-alt .code:n = + \__acro_declare_pdfstring_alt:Vw \l__acro_current_id_str #1 // \acro_stop: + } + +% class: +\acro_declare_property_simple:n {class} + +% extra information: +\acro_declare_property_simple:n {extra} + +% single appearances: +\acro_declare_property_simple:n {single} + +% single format: +\acro_declare_property_simple:n {single-format} + +% acc supp: +\acro_declare_property:nn {acc_supp} {accsupp} + +% tooltip: +\acro_declare_property_simple:n {tooltip} + +% before-citation: +\acro_declare_property_simple:n {before-citation} + +% after-citation: +\acro_declare_property_simple:n {after-citation} + +% citation -- this needs a bit more work: +\cs_new_protected:Npn \__acro_declare_citation:nw #1#2[#3]#4[#5]#6#7 \acro_stop: + { + % no options: #1: ID, #2: property, #7 is blank + % 1 option: #1: ID, #4: property, #3: option, #5: \q_no_value + % 2 options: #1: ID: #6: property, #3: first option, #5: second option + \tl_if_blank:nTF {#7} + { + \__acro_declare_citation_aux:nnnn {#1} + { \q_no_value } + { \q_no_value } + {#2} + } + { + \quark_if_no_value:nTF {#5} + { + \__acro_declare_citation_aux:nnnx {#1} + { \q_no_value } + {#3} + { \tl_head:n {#4} } + } + { \__acro_declare_citation_aux:nnnn {#1} {#3} {#5} {#6} } + } + } +\cs_generate_variant:Nn \__acro_declare_citation:nw {V} + +\keys_define:nn {acro/declare-acronym} + { + cite .code:n = + \__acro_declare_citation:Vw + \l__acro_current_id_str #1 [\q_no_value][\q_no_value] \scan_stop: \acro_stop: + } +\prop_gput:Nnn \g__acro_properties_prop {cite} {cite} + +% #1: ID +% #2: pre +% #3: post +% #4: citation key +\cs_new_protected:Npn \__acro_declare_citation_aux:nnnn #1#2#3#4 + { + \__acro_property_check:nn {#1} {cite} + \prop_put:Nnn \l__acro_citation_prop {#1} {#4} + \quark_if_no_value:nF {#2} + { \prop_put:Nnn \l__acro_citation_pre_prop {#1} {#2} } + \quark_if_no_value:nF {#3} + { \prop_put:Nnn \l__acro_citation_post_prop {#1} {#3} } + } +\cs_generate_variant:Nn \__acro_declare_citation_aux:nnnn {nnnx} + +% TODO: +% add index entries, by default \index{<sort>@<short>} +% index: overwrite default <sort>@<short> entry completely +% index-sort: overwrite the <sort> part of <sort>@<short> entry + +% need to take care of custom index cmd, at least +% - \index{} +% - \index[]{} +% question is, though, if it should be the same one for all acronyms? +% I go for yes but would also add a `post' property that allows to add arbitrary +% TeX code after an acronym is typeset + +% index: +\acro_declare_property_simple:n {index} + +% index-sort: +\acro_declare_property_simple:n {index-sort} + +% index-cmd: +\acro_declare_property_simple:n {index-cmd} + +% -------------------------------------------------------------------------- +% acronym macros: +\cs_new_protected:Npn \__acro_define_acronym_macro:n #1 + { + \bool_if:NT \l__acro_create_macros_bool + { + \cs_if_exist:cTF {#1} + { + \bool_if:NTF \l__acro_strict_bool + { \cs_set:cpn {#1} { \ac {#1} \acro_xspace: } } + { \acro_serious_message:nn {macro} {#1} } + } + { \cs_new:cpn {#1} { \ac {#1} \acro_xspace: } } + } + } + +% -------------------------------------------------------------------------- +% internal acronym declaring function: +\cs_new_protected:Npn \acro_declare_acronym:nn #1#2 + { \acro_case_insensitive:Nnn \__acro_declare_acronym:nn {#1} {#2} } + +\cs_new_protected:Npn \__acro_declare_acronym:nn #1#2 + { + \seq_gput_right:Nn \g__acro_declared_acronyms_seq {#1} + \bool_gset_true:N \g__acro_first_acronym_declared_bool + \str_set:Nn \l__acro_current_id_str {#1} + \acro_for_properties_do:n + { \bool_new:c {l__acro_ \l__acro_current_id_str _##1_set_bool} } + \keys_set:nn {acro/declare-acronym} {#2} + \bool_new:c {g__acro_#1_first_use_bool} + \bool_new:c {g__acro_#1_used_bool} + \bool_new:c {g__acro_#1_label_bool} + \bool_new:c {g__acro_#1_in_list_bool} + \seq_new:c {g__acro_#1_barriers_seq} + \seq_new:c {g__acro_#1_recorded_barriers_seq} + \bool_if:NF \l__acro_print_only_used_bool + { \bool_gset_true:c {g__acro_#1_in_list_bool} } + \__acro_create_page_records:n {#1} + \__acro_define_acronym_macro:n {#1} + \str_clear:N \l__acro_current_id_str + \acro_property_if_set:nnF {#1} {short} + { \acro_serious_message:nnn {missing} {#1} {short} } + \acro_property_if_set:nnF {#1} {long} + { \acro_serious_message:nnn {missing} {#1} {long} } + \__acro_log_acronym:n {#1} + } + + +% -------------------------------------------------------------------------- +% print the list: +% #1: list of classes +% #2: list of excluded classes +\keys_define:nn {acro/print-acronyms} + { + include-classes .tl_set:N = \l__acro_included_classes_tl , + exclude-classes .tl_set:N = \l__acro_excluded_classes_tl , + name .tl_set:N = \l__acro_list_name_tl , + heading .code:n = \__acro_set_list_heading:n {#1} , + sort .bool_set:N = \l__acro_sort_bool , + local-to-barriers .bool_set:N = \l__acro_use_barrier_bool + } + +\cs_new_protected:Npn \acro_print_acronyms:n #1 + { + \group_begin: + % this is a cheap trick to prevent the \@noitemerr + % if one forgot to delete either the aux file or + % remove \printacronyms -- but it's local: + \cs_set:Npn \@noitemerr {} + \tl_clear:N \l__acro_included_classes_tl + \tl_clear:N \l__acro_excluded_classes_tl + \tl_if_blank:nF {#1} + { \keys_set:nn {acro/print-acronyms} {#1} } + \__acro_aux_file_now:n { \acro@print@list } + \bool_if:NT \l__acro_sort_bool + { \acro_sort_prop:NN \l__acro_short_prop \l__acro_sort_prop } + \acro_title_instance:VV + \l__acro_list_heading_cmd_tl + \l__acro_list_name_tl + \cs_if_exist:NTF \acro@printed@list + { + \acro_list_instance:VVV + \l__acro_list_instance_tl + \l__acro_included_classes_tl + \l__acro_excluded_classes_tl + } + { \@latex@warning@no@line {Rerun~to~get~acronym~list~right} } + \group_end: + } + +% -------------------------------------------------------------------------- +% language support +\RequirePackage {translations} + +\cs_new_protected:Npn \__acro_declare_translation:www #1 \q_mark #2=#3 \q_stop + { + \tl_set:Nx \l__acro_tmpa_tl { \tl_trim_spaces:n {#1} } + \tl_set:Nx \l__acro_tmpb_tl { \tl_trim_spaces:n {#2} } + \tl_if_in:nnT {#3} {=} + {} % TODO: misplaced equal sign + \tl_set:Nx \l__acro_tmpc_tl { \tl_trim_spaces:n {#3} } + \__acro_declare_translation:VVV + \l__acro_tmpb_tl + \l__acro_tmpa_tl + \l__acro_tmpc_tl + } + +% #1: key +% #2: lang +% #3: translation +\cs_new_protected:Npn \__acro_declare_translation:nnn #1#2#3 + { \DeclareTranslation {#1} {#2} {#3} } +\cs_generate_variant:Nn \__acro_declare_translation:nnn {VVV} + +% #1: key +% #2: csv list: { <lang1> = <translation1> , <lang2> = <translation2> } +\cs_new_protected:Npn \acro_declare_translation:nn #1#2 + { + \clist_map_inline:nn {#2} + { + \tl_if_blank:nF {##1} + { \__acro_declare_translation:www #1 \q_mark ##1 \q_stop } + } + } + +% tokenlists using the translations: +\tl_set:Nn \l__acro_list_name_tl { \GetTranslation {acronym-list-name} } +\tl_set:Nn \l__acro_page_name_tl { \GetTranslation {acronym-page-name}\@\, } +\tl_set:Nn \l__acro_pages_name_tl { \GetTranslation {acronym-pages-name}\@\, } +\tl_set:Nn \l__acro_next_page_tl { \,\GetTranslation {acronym-next-page}\@ } +\tl_set:Nn \l__acro_next_pages_tl { \,\GetTranslation {acronym-next-pages}\@ } + +% -------------------------------------------------------------------------- +% allow for a configuration file: + +\file_if_exist:nT + { \l_acro_config_file_name_tl . \l_acro_config_file_extension_tl } + { + \@onefilewithoptions + {\l_acro_config_file_name_tl} [] [] + \l_acro_config_file_extension_tl + } + +% -------------------------------------------------------------------------- +% define user functions: +% document commands: +\NewDocumentCommand \DeclareAcronym {mm} + { \acro_declare_acronym:nn {#1} {#2} } + +\NewDocumentCommand \acsetup { m } + { + \tl_if_blank:nF {#1} + { \keys_set:nn {acro} {#1} } + \ignorespaces + } + +\NewDocumentCommand \ProvideAcroEnding {mmm} + { \acro_provide_ending:nnn {#1} {#2} {#3} } + +\NewDocumentCommand \AcroRegisterTrailing {mm} + { \acro_register_trailing_token:Nn #1 {#2} } + +\NewDocumentCommand \DeclareAcroTranslation {mm} + { \acro_declare_translation:nn {#1} {#2} } + +\DeclareExpandableDocumentCommand \acifused { m } + { \acro_if_acronym_used:nTF {#1} } + +\NewDocumentCommand \acresetall {} + { \acro_reset_all: } + +\NewDocumentCommand \acuseall {} + { \acro_mark_all_as_used: } + +\NewDocumentCommand \acreset { > { \SplitList {,} } m } + { \ProcessList {#1} { \acro_reset:n } \ignorespaces } + +\NewDocumentCommand \acuse { > { \SplitList {,} } m } + { \ProcessList {#1} { \acro_mark_as_used:n } \ignorespaces } + +\NewDocumentCommand \acfirstupper {m} + { \acro_first_upper_case:n {#1} } + +\NewExpandableDocumentCommand \aciffirst {+m+m} + { \bool_if:NTF \l__acro_first_instance_bool {#1} {#2} } + +\NewDocumentCommand \acdot {} { \acro_dot: } +\NewDocumentCommand \acspace {} { \acro_space: } + +\NewDocumentCommand \acbarrier {} + { \acro_barrier: } + +\NewDocumentCommand \acswitchoff {} + { \acro_switch_off: } + +\NewDocumentCommand \acswitchon {} + { \acro_switch_on: } + +\NewDocumentCommand \printacronyms { O{} } + { \acro_print_acronyms:n {#1} } + +% -------------------------------------------------------------------------- +% styles +% #1: name +% #2: template +% #3: settings +\NewDocumentCommand \DeclareAcroFirstStyle {mmm} + { \acro_declare_first_style:nnn {#1} {#2} {#3} } + +\NewDocumentCommand \DeclareAcroExtraStyle {mmm} + { \acro_declare_extra_style:nnn {#1} {#2} {#3} } + +\NewDocumentCommand \DeclareAcroPageStyle {mmm} + { \acro_declare_page_style:nnn {#1} {#2} {#3} } + +\NewDocumentCommand \DeclareAcroListHeading {mm} + { \acro_declare_list_heading:nn {#1} {#2} } + +\NewDocumentCommand \DeclareAcroListStyle {mmm} + { \acro_declare_list_style:nnn {#1} {#2} {#3} } + +% -------------------------------------------------------------------------- +% endings: +\ProvideAcroEnding {plural} {s} {s} + +% -------------------------------------------------------------------------- +% use acronyms: +% automatic: +\NewAcroCommand \ac + { \acro_use:n {#1} } + +\NewAcroCommand \Ac + { + \acro_first_upper: + \acro_use:n {#1} + } + +\NewAcroCommand \iac + { + \acro_indefinite: + \acro_use:n {#1} + } + +\NewAcroCommand \Iac + { + \acro_first_upper: + \acro_indefinite: + \acro_use:n {#1} + } + +\NewAcroCommand \acp + { + \acro_plural: + \acro_use:n {#1} + } + +\NewAcroCommand \Acp + { + \acro_plural: + \acro_first_upper: + \acro_use:n {#1} + } + +\NewAcroCommand \acsingle + { + \acro_get:n {#1} + \acro_single:n {#1} + } + +\NewAcroCommand \acpsingle + { + \acro_get:n {#1} + \acro_plural: + \acro_single:n {#1} + } + +\NewAcroCommand \Acsingle + { + \acro_get:n {#1} + \acro_first_upper: + \acro_single:n {#1} + } + +\NewAcroCommand \Acpsingle + { + \acro_get:n {#1} + \acro_first_upper: + \acro_plural: + \acro_single:n {#1} + } + +% short: +\NewAcroCommand \acs + { \acro_short:n {#1} } + +\NewAcroCommand \Acs + { + \acro_first_upper: + \acro_short:n {#1} + } + +\NewAcroCommand \iacs + { + \acro_indefinite: + \acro_short:n {#1} + } + +\NewAcroCommand \Iacs + { + \acro_first_upper: + \acro_indefinite: + \acro_short:n {#1} + } + +\NewAcroCommand \acsp + { + \acro_plural: + \acro_short:n {#1} + } + +\NewAcroCommand \Acsp + { + \acro_first_upper: + \acro_plural: + \acro_short:n {#1} + } + +% alt: +\NewAcroCommand \aca + { \acro_alt:n {#1} } + +\NewAcroCommand \Aca + { + \acro_first_upper: + \acro_alt:n {#1} + } + +\NewAcroCommand \iaca + { + \acro_indefinite: + \acro_alt:n {#1} + } + +\NewAcroCommand \Iaca + { + \acro_first_upper: + \acro_indefinite: + \acro_alt:n {#1} + } + +\NewAcroCommand \acap + { + \acro_plural: + \acro_alt:n {#1} + } + +\NewAcroCommand \Acap + { + \acro_first_upper: + \acro_plural: + \acro_alt:n {#1} + } + +% long: +\NewAcroCommand \acl + { \acro_long:n {#1} } + +\NewAcroCommand \Acl + { + \acro_first_upper: + \acro_long:n {#1} + } + +\NewAcroCommand \iacl + { + \acro_indefinite: + \acro_long:n {#1} + } + +\NewAcroCommand \Iacl + { + \acro_first_upper: + \acro_indefinite: + \acro_long:n {#1} + } + +\NewAcroCommand \aclp + { + \acro_plural: + \acro_long:n {#1} + } + +\NewAcroCommand \Aclp + { + \acro_plural: + \acro_first_upper: + \acro_long:n {#1} + } + +% first: +\NewAcroCommand \acf + { \acro_first:n {#1} } + +\NewAcroCommand \Acf + { + \acro_first_upper: + \acro_first:n {#1} + } + +\NewAcroCommand \iacf + { + \acro_indefinite: + \acro_first:n {#1} + } + +\NewAcroCommand \Iacf + { + \acro_first_upper: + \acro_indefinite: + \acro_first:n {#1} + } + +\NewAcroCommand \acfp + { + \acro_plural: + \acro_first:n {#1} + } + +\NewAcroCommand \Acfp + { + \acro_plural: + \acro_first_upper: + \acro_first:n {#1} + } + +% first-like: +\NewPseudoAcroCommand \acflike + { \acro_first_like:nn {#1} {#2} } + +\NewPseudoAcroCommand \iacflike + { + \acro_indefinite: + \acro_first_like:nn {#1} {#2} + } + +\NewPseudoAcroCommand \Iacflike + { + \acro_first_upper: + \acro_indefinite: + \acro_first_like:nn {#1} {#2} + } + +\NewPseudoAcroCommand \acfplike + { + \acro_plural: + \acro_first_like:nn {#1} {#2} + } + +% -------------------------------------------------------------------------- +% first appearance styles: +\DeclareAcroFirstStyle {default} {inline} + { } + +\DeclareAcroFirstStyle {reversed} {inline} + { reversed = true } + +\DeclareAcroFirstStyle {short} {inline} + { + only-short = true , + brackets = false + } + +\DeclareAcroFirstStyle {long} {inline} + { + only-long = true , + brackets = false + } + +\DeclareAcroFirstStyle {square} {inline} + { brackets-type = [] } + +\DeclareAcroFirstStyle {plain} {inline} + { + brackets = false , + between = -- + } + +\DeclareAcroFirstStyle {plain-reversed} {inline} + { + brackets = false , + between = -- , + reversed = true + } + +\DeclareAcroFirstStyle {footnote} {note} + { } + +\DeclareAcroFirstStyle {footnote-reversed} {note} + { reversed = true } + +\DeclareAcroFirstStyle {sidenote} {note} + { note-command = \sidenote {#1} } + +\DeclareAcroFirstStyle {sidenote-reversed} {note} + { + note-command = \sidenote {#1} , + reversed = true + } + +\DeclareAcroFirstStyle {empty} {note} + { use-note = false } + +% -------------------------------------------------------------------------- +% extra info appearance styles: +\DeclareAcroExtraStyle {default} {inline} + { + brackets = false , + punct = true , + punct-symbol = . + } + +\DeclareAcroExtraStyle {plain} {inline} + { + brackets = false , + punct = true , + punct-symbol = + } + +\DeclareAcroExtraStyle {paren} {inline} + { + brackets = true , + punct = true , + punct-symbol = + } + +\DeclareAcroExtraStyle {bracket} {inline} + { + brackets = true , + punct = true , + punct-symbol = , + brackets-type = [] + } + +\DeclareAcroExtraStyle {comma} {inline} + { + punct = true, + punct-symbol = {,} , + brackets = false + } + +% -------------------------------------------------------------------------- +% page number appearance styles: +\DeclareAcroPageStyle {default} {inline} + { + punct = true , + punct-symbol = . + } + +\DeclareAcroPageStyle {plain} {inline} + { punct = false } + +\DeclareAcroPageStyle {comma} {inline} + { punct = true } + +\DeclareAcroPageStyle {paren} {inline} + { + brackets=true , + punct-symbol = ~ + } + +\DeclareAcroPageStyle {none} {inline} + { display = false } + +% -------------------------------------------------------------------------- +% list heading styles: +\DeclareAcroListHeading {part} {\part} +\DeclareAcroListHeading {part*} {\part*} +\DeclareAcroListHeading {chapter} {\chapter} +\DeclareAcroListHeading {chapter*} {\chapter*} +\DeclareAcroListHeading {addchap} {\addchap} +\DeclareAcroListHeading {section} {\section} +\DeclareAcroListHeading {section*} {\section*} +\DeclareAcroListHeading {addsec} {\addsec} +\DeclareAcroListHeading {subsection} {\subsection} +\DeclareAcroListHeading {subsection*} {\subsection*} +\DeclareAcroListHeading {subsubsection} {\subsubsection} +\DeclareAcroListHeading {subsubsection*} {\subsubsection*} +\DeclareAcroListHeading {none} {\use_none:n} + +% -------------------------------------------------------------------------- +% list styles: +\DeclareAcroListStyle {description} {list} + { } + +\DeclareAcroListStyle {toc} {list-of} + { } + +\DeclareAcroListStyle {lof} {list-of} + { style = lof } + +\DeclareAcroListStyle {tabular} {table} + { table = tabular } + +\DeclareAcroListStyle {longtable} {table} + { table = longtable } + +\DeclareAcroListStyle {extra-tabular} {extra-table} + { table = tabular } + +\DeclareAcroListStyle {extra-longtable} {extra-table} + { table = longtable } + +\DeclareAcroListStyle {extra-tabular-rev} {extra-table} + { + table = tabular , + reverse = true + } + +\DeclareAcroListStyle {extra-longtable-rev} {extra-table} + { + table = longtable , + reverse = true + } + +% -------------------------------------------------------------------------- +% register some tokens to be checked for: +\AcroRegisterTrailing . {dot} +\AcroRegisterTrailing - {dash} +\AcroRegisterTrailing \babelhyphen {babel-hyphen} + +\acsetup { activate-trailing-tokens = dot } + +% some user macros: +\cs_new_protected:Npn \acro_dot: + { \acro_if_trailing_tokens:nF {dot} {.\@} } + +\cs_new_protected:Npn \acro_space: + { \acro_if_trailing_tokens:nF {dash,babel-hyphen} { \c_space_tl } } + +% -------------------------------------------------------------------------- +% translations: +% list name +\DeclareAcroTranslation {acronym-list-name} + { + Fallback = Acronyms , + English = Acronyms , + French = Acronymes , + German = Abk\"urzungen , + Italian = Acronimi , + Portuguese = Acr\'onimos , + Spanish = Siglas , + Catalan = Sigles , + Turkish = K\i saltmalar + } + +% page name +\DeclareAcroTranslation {acronym-page-name} + { + Fallback = p. , + English = p. , + German = S. , + Portuguese = p. + } + +% pages name +\DeclareAcroTranslation {acronym-pages-name} + { + Fallback = pp. , + English = pp. , + German = S. , + Portuguese = pp. + } + +% following page +\DeclareAcroTranslation {acronym-next-page} + { + Fallback = f. , + English = f. , + German = f. , + Portuguese = s. + } + +% following pages +\DeclareAcroTranslation {acronym-next-pages} + { + Fallback = ff. , + English = ff. , + German = ff. , + Portuguese = ss. + } + +% -------------------------------------------------------------------------- +\file_input_stop: |