summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/stex/source/stex/terms.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/stex/source/stex/terms.dtx')
-rw-r--r--macros/latex/contrib/stex/source/stex/terms.dtx1037
1 files changed, 1037 insertions, 0 deletions
diff --git a/macros/latex/contrib/stex/source/stex/terms.dtx b/macros/latex/contrib/stex/source/stex/terms.dtx
new file mode 100644
index 0000000000..94a71d0208
--- /dev/null
+++ b/macros/latex/contrib/stex/source/stex/terms.dtx
@@ -0,0 +1,1037 @@
+% \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>
+\providecommand\bibfolder{../../lib/bib}
+\input{../../doc/docheader}
+
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \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/terms}
+% \fi
+%
+% \begin{documentation}\label{pkg:terms:doc}
+%
+% 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}{\_stex_term_math_oms:nnnn,\_stex_term_math_oma:nnnn,\_stex_term_math_omb:nnnn}
+% \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}{\_stex_term_math_arg:nnn}
+% \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}{\_stex_term_math_assoc_arg:nnnn}
+% \begin{syntax} \cs{stex_term_arg:nnn}\meta{int}\meta{prec}\meta{notation}\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}{\stex_highlight_term:nn}
+% \begin{syntax} \cs{stex_highlight_term:nn}\Arg{URI}\Arg{args}\end{syntax}
+% Establishes a context for \cs{comp}. Stores the URI in a variable
+% so that \cs{comp} knows which symbol governs the current notation.
+% \end{function}
+%
+% \begin{function}{\comp, \compemph,\compemph@uri, \defemph, \defemph@uri, \symrefemph,\symrefemph@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~invocation~#1~not~allowed~in~notation~component~of~#2
+}
+
+% \end{macrocode}
+% \subsection{Symbol Invocations}
+%
+%
+% \begin{macro}{\stex_invoke_symbol:n}
+%
+% Invokes a semantic macro
+%
+% \begin{macrocode}
+\keys_define:nn { stex / terms } {
+ 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 \_@@_args:n {
+ \str_clear:N \l_@@_lang_str
+ \str_clear:N \l_@@_variant_str
+
+ \keys_set:nn { stex / terms } { #1 }
+}
+
+\cs_new:Nn \_@@_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
+ }
+}
+
+\bool_new:N \l_@@_allow_semantic_bool
+\bool_set_true:N \l_@@_allow_semantic_bool
+
+\cs_new_protected:Nn \stex_invoke_symbol:n {
+ \bool_if:NTF \l_@@_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}{\l_stex_current_symbol_str}
+ }
+}
+
+\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 {
+ \str_set:Nn \l_stex_current_symbol_str { #1 }
+ \bool_set_false:N \l_@@_allow_semantic_bool
+ \_stex_term_oms:nnn {#1 \c_hash_str\c_hash_str}{#1}{
+ \comp{ #2 }
+ }
+ }{
+ \_@@_reset:N \l_stex_current_symbol_str
+ \bool_set_true:N \l_@@_allow_semantic_bool
+ }
+}
+
+\cs_new_protected:Nn \_@@_find_notation:nn {
+ \str_set:Nn \l_stex_current_symbol_str { #1 }
+ \_@@_args:n { #2 }
+ \seq_if_empty:cTF {
+ l_stex_symdecl_ #1 _notations
+ } {
+ \msg_error:nnxx{stex}{error/nonotation}{#1}{s}
+ } {
+ \bool_lazy_all:nTF {
+ {\str_if_empty_p:N \l_@@_variant_str}
+ {\str_if_empty_p:N \l_@@_lang_str}
+ }{
+ \seq_get_left:cN {l_stex_symdecl_#1_notations}\l_@@_variant_str
+ }{
+ \seq_if_in:cxTF {l_stex_symdecl_#1_notations}{
+ \l_@@_variant_str \c_hash_str \l_@@_lang_str
+ }{
+ \str_set:Nx \l_@@_variant_str { \l_@@_variant_str \c_hash_str \l_@@_lang_str }
+ }{
+ \msg_error:nnxx{stex}{error/nonotation}{#1}{
+ ~\l_@@_variant_str \c_hash_str \l_@@_lang_str
+ }
+ }
+ }
+ }
+}
+
+\cs_new_protected:Npn \_@@_invoke_op_notation:nw #1 [#2] {
+ \_@@_find_notation:nn { #1 }{ #2 }
+ \bool_set_false:N \l_@@_allow_semantic_bool
+ \cs_if_exist:cTF {
+ stex_op_notation_ #1 \c_hash_str \l_@@_variant_str _cs
+ }{
+ \use:c{stex_op_notation_ #1 \c_hash_str \l_@@_variant_str _cs}
+ }{
+ \msg_error:nnxx{stex}{error/noop}{#1}{\l_@@_variant_str}
+ }
+ \bool_set_true:N \l_@@_allow_semantic_bool
+}
+
+\cs_new_protected:Npn \_@@_invoke_notation:nw #1 [#2] {
+ \_@@_find_notation:nn { #1 }{ #2 }
+ \cs_if_exist:cTF {
+ stex_notation_ #1 \c_hash_str \l_@@_variant_str _cs
+ }{
+ \tl_set:Nx \stex_symbol_after_invocation_tl {
+ \_@@_reset:N \stex_symbol_after_invocation_tl
+ \_@@_reset:N \l_stex_current_symbol_str
+ \bool_set_true:N \l_@@_allow_semantic_bool
+ }
+ \bool_set_false:N \l_@@_allow_semantic_bool
+ \use:c{stex_notation_ #1 \c_hash_str \l_@@_variant_str _cs}
+ }{
+ \msg_error:nnxx{stex}{error/nonotation}{#1}{
+ ~\l_@@_variant_str
+ }
+ }
+}
+
+\prop_new:N \l_@@_custom_args_prop
+
+\cs_new_protected:Nn \_@@_invoke_custom:nn {
+ \exp_args:Nnx \use:nn {
+ \bool_set_false:N \l_@@_allow_semantic_bool
+ \str_set:Nn \l_stex_current_symbol_str { #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
+ \prop_put:Nno \l_@@_custom_args_prop {args} \l_tmpa_str
+ \tl_set:Nn \arg { \_@@_arg: }
+ \str_if_empty:NTF \l_tmpa_str {
+ \_stex_term_oms:nnn {#1}{#1}{#2}
+ }{
+ \str_if_in:NnTF \l_tmpa_str b {
+ \_stex_term_ombind:nnn {#1}{#1}{#2}
+ }{
+ \str_if_in:NnTF \l_tmpa_str B {
+ \_stex_term_ombind:nnn {#1}{#1}{#2}
+ }{
+ \_stex_term_oma:nnn {#1}{#1}{#2}
+ }
+ }
+ }
+ % TODO check that all arguments exist
+ }{
+ \_@@_reset:N \l_stex_current_symbol_str
+ \_@@_reset:N \arg
+ \_@@_reset:N \l_@@_custom_args_prop
+ \bool_set_true:N \l_@@_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 }
+ \exp_args:NNx \prop_if_in:NnT \l_@@_custom_args_prop {\int_use:N \l_tmpa_int} {
+ % TODO throw error
+ }
+ }
+ \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} {
+ % TODO throw error
+ }
+ \IfBooleanTF#1{
+ \stex_annotate_invisible:n {
+ \exp_args:No \_stex_term_arg:nn {\l_stex_current_symbol_str}{#3}
+ }
+ }{
+ \exp_args:No \_stex_term_arg:nn {\l_stex_current_symbol_str}{#3}
+ }
+}
+
+
+\cs_new_protected:Nn \_stex_term_arg:nn {
+ \exp_args:Nnx \use:nn {
+ \bool_set_true:N \l_@@_allow_semantic_bool
+ \stex_annotate:nnn{ arg }{ #1 }{ #2 }
+ }{
+ \bool_set_false:N \l_@@_allow_semantic_bool
+ }
+}
+
+\cs_new_protected:Nn \_stex_term_math_arg:nnn {
+ \exp_args:Nnx \use:nn
+ { \int_set:Nn \l_@@_downprec { #2 }
+ \_stex_term_arg:nn { #1 }{ #3 }
+ }
+ { \int_set:Nn \exp_not:N \l_@@_downprec { \int_use:N \l_@@_downprec } }
+}
+
+
+% \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}{\_stex_term_math_oms:nnnn}
+% \begin{macrocode}
+\cs_new_protected:Nn \_stex_term_oms:nnn {
+ \stex_annotate:nnn{ OMID }{ #2 }{
+ \stex_highlight_term:nn { #1 } { #3 }
+ }
+}
+
+\cs_new_protected:Nn \_stex_term_math_oms:nnnn {
+ \_@@_maybe_brackets:nn { #3 }{
+ \_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{ OMID }{ #1 }{
+ \stex_highlight_term:nn { #1 } { #2 }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\_stex_term_math_oma:nnnn}
+% \begin{macrocode}
+\cs_new_protected:Nn \_stex_term_oma:nnn {
+ \stex_annotate:nnn{ OMA }{ #2 }{
+ \stex_highlight_term:nn { #1 } { #3 }
+ }
+}
+
+\cs_new_protected:Nn \_stex_term_math_oma:nnnn {
+ \_@@_maybe_brackets:nn { #3 }{
+ \_stex_term_oma:nnn { #1 } { #1\c_hash_str#2 } { #4 }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\_stex_term_math_omb:nnnn}
+% \begin{macrocode}
+\cs_new_protected:Nn \_stex_term_ombind:nnn {
+ \stex_annotate:nnn{ OMBIND }{ #2 }{
+ \stex_highlight_term:nn { #1 } { #3 }
+ }
+}
+
+\cs_new_protected:Nn \_stex_term_math_omb:nnnn {
+ \_@@_maybe_brackets:nn { #3 }{
+ \_stex_term_ombind:nnn { #1 } { #1\c_hash_str#2 } { #4 }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\_stex_term_math_assoc_arg:nnnn}
+% \begin{macrocode}
+\cs_new_protected:Nn \_stex_term_math_assoc_arg:nnnn {
+ % TODO sequences
+ \clist_set:Nn \l_tmpa_clist{ #3 }
+ \int_compare:nNnTF { \clist_count:N \l_tmpa_clist } < 2 {
+ \tl_set:Nn \l_tmpa_tl { #3 }
+ }{
+ \cs_set:Npn \l_tmpa_cs ##1 ##2 { #4 }
+ \clist_reverse:N \l_tmpa_clist
+ \clist_pop:NN \l_tmpa_clist \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 { ##1 } \l_tmpa_tl
+ }
+ }
+ }
+ \exp_args:Nnno
+ \_stex_term_math_arg:nnn{#1}{#2}\l_tmpa_tl
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\stex_term_custom:nn}
+% \begin{macrocode}
+\cs_new_protected:Nn \stex_term_custom:nn {
+ \str_set:Nn \l_@@_custom_uri { #1 }
+ \str_set:Nn \l_tmpa_str { #2 }
+ \tl_clear:N \l_tmpa_tl
+ \int_zero:N \l_tmpa_int
+ \int_set:Nn \l_tmpb_int { \str_count:N \l_tmpa_str }
+ \_@@_custom_loop:
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\_@@_custom_loop:}
+% \begin{macrocode}
+\cs_new_protected:Nn \_@@_custom_loop: {
+ \bool_set_false:N \l_tmpa_bool
+ \bool_while_do:nn {
+ \str_if_eq_p:ee X {
+ \str_item:Nn \l_tmpa_str { \l_tmpa_int + 1 }
+ }
+ }{
+ \int_incr:N \l_tmpa_int
+ }
+
+ \peek_charcode:NTF [ {
+ % notation/text component
+ \_@@_custom_component:w
+ } {
+ \int_compare:nNnTF \l_tmpa_int = \l_tmpb_int {
+ % all arguments read => finish
+ \_@@_custom_final:
+ } {
+ % arguments missing
+ \peek_charcode_remove:NTF * {
+ % invisible, specific argument position or both
+ \peek_charcode:NTF [ {
+ % visible specific argument position
+ \_@@_custom_arg:wn
+ } {
+ % invisible
+ \peek_charcode_remove:NTF * {
+ % invisible specific argument position
+ \_@@_custom_arg_inv:wn
+ } {
+ % invisible next argument
+ \_@@_custom_arg_inv:wn [ \l_tmpa_int + 1 ]
+ }
+ }
+ } {
+ % next normal argument
+ \_@@_custom_arg:wn [ \l_tmpa_int + 1 ]
+ }
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\_@@_custom_arg_inv:wn}
+% \begin{macrocode}
+\cs_new_protected:Npn \_@@_custom_arg_inv:wn [ #1 ] #2 {
+ \bool_set_true:N \l_tmpa_bool
+ \_@@_custom_arg:wn [ #1 ] { #2 }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\_@@_custom_arg:wn}
+% \begin{macrocode}
+\cs_new_protected:Npn \_@@_custom_arg:wn [ #1 ] #2 {
+ \str_set:Nx \l_tmpb_str {
+ \str_item:Nn \l_tmpa_str { #1 }
+ }
+ \str_case:VnTF \l_tmpb_str {
+ { X } {
+ \msg_error:nnx{stex}{error/notationarg}{\l_@@_custom_uri}
+ }
+ { i } { \_@@_custom_set_X:n { #1 } }
+ { b } { \_@@_custom_set_X:n { #1 } }
+ { a } { \_@@_custom_set_X:n { #1 } } % TODO ?
+ { B } { \_@@_custom_set_X:n { #1 } } % TODO ?
+ }{}{
+ \msg_error:nnx{stex}{error/notationarg}{\l_@@_custom_uri}
+ }
+
+ \bool_if:nTF \l_tmpa_bool {
+ \tl_put_right:Nx \l_tmpa_tl {
+ \stex_annotate_invisible:n {
+ \_stex_term_arg:nn { \int_eval:n { #1 } }
+ \exp_not:n { { #2 } }
+ }
+ }
+ } {
+ \tl_put_right:Nx \l_tmpa_tl {
+ \_stex_term_arg:nn { \int_eval:n { #1 } }
+ \exp_not:n { { #2 } }
+ }
+ }
+
+ \_@@_custom_loop:
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\_@@_custom_set_X:n}
+% \begin{macrocode}
+\cs_new_protected:Nn \_@@_custom_set_X:n {
+ \str_set:Nx \l_tmpa_str {
+ \str_range:Nnn \l_tmpa_str 1 { #1 - 1 }
+ X
+ \str_range:Nnn \l_tmpa_str { #1 + 1 } { -1 }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\_@@_custom_component:}
+% \begin{macrocode}
+\cs_new_protected:Npn \_@@_custom_component:w [ #1 ] {
+ \tl_put_right:Nn \l_tmpa_tl { \comp{ #1 } }
+ \_@@_custom_loop:
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\_@@_custom_final:}
+% \begin{macrocode}
+\cs_new_protected:Nn \_@@_custom_final: {
+ \int_compare:nNnTF \l_tmpb_int = 0 {
+ \exp_args:Nnno \_stex_term_oms:nnn
+ }{
+ \str_if_in:NnTF \l_tmpa_str {b} {
+ \exp_args:Nnno \_stex_term_ombind:nnn
+ } {
+ \exp_args:Nnno \_stex_term_oma:nnn
+ }
+ }
+ { \l_@@_custom_uri } { \l_@@_custom_uri } { \l_tmpa_tl }
+}
+% \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 }!{
+ \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 }!{
+ \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}{\stex_highlight_term:nn}
+% \begin{macrocode}
+
+\str_new:N \l_stex_current_symbol_str
+\cs_new_protected:Nn \stex_highlight_term:nn {
+ \exp_args:Nnx
+ \use:nn {
+ \str_set:Nx \l_stex_current_symbol_str { #1 }
+ #2
+ } {
+ \str_set:Nx \exp_not:N \l_stex_current_symbol_str
+ { \l_stex_current_symbol_str }
+ }
+}
+
+\cs_new_protected:Nn \stex_unhighlight_term:n {
+% \latexml_if:TF {
+% #1
+% } {
+% \rustex_if:TF {
+% #1
+% } {
+ #1 %\iffalse{{\fi}} #1 {{\iffalse}}\fi
+% }
+% }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\comp,\compemph@uri,\compemph,\defemph,\defemph@uri,\symrefemph,\symrefemph@uri}
+% \begin{macrocode}
+\cs_new_protected:Npn \comp #1 {
+ \str_if_empty:NF \l_stex_current_symbol_str {
+ \rustex_if:TF {
+ \stex_annotate:nnn { comp }{ \l_stex_current_symbol_str }{ #1 }
+ }{
+ \exp_args:Nnx \compemph@uri { #1 } { \l_stex_current_symbol_str }
+ }
+ }
+}
+
+\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 {
+ \textbf{#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 {
+ %TODO
+}
+
+
+\cs_new_protected:Nn \_@@_invoke_math:n {
+ \peek_charcode_remove:NTF ! {
+ \peek_charcode_remove:NTF ! {
+ \peek_charcode:NTF [ {
+ \_@@_invoke_op_custom:nw
+ }{
+ % TODO throw error
+ }
+ }{
+ \_@@_invoke_op:n { #1 }
+ }
+ }{
+ \peek_charcode_remove:NTF * {
+ \_@@_invoke_text:n { #1 }
+ }{
+ \_@@_invoke_math_ii:n { #1 }
+ }
+ }
+}
+
+\cs_new_protected:Nn \_@@_invoke_op:n {
+ \cs_if_exist:cTF {
+ stex_var_op_notation_ #1 _cs
+ }{
+ \use:c{stex_var_op_notation_ #1 _cs }
+ }{
+ \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
+ }{
+ \str_set:Nn \l_stex_current_symbol_str { #1 }
+ \use:c{stex_var_notation_#1_cs}
+ }{
+ \msg_error:nnxx{stex}{error/nonotation}{variable~#1}{s}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
+
+% \endinput
+% Local Variables:
+% mode: doctex
+% TeX-master: t
+% End: