% -------------------------------------------------------------------------- % the ACRO package % % Typeset Acronyms % % -------------------------------------------------------------------------- % Clemens Niederberger % Web: https://bitbucket.org/cgnieder/acro/ % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- % Copyright 2011-2015 Clemens Niederberger % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Clemens Niederberger. % -------------------------------------------------------------------------- % The acro package consists of the files % - acro.sty, acro0.def, acro1.def, acro_en.tex, acro_en.pdf, README % -------------------------------------------------------------------------- % If you have any ideas, questions, suggestions or bugs to report, please % feel free to contact me. % -------------------------------------------------------------------------- \RequirePackage{expl3,l3sort,xparse,l3keys2e,xtemplate} \ProvidesExplPackage {acro} {2015/04/08} {1.6a} {Typeset Acronyms} % -------------------------------------------------------------------------- % check expl3 version: \@ifpackagelater { expl3 } { 2012/11/21 } { } { \PackageError {acro} { Support~package~expl3~too~old } { You~need~to~update~your~installation~of~the~bundles~'l3kernel'~and~ 'l3packages'.\MessageBreak Loading~acro~will~abort! } \tex_endinput:D } % -------------------------------------------------------------------------- % warning and error messages: \msg_new:nnn {acro} {undefined} { You've~requested~acronym~`#1'~\msg_line_context: \c_space_tl but~you~ apparently~haven't~defined~it,~yet!~Maybe~you've~misspelled~it? } \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: \c_space_tl is~deprecated~and~has~ been~replaced~by~`#3'.~Since~I~will~not~guarantee~that~#1~will~be~kept~ forever~I~encourage~you~to~switch. } \msg_new:nnn {acro} {deprecated} { The~#1~`#2'~you~used~\msg_line_context: \c_space_tl is~deprecated~and~there~ is~no~replacement.~Since~I~will~not~guarantee~that~#1~will~be~kept~forever~ I~encourage~you~to~remove~it~from~your~document. } % message macros: \bool_new:N \l__acro_silence_bool \cs_new_protected:Npn \acro_serious_message:nn { \bool_if:NTF \l__acro_silence_bool { \msg_warning:nn } { \msg_error:nn } } \cs_new_protected:Npn \acro_serious_message:nnn { \bool_if:NTF \l__acro_silence_bool { \msg_warning:nnn } { \msg_error:nnn } } \cs_new_protected:Npn \acro_serious_message:nnnn { \bool_if:NTF \l__acro_silence_bool { \msg_warning:nnnn } { \msg_error:nnnn } } \cs_new_protected:Npn \acro_harmless_message:nnn { \bool_if:NTF \l__acro_silence_bool { \msg_info:nnn } { \msg_warning:nnn } } \cs_new_protected:Npn \acro_harmless_message:nnnn { \bool_if:NTF \l__acro_silence_bool { \msg_info:nnnn } { \msg_warning:nnnn } } \cs_new_protected:Npn \acro_harmless_message:nnnnn { \bool_if:NTF \l__acro_silence_bool { \msg_info:nnnnn } { \msg_warning:nnnnn } } \cs_new_protected:Npn \acro_option_deprecated:nn #1#2 { \tl_if_blank:nTF {#2} { \acro_harmless_message:nnnn {acro} {deprecated} {option} {#1 } } { \acro_harmless_message:nnnnn {acro} {replaced} {option} {#1} {#2} } } \cs_new_protected:Npn \acro_command_deprecated:NN #1#2 { \tl_if_blank:nTF {#2} { \acro_harmless_message:nnnnn {acro} {deprecated} {command} { \token_to_str:N #1 } } { \acro_harmless_message:nnnnn {acro} {replaced} {command} { \token_to_str:N #1 } { \token_to_str:N #2 } } } % -------------------------------------------------------------------------- % temporary variables \tl_new:N \l__acro_tmpa_tl \tl_new:N \l__acro_tmpb_tl \tl_new:N \l__acro_tmpc_tl \prop_new:N \l__acro_tmpa_prop \prop_new:N \l__acro_tmpb_prop \seq_new:N \l__acro_tmpa_seq \seq_new:N \l__acro_tmpb_seq \int_new:N \l__acro_tmpa_int \int_new:N \l__acro_tmpb_int \int_new:N \l__acro_tmpc_int \int_new:N \l__acro_tmpd_int % -------------------------------------------------------------------------- % variants of kernel commands \cs_generate_variant:Nn \quark_if_no_value:nTF { V } \cs_generate_variant:Nn \tl_put_right:Nn { NV } \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 } % -------------------------------------------------------------------------- % boolean variables: \bool_new:N \l__acro_mark_as_used_bool \bool_new:N \g__acro_mark_first_as_used_bool \bool_new:N \l__acro_use_single_bool \bool_new:N \l__acro_print_only_used_bool \bool_set_true:N \l__acro_print_only_used_bool \bool_new:N \l__acro_use_plural_bool \bool_new:N \l__acro_hyperref_loaded_bool \bool_new:N \l__acro_use_hyperref_bool \bool_new:N \l__acro_custom_format_bool \bool_new:N \l__acro_strict_bool \bool_new:N \l__acro_create_macros_bool \bool_new:N \l__acro_xspace_bool \bool_new:N \l__acro_first_upper_bool \bool_new:N \l__acro_indefinite_bool \bool_new:N \l__acro_upper_indefinite_bool \bool_new:N \l__acro_foreign_bool \bool_set_true:N \l__acro_foreign_bool \bool_new:N \l__acro_sort_bool \bool_set_true:N \l__acro_sort_bool \bool_new:N \l__acro_capitalize_list_bool \bool_new:N \l__acro_citation_all_bool \bool_new:N \l__acro_citation_first_bool \bool_set_true:N \l__acro_citation_first_bool \bool_new:N \l__acro_acc_supp_bool \bool_new:N \l__acro_following_page_bool \bool_new:N \l__acro_following_pages_bool \bool_new:N \l__acro_record_pages_bool \bool_set_true:N \l__acro_record_pages_bool \bool_new:N \l__acro_addto_index_bool \bool_new:N \l__acro_is_excluded_bool \bool_new:N \l__acro_page_punct_bool \bool_new:N \l__acro_page_brackets_bool \bool_new:N \l__acro_page_display_bool \bool_new:N \l__acro_new_page_numbering_bool \bool_new:N \l__acro_first_use_brackets_bool \bool_new:N \l__acro_first_only_short_bool \bool_new:N \l__acro_first_reversed_bool \bool_new:N \l__acro_use_note_bool \bool_new:N \l__acro_extra_punct_bool \bool_new:N \l__acro_extra_use_brackets_bool \bool_new:N \l__acro_in_list_bool \bool_new:N \l__acro_place_label_bool \bool_new:N \l__acro_list_all_pages_bool \bool_set_true:N \l__acro_list_all_pages_bool % -------------------------------------------------------------------------- % token list variables: \tl_new:N \l__acro_ignore_tl \tl_new:N \l__acro_short_format_tl \tl_new:N \l__acro_list_short_format_tl \tl_new:N \l__acro_long_format_tl \tl_new:N \l__acro_first_long_format_tl \tl_new:N \l__acro_list_long_format_tl \tl_new:N \l__acro_default_indefinite_tl \tl_set:Nn \l__acro_default_indefinite_tl { a } \tl_new:N \l__acro_extra_format_tl \tl_new:N \l__acro_foreign_tl \tl_new:N \l__acro_foreign_sep_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_first_instance_tl \tl_set:Nn \l__acro_first_instance_tl { default } \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_set:Nn \l__acro_page_name_tl { p.\@\, } \tl_new:N \l__acro_pages_name_tl \tl_set:Nn \l__acro_pages_name_tl { pp.\@\, } \tl_new:N \l__acro_next_page_tl \tl_set:Nn \l__acro_next_page_tl { \,f.\@ } \tl_new:N \l__acro_next_pages_tl \tl_set:Nn \l__acro_next_pages_tl { \,ff.\@ } \tl_new:N \l__acro_list_instance_tl \tl_set:Nn \l__acro_list_instance_tl { list } \tl_new:N \l__acro_list_type_tl \tl_set:Nn \l__acro_list_type_tl { description } \tl_new:N \l__acro_list_title_tl \tl_set:Nn \l__acro_list_title_tl { section* } \tl_new:N \l__acro_list_name_tl \tl_set:Nn \l__acro_list_name_tl { Acronyms } \tl_new:N \l__acro_short_tl \tl_new:N \l__acro_short_plural_tl \tl_new:N \l__acro_default_plural_tl \tl_set:Nn \l__acro_default_plural_tl { s } \tl_new:N \l__acro_alt_tl \tl_new:N \l__acro_long_tl \tl_new:N \l__acro_long_pre_tl \tl_new:N \l__acro_long_post_tl \tl_new:N \l__acro_custom_format_tl \tl_new:N \l__acro_first_between_tl \tl_new:N \l__acro_citation_space_tl \tl_set:Nn \l__acro_citation_space_tl { \nobreakspace } \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_index_short_tl \tl_new:N \l__acro_index_format_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: } % -------------------------------------------------------------------------- % length variables: \dim_new:N \l__acro_table_width_dim \dim_set:Nn \l__acro_table_width_dim { .7\linewidth } \dim_new:N \l__acro_page_space_dim % -------------------------------------------------------------------------- % small commands for use at various places \cs_new:Npn \acro_no_break: { \tex_penalty:D \c_ten_thousand } \cs_new_protected:Npn \__acro_first_upper_case:n #1 { \tl_mixed_case:n {#1} } \cs_generate_variant:Nn \__acro_first_upper_case:n { x } \cs_generate_variant:Nn \tl_mixed_case:n { x } \cs_new_eq:NN \acro_first_upper_case:n \__acro_first_upper_case:n \NewDocumentCommand \acfirstupper { m } { \acro_first_upper_case:n {#1} } % -------------------------------------------------------------------------- % options: \keys_define:nn {acro} { version .code:n = \acro_option_deprecated:nn { version } { } , 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 , accsupp .bool_set:N = \l__acro_acc_supp_bool , accsupp-options .tl_set:N = \l__acro_acc_supp_options_tl , macros .bool_set:N = \l__acro_create_macros_bool , xspace .bool_set:N = \l__acro_xspace_bool , strict .bool_set:N = \l__acro_strict_bool , sort .bool_set:N = \l__acro_sort_bool , short-format .code:n = \tl_set:Nn \l__acro_short_format_tl {#1} \tl_set:Nn \l__acro_list_short_format_tl {#1} , 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} , first-long-format .code:n = \tl_set:Nn \l__acro_first_long_format_tl {#1} , display-foreign .bool_set:N = \l__acro_foreign_bool , foreign-format .tl_set:N = \l__acro_foreign_format_tl , list-short-format .tl_set:N = \l__acro_list_short_format_tl , list-long-format .tl_set:N = \l__acro_list_long_format_tl , list-foreign-format .tl_set:N = \l__acro_foreign_list_format_tl , extra-format .tl_set:N = \l__acro_extra_format_tl , single .bool_set:N = \l__acro_use_single_bool , first-style .tl_set:N = \l__acro_first_instance_tl , extra-style .tl_set:N = \l__acro_extra_instance_tl , label .bool_set:N = \l__acro_place_label_bool , label-prefix .tl_set:N = \l__acro_label_prefix_tl , 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 , page-ref .tl_set:N = \l__acro_page_instance_tl , page-name .tl_set:N = \l__acro_page_name_tl , pages-name .tl_set:N = \l__acro_pages_name_tl , page-ranges .code:n = \bool_set_false:N \l__acro_following_page_bool \bool_set_false:N \l__acro_following_pages_bool \acro_option_deprecated:nn { pages-ranges } { } , following-page .bool_set:N = \l__acro_following_page_bool , following-pages .bool_set:N = \l__acro_following_pages_bool , record-pages .code:n = \acro_option_deprecated:nn { record-pages } { } , next-page .tl_set:N = \l__acro_next_page_tl , next-pages .tl_set:N = \l__acro_next_pages_tl , list-style .tl_set:N = \l__acro_list_instance_tl , list-type .tl_set:N = \l__acro_list_type_tl , list-header .code:n = \acro_option_deprecated:nn { list-header } { list-heading } \tl_set:Nn \l__acro_list_title_tl {#1} , list-heading .tl_set:N = \l__acro_list_title_tl , list-name .tl_set:N = \l__acro_list_name_tl , list-table-width .dim_set:N = \l__acro_table_width_dim , hyperref .bool_set:N = \l__acro_use_hyperref_bool , only-used .bool_set:N = \l__acro_print_only_used_bool , mark-as-used .choice: , mark-as-used / first .code:n = \bool_gset_true:N \g__acro_mark_first_as_used_bool , mark-as-used / any .code:n = \bool_gset_false:N \g__acro_mark_first_as_used_bool , plural-ending .tl_set:N = \l__acro_default_plural_tl , 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-space .tl_set:N = \l__acro_citation_space_tl , index .bool_set:N = \l__acro_addto_index_bool , index-cmd .code:n = \cs_set:Npn \__acro_index_cmd:n {#1} , uc-cmd .code:n = \cs_set_eq:NN \__acro_first_upper_case:n #1 } \AtBeginDocument { \bool_if:NTF \l__acro_xspace_bool { \@ifpackageloaded {xspace} { } { \RequirePackage {xspace} } \cs_new_eq:NN \acro_xspace: \xspace } { \cs_new:Npn \acro_xspace: {} } \bool_if:NF \l__acro_record_pages_bool { \cs_set_eq:NN \acro_record_page_number:n \use_none:n } } % -------------------------------------------------------------------------- % setup command: \NewDocumentCommand \acsetup { m } { \keys_set:nn {acro} {#1} \ignorespaces } % -------------------------------------------------------------------------- \cs_new_protected:Npn \acro_plural: { \bool_set_true:N \l__acro_use_plural_bool } \cs_new_protected:Npn \acro_upper: { \bool_set_true:N \l__acro_first_upper_bool } % typeset the short form: \cs_new:Npn \__acro_write_short:n #1 { \mode_if_horizontal:F { \leavevmode } \group_begin: \bool_if:NTF \l__acro_custom_format_bool { \l__acro_custom_format_tl } { \l__acro_short_format_tl } { #1 } \group_end: \bool_if:NT \l__acro_use_plural_bool { \tl_use:N \l__acro_short_plural_tl } } \cs_generate_variant:Nn \__acro_write_short:n { V } % typeset the longform,...: % TODO: rethink the formatting mechanism % right now a custom format gets applied additionally to the global one % although before it \cs_new_protected:Npn \__acro_write_long:Nn #1#2 { \mode_if_horizontal:F { \leavevmode } \group_begin: \bool_if:NTF \l__acro_custom_long_format_bool { \l__acro_custom_long_format_tl } { \use:n } { \exp_args:Nx #1 { \bool_if:NTF \l__acro_first_upper_bool { \exp_not:N \__acro_first_upper_case:n { \exp_not:n {#2} } } { \exp_not:n {#2} } } } \group_end: } \cs_generate_variant:Nn \__acro_write_long:Nn { NV,No,Nf } % -------------------------------------------------------------------------- % hyperref support \cs_new_eq:NN \acro_hyper_target:nn \use_ii:nn \cs_new_eq:NN \acro_hyper_link:nn \use_ii:nn \cs_new_protected:Npn \__acro_activate_hyperref_support: { \bool_if:nT { \l__acro_hyperref_loaded_bool && \l__acro_use_hyperref_bool } { \cs_set_eq:NN \acro_hyper_link:nn \hyperlink \cs_set:Npn \acro_hyper_target:nn ##1##2 { \raisebox { 3ex } [ 0pt ] { \hypertarget {##1} { } } ##2 } } } \cs_new_protected:Npn \__acro_make_link:nNN #1#2#3 { \bool_if:nTF { \l__acro_use_hyperref_bool && \l__acro_hyperref_loaded_bool } { \tl_set:Nn #2 { \acro_hyper_link:nn {#1} { \phantom {#3} } \__acro_is_single:nTF {#1} { \hbox_overlap_left:n {#3} } { \acro_color_link:n { \hbox_overlap_left:n {#3} } } } } { \tl_set:Nn #2 {#3} } } \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 \cs_new:Npn \__acro_note_command:n #1 {#1} % #1: id % #2: short % #3: long \DeclareObjectType { acro-first } { 3 } % template for inline appearance: \DeclareTemplateInterface { acro-first } { inline } { 3 } { brackets : boolean = true , brackets-type : tokenlist = () , only-short : boolean = false , reversed : boolean = false , between : tokenlist , foreign-sep : tokenlist = { , ~ } } \DeclareTemplateCode { acro-first } { inline } { 3 } { brackets = \l__acro_first_use_brackets_bool , brackets-type = \l__acro_first_brackets_tl , only-short = \l__acro_first_only_short_bool , reversed = \l__acro_first_reversed_bool , between = \l__acro_first_between_tl , foreign-sep = \l__acro_foreign_sep_tl } { \AssignTemplateKeys \bool_if:nT { !\l__acro_first_only_short_bool && !\l__acro_first_reversed_bool } { \__acro_indefinite:nn {#1} { long } \__acro_write_long:No \l__acro_first_long_format_tl {#3} \tl_use:N \c_space_tl \tl_if_blank:VF \l__acro_first_between_tl { \tl_use:N \l__acro_first_between_tl \tl_use:N \c_space_tl } } \bool_if:nT { \l__acro_first_use_brackets_bool && !\l__acro_first_reversed_bool } { \tl_head:N \l__acro_first_brackets_tl } \bool_if:nT { \l__acro_foreign_bool && !\l__acro_first_reversed_bool && !\l__acro_first_only_short_bool } { \prop_get:NnNT \l__acro_foreign_prop {#1} \l__acro_foreign_tl { \group_begin: \tl_use:N \l__acro_foreign_format_tl \tl_use:N \l__acro_foreign_tl \group_end: \tl_use:N \l__acro_foreign_sep_tl } } \bool_if:nT { \l__acro_first_reversed_bool || \l__acro_first_only_short_bool } { \__acro_indefinite:nn {#1} { short } } \__acro_acc_supp:nn {#1} { \__acro_write_short:n {#2} } \bool_if:nT { \l__acro_first_use_brackets_bool && !\l__acro_first_reversed_bool } { \tl_tail:N \l__acro_first_brackets_tl } \bool_if:nT { !\l__acro_first_only_short_bool && \l__acro_first_reversed_bool } { \tl_if_blank:VF \l__acro_first_between_tl { \tl_use:N \c_space_tl \tl_use:N \l__acro_first_between_tl } \tl_use:N \c_space_tl \bool_if:nT { \l__acro_first_use_brackets_bool && \l__acro_first_reversed_bool } { \tl_head:N \l__acro_first_brackets_tl } \__acro_write_long:No \l__acro_first_long_format_tl {#3} \bool_if:nT { \l__acro_foreign_bool && \l__acro_first_reversed_bool } { \prop_get:NnNT \l__acro_foreign_prop {#1} \l__acro_foreign_tl { \tl_use:N \l__acro_foreign_sep_tl \group_begin: \tl_use:N \l__acro_foreign_format_tl \tl_use:N \l__acro_foreign_tl \group_end: } } \bool_if:nT { \l__acro_first_use_brackets_bool && \l__acro_first_reversed_bool } { \tl_tail:N \l__acro_first_brackets_tl } } \__acro_cite_if:Nn \l__acro_citation_first_bool {#1} \__acro_index_if:Nn \l__acro_addto_index_bool {#1} } % template for footnotes, sidenotes, ... \DeclareTemplateInterface { acro-first } { note } { 3 } { use-note : boolean = true , note-command : function 1 = \footnote {#1} , foreign-sep : tokenlist = ~ } \DeclareTemplateCode { acro-first } { note } { 3 } { use-note = \l__acro_use_note_bool , note-command = \__acro_note_command:n , foreign-sep = \l__acro_foreign_sep_tl } { \AssignTemplateKeys \__acro_indefinite:nn {#1} { short } \__acro_acc_supp:nn {#1} { \__acro_write_short:n {#2} } \bool_if:NT \l__acro_use_note_bool { \__acro_note_command:n { \__acro_write_long:No \l__acro_first_long_format_tl {#3} \bool_if:NT \l__acro_foreign_bool { \prop_get:NnNT \l__acro_foreign_prop {#1} \l__acro_foreign_tl { \tl_use:N \l__acro_foreign_sep_tl ( \group_begin: \tl_use:N \l__acro_foreign_format_tl \tl_use:N \l__acro_foreign_tl \group_end: ) } } \__acro_cite_if:Nn \l__acro_citation_first_bool {#1} \__acro_index_if:Nn \l__acro_addto_index_bool {#1} } } } % the different styles: \DeclareInstance { acro-first } { default } { inline } { } \DeclareInstance { acro-first } { square } { inline } { brackets-type = [] } \DeclareInstance { acro-first } { plain } { inline } { brackets = false , between = -- } \DeclareInstance { acro-first } { plain-reversed } { inline } { brackets = false , between = -- , reversed = true } \DeclareInstance { acro-first } { footnote } { note } { } \DeclareInstance { acro-first } { sidenote } { note } { note-command = \sidenote {#1} } \DeclareInstance { acro-first } { empty } { note } { use-note = false } \DeclareInstance { acro-first } { short } { inline } { only-short = true , brackets = false } \DeclareInstance { acro-first } { reversed } { inline } { reversed = true } % -------------------------------------------------------------------------- % formatting the extras information: \DeclareObjectType { acro-extra } { 1 } \DeclareTemplateInterface { acro-extra } { default } { 1 } { punct : boolean = false , punct-symbol : tokenlist = {,} , brackets : boolean = true , brackets-type : tokenlist = () } \DeclareTemplateCode { acro-extra } { default } { 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:Nn \l__acro_extra_format_tl {#1} \bool_if:NT \l__acro_extra_use_brackets_bool { \tl_tail:N \l__acro_extra_brackets_tl } } % the different styles: \DeclareInstance { acro-extra } { default } { default } { brackets = false , punct = true , punct-symbol = . } \DeclareInstance { acro-extra } { plain } { default } { brackets = false , punct = false } \DeclareInstance { acro-extra } { paren } { default } { punct = true , punct-symbol = } \DeclareInstance { acro-extra } { bracket } { default } { punct = true , punct-symbol = , brackets-type=[] } \DeclareInstance { acro-extra } { comma } { default } { punct = true, brackets = false } % -------------------------------------------------------------------------- % 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 } { % have the numbers changed? \tl_set:Nx \l__acro_tmpa_tl { \seq_use:cnnn { 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 } { \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 } { \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 } } \seq_clear:N \l__acro_tmpa_seq \seq_clear:N \l__acro_tmpb_seq } \cs_new:Npn \acro_determine_page_ranges:NNn #1#2#3 { \seq_remove_duplicates:N #1 % current page: \int_set:Nn \l__acro_tmpa_int { \acro_get_abspage:nnn #3 } \int_set:Nn \l__acro_tmpb_int { \acro_get_page_number:nnn #3 } % last page: \seq_get_right:NN #1 \l__acro_last_page_tl \int_set:Nn \l__acro_tmpc_int { \acro_get_abspage_from:N \l__acro_last_page_tl } \int_set:Nn \l__acro_tmpd_int { \acro_get_page_number_from:N \l__acro_last_page_tl } \bool_if:nTF { \int_compare_p:nNn { \l__acro_tmpa_int - \l__acro_tmpc_int } = { \l__acro_tmpb_int - \l__acro_tmpd_int } && \int_compare_p:nNn { \l__acro_tmpb_int - \l__acro_tmpd_int } = {1} } {% same kind of page numbering, one page ahead % => possible range \seq_put_right:Nn #1 {#3} } {% any possible range ended \tl_put_right:Nn #2 { \acro_page_range_comma: } \int_compare:nNnTF { \seq_count:N #1 } > {2} {% real range \seq_get_left:NN #1 \l__acro_tmpa_tl \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } \bool_if:NTF \l__acro_following_pages_bool { \tl_put_right:Nn #2 { \l__acro_next_pages_tl } } { \tl_put_right:Nn #2 { -- } \seq_get_right:NN #1 \l__acro_tmpa_tl \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } } } { \int_compare:nNnTF { \seq_count:N #1 } = {2} {% range of two pages \seq_get_left:NN #1 \l__acro_tmpa_tl \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } \bool_if:NTF \l__acro_following_page_bool { \tl_put_right:Nn #2 { \l__acro_next_page_tl } } { \tl_put_right:Nn #2 { ,~ } \seq_get_right:NN #1 \l__acro_tmpa_tl \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } } } {% no range at all \seq_get_right:NN #1 \l__acro_tmpa_tl \tl_put_right:Nx #2 { \acro_get_thepage_from:N \l__acro_tmpa_tl } } } \seq_clear:N #1 \seq_put_right:Nn #1 {#3} } } \cs_generate_variant:Nn \acro_determine_page_ranges:NNn { NNV } % -------------------------------------------------------------------------- \DeclareObjectType { acro-page-number } { 1 } \DeclareTemplateInterface { acro-page-number } { default } { 1 } { display : boolean = true , punct : boolean = false , punct-symbol : tokenlist = {,} , brackets : boolean = false , brackets-type : tokenlist = () , space : length = .3ex } \DeclareTemplateCode { acro-page-number } { default } { 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_dim } { \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 \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 } } } % the different styles: \DeclareInstance { acro-page-number } { default } { default } { punct = true , punct-symbol = . } \DeclareInstance { acro-page-number } { plain } { default } { punct = false } \DeclareInstance { acro-page-number } { comma } { default } { punct = true } \DeclareInstance { acro-page-number } { paren } { default } { brackets=true , punct-symbol = ~ } \DeclareInstance { acro-page-number } { none } { default } { display = false } % -------------------------------------------------------------------------- % 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} } % the different styles: \DeclareInstance { acro-title } { chapter* } { sectioning } { name-format = \chapter* {#1} } \DeclareInstance { acro-title } { part* } { sectioning } { name-format = \part* {#1} } \DeclareInstance { acro-title } { section* } { sectioning } { name-format = \section* {#1} } \DeclareInstance { acro-title } { subsection* } { sectioning } { name-format = \subsection* {#1} } \DeclareInstance { acro-title } { chapter } { sectioning } { name-format = \chapter {#1} } \DeclareInstance { acro-title } { part } { sectioning } { name-format = \part {#1} } \DeclareInstance { acro-title } { section } { sectioning } { name-format = \section {#1} } \DeclareInstance { acro-title } { subsection } { sectioning } { name-format = \subsection {#1} } \DeclareInstance { acro-title } { addchap } { sectioning } { name-format = \addchap {#1} } \DeclareInstance { acro-title } { addsec } { sectioning } { name-format = \addsec {#1} } \DeclareInstance { acro-title } { none } { sectioning } { name-format = \use_none:n {#1} } % -------------------------------------------------------------------------- % outputting the whole list \DeclareObjectType { acro-list } { 3 } % #1: id % #2: excluded classes % #3: continue if not excluded \cs_new_protected:Npn \acro_is_excluded:nnF #1#2#3 { \bool_set_false:N \l__acro_is_excluded_bool \tl_if_empty:nTF {#2} {#3} { \clist_map_inline:nn {#2} { \prop_get:NnNF \l__acro_class_prop {#1} \l__acro_tmpa_tl {} \tl_if_eq:VnT \l__acro_tmpa_tl {##1} { \bool_set_true:N \l__acro_is_excluded_bool } } \bool_if:NF \l__acro_is_excluded_bool {#3} } } % build the list, dummy functions to be redefined in the template code: \cs_new:Npn \acro_print_list_short:nn #1#2 { } \cs_new:Npn \acro_print_list_long:n #1 { } \cs_new:Npn \acro_print_list_extra:n #1 { } \cs_new:Npn \acro_print_list_page:n #1 { } \cs_new:Npn \acroenparen #1 { ( #1 ) } \cs_new_protected:Npn \acro_get_foreign:n #1 { \prop_get:NnNT \l__acro_foreign_prop {#1} \l__acro_foreign_tl { \tl_use:N \l__acro_foreign_sep_tl \group_begin: \tl_use:N \l__acro_foreign_list_format_tl { \tl_use:N \l__acro_foreign_tl } \group_end: } } % Test, if acronyms should be printed or not; needs testing for in/excluded % classes and options `only-used' and `single': \cs_new_protected:Npn \acro_list_allow_items:nn #1#2 { \prop_map_inline:Nn \l__acro_short_prop { \acro_get:n {##1} \bool_if:nT { \bool_if_p:c { g__acro_##1_in_list_bool } && ( ( \l__acro_use_single_bool && \cs_if_exist_p:c { acro@##1@twice } ) || ( !\l__acro_use_single_bool && \cs_if_exist_p:c { acro@##1@once } && \l__acro_print_only_used_bool ) ) || ( !\l__acro_use_single_bool && !\l__acro_print_only_used_bool ) } { \acro_is_excluded:nnF {##1} {#2} { \tl_if_blank:nTF {#1} { \acro_print_list_short:nn {##1} {##2} \bool_if:NT \l__acro_capitalize_list_bool { \bool_set_true:N \l__acro_first_upper_bool } \acro_print_list_long:n {##1} \bool_set_false:N \l__acro_first_upper_bool \bool_if:NT \l__acro_foreign_bool { \acro_get_foreign:n {##1} } \acro_print_list_extra:n {##1} \acro_print_list_page:n {##1} } { \clist_map_inline:nn {#1} { \prop_get:NnNT \l__acro_class_prop {##1} \l__acro_tmpa_tl { \tl_set:Nn \l__acro_tmpb_tl { ####1 } \tl_trim_spaces:N \l__acro_tmpa_tl \tl_trim_spaces:N \l__acro_tmpb_tl \tl_if_eq:NNT \l__acro_tmpa_tl \l__acro_tmpb_tl { \acro_print_list_short:nn {##1} { ##2 } \bool_if:NT \l__acro_capitalize_list_bool { \bool_set_true:N \l__acro_first_upper_bool } \acro_print_list_long:n {##1} \bool_set_false:N \l__acro_first_upper_bool \bool_if:NT \l__acro_foreign_bool { \acro_get_foreign:n {##1} } \acro_print_list_extra:n {##1} \acro_print_list_page:n {##1} } } } } } } } } % list template: \DeclareTemplateInterface {acro-list} {list} {3} { foreign-sep : tokenlist = { ~ } } \DeclareTemplateCode {acro-list} {list} {3} { foreign-sep = \l__acro_foreign_sep_tl } { \AssignTemplateKeys \bool_set_true:N \l__acro_in_list_bool \__acro_activate_hyperref_support: \cs_set:Npn \acro_print_list_short:nn ##1##2 { \item [ \acro_hyper_target:nn {##1} { \__acro_acc_supp:nn {##1} { \__acro_write_short:n { \l__acro_list_short_format_tl { ##2 } } } } ] } \cs_set:Npn \acro_print_list_long:n ##1 { \__acro_write_long:Nf \l__acro_list_long_format_tl { \prop_if_in:NnTF \l__acro_list_prop {##1} { \prop_get:Nn \l__acro_list_prop {##1} } { \prop_get:Nn \l__acro_long_prop {##1} } } \__acro_cite_if:Nn \l__acro_citation_all_bool {##1} } \cs_set_protected:Npn \acro_print_list_extra:n ##1 { \prop_get:NnNT \l__acro_extra_prop {##1} \l__acro_tmpa_tl { \UseInstance { acro-extra } { \l__acro_extra_instance_tl } { \l__acro_tmpa_tl } } } \cs_set:Npn \acro_print_list_page:n ##1 { \bool_if:nT { \cs_if_exist_p:c { acro@##1@once } } { \UseInstance { acro-page-number } { \l__acro_page_instance_tl } {##1} } } \begin {#1} \acro_list_allow_items:nn {#2} {#3} \end {#1} } % table template: \DeclareTemplateInterface {acro-list} {table} {3} { table : tokenlist = longtable , table-spec : tokenlist = lp{\l__acro_table_width_dim} , foreign-sep : tokenlist = { ~ } } \DeclareTemplateCode { acro-list } { table } { 3 } { table = \l__acro_list_table_tl , table-spec = \l__acro_list_table_spec_tl , foreign-sep = \l__acro_foreign_sep_tl } { \AssignTemplateKeys \__acro_activate_hyperref_support: \cs_set:Npn \acro_print_list_short:nn ##1##2 { \acro_hyper_target:nn {##1} { \__acro_acc_supp:nn {##1} { \__acro_write_short:n { \l__acro_list_short_format_tl { ##2 } } } } & } \cs_set:Npn \acro_print_list_long:n ##1 { \__acro_write_long:Nf \l__acro_list_long_format_tl { \prop_if_in:NnTF \l__acro_list_prop {##1} { \prop_get:Nn \l__acro_list_prop {##1} } { \prop_get:Nn \l__acro_long_prop {##1} } } \__acro_cite_if:Nn \l__acro_citation_all_bool {##1} } \cs_set_protected:Npn \acro_print_list_extra:n ##1 { \prop_get:NnNT \l__acro_extra_prop {##1} \l__acro_tmpa_tl { \UseInstance { acro-extra } { \l__acro_extra_instance_tl } { \l__acro_tmpa_tl } } } \cs_set:Npn \acro_print_list_page:n ##1 { \bool_if:nT { \cs_if_exist_p:c { acro@##1@once } } { \UseInstance { acro-page-number } { \l__acro_page_instance_tl } {##1} } \tabularnewline } \exp_args:Noo \begin { \l__acro_list_table_tl } { \l__acro_list_table_spec_tl } \acro_list_allow_items:nn {#2} {#3} \exp_args:No \end { \l__acro_list_table_tl } } % extra-table template: \DeclareTemplateInterface { acro-list } { extra-table } { 3 } { table : tokenlist = longtable , table-spec : tokenlist = lp{\l__acro_table_width_dim}ll } \DeclareTemplateCode { acro-list } { extra-table } { 3 } { table = \l__acro_list_table_tl , table-spec = \l__acro_list_table_spec_tl } { \AssignTemplateKeys \__acro_activate_hyperref_support: \cs_set:Npn \acro_print_list_short:nn ##1##2 { \acro_hyper_target:nn {##1} { \__acro_acc_supp:nn {##1} { \__acro_write_short:n { \l__acro_list_short_format_tl { ##2 } } } } & } \cs_set:Npn \acro_print_list_long:n ##1 { \__acro_write_long:Nf \l__acro_list_long_format_tl { \prop_if_in:NnTF \l__acro_list_prop {##1} { \prop_get:Nn \l__acro_list_prop {##1} } { \prop_get:Nn \l__acro_long_prop {##1} } } \__acro_cite_if:Nn \l__acro_citation_all_bool {##1} & } \cs_set_protected:Npn \acro_print_list_extra:n ##1 { \prop_get:NnNT \l__acro_extra_prop {##1} \l__acro_tmpa_tl { \UseInstance { acro-extra } { \l__acro_extra_instance_tl } { \l__acro_tmpa_tl } } & } \cs_set:Npn \acro_print_list_page:n ##1 { \bool_if:nT { \cs_if_exist_p:c { acro@##1@once } } { \UseInstance { acro-page-number } { \l__acro_page_instance_tl } {##1} } \tabularnewline } \exp_args:Noo \begin { \l__acro_list_table_tl } { \l__acro_list_table_spec_tl } \acro_list_allow_items:nn {#2} {#3} \exp_args:No \end { \l__acro_list_table_tl } } % extra-table-rev template: \DeclareTemplateInterface { acro-list } { extra-table-rev } { 3 } { table : tokenlist = longtable , table-spec : tokenlist = llp{\l__acro_table_width_dim}l } \DeclareTemplateCode { acro-list } { extra-table-rev } { 3 } { table = \l__acro_list_table_tl , table-spec = \l__acro_list_table_spec_tl } { \AssignTemplateKeys \__acro_activate_hyperref_support: \cs_set:Npn \acro_print_list_short:nn ##1##2 { \acro_hyper_target:nn {##1} { \__acro_acc_supp:nn {##1} { \__acro_write_short:n { ##2 } } } & } \cs_set_protected:Npn \acro_print_list_extra:n ##1 { \bool_if:NT \l__acro_capitalize_list_bool { \bool_set_true:N \l__acro_first_upper_bool } \__acro_write_long:Nf \l__acro_long_format_tl { \prop_if_in:NnTF \l__acro_list_prop {##1} { \prop_get:Nn \l__acro_list_prop {##1} } { \prop_get:Nn \l__acro_long_prop {##1} } } \__acro_cite_if:Nn \l__acro_citation_all_bool {##1} & } \cs_set_protected:Npn \acro_print_list_long:n ##1 { \prop_get:NnNT \l__acro_extra_prop {##1} \l__acro_tmpa_tl { \UseInstance { acro-extra } { \l__acro_extra_instance_tl } { \l__acro_tmpa_tl } } & } \cs_set:Npn \acro_print_list_page:n ##1 { \bool_if:nT { \cs_if_exist_p:c { acro@##1@once } } { \UseInstance { acro-page-number } { \l__acro_page_instance_tl } {##1} } \tabularnewline } \exp_args:Noo \begin { \l__acro_list_table_tl } { \l__acro_list_table_spec_tl } \acro_list_allow_items:nn {#2} {#3} \exp_args:No \end { \l__acro_list_table_tl } } % the different styles: \DeclareInstance {acro-list} {list} { list } { } \DeclareInstance { acro-list } { tabular } { table } { table = tabular } \DeclareInstance { acro-list } { longtable } { table } { table = longtable } \DeclareInstance { acro-list } { extra-longtable } { extra-table } { table = longtable } \DeclareInstance { acro-list } { extra-tabular } { extra-table } { table = tabular } \DeclareInstance { acro-list } { extra-longtable-rev } { extra-table-rev } { table = longtable } \DeclareInstance { acro-list } { extra-tabular-rev } { extra-table-rev } { table = tabular } % -------------------------------------------------------------------------- % automatic typesetting, the internals of \ac: % #1: id \cs_new_protected:Npn \acro_use:n #1 { % get the acronym and the plural settings: \acro_get:n {#1} \acro_is_used:nTF {#1} { % this is not the first time \__acro_indefinite:nn {#1} {short} \__acro_acc_supp:nn {#1} { \__acro_write_short:V \l__acro_short_tl } \acro_after:n {#1} } { % this is the first time \bool_gset_true:c { g__acro_#1_first_use_bool } \__acro_is_single:nTF {#1} { \__acro_indefinite:nn {#1} {long} \__acro_write_long:NV \l__acro_long_format_tl \l__acro_long_tl } { \UseInstance {acro-first} { \l__acro_first_instance_tl } {#1} { \l__acro_short_tl } { \l__acro_long_tl } } } } \prg_new_conditional:Npnn \__acro_is_single:n #1 { p,T,TF } { \bool_if:nTF { !\l__acro_use_single_bool || \cs_if_exist_p:c { acro@#1@twice } } { \prg_return_false: } { \prg_return_true: } } \cs_new_protected:Npn \acro_use_acronym:n #1 { \use:c {bool_set_#1:N} \l__acro_mark_as_used_bool } % -------------------------------------------------------------------------- % some helpers we'll need more often: \cs_new_protected:Npn \acro_defined:n #1 { \prop_if_in:NnF \l__acro_short_prop {#1} { \acro_serious_message:nnn {acro} {undefined} {#1} } } \cs_new_protected:Npn \acro_get:n #1 { \bool_if:NF \l__acro_in_list_bool { \leavevmode } % \acro_defined:n {#1} \__acro_activate_hyperref_support: \prop_get:NnNF \l__acro_short_prop {#1} \l__acro_tmpa_tl {} \__acro_make_link:nNN {#1} \l__acro_short_tl \l__acro_tmpa_tl \prop_get:NnNF \l__acro_short_plural_prop {#1} \l__acro_short_plural_tl {} \prop_get:NnNF \l__acro_long_prop {#1} \l__acro_long_tl {} \prop_get:NnNTF \l__acro_long_format_prop {#1} \l__acro_custom_long_format_tl { \bool_set_true:N \l__acro_custom_long_format_bool } { \bool_set_false:N \l__acro_custom_long_format_bool } \prop_get:NnNF \l__acro_first_long_format_prop {#1} \l__acro_first_long_format_tl {}% to avoid hanging compilation if first-long-format hasn't been set \prop_get:NnNT \l__acro_long_pre_prop {#1} \l__acro_long_pre_tl { \tl_put_left:NV \l__acro_long_tl \l__acro_long_pre_tl } \prop_get:NnNF \l__acro_alt_prop {#1} \l__acro_tmpb_tl {} \__acro_make_link:nNN {#1} \l__acro_alt_tl \l__acro_tmpb_tl \prop_get:NnNTF \l__acro_format_prop {#1} \l__acro_custom_format_tl { \bool_set_true:N \l__acro_custom_format_bool } { \bool_set_false:N \l__acro_custom_format_bool } \__acro_set_plural:n {#1} \prop_get:NnNT \l__acro_long_post_prop {#1} \l__acro_long_post_tl { \tl_put_right:NV \l__acro_long_tl \l__acro_long_post_tl } } \cs_new_protected:Npn \__acro_set_plural:n #1 { \bool_if:NT \l__acro_use_plural_bool { \bool_if:nTF { \prop_get:Nn \l__acro_long_plural_form_prop {#1} } { \prop_get:NnNF \l__acro_long_plural_prop {#1} \l__acro_long_tl {} } { \tl_put_right:Nn \l__acro_long_tl { \prop_get:Nn \l__acro_long_plural_prop {#1} } } } } % -------------------------------------------------------------------------- % 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 { TF } { \bool_if:nTF { \bool_if_p:c { g__acro_#1_used_bool } && ( ( \bool_if_p:c { g__acro_#1_first_use_bool } && \g__acro_mark_first_as_used_bool ) || ! \g__acro_mark_first_as_used_bool ) } { \if@filesw \bool_if:NTF \l__acro_mark_as_used_bool { \iow_shipout_x:Nn \@auxout { \token_to_str:N \acro@used@twice {#1} { \thepage } { \arabic{page} } { \arabic{abspage} } } } { \iow_shipout_x:Nn \@auxout { \token_to_str:N \acro@used@twice {#1} {} {} {} } } \fi \prg_return_true: } { \bool_if:NTF \l__acro_mark_as_used_bool { % \if@filesw \iow_shipout_x:Nn \@auxout { \token_to_str:N \acro@used@once {#1} { \thepage } { \arabic{page} } { \arabic{abspage} } } % \fi \bool_if:nT { !\bool_if_p:c { g__acro_#1_label_bool } && \l__acro_place_label_bool } { \bool_gset_true:c { g__acro_#1_label_bool } \label{\l__acro_label_prefix_tl #1} } \bool_gset_true:c { g__acro_#1_used_bool } } { \if@filesw \iow_shipout_x:Nn \@auxout { \token_to_str:N \acro@used@once {#1} {} {} {} } \fi } \prg_return_false: } } \cs_new:Npn \acro_is_used:n #1 { \acro_is_used:nTF {#1} { } { } } % -------------------------------------------------------------------------- % 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 } { \seq_gput_right:cn { g__acro_#1_pages_seq } { {#2}{#3}{#4} } } } \cs_new_protected:Npn \acro@used@twice #1#2#3#4 { \cs_gset_nopar:cpn { acro@#1@twice } {#1} \tl_if_empty:nF { #2#3#4 } { \seq_gput_right:cn { g__acro_#1_pages_seq } { {#2}{#3}{#4} } } } \cs_new_protected:Npn \acro@pages #1#2 { \tl_gset:cn { g__acro_#1_recorded_pages_tl } {#2} } \bool_new:N \g__acro_rerun_bool \cs_new_protected:Npn \acro@rerun@check { \bool_if:NT \g__acro_rerun_bool { \@latex@warning@no@line {Acronyms~ may~ have~ changed.~ Please~ rerun~ LaTeX} } } \AtEndDocument { \bool_gset_false:N \g__acro_rerun_bool \cs_gset_protected:Npn \acro@used@once #1#2#3#4 { \tl_set:Nn \l__acro_tmpa_tl {#1} \tl_if_eq:cNF { acro@#1@once } \l__acro_tmpa_tl { \bool_gset_true:N \g__acro_rerun_bool } } \cs_gset_protected:Npn \acro@used@twice #1#2#3#4 { \tl_set:Nn \l__acro_tmpa_tl {#1} \tl_if_eq:cNF { acro@#1@twice } \l__acro_tmpa_tl { \bool_gset_true:N \g__acro_rerun_bool } } \prop_map_inline:Nn \l__acro_short_prop { \seq_if_empty:cF { g__acro_#1_pages_seq } { \if@filesw \iow_shipout_x:Nn \@auxout { \token_to_str:N \acro@pages {#1} { \seq_use:cnnn { g__acro_#1_pages_seq } { | } { | } { | } } } \fi } } \iow_shipout_x:Nn \@auxout { \acro@rerun@check } } % if `acro' is deactivated prevent unnecessary errors from aux file: \if@filesw \AtBeginDocument { \iow_now:Nx \@auxout { \token_to_str:N \providecommand \token_to_str:N \acro@used@once [4] {} ^^J \token_to_str:N \providecommand \token_to_str:N \acro@used@twice [4] {} ^^J \token_to_str:N \providecommand \token_to_str:N \acro@pages [2] {} ^^J \token_to_str:N \providecommand \token_to_str:N \acro@rerun@check {} } } \fi % -------------------------------------------------------------------------- \cs_new: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} } % the standard internals: \cs_new_protected:Npn \acro_short:n #1 { \acro_get:n {#1} \acro_is_used:n {#1} \__acro_indefinite:nn {#1} { short } \__acro_is_single:nT {#1} { \cs_set_eq:NN \acro_hyper_link:nn \use_ii:nn } \__acro_acc_supp:nn {#1} { \__acro_write_short:V \l__acro_short_tl } \acro_after:n {#1} } % get alternative entry: \cs_new_protected:Npn \acro_alt:n #1 { \acro_get:n {#1} \acro_is_used:n {#1} \__acro_indefinite:nn {#1} { alt } \__acro_is_single:nT {#1} { \cs_set_eq:NN \acro_hyper_link:nn \use_ii:nn } \__acro_acc_supp:nn {#1} { \__acro_write_short:V \l__acro_alt_tl } \acro_after:n {#1} } % get long entry: \cs_new_protected:Npn \acro_long:n #1 { \acro_get:n {#1} \acro_is_used:n {#1} \__acro_indefinite:nn {#1} { long } \__acro_is_single:nT {#1} { \cs_set_eq:NN \acro_hyper_link:nn \use_ii:nn } \__acro_write_long:NV \l__acro_long_format_tl \l__acro_long_tl \acro_after:n {#1} } % output like the first time: \cs_new_protected:Npn \acro_first:n #1 { \bool_gset_true:c { g__acro_#1_first_use_bool } \acro_get:n {#1} \acro_is_used:n {#1} \__acro_is_single:nT {#1} { \cs_set_eq:NN \acro_hyper_link:nn \use_ii:nn } \UseInstance { acro-first } { \l__acro_first_instance_tl } {#1} { \l__acro_short_tl } { \l__acro_long_tl } } % output like the first time with own long version: \cs_new_protected:Npn \acro_first_like:nn #1#2 { \bool_gset_true:c { g__acro_#1_first_use_bool } \acro_get:n {#1} \acro_is_used:n {#1} \__acro_is_single:nT {#1} { \cs_set_eq:NN \acro_hyper_link:nn \use_ii:nn } \UseInstance { acro-first } { \l__acro_first_instance_tl } {#1} { \l__acro_short_tl } {#2} } % ---------------------------------------------------------------------------- % citations: \cs_new:Npn \__acro_citation_cmd:w { \cite } %{} \cs_new_protected:Npn \acro_cite: { \bool_set_true:N \l__acro_citation_all_bool } % #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_if:Nn #1#2 { \bool_if:NT #1 { \prop_get:NnNT \l__acro_citation_prop {#2} \l__acro_tmpa_tl { \prop_get:NnN \l__acro_citation_pre_prop {#2} \l__acro_tmpb_tl \prop_get:NnN \l__acro_citation_post_prop {#2} \l__acro_tmpc_tl \acro_no_break: \tl_use:N \l__acro_citation_space_tl \__acro_cite:VVV \l__acro_tmpb_tl \l__acro_tmpc_tl \l__acro_tmpa_tl } } } % ---------------------------------------------------------------------------- % indexing: \cs_new_protected:Npn \__acro_index_if:Nn #1#2 { \bool_if:nT { #1 && \l__acro_mark_as_used_bool } { \prop_get:NnN \l__acro_index_cmd_prop {#2} \l__acro_tmpa_tl \prop_get:NnN \l__acro_index_sort_prop {#2} \l__acro_tmpb_tl \prop_get:NnN \l__acro_index_prop {#2} \l__acro_tmpc_tl \__acro_index:VnVV \l__acro_tmpa_tl {#2} \l__acro_tmpb_tl \l__acro_tmpc_tl } } \cs_new_protected:Npn \acro_index: { \bool_set_true:N \l__acro_addto_index_bool } \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:Npn \acro_acc_supp:nnn #1#2#3 { \BeginAccSupp { ActualText = #1 , #2 } #3 \EndAccSupp { } } \cs_generate_variant:Nn \acro_acc_supp:nnn { VV } \AtBeginDocument { \bool_if:NT \l__acro_acc_supp_bool { \RequirePackage { accsupp } \cs_set_protected:Npn \__acro_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 {} } \bool_if:NT \l__acro_use_plural_bool { \tl_put_right:NV \l__acro_acc_supp_tl \l__acro_short_plural_tl } \acro_acc_supp:VVn \l__acro_acc_supp_tl \l__acro_acc_supp_options_tl {#2} } } } % -------------------------------------------------------------------------- % indefinite articles: \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_true:N \l__acro_indefinite_bool } } \cs_new_protected:Npn \__acro_indefinite:nn #1#2 { \bool_if:NT \l__acro_indefinite_bool { \prop_get:cn { l__acro_#2_indefinite_prop } {#1} ~ } \bool_if:NT \l__acro_upper_indefinite_bool { \__acro_first_upper_case:x { \prop_get: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) \luatex_if_engine:TF { \tl_set:Nn \l__acro_tmpa_tl { acro ~ = ~ acro ~ or ~ { ~ } ~ function ~ acro.strcmp ~ (A, B) ~ if ~ A ~ == ~ B ~ then ~ tex.write ("0") ~ elseif ~ A ~ < ~ B ~ then ~ tex.write ("-1") ~ else ~ tex.write ("1") ~ end ~ end } \luatex_directlua:D { \l__acro_tmpa_tl } \cs_new_protected:Npn \acro_strcmp:nn #1#2 { \luatex_directlua:D { acro.strcmp ( " \__acro_escape_x:n {#1} " , " \__acro_escape_x:n {#2} " ) } } \cs_new:Npn \__acro_escape_x:n #1 { \luatex_luaescapestring:D { \etex_detokenize:D \exp_after:wN { \luatex_expanded:D {#1} } } } } { \cs_new_eq:NN \acro_strcmp:nn \pdftex_strcmp:D } \AtBeginDocument { \bool_if:NT \l__acro_sort_bool { \cs_new_protected:Npn \acro_sort_prop:N #1 { \seq_clear:N \l__acro_tmpa_seq \prop_clear:N \l__acro_tmpa_prop \prop_clear:N \l__acro_tmpb_prop \prop_map_inline:Nn \l__acro_sort_prop { \seq_put_right:Nn \l__acro_tmpa_seq { ##2 } \prop_put:Nnn \l__acro_tmpa_prop { ##2 } {##1} } \seq_sort:Nn \l__acro_tmpa_seq { \tl_to_lowercase:n { \int_compare:nTF { \acro_strcmp:nn {##1} { ##2 } = -1 } { \sort_ordered: } { \sort_reversed: } } } \seq_map_inline:Nn \l__acro_tmpa_seq { % get ID: \prop_get:NnNF \l__acro_tmpa_prop {##1} \l__acro_tmpa_tl {} % get prop entry of ID in #1: \prop_get:NVNT #1 \l__acro_tmpa_tl \l__acro_tmpb_tl { \prop_put:NVV \l__acro_tmpb_prop \l__acro_tmpa_tl \l__acro_tmpb_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 } } } % -------------------------------------------------------------------------- % the user commands: % #1: ID % #2: true|false \cs_new_protected:Npn \acro_check_acronym:nn #1#2 { \acro_defined:n {#1} \acro_use_acronym:n {#2} } % automatic: \NewDocumentCommand \ac { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_use:n {#2} \group_end: } \NewDocumentCommand \iac { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_indefinite: \acro_use:n {#2} \group_end: } \NewDocumentCommand \Iac { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_upper: \acro_indefinite: \acro_use:n {#2} \group_end: } \NewDocumentCommand \Ac { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_upper: \acro_use:n {#2} \group_end: } \NewDocumentCommand \acp { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_plural: \acro_use:n {#2} \group_end: } \NewDocumentCommand \Acp { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_plural: \acro_upper: \acro_use:n {#2} \group_end: } % short: \NewDocumentCommand \acs { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_short:n {#2} \group_end: } \NewDocumentCommand \iacs { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_indefinite: \acro_short:n {#2} \group_end: } \NewDocumentCommand \Iacs { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_upper: \acro_indefinite: \acro_short:n {#2} \group_end: } \NewDocumentCommand \acsp { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_plural: \acro_short:n {#2} \group_end: } % alt: \NewDocumentCommand \aca { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_alt:n {#2} \group_end: } \NewDocumentCommand \iaca { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_indefinite: \acro_alt:n {#2} \group_end: } \NewDocumentCommand \Iaca { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_upper: \acro_indefinite: \acro_alt:n {#2} \group_end: } \NewDocumentCommand \acap { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_plural: \acro_alt:n {#2} \group_end: } % long: \NewDocumentCommand \acl { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_long:n {#2} \group_end: } \NewDocumentCommand \iacl { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_indefinite: \acro_long:n {#2} \group_end: } \NewDocumentCommand \Iacl { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_upper: \acro_indefinite: \acro_long:n {#2} \group_end: } \NewDocumentCommand \Acl { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_upper: \acro_long:n {#2} \group_end: } \NewDocumentCommand \aclp { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_plural: \acro_long:n {#2} \group_end: } \NewDocumentCommand \Aclp { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_plural: \acro_upper: \acro_long:n {#2} \group_end: } % first: \NewDocumentCommand \acf { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_first:n {#2} \group_end: } \NewDocumentCommand \iacf { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_indefinite: \acro_first:n {#2} \group_end: } \NewDocumentCommand \Iacf { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_upper: \acro_indefinite: \acro_first:n {#2} \group_end: } \NewDocumentCommand \Acf { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_upper: \acro_first:n {#2} \group_end: } \NewDocumentCommand \acfp { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_plural: \acro_first:n {#2} \group_end: } \NewDocumentCommand \Acfp { sm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_plural: \acro_upper: \acro_first:n {#2} \group_end: } % first-like: \NewDocumentCommand \acflike { smm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_first_like:nn {#2} {#3} \group_end: } \NewDocumentCommand \iacflike { smm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_indefinite: \acro_first_like:nn {#2} {#3} \group_end: } \NewDocumentCommand \Iacflike { smm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_upper: \acro_indefinite: \acro_first_like:nn {#2} {#3} \group_end: } \NewDocumentCommand \acfplike { smm } { \group_begin: \IfBooleanTF #1 { \acro_check_acronym:nn {#2} {false} } { \acro_check_acronym:nn {#2} {true} } \acro_plural: \acro_first_like:nn {#2} {#3} \group_end: } % 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 \iow_shipout_x:Nn \@auxout { \token_to_str:N \acro@used@once {#1} {} {} {} } \iow_shipout_x:Nn \@auxout { \token_to_str:N \acro@used@twice {#1} {} {} {} } \fi } \cs_new_protected:Npn \acro_reset_all: { \prop_map_inline:Nn \l__acro_short_prop { \acro_reset:n {##1} } } \cs_new_protected:Npn \acro_mark_all_as_used: { \prop_map_inline:Nn \l__acro_short_prop { \acro_mark_as_used:n {##1} } } \DeclareExpandableDocumentCommand \acifused { m } { \acro_if_acronym_used:nTF {#1} } \prg_new_conditional:Npnn \acro_if_acronym_used:n #1 { TF } { \bool_if:nTF { \bool_if_p:c { g__acro_#1_used_bool } && ( !\__acro_is_single_p:n {#1} ) } { \prg_return_true: } { \prg_return_false: } } \NewDocumentCommand \acresetall {} { \acro_reset_all: } \NewDocumentCommand \acuseall {} { \acro_mark_all_as_used: } \NewDocumentCommand \acreset { > { \SplitList { , } } m } { \ProcessList {#1} { \acro_reset:n } \ignorespaces } \NewDocumentCommand \acuse { > { \SplitList { , } } m } { \ProcessList {#1} { \acro_mark_as_used:n } \ignorespaces } % --------------------------------------------------------------------------- % process options: \ProcessKeysOptions {acro} % --------------------------------------------------------------------------- % PDF bookmark support \cs_new:Npn \acpdfstring { \acro_pdf_string:n } \cs_new:Npn \acpdfstringplural { \acro_pdf_string_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_pdf_string:n #1 { \acro_if_star_gobble:nTF {#1} { \prop_get:Nn \l__acro_pdfstring_prop } { \prop_get:Nn \l__acro_pdfstring_prop {#1} } } \cs_new:Npn \acro_pdf_string_plural:n #1 { \acro_if_star_gobble:nTF {#1} { \prop_get:Nn \l__acro_pdfstring_plural_prop } { \prop_get:Nn \l__acro_pdfstring_plural_prop {#1} } } \AtBeginDocument { \@ifpackageloaded { hyperref } { \bool_set_true:N \l__acro_hyperref_loaded_bool \pdfstringdefDisableCommands { \cs_set_eq:NN \ac \acpdfstring \cs_set_eq:NN \Ac \acpdfstring \cs_set_eq:NN \acs \acpdfstring \cs_set_eq:NN \acl \acpdfstring \cs_set_eq:NN \Acl \acpdfstring \cs_set_eq:NN \acf \acpdfstring \cs_set_eq:NN \Acf \acpdfstring \cs_set_eq:NN \aca \acpdfstring \cs_set_eq:NN \acp \acpdfstringplural \cs_set_eq:NN \Acp \acpdfstringplural \cs_set_eq:NN \acsp \acpdfstringplural \cs_set_eq:NN \aclp \acpdfstringplural \cs_set_eq:NN \Aclp \acpdfstringplural \cs_set_eq:NN \acfp \acpdfstringplural \cs_set_eq:NN \Acfp \acpdfstringplural \cs_set_eq:NN \acap \acpdfstringplural } \cs_set_protected:Npn \acro_hyper_page:n #1 { \hyperpage {#1} } } {} } % -------------------------------------------------------------------------- % additional variables: \tl_new:N \l__acro_current_key_tl % -------------------------------------------------------------------------- % key and order checking \msg_new:nnn {acro} {no-id} { Something~has~gone~wrong,~you've~probably~forgotten~to~set~the~acronym~ID. } \msg_new:nnn {acro} {before-short} { You've~set~The~key~`#2'~before~the~`short'~key~for~acronym~`#1'~but~ needs~to~be~set~after~it. } \msg_new:nnn {acro} {missing} { The~`#2'~key~for~acronym~`#1'~is~missing. } \msg_new:nnn {acro} {doubled-key} { It~seems~to~me~you~have~used~the~`#1'~key~before.~If~you~haven't~there's~ something~different~wrong~and~I'm~lost.~You~'re~on~your~own~now. } \cs_new_protected:Npn \__acro_key_check:nn #1#2 { \tl_if_blank:VT \l__acro_current_key_tl { \acro_serious_message:nn {acro} {no-id} } \bool_if:cF { l__acro_#1_short_set_bool } { \acro_serious_message:nnnn {acro} {before-short} {#1} {#2} } \bool_new:c { l__acro_#1_#2_set_bool } \bool_set_true:c { l__acro_#1_#2_set_bool } } \cs_new_protected:Npn \__acro_first_key_check:n #1 { \cs_if_exist:cTF { l__acro_#1_short_set_bool } { \bool_if:cT { l__acro_#1_short_set_bool } { \acro_serious_message:nnn {acro} {doubled-key} {#1} } } { \bool_new:c { l__acro_#1_short_set_bool } \bool_set_true:c { l__acro_#1_short_set_bool } } } % -------------------------------------------------------------------------- % the internal key selection functions for \DeclareAcronym: % #1: name in associated cs % #2: key name % #3: action \cs_new_protected:Npn \acro_declare_key_generic:nnn #1#2#3 { \prop_new:c { l__acro_#1_prop } \cs_new_protected:cpn { __acro_declare_#1:nn } ##1##2 { #3 } \cs_generate_variant:cn { __acro_declare_#1:nn } { V } \keys_define:nn { acro / declare-acronym } { #2 .code:n = \use:c {__acro_declare_#1:Vn} \l__acro_current_key_tl {##1} } } \cs_generate_variant:Nn \cs_generate_variant:Nn {c} % #1: name in associated cs % #2: key name % #3: action \cs_new_protected:Npn \acro_declare_key:nnn #1#2#3 { \acro_declare_key_generic:nnn {#1} {#2} { \__acro_key_check:nn {##1} {#2} \prop_put:cnn { l__acro_#1_prop } {##1} {##2} #3 } } % #1: name in associated cs % #2: key name \cs_new_protected:Npn \acro_declare_key:nn #1#2 { \acro_declare_key:nnn {#1} {#2} {} } \cs_generate_variant:Nn \acro_declare_key:nn { V } \cs_new_protected:Npn \acro_declare_simple_key:n #1 { \tl_set:Nn \l__acro_tmpa_tl {#1} \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_} \acro_declare_key:Vn \l__acro_tmpa_tl {#1} } % #1: new alias key % #2: old key \cs_new_protected:Npn \acro_declare_key_alias:nn #1#2 { \keys_define:nn { acro / declare-acronym } { #1 .meta:n = { #2 = {##1} } } } % -------------------------------------------------------------------------- % declare the keys for \DeclareAcronym: % short: \acro_declare_key_generic:nnn {short} {short} { \__acro_first_key_check:n {#1} \prop_put:Nnn \l__acro_short_prop {#1} {#2} \prop_put:Nnn \l__acro_sort_prop {#1} {#1} \prop_put:Nnn \l__acro_index_sort_prop {#1} {#1} \prop_put:Nnn \l__acro_alt_prop {#1} {#2} \prop_put:Nnx \l__acro_pdfstring_prop {#1} { \exp_not:n {#2} } \prop_put:Nnn \l__acro_short_plural_prop {#1} { \l__acro_default_plural_tl } \prop_put:Nnx \l__acro_short_indefinite_prop {#1} { \l__acro_default_indefinite_tl } \prop_put:Nnx \l__acro_alt_indefinite_prop {#1} { \l__acro_default_indefinite_tl } \prop_put:Nnx \l__acro_pdfstring_plural_prop {#1} { \exp_not:n {#2} \exp_not:V \l__acro_default_plural_tl } } % short plural: \acro_declare_simple_key:n {short-plural} % long: \acro_declare_key:nnn {long} {long} { \prop_put:Nnn \l__acro_long_plural_form_prop {#1} { \c_false_bool } \prop_put:Nnx \l__acro_long_indefinite_prop {#1} { \l__acro_default_indefinite_tl } \bool_if:cF { l__acro_#1_long-plural_set_bool } { \prop_put:Nnn \l__acro_long_plural_prop {#1} { \l__acro_default_plural_tl } } } % list: \acro_declare_simple_key:n {list} % long plural: \acro_declare_key:nnn {long_plural} {long-plural} { \prop_put:Nnn \l__acro_long_plural_form_prop {#1} { \c_false_bool } } % long plural form: \acro_declare_key_generic:nnn {long_plural_form} {long-plural-form} { \__acro_key_check:nn {#1} { long-plural-form } \prop_put:Nnn \l__acro_long_plural_form_prop {#1} { \c_true_bool } \prop_put:Nnn \l__acro_long_plural_prop {#1} {#2} } % short indefinite article: \acro_declare_simple_key:n {short-indefinite} % long indefinite article: \acro_declare_simple_key:n {long-indefinite} % pre long: \acro_declare_simple_key:n {long-pre} % post long: \acro_declare_simple_key:n {long-post} % sort: \acro_declare_key:nnn {sort} {sort} { \bool_if:cF { l__acro_#1_index-sort_set_bool } { \prop_put:Nnn \l__acro_index_sort_prop {#1} {#2} } } % alternative: \acro_declare_key:nnn {alt} {alt} { \prop_put:Nnx \l__acro_alt_indefinite_prop {#1} { \l__acro_default_indefinite_tl } } % alt. indefinite article: \acro_declare_simple_key:n {alt-indefinite} % foreign: \acro_declare_simple_key:n {foreign} % format: \acro_declare_simple_key:n {format} % short format: \acro_declare_key_alias:nn {short-format} {format} % long format: \acro_declare_simple_key:n {long-format} % first long format: \acro_declare_simple_key:n {first-long-format} % pdfstring: \prop_new:N \l__acro_pdfstring_prop \prop_new:N \l__acro_pdfstring_plural_prop \cs_new_protected:Npn \__acro_declare_pdfstring:nw #1#2/#3/#4 \acro_stop: { \__acro_key_check:nn {#1} { pdfstring } \prop_put:Nnx \l__acro_pdfstring_prop {#1} {#2} \tl_if_empty:nTF { #3 } { \prop_put:Nnx \l__acro_pdfstring_plural_prop {#1} { \exp_not:n {#2} \exp_not:V \l__acro_default_plural_tl } } { \prop_put:Nnx \l__acro_pdfstring_plural_prop {#1} { \exp_not:n { #2#3 } } } } \cs_generate_variant:Nn \__acro_declare_pdfstring:nw { V } \keys_define:nn { acro / declare-acronym } { pdfstring .code:n = \__acro_declare_pdfstring:Vw \l__acro_current_key_tl #1 // \acro_stop: , } % class: \acro_declare_simple_key:n {class} % extra information: \acro_declare_simple_key:n {extra} % acc supp: \acro_declare_key:nn {acc_supp} {accsupp} % citation: \prop_new:N \l__acro_citation_prop \prop_new:N \l__acro_citation_pre_prop \prop_new:N \l__acro_citation_post_prop \cs_new_protected:Npn \__acro_declare_citation:nw #1#2[#3]#4[#5]#6#7 \acro_stop: { % no options: #1: ID, #2: key, #3 is blank % 1 option: #1: ID, #4: key, #3: option, #5 is blank % 2 options: #1: ID: #6: key, #3: first option, #5: second option \tl_if_blank:nF { #2#4#6 } { \tl_if_empty:nTF { #3 } { \__acro_declare_citation_aux:nnnn {#1} { } { } {#2} } { \tl_if_empty:nTF { #5 } { \__acro_declare_citation_aux:nnnn {#1} { #3 } { } { #4 } } { \__acro_declare_citation_aux:nnnn {#1} { #3 } { #5 } { #6 } } } } } \cs_generate_variant:Nn \__acro_declare_citation:nw { V } \keys_define:nn { acro / declare-acronym } { cite .code:n = \__acro_declare_citation:Vw \l__acro_current_key_tl #1 [][] \scan_stop: \acro_stop: } \cs_new_protected:Npn \__acro_declare_citation_aux:nnnn #1#2#3#4 { \__acro_key_check:nn {#1} { cite } \prop_put:Nnn \l__acro_citation_prop {#1} { #4 } \tl_if_empty:nF {#2} { \prop_put:Nnn \l__acro_citation_pre_prop {#1} {#2} } \tl_if_empty:nF { #3 } { \prop_put:Nnn \l__acro_citation_post_prop {#1} { #3 } } } % TODO: % add index entries, by default \index{@} % index: overwrite default @ entry completely % index-sort: overwrite the part of @ entry % need to take care of custom index cmd, at least % - \index{} % - \index[]{} % question is, though, if it should be the same one for all acronyms? % I go for yes but would also add a `post' key that allows to add arbitrary % TeX code after an acronym is typeset % index: \acro_declare_simple_key:n {index} % index-sort: \acro_declare_simple_key:n {index-sort} % index-cmd: \acro_declare_simple_key: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:nnn {acro} {macro} {#1} } } { \cs_new:cpn {#1} { \ac {#1} \acro_xspace: } } } } % -------------------------------------------------------------------------- % internal acronym declaring function: \cs_new_protected:Npn \acro_declare_acronym:nn #1#2 { \tl_set:Nn \l__acro_current_key_tl {#1} \keys_set:nn { acro / declare-acronym } {#2} \bool_new:c { g__acro_#1_first_use_bool } \bool_new:c { g__acro_#1_used_bool } \bool_new:c { g__acro_#1_label_bool } \bool_new:c { g__acro_#1_in_list_bool } \bool_if:NF \l__acro_print_only_used_bool { \bool_gset_true:c { g__acro_#1_in_list_bool } } \acro_create_page_records:n {#1} \acro_define_acronym_macro:n {#1} \tl_clear:N \l__acro_current_key_tl \bool_if:cF { l__acro_#1_short_set_bool } { \acro_serious_message:nnnn {acro} {missing} {#1} {short} } \bool_if:cF { l__acro_#1_long_set_bool } { \acro_serious_message:nnnn {acro} {missing} {#1} {long} } } % -------------------------------------------------------------------------- % the user command: \NewDocumentCommand \DeclareAcronym { mm } { \acro_declare_acronym:nn {#1} {#2} } % -------------------------------------------------------------------------- % print the list: % #1: list of classes % #2: list of excluded classes \tl_new:N \l__acro_included_classes_tl \tl_new:N \l__acro_excluded_classes_tl \cs_new_protected:Npn \acro_use_list_instance:nn #1#2 { \UseInstance { acro-list } { \l__acro_list_instance_tl } { \l__acro_list_type_tl } {#1} {#2} } \cs_generate_variant:Nn \acro_use_list_instance:nn { VV } \keys_define:nn { acro / print-acronyms } { include-classes .tl_set:N = \l__acro_included_classes_tl , exclude-classes .tl_set:N = \l__acro_excluded_classes_tl , name .tl_set:N = \l__acro_list_name_tl , header .code:n = \acro_option_deprecated:nn { header } { heading } \tl_set:Nn \l__acro_list_title_tl {#1} , heading .tl_set:N = \l__acro_list_title_tl , sort .bool_set:N = \l__acro_sort_bool } \cs_new_protected:Npn \acro_print_acronyms:n #1 { \group_begin: % this is a cheap trick to prevent the \@noitemerr % if one forgot to delete either the aux file or % remove \printacronyms -- but it's local: \cs_set:Npn \@noitemerr {} \tl_clear:N \l__acro_included_classes_tl \tl_clear:N \l__acro_excluded_classes_tl \keys_set:nn { acro / print-acronyms } {#1} \iow_now:Nx \@auxout { \string \acro@print@list } \bool_if:NT \l__acro_sort_bool { \acro_sort_prop:N \l__acro_short_prop } \UseInstance { acro-title } { \l__acro_list_title_tl } { \l__acro_list_name_tl } \cs_if_exist:NTF \acro@printed@list { \acro_use_list_instance:VV \l__acro_included_classes_tl \l__acro_excluded_classes_tl } { \@latex@warning@no@line {Rerun~to~get~acronym~list~right} } \group_end: } \NewDocumentCommand \printacronyms { O{} } { \acro_print_acronyms:n {#1} } % -------------------------------------------------------------------------- % language support \RequirePackage { translations } % Listenname \DeclareTranslationFallback { acronym-list-name } { Acronyms } \DeclareTranslation { English } { acronym-list-name } { Acronyms } \DeclareTranslation { American } { acronym-list-name } { Acronyms } \DeclareTranslation { British } { acronym-list-name } { Acronyms } \DeclareTranslation { French } { acronym-list-name } { Acronymes } \DeclareTranslation { German } { acronym-list-name } { Abk\"urzungen } \DeclareTranslation { Italian } { acronym-list-name } { Acronimi } \DeclareTranslation { Portuguese } { acronym-list-name } { Acr\'onimos } \DeclareTranslation { Spanish } { acronym-list-name } { Siglas } \DeclareTranslation { Catalan } { acronym-list-name } { Sigles } \DeclareTranslation { Turkish } { acronym-list-name } { K\i saltmalar } \tl_set:Nn \l__acro_list_name_tl { \GetTranslation { acronym-list-name } } % Seitenname \DeclareTranslationFallback { acronym-page-name } { p. } \DeclareTranslation { English } { acronym-page-name } { p. } \DeclareTranslation { German } { acronym-page-name } { S. } \DeclareTranslation { Portuguese } { acronym-page-name } { p. } \tl_set:Nn \l__acro_page_name_tl { \GetTranslation { acronym-page-name }\@\, } % Seitenname - Plural \DeclareTranslationFallback { acronym-pages-name } { pp. } \DeclareTranslation { English } { acronym-pages-name } { pp. } \DeclareTranslation { German } { acronym-pages-name } { S. } \DeclareTranslation { Portuguese } { acronym-pages-name } { pp. } \tl_set:Nn \l__acro_pages_name_tl { \GetTranslation { acronym-pages-name }\@\, } % einzelne folgende Seite \DeclareTranslationFallback { acronym-next-page } { f. } \DeclareTranslation { English } { acronym-next-page } { f. } \DeclareTranslation { German } { acronym-next-page } { f. } \DeclareTranslation { Portuguese } { acronym-next-page } { s. } \tl_set:Nn \l__acro_next_page_tl { \,\GetTranslation {acronym-next-page }\@ } % mehrere folgende Seiten \DeclareTranslationFallback { acronym-next-pages } { ff. } \DeclareTranslation { English } { acronym-next-pages } { ff. } \DeclareTranslation { German } { acronym-next-pages } { ff. } \DeclareTranslation { Portuguese } { acronym-next-pages } { ss. } \tl_set:Nn \l__acro_next_pages_tl { \,\GetTranslation {acronym-next-pages }\@ } \tex_endinput:D % -------------------------------------------------------------------------- % HISTORY: 2012/06/22 v0.1 - first public release 2012/06/23 v0.1a - bug fix, added `strict' and `macros' option and creation of shortcut macros - added capitalized version of long forms - added `sort' option 2012/06/24 v0.1b - added \Acf and \Acfp, added option `plural-ending' 2012/06/24 v0.1c - added excluded argument to \printacronyms 2012/06/24 v0.2 - renamed \NewAcronym => \DeclareAcronym \AcronymFormat => \DeclareAcronymFormat 2012/06/25 v0.2a - new first-style's: `short' and `reversed' 2012/06/25 v0.3 - new list formats: extra-tabular, extra-longtable, extra-tabular-rev, extra-longtable-rev - extra precaution when using \printacronyms to avoid errors. 2012/06/27 v0.3a - new option `list-caps', \Acp added 2012/06/29 v0.3b - extended the `text' template to the `acro-first' object - added `acro-first' instances `plain' and `plain-reversed' 2012/07/16 v0.3c - small adjustments to the documentation 2012/07/23 v0.3d - first CTAN version 2012/07/24 v0.3e - adapted to updated l3kernel 2012/09/28 v0.4 - added means to add citations to acronyms 2012/10/07 v0.4a - new options: "uc-cmd", "list-long-format" - preliminary language support, needs package `translations' 2012/11/30 v0.5 - added starred variants of the commands that won't mark an acronym as used - added \acreset{} - added preliminary support for pdf strings: in pdf strings always the singular lowercase short version is inserted (the equivalent of \acs) 2012/12/14 v0.6 - bug with not-colored links resolved - bug introduced with the last update (full expansion of the short entry) resolved - option `xspace' added 2013/01/02 v0.6a - \acuseall 2013/01/16 v1.0 - new syntax of \DeclareAcronym - new option `version' - new `accsupp' acronym property - new `sort' acronym property - new syntax of \printacronyms - new default: `sort=true' - new options `page-ranges', `next-page', `next-pages', `pages-name', `record-pages' - no automatic label placement for page number referencing any more 2013/01/26 v1.1 - bug fix in the plural detection - new keys `long-pre' and `long-post' - new keys `index', `index-sort' and `index-cmd' - new options `index' and `index-cmd' 2013/01/29 v1.1a - added `long-format' key - renamed `format' key into `short-format', kept `format' for compatibility reasons 2013/02/09 v1.2 - error message instead of hanging when an undefined acronym is used - added `first-long-format' key and `first-long-format' option - added \acflike and \acfplike - improvements and bug fixes to the page recording mechanism - new option `mark-as-used' - new keys: `short-indefinite', `alt-indefinite' and `long-indefinite' - new commands: \iac, \Iac, \iacs, \Iacs, \iaca, \Iaca, \iacl, \Iacl, \iacf, \Iacf, \iacflike and \Iacflike 2013/04/04 v1.2a - added Portuguese translations 2013/05/06 v1.3 - protected internal commands where appropriate - new option `sort' to \printacronyms - renamed options `print-acronyms/header' and `list-header' into `print-acronyms/heading' and `list-heading' - fix: added missing group to \printacronyms - add key `foreign' - rewritten page-recording: * most importantly: record them at shipout; this is done when \acro@used@once or \acro@used@twice are written to the aux file * no restrictions regarding \pagenumbering * options `page-ranges' and `record-pages' are deprecated * new options `following-page' and `following-pages' - disable \@noitemerr in the list of acronyms: we don't need it there but there are occasions when it is annoying - cleaned the sty file, added a few more comments 2013/05/09 v1.3a - Bug fix: corrected wrong argument checking in \Ac, thanks to Michel Voßkuhle 2013/05/30 v1.3b - obey \if@filesw 2013/06/16 v1.3c - added \leavevmode to \acro_get:n 2013/07/08 v1.3d - corrected wrong call of \leavevmode in the list (list-type=list) 2013/08/07 v1.3e - bug fix in the list when testing for used acronyms - new commands \acifused, \acfirstupper 2013/08/27 v1.4 - new property `list' 2013/09/02 v1.4a - bug fix: used acronyms are added to the list when the list is printed before the use - \DeclareAcronym may now be used after \begin{document} 2013/09/24 v1.4b - bug fix: only-used=false works again for only declared but unused acronyms (only if option single is not used) 2013/11/04 v1.4c - remove \hbox from the written short form - changed \__acro_make_link:nNN in a way that it doesn't box its when links are deactivated 2013/11/22 v1.4d - require `l3sort' independently from the `sort' option instead of at begin document in order to avoid conflicts with `babel' and `french' 2013/12/18 v1.5 - new option `label=true|false' that places \label{:} the first time an acronym is used - new option `pages=first|all' that determines if in the list of acronyms all appearances are listed or only the first time; implicitly sets `label=true' 2015/02/26 v1.6 - new `acro-title' instance `none' - change of expl3's tl uppercasing function (adapt to updates of l3kernel and friends - new package option `messages=silent|loud' - fix issue https://bitbucket.org/cgnieder/acro/issue/23/ - fix issue https://bitbucket.org/cgnieder/acro/issue/24/ - fix issue https://bitbucket.org/cgnieder/acro/issue/28/ - drop support for version 0 2015/04/08 v1.6a - more generalized user command definitions, see http://tex.stackexchange.com/q/236362/ for an application % -------------------------------------------------------------------------- % TODO: - extend option `macros' to also define uppercase macros, possibly as a choice - https://bitbucket.org/cgnieder/acro/issue/18 - options user1, user2, user3? (Genitiv lang, Akkusativ lang,...) Bsp: ``des Bundesinstituts für Risikobewertung'' - Option `totoc'!? - revise list styles to allow _full_ customization by creating own instances! this probably needs a handfull of macros that give access to the entries without worrying about internals - add \ACF, \ACFP, \ACL and \ACLP that will print all words of the long form capitalized