% \iffalse meta-comment
% A LaTeX Class for Semantic Lectures Slides (originally developed for Michael Kohlhase)
% Copyright (c) 2019 Michael Kohlhase, all rights reserved
%               this file is released under the
%               Gnu Library Public Licences (LGPL)
%
% The original of this file is in the public repository at 
% http://github.com/sLaTeX/sTeX/
% \fi
% 
% \iffalse
%
%<*driver>
\def\stexdocpath{../doc}
\input{\stexdocpath/stex-docheader}
\stextoptitle{NotesSlides -- Slides and Course Notes}{notesslides}
\docmodule
%</driver>
% \fi
% 
%
% \begin{stexmanual}
%    \begin{sfragment}{NotesSlides Manual}
	%      \input{\stexdocpath/packages/stex-notesslides}
%    \end{sfragment}
% \end{stexmanual}
%
% \begin{documentation}
%    \begin{sfragment}{NotesSlides Documentation}
%       TODO
%    \end{sfragment}
% \end{documentation}
%
%
% \begin{implementation}\label{pkg:notesslides:impl}
%
% \begin{sfragment}{Implementation: The notesslides Package} 
%
%\begin{sfragment}[id=sec:impl:init]{Class and Package Options}
%
% We define some Package Options and switches for the |notesslides| class and activate them
% by passing them on to |beamer.cls| and |omdoc.cls| and the |notesslides| package. We pass
% the |nontheorem| option to the |statements| package when we are not in notes mode, since
% the |beamer| package has its own (overlay-aware) theorem environments. 
%
%    \begin{macrocode}
%<*cls>
%<@@=notesslides>
\ProvidesExplClass{notesslides}{2023/10/13}{3.4.0}{notesslides Class}
\RequirePackage{l3keys2e}

\str_const:Nn \c_@@_class_str {article}

\keys_define:nn{notesslides / cls}{
  class   .str_set_x:N = \c_@@_class_str,
  notes   .bool_set:N  = \c_notesslides_notes_bool ,
  slides  .code:n      = { \bool_set_false:N \c_notesslides_notes_bool },
  %docopt  .str_set_x:N = \c_@@_docopt_str,
  unknown .code:n      = {
    \PassOptionsToClass{\CurrentOption}{beamer}
    \PassOptionsToClass{\CurrentOption}{\c_@@_class_str}
    \PassOptionsToPackage{\CurrentOption}{notesslides}
    \PassOptionsToPackage{\CurrentOption}{stex}
  }
}
\ProcessKeysOptions{ notesslides / cls }

\RequirePackage{stex}
\stex_if_html_backend:T {
  \bool_set_true:N\c_notesslides_notes_bool
}

\bool_if:NTF \c_notesslides_notes_bool {
  \PassOptionsToPackage{notes=true}{notesslides}
  \message{notesslides.cls:~Formatting~document~in~notes~mode}
}{
  \PassOptionsToPackage{notes=false}{notesslides}
  \message{notesslides.cls:~Formatting~document~in~slides~mode}
}

\bool_if:NTF \c_notesslides_notes_bool {
  \LoadClass{\c_@@_class_str}
}{
  \LoadClass[10pt,notheorems,xcolor={dvipsnames,svgnames}]{beamer}
  %\newcounter{Item}
  %\newcounter{paragraph}
  %\newcounter{subparagraph}
  %\newcounter{Hfootnote}
}
\RequirePackage{notesslides}
%</cls>
%    \end{macrocode}
% now we do the same for the |notesslides| package. 
%    \begin{macrocode}
%<*package>
\ProvidesExplPackage{notesslides}{2023/10/13}{3.4.0}{notesslides Package}
\RequirePackage{l3keys2e}

\keys_define:nn{notesslides / pkg}{
  notes           .bool_set:N   = \c_notesslides_notes_bool ,
  slides          .code:n       = { \bool_set_false:N \c_notesslides_notes_bool },
  sectocframes    .bool_set:N   = \c_notesslides_sectocframes_bool ,
  topsect         .str_set_x:N  = \c_notesslides_topsect_str,
  unknown         .code:n       = {
    \PassOptionsToPackage{\CurrentOption}{stex}
    \PassOptionsToPackage{\CurrentOption}{tikzinput}
  }
}
\ProcessKeysOptions{ notesslides / pkg }

\RequirePackage{stex}
\stex_if_html_backend:T {
  \bool_set_true:N\c_notesslides_notes_bool
}

