% -------------------------------------------------------------------------- % the ACRO package % % Typeset Acronyms % % -------------------------------------------------------------------------- % Clemens Niederberger % Web: https://bitbucket.org/cgnieder/acro/ % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- % Copyright 2011-2012 Clemens Niederberger % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Clemens Niederberger. % -------------------------------------------------------------------------- % The acro package consists of the files % - acro.sty, acro_en.tex, acro_en.pdf, README % -------------------------------------------------------------------------- % If you have any ideas, questions, suggestions or bugs to report, please % feel free to contact me. % -------------------------------------------------------------------------- \RequirePackage{expl3,xparse,l3keys2e,xtemplate} \ProvidesExplPackage {acro} {2012/09/29} {0.4} {Typeset Acronyms} % error messages: \msg_new:nnnn { acro } { undefined } { You've~requested~acronym~`#1'~but~it~seems~that~it~was~never~defined! } { You've~requested~acronym~`#1'~\msg_line_context: \c_space_tl but~you~ apperantly~haven't~defined~it,~yet!~Maybe~you've~mispelled~it? } % 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 \seq_new:N \l__acro_tmpa_seq % boolean variables: \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_first_upper_bool \bool_new: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 % tokenlist variables: \tl_new:N \l__acro_short_format_tl \tl_new:N \l__acro_long_format_tl \tl_new:N \l__acro_extra_format_tl \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_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_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 } % property list variables: \prop_new:N \l__acro_short_prop \prop_new:N \l__acro_alt_prop \prop_new:N \l__acro_long_prop \prop_new:N \l__acro_class_prop \prop_new:N \l__acro_replace_plural_prop \prop_new:N \l__acro_short_plural_prop \prop_new:N \l__acro_long_plural_prop \prop_new:N \l__acro_extra_prop \prop_new:N \l__acro_format_prop \prop_new:N \l__acro_citation_prop \prop_new:N \l__acro_citation_pre_prop \prop_new:N \l__acro_citation_post_prop % length variables: \dim_new:N \l__acro_table_width_dim \dim_set:Nn \l__acro_table_width_dim { .7\linewidth } \cs_new:Npn \__acro_citation_cmd:w { \cite } \cs_new:Npn \__acro_no_break: { \tex_penalty:D \c_ten_thousand } % options: \keys_define:nn { acro } { macros .bool_set:N = \l__acro_create_macros_bool , strict .bool_set:N = \l__acro_strict_bool , sort .bool_set:N = \l__acro_sort_bool , short-format .tl_set:N = \l__acro_short_format_tl , long-format .tl_set:N = \l__acro_long_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 , page-ref .tl_set:N = \l__acro_page_instance_tl , page-name .tl_set:N = \l__acro_page_name_tl , list-style .tl_set:N = \l__acro_list_instance_tl , list-type .tl_set:N = \l__acro_list_type_tl , list-header .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 , 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-all .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 } % setup command: \NewDocumentCommand \acsetup { m } { \keys_set:nn { acro } { #1 } \ignorespaces } % -------------------------------------------------------------------------- % adding an acronym, internal command: % #1: use/replace plural (boolean) % #2: id % #3: short % #4: short plural % #5: alt % #6: long % #7: long plural % #8: class % #9: extra \cs_new:Npn \acro_new:nnnnnnnnn #1#2#3#4#5#6#7#8#9 { \IfBooleanTF { #1 } { \prop_put:Nnn \l__acro_replace_plural_prop { #2 } { \c_true_bool } } { \prop_put:Nnn \l__acro_replace_plural_prop { #2 } { \c_false_bool } } \prop_put:Nnn \l__acro_short_prop { #2 } { #3 } \IfNoValueTF { #4 } { \prop_put:Nnn \l__acro_short_plural_prop { #2 } { \l__acro_default_plural_tl } } { \prop_put:Nnn \l__acro_short_plural_prop { #2 } { #4 } } \IfNoValueTF { #5 } { \prop_put:Nnn \l__acro_alt_prop { #2 } { #2 } } { \prop_put:Nnn \l__acro_alt_prop { #2 } { #5 } } \prop_put:Nnn \l__acro_long_prop { #2 } { #6 } \IfNoValueTF { #7 } { \prop_put:Nnn \l__acro_long_plural_prop { #2 } { \l__acro_default_plural_tl } } { \prop_put:Nnn \l__acro_long_plural_prop { #2 } { #7 } } \IfNoValueF { #8 } { \prop_put:Nnn \l__acro_class_prop { #2 } { #8} } \IfNoValueF { #9 } { \prop_put:Nnn \l__acro_extra_prop { #2 } { #9 } } \bool_new:c { g_acro_#2_used_bool } \bool_new:c { g_acro_#2_label_bool } \bool_if:NT \l__acro_create_macros_bool { \cs_if_exist:cTF { #2 } { \bool_if:NT \l__acro_strict_bool { \cs_set:cpn { #2 } { \ac { #2 } } } } { \cs_new:cpn { #2 } { \ac { #2 } } } } } % 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 } { \hbox:n { #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,...: \cs_new:Npn \__acro_write_long:Nn #1#2 { \mode_if_horizontal:F { \leavevmode } \group_begin: \tl_use:N #1 \bool_if:NTF \l__acro_first_upper_bool { \tl_to_uppercase:n { \tl_head:n { #2 } } \tl_tail:n { #2 } } { #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: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:Npn \__acro_make_link:nNN #1#2#3 { \tl_set:Nn #2 { \acro_hyper_link:nn { #1 } { \phantom { #3 } } \__acro_is_single:nTF { #1 } { \hbox_overlap_left:n { #3 } } { \bool_if:nTF { \l__acro_use_hyperref_bool && \l__acro_hyperref_loaded_bool } { \textcolor { \@linkcolor } { \hbox_overlap_left:n { #3 } } } { \hbox_overlap_left:n { #3 } } } } } % -------------------------------------------------------------------------- % output style of the first time an acronym is used \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 \tl_new:N \l__acro_first_brackets_tl % #1: id % #2: short % #3: long \DeclareObjectType { acro-first } { 3 } \DeclareTemplateInterface { acro-first } { text } { 3 } { brackets : boolean = true , brackets-type : tokenlist = () , only-short : boolean = false , reversed : boolean = false , between : tokenlist , } \DeclareTemplateCode { acro-first } { text } { 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 , } { \AssignTemplateKeys \bool_if:nT { !\l__acro_first_only_short_bool && !\l__acro_first_reversed_bool } { \__acro_write_long:No \l__acro_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 } \__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_long_format_tl { #3 } \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 } } \DeclareTemplateInterface { acro-first } { footnote } { 3 } { } \DeclareTemplateCode { acro-first } { footnote } { 3 } { } { \AssignTemplateKeys \__acro_write_short:n { #2 } \footnote { \__acro_write_long:No \l__acro_long_format_tl { #3 } \__acro_cite_if:Nn \l__acro_citation_first_bool { #1 } } } % the different styles: \DeclareInstance { acro-first } { default } { text } { } \DeclareInstance { acro-first } { square } { text } { brackets-type = [] } \DeclareInstance { acro-first } { plain } { text } { brackets = false , between = -- } \DeclareInstance { acro-first } { plain-reversed } { text } { brackets = false , between = -- , reversed = true } \DeclareInstance { acro-first } { footnote } { footnote } { } \DeclareInstance { acro-first } { short } { text } { only-short = true , brackets = false } \DeclareInstance { acro-first } { reversed } { text } { reversed = true } % -------------------------------------------------------------------------- % formatting the extras information: \bool_new:N \l__acro_extra_punct_bool \bool_new:N \l__acro_extra_use_brackets_bool \tl_new:N \l__acro_extra_brackets_tl \tl_new:N \l__acro_extra_punct_tl \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 } { } \DeclareInstance { acro-extra } { bracket } { default } { brackets-type=[] } \DeclareInstance { acro-extra } { comma } { default } { punct = true, brackets = false } % -------------------------------------------------------------------------- % outputting the page number: \bool_new:N \l__acro_page_punct_bool \bool_new:N \l__acro_page_display_bool \tl_new:N \l__acro_page_punct_tl \dim_new:N \l__acro_page_space_dim \cs_new:Npn \acro_no_break: { \tex_penalty:D \c_ten_thousand } \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 , name : tokenlist , } \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 , name = \l__acro_page_name_tl , } { \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 } \tl_use:N \l__acro_page_name_tl \acro_no_break: \skip_horizontal:N \l__acro_page_space_dim \acro_no_break: \pageref { ac:#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 } } % -------------------------------------------------------------------------- % outputting the whole list \DeclareObjectType { acro-list } { 3 } % excluded items: \bool_new:N \l__acro_is_excluded_bool \cs_generate_variant:Nn \tl_if_eq:nnT { nV } % #1: id % #2: excluded classes % #3: continue if not excluded \cs_new:Npn \acro_is_excluded:nnF #1#2#3 { \bool_set_false:N \l__acro_is_excluded_bool \IfNoValueTF { #2 } { #3 } { \clist_map_inline:nn { #2 } { \prop_get:NnN \l__acro_class_prop { #1 } \l__acro_tmpa_tl \tl_if_eq:nVT { ##1 } \l__acro_tmpa_tl { \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 { } % Test, if acronyms should be printed or not; needs testing for in/excluded % classes and options `only-used' and `single': \cs_new:Npn \acro_list_allow_items:nn #1#2 { \prop_map_inline:Nn \l__acro_short_prop { \acro_get:n { ##1 } \bool_if:nT { ( \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 \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 \acro_print_list_extra:n { ##1 } \acro_print_list_page:n { ##1 } } } } } } } } } % list template: \DeclareTemplateInterface { acro-list } { list } { 3 } { } \DeclareTemplateCode { acro-list } { list } { 3 } { } { \AssignTemplateKeys \__acro_activate_hyperref_support: \cs_set:Npn \acro_print_list_short:nn ##1##2 { \item [ \acro_hyper_target:nn { ##1 } { \__acro_write_short:n { ##2 } } ] } \cs_set:Npn \acro_print_list_long:n ##1 { \__acro_write_long:Nf \l__acro_long_format_tl { \prop_get:Nn \l__acro_long_prop { ##1 } } \__acro_cite_if:Nn \l__acro_citation_all_bool { ##1 } } \cs_set: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: \tl_new:N \l__acro_list_table_tl \tl_new:N \l__acro_list_table_spec_tl \DeclareTemplateInterface { acro-list } { table } { 3 } { table : tokenlist = longtable , table-spec : tokenlist = lp{\l__acro_table_width_dim} } \DeclareTemplateCode { acro-list } { 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_write_short:n { ##2 } } & } \cs_set:Npn \acro_print_list_long:n ##1 { \__acro_write_long:Nf \l__acro_long_format_tl { \prop_get:Nn \l__acro_long_prop { ##1 } } \__acro_cite_if:Nn \l__acro_citation_all_bool { ##1 } } \cs_set: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_write_short:n { ##2 } } & } \cs_set:Npn \acro_print_list_long:n ##1 { \__acro_write_long:Nf \l__acro_long_format_tl { \prop_get:Nn \l__acro_long_prop { ##1 } } \__acro_cite_if:Nn \l__acro_citation_all_bool { ##1 } & } \cs_set: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_write_short:n { ##2 } } & } \cs_set: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_get:Nn \l__acro_long_prop { ##1 } } \__acro_cite_if:Nn \l__acro_citation_all_bool { ##1 } & } \cs_set: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:Npn \acro_use:n #1 { % get the acronym and the plural settings: \acro_get:n { #1 } \acro_set_plural:n { #1 } \acro_is_used:nTF { #1 } { % this is not the first time \__acro_write_short:V \l__acro_short_tl \__acro_cite_if:Nn \l__acro_citation_all_bool { #1 } } { % this is the first time \__acro_is_single:nTF { #1 } { \__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 } } } } \cs_new:Npn \__acro_is_single:nTF #1#2#3 { \bool_if:nTF { !\l__acro_use_single_bool || \cs_if_exist_p:c { acro@#1@twice } } { #3 } { #2 } } \cs_new:Npn \__acro_is_single:nT #1#2 { \bool_if:nF { !\l__acro_use_single_bool || \cs_if_exist_p:c { acro@#1@twice } } { #2 } } % -------------------------------------------------------------------------- % some helpers we'll need more often: \cs_new:Npn \acro_get:n #1 { \__acro_activate_hyperref_support: \prop_get:NnNF \l__acro_short_prop { #1 } \l__acro_tmpa_tl { \msg_error:nnx { acro } { undefined } { #1 } } \__acro_make_link:nNN { #1 } \l__acro_short_tl \l__acro_tmpa_tl \prop_get:NnN \l__acro_short_plural_prop { #1 } \l__acro_short_plural_tl \prop_get:NnN \l__acro_long_prop { #1 } \l__acro_long_tl \prop_get:NnN \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 } } \cs_generate_variant:Nn \tl_put_right:Nn { NV } \cs_new:Npn \acro_set_plural:n #1 { \bool_if:NT \l__acro_use_plural_bool { \bool_if:nTF { \prop_get:Nn \l__acro_replace_plural_prop { #1 } } { \prop_get:NnN \l__acro_short_plural_prop { #1 } \l__acro_alt_tl \prop_get:NnN \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: \cs_new:Npn \acro_is_used:nTF #1#2#3 { \bool_if:cTF { g_acro_#1_used_bool } { \iow_now:Nx \@auxout { \string \acro@used@twice { #1 } } #2 } { \iow_now:Nx \@auxout { \string \acro@used@once { #1 } } \bool_if:cF { g_acro_#1_label_bool } { \bool_gset_true:c { g_acro_#1_label_bool } \label{ac:#1} } \bool_gset_true:c { g_acro_#1_used_bool } #3 } } \cs_new:Npn \acro_is_used:n #1 { \acro_is_used:nTF { #1 } { } { } } \cs_new:Npn \acro@used@once #1 { \expandafter\xdef\csname acro@#1@once \endcsname { #1 } } \cs_new:Npn \acro@used@twice #1 { \expandafter\xdef\csname acro@#1@twice \endcsname { #1 } } \AtEndDocument { \cs_set:Npn \acro@used@twice #1 { \def\reserved@a{#1}% \expandafter\ifx\csname acro@#1@twice \endcsname\reserved@a\else \@tempswatrue\fi } } % -------------------------------------------------------------------------- % the standard internals: \cs_new:Npn \acro_short:n #1 { \acro_get:n { #1 } \acro_set_plural:n { #1 } \acro_is_used:n { #1 } \__acro_is_single:nT { #1 } { \cs_set_eq:NN \acro_hyper_link:nn \use_ii:nn } \__acro_write_short:V \l__acro_short_tl \__acro_cite_if:Nn \l__acro_citation_all_bool { #1 } } % get alternative entry: \cs_new:Npn \acro_alt:n #1 { \acro_get:n { #1 } \acro_set_plural:n { #1 } \acro_is_used:n { #1 } \__acro_is_single:nT { #1 } { \cs_set_eq:NN \acro_hyper_link:nn \use_ii:nn } \__acro_write_short:V \l__acro_alt_tl \__acro_cite_if:Nn \l__acro_citation_all_bool { #1 } } % get long entry: \cs_new:Npn \acro_long:n #1 { \acro_get:n { #1 } \acro_set_plural:n { #1 } \acro_is_used:n { #1 } \__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_cite_if:Nn \l__acro_citation_all_bool { #1 } } % output like the first time: \cs_new:Npn \acro_first:n #1 { \acro_get:n { #1 } \acro_set_plural: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 } } % set custom format: \cs_new:Npn \acro_format:nn #1#2 { \prop_put:Nnn \l__acro_format_prop { #1 } { #2 } } % add citation: \cs_new:Npn \acro_citation:nnnn #1#2#3#4 { \prop_put:Nnn \l__acro_citation_prop { #1 } { #4 } \IfNoValueF { #2 } { \prop_put:Nnn \l__acro_citation_pre_prop { #1 } { #2 } } \IfNoValueF { #3 } { \prop_put:Nnn \l__acro_citation_post_prop { #1 } { #3 } } } % #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: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 } } } % -------------------------------------------------------------------------- % experimental sorting feature: \AtBeginDocument { \bool_if:NT \l__acro_sort_bool { \RequirePackage { l3sort } \cs_new:Npn \acro_sort_prop:N #1 { \seq_clear:N \l__acro_tmpa_seq \prop_map_inline:Nn #1 { \seq_put_right:Nn \l__acro_tmpa_seq { ##1 } } \seq_sort:Nn \l__acro_tmpa_seq { \tl_to_lowercase:n { \int_compare:nTF { \pdfstrcmp { ##1 } { ##2 } = -1 } { \sort_ordered: } { \sort_reversed: } } } \prop_clear:N \l__acro_tmpa_prop \seq_map_inline:Nn \l__acro_tmpa_seq { \prop_get:NnN #1 { ##1 } \l__acro_tmpa_tl \prop_put:NnV \l__acro_tmpa_prop { ##1 } \l__acro_tmpa_tl } \prop_set_eq:NN #1 \l__acro_tmpa_prop } } } % -------------------------------------------------------------------------- % print the whole list: \cs_new:Npn \acro_print_acronyms:nn #1#2 { \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 { \UseInstance { acro-list } { \l__acro_list_instance_tl } { \l__acro_list_type_tl } { #1 } { #2 } } { \@latex@warning@no@line {Rerun~to~get~acronym~list~right} } } \cs_new:Npn \acro@print@list { \cs_if_exist:NF \acro@printed@list { \cs_new:Npn \acro@printed@list {} } } % -------------------------------------------------------------------------- % USER COMMANDS % adding an acronym, user command: % #1: use/replace plural (boolean) % #2: id % #3: short % #4: short plural % #5: alt % #6: long % #7: long plural % #8: class % #9: extra \NewDocumentCommand \DeclareAcronym { sm>{\SplitArgument{1}{,}}mo>{\SplitArgument{1}{,}}+mgo } { \acro_new:nnnnnnnnn { #1 } { #2 } #3 { #4 } #5 { #7 } { #6 } } \@onlypreamble \DeclareAcronym \NewDocumentCommand \DeclareAcronymFormat { mm } { \acro_format:nn { #1 } { #2 } } \@onlypreamble \DeclareAcronymFormat \NewDocumentCommand \DeclareAcronymCitation { moom } { \acro_citation:nnnn { #1 } { #2 } { #3 } { #4 } } \@onlypreamble \DeclareAcronymCitation % automatic: \NewDocumentCommand \ac { m } { \group_begin: \acro_use:n { #1 } \group_end: } \NewDocumentCommand \Ac { m } { \group_begin: \bool_set_true:N \l__acro_first_upper_bool \acro_use:n { #1 } \group_end: } \NewDocumentCommand \acp { m } { \group_begin: \bool_set_true:N \l__acro_use_plural_bool \acro_use:n { #1 } \group_end: } \NewDocumentCommand \Acp { m } { \group_begin: \bool_set_true:N \l__acro_use_plural_bool \bool_set_true:N \l__acro_first_upper_bool \acro_use:n { #1 } \group_end: } % short: \NewDocumentCommand \acs { m } { \group_begin: \acro_short:n { #1 } \group_end: } \NewDocumentCommand \acsp { m } { \group_begin: \bool_set_true:N \l__acro_use_plural_bool \acro_short:n { #1 } \group_end: } % alt: \NewDocumentCommand \aca { m } { \group_begin: \acro_alt:n { #1 } \group_end: } \NewDocumentCommand \acap { m } { \group_begin: \bool_set_true:N \l__acro_use_plural_bool \acro_alt:n { #1 } \group_end: } % long: \NewDocumentCommand \acl { m } { \group_begin: \acro_long:n { #1 } \group_end: } \NewDocumentCommand \Acl { m } { \group_begin: \bool_set_true:N \l__acro_first_upper_bool \acro_long:n { #1 } \group_end: } \NewDocumentCommand \aclp { m } { \group_begin: \bool_set_true:N \l__acro_use_plural_bool \acro_long:n { #1 } \group_end: } \NewDocumentCommand \Aclp { m } { \group_begin: \bool_set_true:N \l__acro_use_plural_bool \bool_set_true:N \l__acro_first_upper_bool \acro_long:n { #1 } \group_end: } % first: \NewDocumentCommand \acf { m } { \group_begin: \acro_first:n { #1 } \group_end: } \NewDocumentCommand \Acf { m } { \group_begin: \bool_set_true:N \l__acro_first_upper_bool \acro_first:n { #1 } \group_end: } \NewDocumentCommand \acfp { m } { \group_begin: \bool_set_true:N \l__acro_use_plural_bool \acro_first:n { #1 } \group_end: } \NewDocumentCommand \Acfp { m } { \group_begin: \bool_set_true:N \l__acro_use_plural_bool \bool_set_true:N \l__acro_first_upper_bool \acro_first:n { #1 } \group_end: } % reset outputs, they'll behave like the first time again (!not like the _only_ % time!): \NewDocumentCommand \acresetall {} { \prop_map_inline:Nn \l__acro_short_prop { \bool_gset_false:c { g_acro_##1_used_bool } } } % typeset the list: \NewDocumentCommand \printacronyms { G{}o } { \acro_print_acronyms:nn { #1 } { #2 } } \ProcessKeysOptions { acro } \AtBeginDocument { \@ifpackageloaded { hyperref } { \bool_set_true:N \l__acro_hyperref_loaded_bool } {} } \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 % -------------------------------------------------------------------------- % TODO: - Sprach-Support Überschrift der Acronym-Liste - Option `totoc'?