% \iffalse meta-comment
% An Infrastructure for Semantic Macros and Module Scoping
% Copyright (c) 2019 Michael Kohlhase, all rights reserved
%                this file is released under the
%                LaTeX Project Public License (LPPL)
% 
% The original of this file is in the public repository at 
% http://github.com/sLaTeX/sTeX/
%
% TODO update copyright  
%
%<*driver>
\def\libfolder#1{../../lib/#1}
\input{../../doc/stex-docheader}

\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \title{ \sTeX-References
% 	\thanks{Version {\fileversion} (last revised {\filedate})} 
% }
%
% \author{Michael Kohlhase, Dennis Müller\\
% 	FAU Erlangen-Nürnberg\\
% 	\url{http://kwarc.info/}
% }
%
% \maketitle
%
%\ifinfulldoc\else
% This is the documentation for the \pkg{stex-references} package.
% For a more high-level introduction, 
%  see \href{\basedocurl/manual.pdf}{the \sTeX Manual} or the
% \href{\basedocurl/stex.pdf}{full \sTeX documentation}.
% \fi
%
% \begin{documentation}\label{pkg:sref:doc}
%
% This sub package contains code related to links and cross-references
%
%\ifinfulldoc\else
% \input{../../doc/packages/stex-references}
% \fi
%
% \section{Macros and Environments}\label{pkg:sref:doc:macros}
%
%
% \begin{function}{\stex_get_document_uri:}
%   Computes the current document uri from the current archive's |narr|-field and its
%   location relative to the archive's |source|-directory. Reference targets are computed
%   from this URI and the reference-id.
%
%   \begin{variable}{\l_stex_current_docns_str}
%      Stores its result in |\l_stex_current_docns_str|
%   \end{variable}
% \end{function}
%
% \begin{function}{\stex_get_document_url:}
%   Computes the current URL from the current archive's |docurl|-field and its location
%   relative to the archive's |source|-directory. Reference targets are computed from this
%   URL and the reference-id, if this document is only included in SMS mode.
%
%   \begin{variable}{\l_stex_current_docurl_str}
%      Stores its result in |\l_stex_current_docurl_str|
%   \end{variable}
% \end{function}
%
% \subsection{Setting Reference Targets}
%
% \begin{function}{\stex_ref_new_doc_target:n}
%    \begin{syntax} \cs{stex_ref_new_doc_target:n}\Arg{id} \end{syntax}
%
%    Sets a new reference target with id \meta{id}.
% \end{function}
%
% \begin{function}{\stex_ref_new_sym_target:n}
%    \begin{syntax} \cs{stex_ref_new_sym_target:n}\Arg{uri} \end{syntax}
%
%    Sets a new reference target for the symbol \meta{uri}.
% \end{function}
%
% \subsection{Using References}
%
% \begin{function}{\sref}
%   \begin{syntax} \cs{sref}|[|\meta{opt-args}|]|\Arg{id} \end{syntax}
%   References the label with if \meta{id}.
%   Optional arguments: \textcolor{red}{TODO}
% \end{function}
%
% \begin{function}{\srefsym}
%   \begin{syntax} \cs{srefsym}|[|\meta{opt-args}|]|\Arg{symbol} \end{syntax}
%   Like \cs{sref}, but references the \emph{canonical label} for
%   the provided symbol. The canonical target is the last of the following
%   occuring in the document:
%   \begin{itemize}
%     \item A \cs{definiendum} or \cs{definame} for \meta{symbol},
%     \item The |sassertion|, |sexample| or |sparagraph| with |for=|\meta{symbol} that
%       generated \meta{symbol} in the first place, or
%     \item A \cs{sparagraph} with |type=symdoc| and |for=|\meta{symbol}.
%   \end{itemize}
% \end{function}
%
% \begin{function}{\srefsymuri}
%   \begin{syntax} \cs{srefsymuri}\Arg{URI}\Arg{text} \end{syntax}
%    A convenient short-hand for |\srefsym[linktext={text}]{URI}|,
%    but requires the first argument to be a full URI already.
%    Intended to be used in e.g. \cs{compemph@uri}, \cs{defemph@uri}, etc.
% \end{function}
%
% \end{documentation}
%
% \begin{implementation}\label{pkg:sref:impl}
%
% \section{\sTeX-References Implementation}
%
%    \begin{macrocode}
%<*package>

%%%%%%%%%%%%%   stex-references.dtx   %%%%%%%%%%%%%

%<@@=stex_refs>
%    \end{macrocode}
%
% Warnings and error messages
%
%    \begin{macrocode}
\msg_new:nnn{stex}{error/extrefmissing}{
  Missing~in~or~cite~value~for~\detokenize{\extref}!
}
\msg_new:nnn{stex}{warning/smsmissing}{
  .sref~file~#1~doesn't~exist!
}
\msg_new:nnn{stex}{warning/smslabelmissing}{
  No~label~#2~in~.sref~file~#1!
}
%    \end{macrocode}
%
% References are stored in the file |\jobname.sref|, to enable
% cross-referencing external documents.
%
%    \begin{macrocode}
\iow_new:N \c_@@_refs_iow
\AtBeginDocument{
  \iow_open:Nn \c_@@_refs_iow {\jobname.sref}
}
\AtEndDocument{
  \iow_close:N \c_@@_refs_iow
}
%    \end{macrocode}
%
%
% \subsection{Document URIs and URLs}
%
% \begin{variable}{\l_stex_current_docns_str}
%    \begin{macrocode}
\str_new:N \l_stex_current_docns_str
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\stex_get_document_uri:}
%    \begin{macrocode}
\cs_new_protected:Nn \stex_get_document_uri: {
  \seq_set_eq:NN \l_tmpa_seq \g_stex_currentfile_seq
  \seq_pop_right:NN \l_tmpa_seq \l_tmpb_str
  \exp_args:NNno \seq_set_split:Nnn \l_tmpb_seq . \l_tmpb_str
  \seq_get_left:NN \l_tmpb_seq \l_tmpb_str
  \seq_put_right:No \l_tmpa_seq \l_tmpb_str

  \str_clear:N \l_tmpa_str
  \prop_if_exist:NT \l_stex_current_repository_prop {
    \prop_get:NnNF \l_stex_current_repository_prop { narr } \l_tmpa_str {
      \prop_get:NnNF \l_stex_current_repository_prop { ns } \l_tmpa_str {}
    }
  }

  \str_if_empty:NTF \l_tmpa_str {
    \str_set:Nx \l_stex_current_docns_str { 
      file:/\stex_path_to_string:N \l_tmpa_seq
    }
  }{
    \bool_set_true:N \l_tmpa_bool
    \bool_while_do:Nn \l_tmpa_bool {
      \seq_pop_left:NN \l_tmpa_seq \l_tmpb_str
      \exp_args:No \str_case:nnTF { \l_tmpb_str } {
        {source} { \bool_set_false:N \l_tmpa_bool }
      }{}{
        \seq_if_empty:NT \l_tmpa_seq {
          \bool_set_false:N \l_tmpa_bool
        }
      }
    }
  
    \seq_if_empty:NTF \l_tmpa_seq {
      \str_gset_eq:NN \l_stex_current_docns_str \l_tmpa_str
    }{
      \str_gset:Nx \l_stex_current_docns_str { 
        \l_tmpa_str/\stex_path_to_string:N \l_tmpa_seq
      }
    }
  }
  %\stex_get_document_url:
}
%    \end{macrocode}
% \end{macro}
%
% \begin{variable}{\l_stex_current_docurl_str}
%    \begin{macrocode}
\str_new:N \l_stex_current_docurl_str
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\stex_get_document_url:}
%    \begin{macrocode}
\cs_new_protected:Nn \stex_get_document_url: {
  \seq_set_eq:NN \l_tmpa_seq \g_stex_currentfile_seq
  \seq_pop_right:NN \l_tmpa_seq \l_tmpb_str
  \exp_args:NNno \seq_set_split:Nnn \l_tmpb_seq . \l_tmpb_str
  \seq_get_left:NN \l_tmpb_seq \l_tmpb_str
  \seq_put_right:No \l_tmpa_seq \l_tmpb_str

  \str_clear:N \l_tmpa_str
  \prop_if_exist:NT \l_stex_current_repository_prop {
    \prop_get:NnNF \l_stex_current_repository_prop { docurl } \l_tmpa_str {
      \prop_get:NnNF \l_stex_current_repository_prop { narr } \l_tmpa_str {
        \prop_get:NnNF \l_stex_current_repository_prop { ns } \l_tmpa_str {}
      }
    }
  }

  \str_if_empty:NTF \l_tmpa_str {
    \str_set:Nx \l_stex_current_docurl_str { 
      file:/\stex_path_to_string:N \l_tmpa_seq
    }
  }{
    \bool_set_true:N \l_tmpa_bool
    \bool_while_do:Nn \l_tmpa_bool {
      \seq_pop_left:NN \l_tmpa_seq \l_tmpb_str
      \exp_args:No \str_case:nnTF { \l_tmpb_str } {
        {source} { \bool_set_false:N \l_tmpa_bool }
      }{}{
        \seq_if_empty:NT \l_tmpa_seq {
          \bool_set_false:N \l_tmpa_bool
        }
      }
    }
  
    \seq_if_empty:NTF \l_tmpa_seq {
      \str_set_eq:NN \l_stex_current_docurl_str \l_tmpa_str
    }{
      \str_set:Nx \l_stex_current_docurl_str { 
        \l_tmpa_str/\stex_path_to_string:N \l_tmpa_seq
      }
    }
  }
}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Setting Reference Targets}
%
%    \begin{macrocode}
\str_const:Nn \c_@@_url_str{URL}
\str_const:Nn \c_@@_ref_str{REF}
\str_new:N \l_@@_curr_label_str
% @currentlabel -> number
% @currentlabelname -> title
% @currentHref -> name.number <- id of some kind
% @currentcounter <- name/id
% \#autorefname <- "Section"
% \theH# -> \arabic{section}
% \the#  -> number
% \hyper@makecurrent{#}
\int_new:N \l_@@_unnamed_counter_int
%    \end{macrocode}
%
% Restoring references from |.sref|-files
%
% \begin{macro}{\STEXInternalSrefRestoreTarget}
%    \begin{macrocode}
\cs_new_protected:Npn \STEXInternalSrefRestoreTarget #1#2#3#4#5 {}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\stex_ref_new_doc_target:n}
%    \begin{macrocode}
\seq_new:N \g_stex_ref_files_seq

\cs_new_protected:Nn \stex_ref_new_doc_target:n {
  %\stex_get_document_uri:
  \str_clear:N \l_@@_curr_label_str
  \str_set:Nx \l_tmpa_str { #1 }
  \str_if_empty:NT \l_tmpa_str {
    \int_gincr:N \l_@@_unnamed_counter_int
    \str_set:Nx \l_tmpa_str {REF\int_use:N \l_@@_unnamed_counter_int}
  }
  \str_set:Nx \l_@@_curr_label_str {
    \l_stex_current_docns_str?\l_tmpa_str
  }

  \exp_args:Noo \STEXInternalAuxAddDocRef\l_stex_current_docns_str\l_tmpa_str
  
  %\seq_if_exist:cF{g_@@_labels_\l_tmpa_str _seq}{
  %  \seq_new:c {g_@@_labels_\l_tmpa_str _seq}
  %}
  %\seq_if_in:coF{g_@@_labels_\l_tmpa_str _seq}\l_@@_curr_label_str {
  %  \seq_gput_right:co{g_@@_labels_\l_tmpa_str _seq}\l_@@_curr_label_str
  %}


  \stex_if_smsmode:TF {
    %\stex_get_document_url:
    %\str_gset_eq:cN {sref_url_\l_@@_curr_label_str _str}\l_stex_current_docurl_str
    %\str_gset_eq:cN {sref_\l_@@_curr_label_str _type}\c_@@_url_str
  }{
    \iow_now:Nx \c_@@_refs_iow {
      \STEXInternalSrefRestoreTarget
        {\l_stex_current_docns_str}
        {\l_tmpa_str}
        {\@currentcounter}
        {\@currentlabel}
        {\tl_if_exist:NT\@currentlabelname{\exp_args:No\unexpanded\@currentlabelname}}
    }
    %\iow_now:Nx \c_@@_refs_iow { 
    %  {\l_stex_current_docns_str?\l_tmpa_str}~=~{{\use:c{\@currentcounter autorefname}~\@currentlabel}~(\@currentlabelname)~in~\exp_args:No\unexpanded\g_@@_title_tl},}
    \stex_debug:nn{sref}{New~label~\l_@@_curr_label_str~at~\use:c{\use:c{@currentcounter}autorefname}}
    \exp_args:Nx\label{sref_\l_@@_curr_label_str}
    \immediate\write\@auxout{\STEXInternalAuxAddDocRef{\l_stex_current_docns_str}{\l_tmpa_str}}
    %\str_gset:cx {sref_\l_@@_curr_label_str _type}\c_@@_ref_str
  }
}
\NewDocumentCommand \slabel {m} {\stex_ref_new_doc_target:n {#1}}
%    \end{macrocode}
% \end{macro}
%
% The following is used to set the necessary macros in the |.aux|-file.
%
%    \begin{macrocode}
\cs_new_protected:Npn \STEXInternalAuxAddDocRef #1 #2 {
  \exp_args:NNx \seq_if_in:NnTF \g_stex_ref_files_seq {\detokenize{#1}} {
    \exp_args:Nnx \seq_if_in:cnF{g_stex_ref_ #1 _seq}{\detokenize{#2}}{
      \exp_args:Nnx \seq_gput_left:cn{g_stex_ref_ #1 _seq}{\detokenize{#2}}
    }
  }{
      \exp_args:NNx \seq_gput_right:Nn \g_stex_ref_files_seq {\detokenize{#1}}
      %\seq_if_exist:cF{g_stex_ref_ #1 _seq}{
        \seq_new:c{g_stex_ref_ #1 _seq} % <- seq_new throws errors??
      %}
      \exp_args:Nnx \seq_gput_left:cn{g_stex_ref_ #1 _seq}{\detokenize{#2}}
  }
  
  %\str_set:Nn \l_tmpa_str {#1?#2}
  %\str_gset_eq:cN{sref_#1?#2_type}\c_@@_ref_str
  %\seq_if_exist:cF{g_@@_labels_#2_seq}{
  %  \seq_new:c {g_@@_labels_#2_seq}
  %}
  %\seq_if_in:coF{g_@@_labels_#2_seq}\l_tmpa_str {
  %  \seq_gput_right:co{g_@@_labels_#2_seq}\l_tmpa_str
  %}
}
%    \end{macrocode}
% To avoid resetting the same macros when the |.aux|-file is read
% at the end of the document:
%
%    \begin{macrocode}
\AtEndDocument{
  \def\STEXInternalAuxAddDocRef#1 #2 {}{}
}
%    \end{macrocode}
%
% \begin{macro}{\stex_ref_new_sym_target:n}
%    \begin{macrocode}
\cs_new_protected:Nn \stex_ref_new_sym_target:n {

%  \stex_if_smsmode:TF {
%    \str_if_exist:cF{sref_sym_#1_type}{
%      \stex_get_document_url:
%      \str_gset_eq:cN {sref_sym_url_#1_str}\l_stex_current_docurl_str
%      \str_gset_eq:cN {sref_sym_#1_type}\c_@@_url_str
%    }
%  }{
%    \str_if_empty:NF \l_@@_curr_label_str {
%      \str_gset_eq:cN {sref_sym_#1_label_str}\l_@@_curr_label_str
%      \immediate\write\@auxout{
%        \exp_not:N\expandafter\def\exp_not:N\csname \exp_not:N\detokenize{sref_sym_#1_label_str}\exp_not:N\endcsname{
%            \l_@@_curr_label_str
%          }
%      }
%    }
%  }
}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Using References}
%
% \begin{macro}{\sref}
% Optional arguments:
%    \begin{macrocode}

\keys_define:nn { stex / sref / 1 } {
  archive   .str_set_x:N  = \l_@@_repo_str,
  file      .str_set_x:N  = \l_@@_file_str,
  % TODO get rid of this
  fallback  .code:n = {},
  pre       .code:n = {},
  post      .code:n = {}
}
\cs_new_protected:Nn \_@@_args_i:n {
  \str_clear:N \l_@@_repo_str
  \str_clear:N \l_@@_file_str
  \keys_set:nn { stex / sref / 1 } { #1 }
}
\keys_define:nn { stex / sref / 2 } {
  in      .str_set_x:N  = \l_@@_in_str,
  archive    .str_set_x:N  = \l_@@_repob_str,
  title    .tl_set:N  = \l_@@_title_tl
}
\cs_new_protected:Nn \_@@_args_ii:n {
  \str_clear:N \l_@@_in_str
  \tl_clear:N \l_@@_title_tl
  \str_clear:N \l_@@_repob_str
  \keys_set:nn { stex / sref / 2 } { #1 }
}
%    \end{macrocode}
% The actual macro:
%    \begin{macrocode}
\NewDocumentCommand \sref { O{} m O{}}{
  \_@@_args_i:n{#1}
  \_@@_args_ii:n{#3}
  \str_clear:N \l_@@_uri_str
  \_@@_find_uri:n{#2}
  \_@@_do_sref:n{#2}
}
\NewDocumentCommand \extref { O{} m m}{
  \_@@_args_i:n{#1}
  \_@@_args_ii:n{#3}
  \str_if_empty:NT \l_@@_in_str {
    \msg_error:nn{stex}{error/extrefmissing}
  }
  \str_clear:N \l_@@_uri_str
  \_@@_find_uri:n{#2}
  \_@@_do_sref_in:n{#2}
}

\cs_new_protected:Nn \_@@_find_uri:n {
  \stex_debug:nn{sref}{File:~\l_@@_file_str^^JRepo:\l_@@_repo_str}
  \str_if_empty:NTF \l_@@_file_str {
    \stex_debug:nn{sref}{Empty.~Checking~current~file~for~#1}
    \seq_if_exist:cT{g_stex_ref_\l_stex_current_docns_str _seq}{
      \seq_map_inline:cn{g_stex_ref_\l_stex_current_docns_str _seq}{
        \str_if_eq:nnT{#1}{##1}{
          \str_set_eq:NN \l_@@_uri_str \l_stex_current_docns_str
          \stex_debug:nn{sref}{Found.}
          \seq_map_break:
        }
      }
    }
    \str_if_empty:NT \l_@@_uri_str {
      \stex_debug:nn{sref}{Checking~other~files}
      \seq_map_inline:Nn \g_stex_ref_files_seq {
        \stex_debug:nn{sref}{##1...}
        \seq_map_inline:cn{g_stex_ref_##1_seq}{
          \str_if_eq:nnT{#1}{####1}{
            \stex_debug:nn{sref}{Found~##1}
            \str_set:Nn \l_@@_uri_str {##1}
            \seq_map_break:n{\seq_map_break:}
          }
        }
      }
    }
  }{
    \str_if_empty:NTF \l_@@_repo_str {
      \prop_if_exist:NTF \l_stex_current_repository_prop {
        \prop_get:NnN \l_stex_current_repository_prop { ns } \l_@@_uri_str
        \str_set:Nx \l_@@_uri_str {\l_@@_uri_str / \l_@@_file_str}
        \stex_path_from_string:Nn \l_tmpb_seq \l_@@_uri_str
        \str_set:Nx \l_@@_uri_str {\stex_path_to_string:N \l_tmpb_seq}
      }{
        \stex_path_from_string:Nn \l_tmpb_seq {
          \stex_path_to_string:N \g_stex_currentfile_seq/ .. / \l_@@_file_str
        }
        \str_set:Nx \l_@@_uri_str {file:/\stex_path_to_string:N \l_tmpb_seq}
      }
    }{
      \stex_require_repository:n \l_@@_repo_str
      \prop_get:cnN { c_stex_mathhub_\l_@@_repo_str _manifest_prop } { ns } \l_@@_uri_str
      \str_set:Nx \l_@@_uri_str {\l_@@_uri_str / \l_@@_file_str}
      \stex_path_from_string:Nn \l_tmpb_seq \l_@@_uri_str
      \str_set:Nx \l_@@_uri_str {\stex_path_to_string:N \l_tmpb_seq}
    }
  }
}

\cs_new_protected:Nn \_@@_do_autoref:n{
  \cs_if_exist:cTF{autoref}{
     \exp_args:Nx\autoref{sref_#1}
   }{
     \exp_args:Nx\ref{sref_#1}
   }
}

\cs_new_protected:Nn \_@@_do_sref:n {
  \str_if_empty:NTF \l_@@_uri_str {
    \str_if_empty:NTF \l_@@_in_str {
      \stex_debug:nn{sref}{autoref~on~#1}
      \_@@_do_autoref:n{#1}
    }{
      \stex_debug:nn{sref}{srefin~on~#1}
      \_@@_do_sref_in:n{#1}
    }
  }{
    \exp_args:NNo \seq_if_in:NnTF \g_stex_ref_files_seq \l_@@_uri_str {
      \exp_args:Nnx \seq_if_in:cnTF{g_stex_ref_\l_@@_uri_str _seq}{\detokenize{#1}}{
        \stex_debug:nn{sref}{Reference~found~in~ref~files;~autoref~on~#1}
        \_@@_do_autoref:n{\l_@@_uri_str?#1}
      }{
        \str_if_empty:NTF \l_@@_in_str {
          \stex_debug:nn{sref}{in~empty;~autoref~on~#1}
          \_@@_do_autoref:n{#1}
        }{
          \stex_debug:nn{sref}{in~non-empty;~srefin~on~#1}
          \_@@_do_sref_in:n{#1}
        }
      }
    }{
      \str_if_empty:NTF \l_@@_in_str {
        \stex_debug:nn{sref}{in~empty;~autoref~on~#1}
        \_@@_do_autoref:n{#1}
      }{
        \stex_debug:nn{sref}{in~non-empty;~srefin~on~#1}
        \_@@_do_sref_in:n{#1}
      }
    }
  }
}

\cs_new_protected:Nn \_@@_restore_target:nnnnn {
  \str_if_empty:NTF \l_@@_uri_str {
    \exp_args:No \str_if_eq:nnT \l_@@_id_str {#2}{
      \tl_set:Nn \l_@@_return_tl {
        \use:c{#3autorefname}~#4\tl_if_empty:nF{#5}{~(#5)}~in~
        \tl_if_empty:nTF\l_@@_title_tl{
          ???
        }\l_@@_title_tl
      }
    }
  }{
    \stex_debug:nn{sref}{\l_@@_uri_str{}~ == ~ #1 ~ ?}
    \exp_args:No \str_if_eq:nnT \l_@@_uri_str {#1}{
      \stex_debug:nn{sref}{\l_@@_id_str~ == ~ #2 ~ ?}
      \exp_args:No \str_if_eq:nnT \l_@@_id_str {#2}{
        \stex_debug:nn{sref}{success!}
        \tl_set:Nn \l_@@_return_tl {
          \use:c{#3autorefname}~#4\tl_if_empty:nF{#5}{~(#5)}~in~
          \tl_if_empty:nTF\l_@@_title_tl{
            ???
          }\l_@@_title_tl
        }
        \endinput
      }
    }
  }
}

\cs_new_protected:Nn \_@@_do_sref_in:n {
  \stex_debug:nn{sref}{In: \l_@@_in_str^^JRepo:\l_@@_repo_str}
  \stex_debug:nn{sref}{URI: \l_@@_uri_str?#1}
  %\msg_warning:nnn{stex}{warning/smsmissing}{<filename>}
  \begingroup\catcode13=9\relax\catcode10=9\relax
    \str_if_empty:NTF \l_@@_repob_str {
      \prop_if_exist:NTF \l_stex_current_repository_prop {
        \str_set:Nx \l_tmpa_str {
          \c_stex_mathhub_str /
          \prop_item:Nn \l_stex_current_repository_prop { id }
          / source / \l_@@_in_str .sref
        }
      }{
        \str_set:Nx \l_tmpa_str {
          \stex_path_to_string:N \g_stex_currentfile_seq/ .. / \l_@@_in_str . sref
        }
      }
    }{
      \str_set:Nx \l_tmpa_str {
        \c_stex_mathhub_str / \l_@@_repob_str 
        / source / \l_@@_in_str . sref
      }
    }
    \stex_path_from_string:Nn \l_tmpb_seq \l_tmpa_str
    \stex_path_to_string:NN \l_tmpb_seq \l_tmpa_str
    \stex_debug:nn{sref}{File: \l_tmpa_str}
    \exp_args:No \IfFileExists \l_tmpa_str {
      \tl_clear:N \l_@@_return_tl
      \str_set:Nn \l_@@_id_str {#1}
      \let\STEXInternalSrefRestoreTarget\_@@_restore_target:nnnnn
      \use:c{@ @ input}{\l_tmpa_str}
      \exp_args:No \tl_if_empty:nTF \l_@@_return_tl {
        \exp_args:Nnno \msg_warning:nnnn{stex}{warning/smslabelmissing}\l_tmpa_str{#1}
        \_@@_do_autoref:n{
          \str_if_empty:NF\l_@@_uri_str{\l_@@_uri_str?}#1
        }
      }{
        \l_@@_return_tl
      }
    }{
      \exp_args:Nnno \msg_warning:nnn{stex}{warning/smsmissing}\l_tmpa_str
      \_@@_do_autoref:n{
        \str_if_empty:NF\l_@@_uri_str{\l_@@_uri_str?}#1
      }
    }
  \endgroup
}

 % \_@@_args:n { #1 }
 % \str_if_empty:NTF \l_@@_indocument_str {
 %   \str_set:Nx \l_tmpa_str { #2 }
 %   \exp_args:NNno \seq_set_split:Nnn \l_tmpa_seq ? \l_tmpa_str
 %   \int_compare:nNnTF {\seq_count:N \l_tmpa_seq} = 1 {
 %     \seq_if_exist:cTF{g_@@_labels_\l_tmpa_str _seq}{
 %       \seq_get_left:cNF {g_@@_labels_\l_tmpa_str _seq} \l_tmpa_str {
 %         \str_clear:N \l_tmpa_str
 %       }
 %     }{
 %       \str_clear:N \l_tmpa_str
 %     }
 %   }{
 %     \seq_pop_left:NN \l_tmpa_seq \l_tmpb_str
 %     \seq_pop_right:NN \l_tmpa_seq \l_tmpa_str
 %    \int_set:Nn \l_tmpa_int { \exp_args:Ne \str_count:n {\l_tmpb_str?\l_tmpa_str} }
 %     \seq_if_exist:cTF{g_@@_labels_\l_tmpa_str _seq}{
 %       \str_set_eq:NN \l_tmpc_str \l_tmpa_str
 %       \str_clear:N \l_tmpa_str
 %       \seq_map_inline:cn {g_@@_labels_\l_tmpc_str _seq} {
 %         \str_if_eq:eeT { \l_tmpb_str?\l_tmpc_str }{
 %           \str_range:nnn { ##1 }{ -\l_tmpa_int}{ -1 } 
 %         }{
 %           \seq_map_break:n {
 %             \str_set:Nn \l_tmpa_str { ##1 }
 %           }
 %         }
 %       }
 %     }{
 %       \str_clear:N \l_tmpa_str
 %     }
 %   }
 %   \str_if_empty:NTF \l_tmpa_str {
 %     \tl_if_empty:NTF \l_@@_linktext_tl \l_@@_fallback_tl \l_@@_linktext_tl
 %   }{
 %     \str_if_eq:cNTF {sref_\l_tmpa_str _type} \c_@@_ref_str {
 %       \tl_if_empty:NTF \l_@@_linktext_tl {
 %         \cs_if_exist:cTF{autoref}{
 %           \l_@@_pre_tl\exp_args:Nx\autoref{sref_\l_tmpa_str}\l_@@_post_tl
 %         }{
 %           \l_@@_pre_tl\exp_args:Nx\ref{sref_\l_tmpa_str}\l_@@_post_tl
 %         }
 %       }{
 %         \ltx@ifpackageloaded{hyperref}{
 %           \hyperref[sref_\l_tmpa_str]\l_@@_linktext_tl
 %         }{
 %           \l_@@_linktext_tl
 %         }
 %       }
 %     }{
 %       \ltx@ifpackageloaded{hyperref}{
 %         \href{\use:c{sref_url_\l_tmpa_str _str}}{\tl_if_empty:NTF \l_@@_linktext_tl \l_@@_fallback_tl \l_@@_linktext_tl}
 %       }{
 %         \tl_if_empty:NTF \l_@@_linktext_tl \l_@@_fallback_tl \l_@@_linktext_tl
 %       }
 %     }
 %   }
 % }{
    % TODO
 % }
%}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\srefsym}
%    \begin{macrocode}
\NewDocumentCommand \srefsym { O{} m}{
  \stex_get_symbol:n { #2 }
  \_@@_sym_aux:nn{#1}{\l_stex_get_symbol_uri_str}
}

\cs_new_protected:Nn \_@@_sym_aux:nn {

%  \str_if_exist:cTF {sref_sym_#2 _label_str }{
%    \sref[#1]{\use:c{sref_sym_#2 _label_str}}
%  }{
%    \_@@_args:n { #1 }
%    \str_if_empty:NTF \l_@@_indocument_str {
%      \tl_if_exist:cTF{sref_sym_#2 _type}{
%        % doc uri in \l_tmpb_str
%        \str_set:Nx \l_tmpa_str {\use:c{sref_sym_#2 _type}}
%        \str_if_eq:NNTF \l_tmpa_str \c_@@_ref_str {
%          % reference
%          \tl_if_empty:NTF \l_@@_linktext_tl {
%            \cs_if_exist:cTF{autoref}{
%              \l_@@_pre_tl\autoref{sref_sym_#2}\l_@@_post_tl
%            }{
%              \l_@@_pre_tl\ref{sref_sym_#2}\l_@@_post_tl
%            }
%          }{
%            \ltx@ifpackageloaded{hyperref}{
%              \hyperref[sref_sym_#2]\l_@@_linktext_tl
%            }{
%              \l_@@_linktext_tl
%            }
%          }
%        }{
%          % URL
%          \ltx@ifpackageloaded{hyperref}{
%            \href{\use:c{sref_sym_url_#2 _str}}{\tl_if_empty:NTF \l_@@_linktext_tl \l_@@_fallback_tl \l_@@_linktext_tl}
%          }{
%            \tl_if_empty:NTF \l_@@_linktext_tl \l_@@_fallback_tl \l_@@_linktext_tl
%          }
%        }
%      }{
%        \tl_if_empty:NTF \l_@@_linktext_tl \l_@@_fallback_tl \l_@@_linktext_tl
%      }
%    }{
%      % TODO
%    }
%  }
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\srefsymuri}
%    \begin{macrocode}
\cs_new_protected:Npn \srefsymuri #1 #2 { % TODO
  #2%\_@@_sym_aux:nn{linktext={#2}}{#1}
}
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \end{implementation}
% \ifinfulldoc\else\printbibliography\fi
%
% \PrintIndex
