% \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} % % \fi % % \title{ \sTeX-Terms % \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-terms} package. % For a more high-level introduction, % see \href{\basedocurl/manual.pdf}{the \sTeX Manual} or the % \href{\basedocurl/stex.pdf}{full \sTeX documentation}. % % \input{../../doc/packages/stex-terms} % \fi % % \begin{documentation}\label{pkg:terms:doc} % \changes{3.1.0}{2022/03/01}{!-Notation now works for symbols with arity=0 without needing an op-notation} % \changes{3.1.0}{2022/03/01}{Introduced \detokenize{\varemph, \varemph@uri}} % \changes{3.1.0}{2022/02/28}{Fixed bug with \detokenize{\STEXInternalCurrentSymbolStr} in variable annotations} % % Code related to symbolic expressions, typesetting notations, % notation components, etc. % % \section{Macros and Environments}\label{pkg:terms:doc:macros} % % \begin{function}{\STEXsymbol} % Uses \cs{stex_get_symbol:n} to find the symbol denoted by % the first argument and passes the result on to % \cs{stex_invoke_symbol:n} % \end{function} % % \begin{function}{\symref} % \begin{syntax} \cs{symref}\Arg{symbol}\Arg{text} \end{syntax} % shortcut for \cs{STEXsymbol}\Arg{symbol}|![|\meta{text}|]| % \end{function} % % \begin{function}{\stex_invoke_symbol:n} % Executes a semantic macro. Outside of math mode or if followed by |*|, % it continues to \cs{stex_term_custom:nn}. In math mode, % it uses the default or optionally provided notation of % the associated symbol. % % If followed by |!|, it will invoke the symbol \emph{itself} % rather than its application (and continue to % \cs{stex_term_custom:nn}), i.e. it allows to refer to % |\plus![addition]| as an operation, rather than % |\plus[addition of]{some}{terms}|. % \end{function} % % \begin{function}{\STEXInternalTermMathOMSiiii,\STEXInternalTermMathOMAiiii,\STEXInternalTermMathOMBiiii} % \begin{syntax} \meta{URI}\meta{fragment}\meta{precedence}\meta{body} \end{syntax} % % Annotates \meta{body} as an \omdoc-term (|OMID|, |OMA| or |OMBIND|, respectively) % with head symbol \meta{URI}, generated % by the specific notation \meta{fragment} with (upwards) operator precedence % \meta{precedence}. Inserts parentheses according to % the current downwards precedence and operator precedence. % \end{function} % % \begin{function}{\STEXInternalTermMathArgiii} % \begin{syntax} \cs{stex_term_arg:nnn}\meta{int}\meta{prec}\meta{body} \end{syntax} % Annotates \meta{body} as the \meta{int}th argument of the current |OMA| or |OMBIND|, % with (downwards) argument precedence \meta{prec}. % \end{function} % % \begin{function}{\STEXInternalTermMathAssocArgiiiii} % \begin{syntax} \cs{stex_term_arg:nnn}\meta{int}\meta{prec}\meta{notation}\meta{type}\meta{body} \end{syntax} % Annotates \meta{body} as the \meta{int}th (associative) \emph{sequence} argument % (as comma-separated list of terms) of the current |OMA| or |OMBIND|, % with (downwards) argument precedence \meta{prec} and associative % notation \meta{notation}. % % \end{function} % % \begin{variable}{\infprec, \neginfprec} % Maximal and minimal notation precedences. % \end{variable} % % \begin{function}{\dobrackets} % \begin{syntax} \cs{dobrackets} \Arg{body} \end{syntax} % Puts \meta{body} in parentheses; scaled if in display mode % unscaled otherwise. Uses the current \sTeX brackets (by default |(| and |)|), % which can be changed temporarily using \cs{withbrackets}. % \end{function} % % \begin{function}{\withbrackets} % \begin{syntax} \cs{withbrackets} \meta{left} \meta{right} \Arg{body} \end{syntax} % Temporarily (i.e. within \meta{body}) sets the brackets used by \sTeX for automated % bracketing (by default |(| and |)|) to \meta{left} and \meta{right}. % % Note that \meta{left} and \meta{right} need to be allowed % after \cs{left} and \cs{right} in displaymode. % \end{function} % % \begin{function}{\stex_term_custom:nn} % \begin{syntax} \cs{stex_term_custom:nn}\Arg{URI}\Arg{args}\end{syntax} % Implements custom one-time notation. % Invoked by \cs{stex_invoke_symbol:n} in text mode, or if % followed by |*| in math mode, or whenever followed by |!|. % \end{function} % % \begin{function}{\comp, \compemph,\compemph@uri, \defemph, \defemph@uri, \symrefemph,\symrefemph@uri,\varemph,\varemph@uri} % \begin{syntax} \cs{comp}\Arg{args}\end{syntax} % Marks \meta{args} as a notation component of the current symbol for % highlighting, linking, etc. % % The precise behavior is governed by \cs{@comp}, which takes as % additional argument the URI of the current symbol. By default, % \cs{@comp} adds the URI as a PDF tooltip and colors the highlighted part % in blue. % % \cs{@defemph} behaves like \cs{@comp}, and can be similarly redefined, % but marks an expression as \emph{definiendum} (used by \cs{definiendum}) % \end{function} % % \begin{function}{\STEXinvisible} % Exports its argument as \omdoc (invisible), but does % not produce PDF output. Useful e.g. for semantic macros % that take arguments that are not part of the symbolic % notation. % \end{function} % % \begin{function}{\ellipses} % TODO % \end{function} % % \end{documentation} % % \begin{implementation}\label{pkg:terms:impl} % % \section{\sTeX-Terms Implementation} % % \begin{macrocode} %<*package> %%%%%%%%%%%%% terms.dtx %%%%%%%%%%%%% %<@@=stex_terms> % \end{macrocode} % % Warnings and error messages % % \begin{macrocode} \msg_new:nnn{stex}{error/nonotation}{ Symbol~#1~invoked,~but~has~no~notation#2! } \msg_new:nnn{stex}{error/notationarg}{ Error~in~parsing~notation~#1 } \msg_new:nnn{stex}{error/noop}{ Symbol~#1~has~no~operator~notation~for~notation~#2 } \msg_new:nnn{stex}{error/notallowed}{ Symbol~invokation~#1~not~allowed~in~notation~component~of~#2 } \msg_new:nnn{stex}{error/doubleargument}{ Argument~#1~of~symbol~#2~already~assigned } \msg_new:nnn{stex}{error/overarity}{ Argument~#1~invalid~for~symbol~#2~with~arity~#3 } % \end{macrocode} % \subsection{Symbol Invocations} % % % \begin{macro}{\stex_invoke_symbol:n} % % Invokes a semantic macro % % \begin{macrocode} \bool_new:N \l_stex_allow_semantic_bool \bool_set_true:N \l_stex_allow_semantic_bool \cs_new_protected:Nn \stex_invoke_symbol:n { \ifvmode\indent\fi \bool_if:NTF \l_stex_allow_semantic_bool { \str_if_eq:eeF { \prop_item:cn { l_stex_symdecl_#1_prop }{ deprecate } }{}{ \msg_warning:nnxx{stex}{warning/deprecated}{ Symbol~#1 }{ \prop_item:cn {l_stex_symdecl_#1_prop}{ deprecate } } } \if_mode_math: \exp_after:wN \_@@_invoke_math:n \else: \exp_after:wN \_@@_invoke_text:n \fi: { #1 } }{ \msg_error:nnxx{stex}{error/notallowed}{#1}{\STEXInternalCurrentSymbolStr} } } \cs_new_protected:Nn \_@@_invoke_text:n { \peek_charcode_remove:NTF ! { \_@@_invoke_op_custom:nn {#1} }{ \_@@_invoke_custom:nn {#1} } } \cs_new_protected:Nn \_@@_invoke_math:n { \peek_charcode_remove:NTF ! { % operator \peek_charcode_remove:NTF * { % custom op \_@@_invoke_op_custom:nn {#1} }{ % op notation \peek_charcode:NTF [ { \_@@_invoke_op_notation:nw {#1} }{ \_@@_invoke_op_notation:nw {#1}[] } } }{ \peek_charcode_remove:NTF * { \_@@_invoke_custom:nn {#1} % custom }{ % normal \peek_charcode:NTF [ { \_@@_invoke_notation:nw {#1} }{ \_@@_invoke_notation:nw {#1}[] } } } } \cs_new_protected:Nn \_@@_invoke_op_custom:nn { \exp_args:Nnx \use:nn { \def\comp{\_comp} \str_set:Nn \STEXInternalCurrentSymbolStr { #1 } \bool_set_false:N \l_stex_allow_semantic_bool \stex_mathml_intent:nn{#1}{ \_stex_term_oms:nnn {#1}{#1 \c_hash_str CUSTOM-}{ \comp{ #2 } } } }{ \_stex_reset:N \comp \_stex_reset:N \STEXInternalCurrentSymbolStr \bool_set_true:N \l_stex_allow_semantic_bool } } \keys_define:nn { stex / terms } { % lang .tl_set_x:N = \l_stex_notation_lang_str , variant .tl_set_x:N = \l_stex_notation_variant_str , unknown .code:n = \str_set:Nx \l_stex_notation_variant_str \l_keys_key_str } \cs_new_protected:Nn \_@@_args:n { % \str_clear:N \l_stex_notation_lang_str \str_clear:N \l_stex_notation_variant_str \keys_set:nn { stex / terms } { #1 } } \cs_new_protected:Nn \stex_find_notation:nn { \_@@_args:n { #2 } \seq_if_empty:cTF { l_stex_symdecl_ #1 _notations } { \msg_error:nnxx{stex}{error/nonotation}{#1}{s} } { \str_if_empty:NTF \l_stex_notation_variant_str { \seq_get_left:cN {l_stex_symdecl_#1_notations}\l_stex_notation_variant_str }{ \seq_if_in:cxTF {l_stex_symdecl_#1_notations}{ \l_stex_notation_variant_str }{ % \str_set:Nx \l_stex_notation_variant_str { \l_stex_notation_variant_str \c_hash_str \l_stex_notation_lang_str } }{ \msg_error:nnxx{stex}{error/nonotation}{#1}{ ~\l_stex_notation_variant_str } } } } } \cs_new_protected:Npn \_@@_invoke_op_notation:nw #1 [#2] { \exp_args:Nnx \use:nn { \def\comp{\_comp} \str_set:Nn \STEXInternalCurrentSymbolStr { #1 } \stex_find_notation:nn { #1 }{ #2 } \bool_set_false:N \l_stex_allow_semantic_bool \cs_if_exist:cTF { stex_op_notation_ #1 \c_hash_str \l_stex_notation_variant_str _cs }{ \_stex_term_oms:nnn { #1 }{ #1 \c_hash_str \l_stex_notation_variant_str }{ \use:c{stex_op_notation_ #1 \c_hash_str \l_stex_notation_variant_str _cs} } }{ \int_compare:nNnTF {\prop_item:cn {l_stex_symdecl_#1_prop}{arity}} = 0{ \cs_if_exist:cTF { stex_notation_ #1 \c_hash_str \l_stex_notation_variant_str _cs }{ \tl_set:Nx \STEXInternalSymbolAfterInvokationTL { \_stex_reset:N \comp \_stex_reset:N \STEXInternalSymbolAfterInvokationTL \_stex_reset:N \STEXInternalCurrentSymbolStr \bool_set_true:N \l_stex_allow_semantic_bool } \def\comp{\_comp} \str_set:Nn \STEXInternalCurrentSymbolStr { #1 } \bool_set_false:N \l_stex_allow_semantic_bool \use:c{stex_notation_ #1 \c_hash_str \l_stex_notation_variant_str _cs} }{ \msg_error:nnxx{stex}{error/nonotation}{#1}{ ~\l_stex_notation_variant_str } } }{ \msg_error:nnxx{stex}{error/noop}{#1}{\l_stex_notation_variant_str} } } }{ \_stex_reset:N \comp \_stex_reset:N \STEXInternalCurrentSymbolStr \bool_set_true:N \l_stex_allow_semantic_bool } } \cs_new_protected:Npn \_@@_invoke_notation:nw #1 [#2] { \stex_find_notation:nn { #1 }{ #2 } \cs_if_exist:cTF { stex_notation_ #1 \c_hash_str \l_stex_notation_variant_str _cs }{ \tl_set:Nx \STEXInternalSymbolAfterInvokationTL { \_stex_reset:N \comp \_stex_reset:N \STEXInternalSymbolAfterInvokationTL \_stex_reset:N \STEXInternalCurrentSymbolStr \bool_set_true:N \l_stex_allow_semantic_bool } \def\comp{\_comp} \str_set:Nn \STEXInternalCurrentSymbolStr { #1 } \bool_set_false:N \l_stex_allow_semantic_bool \use:c{stex_notation_ #1 \c_hash_str \l_stex_notation_variant_str _cs} }{ \msg_error:nnxx{stex}{error/nonotation}{#1}{ ~\l_stex_notation_variant_str } } } \prop_new:N \l_@@_custom_args_prop \clist_new:N \l_stex_argnames_seq \seq_new:N \l_@@_tmp_seq \cs_new_protected:Nn\_@@_custom_comp:n{\bool_set_false:N \l_stex_allow_semantic_bool\_comp{#1}\bool_set_true:N \l_stex_allow_semantic_bool} \cs_new_protected:Nn \_@@_invoke_custom:nn { \exp_args:Nnx \use:nn { \def\comp{\_@@_custom_comp:n} \str_set:Nn \STEXInternalCurrentSymbolStr { #1 } \prop_clear:N \l_@@_custom_args_prop \prop_put:Nnn \l_@@_custom_args_prop {currnum} {1} \prop_get:cnN { l_stex_symdecl_#1 _prop }{ args } \l_tmpa_str \exp_args:NNx \seq_set_from_clist:Nn \l_stex_argnames_seq { \prop_item:cn {l_stex_symdecl_#1 _prop}{argnames} } \prop_put:Nno \l_@@_custom_args_prop {args} \l_tmpa_str \tl_set:Nn \arg { \_@@_arg: } \str_if_empty:NTF \l_tmpa_str { \stex_mathml_intent:nn{#1}{ \_stex_term_oms:nnn {#1}{#1\c_hash_str CUSTOM-}{\ignorespaces#2} } }{ \seq_clear:N \l_@@_tmp_seq \exp_args:Nx\int_step_inline:nn{\prop_item:cn{l_stex_symdecl_#1 _prop}{arity}}{ \tl_set:Nx \l_@@_tmp_tl {\seq_item:Nn \l_stex_argnames_seq {##1}} \bool_lazy_or:nnT{ \str_if_eq_p:nn{a}{\str_item:Nn\l_tmpa_str{##1}} }{ \str_if_eq_p:nn{B}{\str_item:Nn\l_tmpa_str{##1}} }{ \tl_put_right:Nn \l_@@_tmp_tl + } \seq_put_right:No \l_@@_tmp_seq \l_@@_tmp_tl } \stex_mathml_intent:nn{ #1[\prop_item:cn {l_stex_symdecl_#1 _prop}{ args }]( \seq_use:Nn \l_@@_tmp_seq , ) }{ \str_if_in:NnTF \l_tmpa_str b { \_stex_term_ombind:nnn {#1}{#1\c_hash_str CUSTOM-\l_tmpa_str}{\ignorespaces#2} }{ \str_if_in:NnTF \l_tmpa_str B { \_stex_term_ombind:nnn {#1}{#1\c_hash_str CUSTOM-\l_tmpa_str}{\ignorespaces#2} }{ \_stex_term_oma:nnn {#1}{#1\c_hash_str CUSTOM-\l_tmpa_str}{\ignorespaces#2} } } } } % TODO check that all arguments exist }{ \_stex_reset:N \l_stex_argnames_seq \_stex_reset:N \STEXInternalCurrentSymbolStr \_stex_reset:N \arg \_stex_reset:N \comp \_stex_reset:N \l_@@_custom_args_prop %\bool_set_true:N \l_stex_allow_semantic_bool } } \NewDocumentCommand \_@@_arg: { s O{} m}{ \tl_if_empty:nTF {#2}{ \int_set:Nn \l_tmpa_int {\prop_item:Nn \l_@@_custom_args_prop {currnum}} \bool_set_true:N \l_tmpa_bool \bool_do_while:Nn \l_tmpa_bool { \exp_args:NNx \prop_if_in:NnTF \l_@@_custom_args_prop {\int_use:N \l_tmpa_int} { \int_incr:N \l_tmpa_int }{ \bool_set_false:N \l_tmpa_bool } } }{ \int_set:Nn \l_tmpa_int { #2 } } \str_set:Nx \l_tmpa_str {\prop_item:Nn \l_@@_custom_args_prop {args} } \int_compare:nNnT \l_tmpa_int > {\str_count:N \l_tmpa_str} { \msg_error:nnxxx{stex}{error/overarity} {\int_use:N \l_tmpa_int} {\STEXInternalCurrentSymbolStr} {\str_count:N \l_tmpa_str} } \str_set:Nx \l_tmpa_str {\str_item:Nn \l_tmpa_str \l_tmpa_int} \exp_args:NNx \prop_if_in:NnT \l_@@_custom_args_prop {\int_use:N \l_tmpa_int} { \bool_lazy_any:nF { {\str_if_eq_p:Vn \l_tmpa_str {a}} {\str_if_eq_p:Vn \l_tmpa_str {B}} }{ \msg_error:nnxx{stex}{error/doubleargument} {\int_use:N \l_tmpa_int} {\STEXInternalCurrentSymbolStr} } } \exp_args:NNx \prop_put:Nnn \l_@@_custom_args_prop {\int_use:N \l_tmpa_int} {\ignorespaces#3} \bool_if:NTF \l_stex_allow_semantic_bool \use_i:nn { \bool_set_true:N \l_stex_allow_semantic_bool \use:nn } { \stex_mathml_arg:nn{\seq_item:Nn \l_stex_argnames_seq \l_tmpa_int}{ \IfBooleanTF#1{ \stex_annotate_invisible:n { %TODO \exp_args:No \_stex_term_arg:nn {\l_tmpa_str\int_use:N \l_tmpa_int}{\ignorespaces#3} } }{ %TODO \exp_args:No \_stex_term_arg:nn {\l_tmpa_str\int_use:N \l_tmpa_int}{\ignorespaces#3} } }} {\bool_set_false:N \l_stex_allow_semantic_bool} } \cs_new_protected:Nn \_stex_term_arg:nn { \bool_set_true:N \l_stex_allow_semantic_bool \stex_annotate:nnn{ arg }{ #1 }{ #2 } \bool_set_false:N \l_stex_allow_semantic_bool } \cs_new_protected:Npn \STEXInternalTermMathArgiii #1#2#3 { \exp_args:Nnx \use:nn { \int_set:Nn \l_@@_downprec { #2 } \stex_mathml_arg:nn{\seq_item:Nn \l_stex_argnames_seq \l_tmpa_int}{ \_stex_term_arg:nn { #1 }{ #3 } } } { \int_set:Nn \exp_not:N \l_@@_downprec { \int_use:N \l_@@_downprec } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\STEXInternalTermMathAssocArgiiiii} % \begin{macrocode} \cs_new_protected:Npn \STEXInternalTermMathAssocArgiiiii #1#2#3#4#5 { \cs_set:Npn \l_tmpa_cs ##1 ##2 { #4 } \tl_set:Nn \l_tmpb_tl {\STEXInternalTermMathArgiii{#5#1}{#2}} \tl_if_empty:nTF { #3 }{ \STEXInternalTermMathArgiii{#5#1}{#2}{} }{ \exp_args:Nx \tl_if_empty:nTF { \tl_tail:n{ #3 }}{ \expandafter\if\expandafter\relax\noexpand#3 \tl_set:Nn \l_tmpa_tl {\_@@_math_assoc_arg_maybe_sequence:Nnn#3{#1}{#5}} \else \tl_set:Nn \l_tmpa_tl {\_@@_math_assoc_arg_simple:nnn{#1}{#3}{#5}} \fi \l_tmpa_tl }{ \_@@_math_assoc_arg_simple:nnn{#1}{#3}{#5} } } } \cs_new_protected:Nn \_@@_math_assoc_arg_maybe_sequence:Nnn { \str_set:Nx \l_tmpa_str { \cs_argument_spec:N #1 } \str_if_empty:NTF \l_tmpa_str { \exp_args:Nx \cs_if_eq:NNTF { \tl_head:N #1 } \stex_invoke_sequence:n { \tl_set:Nx \l_tmpa_tl {\tl_tail:N #1} \str_set:Nx \l_tmpa_str {\exp_after:wN \use:n \l_tmpa_tl} \tl_set:Nx \l_tmpa_tl {\prop_item:cn {l_stex_symdecl_varseq://\l_tmpa_str _prop}{notation}} \exp_args:NNo \seq_set_from_clist:Nn \l_tmpa_seq \l_tmpa_tl \tl_set:Nx \l_tmpa_tl {{\exp_not:N \exp_not:n{ \exp_not:n{\exp_args:Nnx \use:nn} { \exp_not:n { \def\comp{\_varcomp} \str_set:Nn \STEXInternalCurrentSymbolStr } {varseq://\l_tmpa_str} \exp_not:n{ ##1 } }{ \exp_not:n { \_stex_reset:N \comp \_stex_reset:N \STEXInternalCurrentSymbolStr } } }}} \exp_args:Nno \use:n {\seq_set_map:NNn \l_tmpa_seq \l_tmpa_seq} \l_tmpa_tl \seq_reverse:N \l_tmpa_seq \seq_pop:NN \l_tmpa_seq \l_tmpa_tl \seq_map_inline:Nn \l_tmpa_seq { \exp_args:NNNo \exp_args:NNo \tl_set:No \l_tmpa_tl { \exp_args:Nno \l_tmpa_cs { ##1 } \l_tmpa_tl } } \tl_set:Nx \l_tmpa_tl { \_stex_term_omv:nn {varseq://\l_tmpa_str}{ \exp_args:No \exp_not:n \l_tmpa_tl } } \exp_args:No\l_tmpb_tl\l_tmpa_tl }{ \_@@_math_assoc_arg_simple:nnn{#2} { #1 }{#3} } } { \_@@_math_assoc_arg_simple:nnn{#2} { #1 }{#3} } } \cs_new_protected:Nn \_@@_math_assoc_arg_simple:nnn { \clist_set:Nn \l_tmpa_clist{ #2 } \int_compare:nNnTF { \clist_count:N \l_tmpa_clist } < 2 { \tl_set:Nn \l_tmpa_tl { \stex_mathml_arg:nn{\seq_item:Nn \l_stex_argnames_seq #1}{ \_stex_term_arg:nn{A#3#1}{ #2 } } } }{ \clist_reverse:N \l_tmpa_clist \clist_pop:NN \l_tmpa_clist \l_tmpa_tl \tl_set:Nx \l_tmpa_tl { \stex_mathml_arg:nn{\seq_item:Nn \l_stex_argnames_seq #1}{ \_stex_term_arg:nn{A#3#1}{ \exp_args:No \exp_not:n \l_tmpa_tl } }} \clist_map_inline:Nn \l_tmpa_clist { \exp_args:NNNo \exp_args:NNo \tl_set:No \l_tmpa_tl { \exp_args:Nno \l_tmpa_cs { \stex_mathml_arg:nn{\seq_item:Nn \l_stex_argnames_seq #1}{ \_stex_term_arg:nn{A#3#1}{##1} } } \l_tmpa_tl } } } \exp_args:No\l_tmpb_tl\l_tmpa_tl } % \end{macrocode} % \end{macro} % % \subsection{Terms} % % Precedences: % \begin{variable}{\infprec, \neginfprec, \l_@@_downprec} % \begin{macrocode} \tl_const:Nx \infprec {\int_use:N \c_max_int} \tl_const:Nx \neginfprec {-\int_use:N \c_max_int} \int_new:N \l_@@_downprec \int_set_eq:NN \l_@@_downprec \infprec % \end{macrocode} % \end{variable} % % Bracketing: % % \begin{variable}{\l_@@_left_bracket_str, \l_@@_right_bracket_str} % \begin{macrocode} \tl_set:Nn \l_@@_left_bracket_str ( \tl_set:Nn \l_@@_right_bracket_str ) % \end{macrocode} % \end{variable} % % \begin{macro}{\_@@_maybe_brackets:nn} % % Compares precedences and insert brackets accordingly % % \begin{macrocode} \cs_new_protected:Nn \_@@_maybe_brackets:nn { \bool_if:NTF \l_@@_brackets_done_bool { \bool_set_false:N \l_@@_brackets_done_bool #2 } { \int_compare:nNnTF { #1 } > \l_@@_downprec { \bool_if:NTF \l_stex_inparray_bool { #2 }{ \stex_debug:nn{dobrackets}{\number#1 > \number\l_@@_downprec; \detokenize{#2}} \dobrackets { #2 } } }{ #2 } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\dobrackets} % \begin{macrocode} \bool_new:N \l_@@_brackets_done_bool %\RequirePackage{scalerel} \cs_new_protected:Npn \dobrackets #1 { %\ThisStyle{\if D\m@switch % \exp_args:Nnx \use:nn % { \exp_after:wN \left\l_@@_left_bracket_str #1 } % { \exp_not:N\right\l_@@_right_bracket_str } % \else \exp_args:Nnx \use:nn { \bool_set_true:N \l_@@_brackets_done_bool \int_set:Nn \l_@@_downprec \infprec \l_@@_left_bracket_str #1 } { \bool_set_false:N \l_@@_brackets_done_bool \l_@@_right_bracket_str \int_set:Nn \l_@@_downprec { \int_use:N \l_@@_downprec } } %\fi} } % \end{macrocode} % \end{macro} % % \begin{macro}{\withbrackets} % \begin{macrocode} \cs_new_protected:Npn \withbrackets #1 #2 #3 { \exp_args:Nnx \use:nn { \tl_set:Nx \l_@@_left_bracket_str { #1 } \tl_set:Nx \l_@@_right_bracket_str { #2 } #3 } { \tl_set:Nn \exp_not:N \l_@@_left_bracket_str {\l_@@_left_bracket_str} \tl_set:Nn \exp_not:N \l_@@_right_bracket_str {\l_@@_right_bracket_str} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\STEXinvisible} % \begin{macrocode} \cs_new_protected:Npn \STEXinvisible #1 { \stex_annotate_invisible:n { #1 } } % \end{macrocode} % \end{macro} % % \omdoc terms: % % \begin{macro}{\STEXInternalTermMathOMSiiii} % \begin{macrocode} \cs_new_protected:Nn \_stex_term_oms:nnn { \stex_annotate:nnn{ OMID }{ #2 }{ #3 } } \cs_new_protected:Npn \STEXInternalTermMathOMSiiii #1#2#3#4 { \_@@_maybe_brackets:nn { #3 }{ \stex_mathml_intent:nn{#1} { \_stex_term_oms:nnn { #1 } { #1\c_hash_str#2 } { #4 } } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\_stex_term_math_omv:nn} % \begin{macrocode} \cs_new_protected:Nn \_stex_term_omv:nn { \stex_annotate:nnn{ OMV }{ #1 }{ #2 } } % \end{macrocode} % \end{macro} % % \begin{macro}{\STEXInternalTermMathOMAiiii} % \begin{macrocode} \cs_new_protected:Nn \_stex_term_oma:nnn { \stex_annotate:nnn{ OMA }{ #2 }{ #3 } } \cs_new_protected:Npn \STEXInternalTermMathOMAiiii #1#2#3#4 { \exp_args:Nnx \use:nn { \seq_clear:N \l_@@_tmp_seq \prop_if_exist:cT{l_stex_symdecl_#1 _prop}{ \exp_args:NNx \seq_set_from_clist:Nn \l_stex_argnames_seq { \prop_item:cn {l_stex_symdecl_#1 _prop}{argnames} } \exp_args:Nx\int_step_inline:nn{\prop_item:cn{l_stex_symdecl_#1 _prop}{arity}}{ \tl_set:Nx \l_@@_tmp_tl {\seq_item:Nn \l_stex_argnames_seq {##1}} \bool_lazy_or:nnT{ \str_if_eq_p:nn{a}{\str_item:Nn\l_tmpa_str{##1}} }{ \str_if_eq_p:nn{B}{\str_item:Nn\l_tmpa_str{##1}} }{ \tl_put_right:Nn \l_@@_tmp_tl + } \seq_put_right:No \l_@@_tmp_seq \l_@@_tmp_tl } } \_@@_maybe_brackets:nn { #3 }{ \stex_mathml_intent:nn{ #1[\prop_item:cn {l_stex_symdecl_#1 _prop}{ args }]( \seq_use:Nn \l_@@_tmp_seq , ) }{ \_stex_term_oma:nnn { #1 } { #1\c_hash_str#2 } { #4 } } } }{ \_stex_reset:N \l_stex_argnames_seq } } % \end{macrocode} % \end{macro} % % \begin{macro}{\STEXInternalTermMathOMBiiii} % \begin{macrocode} \cs_new_protected:Nn \_stex_term_ombind:nnn { \stex_annotate:nnn{ OMBIND }{ #2 }{ #3 } } \cs_new_protected:Npn \STEXInternalTermMathOMBiiii #1#2#3#4 { \exp_args:Nnx \use:nn { \seq_clear:N \l_@@_tmp_seq \prop_if_exist:cT{l_stex_symdecl_#1 _prop}{ \exp_args:NNx \seq_set_from_clist:Nn \l_stex_argnames_seq { \prop_item:cn {l_stex_symdecl_#1 _prop}{argnames} } \exp_args:Nx\int_step_inline:nn{\prop_item:cn{l_stex_symdecl_#1 _prop}{arity}}{ \tl_set:Nx \l_@@_tmp_tl {\seq_item:Nn \l_stex_argnames_seq {##1}} \bool_lazy_or:nnT{ \str_if_eq_p:nn{a}{\str_item:Nn\l_tmpa_str{##1}} }{ \str_if_eq_p:nn{B}{\str_item:Nn\l_tmpa_str{##1}} }{ \tl_put_right:Nn \l_@@_tmp_tl + } \seq_put_right:No \l_@@_tmp_seq \l_@@_tmp_tl } } \_@@_maybe_brackets:nn { #3 }{ \stex_mathml_intent:nn{ #1[\prop_item:cn {l_stex_symdecl_#1 _prop}{ args }]( \seq_use:Nn \l_@@_tmp_seq , ) }{ \_stex_term_ombind:nnn { #1 } { #1\c_hash_str#2 } { #4 } } } }{ \_stex_reset:N \l_stex_argnames_seq } } % \end{macrocode} % \end{macro} % % % % \begin{macro}{\symref,\symname} % \begin{macrocode} \cs_new:Nn \stex_capitalize:n { \uppercase{#1} } \keys_define:nn { stex / symname } { pre .tl_set_x:N = \l_@@_pre_tl , post .tl_set_x:N = \l_@@_post_tl , root .tl_set_x:N = \l_@@_root_tl } \cs_new_protected:Nn \stex_symname_args:n { \tl_clear:N \l_@@_post_tl \tl_clear:N \l_@@_pre_tl \tl_clear:N \l_@@_root_str \keys_set:nn { stex / symname } { #1 } } \NewDocumentCommand \symref { m m }{ \let\compemph_uri_prev:\compemph@uri \let\compemph@uri\symrefemph@uri \STEXsymbol{#1}!{ #2 } \let\compemph@uri\compemph_uri_prev: } \NewDocumentCommand \synonym { O{} m m}{ \stex_symname_args:n { #1 } \let\compemph_uri_prev:\compemph@uri \let\compemph@uri\symrefemph@uri % TODO \STEXsymbol{#2}!{\l_@@_pre_tl #3 \l_@@_post_tl} \let\compemph@uri\compemph_uri_prev: } \NewDocumentCommand \symname { O{} m }{ \stex_symname_args:n { #1 } \stex_get_symbol:n { #2 } \str_set:Nx \l_tmpa_str { \prop_item:cn { l_stex_symdecl_ \l_stex_get_symbol_uri_str _prop } { name } } \exp_args:NNno \str_replace_all:Nnn \l_tmpa_str {-} {~} \let\compemph_uri_prev:\compemph@uri \let\compemph@uri\symrefemph@uri \exp_args:NNx \use:nn \stex_invoke_symbol:n { { \l_stex_get_symbol_uri_str }!\ifmmode*\fi{ \l_@@_pre_tl \l_tmpa_str \l_@@_post_tl } } \let\compemph@uri\compemph_uri_prev: } \NewDocumentCommand \Symname { O{} m }{ \stex_symname_args:n { #1 } \stex_get_symbol:n { #2 } \str_set:Nx \l_tmpa_str { \prop_item:cn { l_stex_symdecl_ \l_stex_get_symbol_uri_str _prop } { name } } \exp_args:NNno \str_replace_all:Nnn \l_tmpa_str {-} {~} \let\compemph_uri_prev:\compemph@uri \let\compemph@uri\symrefemph@uri \exp_args:NNx \use:nn \stex_invoke_symbol:n { { \l_stex_get_symbol_uri_str }!\ifmmode*\fi{ \exp_after:wN \stex_capitalize:n \l_tmpa_str \l_@@_post_tl } } \let\compemph@uri\compemph_uri_prev: } % \end{macrocode} % \end{macro} % % % \subsection{Notation Components} % \begin{macrocode} %<@@=stex_notationcomps> % \end{macrocode} % % \begin{macro}{\comp,\compemph@uri,\compemph,\defemph,\defemph@uri,\symrefemph,\symrefemph@uri,\varemph,\varemph@uri} % \begin{macrocode} \cs_new_protected:Npn \_comp #1 { \str_if_empty:NF \STEXInternalCurrentSymbolStr { \stex_html_backend:TF { \stex_annotate:nnn { comp }{ \STEXInternalCurrentSymbolStr }{ #1 } }{ \exp_args:Nnx \compemph@uri { #1 } { \STEXInternalCurrentSymbolStr } } } } \cs_new_protected:Npn \_varcomp #1 { \str_if_empty:NF \STEXInternalCurrentSymbolStr { \stex_html_backend:TF { \stex_annotate:nnn { varcomp }{ \STEXInternalCurrentSymbolStr }{ #1 } }{ \exp_args:Nnx \varemph@uri { #1 } { \STEXInternalCurrentSymbolStr } } } } \def\comp{\_comp} \cs_new_protected:Npn \compemph@uri #1 #2 { \compemph{ #1 } } \cs_new_protected:Npn \compemph #1 { #1 } \cs_new_protected:Npn \defemph@uri #1 #2 { \defemph{#1} } \cs_new_protected:Npn \defemph #1 { \textbf{#1} } \cs_new_protected:Npn \symrefemph@uri #1 #2 { \symrefemph{#1} } \cs_new_protected:Npn \symrefemph #1 { \emph{#1} } \cs_new_protected:Npn \varemph@uri #1 #2 { \varemph{#1} } \cs_new_protected:Npn \varemph #1 { #1 } % \end{macrocode} % \end{macro} % % % \begin{macro}{\ellipses} % \begin{macrocode} \NewDocumentCommand \ellipses {} { \ldots } % \end{macrocode} % \end{macro} % % % \begin{macro}{\parray,\prmatrix,\parrayline,\parraylineh,\parraycell} % \begin{macrocode} \bool_new:N \l_stex_inparray_bool \bool_set_false:N \l_stex_inparray_bool \NewDocumentCommand \parray { m m } { \begingroup \bool_set_true:N \l_stex_inparray_bool \begin{array}{#1} #2 \end{array} \endgroup } \NewDocumentCommand \prmatrix { m } { \begingroup \bool_set_true:N \l_stex_inparray_bool \begin{matrix} #1 \end{matrix} \endgroup } \def \maybephline { \bool_if:NT \l_stex_inparray_bool {\hline} } \def \parrayline #1 #2 { #1 #2 \bool_if:NT \l_stex_inparray_bool {\\} } \def \pmrow #1 { \parrayline{}{ #1 } } \def \parraylineh #1 #2 { #1 #2 \bool_if:NT \l_stex_inparray_bool {\\\hline} } \def \parraycell #1 { #1 \bool_if:NT \l_stex_inparray_bool {&} } % \end{macrocode} % \end{macro} % % \subsection{Variables} % \begin{macrocode} %<@@=stex_variables> % \end{macrocode} % % \begin{macro}{\stex_invoke_variable:n} % % Invokes a variable % % \begin{macrocode} \cs_new_protected:Nn \stex_invoke_variable:n { \if_mode_math: \exp_after:wN \_@@_invoke_math:n \else: \exp_after:wN \_@@_invoke_text:n \fi: {#1} } \cs_new_protected:Nn \_@@_invoke_text:n { \peek_charcode_remove:NTF ! { \_@@_invoke_op_custom:nn {#1} }{ \_@@_invoke_custom:nn {#1} } } \cs_new_protected:Nn \_@@_invoke_math:n { \peek_charcode_remove:NTF ! { \peek_charcode_remove:NTF ! { \peek_charcode:NTF [ { % TODO throw error }{ \_@@_invoke_op_custom:nn } }{ \_@@_invoke_op:n { #1 } } }{ \peek_charcode_remove:NTF * { \_@@_invoke_custom:nn { #1 } }{ \_@@_invoke_math_ii:n { #1 } } } } \cs_new_protected:Nn \_@@_invoke_op_custom:nn { \exp_args:Nnx \use:nn { \def\comp{\_varcomp} \str_set:Nn \STEXInternalCurrentSymbolStr { var://#1 } \bool_set_false:N \l_stex_allow_semantic_bool \_stex_term_omv:nn {var://#1}{ \comp{ #2 } } }{ \_stex_reset:N \comp \_stex_reset:N \STEXInternalCurrentSymbolStr \bool_set_true:N \l_stex_allow_semantic_bool } } \cs_new_protected:Nn \_@@_invoke_op:n { \cs_if_exist:cTF { stex_var_op_notation_ #1 _cs }{ \exp_args:Nnx \use:nn { \def\comp{\_varcomp} \str_set:Nn \STEXInternalCurrentSymbolStr { var://#1 } \_stex_term_omv:nn { var://#1 }{ \use:c{stex_var_op_notation_ #1 _cs } } }{ \_stex_reset:N \comp \_stex_reset:N \STEXInternalCurrentSymbolStr } }{ \int_compare:nNnTF {\prop_item:cn {l_stex_symdecl_var://#1_prop}{arity}} = 0{ \_@@_invoke_math_ii:n {#1} }{ \msg_error:nnxx{stex}{error/noop}{variable~#1}{} } } } \cs_new_protected:Npn \_@@_invoke_math_ii:n #1 { \cs_if_exist:cTF { stex_var_notation_#1_cs }{ \tl_set:Nx \STEXInternalSymbolAfterInvokationTL { \_stex_reset:N \comp \_stex_reset:N \STEXInternalSymbolAfterInvokationTL \_stex_reset:N \STEXInternalCurrentSymbolStr \bool_set_true:N \l_stex_allow_semantic_bool } \def\comp{\_varcomp} \str_set:Nn \STEXInternalCurrentSymbolStr { var://#1 } \bool_set_false:N \l_stex_allow_semantic_bool \use:c{stex_var_notation_#1_cs} }{ \msg_error:nnxx{stex}{error/nonotation}{variable~#1}{s} } } \cs_new_protected:Nn \_@@_invoke_custom:nn { \exp_args:Nnx \use:nn { \def\comp{\_varcomp} \str_set:Nn \STEXInternalCurrentSymbolStr { var://#1 } \prop_clear:N \l__stex_terms_custom_args_prop \prop_put:Nnn \l__stex_terms_custom_args_prop {currnum} {1} \prop_get:cnN { l_stex_symdecl_var://#1 _prop }{ args } \l_tmpa_str \prop_put:Nno \l__stex_terms_custom_args_prop {args} \l_tmpa_str \tl_set:Nn \arg { \__stex_terms_arg: } \str_if_empty:NTF \l_tmpa_str { \_stex_term_omv:nn {var://#1}{\ignorespaces#2} }{ \str_if_in:NnTF \l_tmpa_str b { \_stex_term_ombind:nnn {var://#1}{}{\ignorespaces#2} }{ \str_if_in:NnTF \l_tmpa_str B { \_stex_term_ombind:nnn {var://#1}{}{\ignorespaces#2} }{ \_stex_term_oma:nnn {var://#1}{}{\ignorespaces#2} } } } % TODO check that all arguments exist }{ \_stex_reset:N \STEXInternalCurrentSymbolStr \_stex_reset:N \arg \_stex_reset:N \comp \_stex_reset:N \l__stex_terms_custom_args_prop %\bool_set_true:N \l_stex_allow_semantic_bool } } % \end{macrocode} % \end{macro} % % \subsection{Sequences} % \begin{macrocode} %<@@=stex_sequences> \cs_new_protected:Nn \stex_invoke_sequence:n { \peek_charcode_remove:NTF ! { \_stex_term_omv:nn {varseq://#1}{ \exp_args:Nnx \use:nn { \def\comp{\_varcomp} \str_set:Nn \STEXInternalCurrentSymbolStr {varseq://#1} \prop_item:cn{l_stex_symdecl_varseq://#1_prop}{notation} }{ \_stex_reset:N \comp \_stex_reset:N \STEXInternalCurrentSymbolStr } } }{ \bool_set_false:N \l_stex_allow_semantic_bool \def\comp{\_varcomp} \str_set:Nn \STEXInternalCurrentSymbolStr {varseq://#1} \tl_set:Nx \STEXInternalSymbolAfterInvokationTL { \_stex_reset:N \comp \_stex_reset:N \STEXInternalSymbolAfterInvokationTL \_stex_reset:N \STEXInternalCurrentSymbolStr \bool_set_true:N \l_stex_allow_semantic_bool } \use:c { stex_varseq_#1_cs } } } % \end{macrocode} % \begin{macrocode} % % \end{macrocode} % % \end{implementation} % \ifinfulldoc\else\printbibliography\fi % % \PrintIndex % \endinput % Local Variables: % mode: doctex % TeX-master: t % End: