% \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-Symbols % \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-symbols} package. % For a more high-level introduction, % see \href{\basedocurl/manual.pdf}{the \sTeX Manual} or the % \href{\basedocurl/stex.pdf}{full \sTeX documentation}. % % \tableofcontents % % \input{../../doc/packages/stex-symbols} % \fi % % \begin{documentation}\label{pkg:symbols:doc} % \changes{3.1.0}{2022/03/03}{Introduced sequence variables} % \changes{3.1.0}{2022/03/01}{Fixed bug with precedences in variables} % \changes{3.1.0}{2022/03/01}{Introduced \detokenize{\varemph, \varemph@uri}} % % Code related to symbol declarations and notations % % \section{Macros and Environments}\label{pkg:symbols:doc:macros} % % \begin{function}{\symdecl} % \begin{syntax} \cs{symdecl}\Arg{macroname}|[|\meta{args}|]| \end{syntax} % Declares a new symbol with semantic macro \cs{macroname}. Optional % arguments are: % \begin{itemize} % \item |name|: An (\omdoc) name. By default equal to \meta{macroname}. % \item |type|: An (ideally semantic) term, representing a \emph{type}. Not used by \sTeX, but % passed on to \mmt for semantic services. % \item |def|: An (ideally semantic) term, representing a \emph{definiens}. Not used by \sTeX, but % passed on to \mmt for semantic services. % \item |local|: A boolean (by default false). If set, this declaration % will not be added to the module content, i.e. importing % the current module will not make this declaration available. % \item |args|: Specifies the ``signature'' of the semantic macro. % Can be either an integer $0 \leq n \leq 9$, or a (more precise) % sequence of the following characters: % \begin{itemize} % \item[|i|] a ``normal'' argument, e.g. % |\symdecl{plus}[args=ii]| allows for |\plus{2}{2}|. % \item[|a|] an \emph{associative} argument; i.e. a sequence of % arbitrarily many arguments provided as a comma-separated list, % e.g. % |\symdecl{plus}[args=a]| allows for |\plus{2,2,2}|. % \item[|b|] a \emph{variable} argument. Is treated by \sTeX % like an |i|-argument, but an application is turned into % an |OMBind| in \omdoc, binding the provided variable % in the subsequent arguments of the operator; e.g. % |\symdecl{forall}[args=bi]| allows for |\forall{x\in\Nat}{x\geq0}|. % \end{itemize} % \end{itemize} % \end{function} % % \begin{function}{\stex_symdecl_do:n} % Implements the core functionality of \cs{symdecl}, and is % called by \cs{symdecl} and \cs{symdef}. % % Ultimately stores the symbol \meta{URI} in the property % list |\l_stex_symdecl_|\meta{URI}|_prop| with fields: % \begin{itemize} % \item |name| (string), % \item |module| (string), % \item |notations| (sequence of strings; initially empty), % \item |local| (boolean), % \item |type| (token list), % \item |args| (string of |i|s, |a|s and |b|s), % \item |arity| (integer string), % \item |assocs| (integer string; number of associative arguments), % \end{itemize} % \end{function} % % \begin{function}{\stex_all_symbols:n} % Iterates over all currently available symbols. % Requires two |\seq_map_break:| to break fully. % \end{function} % % \begin{function}{\stex_get_symbol:n} % Computes the full URI of a symbol from a macro argument, e.g. % the macro name, the macro itself, the full URI... % \end{function} % % \begin{function}{\notation} % \begin{syntax} \cs{notation}|[|\meta{args}|]|\Arg{symbol}\Arg{notations$^+$} \end{syntax} % Introduces a new notation for \meta{symbol}, see \cs{stex_notation_do:nn} % \end{function} % % \begin{function}{\stex_notation_do:nn} % \begin{syntax} \cs{stex_notation_do:nn}\Arg{URI}\Arg{notations$^+$}\end{syntax} % % Implements the core functionality of \cs{notation}, and is % called by \cs{notation} and \cs{symdef}. % % Ultimately stores the notation in the property % list\\ |\g_stex_notation_|\meta{URI}|#|\meta{variant}|#|^^A % \meta{lang}|_prop| with fields: % \begin{itemize} % \item |symbol| (URI string), % \item |language| (string), % \item |variant| (string), % \item |opprec| (integer string), % \item |argprecs| (sequence of integer strings) % \end{itemize} % \end{function} % % \begin{function}{\symdef} % \begin{syntax} \cs{symdef}|[|\meta{args}|]|\Arg{symbol}\Arg{notations$^+$} \end{syntax} % Combines \cs{symdecl} and \cs{notation} by introducing a new % symbol and assigning a new notation for it. % \end{function} % % \end{documentation} % % \begin{implementation}\label{pkg:symbols:impl} % % \section{\sTeX-Symbols Implementation} % % \begin{macrocode} %<*package> %%%%%%%%%%%%% symbols.dtx %%%%%%%%%%%%% % \end{macrocode} % % Warnings and error messages % % \begin{macrocode} \msg_new:nnn{stex}{error/wrongargs}{ args~value~in~symbol~declaration~for~#1~ needs~to~be~i,~a,~b~or~B,~but~#2~given } \msg_new:nnn{stex}{error/unknownsymbol}{ No~symbol~#1~found! } \msg_new:nnn{stex}{error/seqlength}{ Expected~#1~arguments;~got~#2! } \msg_new:nnn{stex}{error/unknownnotation}{ Unknown~notation~#1~for~#2! } % \end{macrocode} % % \subsection{Symbol Declarations} % \begin{macrocode} %<@@=stex_symdecl> % \end{macrocode} % % \begin{macro}{\stex_all_symbols:n} % Map over all available symbols % \begin{macrocode} \cs_new_protected:Nn \stex_all_symbols:n { \def \_@@_all_symbols_cs ##1 {#1} \seq_map_inline:Nn \l_stex_all_modules_seq { \seq_map_inline:cn{c_stex_module_##1_constants}{ \_@@_all_symbols_cs{##1?####1} } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\STEXsymbol} % \begin{macrocode} \NewDocumentCommand \STEXsymbol { m } { \stex_get_symbol:n { #1 } \exp_args:No \stex_invoke_symbol:n { \l_stex_get_symbol_uri_str } } % \end{macrocode} % \end{macro} % % |symdecl| arguments: % % \begin{macrocode} \keys_define:nn { stex / symdecl } { name .str_set_x:N = \l_stex_symdecl_name_str , local .bool_set:N = \l_stex_symdecl_local_bool , args .str_set_x:N = \l_stex_symdecl_args_str , type .tl_set:N = \l_stex_symdecl_type_tl , deprecate .str_set_x:N = \l_stex_symdecl_deprecate_str , align .str_set:N = \l_stex_symdecl_align_str , % TODO(?) gfc .str_set:N = \l_stex_symdecl_gfc_str , % TODO(?) specializes .str_set:N = \l_stex_symdecl_specializes_str , % TODO(?) def .tl_set:N = \l_stex_symdecl_definiens_tl , reorder .str_set_x:N = \l_stex_symdecl_reorder_str , assoc .choices:nn = {bin,binl,binr,pre,conj,pwconj} {\str_set:Nx \l_stex_symdecl_assoctype_str {\l_keys_choice_tl}} } \bool_new:N \l_stex_symdecl_make_macro_bool \cs_new_protected:Nn \_@@_args:n { \str_clear:N \l_stex_symdecl_name_str \str_clear:N \l_stex_symdecl_args_str \str_clear:N \l_stex_symdecl_deprecate_str \str_clear:N \l_stex_symdecl_reorder_str \str_clear:N \l_stex_symdecl_assoctype_str \bool_set_false:N \l_stex_symdecl_local_bool \tl_clear:N \l_stex_symdecl_type_tl \tl_clear:N \l_stex_symdecl_definiens_tl \keys_set:nn { stex / symdecl } { #1 } } % \end{macrocode} % % \begin{macro}{\symdecl} % % Parses the optional arguments and passes them on to % \cs{stex_symdecl_do:} (so that \cs{symdef} % can do the same) % % \begin{macrocode} \NewDocumentCommand \symdecl { s m O{}} { \_@@_args:n { #3 } \IfBooleanTF #1 { \bool_set_false:N \l_stex_symdecl_make_macro_bool } { \bool_set_true:N \l_stex_symdecl_make_macro_bool } \stex_symdecl_do:n { #2 } \stex_smsmode_do: } \cs_new_protected:Nn \stex_symdecl_do:nn { \_@@_args:n{#1} \bool_set_false:N \l_stex_symdecl_make_macro_bool \stex_symdecl_do:n{#2} } \stex_deactivate_macro:Nn \symdecl {module~environments} % \end{macrocode} % \end{macro} % % % \begin{macro}{\stex_symdecl_do:n} % \begin{macrocode} \cs_new_protected:Nn \stex_symdecl_do:n { \stex_if_in_module:F { % TODO throw error? some default namespace? } \str_if_empty:NT \l_stex_symdecl_name_str { \str_set:Nx \l_stex_symdecl_name_str { #1 } } \prop_if_exist:cT { l_stex_symdecl_ \l_stex_current_module_str ? \l_stex_symdecl_name_str _prop }{ % TODO throw error (beware of circular dependencies) } \prop_clear:N \l_tmpa_prop \prop_put:Nnx \l_tmpa_prop { module } { \l_stex_current_module_str } \seq_clear:N \l_tmpa_seq \prop_put:Nno \l_tmpa_prop { name } \l_stex_symdecl_name_str \prop_put:Nno \l_tmpa_prop { type } \l_stex_symdecl_type_tl \str_if_empty:NT \l_stex_symdecl_deprecate_str { \str_if_empty:NF \l_stex_module_deprecate_str { \str_set_eq:NN \l_stex_symdecl_deprecate_str \l_stex_module_deprecate_str } } \prop_put:Nno \l_tmpa_prop { deprecate } \l_stex_symdecl_deprecate_str \exp_args:No \stex_add_constant_to_current_module:n { \l_stex_symdecl_name_str } % arity/args \int_zero:N \l_tmpb_int \bool_set_true:N \l_tmpa_bool \str_map_inline:Nn \l_stex_symdecl_args_str { \token_case_meaning:NnF ##1 { 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} {\tl_to_str:n i} { \bool_set_false:N \l_tmpa_bool } {\tl_to_str:n b} { \bool_set_false:N \l_tmpa_bool } {\tl_to_str:n a} { \bool_set_false:N \l_tmpa_bool \int_incr:N \l_tmpb_int } {\tl_to_str:n B} { \bool_set_false:N \l_tmpa_bool \int_incr:N \l_tmpb_int } }{ \msg_error:nnxx{stex}{error/wrongargs}{ \l_stex_current_module_str ? \l_stex_symdecl_name_str }{##1} } } \bool_if:NTF \l_tmpa_bool { % possibly numeric \str_if_empty:NTF \l_stex_symdecl_args_str { \prop_put:Nnn \l_tmpa_prop { args } {} \prop_put:Nnn \l_tmpa_prop { arity } { 0 } }{ \int_set:Nn \l_tmpa_int { \l_stex_symdecl_args_str } \prop_put:Nnx \l_tmpa_prop { arity } { \int_use:N \l_tmpa_int } \str_clear:N \l_tmpa_str \int_step_inline:nn \l_tmpa_int { \str_put_right:Nn \l_tmpa_str i } \prop_put:Nnx \l_tmpa_prop { args } { \l_tmpa_str } } } { \prop_put:Nnx \l_tmpa_prop { args } { \l_stex_symdecl_args_str } \prop_put:Nnx \l_tmpa_prop { arity } { \str_count:N \l_stex_symdecl_args_str } } \prop_put:Nnx \l_tmpa_prop { assocs } { \int_use:N \l_tmpb_int } \tl_if_empty:NTF \l_stex_symdecl_definiens_tl { \prop_put:Nnx \l_tmpa_prop { defined }{ false } }{ \prop_put:Nnx \l_tmpa_prop { defined }{ true } } % semantic macro \bool_if:NT \l_stex_symdecl_make_macro_bool { \exp_args:Nx \stex_do_up_to_module:n { \tl_set:cn { #1 } { \stex_invoke_symbol:n { \l_stex_current_module_str ? \l_stex_symdecl_name_str }} } } \stex_debug:nn{symbols}{New~symbol:~ \l_stex_current_module_str ? \l_stex_symdecl_name_str^^J Type:~\exp_not:o { \l_stex_symdecl_type_tl }^^J Args:~\prop_item:Nn \l_tmpa_prop { args }^^J Definiens:~\exp_not:o {\l_stex_symdecl_definiens_tl} } % circular dependencies require this: \stex_if_do_html:T { \stex_annotate_invisible:nnn {symdecl} { \l_stex_current_module_str ? \l_stex_symdecl_name_str } { \tl_if_empty:NF \l_stex_symdecl_type_tl { \stex_annotate_invisible:nnn{type}{}{$\l_stex_symdecl_type_tl$} } \stex_annotate_invisible:nnn{args}{\prop_item:Nn \l_tmpa_prop { args }}{} \stex_annotate_invisible:nnn{macroname}{#1}{} \tl_if_empty:NF \l_stex_symdecl_definiens_tl { \stex_annotate_invisible:nnn{definiens}{} {$\l_stex_symdecl_definiens_tl$} } \str_if_empty:NF \l_stex_symdecl_assoctype_str { \stex_annotate_invisible:nnn{assoctype}{\l_stex_symdecl_assoctype_str}{} } \str_if_empty:NF \l_stex_symdecl_reorder_str { \stex_annotate_invisible:nnn{reorderargs}{\l_stex_symdecl_reorder_str}{} } } } \prop_if_exist:cF { l_stex_symdecl_ \l_stex_current_module_str ? \l_stex_symdecl_name_str _prop } { \bool_if:NTF \l_stex_symdecl_local_bool \stex_do_up_to_module:x \stex_execute_in_module:x { \_@@_restore_symbol:nnnnnnn {\l_stex_symdecl_name_str} { \prop_item:Nn \l_tmpa_prop {args} } { \prop_item:Nn \l_tmpa_prop {arity} } { \prop_item:Nn \l_tmpa_prop {assocs} } { \prop_item:Nn \l_tmpa_prop {defined} } {\bool_if:NT \l_stex_symdecl_make_macro_bool {#1} } {\l_stex_current_module_str} } } } \cs_new_protected:Nn \_@@_restore_symbol:nnnnnnn { \prop_clear:N \l_tmpa_prop \prop_put:Nnn \l_tmpa_prop { module } { #7 } \prop_put:Nnn \l_tmpa_prop { name } { #1} \prop_put:Nnn \l_tmpa_prop { args } {#2} \prop_put:Nnn \l_tmpa_prop { arity } { #3 } \prop_put:Nnn \l_tmpa_prop { assocs } { #4 } \prop_put:Nnn \l_tmpa_prop { defined } { #5 } \tl_if_empty:nF{#6}{ \tl_set:cx{#6}{\stex_invoke_symbol:n{\detokenize{#7 ? #1}}} } \prop_set_eq:cN{l_stex_symdecl_ \detokenize{#7 ? #1} _prop}\l_tmpa_prop \seq_clear:c{l_stex_symdecl_ \detokenize{#7 ? #1} _notations} } % \end{macrocode} % \end{macro} % % \begin{macro}{\textsymdecl} % \begin{macrocode} \keys_define:nn { stex / textsymdecl } { name .str_set_x:N = \l_@@_name_str , type .tl_set:N = \l_@@_type_tl } \cs_new_protected:Nn \_stex_textsymdecl_args:n { \str_clear:N \l_@@_name_str \tl_clear:N \l_@@_type_tl \keys_set:nn { stex / textsymdecl } { #1 } } \NewDocumentCommand \textsymdecl {m O{} m} { \_stex_textsymdecl_args:n { #2 } \str_if_empty:NTF \l_@@_name_str { \_@@_args:n{name=#1,#2} }{ \_@@_args:n{#2} } \bool_set_true:N \l_stex_symdecl_make_macro_bool \stex_symdecl_do:n{#1-sym} \stex_execute_in_module:n{ \cs_set_nopar:cpn{#1name}{ \ifvmode\hbox_unpack:N\c_empty_box\fi \hbox{#3}\xspace } \cs_set_nopar:cpn{#1}{ \ifmmode\csname#1-sym\expandafter\endcsname\else \ifvmode\hbox_unpack:N\c_empty_box\fi \symref{#1-sym}{\hbox{#3}}\expandafter\xspace \fi } } \stex_execute_in_module:x{ \__stex_notation_restore_notation:nnnnn {\l_stex_current_module_str?\tl_if_empty:NTF\l_@@_name_str{#1}\l_@@_name_str} {}{0} {\exp_not:n{\STEXInternalTermMathOMSiiii{\STEXInternalCurrentSymbolStr}{}{\neginfprec}{ \comp{\hbox{#3}}\STEXInternalSymbolAfterInvokationTL }}} {} } \stex_smsmode_do: } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_get_symbol:n} % % \begin{macrocode} \str_new:N \l_stex_get_symbol_uri_str \cs_new_protected:Nn \stex_get_symbol:n { \tl_if_head_eq_catcode:nNTF { #1 } \relax { \tl_set:Nn \l_tmpa_tl { #1 } \_@@_get_symbol_from_cs: }{ % argument is a string % is it a command name? \cs_if_exist:cTF { #1 }{ \cs_set_eq:Nc \l_tmpa_tl { #1 } \str_set:Nx \l_tmpa_str { \cs_argument_spec:N \l_tmpa_tl } \str_if_empty:NTF \l_tmpa_str { \exp_args:Nx \cs_if_eq:NNTF { \tl_head:N \l_tmpa_tl } \stex_invoke_symbol:n { \_@@_get_symbol_from_cs: }{ \_@@_get_symbol_from_string:n { #1 } } } { \_@@_get_symbol_from_string:n { #1 } } }{ % argument is not a command name \_@@_get_symbol_from_string:n { #1 } % \l_stex_all_symbols_seq } } \str_if_eq:eeF { \prop_item:cn { l_stex_symdecl_\l_stex_get_symbol_uri_str _prop }{ deprecate } }{}{ \msg_warning:nnxx{stex}{warning/deprecated}{ Symbol~\l_stex_get_symbol_uri_str }{ \prop_item:cn {l_stex_symdecl_\l_stex_get_symbol_uri_str _prop}{ deprecate } } } } \cs_new_protected:Nn \_@@_get_symbol_from_string:n { \tl_set:Nn \l_tmpa_tl { \msg_error:nnn{stex}{error/unknownsymbol}{#1} } \str_set:Nn \l_tmpa_str { #1 } %\int_set:Nn \l_tmpa_int { \str_count:N \l_tmpa_str } \str_if_in:NnTF \l_tmpa_str ? { \exp_args:NNno \seq_set_split:Nnn \l_tmpa_seq ? \l_tmpa_str \seq_pop_right:NN \l_tmpa_seq \l_tmpa_str \str_set:Nx \l_tmpb_str {\seq_use:Nn \l_tmpa_seq ?} }{ \str_clear:N \l_tmpb_str } \str_if_empty:NTF \l_tmpb_str { \seq_map_inline:Nn \l_stex_all_modules_seq { \seq_map_inline:cn{c_stex_module_##1_constants}{ \exp_args:Nno \str_if_eq:nnT{####1} \l_tmpa_str { \seq_map_break:n{\seq_map_break:n{ \tl_set:Nn \l_tmpa_tl { \str_set:Nn \l_stex_get_symbol_uri_str { ##1 ? ####1 } } }} } } } }{ \int_set:Nn \l_tmpa_int { \str_count:N \l_tmpb_str } \seq_map_inline:Nn \l_stex_all_modules_seq { \str_if_eq:eeT{ \l_tmpb_str }{ \str_range:nnn {##1}{-\l_tmpa_int}{-1}}{ \seq_map_inline:cn{c_stex_module_##1_constants}{ \exp_args:Nno \str_if_eq:nnT{####1} \l_tmpa_str { \seq_map_break:n{\seq_map_break:n{ \tl_set:Nn \l_tmpa_tl { \str_set:Nn \l_stex_get_symbol_uri_str { ##1 ? ####1 } } }} } } } } } \l_tmpa_tl } \cs_new_protected:Nn \_@@_get_symbol_from_cs: { \exp_args:NNx \tl_set:Nn \l_tmpa_tl { \tl_tail:N \l_tmpa_tl } \tl_if_single:NTF \l_tmpa_tl { \exp_args:No \tl_if_head_is_group:nTF \l_tmpa_tl { \exp_after:wN \str_set:Nn \exp_after:wN \l_stex_get_symbol_uri_str \l_tmpa_tl }{ % TODO % tail is not a single group } }{ % TODO % tail is not a single group } } % \end{macrocode} % \end{macro} % % \subsection{Notations} % \begin{macrocode} %<@@=stex_notation> % \end{macrocode} % % |notation| arguments: % % \begin{macrocode} \keys_define:nn { stex / notation } { % lang .tl_set_x:N = \l_@@_lang_str , variant .tl_set_x:N = \l_@@_variant_str , prec .str_set_x:N = \l_@@_prec_str , op .tl_set:N = \l_@@_op_tl , primary .bool_set:N = \l_@@_primary_bool , primary .default:n = {true} , unknown .code:n = \str_set:Nx \l_@@_variant_str \l_keys_key_str } \cs_new_protected:Nn \_stex_notation_args:n { % \str_clear:N \l_@@_lang_str \str_clear:N \l_@@_variant_str \str_clear:N \l_@@_prec_str \tl_clear:N \l_@@_op_tl \bool_set_false:N \l_@@_primary_bool \keys_set:nn { stex / notation } { #1 } } % \end{macrocode} % % % % \begin{macro}{\notation} % \begin{macrocode} \NewDocumentCommand \notation { s m O{}} { \_stex_notation_args:n { #3 } \tl_clear:N \l_stex_symdecl_definiens_tl \stex_get_symbol:n { #2 } \tl_set:Nn \l_stex_notation_after_do_tl { \_@@_final: \IfBooleanTF#1{ \stex_setnotation:n {\l_stex_get_symbol_uri_str} }{} \stex_smsmode_do:\ignorespacesandpars } \stex_notation_do:nnnnn { \prop_item:cn {l_stex_symdecl_\l_stex_get_symbol_uri_str _prop } { args } } { \prop_item:cn { l_stex_symdecl_\l_stex_get_symbol_uri_str _prop } { arity } } { \l_@@_variant_str } { \l_@@_prec_str} } \stex_deactivate_macro:Nn \notation {module~environments} % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_notation_do:nnnnn} % \begin{macrocode} \seq_new:N \l_@@_precedences_seq \tl_new:N \l_@@_opprec_tl \int_new:N \l_@@_currarg_int \tl_new:N \STEXInternalSymbolAfterInvokationTL \cs_new_protected:Nn \stex_notation_do:nnnnn { \let\STEXInternalCurrentSymbolStr\relax \seq_clear:N \l_@@_precedences_seq \tl_clear:N \l_@@_opprec_tl \str_set:Nx \l_@@_args_str { #1 } \str_set:Nx \l_@@_arity_str { #2 } \str_set:Nx \l_@@_suffix_str { #3 } \str_set:Nx \l_@@_prec_str { #4 } % precedences \str_if_empty:NTF \l_@@_prec_str { \int_compare:nNnTF \l_@@_arity_str = 0 { \tl_set:No \l_@@_opprec_tl { \neginfprec } }{ \tl_set:Nn \l_@@_opprec_tl { 0 } } } { \str_if_eq:onTF \l_@@_prec_str {nobrackets}{ \tl_set:No \l_@@_opprec_tl { \neginfprec } \int_step_inline:nn { \l_@@_arity_str } { \exp_args:NNo \seq_put_right:Nn \l_@@_precedences_seq { \infprec } } }{ \seq_set_split:NnV \l_tmpa_seq ; \l_@@_prec_str \seq_pop_left:NNTF \l_tmpa_seq \l_tmpa_str { \tl_set:No \l_@@_opprec_tl { \l_tmpa_str } \seq_pop_left:NNT \l_tmpa_seq \l_tmpa_str { \exp_args:NNNo \exp_args:NNno \seq_set_split:Nnn \l_tmpa_seq {\tl_to_str:n{x} } { \l_tmpa_str } \seq_map_inline:Nn \l_tmpa_seq { \seq_put_right:Nn \l_tmpb_seq { ##1 } } } }{ \int_compare:nNnTF \l_@@_arity_str = 0 { \tl_set:No \l_@@_opprec_tl { \infprec } }{ \tl_set:No \l_@@_opprec_tl { 0 } } } } } \seq_set_eq:NN \l_tmpa_seq \l_@@_precedences_seq \int_step_inline:nn { \l_@@_arity_str } { \seq_pop_left:NNF \l_tmpa_seq \l_tmpb_str { \exp_args:NNo \seq_put_right:No \l_@@_precedences_seq { \l_@@_opprec_tl } } } \tl_clear:N \l_stex_notation_dummyargs_tl \int_compare:nNnTF \l_@@_arity_str = 0 { \exp_args:NNe \cs_set:Npn \l_stex_notation_macrocode_cs { \STEXInternalTermMathOMSiiii { \STEXInternalCurrentSymbolStr } { \l_@@_suffix_str } { \l_@@_opprec_tl } { \exp_not:n { #5 } } } \l_stex_notation_after_do_tl }{ \str_if_in:NnTF \l_@@_args_str b { \exp_args:Nne \use:nn { \cs_generate_from_arg_count:NNnn \l_stex_notation_macrocode_cs \cs_set:Npn \l_@@_arity_str } { { \STEXInternalTermMathOMBiiii { \STEXInternalCurrentSymbolStr } { \l_@@_suffix_str } { \l_@@_opprec_tl } { \exp_not:n { #5 } } }} }{ \str_if_in:NnTF \l_@@_args_str B { \exp_args:Nne \use:nn { \cs_generate_from_arg_count:NNnn \l_stex_notation_macrocode_cs \cs_set:Npn \l_@@_arity_str } { { \STEXInternalTermMathOMBiiii { \STEXInternalCurrentSymbolStr } { \l_@@_suffix_str } { \l_@@_opprec_tl } { \exp_not:n { #5 } } } } }{ \exp_args:Nne \use:nn { \cs_generate_from_arg_count:NNnn \l_stex_notation_macrocode_cs \cs_set:Npn \l_@@_arity_str } { { \STEXInternalTermMathOMAiiii { \STEXInternalCurrentSymbolStr } { \l_@@_suffix_str } { \l_@@_opprec_tl } { \exp_not:n { #5 } } } } } } \str_set_eq:NN \l_@@_remaining_args_str \l_@@_args_str \int_zero:N \l_@@_currarg_int \seq_set_eq:NN \l_@@_remaining_precs_seq \l_@@_precedences_seq \_@@_arguments: } } % \end{macrocode} % \end{macro} % % \begin{macro}{\_@@_arguments:} % % Takes care of annotating the arguments in a % notation macro % % \begin{macrocode} \cs_new_protected:Nn \_@@_arguments: { \int_incr:N \l_@@_currarg_int \str_if_empty:NTF \l_@@_remaining_args_str { \l_stex_notation_after_do_tl }{ \str_set:Nx \l_tmpa_str { \str_head:N \l_@@_remaining_args_str } \str_set:Nx \l_@@_remaining_args_str { \str_tail:N \l_@@_remaining_args_str } \str_if_eq:VnTF \l_tmpa_str a { \_@@_argument_assoc:nn{a} }{ \str_if_eq:VnTF \l_tmpa_str B { \_@@_argument_assoc:nn{B} }{ \seq_pop_left:NN \l_@@_remaining_precs_seq \l_tmpb_str \tl_put_right:Nx \l_stex_notation_dummyargs_tl { { \STEXInternalTermMathArgiii { \l_tmpa_str\int_use:N \l_@@_currarg_int } { \l_tmpb_str } { ####\int_use:N \l_@@_currarg_int } } } \_@@_arguments: } } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\_@@_argument_assoc:nn} % \begin{macrocode} \cs_new_protected:Nn \_@@_argument_assoc:nn { \cs_generate_from_arg_count:NNnn \l_tmpa_cs \cs_set:Npn {\l_@@_arity_str}{ #2 } \int_zero:N \l_tmpa_int \tl_clear:N \l_tmpa_tl \str_map_inline:Nn \l_@@_args_str { \int_incr:N \l_tmpa_int \tl_put_right:Nx \l_tmpa_tl { \str_if_eq:nnTF {##1}{a}{ {} }{ \str_if_eq:nnTF {##1}{B}{ {} }{ {\_stex_term_arg:nn{##1\int_use:N \l_tmpa_int}{################ \int_use:N \l_tmpa_int}} } } } } \exp_after:wN\exp_after:wN\exp_after:wN \def \exp_after:wN\exp_after:wN\exp_after:wN \l_tmpa_cs \exp_after:wN\exp_after:wN\exp_after:wN ## \exp_after:wN\exp_after:wN\exp_after:wN 1 \exp_after:wN\exp_after:wN\exp_after:wN ## \exp_after:wN\exp_after:wN\exp_after:wN 2 \exp_after:wN\exp_after:wN\exp_after:wN { \exp_after:wN \exp_after:wN \exp_after:wN \exp_not:n \exp_after:wN \exp_after:wN \exp_after:wN { \exp_after:wN \l_tmpa_cs \l_tmpa_tl } } \seq_pop_left:NN \l_@@_remaining_precs_seq \l_tmpa_str \tl_put_right:Nx \l_stex_notation_dummyargs_tl { { \STEXInternalTermMathAssocArgiiii { #1\int_use:N \l_@@_currarg_int } { \l_tmpa_str } { ####\int_use:N \l_@@_currarg_int } { \l_tmpa_cs {####1} {####2} } } } \_@@_arguments: } % \end{macrocode} % \end{macro} % % \begin{macro}{\_@@_final:} % % Called after processing all notation arguments % % \begin{macrocode} \cs_new_protected:Nn \_@@_restore_notation:nnnnn { \cs_generate_from_arg_count:cNnn{stex_notation_\detokenize{#1} \c_hash_str \detokenize{#2}_cs} \cs_set_nopar:Npn {#3}{#4} \tl_if_empty:nF {#5}{ \tl_set:cn{stex_op_notation_\detokenize{#1} \c_hash_str \detokenize{#2}_cs}{ \comp{ #5 } } } \seq_if_exist:cT { l_stex_symdecl_\detokenize{#1} _notations }{ \seq_put_right:cx { l_stex_symdecl_\detokenize{#1} _notations } { \detokenize{#2} } } } \cs_new_protected:Nn \_@@_final: { \stex_execute_in_module:x { \_@@_restore_notation:nnnnn {\l_stex_get_symbol_uri_str} {\l_@@_suffix_str} {\l_@@_arity_str} { \exp_after:wN \exp_after:wN \exp_after:wN \exp_not:n \exp_after:wN \exp_after:wN \exp_after:wN { \exp_after:wN \l_stex_notation_macrocode_cs \l_stex_notation_dummyargs_tl \STEXInternalSymbolAfterInvokationTL} } {\exp_args:No \exp_not:n \l_@@_op_tl } } \stex_debug:nn{symbols}{ Notation~\l_@@_suffix_str ~for~\l_stex_get_symbol_uri_str^^J Operator~precedence:~\l_@@_opprec_tl^^J Argument~precedences:~ \seq_use:Nn \l_@@_precedences_seq {,~}^^J Notation: \cs_meaning:c { stex_notation_ \l_stex_get_symbol_uri_str \c_hash_str \l_@@_suffix_str _cs } } % HTML annotations \stex_if_do_html:T { \stex_annotate_invisible:nnn { notation } { \l_stex_get_symbol_uri_str } { \stex_annotate_invisible:nnn { notationfragment } { \l_@@_suffix_str }{} \stex_annotate_invisible:nnn { precedence } { \l_@@_prec_str }{} \int_zero:N \l_tmpa_int \str_set_eq:NN \l_@@_remaining_args_str \l_@@_args_str \tl_clear:N \l_tmpa_tl \int_step_inline:nn { \l_@@_arity_str }{ \int_incr:N \l_tmpa_int \str_set:Nx \l_tmpb_str { \str_head:N \l_@@_remaining_args_str } \str_set:Nx \l_@@_remaining_args_str { \str_tail:N \l_@@_remaining_args_str } \str_if_eq:VnTF \l_tmpb_str a { \tl_set:Nx \l_tmpa_tl { \l_tmpa_tl { \stex_annotate:nnn{argmarker}{\int_use:N \l_tmpa_int a}{} , \stex_annotate:nnn{argmarker}{\int_use:N \l_tmpa_int b}{} } } }{ \str_if_eq:VnTF \l_tmpb_str B { \tl_set:Nx \l_tmpa_tl { \l_tmpa_tl { \stex_annotate:nnn{argmarker}{\int_use:N \l_tmpa_int a}{} , \stex_annotate:nnn{argmarker}{\int_use:N \l_tmpa_int b}{} } } }{ \tl_set:Nx \l_tmpa_tl { \l_tmpa_tl { \stex_annotate:nnn{argmarker}{\int_use:N \l_tmpa_int}{} } } } } } \stex_annotate_invisible:nnn { notationcomp }{}{ \str_set:Nx \STEXInternalCurrentSymbolStr {\l_stex_get_symbol_uri_str } $ \exp_args:Nno \use:nn { \use:c { stex_notation_ \STEXInternalCurrentSymbolStr \c_hash_str \l_@@_suffix_str _cs } } { \l_tmpa_tl } $ } \tl_if_empty:NF \l_@@_op_tl { \stex_annotate_invisible:nnn { notationopcomp }{}{ $\l_@@_op_tl$ } } } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\setnotation} % \begin{macrocode} \keys_define:nn { stex / setnotation } { % lang .tl_set_x:N = \l_@@_lang_str , variant .tl_set_x:N = \l_@@_variant_str , unknown .code:n = \str_set:Nx \l_@@_variant_str \l_keys_key_str } \cs_new_protected:Nn \_stex_setnotation_args:n { % \str_clear:N \l_@@_lang_str \str_clear:N \l_@@_variant_str \keys_set:nn { stex / setnotation } { #1 } } \cs_new_protected:Nn \_@@_setnotation:nn { \seq_if_exist:cT{l_stex_symdecl_#1_notations}{ \seq_remove_all:cn { l_stex_symdecl_#1 _notations }{ #2 } \seq_put_left:cn { l_stex_symdecl_#1 _notations }{ #2 } } } \cs_new_protected:Nn \stex_setnotation:n { \exp_args:Nnx \seq_if_in:cnTF { l_stex_symdecl_#1 _notations } { \l_@@_variant_str }{ \stex_execute_in_module:x{ \_@@_setnotation:nn {#1}{\l_@@_variant_str} } \stex_debug:nn {notations}{ Setting~default~notation~ {\l_@@_variant_str }~for~ #1 \\ \expandafter\meaning\csname l_stex_symdecl_#1 _notations\endcsname } }{ \msg_error:nnxx{stex}{unknownnotation}{\l_@@_variant_str}{#1} } } \NewDocumentCommand \setnotation {m m} { \stex_get_symbol:n { #1 } \_stex_setnotation_args:n { #2 } \stex_setnotation:n{\l_stex_get_symbol_uri_str} \stex_smsmode_do:\ignorespacesandpars } \cs_new_protected:Nn \stex_copy_notations:nn { \stex_debug:nn {notations}{ Copying~notations~from~#2~to~#1\\ \seq_use:cn{l_stex_symdecl_#2_notations}{,~} } \tl_clear:N \l_tmpa_tl \int_step_inline:nn { \prop_item:cn {l_stex_symdecl_#2_prop}{ arity } } { \tl_put_right:Nn \l_tmpa_tl { {######## ##1} } } \seq_map_inline:cn {l_stex_symdecl_#2_notations}{\begingroup \stex_debug:nn{Here}{Here:~##1} \cs_set_eq:Nc \l_tmpa_cs { stex_notation_ #2 \c_hash_str ##1 _cs } \edef \l_tmpa_tl { \exp_after:wN\exp_after:wN\exp_after:wN \exp_not:n \exp_after:wN\exp_after:wN\exp_after:wN { \exp_after:wN \l_tmpa_cs \l_tmpa_tl } } \exp_after:wN \def \exp_after:wN \l_tmpa_tl \exp_after:wN ####\exp_after:wN 1 \exp_after:wN ####\exp_after:wN 2 \exp_after:wN { \l_tmpa_tl } \edef \l_tmpa_tl { \exp_after:wN \exp_not:n \exp_after:wN { \l_tmpa_tl {######## 1}{######## 2} } } \stex_debug:nn{Here}{Here:~\expandafter\detokenize\expandafter{\l_tmpa_tl}} \stex_execute_in_module:x { \_@@_restore_notation:nnnnn {#1}{##1} { \prop_item:cn {l_stex_symdecl_#2_prop}{ arity } } { \exp_after:wN\exp_not:n\exp_after:wN{\l_tmpa_tl} } { \cs_if_exist:cT{stex_op_notation_ #2\c_hash_str ##1 _cs}{ \exp_args:NNo\exp_args:No\exp_not:n{\csname stex_op_notation_ #2\c_hash_str ##1 _cs\endcsname} } } }\endgroup } } \NewDocumentCommand \copynotation {m m} { \stex_get_symbol:n { #1 } \str_set_eq:NN \l_tmpa_str \l_stex_get_symbol_uri_str \stex_get_symbol:n { #2 } \exp_args:Noo \stex_copy_notations:nn \l_tmpa_str \l_stex_get_symbol_uri_str \stex_smsmode_do:\ignorespacesandpars } % \end{macrocode} % \end{macro} % % \begin{macro}{\symdef} % \begin{macrocode} \keys_define:nn { stex / symdef } { name .str_set_x:N = \l_stex_symdecl_name_str , local .bool_set:N = \l_stex_symdecl_local_bool , args .str_set_x:N = \l_stex_symdecl_args_str , type .tl_set:N = \l_stex_symdecl_type_tl , def .tl_set:N = \l_stex_symdecl_definiens_tl , reorder .str_set_x:N = \l_stex_symdecl_reorder_str , op .tl_set:N = \l_@@_op_tl , % lang .str_set_x:N = \l_@@_lang_str , variant .str_set_x:N = \l_@@_variant_str , prec .str_set_x:N = \l_@@_prec_str , assoc .choices:nn = {bin,binl,binr,pre,conj,pwconj} {\str_set:Nx \l_stex_symdecl_assoctype_str {\l_keys_choice_tl}}, unknown .code:n = \str_set:Nx \l_@@_variant_str \l_keys_key_str } \cs_new_protected:Nn \_@@_symdef_args:n { \str_clear:N \l_stex_symdecl_name_str \str_clear:N \l_stex_symdecl_args_str \str_clear:N \l_stex_symdecl_assoctype_str \str_clear:N \l_stex_symdecl_reorder_str \bool_set_false:N \l_stex_symdecl_local_bool \tl_clear:N \l_stex_symdecl_type_tl \tl_clear:N \l_stex_symdecl_definiens_tl % \str_clear:N \l_@@_lang_str \str_clear:N \l_@@_variant_str \str_clear:N \l_@@_prec_str \tl_clear:N \l_@@_op_tl \keys_set:nn { stex / symdef } { #1 } } \NewDocumentCommand \symdef { m O{} } { \_@@_symdef_args:n { #2 } \bool_set_true:N \l_stex_symdecl_make_macro_bool \stex_symdecl_do:n { #1 } \tl_set:Nn \l_stex_notation_after_do_tl { \_@@_final: \stex_smsmode_do:\ignorespacesandpars } \str_set:Nx \l_stex_get_symbol_uri_str { \l_stex_current_module_str ? \l_stex_symdecl_name_str } \exp_args:Nx \stex_notation_do:nnnnn { \prop_item:cn {l_stex_symdecl_\l_stex_get_symbol_uri_str _prop } { args } } { \prop_item:cn { l_stex_symdecl_\l_stex_get_symbol_uri_str _prop } { arity } } { \l_@@_variant_str } { \l_@@_prec_str} } \stex_deactivate_macro:Nn \symdef {module~environments} % \end{macrocode} % \end{macro} % % \subsection{Variables} % % \begin{macrocode} %<@@=stex_variables> \keys_define:nn { stex / vardef } { name .str_set_x:N = \l_@@_name_str , args .str_set_x:N = \l_@@_args_str , type .tl_set:N = \l_@@_type_tl , def .tl_set:N = \l_@@_def_tl , op .tl_set:N = \l_@@_op_tl , prec .str_set_x:N = \l_@@_prec_str , reorder .str_set_x:N = \l_@@_reorder_str , assoc .choices:nn = {bin,binl,binr,pre,conj,pwconj} {\str_set:Nx \l_@@_assoctype_str {\l_keys_choice_tl}}, bind .choices:nn = {forall,exists} {\str_set:Nx \l_@@_bind_str {\l_keys_choice_tl}} } \cs_new_protected:Nn \_@@_args:n { \str_clear:N \l_@@_name_str \str_clear:N \l_@@_args_str \str_clear:N \l_@@_prec_str \str_clear:N \l_@@_assoctype_str \str_clear:N \l_@@_reorder_str \str_clear:N \l_@@_bind_str \tl_clear:N \l_@@_type_tl \tl_clear:N \l_@@_def_tl \tl_clear:N \l_@@_op_tl \keys_set:nn { stex / vardef } { #1 } } \NewDocumentCommand \_@@_do_simple:nnn { m O{}} { \_@@_args:n {#2} \str_if_empty:NT \l_@@_name_str { \str_set:Nx \l_@@_name_str { #1 } } \prop_clear:N \l_tmpa_prop \prop_put:Nno \l_tmpa_prop { name } \l_@@_name_str \int_zero:N \l_tmpb_int \bool_set_true:N \l_tmpa_bool \str_map_inline:Nn \l_@@_args_str { \token_case_meaning:NnF ##1 { 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} {\tl_to_str:n i} { \bool_set_false:N \l_tmpa_bool } {\tl_to_str:n b} { \bool_set_false:N \l_tmpa_bool } {\tl_to_str:n a} { \bool_set_false:N \l_tmpa_bool \int_incr:N \l_tmpb_int } {\tl_to_str:n B} { \bool_set_false:N \l_tmpa_bool \int_incr:N \l_tmpb_int } }{ \msg_error:nnxx{stex}{error/wrongargs}{ variable~\l_@@_name_str }{##1} } } \bool_if:NTF \l_tmpa_bool { % possibly numeric \str_if_empty:NTF \l_@@_args_str { \prop_put:Nnn \l_tmpa_prop { args } {} \prop_put:Nnn \l_tmpa_prop { arity } { 0 } }{ \int_set:Nn \l_tmpa_int { \l_@@_args_str } \prop_put:Nnx \l_tmpa_prop { arity } { \int_use:N \l_tmpa_int } \str_clear:N \l_tmpa_str \int_step_inline:nn \l_tmpa_int { \str_put_right:Nn \l_tmpa_str i } \str_set_eq:NN \l_@@_args_str \l_tmpa_str \prop_put:Nnx \l_tmpa_prop { args } { \l_@@_args_str } } } { \prop_put:Nnx \l_tmpa_prop { args } { \l_@@_args_str } \prop_put:Nnx \l_tmpa_prop { arity } { \str_count:N \l_@@_args_str } } \prop_put:Nnx \l_tmpa_prop { assocs } { \int_use:N \l_tmpb_int } \tl_set:cx { #1 }{ \stex_invoke_variable:n { \l_@@_name_str } } \prop_set_eq:cN { l_stex_variable_\l_@@_name_str _prop} \l_tmpa_prop \tl_if_empty:NF \l_@@_op_tl { \cs_set:cpx { stex_var_op_notation_ \l_@@_name_str _cs } { \exp_not:N\comp{ \exp_args:No \exp_not:n { \l_@@_op_tl } } } } \tl_set:Nn \l_stex_notation_after_do_tl { \exp_args:Nne \use:nn { \cs_generate_from_arg_count:cNnn { stex_var_notation_\l_@@_name_str _cs } \cs_set:Npn { \prop_item:Nn \l_tmpa_prop { arity } } } {{ \exp_after:wN \exp_after:wN \exp_after:wN \exp_not:n \exp_after:wN \exp_after:wN \exp_after:wN { \exp_after:wN \l_stex_notation_macrocode_cs \l_stex_notation_dummyargs_tl \STEXInternalSymbolAfterInvokationTL} }} \stex_if_do_html:T { \stex_annotate_invisible:nnn {vardecl}{\l_@@_name_str}{ \stex_annotate_invisible:nnn { precedence } { \l_@@_prec_str }{} \tl_if_empty:NF \l_@@_type_tl {\stex_annotate_invisible:nnn{type}{}{$\l_@@_type_tl$}} \stex_annotate_invisible:nnn{args}{ \l_@@_args_str }{} \stex_annotate_invisible:nnn{macroname}{#1}{} \tl_if_empty:NF \l_@@_def_tl { \stex_annotate_invisible:nnn{definiens}{} {$\l_@@_def_tl$} } \str_if_empty:NF \l_@@_assoctype_str { \stex_annotate_invisible:nnn{assoctype}{\l_@@_assoctype_str}{} } \str_if_empty:NF \l_@@_reorder_str { \stex_annotate_invisible:nnn{reorderargs}{\l_@@_reorder_str}{} } \int_zero:N \l_tmpa_int \str_set_eq:NN \l_@@_remaining_args_str \l_@@_args_str \tl_clear:N \l_tmpa_tl \int_step_inline:nn { \prop_item:Nn \l_tmpa_prop { arity } }{ \int_incr:N \l_tmpa_int \str_set:Nx \l_tmpb_str { \str_head:N \l_@@_remaining_args_str } \str_set:Nx \l_@@_remaining_args_str { \str_tail:N \l_@@_remaining_args_str } \str_if_eq:VnTF \l_tmpb_str a { \tl_set:Nx \l_tmpa_tl { \l_tmpa_tl { \stex_annotate:nnn{argmarker}{\int_use:N \l_tmpa_int a}{} , \stex_annotate:nnn{argmarker}{\int_use:N \l_tmpa_int b}{} } } }{ \str_if_eq:VnTF \l_tmpb_str B { \tl_set:Nx \l_tmpa_tl { \l_tmpa_tl { \stex_annotate:nnn{argmarker}{\int_use:N \l_tmpa_int a}{} , \stex_annotate:nnn{argmarker}{\int_use:N \l_tmpa_int b}{} } } }{ \tl_set:Nx \l_tmpa_tl { \l_tmpa_tl { \stex_annotate:nnn{argmarker}{\int_use:N \l_tmpa_int}{} } } } } } \stex_annotate_invisible:nnn { notationcomp }{}{ \str_set:Nx \STEXInternalCurrentSymbolStr {var://\l_@@_name_str } $ \exp_args:Nno \use:nn { \use:c { stex_var_notation_\l_@@_name_str _cs } } { \l_tmpa_tl } $ } \tl_if_empty:NF \l_@@_op_tl { \stex_annotate_invisible:nnn { notationopcomp }{}{ $\l_@@_op_tl$ } } } \str_if_empty:NF \l_@@_bind_str { \stex_annotate_invisible:nnn {bindtype}{\l_@@_bind_str,\l_@@_name_str}{} } }\ignorespacesandpars } \stex_notation_do:nnnnn { \l_@@_args_str } { \prop_item:Nn \l_tmpa_prop { arity } } {}{ \l_@@_prec_str} } \cs_new:Nn \_stex_reset:N { \tl_if_exist:NTF #1 { \def \exp_not:N #1 { \exp_args:No \exp_not:n #1 } }{ \let \exp_not:N #1 \exp_not:N \undefined } } \NewDocumentCommand \_@@_do_complex:nn { m m }{ \clist_set:Nx \l_@@_names { \tl_to_str:n {#1} } \exp_args:Nnx \use:nn { % TODO \stex_annotate_invisible:nnn {vardecl}{\clist_use:Nn\l_@@_names,}{ #2 } }{ \_stex_reset:N \varnot \_stex_reset:N \vartype \_stex_reset:N \vardefi } } \NewDocumentCommand \vardef { s } { \IfBooleanTF#1 { \_@@_do_complex:nn }{ \_@@_do_simple:nnn } } \NewDocumentCommand \svar { O{} m }{ \tl_if_empty:nTF {#1}{ \str_set:Nn \l_tmpa_str { #2 } }{ \str_set:Nn \l_tmpa_str { #1 } } \_stex_term_omv:nn { var://\l_tmpa_str }{ \exp_args:Nnx \use:nn { \def\comp{\_varcomp} \str_set:Nx \STEXInternalCurrentSymbolStr { var://\l_tmpa_str } \comp{ #2 } }{ \_stex_reset:N \comp \_stex_reset:N \STEXInternalCurrentSymbolStr } } } \keys_define:nn { stex / varseq } { name .str_set_x:N = \l_@@_name_str , args .int_set:N = \l_@@_args_int , type .tl_set:N = \l_@@_type_tl , mid .tl_set:N = \l_@@_mid_tl , bind .choices:nn = {forall,exists} {\str_set:Nx \l_@@_bind_str {\l_keys_choice_tl}} } \cs_new_protected:Nn \_@@_seq_args:n { \str_clear:N \l_@@_name_str \int_set:Nn \l_@@_args_int 1 \tl_clear:N \l_@@_type_tl \str_clear:N \l_@@_bind_str \keys_set:nn { stex / varseq } { #1 } } \NewDocumentCommand \varseq {m O{} m m m}{ \_@@_seq_args:n { #2 } \str_if_empty:NT \l_@@_name_str { \str_set:Nx \l_@@_name_str { #1 } } \prop_clear:N \l_tmpa_prop \prop_put:Nnx \l_tmpa_prop { arity }{\int_use:N \l_@@_args_int} \seq_set_from_clist:Nn \l_tmpa_seq {#3} \int_compare:nNnF {\seq_count:N \l_tmpa_seq} = \l_@@_args_int { \msg_error:nnxx{stex}{error/seqlength} {\int_use:N \l_@@_args_int} {\seq_count:N \l_tmpa_seq} } \seq_set_from_clist:Nn \l_tmpb_seq {#4} \int_compare:nNnF {\seq_count:N \l_tmpb_seq} = \l_@@_args_int { \msg_error:nnxx{stex}{error/seqlength} {\int_use:N \l_@@_args_int} {\seq_count:N \l_tmpb_seq} } \prop_put:Nnn \l_tmpa_prop {starts} {#3} \prop_put:Nnn \l_tmpa_prop {ends} {#4} \cs_generate_from_arg_count:cNnn {stex_varseq_\l_@@_name_str _cs} \cs_set:Npn {\int_use:N \l_@@_args_int} { #5 } \exp_args:NNo \tl_set:No \l_tmpa_tl {\use:c{stex_varseq_\l_@@_name_str _cs}} \int_step_inline:nn \l_@@_args_int { \tl_put_right:Nx \l_tmpa_tl { {\seq_item:Nn \l_tmpa_seq {##1}} } } \tl_set:Nx \l_tmpa_tl {\exp_args:NNo \exp_args:No \exp_not:n{\l_tmpa_tl}} \tl_put_right:Nn \l_tmpa_tl {,\ellipses,} \tl_if_empty:NF \l_@@_mid_tl { \tl_put_right:No \l_tmpa_tl \l_@@_mid_tl \tl_put_right:Nn \l_tmpa_tl {,\ellipses,} } \exp_args:NNo \tl_set:No \l_tmpb_tl {\use:c{stex_varseq_\l_@@_name_str _cs}} \int_step_inline:nn \l_@@_args_int { \tl_put_right:Nx \l_tmpb_tl { {\seq_item:Nn \l_tmpb_seq {##1}} } } \tl_set:Nx \l_tmpb_tl {\exp_args:NNo \exp_args:No \exp_not:n{\l_tmpb_tl}} \tl_put_right:No \l_tmpa_tl \l_tmpb_tl \prop_put:Nno \l_tmpa_prop { notation }\l_tmpa_tl \tl_set:cx {#1} {\stex_invoke_sequence:n {\l_@@_name_str}} \exp_args:NNo \tl_set:No \l_tmpa_tl {\use:c{stex_varseq_\l_@@_name_str _cs}} \int_step_inline:nn \l_@@_args_int { \tl_set:Nx \l_tmpa_tl {\exp_args:No \exp_not:n \l_tmpa_tl { \STEXInternalTermMathArgiii{i##1}{0}{\exp_not:n{####}##1} }} } \tl_set:Nx \l_tmpa_tl { \STEXInternalTermMathOMAiiii { varseq://\l_@@_name_str}{}{0}{ \exp_args:NNo \exp_args:No \exp_not:n {\l_tmpa_tl} } } \tl_set:No \l_tmpa_tl { \exp_after:wN { \l_tmpa_tl \STEXInternalSymbolAfterInvokationTL} } \exp_args:Nno \use:nn { \cs_generate_from_arg_count:cNnn {stex_varseq_\l_@@_name_str _cs} \cs_set:Npn {\int_use:N \l_@@_args_int}}{\l_tmpa_tl} \stex_debug:nn{sequences}{New~Sequence:~ \expandafter\meaning\csname stex_varseq_\l_@@_name_str _cs\endcsname\\~\\ \prop_to_keyval:N \l_tmpa_prop } \stex_if_do_html:T{\stex_annotate_invisible:nnn{varseq}{\l_@@_name_str}{ \tl_if_empty:NF \l_@@_type_tl { \stex_annotate:nnn {type}{}{$\l_@@_type_tl$} } \stex_annotate:nnn {args}{\int_use:N \l_@@_args_int}{} \str_if_empty:NF \l_@@_bind_str { \stex_annotate:nnn {bindtype}{\l_@@_bind_str}{} } \stex_annotate:nnn{startindex}{}{$#3$} \stex_annotate:nnn{endindex}{}{$#4$} \tl_clear:N \l_tmpa_tl \int_step_inline:nn \l_@@_args_int { \tl_set:Nx \l_tmpa_tl { \l_tmpa_tl { \stex_annotate:nnn{argmarker}{##1}{} } } } \stex_annotate_invisible:nnn { notationcomp }{}{ \str_set:Nx \STEXInternalCurrentSymbolStr {varseq://\l_@@_name_str } $ \exp_args:Nno \use:nn { \use:c { stex_varseq_\l_@@_name_str _cs } } { \l_tmpa_tl } $ } \stex_annotate_invisible:nnn { notationopcomp }{}{ $ \prop_item:Nn \l_tmpa_prop { notation } $ } }} \prop_set_eq:cN {stex_varseq_\l_@@_name_str _prop}\l_tmpa_prop \ignorespacesandpars } % \end{macrocode} % % \begin{macrocode} % % \end{macrocode} % % \end{implementation} % \ifinfulldoc\else\printbibliography\fi % % \PrintIndex % \endinput % Local Variables: % mode: doctex % TeX-master: t % End: