% \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\bibfolder#1{../../lib/bib/#1} \input{../../doc/stex-docheader} \begin{document} \DocInput{\jobname.dtx} \end{document} % % \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}{\STEXreftitle} % \begin{syntax} \cs{STEXreftitle}\Arg{some title} \end{syntax} % % Sets the title of the current document to \meta{some title}. % A reference to the current document from \emph{some other} % document will then be displayed accordingly. e.g. % if |\STEXreftitle{foo book}| is called, then referencing % Definition 3.5 in this document in another document will display % |Definition 3.5 in foo book|. % \end{function} % % \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> %%%%%%%%%%%%% references.dtx %%%%%%%%%%%%% %<@@=stex_refs> % \end{macrocode} % % Warnings and error messages % % \begin{macrocode} % \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} % % \begin{macro}{\STEXreftitle} % \begin{macrocode} \str_set:Nn \g_@@_title_tl {Unnamed~Document} \NewDocumentCommand \STEXreftitle { m } { \tl_gset:Nx \g_@@_title_tl { #1 } } % \end{macrocode} % \end{macro} % % \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_set_eq:NN \l_stex_current_docns_str \l_tmpa_str }{ \str_set:Nx \l_stex_current_docns_str { \l_tmpa_str/\stex_path_to_string:N \l_tmpa_seq } } } } % \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 % \theH# -> \arabic{section} % \the# -> number % \hyper@makecurrent{#} \int_new:N \l_@@_unnamed_counter_int % \end{macrocode} % % \begin{macro}{\stex_ref_new_doc_target:n} % \begin{macrocode} \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_incr: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 } \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 { \l_tmpa_str~=~\expandafter\unexpanded\expandafter{\@currentlabel}~in~\exp_args:No\unexpanded\g_@@_title_tl,} \exp_args:Nx\label{sref_\l_@@_curr_label_str} \immediate\write\@auxout{\stexauxadddocref{\l_stex_current_docns_str}{\l_tmpa_str}} \str_gset:cx {sref_\l_@@_curr_label_str _type}\c_@@_ref_str } } % \end{macrocode} % \end{macro} % % The following is used to set the necessary macros in the |.aux|-file. % % \begin{macrocode} \cs_new_protected:Npn \stexauxadddocref #1 #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\stexauxadddocref#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{macrocode} \str_new:N \l_@@_indocument_str % \end{macrocode} % % \begin{macro}{\sref} % Optional arguments: % \begin{macrocode} \keys_define:nn { stex / sref } { linktext .tl_set:N = \l_@@_linktext_tl , fallback .tl_set:N = \l_@@_fallback_tl , pre .tl_set:N = \l_@@_pre_tl , post .tl_set:N = \l_@@_post_tl , } \cs_new_protected:Nn \_@@_args:n { \tl_clear:N \l_@@_linktext_tl \tl_clear:N \l_@@_fallback_tl \tl_clear:N \l_@@_pre_tl \tl_clear:N \l_@@_post_tl \str_clear:N \l_@@_repo_str \keys_set:nn { stex / sref } { #1 } } % \end{macrocode} % The actual macro: % \begin{macrocode} \NewDocumentCommand \sref { O{} m}{ \_@@_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 { \_@@_sym_aux:nn{linktext={#2}}{#1} } % \end{macrocode} % \end{macro} % % \begin{macrocode} % % \end{macrocode} % % \end{implementation} % \ifinfulldoc\else\printbibliography\fi % % \PrintIndex