summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/fnpct
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-02-28 03:02:40 +0000
committerNorbert Preining <norbert@preining.info>2022-02-28 03:02:40 +0000
commit7a8d1925127ad121a8f591db931524f9b8eacb93 (patch)
treedf5084184ea4d6732d6a9fae1d263b6915dbb36d /macros/latex/contrib/fnpct
parenta911d39178540078c8ff5bc880418478d7433c40 (diff)
CTAN sync 202202280302
Diffstat (limited to 'macros/latex/contrib/fnpct')
-rw-r--r--macros/latex/contrib/fnpct/README7
-rw-r--r--macros/latex/contrib/fnpct/fnpct-2019-10-05.sty1191
-rw-r--r--macros/latex/contrib/fnpct/fnpct-manual.cls6
-rw-r--r--macros/latex/contrib/fnpct/fnpct-manual.pdfbin509779 -> 494932 bytes
-rw-r--r--macros/latex/contrib/fnpct/fnpct-manual.tex28
-rw-r--r--macros/latex/contrib/fnpct/fnpct.sty51
6 files changed, 1245 insertions, 38 deletions
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[<mark>]{<text>} like commands
+% #1: old new name
+% #2: internal name of old definition
+% #3: mult-variant
+%
+% \footnote[<mark>]{<text>} 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{<text>} 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[<mark>]{<text>} 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[<mark>][<oarg>]{<text>} 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(<oarg>)[<mark>]{<text>} 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{<arg>} 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[<mark>] 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
--- a/macros/latex/contrib/fnpct/fnpct-manual.pdf
+++ b/macros/latex/contrib/fnpct/fnpct-manual.pdf
Binary files 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