\cs_set:Npn \sectiontitleemph #1 {
  \textbf{\Large #1}
}

\newif\ifnotes
\bool_if:NTF \c_notesslides_notes_bool {
  \notestrue
  \PassOptionsToPackage{usenames,dvipsnames,svgnames}{xcolor}
  \RequirePackage[noamsthm,hyperref]{beamerarticle}
  \RequirePackage{mdframed}
  \str_if_empty:NTF \c_notesslides_topsect_str{
    %\setsectionlevel{section}
  } {
    \exp_args:No \setsectionlevel \c_notesslides_topsect_str
  }
}{
  \notesfalse

  \cs_new_protected:Nn \_@@_do_sectocframes: {
    \cs_set_protected:Nn \_@@_do_label:n {
      \str_case:nnF{##1}{
        {part}    {
          \tl_set:Nx\l_@@_num{\thepart}
          \tl_set:cx{@ @ label}{
            \cs_if_exist:NTF\parttitlename{\exp_not:N\parttitlename}{\exp_not:N\partname}{}~\l_@@_num\\}
        }
        {chapter} {
          \tl_set:Nx\l_@@_num{\thechapter}
          \tl_set:cx{@ @ label}{
            \cs_if_exist:NTF\chaptertitlename{\exp_not:N\chaptertitlename}{\exp_not:N\chaptername}{}~\l_@@_num\\}
        }
        {section} {
          \tl_set:Nx\l_@@_num{\cs_if_exist:NT\thechapter{\thechapter.}\thesection}
          \tl_set:cx{@ @ label}{\l_@@_num\quad}
        }
        {subsection} {
          \tl_set:Nx\l_@@_num{\cs_if_exist:NT\thechapter{\thechapter.}\thesection.\thesubsection}
          \tl_set:cx{@ @ label}{\l_@@_num\quad}
        }
        {subsubsection} {
          \tl_set:Nx\l_@@_num{\cs_if_exist:NT\thechapter{\thechapter.}\thesection.\thesubsection.\thesubsubsection}
          \tl_set:cx{@ @ label}{\l_@@_num\quad}
        }
        {paragraph} {
          \tl_set:Nx\l_@@_num{\cs_if_exist:NT\thechapter{\thechapter.}\thesection.\thesubsection.\thesubsubsection.\theparagraph}
          \tl_set:cx{@ @ label}{\l_@@_num\quad}
        }
      }{
        \tl_set:Nx\l_@@_num{\cs_if_exist:NT\thechapter{\thechapter.}\thesection.\thesubsection.\thesubsubsection.\theparagraph.\thesubparagraph}
        \tl_set:cx{@ @ label}{\l_@@_num\quad}
      }
    }
    \cs_set_protected:Nn \_sfragment_do_level:nn {
      \tl_if_exist:cT{c@##1}{\stepcounter{##1}}
      \addcontentsline{toc}{##1}{\protect\numberline{\use:c{the##1}}##2}
      \_@@_do_label:n{##1}
      \pdfbookmark[\int_use:N \l_stex_docheader_sect]{\l_@@_num\ ##2}{##1.\l_@@_num}
      \begin{frame}[noframenumbering]
        \vfill\centering
        \sectiontitleemph{
          \use:c{@ @ label} ##2
        }
      \end{frame}
      \int_incr:N \l_stex_docheader_sect
      \tl_set:Nn \stex_current_section_level{##1}
    }
  }

  \AtBeginDocument{
    \str_if_empty:NTF \c_notesslides_topsect_str {
      \setsectionlevel{section}
    } {
      \exp_args:No \setsectionlevel \c_notesslides_topsect_str
      \exp_args:No \str_if_eq:nnTF \c_notesslides_topsect_str {chapter} {
        \_@@_define_chapter:
      }{
        \exp_args:No \str_if_eq:nnT \c_notesslides_topsect_str {part} {
          \_@@_define_chapter:
          \_@@_define_part:
        }
      }
    }
  }

  \bool_if:NT \c_notesslides_sectocframes_bool {
    \_@@_do_sectocframes:
  }
}

\cs_new_protected:Nn \_@@_define_chapter: {
  \cs_if_exist:NF \chaptername {
    \cs_set_protected:Npn \chaptername {Chapter}
  }
  \cs_if_exist:NF \chapter {
    \cs_set_protected:Npn \chapter {INVALID}
  }
  \cs_if_exist:NF \c@chapter {
    \newcounter{chapter}\counterwithin*{section}{chapter}
  }
}

\cs_new_protected:Nn \_@@_define_part: {
  \cs_if_exist:NF \partname {
    \cs_set_protected:Npn \partname {Part}
  }
  \cs_if_exist:NF \part {
    \cs_set_protected:Npn \part {INVALID}
  }
  \cs_if_exist:NF \c@part {
    \newcounter{part}\counterwithin*{chapter}{part}
  }
}
%    \end{macrocode}
%
% \begin{macro}{\prematurestop}
%   We initialize |\afterprematurestop|, and provide 
%   |\prematurestop@endsfragment| which looks up |\sfragment@level| and recursively ends
%   enough |{sfragment}|s. 
%    \begin{macrocode}
\def \c_@@_document_str{document} 
\newcommand\afterprematurestop{}
\def\prematurestop@endsfragment{
  \unless\ifx\@currenvir\c_@@_document_str
    \expandafter\expandafter\expandafter\end\expandafter\expandafter\expandafter{\expandafter\@currenvir\expandafter}
    \expandafter\prematurestop@endsfragment
  \fi
}
\providecommand\prematurestop{
  \stex_if_html_backend:F{
  \message{Stopping~sTeX~processing~prematurely}
  \prematurestop@endsfragment
  \afterprematurestop
  \end{document}
  }
}
%    \end{macrocode}
% \end{macro}
%
% \end{sfragment}
% \begin{sfragment}[id=sec:impl:noteslides]{Notes and Slides}
% For the notes case, we also provide the |\usetheme| macro that would otherwise
% come from the the |beamer| class.
%    \begin{macrocode}
\bool_if:NT \c_notesslides_notes_bool {
  \renewcommand\usetheme[2][]{\usepackage[#1]{beamertheme#2}}
}
\NewDocumentCommand \libusetheme {O{} m} {
  \libusepackage[#1]{beamertheme#2}
}
%    \end{macrocode}
% We define the sizes of slides in the notes. Somehow, we cannot get by with the same
% here. 
%    \begin{macrocode}
\newlength{\slidewidth}\setlength{\slidewidth}{13.5cm}
\newlength{\slideheight}\setlength{\slideheight}{9cm}
%    \end{macrocode}
% 
% We first set up the slide boxes in |notes| mode. We set up sizes and provide a
% box register for the frames and a counter for the slides.
% 
%    \begin{macrocode}
\ifnotes

\newlength{\slideframewidth}
\setlength{\slideframewidth}{1.5pt}
%    \end{macrocode}
% 
% \begin{environment}{frame}
%   We first define the keys. 
%    \begin{macrocode}
\cs_new_protected:Nn \_@@_do_yes_param:Nn {
  \exp_args:Nx \str_if_eq:nnTF { \str_uppercase:n{ #2 } }{ yes }{
    \bool_set_true:N #1
  }{
    \bool_set_false:N #1
  }
}

\stex_keys_define:nnnn{notesslides / frame}{
  \str_clear:N \l_@@_frame_label_str
  \bool_set_true:N \l_@@_frame_allowframebreaks_bool
  \bool_set_true:N \l_@@_frame_allowdisplaybreaks_bool
  \bool_set_true:N \l_@@_frame_fragile_bool
  \bool_set_true:N \l_@@_frame_shrink_bool
  \bool_set_true:N \l_@@_frame_squeeze_bool
  \bool_set_true:N \l_@@_frame_t_bool
}{
  label               .str_set_x:N  = \l_@@_frame_label_str,
  allowframebreaks    .code:n       = {
    \_@@_do_yes_param:Nn \l_@@_frame_allowframebreaks_bool { #1 }
  },
  allowdisplaybreaks  .code:n       = {
    \_@@_do_yes_param:Nn \l_@@_frame_allowdisplaybreaks_bool { #1 }
  },
  fragile             .code:n       = {
    \_@@_do_yes_param:Nn \l_@@_frame_fragile_bool { #1 }
  },
  shrink              .code:n       = {
    \_@@_do_yes_param:Nn \l_@@_frame_shrink_bool { #1 }
  },
  squeeze             .code:n       = {
    \_@@_do_yes_param:Nn \l_@@_frame_squeeze_bool { #1 }
  },
  t                   .code:n       = {
    \_@@_do_yes_param:Nn \l_@@_frame_t_bool { #1 }
  },
  unknown   .code:n       = {}
}{}
%    \end{macrocode}
%
% We redefine the |itemize| environment so that it looks more like the one in |beamer|. 
%
%    \begin{macrocode}
\cs_new_protected:Nn \_@@_setup_itemize: {
  \def\itemize@level{outer}
  \def\itemize@outer{outer}
  \def\itemize@inner{inner}
  %\newcommand\metakeys@show@keys[2]{\marginnote{{\scriptsize ##2}}}
  \renewenvironment{itemize}{
    \ifx\itemize@level\itemize@outer
      \def\itemize@label{$\rhd$}
    \fi
    \ifx\itemize@level\itemize@inner
      \def\itemize@label{$\scriptstyle\rhd$}
    \fi
    \begin{list}
    {\itemize@label}
    {\setlength{\labelsep}{.3em}
      \setlength{\labelwidth}{.5em}
      \setlength{\leftmargin}{1.5em}
    }
    \edef\itemize@level{\itemize@inner}
  }{
    \end{list}
  }
}
%    \end{macrocode}
% 
% We create the box with the |mdframed| environment from the equinymous package.
%
%    \begin{macrocode}
\stex_if_html_backend:TF {
  \cs_new_protected:Nn \_@@_frame_box_begin: {
    \vbox\bgroup
    \begin{stex_annotate_env}{shtml:frame={}}
      \mdf@patchamsthm\notesslidesfont
  }
  \cs_new_protected:Nn \_@@_frame_box_end: {
    %^^A \notesslides@slidelabel
    \medskip\par\noindent\tiny\notesslidesfooter
    \end{stex_annotate_env}\egroup
  }
}{
  \cs_new_protected:Nn \_@@_frame_box_begin: {
    \begin{mdframed}[
      linewidth=\slideframewidth,
      skipabove=1ex,
      skipbelow=1ex,
      userdefinedwidth=\slidewidth,
      align=center
    ]\notesslidesfont
  }
  \cs_new_protected:Nn \_@@_frame_box_end: {
    \medskip\par\noindent\tiny\notesslidesfooter%^^A\notesslides@slidelabel
    \end{mdframed}
  }
}
%    \end{macrocode}
%
% We define the environment, read them, and construct the slide number and label.
%
%    \begin{macrocode}
\renewenvironment{frame}[1][]{
  \stex_keys_set:nn{notesslides / frame}{#1}
  \stepcounter{framenumber}
  \renewcommand\newpage{\addtocounter{framenumber}{1}}
  \def\@currentlabel{\theframenumber}
  \str_if_empty:NF \l_@@_frame_label_str {
    \label{\l_@@_frame_label_str}
  }
  \_@@_setup_itemize:
  \_@@_frame_box_begin:
}{
  \_@@_frame_box_end:
}
%    \end{macrocode}
% \end{environment}
% 
% Now, we need to redefine the frametitle (we are still in course notes mode). 
% \begin{macro}{\frametitle}
%    \begin{macrocode}
\renewcommand{\frametitle}[1]{
  \stexdoctitle { #1 }
  \notesslidestitleemph{#1}\medskip
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\pause}
%    \begin{macrocode}
\newcommand\pause{}
%    \end{macrocode}
% \end{macro}
%
% We redefine the \env{columns} and \env{column} environments:
%
%    \begin{macrocode}
\renewenvironment{columns}[1][]{
  \par\noindent
  \begin{minipage}
  \slidewidth\centering\leavevmode
%  \stex_if_html_backend:T{
%    \cs_if_exist:NT \rustex_if:T {
%      \rustex_if:T {\par
%        \rustex_direct_HTML:n{<table><tr><td>}
%      }
%    }
%  }
}{
%  \stex_if_html_backend:T{
%    \cs_if_exist:NT \rustex_if:T {
%      \rustex_if:T {\par
%        \rustex_direct_HTML:n{</td></tr></table>}
%      }
%    }
%  }
  \end{minipage}\par\noindent
}
\newsavebox\columnbox
\renewenvironment<>{column}[2][]{
  \begin{lrbox}{\columnbox}
%    \stex_if_html_backend:T{
%      \cs_if_exist:NT \rustex_if:T {
%        \rustex_if:T {\par
%          \rustex_direct_HTML:n{</td><td>}
%        }
%      }
%    }
    \begin{minipage}{#2}
}{
  \end{minipage}
%  \stex_if_html_backend:T{
%    \cs_if_exist:NT \rustex_if:T {
%      \rustex_if:T {\par
%        \rustex_direct_HTML:n{</td><td>}
%      }
%    }
%  }
  \end{lrbox}\usebox\columnbox
}
%    \end{macrocode}
%
%
%    \begin{macrocode}
\fi
%    \end{macrocode}
%
% \end{sfragment}
%
% \begin{sfragment}{Environment and Macro Patches}
%
% The \env{note} environment is used to leave out text in the |slides| mode. It does not have
% a counterpart in OMDoc. So for course notes, we define the \env{note} environment to be a
% no-operation otherwise we declare the \env{note} environment to produce no
% output.
%
%    \begin{macrocode}
\bool_if:NTF \c_notesslides_notes_bool {
  \renewenvironment{note}{\ignorespaces}{}
}{
  \renewenvironment{note}{\setbox \l_tmpa_box\vbox\bgroup}{\egroup}
}
%    \end{macrocode}
%
% For other environments we introduce variants prefixed with |n|,
% which are excluded in |slides| mode.
%
%    \begin{macrocode}
\cs_new_protected:Nn \_@@_notes_env:nnnn {
  \bool_if:NTF \c_notesslides_notes_bool {
    \newenvironment{#1}#2{#3}{#4}
  }{
    \newenvironment{#1}#2{
      \cs_set:Npn \_@@_eat: ####1 \end ####2 {
        \str_if_eq:nnTF{#1}{####2}{
          \end{#1}
        }{
          \_@@_eat:
        }
      }
      \_@@_eat:
      %\setbox\l_tmpa_box\vbox\bgroup#3
    }{
      %#4\egroup
    }
  }
}

\_@@_notes_env:nnnn{nparagraph}{[1][]}{\begin{sparagraph}[#1]}{\end{sparagraph}}
\_@@_notes_env:nnnn{nfragment}{[2][]}{\begin{sfragment}[#1]{#2}}{\end{sfragment}}
\_@@_notes_env:nnnn{ndefinition}{[1][]}{\begin{sdefinition}[#1]}{\end{sdefinition}}
\_@@_notes_env:nnnn{nassertion}{[1][]}{\begin{sassertion}[#1]}{\end{sassertion}}
\_@@_notes_env:nnnn{nproof}{[2][]}{\begin{sproof}[#1]{#2}}{\end{sproof}}
\_@@_notes_env:nnnn{nexample}{[1][]}{\begin{sexample}[#1]}{\end{sexample}}

\RequirePackage{graphicx}

\NewDocumentCommand\frameimage{s O{} m}{
  \IfBooleanTF #1 {
    \begin{frame}[plain]
  }{
    \begin{frame}
  }
    \bool_if:NTF \c_notesslides_notes_bool {
      \slidewidth=\dimexpr\slidewidth-(2\slideframewidth)\relax
    }{ 
      \slidewidth=\textwidth\relax
    }
    \def\Gin@ewidth{}\setkeys{Gin}{#2}
    \tl_if_empty:NTF \Gin@ewidth {
      \mhgraphics[width=\slidewidth,#2]{#3}
    }{
      \mhgraphics[#2]{#3}
    }
  \end{frame}
}
%    \end{macrocode}
%
% hacking inputref:
%
% \begin{macro}{\inputref*}
%    \begin{macrocode}
\cs_set_eq:NN\_@@_inputref:\inputref
\cs_set_protected:Npn\inputref{\@ifstar\ninputref\_@@_inputref:}
\bool_if:NTF \c_notesslides_notes_bool {
  \newcommand\ninputref[2][]{
    \_@@_inputref:[#1]{#2}
  }
}{
  \newcommand\ninputref[2][]{}
}
%    \end{macrocode}
% \end{macro}
%
% \end{sfragment}
%
% \begin{sfragment}{Styling Across Notes/Slides}
%    \begin{macrocode}
\def\notesslidestitleemph#1{
  {\Large\bf\sf#1}
  \vskip0.1\baselineskip
  \leaders\vrule width \textwidth
  \vskip0.4pt%
  \nointerlineskip
}

\def\notesslidesfooter{}

\let\notesslidesfont\sffamily
%    \end{macrocode}
% \end{sfragment}
%
% \begin{sfragment}{Beamer Compatibility}
% All of this should be removed and made part of a template
%    \begin{macrocode}

\bool_if:NT \c_notesslides_notes_bool {
  \def\author{\@dblarg\ns@author}
  \long\def\ns@author[#1]#2{%
    \tl_if_empty:nTF{#1}{
      \def\beamer@shortauthor{#2}
    }{
      \def\beamer@shortauthor{#1}
    }
    \def\@author{#2}
  }
  \def\title{\@dblarg\ns@title}
  \long\def\ns@title[#1]#2{%
    \tl_if_empty:nTF{#1}{
      \def\beamer@shorttitle{#2}
    }{
      \def\beamer@shorttitle{#1}
    }
    \def\@title{#2}
    \stexdoctitle{#2}
  }
  \def\insertshortauthor{
    \hbox\bgroup\def\\{}\cs_if_exist:NT\beamer@shortauthor\beamer@shortauthor\egroup
  }
  \def\insertshorttitle{
    \hbox\bgroup\def\\{}\cs_if_exist:NT\beamer@shorttitle\beamer@shorttitle\egroup
  }
  \stex_if_html_backend:TF{
    \def\insertframenumber{\stex_annotate:nn{shtml:framenumber={}}{}}
  }{
    \def\insertframenumber{\@arabic\c@framenumber}
  }
  \def\insertshortdate{\today}
}
%    \end{macrocode}
% \end{sfragment}
%
%
% \subsection{TODO Excursions}\label{sec:impl:excursions}
%
% \begin{macro}{\excursion}
%  The excursion macros are very simple, we define a new internal macro |\excursionref| and
%  use it in |\excursion|, which is just an |\inputref| that checks if the new macro is
%  defined before formatting the file in the argument. 
%    \begin{macrocode}
\gdef\printexcursions{}
\newcommand\excursionref[2]{% label, text
  \bool_if:NT \c_notesslides_notes_bool {
    \begin{sparagraph}[title=Excursion]
      #2 \sref[fallback=the appendix]{#1}.
    \end{sparagraph}
  }
}
\newcommand\activate@excursion[2][]{
  \tl_gput_right:Nn\printexcursions{\inputref[#1]{#2}}
}
\newcommand\excursion[4][]{% repos, label, path, text
  \bool_if:NT \c_notesslides_notes_bool {
    \activate@excursion[#1]{#3}
    \excursionref{#2}{#4}
  }
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\excursiongroup}
%    \begin{macrocode}
\keys_define:nn{notesslides / excursiongroup }{
  id        .str_set_x:N  = \l_@@_excursion_id_str,
  intro     .tl_set:N     = \l_@@_excursion_intro_tl,
  archive   .str_set_x:N  = \l_@@_excursion_mhrepos_str
}
\cs_new_protected:Nn \_@@_excursion_args:n {
  \tl_clear:N \l_@@_excursion_intro_tl
  \str_clear:N \l_@@_excursion_id_str
  \str_clear:N \l_@@_excursion_mhrepos_str
  \keys_set:nn {notesslides / excursiongroup }{ #1 }
}
\newcommand\excursiongroup[1][]{
  \_@@_excursion_args:n{ #1 }
  \tl_if_empty:NF\printexcursions
  {\IfInputref{}{\begin{note}
    \begin{sfragment}{Excursions}% TODO pass on id
      \ifdefempty\l_@@_excursion_intro_tl{}{
        \exp_args:NNe \use:nn \inputref{[\l_@@_excursion_mhrepos_str]{
          \l_@@_excursion_intro_tl
        }}
      }
      \printexcursions%
    \end{sfragment}
  \end{note}}}
}
\ifcsname beameritemnestingprefix\endcsname\else\def\beameritemnestingprefix{}\fi
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\prop_new:N \g_@@_variables_prop
\cs_set_protected:Npn \setSGvar #1 #2 {
  \prop_gput:Nnn \g_@@_variables_prop {#1}{#2}
}
\cs_set_protected:Npn \useSGvar #1 {
  \prop_item:Nn \g_@@_variables_prop {#1}
}
\cs_set_protected:Npn \ifSGvar #1 #2 #3 {
  \prop_get:NnNF \g_@@_variables_prop {#1} \l_@@_tmp {
    \PackageError{document-structure}
    {The sTeX Global variable #1 is undefined}
    {set it with \protect\setSGvar}\TODO better error
  }
  \tl_if_eq:NnT \l_@@_tmp {#2}{ #3 }
}


%</package>
%    \end{macrocode}
%
% \end{sfragment}
% \end{implementation}
\endinput
% \endinput
% Local Variables:
% mode: doctex
% TeX-master: t
% End: