% vim: ft=tex ts=2 sts=2 sw=2 et:
\NeedsTeXFormat{LaTeX2e}

\ProvidesExplClass{note}{2023/07/15}{1.0}{Note}


%%% Class

\RequirePackage { l3keys2e }
\LoadClass [ english, french, 11pt ] { article }


%%% Error messages

% https://github.com/latex3/latex3/issues/887
\prop_gput:Nnn \g_msg_module_type_prop { note } { Class }

\msg_new:nnn { note } { Not~LuaLaTeX }
  { Please ~ use ~ LuaLaTeX. }


%%% Constants

%% Dimensions

% Height of the page header
\dim_const:Nn \c__note_head_height_dim { 6.5mm }

% Spacing between logos in the page header
\dim_const:Nn \c__note_logos_sep_dim
  { \c__note_head_height_dim / 2}

% Spacing between the page header and body
\dim_const:Nn \c__note_head_sep_dim { 8.5mm }

% Skip between the page footer and body
\dim_const:Nn \c__note_foot_skip_dim
  { \c__note_head_height_dim + \c__note_head_sep_dim }

% Margin around {body + footer + header}
\dim_const:Nn \c__note_margin_dim { 33mm }

% Left margin of list items
\dim_const:Nn \c__note_list_left_margin_dim
  { 8.5mm }

%% Skips

% Spacing between heading number and text
\skip_const:Nn \c__note_heading_sep_skip { .5em }

% Spacing between list item and label
\skip_const:Nn \c__note_list_label_sep_skip
  { \c__note_heading_sep_skip }

% Parskip
\skip_const:Nn \c__note_par_skip
  { 9pt plus 3pt minus 2pt }

% Parindent
\skip_const:Nn \c__note_par_indent_skip { 0pt }

% Section
\skip_const:Nn \c__note_section_skip
  { ( \c__note_par_skip * 200 ) / 100 }

% Subsection
\skip_const:Nn \c__note_subsection_skip
  { ( \c__note_par_skip * 160 ) / 100 }

% Subsubsection
\skip_const:Nn \c__note_subsubsection_skip
  { ( \c__note_par_skip * 130 ) / 100 }

% Total spacing between successive list items
\skip_const:Nn \c__note_list_total_item_sep_skip
  { \c__note_par_skip / 2 }

% Spacing between paragraphs inside a single list item
\skip_const:Nn \c__note_list_par_sep_skip
  { \c__note_par_skip / 4 }

% Spacing between footnote mark and text
\skip_const:Nn \c__note_footnote_mark_sep_skip
  { \c__note_par_skip / 4 }

%% Strings

% Separator between title and subtitle in PDF infos
\str_const:Nn \c__note_title_sep_str { ~ — ~ }


%%% Declarations

\tl_new:N \g__note_subtitle_tl
\tl_new:N \g__note_date_tl
\tl_new:N \g__note_author_tl
\tl_new:N \g__note_reference_tl
\tl_new:N \g__note_place_tl
\tl_new:N \g__note_sender_title_tl
\tl_new:N \g__note_recipient_title_tl
\tl_new:N \g__note_plaintiff_tl
\tl_new:N \g__note_defendant_tl
\tl_new:N \g__note_court_prefix_tl
\tl_new:N \g__note_court_tl
\tl_new:N \l__note_meta_title_tl
\tl_new:N \l__note_meta_author_tl
\tl_new:N \l__note_sigs_flush_tl

\seq_new:N \g__note_logos_url_seq
\seq_new:N \g__note_logos_seq
\seq_new:N \g__note_sigs_name_seq
\seq_new:N \g__note_sigs_title_seq
\seq_new:N \g__note_sender_addr_seq
\seq_new:N \g__note_recipient_addr_seq

\int_new:N \g__note_logos_map_int
\int_new:N \g__note_sigs_map_int

\box_new:N \l__note_logos_box
\box_new:N \l__note_date_box

\bool_new:N \g__note_show_head_bool


%%% Common variants

\cs_generate_variant:Nn \exp_args:Nnnx { cnnx }
\cs_generate_variant:Nn \exp_args:Nnnn { cnnn }


%%% Basic checks

\sys_if_engine_luatex:F
  { \msg_fatal:nn { note } { Not ~ LuaLaTeX } }


%%% Options

\keys_define:nn { note/options }
  {
    nm .str_set:N  = \g__note_mode_str,
    nm .default:n  = { note },
  }

\ProcessKeysOptions { note/options }

\str_if_eq:VnF \g__note_mode_str { note }
  {
    \bool_gset_false:N \g__note_show_head_bool
  }


%%% Packages

\RequirePackage { fontspec }
\RequirePackage { xparse }
\RequirePackage { etl }
\RequirePackage [ latin, english, french ] { babel }
\RequirePackage [ babel ] { csquotes }
\RequirePackage { enumitem }
\RequirePackage { fancyhdr }
\RequirePackage [ explicit ] { titlesec }
\RequirePackage [ svgnames ] { xcolor }
\RequirePackage { graphicx }
\RequirePackage { acro }
\RequirePackage { geometry }
\RequirePackage { parskip }
\RequirePackage { tabularx }
\RequirePackage { siunitx }
\RequirePackage { booktabs }
\RequirePackage [ avoid-all ] { widows-and-orphans }
\RequirePackage [ babel = true ] { microtype }
\RequirePackage { hyperref }


%%% Colors

\definecolor { note/red } { HTML } { cd1e27 }
\definecolor { note/dark-blue } { HTML } { 44589f } %4e5368 }
\definecolor { note/light-blue } { HTML } { 729fcf }


%%% Geometry

\geometry
  {
    %showframe,
    centering,
    a4paper,
    headheight = \c__note_head_height_dim,
    headsep = \c__note_head_sep_dim,
    footskip = \c__note_foot_skip_dim,
    margin = \c__note_margin_dim,
    includehead,
    includefoot,
  }

\bool_if:NF \g__note_show_head_bool
  {
    \geometry
      {
        headheight = 0pt,
        headsep = 0pt,
      }
  }


%%% Paragraphs

\skip_set_eq:NN \parindent \c__note_par_indent_skip
\skip_set_eq:NN \parskip \c__note_par_skip


%%% Babel

\AddBabelHook { * } { foreign }
  { \em }

\frenchsetup
  {
    ListItemsAsPar  = true,
    FrenchFootnotes = true,
  }


%%% Lists

% TODO fix the skip v. dim mess
\SetEnumitemKey { note/spacing }
  {
    itemsep       =
      \skip_eval:n
        {
          \c__note_list_total_item_sep_skip
          - \c__note_list_par_sep_skip
        },
    parsep        = \skip_use:N \c__note_list_par_sep_skip,
    topsep        = 0pt,
    itemindent    = 0pt,
    listparindent = 0pt,
    leftmargin    = \skip_use:N \c__note_list_left_margin_dim,
    labelsep      = \skip_use:N \c__note_list_label_sep_skip,
  }

\setlist [ enumerate ] { note/spacing }

\setlist [ enumerate, 1 ]
  {
    label = \textcolor { note/dark-blue } { \sffamily \arabic*. },
  }

\setlist [ itemize ] { note/spacing }

\setlist [ itemize, 1 ]
  {
    label = \textcolor { note/dark-blue } { \sffamily \textbullet },
  }


%%% Hyperref

\hypersetup
  {
    colorlinks,
    urlcolor  = RoyalBlue,
    linkcolor = note/red ! 80 ! black, %VioletRed,
  }

