% --------------------------------------------------------------------------
% 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: