From 7a8d1925127ad121a8f591db931524f9b8eacb93 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 28 Feb 2022 03:02:40 +0000 Subject: CTAN sync 202202280302 --- macros/latex/contrib/fnpct/README | 7 +- macros/latex/contrib/fnpct/fnpct-2019-10-05.sty | 1191 +++++++++++++++++++++++ macros/latex/contrib/fnpct/fnpct-manual.cls | 6 +- macros/latex/contrib/fnpct/fnpct-manual.pdf | Bin 509779 -> 494932 bytes macros/latex/contrib/fnpct/fnpct-manual.tex | 28 +- macros/latex/contrib/fnpct/fnpct.sty | 51 +- 6 files changed, 1245 insertions(+), 38 deletions(-) create mode 100644 macros/latex/contrib/fnpct/fnpct-2019-10-05.sty (limited to 'macros/latex/contrib/fnpct') diff --git a/macros/latex/contrib/fnpct/README b/macros/latex/contrib/fnpct/README index 88d9dc33ef..7a6961da7f 100644 --- a/macros/latex/contrib/fnpct/README +++ b/macros/latex/contrib/fnpct/README @@ -1,5 +1,5 @@ -------------------------------------------------------------------------- -the FNPCT package v1.1 2022/02/03 +the FNPCT package v1.1a 2022/02/27 footnotes' interaction with punctuation @@ -23,8 +23,9 @@ This work has the LPPL maintenance status `maintained'. The Current Maintainer of this work is Clemens Niederberger. -------------------------------------------------------------------------- The fnpct package consists of the files - - fnpct.sty, - - fnpct_en.tex and fnpct_en.pdf + - fnpct.sty, fnpct-2019-10-05.sty + - fnpct-check-packages.tex + - fnpct-manual.tex, fnpct-manual.cls fnpct-manual.pdf - README -------------------------------------------------------------------------- the package is inspired by the following question on TeX.SE: diff --git a/macros/latex/contrib/fnpct/fnpct-2019-10-05.sty b/macros/latex/contrib/fnpct/fnpct-2019-10-05.sty new file mode 100644 index 0000000000..e599c1afd3 --- /dev/null +++ b/macros/latex/contrib/fnpct/fnpct-2019-10-05.sty @@ -0,0 +1,1191 @@ +% -------------------------------------------------------------------------- +% the FNPCT package +% +% footnote kerning +% +% -------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/fnpct/ +% E-Mail: contact@mychemistry.eu +% -------------------------------------------------------------------------- +% Copyright 2012--2020 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% -------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% -------------------------------------------------------------------------- +% the package is inspired by the following question on TeX.SE: +% http://tex.stackexchange.com/q/56094/5049 +% -------------------------------------------------------------------------- +\RequirePackage {xparse,l3keys2e,scrlfile} +\ExplSyntaxOn + +\tl_const:Nn \c_fnpct_date_tl {2019/10/05} +\tl_const:Nn \c_fnpct_version_major_number_tl {0} +\tl_const:Nn \c_fnpct_version_minor_number_tl {5} +\tl_const:Nn \c_fnpct_version_subrelease_tl {} +\tl_const:Nx \c_fnpct_version_number_tl + { + \c_fnpct_version_major_number_tl . + \c_fnpct_version_minor_number_tl + } +\tl_const:Nx \c_fnpct_version_tl + { + \c_fnpct_version_number_tl + \c_fnpct_version_subrelease_tl + } +\tl_const:Nn \c_fnpct_info_tl {footnote~ kerning} + +\ProvidesExplPackage + {fnpct} + {\c_fnpct_date_tl} + {\c_fnpct_version_tl} + {\c_fnpct_info_tl} + +% -------------------------------------------------------------------------- +% this is plain's \nobreak: +\cs_new:Npn \fnpct_no_break: { \tex_penalty:D 10000 \scan_stop: } + +% -------------------------------------------------------------------------- +% variables: +\tl_new:N \l__fnpct_tmpa_tl +\tl_new:N \l__fnpct_tmpb_tl + +\dim_new:N \l__fnpct_tmpa_dim +\dim_new:N \l__fnpct_tmpb_dim + +\int_new:N \l__fnpct_tmpa_int + +\seq_new:N \l__fnpct_tmpa_seq +\seq_new:N \l__fnpct_tmpb_seq + +\dim_new:N \l__fnpct_after_comma_dim +\dim_set:Nn \l__fnpct_after_comma_dim {-.06em} +\dim_new:N \l__fnpct_after_dot_dim +\dim_set:Nn \l__fnpct_after_dot_dim {-.06em} +\dim_new:N \l__fnpct_before_comma_dim +\dim_set:Nn \l__fnpct_before_comma_dim {-.16em} +\dim_new:N \l__fnpct_before_dot_dim +\dim_set:Nn \l__fnpct_before_dot_dim {-.16em} +\dim_new:N \l__fnpct_before_footnote_dim +\dim_set:Nn \l__fnpct_before_footnote_dim {.06em} +\dim_new:N \l__fnpct_normal_mark_width_dim +\dim_set:Nn \l__fnpct_normal_mark_width_dim {1em} +\dim_new:N \l__fnpct_normal_indent_dim +\dim_set:Nn \l__fnpct_normal_indent_dim {1.5em} +\dim_new:N \l__fnpct_normal_parindent_dim +\dim_set:Nn \l__fnpct_normal_parindent_dim {1em} +\dim_new:N \l__fnpct_french_before_footnote_space_dim +\dim_set:Nn \l__fnpct_french_before_footnote_space_dim {.16667em} + +\int_new:N \l__fnpct_multiple_notes_int + +\tl_new:N \l__fnpct_multiple_footnotes_delimiter_tl +\tl_set:Nn \l__fnpct_multiple_footnotes_delimiter_tl {;} +\tl_new:N \l__fnpct_multiple_footnote_separator_tl +\tl_new:N \l__fnpct_last_punct_mark_tl +\tl_new:N \l__fnpct_punctuation_marks_tl +\tl_set:Nn \l__fnpct_punctuation_marks_tl {.,} +\tl_new:N \l__fnpct_multiple_true_tl +\tl_new:N \l__fnpct_multiple_false_tl + +\bool_new:N \l__fnpct_strict_bool +\bool_new:N \l__fnpct_punct_after_bool +\bool_new:N \l__fnpct_dont_mess_around_bool +\bool_new:N \l__fnpct_multiple_default_bool +\bool_new:N \l__fnpct_multiple_footnotes_bool +\bool_new:N \l__fnpct_reverse_switch_bool +\bool_new:N \l__fnpct_normal_marks_bool +\bool_new:N \l__fnpct_hyperref_bool +\bool_new:N \g__fnpct_after_punctuation_bool +\bool_new:N \g__fnpct_only_text_bool +\bool_new:N \l__fnpct_makepagenote_bool + +\seq_new:N \l__fnpct_multiple_footnotes_seq +\seq_new:N \l__fnpct_footnote_class_seq + +\prop_new:N \l__fnpct_punctuation_marks_after_prop +\prop_new:N \l__fnpct_punctuation_marks_before_prop +\prop_new:N \l__fnpct_sepfootnote_foot_classes_prop +\prop_new:N \l__fnpct_sepfootnote_end_classes_prop +\prop_new:N \l__fnpct_sepfootnote_symbol_classes_prop +\prop_new:N \g__fnpct_adapted_notes_prop +\prop_new:N \g__fnpct_inner_footnote_prop +\prop_new:N \g__fnpct_inner_footnote_hyperref_prop +\prop_new:N \l__fnpct_footnote_fixfoot_prop + +% -------------------------------------------------------------------------- +% variants: +\cs_generate_variant:Nn \str_remove_once:Nn {NV} +\cs_generate_variant:Nn \tl_remove_all:Nn {NV} +\cs_generate_variant:Nn \tl_put_right:Nn {NV} +\cs_generate_variant:Nn \seq_set_split:Nnn {NnV,NV} +\cs_generate_variant:Nn \prop_gput:Nnn {Nx,Nxo} +\cs_generate_variant:Nn \prop_put:Nnn {Nnx} +\cs_generate_variant:Nn \prop_if_in:NnTF {Nx} + +% -------------------------------------------------------------------------- +% messages: +\cs_new_protected:Npn \fnpct_dont_mess_around: + { + \iow_log:n { ................................................. } + \iow_log:n { . ~ fnpct~info: } + \iow_log:n { . } + \iow_log:n { . ~ All~right,~not~messing~around.~:( } + \iow_log:n { . ~ But~I'd~really~love~to. } + \iow_log:n { . ~ (https://www.youtube.com/results?search_query=mess+around+ray+charles) } + \iow_log:n { ................................................. } + } + +\msg_new:nnn {fnpct} {already-adapted} + { + The~ command~ \token_to_str:N #1 \c_space_tl has~ already~ been~ + adapted. \\ + I~ will~ do~ nothing~ instead. + } + +\msg_new:nnn {fnpct} {pagenote} + { + If~ you~ use~ the~ `pagenote'~ package~ with~ `fnpct'~ please~ make~ sure~ + to~ use~ \token_to_str:N \makepagenote \c_space_tl after~ loading~ + `fnpct'! + } + +\msg_new:nnn {fnpct} {deprecated} + { + You've~ tried~ setting~ #1~ `#2'~ \msg_line_context: .~ However,~ + #1~ `#2'~ is~ deprecated.~ + \tl_if_blank:nF {#3} {Please~ use~ #1~ `#3'~ instead.~} + Refer~ to~ the~ manual~ for~ details. + } + +\cs_new_protected:Npn \fnpct_message:nx #1#2 + { + \bool_if:NTF \l__fnpct_strict_bool + { \msg_error:nnx {fnpct} {#1} } + { \msg_warning:nnx {fnpct} {#1} } + {#2} + } + +% -------------------------------------------------------------------------- +\prg_new_conditional:Npnn \fnpct_if_package_loaded:n #1 {p,T,F,TF} + { + \@ifpackageloaded {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +% -------------------------------------------------------------------------- +% multiple footnote input and output variables: +% check for KOMA-Script's \multfootsep: +\cs_if_exist:NTF \KOMAClassName + { \tl_set:Nn \l__fnpct_multiple_footnote_separator_tl { \multfootsep } } + { \tl_set:Nn \l__fnpct_multiple_footnote_separator_tl {,} } + +% -------------------------------------------------------------------------- +% #1: before/after +% #2: punctuation mark +% #3: dimension +\cs_new_protected:Npn \fnpct_set_punctuation_dim:nnn #1#2#3 + { + \prop_put:cnx { l__fnpct_punctuation_marks_#1_prop } + {#2} + { \dim_eval:n {#3} } + } +\cs_generate_variant:Nn \fnpct_set_punctuation_dim:nnn {nV} + +\fnpct_set_punctuation_dim:nnn {after} {.} { \l__fnpct_after_dot_dim } +\fnpct_set_punctuation_dim:nnn {after} {,} { \l__fnpct_after_comma_dim } +\fnpct_set_punctuation_dim:nnn {before} {.} { \l__fnpct_before_dot_dim } +\fnpct_set_punctuation_dim:nnn {before} {,} { \l__fnpct_before_comma_dim } + +\cs_new_protected:Npn \fnpct_rm_punctuation:n #1 + { + \tl_remove_all:Nn \l__fnpct_punctuation_marks_tl {#1} + \prop_del:Nn \l__fnpct_punctuation_marks_after_prop {#1} + \prop_del:Nn \l__fnpct_punctuation_marks_before_prop {#1} + } + +\cs_new_protected:Npn \fnpct_add_punctuation:n #1 + { \__fnpct_add_punctuation:w #1 [ \q_no_value ] \q_no_value \q_stop } +\cs_generate_variant:Nn \fnpct_add_punctuation:n {V} + +\cs_new_protected:Npn \__fnpct_add_punctuation:w #1[#2]#3 \q_stop + { + \quark_if_no_value:nTF {#2} + { + % there is no option at all + \tl_map_inline:nn {#1} + { + \tl_put_right:Nn \l__fnpct_punctuation_marks_tl {##1} + \fnpct_set_punctuation_dim:nnn {after} {##1} {0pt} + \fnpct_set_punctuation_dim:nnn {before} {##1} {0pt} + \tl_set:No \l__fnpct_last_punct_mark_tl {##1} + } + } + { + \tl_if_blank:nTF {#1} + { + % #2 is a second option (= before space) + \fnpct_set_punctuation_dim:nVn {before} + \l__fnpct_last_punct_mark_tl + {#2} + } + { + % #2 is a first option (= after space), #1 might be more than one token: + \tl_if_single_token:nTF {#1} + { + \tl_put_right:Nn \l__fnpct_punctuation_marks_tl {#1} + \fnpct_set_punctuation_dim:nnn {after} {#1} {#2} + \fnpct_set_punctuation_dim:nnn {before} {#1} {0pt} + \tl_set:No \l__fnpct_last_punct_mark_tl {#1} + } + { + \int_zero:N \l__fnpct_tmpa_int + \tl_map_inline:nn {#1} + { + \tl_put_right:Nn \l__fnpct_punctuation_marks_tl {##1} + \int_compare:nTF { \l__fnpct_tmpa_int < ( \tl_count:n {#1} - 1 ) } + { + \fnpct_set_punctuation_dim:nnn {after} {##1} {0pt} + \fnpct_set_punctuation_dim:nnn {before} {##1} {0pt} + } + { + \fnpct_set_punctuation_dim:nnn {after} {##1} {#2} + \fnpct_set_punctuation_dim:nnn {before} {##1} {0pt} + } + \tl_set:No \l__fnpct_last_punct_mark_tl {##1} + \int_incr:N \l__fnpct_tmpa_int + } + } + } + } + % is there more? + \tl_if_eq:nnF {#3} { [\q_no_value]\q_no_value } + { + \quark_if_no_value:nF {#3} + { + \tl_set:Nn \l__fnpct_tmpa_tl {#3} + \tl_remove_all:Nn \l__fnpct_tmpa_tl { [\q_no_value]\q_no_value } + \fnpct_add_punctuation:V \l__fnpct_tmpa_tl + } + } + } + +% -------------------------------------------------------------------------- +% options: +\keys_define:nn {fnpct} + { + bigfoot-default-top .code:n = + \msg_warning:nnnn {fnpct} {deprecated} {option} {bigfoot-default-top} , + strict .bool_set:N = \l__fnpct_strict_bool , + after-comma-space .code:n = + \fnpct_set_punctuation_dim:nnn {after} {,} {#1} , + after-dot-space .code:n = + \fnpct_set_punctuation_dim:nnn {after} {.} {#1} , + before-comma-space .code:n = + \fnpct_set_punctuation_dim:nnn {before} {,} {#1} , + before-dot-space .code:n = + \fnpct_set_punctuation_dim:nnn {before} {.} {#1} , + after-punct-space .code:n = + \prop_map_inline:Nn \l__fnpct_punctuation_marks_after_prop + { \fnpct_set_punctuation_dim:nnn {after} {##1} {#1} } , + before-punct-space .code:n = + \prop_map_inline:Nn \l__fnpct_punctuation_marks_before_prop + { \fnpct_set_punctuation_dim:nnn {before} {##1} {#1} } , + before-footnote-space .dim_set:N = \l__fnpct_before_footnote_dim , + french-before-footnote-space .dim_set:N = + \l__fnpct_french_before_footnote_space_dim , + punct-after .bool_set:N = \l__fnpct_punct_after_bool , + dont-mess-around .code:n = + \prop_map_inline:Nn \l__fnpct_punctuation_marks_after_prop + { \fnpct_set_punctuation_dim:nnn {after} {##1} {0pt} } + \prop_map_inline:Nn \l__fnpct_punctuation_marks_before_prop + { \fnpct_set_punctuation_dim:nnn {before} {##1} {0pt} } + \dim_zero:N \l__fnpct_before_footnote_dim + \bool_set_true:N \l__fnpct_punct_after_bool + \bool_set_true:N \l__fnpct_dont_mess_around_bool + \fnpct_dont_mess_around: , + mult-fn-delim .tl_set:N = \l__fnpct_multiple_footnotes_delimiter_tl , + mult-fn-sep .tl_set:N = \l__fnpct_multiple_footnote_separator_tl , + multiple .bool_set:N = \l__fnpct_multiple_default_bool , + normal-marks .bool_set:N = \l__fnpct_normal_marks_bool , + normal-mark-width .dim_set:N = \l__fnpct_normal_mark_width_dim , + normal-indent .dim_set:N = \l__fnpct_normal_indent_dim , + normal-parindent .dim_set:N = \l__fnpct_normal_parindent_dim , + verb-format .tl_set:N = \l__fnpct_verbatim_format_tl , + add-punct-marks .code:n = \fnpct_add_punctuation:n {#1} , + remove-punct-marks .code:n = + \tl_map_function:nN {#1} \fnpct_rm_punctuation:n + } + +\ProcessKeysOptions {fnpct} + +% -------------------------------------------------------------------------- +% MAIN INTERNAL FOOTNOTE FUNCTION: +% write the notes: +\cs_new:Npn \__fnpct_no_value_or_quark_no_value:nTF #1#2#3 + { + \IfNoValueTF {#1} {#2} + { \quark_if_no_value:nTF {#1} {#2} {#3} } + } + +\cs_new:Npn \fnpct_write_note:Nnnn #1#2#3#4 + { + \__fnpct_no_value_or_quark_no_value:nTF {#2} + { #1 {#4} } + { + \__fnpct_no_value_or_quark_no_value:nTF {#3} + { #1 [#2] {#4} } + { #1 [#2] [#3] {#4} } + } + } + +\cs_new:Npn \fnpct_write_snote:Nnnn #1#2#3#4 + { + \__fnpct_no_value_or_quark_no_value:nTF {#2} + { + \__fnpct_no_value_or_quark_no_value:nTF {#3} + { #1 {#4} } + { #1 [#3] {#4} } + } + { + \__fnpct_no_value_or_quark_no_value:nTF {#3} + { #1 (#2) {#4} } + { #1 (#2) [#3] {#4} } + } + } + +% check for punctuation: +\cs_new_protected:Npn \fnpct_check_punctuation:TF #1#2 + { \__fnpct_check_punctuation:nTF {0} {#1} {#2} } + +\cs_new_protected:Npn \__fnpct_check_punctuation:nTF #1#2#3 + { + \__fnpct_get_head:NN + \l__fnpct_current_punct_mark_tl + \l__fnpct_punctuation_marks_tl + \exp_args:NV \peek_meaning_remove:NTF \l__fnpct_current_punct_mark_tl + {#2} + { + \__fnpct_check_punctuation_aux:nnn {#1} + { \__fnpct_check_punctuation:VTF \l__fnpct_tmpa_int {#2} {#3} } + {#3} + } + } + +\cs_new_protected:Npn \__fnpct_check_punctuation_aux:nnn #1#2#3 + { + \int_set:Nn \l__fnpct_tmpa_int {#1} + \int_incr:N \l__fnpct_tmpa_int + \tl_set:Nx \l__fnpct_tmpb_tl { \int_to_arabic:n { \l__fnpct_tmpa_int } } + \tl_remove_all:NV \l__fnpct_punctuation_marks_tl + \l__fnpct_current_punct_mark_tl + \tl_put_right:NV \l__fnpct_punctuation_marks_tl + \l__fnpct_current_punct_mark_tl + \int_compare:nTF { \l__fnpct_tmpa_int < \tl_count:V \l__fnpct_punctuation_marks_tl } + {#2} + {#3} + } +\cs_generate_variant:Nn \__fnpct_check_punctuation:nTF {V} + +\cs_new_protected:Npn \__fnpct_get_head:NN #1#2 + { \tl_set:Nx #1 { \tl_head:V #2 } } + +% check for multiple notes: +\cs_new_protected:Npn \fnpct_check_multiple:TF #1#2 + { + \tl_set:Nn \l__fnpct_multiple_true_tl {#1} + \tl_set:Nn \l__fnpct_multiple_false_tl {#2} + \bool_gset_false:N \g__fnpct_after_punctuation_bool + \peek_after:Nw \__fnpct_check_multiple: + } + +\cs_new_protected:Npn \__fnpct_check_multiple: + { + \prop_map_inline:Nn \g__fnpct_adapted_notes_prop + { + \tl_set_rescan:Nnn \l__fnpct_tmpb_tl {} {##1} + \exp_args:NV + \token_if_eq_meaning:NNTF \l__fnpct_tmpb_tl \l_peek_token + { + \bool_set_true:N \l__fnpct_multiple_footnotes_bool + \prop_map_break: + } + { \bool_set_false:N \l__fnpct_multiple_footnotes_bool } + } + \bool_if:NTF \l__fnpct_multiple_footnotes_bool + { \tl_use:N \l__fnpct_multiple_true_tl } + { \tl_use:N \l__fnpct_multiple_false_tl } + } + +% check which mode is active: +\prg_new_conditional:Npnn \fnpct_punct_if_after: {T,TF} + { + \bool_if:nTF + { + \bool_xor_p:nn + { \l__fnpct_punct_after_bool } + { \l__fnpct_reverse_switch_bool } + } + { \prg_return_true: } + { \prg_return_false: } + } + +% this is where the magic happens: +\cs_new_protected:Npn \fnpct_handle_punctuation:n #1 + { + \fnpct_check_punctuation:TF + { + % this is need as some commands like biblatex's \autocite may in turn + % call \footnote. It then must not insert the pre-footnote-space: + \bool_gset_true:N \g__fnpct_after_punctuation_bool + % A: after=1 && reverse=0 + % after=0 && reverse=1 + % B: after=1 && reverse=1 + % after=0 && reverse=0 + \fnpct_punct_if_after:TF + { + \fnpct_no_break: + \skip_horizontal:N \l__fnpct_before_footnote_dim + } + { + \tl_use:N \l__fnpct_current_punct_mark_tl + \prop_get:NVNT \l__fnpct_punctuation_marks_after_prop + \l__fnpct_current_punct_mark_tl + \l__fnpct_tmpa_tl + { + \dim_set:Nn \l__fnpct_tmpa_dim { \l__fnpct_tmpa_tl } + \fnpct_no_break: + \skip_horizontal:N \l__fnpct_tmpa_dim + \fnpct_no_break: + \skip_horizontal:N \c_zero_skip + \fnpct_no_break: + } + } + #1 + \bool_gset_false:N \g__fnpct_after_punctuation_bool + \fnpct_punct_if_after:T + { + \fnpct_no_break: + \prop_get:NVNT \l__fnpct_punctuation_marks_before_prop + \l__fnpct_current_punct_mark_tl + \l__fnpct_tmpa_tl + { + \dim_set:Nn \l__fnpct_tmpa_dim { \l__fnpct_tmpa_tl } + \fnpct_no_break: + \skip_horizontal:N \l__fnpct_tmpa_dim + \fnpct_no_break: + \skip_horizontal:N \c_zero_skip + \fnpct_no_break: + } + \tl_use:N \l__fnpct_current_punct_mark_tl + } + \bool_set_false:N \l__fnpct_reverse_switch_bool + } + { + % what about multiple footnotes? (their usage is discouraged with + % this package, but anyway...) + % this check should probably/maybe be removed (?!) + \fnpct_check_multiple:TF + { + \bool_set_true:N \l__fnpct_multiple_footnotes_bool + \fnpct_no_break: + \bool_if:NF \g__fnpct_after_punctuation_bool + { \skip_horizontal:N \l__fnpct_before_footnote_dim } + #1 + \fnpct_no_break: + \textsuperscript { \l__fnpct_multiple_footnote_separator_tl } + } + { + % else insert space and then note + \bool_if:NTF \l__fnpct_multiple_footnotes_bool + { \bool_set_false:N \l__fnpct_multiple_footnotes_bool } + { + \fnpct_no_break: + \bool_if:NF \g__fnpct_after_punctuation_bool + { \skip_horizontal:N \l__fnpct_before_footnote_dim } + } + #1 + \bool_set_false:N \l__fnpct_reverse_switch_bool + } + } + } + + +% #1: original command +% #2: optional argument of original command +% #3: second optional argument of original command +% #4: mandatory argument of original command +% #5: boolean flag for starred version +\cs_new_protected:Npn \fnpct_handle_note:Nnnnn #1#2#3#4#5 + { + % if a punctuation mark follows remove it, insert dot, skip back + % and then insert footnote + \bool_if:NF \l__fnpct_dont_mess_around_bool + { + \IfBooleanT {#5} + { \bool_set_true:N \l__fnpct_reverse_switch_bool } + } + \fnpct_handle_punctuation:n + { + \fnpct_write_note:Nnnn #1 {#2} {#3} {#4} + \fnpct_write_inner:N #1 + } + } +\cs_generate_variant:Nn \fnpct_handle_note:Nnnnn {c} + +\cs_new_protected:Npn \fnpct_handle_snote:Nnnnn #1#2#3#4#5 + { + \bool_if:NF \l__fnpct_dont_mess_around_bool + { + \IfBooleanT {#5} + { \bool_set_true:N \l__fnpct_reverse_switch_bool } + } + \fnpct_handle_punctuation:n + { + \fnpct_write_snote:Nnnn #1 {#2} {#3} {#4} + \fnpct_write_inner:N #1 + } + } +\cs_generate_variant:Nn \fnpct_handle_snote:Nnnnn {c} + +% -------------------------------------------------------------------------- +% MULTIPLE FOOTNOTES +% #1: original note command +% #2: star +% #3: multiple notes separated by \l__fnpct_multiple_footnotes_delimiter_tl +\cs_new_protected:Npn \fnpct_mult_note:Nnn #1#2#3 + { + \bool_if:NF \l__fnpct_dont_mess_around_bool + { + \IfBooleanT {#2} + { \bool_set_true:N \l__fnpct_reverse_switch_bool } + } + % split input: + \seq_set_split:NVn \l__fnpct_multiple_footnotes_seq + \l__fnpct_multiple_footnotes_delimiter_tl + {#3} + \fnpct_handle_punctuation:n + { \fnpct_write_notes:NN #1 \l__fnpct_multiple_footnotes_seq } + + } +\cs_generate_variant:Nn \fnpct_mult_note:Nnn {c} + +% #1: original note command +% #2: sequence variable holding the note arguments +\cs_new_protected:Npn \fnpct_write_notes:NN #1#2 + { + \int_zero:N \l__fnpct_multiple_notes_int + \seq_map_inline:Nn #2 + { + \__fnpct_read_note_with_option:w ##1 \q_stop {#1} + \int_incr:N \l__fnpct_multiple_notes_int + } + } + +% this shouldn't be a document command but is a really easy way to make +% biblatex's \footcite et.al. compatible with the `multiple' option +% #1: optional star => only invoke \footnotetext +% #2: optional argument to original note command +% #3: second optional argument to original note command +% #4: mandatory argument to original note command +% #5: original note command +\NewDocumentCommand \__fnpct_read_note_with_option:w { soo+u{\q_stop}m } + { + \bool_if:nT + { + \int_compare_p:n { \l__fnpct_multiple_notes_int > 0 } + && + \int_compare_p:n + { + \l__fnpct_multiple_notes_int + < + \seq_count:N \l__fnpct_multiple_footnotes_seq + } + } + { + \IfBooleanTF {#1} + { \tex_unskip:D } + { \textsuperscript { \l__fnpct_multiple_footnote_separator_tl } } + } + \IfBooleanTF {#1} + { + % TODO: maybe provide option to change \footnotetext? Or do it + % automatically? + \bool_gset_true:N \g__fnpct_only_text_bool + \IfNoValueTF {#2} + { \footnotetext {#4} } + { \footnotetext [#2] {#4} } + } + { \fnpct_write_note:Nnnn #5 {#2} {#3} {#4} } + \fnpct_write_inner:N #5 + } + +% -------------------------------------------------------------------------- +% NESTED FOOTNOTES: +% 1 layer of nesting... +% this shouldn't be a document command! But for the time being I'll stick to +% this easy solution... +\NewDocumentCommand \fnpct_inner_footnote:w {o+m} + { + \IfNoValueTF {#1} + { + % TODO: maybe detect what type of note we're in and use the appropriate mark? + % Or provide a user interface to choose the appropriate mark? + \fnpct_orig_footnotemark:w + \prop_gput:Nxn \g__fnpct_inner_footnote_prop { \thefootnote } {#2} + \bool_if:NT \l__fnpct_hyperref_bool + { + \prop_gput:Nxo \g__fnpct_inner_footnote_hyperref_prop + { \thefootnote } { \Hy@footnote@currentHref } + } + } + { + \fnpct_orig_footnotemark:w [#1] + \prop_gput:Nnn \g__fnpct_inner_footnote_prop {#1} {#2} + \bool_if:NT \l__fnpct_hyperref_bool + { + \prop_gput:Nno \g__fnpct_inner_footnote_hyperref_prop + {#1} { \Hy@footnote@currentHref } + } + } + } + +\cs_new_protected:Npn \fnpct_write_inner:N #1 + { + \token_if_eq_meaning:NNF #1 \fnpct_inner_footnote:w + { + \prop_map_inline:Nn \g__fnpct_inner_footnote_prop + { + \footnotetext [##1] + { + \bool_if:NT \l__fnpct_hyperref_bool + { + \prop_get:NnN \g__fnpct_inner_footnote_hyperref_prop + {##1} \l__fnpct_tmpa_tl + \Hy@raisedlink + { \exp_args:NV \hyper@@anchor \l__fnpct_tmpa_tl } + } + ##2 + } + } + \prop_gclear:N \g__fnpct_inner_footnote_prop + } + } + +\NewDocumentCommand \writeinnernotes {} + { \fnpct_write_inner:N X } + +% -------------------------------------------------------------------------- +% MANUAL KERNING: +\cs_new_protected:Npn \fnpct_kfp: + { + \fnpct_no_break: + \prop_get:NnNT \l__fnpct_punctuation_marks_before_prop {.} + \l__fnpct_tmpa_tl + { \dim_set:Nn \l__fnpct_tmpa_dim { \l__fnpct_tmpa_tl } } + \prop_get:NnNT \l__fnpct_punctuation_marks_after_prop {.} + \l__fnpct_tmpb_tl + { \dim_set:Nn \l__fnpct_tmpb_dim { \l__fnpct_tmpb_tl } } + \bool_if:NTF \l__fnpct_punct_after_bool + { \skip_horizontal:N \l__fnpct_tmpa_dim } + { \skip_horizontal:N \l__fnpct_tmpb_dim } + } + +\cs_new_protected:Npn \fnpct_kfc: + { + \fnpct_no_break: + \prop_get:NnNT \l__fnpct_punctuation_marks_before_prop {,} + \l__fnpct_tmpa_tl + { \dim_set:Nn \l__fnpct_tmpa_dim { \l__fnpct_tmpa_tl } } + \prop_get:NnNT \l__fnpct_punctuation_marks_after_prop {,} + \l__fnpct_tmpb_tl + { \dim_set:Nn \l__fnpct_tmpb_dim { \l__fnpct_tmpb_tl } } + \bool_if:NTF \l__fnpct_punct_after_bool + { \skip_horizontal:N \l__fnpct_tmpa_dim } + { \skip_horizontal:N \l__fnpct_tmpb_dim } + } + +\NewDocumentCommand \kfp {} { \fnpct_kfp: } +\NewDocumentCommand \kfc {} { \fnpct_kfc: } + +% -------------------------------------------------------------------------- +% NORMAL MARKS: +\AtBeginDocument + { + \bool_if:NT \l__fnpct_normal_marks_bool + { + \cs_if_exist:NF \KOMAoption + { \RequirePackage { scrextend } } + \deffootnote + [ \l__fnpct_normal_mark_width_dim ] + { \l__fnpct_normal_indent_dim } + { \l__fnpct_normal_parindent_dim } + { \thefootnotemark . \enskip } + } + } + +% -------------------------------------------------------------------------- +% LET'S MAKE IT EASIER TO ADAPT EXISTING FUNCTIONS: +% COPY, RENEW AND CREATE MULT + +\prg_new_conditional:Npnn \fnpct_if_adapted:N #1 {p,T,F,TF} + { + \prop_if_in:NnTF \g__fnpct_adapted_notes_prop {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +\cs_new_protected:Npn \fnpct_add_to_adapted:NN #1#2 + { + % \tl_show:n {1:~#1} \tl_show:n {2:~#2} + \prop_gput:Nnn \g__fnpct_adapted_notes_prop {#1} {#2} + } + +% standard \footnote[]{} like commands +% #1: old new name +% #2: internal name of old definition +% #3: mult-variant +% +% \footnote[]{} like: +\cs_new_protected:Npn \fnpct_renew_and_mult:NNN #1#2#3 + { + \fnpct_if_adapted:NF #1 + { + \fnpct_add_to_adapted:NN #1#2 + \cs_new_eq:NN #2#1 + \fnpct_create_mult_variant:NN #3#2 + \bool_if:NTF \l__fnpct_multiple_default_bool + { \cs_set_eq:NN #1#3 } + { + \RenewDocumentCommand #1 {so+m} + { \fnpct_handle_note:Nnnnn #2 {##2} { \q_no_value } {##3} {##1} } + } + } + } +\cs_generate_variant:Nn \fnpct_renew_and_mult:NNN {ccc,Nc} + +% \footnote{} like: +\cs_new_protected:Npn \fnpct_renew_and_mult_no_opt:NNN #1#2#3 + { + \fnpct_if_adapted:NF #1 + { + \fnpct_add_to_adapted:NN #1#2 + \cs_new_eq:NN #2#1 + \fnpct_create_mult_variant:NN #3#2 + \bool_if:NTF \l__fnpct_multiple_default_bool + { \cs_set_eq:NN #1#3 } + { + \RenewDocumentCommand #1 {s+m} + { + \fnpct_handle_note:Nnnnn #2 { \q_no_value } { \q_no_value } + {##2} {##1} + } + } + } + } +\cs_generate_variant:Nn \fnpct_renew_and_mult_no_opt:NNN {Nc,ccc} + +% renew but don't create mult-variant: +% \footnote[]{} like: +\cs_new_protected:Npn \fnpct_renew:NN #1#2 + { + \fnpct_if_adapted:NF #1 + { + \fnpct_add_to_adapted:NN #1#2 + \cs_new_eq:NN #2#1 + \RenewDocumentCommand #1 {so+m} + { \fnpct_handle_note:Nnnnn #2 {##2} { \q_no_value } {##3} {##1} } + } + } +\cs_generate_variant:Nn \fnpct_renew:NN {cc,Nc} + +% new +\cs_new_protected:Npn \fnpct_new:NN #1#2 + { + \fnpct_if_adapted:NF #1 + { + \fnpct_add_to_adapted:NN #1#2 + \NewDocumentCommand #1 {so+m} + { \fnpct_handle_note:Nnnnn #2 {##2} { \q_no_value } {##3} {##1} } + } + } +\cs_generate_variant:Nn \fnpct_new:NN {cc,Nc} + +% \note[][]{} like: +\cs_new_protected:Npn \fnpct_renew_and_mult_opt:NNN #1#2#3 + { + \fnpct_if_adapted:NF #1 + { + \fnpct_add_to_adapted:NN #1#2 + \cs_new_eq:NN #2#1 + \fnpct_create_mult_variant:NN #3#2 + \bool_if:NTF \l__fnpct_multiple_default_bool + { \cs_set_eq:NN #1#3 } + { + \RenewDocumentCommand #1 {soo+m} + { \fnpct_handle_note:Nnnnn #2 {##2} {##3} {##4} {##1} } + } + } + } +\cs_generate_variant:Nn \fnpct_renew_and_mult_opt:NNN {ccc,Nc} + +% \note()[]{} like: +\cs_new_protected:Npn \fnpct_renew_and_mult_snotez:NNN #1#2#3 + { + \fnpct_if_adapted:NF #1 + { + \fnpct_add_to_adapted:NN #1#2 + \cs_new_eq:NN #2#1 + \fnpct_create_mult_variant:NN #3#2 + \bool_if:NTF \l__fnpct_multiple_default_bool + { \cs_set_eq:NN #1#3 } + { + \RenewDocumentCommand #1 {sd()o+m} + { \fnpct_handle_snote:Nnnnn #2 {##2} {##3} {##4} {##1} } + } + } + } +\cs_generate_variant:Nn \fnpct_renew_and_mult_snotez:NNN {ccc,Nc} + +\cs_new_protected:Npn \fnpct_renew_opt:NN #1#2 + { + \fnpct_if_adapted:NF #1 + { + \fnpct_add_to_adapted:NN #1#2 + \cs_new_eq:NN #2#1 + \RenewDocumentCommand #1 {soo+m} + { \fnpct_handle_note:Nnnnn #2 {##2} {##3} {##4} {##1} } + } + } +\cs_generate_variant:Nn \fnpct_renew_opt:NN {cc,Nc} + +% \note{} like +\cs_new_protected:Npn \fnpct_renew_no_opt:NN #1#2 + { + \fnpct_if_adapted:NF #1 + { + \fnpct_add_to_adapted:NN #1#2 + \cs_new_eq:NN #2#1 + \RenewDocumentCommand #1 {s+m} + { \fnpct_handle_note:Nnnnn #2 { \q_no_value } { \q_no_value } {##2} {##1} } + } + } +\cs_generate_variant:Nn \fnpct_renew_no_opt:NN {cc,Nc} + +% \note like +\cs_new_protected:Npn \fnpct_renew_no_arg:NN #1#2 + { + \fnpct_if_adapted:NF #1 + { + \fnpct_add_to_adapted:NN #1#2 + \cs_new_eq:NN #2#1 + \RenewDocumentCommand #1 {s} + { \fnpct_handle_note:Nnnnn #2 { \q_no_value } { \q_no_value } { } {##1} } + } + } +\cs_generate_variant:Nn \fnpct_renew_no_arg:NN {cc} + +% create mult-variant +\cs_new_protected:Npn \fnpct_create_mult_variant:NN #1#2 + { + \NewDocumentCommand #1 {s+m} + { \fnpct_mult_note:Nnn #2 {##1} {##2} } + } + +% \footnotemark[] like commands: +\cs_new_protected:Npn \fnpct_renew_mark:NN #1#2 + { + \fnpct_if_adapted:NF #1 + { + \fnpct_add_to_adapted:NN #1#2 + \cs_new_eq:NN #2#1 + \RenewDocumentCommand #1 {so} + { \fnpct_handle_note:Nnnnn #2 {##2} { \q_no_value } { } {##1} } + } + } +\cs_generate_variant:Nn \fnpct_renew_mark:NN {cc,Nc} + +% user commands: +\NewDocumentCommand \AdaptNote {mm} + { + \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w } + { \fnpct_message:nx {already-adapted} {#1} } + { \fnpct_renew_and_mult:NcN #1 { fnpct_orig_ \cs_to_str:N #1 :w } #2 } + } + +\NewDocumentCommand \AdaptNoteNoMult {m} + { + \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w } + { \fnpct_message:nx {already-adapted} {#1} } + { \fnpct_renew:Nc #1 { fnpct_orig_ \cs_to_str:N #1 :w } } + } + +\NewDocumentCommand \AdaptNoteOpt {mm} + { + \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w } + { \fnpct_message:nx {already-adapted} {#1} } + { \fnpct_renew_and_mult_opt:NcN #1 { fnpct_orig_ \cs_to_str:N #1 :w } #2 } + } + +\NewDocumentCommand \AdaptSnotez {mm} + { + \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w } + { \fnpct_message:nx {already-adapted} {#1} } + { \fnpct_renew_and_mult_snotez:NcN #1 { fnpct_orig_ \cs_to_str:N #1 :w } #2 } + } + +\NewDocumentCommand \AdaptNoteOptNoMult {m} + { + \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w } + { \fnpct_message:nx {already-adapted} {#1} } + { \fnpct_renew_opt:Nc #1 { fnpct_orig_ \cs_to_str:N #1 :w } } + } + +\NewDocumentCommand \AdaptNoteNoOpt {mm} + { + \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w } + { \fnpct_message:nx {already-adapted} {#1} } + { \fnpct_renew_and_mult_no_opt:NcN #1 { fnpct_orig_ \cs_to_str:N #1 :w } #2 } + } + +\NewDocumentCommand \AdaptNoteNoOptNoMult {m} + { + \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1:w } + { \fnpct_message:nx {already-adapted} {#1} } + { \fnpct_renew_no_opt:Nc #1 { fnpct_orig_ \cs_to_str:N #1:w } } + } + +\NewDocumentCommand \AdaptNoteMark {m} + { + \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w } + { \fnpct_message:nx {already-adapted} {#1} } + { \fnpct_renew_mark:Nc #1 { fnpct_orig_ \cs_to_str:N #1 :w } } + } + +% -------------------------------------------------------------------------- +% DO THE REDEFINING: +% +% `bigfoot' loads `manyfoot' which saves its footnote classes in a 2e list: +\str_const:Nn \c__fnpct_footins_str {\footins} +\str_remove_once:Nn \c__fnpct_footins_str {~} +\cs_new_protected:Npn \__fnpct_grab_second:Nnw #1#2#3 \q_stop + { + \str_set:Nn \l__fnpct_tmpa_str {#3} + \str_remove_once:Nn \l__fnpct_tmpa_str {~} + \str_remove_once:NV \l__fnpct_tmpa_str \c__fnpct_footins_str + \seq_put_right:Nx #1 { \l__fnpct_tmpa_str } + } + +\cs_new_protected:Npn \__fnpct_get_fnclasses:NN #1#2 + { + \seq_set_split:NnV \l__fnpct_tmpa_seq {\@elt } #1 + \seq_pop_left:NN \l__fnpct_tmpa_seq \l__fnpct_tmpa_tl + \seq_map_inline:Nn \l__fnpct_tmpa_seq + { \__fnpct_grab_second:Nnw #2 ##1 \q_stop } + \seq_remove_duplicates:N #2 + } + +% before we start make the testing more comfortable: +\cs_new_protected:Npn \fnpct_treatment:nn #1#2 + { \fnpct_if_package_loaded:nT {#1} {#2} } + +\cs_new_protected:Npn \fnpct_special_treatment:nn #1#2 + { \fnpct_if_package_loaded:nTF {#1} {#2} { \AfterPackage* {#1} {#2} } } + +% and now get going: +\AtBeginDocument + { + \fnpct_if_package_loaded:nTF {hyperref} + { \bool_set_true:N \l__fnpct_hyperref_bool } + { + \cs_if_exist:NF \AfterBeginDocument + { \cs_new:Npn \AfterBeginDocument #1 {#1} } + } + \AfterBeginDocument + { + \AdaptNote \footnote \multfootnote + \AdaptNoteMark \footnotemark + \cs_if_exist:NT \footref + { \AdaptNoteNoOptNoMult \footref } + \fnpct_new:NN \innernote \fnpct_inner_footnote:w + %% the `endnotes' package: + \fnpct_treatment:nn {endnotes} + { + \AdaptNote \endnote \multendnote + \AdaptNoteMark \endnotemark + } + %% the `enotez' package: + \fnpct_treatment:nn {enotez} + { \AdaptNote \endnote \multendnote } + %% the `snotez' package: + \fnpct_treatment:nn {snotez} + { + \legacy_if:nTF {snotez@dblarg} + { \AdaptNoteOpt \sidenote \multsidenote } + { \AdaptSnotez \sidenote \multsidenote } + \AdaptNoteMark \sidenotemark + } + %% the `parnotes' package: + \fnpct_treatment:nn {parnotes} + { \AdaptNote \parnote \multparnote } + %% the `pagenote' package: + \fnpct_treatment:nn {pagenote} + { + \bool_if:NTF \l__fnpct_makepagenote_bool + { \AdaptNote \pagenote \multpagenote } + { \msg_warning:nn {fnpct} {pagenote} } + } + %% the `tablefootnote' package: + \fnpct_treatment:nn {tablefootnote} + { \AdaptNote \tablefootnote \multtablefootnote } + %% the `manyfoot' package (also loaded by `bigfoot'): + \fnpct_treatment:nn {manyfoot} + { + \__fnpct_get_fnclasses:NN \MFL@list \l__fnpct_footnote_class_seq + \seq_map_inline:Nn \l__fnpct_footnote_class_seq + { + \str_if_eq:nnTF {#1} {default} + { + \cs_if_exist:NT \footnotedefault + { + \fnpct_renew_and_mult:ccc {footnote#1} + {fnpct_orig_footnote#1:w} + {multfootnote#1} + \fnpct_renew_mark:cc {footnotemark#1} + {fnpct_orig_footnotemark#1:w} + } + } + { + \fnpct_renew_and_mult:ccc {footnote#1} + {fnpct_orig_footnote#1:w} + {multfootnote#1} + \fnpct_renew_mark:cc {footnotemark#1} + {fnpct_orig_footnotemark#1:w} + } + } + } + %% the `bigfoot' package: + \fnpct_special_treatment:nn {bigfoot} + { + \cs_if_exist:NT \footnotedefault + { + % re-set basics: + \cs_set_eq:NN \footnote \footnotedefault + \cs_set_eq:NN \footnotemark \footnotemarkdefault + \cs_set_eq:NN \multfootnote \multfootnotedefault + } + } + %% the `fixfoot' package: + \fnpct_treatment:nn {fixfoot} + { + \prop_map_inline:Nn \l__fnpct_footnote_fixfoot_prop + { \fnpct_renew_no_arg:cc {#2} {fnpct_orig_fix_#2:w} } + } + %% the `sepfootnotes' package: + \fnpct_treatment:nn {sepfootnotes} + { + \prop_map_inline:Nn \l__fnpct_sepfootnote_foot_classes_prop + { + \fnpct_renew_and_mult_no_opt:ccc {#2note} + {fnpct_orig_sep_#2:w} {#2multnote} + \fnpct_renew_and_mult_no_opt:ccc {#2quicknote} + {fnpct_orig_sep_#2_quick:w} {#2multquicknote} + \fnpct_renew_no_opt:cc {#2notemark} {fnpct_orig_sep_#2_mark:w} + } + \prop_map_inline:Nn \l__fnpct_sepfootnote_end_classes_prop + { + \fnpct_renew_and_mult_no_opt:ccc {#2note} + {fnpct_orig_sep_#2:w} {#2multnote} + \fnpct_renew_no_opt:cc {#2notemark} {fnpct_orig_sep_#2_mark:w} + } + } + } + } + +% `fixfoot' package +\fnpct_special_treatment:nn {fixfoot} + { + % hook into \DeclareFixedFootnote so we can redefine all footnote + % classes defined be users + \cs_new_eq:NN \fnpct_new_fixnote:w \DeclareFixedFootnote + \RenewDocumentCommand \DeclareFixedFootnote {smm} + { + \prop_put:Nnx \l__fnpct_footnote_fixfoot_prop {#2} + { \cs_to_str:N #2 } + \IfBooleanTF {#1} + { \fnpct_new_fixnote:w * {#2} {#3} } + { \fnpct_new_fixnote:w {#2} {#3} } + } + } + +% `pagenote' package: +\fnpct_special_treatment:nn {pagenote} + { + \tl_put_left:Nn \makepagenote + { \bool_set_true:N \l__fnpct_makepagenote_bool } + } + +% `sepfootnotes' package: +\fnpct_special_treatment:nn {sepfootnotes} + { + \cs_new_eq:NN \fnpct_orig_new_footnotes:w \newfootnotes + \cs_new_eq:NN \fnpct_orig_new_endnotes:n \newendnotes + \cs_new_eq:NN \fnpct_orig_new_symbolnotes:w \newsymbolfootnotes + \RenewDocumentCommand \newfootnotes {sm} + { + \prop_put:Nnn \l__fnpct_sepfootnote_foot_classes_prop {#2} {#2} + \IfBooleanTF {#1} + { \fnpct_orig_new_footnotes:w * {#2} } + { \fnpct_orig_new_footnotes:w {#2} } + } + \RenewDocumentCommand \newendnotes {m} + { + \prop_put:Nnn \l__fnpct_sepfootnote_end_classes_prop {#1} {#1} + \fnpct_orig_new_endnotes:n {#1} + } + \RenewDocumentCommand \newsymbolfootnotes {om} + { + \prop_put:Nnn \l__fnpct_sepfootnote_symbol_classes_prop {#2} {#2} + \IfNoValueTF {#1} + { \fnpct_orig_new_symbolnotes:w {#2} } + { \fnpct_orig_new_symbolnotes:w [#1] {#2} } + } + } + +% -------------------------------------------------------------------------- +\RequirePackage{translations} +\AtBeginDocument{ + \ifcurrentbaselanguage{French} + { + \AfterBeginDocument{ + \cs_if_exist:NT \@footnotemarkORI + { + \let\@footnotemark\@footnotemarkORI + \setfnpct{ + before-footnote-space = + \l__fnpct_french_before_footnote_space_dim + } + } + } + }{} +} + +% -------------------------------------------------------------------------- +% SETUP COMMAND: +\NewDocumentCommand \setfnpct {m} + { \keys_set:nn {fnpct} {#1} } + +\file_input_stop: diff --git a/macros/latex/contrib/fnpct/fnpct-manual.cls b/macros/latex/contrib/fnpct/fnpct-manual.cls index 95cfab1a77..05355a28b4 100644 --- a/macros/latex/contrib/fnpct/fnpct-manual.cls +++ b/macros/latex/contrib/fnpct/fnpct-manual.cls @@ -23,7 +23,7 @@ % The Current Maintainer of this work is Clemens Niederberger. % -------------------------------------------------------------------------- \RequirePackage[multiple]{fnpct} -\ProvidesClass{fnpct-manual}[2022/02/03] +\ProvidesClass{fnpct-manual}[2022/02/27] \LoadClass[load-preamble,add-index]{cnltx-doc} \RequirePackage{imakeidx} @@ -75,7 +75,8 @@ thempfootnote } , makeindex-setup = {options={-s cnltx.ist},columns=3,columnsep=1em} , - index-setup = {othercode=\footnotesize,level=\addsec} + index-setup = {othercode=\footnotesize,level=\addsec}, + quote-author-format = \upshape } \RequirePackage{array,booktabs} @@ -330,5 +331,6 @@ \fnpct@add@version{2022-01-04}{1.0a} \fnpct@add@version{2022-01-29}{1.0b} \fnpct@add@version{2022-02-03}{1.1} +\fnpct@add@version{2022-02-27}{1.1a} \endinput diff --git a/macros/latex/contrib/fnpct/fnpct-manual.pdf b/macros/latex/contrib/fnpct/fnpct-manual.pdf index bd6098e43f..37670e195e 100644 Binary files a/macros/latex/contrib/fnpct/fnpct-manual.pdf and b/macros/latex/contrib/fnpct/fnpct-manual.pdf differ diff --git a/macros/latex/contrib/fnpct/fnpct-manual.tex b/macros/latex/contrib/fnpct/fnpct-manual.tex index 99968777c7..674b0e293f 100644 --- a/macros/latex/contrib/fnpct/fnpct-manual.tex +++ b/macros/latex/contrib/fnpct/fnpct-manual.tex @@ -37,10 +37,14 @@ before-footnote-space = 0.05em } +\usepackage[biblatex]{embrac} +\ChangeEmph{[}[,.02em]{]}[.055em,-.08em] +\ChangeEmph{(}[-.01em,.04em]{)}[.04em,-.05em] + \addbibresource{cnltx.bib} \addbibresource{\jobname.bib} \addbibresource{biblatex-examples.bib} -\begin{filecontents*}{\jobname.bib} +\begin{filecontents*}[overwrite]{\jobname.bib} @book{bringhurst04, title = {The Elements of Typographic Style}, author = {Robert Bringhurst}, @@ -49,6 +53,14 @@ isbn = {978-0-88179-205-5}, publisher = {Hartley \&\ Marks, Canada} } +@online{tex.sx:56094, + title = {Is there a way to automatically change kerning between + commas/full stops and footnote marks?} , + author = {Christian} , + date = {2012-05-16} , + url = {https://tex.stackexchange.com/q/56094/5049} , + visited = {2022-03-27} +} \end{filecontents*} \AdaptNote\footcite{m}{#NOTE{#1}} @@ -76,7 +88,9 @@ try to add it again to \fnpct. \par Please read this manual carefully so you detect all changes. \par \emph{I am sorry for the inconvenience but I am convinced that the new - syntax is more powerful and more flexible in the long run.} + syntax is more powerful and more flexible in the long run.} \par + You can fall back to the last version~0 by saying + \cs*{usepackage}\Marg{fnpct}\Oarg{=v0}. \end{bewareofthedog} \section{License} @@ -89,13 +103,13 @@ superscripts. This is not appropriate for all superscripts. Symbols must be handled differently than numbers. And of course the amount depends on the chosen font. \bringhurst\ says in \citetitle{bringhurst04}: -\begin{cnltxquote}[\emph{\citetitle{bringhurst04}} \cite{bringhurst04}] +\begin{cnltxquote}[\citetitle{bringhurst04} \emph{\cite{bringhurst04}}] Superscripts frequently come at the ends of phrases or sentences. If they are high above the line, they can be kerned over a comma or period, but this may endanger readability, especially if the text is set in a modest size. \end{cnltxquote} -\fnpct\ can not make these decisions for you. It sets some initial values for +\fnpct\ cannot make these decisions for you. It sets some initial values for the comma and the full stop which looked good to me with the tested fonts. Additionally it kerns the superscripts away from words when it follows directly. The amounts of the kerning can be changed using options. @@ -103,7 +117,10 @@ directly. The amounts of the kerning can be changed using options. \fnpct\ also switches the order of the superscript and the following comma or full stop. Additional punctuation marks can be added to the switching behavior and the amount of kerning can be set for each punctuation mark -individually. This behavior can also be turned off. +individually. This behavior can be turned off. + +The package has been inspired by a question on the Q\&A site +\url{tex.stackexchange.com}~\cite{tex.sx:56094}. \subsection{New Behavior of \cs*{footnote}} \subsubsection{Interaction With Punctuation} @@ -485,7 +502,6 @@ way\footnote{Using \cs*{@mpfn} as counter name is essential to make ranges \AdaptNote\footnote{o+m}[\@mpfn]{\IfNoValueTF{#1}{#NOTE{#2}}{#NOTE[#1]{#2}}} \AdaptNote\footnotemark{o}{\IfNoValueTF{#1}{#NOTE}{#NOTE[#1]}} \MultVariant\footnote - % KOMA-Script's or memoir's \footref: \AdaptNote\footref{m}{#NOTE{#1}} \end{sourcecode} You essentially have to rebuild the syntax of the original command and place diff --git a/macros/latex/contrib/fnpct/fnpct.sty b/macros/latex/contrib/fnpct/fnpct.sty index 175aa7c43f..d939f0a879 100644 --- a/macros/latex/contrib/fnpct/fnpct.sty +++ b/macros/latex/contrib/fnpct/fnpct.sty @@ -25,12 +25,14 @@ \RequirePackage {l3keys2e} \ExplSyntaxOn +\DeclareRelease {v0} {2019-10-05} {fnpct-2019-10-05.sty} + \DeclareHookRule {begindocument} {fnpct} {after} {hyperref} -\tl_const:Nn \c_fnpct_date_tl {2022/02/03} +\tl_const:Nn \c_fnpct_date_tl {2022/02/27} \tl_const:Nn \c_fnpct_version_major_number_tl {1} \tl_const:Nn \c_fnpct_version_minor_number_tl {1} -\tl_const:Nn \c_fnpct_version_subrelease_tl {} +\tl_const:Nn \c_fnpct_version_subrelease_tl {a} \tl_const:Nx \c_fnpct_version_number_tl { \c_fnpct_version_major_number_tl . @@ -49,6 +51,8 @@ {\c_fnpct_version_tl} {\c_fnpct_info_tl} +\DeclareCurrentRelease {v1} {\c_fnpct_date_tl} + % -------------------------------------------------------------------------- % scratch variables and variants of kernel functions: \tl_new:N \l__fnpct_tmpa_tl @@ -481,21 +485,9 @@ \cs_new_protected:Npn \fnpct_save_note_command:N #1 { \cs_undefine:c {fnpct_original_ \__fnpct_remove_backslash:N #1 :w} - \cs_if_exist:cTF { \__fnpct_remove_backslash:N #1 ~ code } - {% xparse command - \cs_new_eq:cc - { fnpct_original_ \__fnpct_remove_backslash:N #1 :w } - { \__fnpct_remove_backslash:N #1 ~ code } - } - { - \cs_if_exist:cTF { \__fnpct_remove_backslash:N #1 ~ } - {% robust command - \cs_new_eq:cc - { fnpct_original_ \__fnpct_remove_backslash:N #1 :w } - { \__fnpct_remove_backslash:N #1 ~ } - } - { \cs_new_eq:cN { fnpct_original_ \__fnpct_remove_backslash:N #1 :w } #1 } - } + \exp_args:Nc \DeclareCommandCopy + { fnpct_original_ \__fnpct_remove_backslash:N #1 :w } + #1 \seq_put_right:Nn \l__fnpct_adapted_commands_seq {#1} \fnpct_set_counter_name:Nx #1 { \__fnpct_remove_backslash:N #1 } } @@ -696,11 +688,11 @@ { \mode_if_horizontal:T { - \dim_compare:nNnTF \lastskip > {0pt} - { \unskip \fnpct_unspace: } + \dim_compare:nNnTF {\lastskip} > {0pt} + { \tex_unskip:D \fnpct_unspace: } { - \int_compare:nNnT \lastpenalty > {0pt} - { \unpenalty \fnpct_unspace: } + \int_compare:nNnT {\lastpenalty} > {0} + { \tex_unpenalty:D \fnpct_unspace: } } } } @@ -1092,8 +1084,8 @@ \fnpct_sepfootnote_new:n {#1} } } - -\hook_gput_code:nnn {begindocument} {fnpct} + +\hook_gput_code:nnn {begindocument/end} {fnpct} { \fnpct_if_package_loaded:nT {hyperref} { @@ -1130,9 +1122,7 @@ \fnpct_if_multiple:T { \MultVariant \footnote } % TODO: should we adapt \thanks? Not with memoir, though... % \AdaptNote \thanks {+m} { \cs_set_eq:NN \rlap \use:n #NOTE{#1} } - %% KOMA-Script and memoir: - \cs_if_exist:NT \footref - { \AdaptNote \footref {m} { #NOTE{#1} } } + \AdaptNote \footref {m} { #NOTE{#1} } %% snotez: \fnpct_treatment:nn {snotez} { @@ -1304,8 +1294,9 @@ } %% sepfootnotes \fnpct_treatment:nn {sepfootnotes} - { + { \cs_set:Nn \__fnpct_sep_mark:n {\footnotemark} + \AdaptNote \sepfootnote {m} [\@mpfn] {#NOTE{#1}} \seq_map_inline:Nn \l__fnpct_sepfootnotes_seq { \cs_if_eq:cNTF {#1notemark} \__fnpct_sep_mark:n @@ -1429,3 +1420,9 @@ tablefootnote see https://tex.stackexchange.com/questions/467561/ - new option `mult-variant-prefix' - new option `unspace' +2022/02/27 v1.1a - fix bug in \fnpct_unspace: + - fix bug in sepfootnotes adaption + - add package check file + - use \DeclareCommandCopy for saving the original note + commands + - use LaTeX's release mechanism -- cgit v1.2.3