\AddToHook { begindocument/before }
  {
    \group_begin:
    \tl_set:Nn \l__note_meta_title_tl
      {
        \@title
        \tl_if_empty:NF \g__note_subtitle_tl
          {
            \str_use:N \c__note_title_sep_str
            \tl_use:N \g__note_subtitle_tl
          }
      }
    \tl_set:Nx \l__note_meta_author_tl
      {
        \tl_if_empty:NTF \g__note_author_tl
          { \seq_use:Nn \g__note_sigs_name_seq { , ~ } }
          { \g__note_author_tl }
      }
    \hypersetup
      {
        pdftitle = { \tl_use:N \l__note_meta_title_tl },
        pdfauthor = { \tl_use:N \l__note_meta_author_tl },
      }
    \group_end:
  }


%%% Headings

\setcounter { secnumdepth } { 5 }

%% Section

\str_if_eq:VnT \g__note_mode_str { brief }
  {
    \cs_gset_eq:NN \sectionbreak \clearpage
  }

\titleformat { \section }
  [ block ]
  {
    %\str_if_eq:VnT \g__note_mode_str { brief }
    %  { \centering }
    \sffamily \Large \bfseries
    \color { note/dark-blue }
  }
  { \Roman { section } . }
  { \skip_use:N \c__note_heading_sep_skip }
  {#1}

%\titlespacing \section
%  { 0pt }
%  { \skip_use:N \c__note_section_skip }
%  { \skip_use:N \c__note_section_skip }

\tl_gset:Nn \thesection
  { \Roman { section } }

%% Subsection

\titleformat { \subsection }
  [ block ]
  {
    \sffamily \large \bfseries
    \color { note/dark-blue }
  }
  { \Alph { subsection } . }
  { \skip_use:N \c__note_heading_sep_skip }
  {#1}

%\titlespacing \subsection
%  { 0pt }
%  { \skip_use:N \c__note_subsection_skip }
%  { \skip_use:N \c__note_subsection_skip }

\tl_gset:Nn \thesubsection
  { \thesection . \Alph { subsection } }

%% Subsubsection

\titleformat { \subsubsection }
  [ block ]
  {
    \sffamily \normalsize \bfseries
    \color { note/dark-blue }
  }
  { \arabic { subsubsection } . }
  { \skip_use:N \c__note_heading_sep_skip }
  {#1}

%\titlespacing \subsubsection
%  { 0pt }
%  { \skip_use:N \c__note_subsubsection_skip }
%  { \skip_use:N \c__note_subsubsection_skip }

\tl_gset:Nn \thesubsubsection
  { \thesubsection . \arabic { subsubsection } }

%% Paragraph

\titleformat { \paragraph }
  [ runin ]
  {
    \sffamily \normalsize %\bfseries
    \color { note/dark-blue }
  }
  {}
  { 0pt }
  %{ \alph { paragraph } . }
  %{ \skip_use:N \c__note_heading_sep_skip }
  {#1}

\titlespacing \paragraph
  { 0pt }
  { \skip_use:N \c__note_par_skip }
  { \skip_use:N \c__note_heading_sep_skip }


%%% Fonts

\setmainfont { Libertinus Serif }
\setsansfont { Libertinus Sans }
\setmonofont { Fira Mono }
  [ Scale = 0.84 ]


%%% Siunitx

% TODO babel
\sisetup
  {
    detect-all,
    locale = FR,
  }

\DeclareSIUnit \euro {€}


%%% Quotes FIXME

\cs_set:Npn \mktextquote #1#2#3#4#5#6
  { #1 { \em #2 } #3 #6 #4 #5 }

\cs_set:Npn \mktextins #1
  { { \em [ #1 ] } }

\cs_set:Npn \mkblockquote #1#2#3#4
  {
    \openautoquote { \em #1 } \closeautoquote #2 #4 #3
  }

\cs_set:Npn \mktextelp
  { \mktextins { ... } }

\NewDocumentEnvironment { block } {}
  {
    \group_begin:
    \begin { list } {}
      {
        \setlength{\topsep}{0pt}
        \setlength{\leftmargin}{4.25mm}
        \setlength{\rightmargin}{0pt}
        \setlength{\listparindent}{\parindent}
        \setlength{\itemindent}{\parindent}
        \setlength{\parsep}{\parskip}
        \@beginparpenalty=10000
      }
    \item[]
  }
  {
    \end { list }
    \group_end:
  }

\SetBlockEnvironment { block }

\DeclareQuoteStyle [ guillemets ] { french }
  [ \initfrenchquotes ]
  { \mkfrenchopenquote { \guillemotleft } }
  [ { \em \mkfrenchopenquote { \guillemotleft } } ]
  { \mkfrenchclosequote { \guillemotright } }
  { \mkfrenchopenquote { \textquotedblleft } }
  [ { \em \mkfrenchopenquote { \textquotedblleft } } ]
  { \mkfrenchclosequote { \textquotedblright } }


%%% Headers and footers

\cs_new:Nn \__note_logos_map_indexed_inline:n
  {
    \int_gincr:N \g__note_logos_map_int
    \cs_gset:cn
      { __note_logos_map_ \int_use:N \g__note_logos_map_int :nnn }
      { #1 }
    \seq_map_indexed_inline:Nn \g__note_logos_seq
      {
        \exp_args:cnnx
          { __note_logos_map_ \int_use:N \g__note_logos_map_int :nnn }
          {##1} % index
          {##2} % image path
          { \seq_item:Nn \g__note_logos_url_seq {##1} } % url
      }
  }

\cs_new:Nn \__note_logos_include:nn
  {
    \__note_logos_map_indexed_inline:n
      {
        \int_compare:nNnT {##1} > {1}
          { \skip_horizontal:n {#2} }
        \tl_if_empty:nF {##3}
          { \href {##3} }
        { \includegraphics [ height = #1 ] {##2} }
      }
  }

\fancypagestyle { fancyplain }
  {
    \fancyhf {}
    \bool_if:NT \g__note_show_head_bool
      {
        % TODO l3box
        \fancyhead [R]
          {
            \parbox [] [ \headheight ] [c] { .5 \textwidth }
              {
                \raggedleft \sffamily
                \tl_if_empty:NTF \g__note_date_tl
                  { \today }
                  { \tl_use:N \g__note_date_tl }
              }
          }
        \fancyhead [L]
          {
            \parbox [] [ \headheight ] [c] { .5 \textwidth }
              {
                \__note_logos_include:nn
                  { \c__note_head_height_dim }
                  { \c__note_logos_sep_dim }
              }
          }
      }
    \fancyfoot [C] { \sffamily \thepage }
    \tl_set:Nn \headrulewidth { 0pt }
    \tl_set:Nn \footrulewidth { 0pt }
  }

\pagestyle { fancyplain }


%%% Preamble

\cs_new:Nn \__note_undef_begin:N
  {
    \AddToHook { begindocument/before }
      { \cs_undefine:N #1 }
  }

\DeclareDocumentCommand \author {m}
  { \tl_set:Nn \g__note_author_tl {#1} }

\__note_undef_begin:N \author

\DeclareDocumentCommand \reference {m}
  { \tl_set:Nn \g__note_reference_tl {#1} }

\__note_undef_begin:N \reference

\NewDocumentCommand \subtitle {m}
  { \tl_set:Nn \g__note_subtitle_tl {#1} }

\__note_undef_begin:N \subtitle

\NewDocumentCommand \place {m}
  { \tl_set:Nn \g__note_place_tl {#1} }

\__note_undef_begin:N \place

\NewDocumentCommand \plaintiff {m}
  { \tl_set:Nn \g__note_plaintiff_tl {#1} }

\__note_undef_begin:N \plaintiff

\NewDocumentCommand \defendant {m}
  { \tl_set:Nn \g__note_defendant_tl {#1} }

\__note_undef_begin:N \defendant

\NewDocumentCommand \court {O{}m}
  {
    \tl_set:Nn \g__note_court_prefix_tl {#1}
    \tl_set:Nn \g__note_court_tl {#2}
  }

\__note_undef_begin:N \court

\DeclareDocumentCommand \date {m}
  { \tl_set:Nn \g__note_date_tl {#1} }

\__note_undef_begin:N \date

\NewDocumentCommand \addlogo {O{}m}
  {
    \seq_put_right:Nn \g__note_logos_url_seq {#1}
    \seq_put_right:Nn \g__note_logos_seq {#2}
  }

\__note_undef_begin:N \addlogo

\cs_new:Nn \__note_sender_addr_add:n
  { \seq_put_right:Nn \g__note_sender_addr_seq {#1} }

\cs_new:Nn \__note_recipient_addr_add:n
  { \seq_put_right:Nn \g__note_recipient_addr_seq {#1} }

\NewDocumentCommand \sender {m>{\SplitList{,}}m}
  {
    \tl_set:Nn \g__note_sender_title_tl {#1}
    \ProcessList {#2} { \__note_sender_addr_add:n }
  }

\__note_undef_begin:N \sender

\NewDocumentCommand \recipient {m>{\SplitList{,}}m}
  {
    \tl_set:Nn \g__note_recipient_title_tl {#1}
    \ProcessList {#2} { \__note_recipient_addr_add:n }
  }

\__note_undef_begin:N \recipient

%%% Titlepage

\cs_new:Nn \__note_title_note_show:
  {
    \begin { center }
      \vspace* { 2.65em }
      {
        \sffamily \LARGE \bfseries
        \color { note/dark-blue }
        \@title
      }
      \tl_if_empty:NF \g__note_subtitle_tl
        {
          \par
          \sffamily \Large
          \tl_use:N \g__note_subtitle_tl
        }
      \vspace* { 2.65em }
    \end { center }
  }

\cs_new:Nn \__note_title_letter_show:
  {
    \begin { flushleft }
      \parbox { .40 \textwidth }
        {
          \flushleft \sffamily
          \textbf { \tl_use:N \g__note_sender_title_tl }
          \vspace* {.25em}
          \par \seq_use:Nn \g__note_sender_addr_seq { \\ }
        }
    \end { flushleft }
    \vspace* { 1em }
    \begin { flushright }
      \parbox { .45 \textwidth }
        {
          \flushleft \sffamily
          \textbf { \tl_use:N \g__note_recipient_title_tl }
          \vspace* {.25em}
          \par \seq_use:Nn \g__note_recipient_addr_seq { \\ }
        }
    \end { flushright }
    \vspace* { 2em }
    \begin {flushright}
    \parbox { .45 \textwidth }
      {
        \flushleft \sffamily
        \tl_if_empty:NTF \g__note_place_tl
          { Le ~ }
          { \tl_use:N \g__note_place_tl , ~ le ~ }
        \tl_if_empty:NTF \g__note_date_tl
          { \today }
          { \tl_use:N \g__note_date_tl }
      }
    \end { flushright }
    \vspace* { 4.5em }
    \group_begin:
      \sffamily
      \textcolor { note/dark-blue } { \bfseries Objet ~ : }
      \hspace { 1em }
      \@title \par
      \tl_if_empty:NF \g__note_reference_tl
        {
          \textcolor { note/dark-blue } { \bfseries Réf. ~ : }
          \hspace { 1em }
          \tl_use:N \g__note_reference_tl
        }
    \group_end:
    \vspace*{1.5em}
  }

\cs_new:Nn \__note_title_brief_show:
  {
    \pagenumbering { Alph }
    \begin { titlepage }
      \vspace* { 13.5mm }
      \begin { flushleft }
        \begin { minipage } { .8 \textwidth }
          \begin { flushleft }
            \color { note/dark-blue }
            \sffamily \bfseries \Huge \@title
          \end { flushleft }
          \tl_if_empty:NF \g__note_reference_tl
            {
              \vspace* { 2.5mm }
              \begin { flushleft }
                \LARGE \normalfont \sffamily
                Dossier ~ \no \g__note_reference_tl
              \end { flushleft }
            }
        \end { minipage }
      \end { flushleft }
      \vspace { 12.5mm }
      \begin { flushright }
        \tl_if_empty:NF \g__note_court_prefix_tl
          {
            \sffamily \large \g__note_court_prefix_tl
            \par
          }
        \LARGE \g__note_court_tl
      \end { flushright }
      \vspace { \fill }
      \begin { center }
          \color { note/dark-blue }
          \sffamily \bfseries \Large Pour
          \vspace* { 2.5mm }
      \end { center }
      \begin { center }
        \begin { minipage } { .8 \textwidth }
          \large \sffamily \g__note_plaintiff_tl
        \end { minipage }
      \end { center }
      \vspace { 11.5mm }
      \begin { center }
          \color { note/dark-blue }
          \sffamily \bfseries \Large Contre
          \vspace* { 2.5mm }
      \end { center }
      \begin { center }
        \begin { minipage } { .8  \textwidth }
          \large \sffamily \g__note_defendant_tl
        \end { minipage }
      \end { center }
      \vspace* { 13.5mm }
    \end { titlepage }
    \pagenumbering { arabic }
  }

\DeclareDocumentCommand \maketitle {}
  {
    \str_case:VnF \g__note_mode_str
      {
        { letter } { \__note_title_letter_show: }
        { brief } { \__note_title_brief_show: }
      }
      { \__note_title_note_show: }
  }


%%% Mail

\NewDocumentCommand \email {m}
  { \href { mailto \c_colon_str #1 } { #1 } }


%%% Eur-Lex

\cs_new:Nn \__note_eurlex_lang:N
  {
    \str_case:VnF #1
      {
        { french } { FR }
      }
      { EN }
  }

\cs_new:Nn \__note_eurlex_uri:Nn
  {
    % https://tex.stackexchange.com/q/384826
    https \c_colon_str //eur-lex.europa.eu/legal-content/
    \__note_eurlex_lang:N #1 /TXT/?uri = #2
  }

\NewDocumentCommand \eurlex {mm}
  {
    \href
      { \__note_eurlex_uri:Nn \languagename {#1} }
      {#2}
  }


%%% JORF

\cs_new:Nn \__note_jorf_uri:n
  { https \c_colon_str //www.legifrance.gouv.fr/jorf/id/ #1 }

\NewDocumentCommand \jorf {mm}
  {
    \href
      { \__note_jorf_uri:n {#1} }
      {#2}
  }


%%% BOFiP

% TODO date
\cs_new:Nn \__note_bofip_uri:n
  { https \c_colon_str //bofip.impots.gouv.fr/doctrine/ #1 }

\NewDocumentCommand \bofip {m}
  { \href { \__note_bofip_uri:n {#1} } {#1} }

%%% Articles

\DeclareExpandableDocumentCommand \art {m}
  {
    \texorpdfstring { \nolinebreak } {}
    \mbox {#1}
  }

\clist_map_inline:nn
  {
    bis, ter, quater, quinquies,
    sexies, septies, octies, nonies
  }
  {
    \exp_args:Nc \DeclareExpandableDocumentCommand {#1} {m}
      { \art { ##1 ~ \lat {#1} } }
  }

\DeclareExpandableDocumentCommand \para {m}
  { § \nobreakspace \mbox { #1 } }

\DeclareExpandableDocumentCommand \rn {m}
  { \art { \int_to_Roman:n {#1} } }

\DeclareExpandableDocumentCommand \ao {m}
  { \art { #1 \up { o } } }

\DeclareExpandableDocumentCommand \L {m}
  { \art { L. \, #1 } }

\DeclareExpandableDocumentCommand \R {m}
  { \art { R. \, #1 } }


%%% Names

\DeclareExpandableDocumentCommand \name {om}
  {
    \IfValueT {#1} { #1 ~ }
    \textsc {#2}
  }

\cs_new:Nn \__note_name_prefix_translate:n
  {
    \str_case:nnF {#1}
      {
        { m } { M. }
        { mm } { MM. }
        { mme } { M \up { me } }
        { mmes } { M \up { mes } }
        { me } { M \up { e } }
      }
      {#1}
  }

\clist_map_inline:nn { m, mm, mme, mmes }
  {
    \exp_args:Nc \DeclareExpandableDocumentCommand {#1} {om}
      {
        \__note_name_prefix_translate:n {#1}
        \nobreakspace
        \IfValueTF {##1}
          { \name [##1] {##2} }
          { \name {##2} }
      }
  }


%%% Todo

\NewDocumentCommand \todo {m}
  { \textcolor { note/red } { [ #1 ] } }


%%% Foreign language shortcuts

\NewExpandableDocumentCommand \en {m}
  { \foreignlanguage { english } {#1} }

\NewExpandableDocumentCommand \lat {m}
  { \foreignlanguage { latin } {#1} }


%%% End of page

\NewDocumentEnvironment { endofpage } {}
  { \vfill } % FIXME
  {}


%%% Footnotes

\AddToHook { begindocument }
  {
    \cs_gset:Npn \@makefntext #1
      {
        \textcolor { note/dark-blue } { \sffamily \@thefnmark . }
        \skip_horizontal:N \c__note_footnote_mark_sep_skip
        #1
      }
    % FIXME
    \cs_gset:Npn \footnoterule
      {
        \kern -3pt
        \textcolor { note/dark-blue }
          { \hrule height .75pt width .25  \textwidth }
        \vspace { .5em }
    }
    \cs_gset:Npn \@makefnmark
      { \hbox { \textsuperscript { \sffamily \@thefnmark } } }
  }


%%% Signatories

\cs_new:Nn \__note_sigs_add:nn
  {
    \seq_put_right:Nn \g__note_sigs_name_seq {#1}
    \seq_put_right:Nn \g__note_sigs_title_seq {#2}
  }

\cs_new:Nn \__note_sigs_map_indexed_inline:n
  {
    \int_gincr:N \g__note_sigs_map_int
    \cs_gset:cn
      { __note_sigs_map_ \int_use:N \g__note_sigs_map_int :nnn }
      { #1 }
    \seq_map_indexed_inline:Nn \g__note_sigs_name_seq
      {
        \exp_args:cnnx
          { __note_sigs_map_ \int_use:N \g__note_sigs_map_int :nnn }
          {##1} % index
          {##2} % name
          { \seq_item:Nn \g__note_sigs_title_seq {##1} } % title
      }
  }

\DeclareDocumentCommand \signature {O{}m}
  { \__note_sigs_add:nn {#2} {#1} }

\DeclareDocumentCommand \makesignatures {s}
  {
    \vspace* { 3em }
    \IfBooleanT {#1}
      {
        \tl_if_empty:NTF \g__note_place_tl
          { Le ~ }
          { Fait ~ à ~ \tl_use:N \g__note_place_tl , ~ le ~ }
        \tl_if_empty:NTF \g__note_date_tl
          { \today }
          { \tl_use:N \g__note_date_tl } .
        \vspace* { 1em }
      }
    \__note_sigs_map_indexed_inline:n
      {
        \group_begin:
          \tl_set:Nx \l__note_sigs_flush_tl
            {
              \int_compare:nNnTF { \int_mod:nn {##1} { 2 } } = { 1 }
                { flushright }
                { flushleft }
            }
          \begin { \tl_use:N \l__note_sigs_flush_tl }
            \parbox { .5 \textwidth }
              {
                \centering
                \textsc {##2}
                \tl_if_empty:nF {##3}
                  {
                    , \\
                    { \itshape ##3 }
                  }
              }
          \end { \tl_use:N \l__note_sigs_flush_tl }
        \group_end:
      }
  }

\DeclareDocumentCommand \opening {m}
  {
    #1
    \vspace { 1em }
  }

\DeclareDocumentCommand \closing {m}
  {
    \vspace { 1em }
    #1
  }

\flushbottom
